Glassmorphic UI Kit — Accessible React 19 Components for Tailwind CSS v4
Overview
Twelve glassmorphic React components (card, panel, button, input, select, modal, tabs, toast, navbar, badge, tooltip, skeleton) built on a CSS-first Tailwind v4 @theme token layer, with generated .d.ts and zero runtime dependencies. Keyboard behaviour is implemented and executed rather than approximated: 66 Vitest tests plus a headless-Chrome pass driven over the DevTools Protocol assert the modal focus trap under real Tab presses, focus restore to the trigger, browser-enforced inert on the background, roving-tabindex arrow navigation, a tooltip that opens on focus, and the toast timer pausing and resuming. Includes a backdrop-filter @supports fallback that drops to opaque surfaces, a contrast scrim with a high-contrast escalation, prefers-reduced-motion handling on every animation, and dark mode driven entirely by tokens. The declared React 18.3 / 19 peer range is exercised on both majors rather than merely declared. Ships a runnable Vite demo, a CI workflow and a changelog; the README documents the contrast, tooltip-positioning and Chrome-only-coverage trade-offs rather than glossing over them.
Source preview
// Restore focus once we are fully gone.
React.useEffect(() => {
if (phase !== "closed") return;
const target = finalFocusRef?.current ?? restoreFocusTo.current;
restoreFocusTo.current = null;
if (!target || !target.isConnected) return;
target.focus({ preventScroll: true });
}, [phase, finalFocusRef]);
// Claim a dismiss layer while we are open, whether or not Escape is enabled -
// an Escape aimed at this dialog must never fall through to one underneath.
const layerRef = React.useRef<DismissLayer | null>(null);
React.useEffect(() => {
if (phase !== "open") return;
const layer = pushDismissLayer();
layerRef.current = layer;
return () => {
layer.release();
layerRef.current = null;
};
}, [phase]);
// Escape, handled only by the topmost layer so nested dialogs close one at a
// time and a tooltip opened inside this dialog gets the key first.
React.useEffect(() => {
if (phase !== "open" || !closeOnEscape) return;
const onKeyDown = (event: KeyboardEvent): void => {
if (event.key !== "Escape") return;
if (layerRef.current && !layerRef.current.isTopmost()) return;
event.stopPropagation();
onCloseRef.current("escape");
};
document.addEventListener("keydown", onKeyDown);
return () => document.removeEventListener("keydown", onKeyDown);Excludes tax, added at checkout where it applies.