Keyboard
- Source
- Aceternity UI ↗
- Author
- Aceternity UI
- Licence
- Aceternity UI licence (free component)
Loading…
A miniature MacBook keyboard whose keys press when you click them or type.
Code
"use client";
import React, { useEffect, useRef, useState } from "react";
import { Keyboard } from "@/lab/aceternity/ui/keyboard";
export default function KeyboardDemo() {
const stageRef = useRef<HTMLDivElement>(null);
const innerRef = useRef<HTMLDivElement>(null);
const [zoom, setZoom] = useState(1);
// The original zooms by viewport breakpoint; here the keyboard is zoomed to fit the stage.
useEffect(() => {
const stage = stageRef.current;
const inner = innerRef.current;
if (!stage || !inner) return;
const fit = () => {
const w = inner.offsetWidth;
const h = inner.offsetHeight;
if (!w || !h) return;
setZoom(
Math.max(
0.5,
Math.min((stage.clientWidth * 0.86) / w, (stage.clientHeight * 0.8) / h),
),
);
};
const ro = new ResizeObserver(fit);
ro.observe(stage);
ro.observe(inner);
return () => ro.disconnect();
}, []);
return (
<div
ref={stageRef}
className="relative flex h-full w-full items-center justify-center overflow-hidden"
>
<div style={{ zoom }}>
<div ref={innerRef}>
<Keyboard className="[zoom:1] sm:[zoom:1] md:[zoom:1] lg:[zoom:1] xl:[zoom:1]" />
</div>
</div>
</div>
);
}
Prompt
Build "Keyboard", a other animation. What it does: A miniature MacBook keyboard whose keys press when you click them or type. Write it as a single self-contained React component in TypeScript that fills its parent (w-full h-full), styled with Tailwind CSS, using @tabler/icons-react, motion. Technique: the Motion library, inline SVG. It sits on a light background, in a 16:10 frame. Respect prefers-reduced-motion with a still state, pause work when the element is off screen, and keep it accessible. Original: https://ui.aceternity.com/components/keyboard (Aceternity UI, Aceternity UI licence (free component)).