Frontend Prompts

Prompts for building responsive layouts, interactive components, animations, and client-side features.

#01 Frontend

Responsive Dashboard Layout

Build a responsive admin dashboard shell in React 19 with TypeScript (strict mode) and Tailwind CSS. The layout has three regions: a collapsible left sidebar for navigation, a sticky top header with a search field and a user-avatar menu, and a main content area showing a grid of stat cards. Drive the overall page with CSS Grid and align components with Flexbox. The sidebar collapses to an icon rail at the lg breakpoint and slides out as an overlay drawer below md, with a hamburger toggle, a backdrop, focus trapping while open, and Escape to close. Persist the collapsed/expanded state in localStorage. Use semantic landmarks (header, nav, main, aside) and ensure every interactive element is keyboard reachable with a visible focus ring. The stat-card grid is responsive — four columns on desktop, two on tablet, one on mobile — and must not shift as data loads (render skeletons of identical dimensions). Keep the component tree small and fully typed: explicit props interfaces, no `any`. Done when the layout is usable by keyboard alone, survives a resize from 320px to 1920px with no overflow or horizontal scroll, and the drawer/collapsed state restores correctly on reload.

#02 Frontend

Accessible Form with Validation

Build a three-step registration form in React 19 + TypeScript + Tailwind that meets WCAG 2.1 AA, using React 19's native form Actions as the primary architecture (not a form library). Step 1 collects personal info (name, email, phone), step 2 is account setup (username, password with a live strength meter), step 3 is preferences (checkboxes, radios, a select). Drive each step with a server (or async) action passed to <form action={...}>, manage per-step submission state with useActionState (so the returned state carries field-level errors and the prior submitted values for re-render), and read pending state with useFormStatus inside the submit button so it disables and shows progress without prop-drilling. Validate every action's FormData with a Zod schema on submit, return typed field errors as the action state, and block progression to the next step until the current one passes. Lean on progressive enhancement: the form must work before hydration, so keep inputs uncontrolled with defaultValue and let the action read FormData rather than wiring controlled state to every field. Accessibility: every input has a real associated <label> (never placeholder-as-label), errors are announced through an aria-live="assertive" region and linked with aria-describedby, the step indicator exposes current/total to screen readers, and on step change focus moves to the new step's heading and the document title updates. The password strength meter scores length and character classes and must never block paste from password managers. Use useOptimistic only where it genuinely helps (e.g. an inline availability hint), and validate the username/email asynchronously inside the action (stub the duplicate-email check). Handle the real-world cases: trimmed whitespace, browser autofill, a failed/rejected action that preserves entered values via the returned state, and back/forward navigation that restores prior steps. Crucially, never convey validation state by color alone. Done when the entire flow is completable by keyboard and by screen reader, the form submits and shows validation even with JavaScript disabled (progressive enhancement), every error is programmatically tied to its field, pending state comes from useFormStatus rather than manual flags, and invalid steps reliably block progression with focus landing on the problem.

#03 Frontend

Animated Card Carousel

Build a card carousel component in React 19 + TypeScript + Tailwind with NO carousel libraries — use native CSS scroll-snap plus transforms. Support touch swipe on mobile, click-and-drag on desktop, and arrow-key navigation when focused. Cards snap cleanly into place; show pagination dots and prev/next buttons that disable at the ends (or, if you implement infinite looping, clone the edges so the wrap is seamless). Derive the visible card count from the container width via ResizeObserver where practical (three on desktop, two on tablet, one on mobile) rather than hard breakpoints. Respect prefers-reduced-motion by dropping the slide animation to an instant jump. Accessibility: expose it as a group with aria-roledescription="carousel", label each slide "n of total", make the dots real <button>s, and use roving tabindex. Handle edge cases: a single card (hide controls), cards added/removed at runtime, and rapid input without jank (coalesce with requestAnimationFrame, transform/translate only — no layout-triggering properties). Done when swipe, drag, and keyboard all converge on the same snapped index, focus is never lost mid-transition, controls disable correctly at the boundaries, and motion degrades cleanly under reduced-motion.

#04 Frontend

Dark Mode Theme Switcher

Implement a complete light / dark / system theme system in a React 19 + TypeScript + Tailwind app using Tailwind's class strategy (darkMode: 'class') backed by CSS custom properties for anything Tailwind tokens don't cover. Provide a three-state toggle. On first paint, resolve the theme from localStorage, falling back to prefers-color-scheme, and apply the class via a small blocking inline script BEFORE hydration so there is no flash of the wrong theme (FOUC). Persist the user's explicit choice; when set to "system", keep reacting to OS changes through a matchMedia listener (and stop reacting once they pick an explicit theme). Define a full semantic token set for both themes — background, surface, raised surface, text primary/secondary, accent, border, ring, shadow — so components reference roles, not raw colors, and theme automatically. Every interactive element needs correct hover, focus-visible, and active states in both themes. Crossfade the transition but disable it under prefers-reduced-motion and never animate on the initial load. Done when reloading in any theme shows zero flash, OS-sync only applies in "system" mode, switching themes remaps tokens with no per-component changes, and contrast in both themes passes WCAG AA.

#05 Frontend

Infinite Scroll Feed

Build an infinite-scroll feed in React 19 + TypeScript + Tailwind backed by a cursor-paginated API (assume GET /api/items?cursor=&limit=20 returning items plus nextCursor). Use IntersectionObserver on a sentinel element to prefetch the next page before the user reaches the bottom, and render fixed-height skeleton placeholders while loading so there is no layout shift. Manage request state with TanStack Query's useInfiniteQuery (or an equivalent typed hook) so caching, dedup, and retries are handled for you. Cover every state explicitly: initial load, loading-more, empty (a friendly zero state), error (inline retry that does NOT discard already-loaded items), and end-of-feed messaging when nextCursor is null. Add a "back to top" button that appears after the first viewport and scrolls smoothly. Guard against the real bugs: the observer firing repeatedly during fast scroll (disconnect or guard while a fetch is in flight), duplicate React keys, and scroll-position restoration when navigating away and back. For very long feeds, virtualize the list or otherwise cap DOM node count. Done when scrolling never double-fetches the same page, an error mid-feed is recoverable in place without losing scroll position, and the list stays smooth past several thousand items.

#06 Frontend

Interactive Data Table

Build a data table component in React 19 + TypeScript + Tailwind that is generic over its row type (Table<T>). Support multi-state column sorting (asc → desc → unsorted) with a visible indicator and aria-sort on the active header, a debounced search box that filters rows and highlights matches inside cells, pagination with numbered pages plus ellipsis for large ranges, and row selection via checkboxes including a header select-all that reflects an indeterminate state. When rows are selected, reveal a bulk-actions toolbar. Make the table horizontally scrollable on small screens with the first column optionally sticky. Render a real <table> with proper scope attributes so it is accessible, and make sort and selection controls keyboard-operable and announced. Keep it fast: memoize the derived filtered/sorted/paged data, avoid re-rendering unaffected rows, and handle 10k rows without freezing (virtualize the body if needed). Get the composition right — sorting, searching, and paging must combine correctly, and select-all must apply only to the current filtered view, not the whole dataset. Cover empty results, a loading skeleton matching the column widths, and columns containing null values. Done when the three features compose correctly together, select-all respects the active filter, and the whole table is operable by keyboard with correct ARIA.

#07 Frontend

Micro-interaction Button Library

Design a typed button library in React 19 + TypeScript + Tailwind with eight polished variants: primary (click ripple), secondary (border draw-in on hover), ghost (background fade), danger (a subtle shake when confirming a destructive action), loading (spinner replacing the label WITHOUT changing the button's width), success (checkmark morph after completion), icon-only (scale + slight rotate on hover, with a required accessible name), and toggle (sliding indicator reflecting pressed state via aria-pressed). Build them all from a single base Button using a discriminated-union props type so illegal combinations (e.g. icon-only with no accessible label) are unrepresentable at compile time. Use Tailwind plus CSS keyframes for the motion and keep JavaScript minimal. Every variant needs a visible focus-visible ring, disabled handling that also blocks the loading state, and full respect for prefers-reduced-motion (animations degrade to instant state changes). The loading and success states must be announced to assistive tech and must prevent double-submission. Done when all eight variants render correctly across sizes, none shift surrounding layout during their animation, the type system rejects invalid prop combinations, and each is fully operable and announced via keyboard and screen reader.