hello world
Terminal-style greeting with a blinking cursor. Hover to resolve the command.
- react
- hooks
- interaction
preview
source · HelloWorld.tsx
import { useState, useEffect } from 'react';
/**
* Hello World snippet — a minimal macOS-style terminal card.
*
* At rest: renders `❯ hello` followed by `Hello, World!` with a blinking
* block cursor. The cursor is driven by a JS interval (not CSS @keyframes)
* so the blink phase stays coherent across browsers without a global rule.
*
* On hover: text transitions to emerald green and a ✓ replaces the cursor,
* simulating a resolved shell command.
*
* Controlled mode (Remotion): when `hovered` or `cursorOn` props are provided
* they take precedence over internal mouse/interval state. This makes the
* component usable as a thin-wrapper inside Remotion compositions without any
* Tailwind dependency — all styles are inline.
*/
type Props = {
/** When defined, overrides internal mouse-enter/leave state. */
hovered?: boolean;
/** When defined, overrides internal interval-driven cursor blink state. */
cursorOn?: boolean;
/**
* When defined, overrides the computed output text colour entirely.
* Used by Remotion to pass a frame-interpolated RGB string so the zinc→emerald
* transition is driven by `interpolate()` rather than CSS `transition` (which
* has no effect in Remotion's headless renderer — each frame is fresh).
*/
textColor?: string;
/**
* 0–1 opacity for the ✓ success indicator. Lets Remotion fade it in smoothly
* instead of popping in when `hovered` flips.
*/
checkOpacity?: number;
};
export default function HelloWorld({ hovered: hoveredProp, cursorOn: cursorOnProp, textColor, checkOpacity }: Props) {
const isControlled = hoveredProp !== undefined;
const [hoveredInternal, setHoveredInternal] = useState(false);
const [cursorOnInternal, setCursorOnInternal] = useState(true);
const hovered = hoveredProp ?? hoveredInternal;
const cursorOn = cursorOnProp ?? cursorOnInternal;
// Drive cursor blink only when idle (not hovered) and not externally controlled.
// Cleanup on hover so the cursor doesn't flash between on/off during transition.
useEffect(() => {
if (isControlled) return;
if (hovered) return;
const id = setInterval(() => setCursorOnInternal((v) => !v), 530);
return () => clearInterval(id);
}, [hovered, isControlled]);
return (
<div
style={{
width: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
padding: 20,
userSelect: 'none',
touchAction: 'manipulation',
fontFamily: '"Geist Mono", "JetBrains Mono", "SF Mono", "Fira Code", monospace',
}}
onMouseEnter={isControlled ? undefined : () => setHoveredInternal(true)}
onMouseLeave={isControlled ? undefined : () => setHoveredInternal(false)}
>
{/* Terminal card */}
<div
style={{
width: '100%',
maxWidth: 220,
borderRadius: 10,
overflow: 'hidden',
boxShadow: '0 25px 50px -12px rgba(0,0,0,0.8)',
outline: '1px solid rgba(255,255,255,0.06)',
}}
>
{/* Window chrome — purely decorative, hidden from a11y tree */}
<div
aria-hidden="true"
style={{
background: '#27272a',
padding: '8px 12px',
display: 'flex',
gap: 6,
alignItems: 'center',
}}
>
<span style={{ width: 10, height: 10, borderRadius: '50%', background: 'rgba(239,68,68,0.8)', display: 'inline-block' }} />
<span style={{ width: 10, height: 10, borderRadius: '50%', background: 'rgba(234,179,8,0.8)', display: 'inline-block' }} />
<span style={{ width: 10, height: 10, borderRadius: '50%', background: 'rgba(34,197,94,0.8)', display: 'inline-block' }} />
</div>
{/* Terminal body */}
<div
style={{
background: '#09090b',
padding: '14px 16px',
fontSize: 11,
lineHeight: 1.6,
minHeight: 68,
}}
>
{/* Input line */}
<div style={{ display: 'flex', gap: 4, marginBottom: 6, alignItems: 'center' }}>
<span style={{ color: '#34d399' }}>❯</span>
<span style={{ color: '#52525b' }}>hello</span>
</div>
{/* Output line + cursor / checkmark */}
<div style={{ display: 'flex', alignItems: 'center' }} aria-live="polite" aria-atomic="true">
<span
style={{
// textColor prop bypasses internal logic for Remotion (frame-interpolated).
// In the browser, fall back to the hovered boolean.
color: textColor ?? (hovered ? 'rgb(134, 239, 172)' : 'rgb(228, 228, 231)'),
transition: textColor ? 'none' : 'color 200ms',
}}
>
Hello, World!
</span>
{/* Block cursor: opacity-toggled so no layout shift */}
{!hovered && (
<span
aria-hidden="true"
style={{
display: 'inline-block',
width: 7,
height: 10,
marginLeft: 3,
background: '#a1a1aa',
verticalAlign: 'middle',
opacity: cursorOn ? 1 : 0,
transition: 'opacity 60ms',
}}
/>
)}
{/* Success indicator — checkOpacity drives a smooth Remotion fade-in;
in the browser it simply appears/disappears with hovered. */}
{hovered && (
<span
aria-hidden="true"
style={{
marginLeft: 6,
color: '#34d399',
opacity: checkOpacity ?? 1,
}}
>
✓
</span>
)}
</div>
</div>
</div>
</div>
);
}