Polymorphic Button with intent + size + state variants via CVA (class-variance-authority), accessible defaults (real `<button>`, focus ring, disabled semantics, loading state with aria-busy), `asChild` for polymorphism, forwarded ref, icon left/right slots, and theme via CSS variables. Avoid the boolean-prop explosion.
Category
Machine Coding
Build live: autocomplete, infinite scroll, carousels, etc.
63 questions
State = the rating value; a hover state for preview. Render N stars, fill based on hover ?? value. Support half-stars, read-only mode, keyboard (arrows), and accessibility (radiogroup or a slider role). The trap: use real buttons/inputs, not divs, and make hover preview not clobber the committed value.
An array of N single-char inputs. Key behaviors: auto-advance focus on entry, backspace moves to the previous box, paste fills all boxes at once, accept only digits, expose the joined value. Manage refs in an array, keep state as a string[].
List of steps with statuses (done | current | upcoming | error), driven by a `currentStep` prop or URL. Render an accessible `<ol>` with `aria-current='step'` on the active one. Allow click navigation to completed steps; lock forward navigation behind validation; show progress visually with line/circle states.
Track elapsed time from timestamps (not by counting ticks), drive UI updates with an interval or requestAnimationFrame, support start/pause/resume/reset/lap, clean up the timer on unmount, and stay accurate when the tab is backgrounded by computing elapsed = now - startTime.
Track a startedAt timestamp + accumulated ms across pauses; compute display from Date.now(). Use requestAnimationFrame (or setInterval) just to trigger re-renders. Don't store ticks in state.
Each task has its own progress (0–100). Track as `tasks: Task[]` with status (idle, running, done, error). Start all in parallel; update progress via callbacks or intervals; render a row per task with a progress bar. Cancel via AbortController. Cap concurrency with a scheduler if needed. Each progress bar memoized so unrelated updates don't re-render others.
Capture pointer position on `pointermove` over a container; render a custom cursor element following with `transform: translate(x, y)` via rAF (not React state — avoid re-render storms). Handle enter/leave to show/hide; use pointer events for cross-input (mouse/pen/touch); throttle to rAF; cleanup listeners on unmount.
Controlled-or-uncontrolled value; a trigger button with `aria-haspopup`/`aria-expanded` and a listbox of options with `role='option'`/`aria-selected`; keyboard support (ArrowUp/Down, Home/End, Enter, Esc, type-ahead); outside-click + Escape to close; focus management; portal for stacking; configurable rendering of items.
Build a headless, accessible combobox: controlled value, filterable options, single/multi-select via props, full keyboard support (arrows, Enter, Escape, type-ahead), proper ARIA (listbox/option/aria-activedescendant), click-outside dismiss, and virtualization for large option sets.
State = the active tab id. Render a tablist of buttons and the active panel. The grading is accessibility: role=tablist/tab/tabpanel, aria-selected, roving tabindex, and arrow-key navigation between tabs. Often built as a compound component (Tabs/Tab/TabPanel) sharing state via Context.
Compound components: <Tabs><TabList><Tab/></TabList><TabPanels><TabPanel/></TabPanels></Tabs>. Active tab in context. Keyboard: Left/Right arrows move focus, Home/End jump. Roles: tablist, tab, tabpanel with aria-controls / aria-labelledby pairing.
Render a list of header/panel pairs; track which panel(s) are open in state. Support single vs multi-expand via a prop, animate height, and make it accessible — button headers, aria-expanded, aria-controls, region roles, and keyboard support.
Each item is a header (button) + a panel. Use real <button> + aria-expanded + aria-controls. Support single-open or multi-open mode. Animate height with grid-template-rows: 0fr → 1fr (modern, no JS measure).
Render into a portal, trap focus inside while open and restore it on close, close on Escape and overlay click, lock body scroll, use role=dialog + aria-modal + aria-labelledby, and support controlled open/close. Accessibility is the hard part, not the visuals.
Render via Portal, lock body scroll, trap focus inside the dialog, restore focus on close, close on Esc + backdrop click, and use role='dialog' aria-modal='true' with labelled title.
Imperative API (`modal.open(<Comp/>)`) backed by a React context store of open modals; renders via a single portal at the root; supports stacking, per-modal options (size, dismissible), focus trap, scroll lock, Esc + outside-click close, and returning a promise for confirm/cancel flows. Decouples 'who opens' from 'who renders'.
Extends the modal manager: each enqueued modal has a priority (number or enum). Modals queue but only the highest-priority one is shown; a new higher-priority modal preempts the current one (or stacks on top depending on policy). Useful for cohesive UX when multiple systems want to show modals (auth, billing, onboarding, errors).
Imperative API (toast.success/error/...) backed by a global store. Render via Portal with aria-live='polite'. Auto-dismiss with pause-on-hover. Cap visible count and queue overflow.
Controlled inputs for email/password, validation (on blur + submit), per-field error state, submit handling with loading/error states, disabled submit while submitting. Use a <form> with onSubmit, proper input types/labels, and never trust client validation alone — the server re-validates.
Structure a login form as a controlled (or RHF-managed) component: labels tied to inputs, validation on blur + submit with errors linked via aria-describedby and aria-invalid, a loading/disabled state on submit, no secrets in client code, HTTPS-only, tokens in httpOnly cookies (not localStorage), generic error messages to avoid user enumeration, and rate limiting on the server.
Lift the whole form's data above the steps (parent state / reducer / context) so it survives step navigation. Track currentStep; validate the current step's slice before advancing; keep per-step errors in shared state; allow free Back; persist for refresh-safety; assemble and submit once at the end.
Keep all form state in one place above the tabs so switching tabs never loses input; render tabs as accessible tablist/tabpanel; validate per-tab but submit the whole form; show per-tab validity/error indicators; and don't unmount inactive tab content if it would drop state.
Generic `<Search items={...} getKey filterFn renderItem onSelect />` (or a hook `useSearch`) — controlled input + debounced filter, supports sync or async sources, keyboard nav (Arrow/Enter/Esc), highlighting, loading/empty/error states, and accessible combobox semantics. Decouples the input from how items are sourced and rendered.
Delay the search request until typing pauses for ~300ms. Implement with a setTimeout that gets cleared on each keystroke — in React, wrap the value in a `useDebouncedValue` hook and fire the request from a `useEffect` that depends on the debounced value. Cancel inflight requests on change.
Controlled input + debounced effect: store the raw input in state, run a debounced effect that fires the search N ms after typing stops. Cancel in-flight requests on new input (AbortController), handle race conditions (ignore stale responses), show loading/empty/error states, and make the listbox accessible.
Controlled input → debounced query → fetch with AbortController to cancel stale requests → results dropdown. Must handle: race conditions (out-of-order responses), loading/empty/error states, keyboard navigation (arrows/enter/escape), min query length, and accessibility (combobox ARIA).
Controlled input → debounced query → fetch with AbortController → results. Must handle: debouncing the derived value (not the input), cancelling stale requests to fix out-of-order races, min query length, loading/empty/error states, and not re-creating the debounced fn each render.
Controlled input + debounced async suggestion fetch + AbortController to drop stale responses + keyboard navigation (arrows, Enter, Esc) + ARIA combobox pattern. Cache by query string.
Debounce input (250–300ms), cancel stale requests with AbortController, race-condition guard via request-id or sequence number, cache results by query, render a listbox combobox with ARIA, keyboard nav (↑↓ Enter Esc), and highlight match. Use React Query for caching + request dedup. Test for double-fire on backspace and quick paste.
The 'hello world' of React interviews. State: an array of {id, text} todos plus controlled input. Add appends, delete filters by id. Watch the details: stable keys (not index), controlled input, trim/empty validation, form submit for Enter support.
Show clean component decomposition (App → List → Item, plus Input + Filter), a single source of truth for state, immutable updates, keys on list items, controlled inputs, basic accessibility, and persistence to localStorage. Then layer features (edit-in-place, filter all/active/completed, count).
The full todo app: array of {id, text, done}, add/edit/delete/toggle done, filter all/active/completed. Stable id keys, immutable updates, controlled inputs in a form, edit-in-place mode, derived (not stored) filtered list, empty states, localStorage persistence. useReducer once it grows.
Normalize state (id-keyed map + ordered ids). Memoize the Row component by id. Selector-style subscriptions so toggling one item only re-renders that row. Lazy-load the Edit modal. Confirm-on-duplicate.
A CRUD task UI: add/edit/delete/toggle tasks, filter by status, maybe priority/due date. State is an array of {id, title, done, ...}; immutable updates; stable id keys. Watch for: controlled inputs, derived (not stored) filtered list, edit-in-place mode, and persistence.
State = current index. Prev/next wrap or clamp; dots/thumbnails jump. Add: autoplay with pause-on-hover, keyboard arrows, swipe on touch, lazy-loading images, and accessibility (aria-roledescription, live region, focus management). Use transform for the slide animation.
Track active index. Render slides in a flex row, transform: translateX(-index * 100%). Auto-advance with setInterval (pause on hover/focus). Lazy-load adjacent images. Keyboard arrows + ARIA region with live announcement.
A machine-coding task: render an N×M grid where N and M (and often cell state) are dynamic. Key points: derive the grid from state (a 1D or 2D array), drive columns with `grid-template-columns: repeat(N, 1fr)` from a variable, handle cell clicks immutably by index, keep keys stable, and lift configuration (size) to controlled inputs. Watch for re-render cost on large grids.
Build a grid of toggleable cells. The graded concepts are in the title: immutable state updates (copy before write, functional updater), modeling 2D structures (1D array with index math, or 2D array copied carefully), and predictable re-renders (stable keys, memoized cells, lifted state). Show you can update one cell without mutating or over-rendering.
Track an ordered array of activated cell ids in state. On click, if not active, push; if already active, ignore (or toggle off). Once all activated, deactivate one-by-one (setInterval) in reverse order via .pop(). Render: each cell highlights if its id is in the array. Clean up the interval on unmount and when the array empties.
Multiple-choice quiz: given a country, pick the right capital from 4 options. State: questions list, current index, selected answer, score. Generate distractors from other countries' capitals (random, avoid the answer). Show feedback after select, then advance. End with a score summary + restart. Keyboard support and accessibility (radiogroup).
Build a 3x3 grid with turn tracking, win/draw detection, and reset. Surface state shape, win-line generation, immutability, and how to extend to NxN as the senior signal.
Render a recursive tree component; track expanded nodes and checkbox state. Checkboxes are tri-state: checking a folder cascades to children, and a parent shows indeterminate when children are mixed. Keep node state in a normalized structure and make it keyboard-accessible.
A recursive tree: a Node component that renders itself for children. State tracks which folders are expanded (a Set of ids). Folders toggle open/closed, files are leaves. Watch: recursion, expanded-state management, accessibility (role=tree/treeitem, keyboard nav), and lazy-loading large trees.
Recursive component that takes a tree node and renders folder/file. Toggle expansion state per node id (Set<string> in a parent or normalized store). Tri-state checkboxes propagate down on parent click and up on child change.
Two approaches: the native HTML Drag and Drop API (draggable, onDragStart/Over/Drop) or pointer-events math. State tracks the dragged item and drop target; reorder the list immutably on drop. Mention accessibility (keyboard reordering) and that a library (dnd-kit) is the production choice.
IntersectionObserver on a sentinel near the bottom triggers loading the next page; cursor pagination (offset breaks under inserts); accumulate pages; show loading/empty/error states; restore scroll on back-navigation via cached pages (React Query); virtualize once the list is long. Bonus: 'load on hover near end' for desktop polish.
Render only the rows visible in the viewport + a small overscan buffer. Compute visible window from scrollTop / itemHeight. For variable heights, measure rows + use a positions cache. Total scroll height is a spacer div equal to total content height. Adopt TanStack Virtual or react-window — rolling your own is a rabbit hole.
Headless data layer (sort/filter/pagination state) decoupled from rendering. Column config drives header + cell render. Server vs client mode. Use TanStack Table headless under the hood; don't reinvent.
Cart state: array of line items {id, name, price, qty}. Operations: add (merge if exists), update qty, remove, clear. Derive totals (subtotal/tax/total) — don't store them. Watch: qty bounds, empty cart state, persistence (localStorage), and that server validates prices.
Model the cart as line items with quantities; compute totals as derived state. Apply optimistic UI on user actions, reconcile prices/availability/promotions with the server (the source of truth for money), and push live changes via WebSocket/polling. Handle conflicts gracefully.
Lazy-init state from localStorage, sync to it with useEffect on change. Wrap reads/writes in try/catch (JSON parse errors, quota, private mode), debounce writes if frequent, version the schema, and sync across tabs with the storage event. Best packaged as a useLocalStorage hook.
State machine: idle → review → confirming → submitting → success | failure | timeout. Show a clear summary on review; require explicit confirm with an idempotency key; lock UI during submit; handle slow/failed network with retry; show distinct success/failure states with next actions. Disable double-submit. Server is source of truth — never trust a client 'success' flag.
URL-driven filter state (search, multi-select facets), debounced search input, server (or client) filter, virtualized grid, add-to-cart with optimistic UI, cart state in Zustand or Context. Components: `<Filters>`, `<ProductGrid>`, `<ProductCard>`, `<CartDrawer>`. Skeleton loading; result count announcement; accessible filter region.
Standard build: a card that fetches current weather for a location and shows temperature, conditions, icon. Use React Query for fetching with caching. Geolocation API for current location with fallback to a default city. Loading + error states. Show units toggle (C/F). Optionally hourly forecast. For interviews: name the API (OpenWeather/WeatherAPI), explain caching, handle the offline case.
Domain: `Match`, `Innings`, `Over`, `Ball`, `Batter`, `Bowler`. Each ball updates running totals (runs, wickets, balls bowled) and triggers UI updates. State machine: ball-by-ball → over-completed → innings-end → match-end. Optimistic updates from a real-time feed (WebSocket); recompute derived stats (run rate, required rate) from primary ball events. Tests are easy because logic is pure.
Week grid: time-axis vertical (hours), day-columns horizontal. Events absolutely positioned within their day column: `top = startMinutes * pxPerMinute`, `height = duration * pxPerMinute`. Overlapping events use the cluster-and-column layout algorithm to share horizontal space. Multi-day events span the day columns above the grid. Click empty to create, drag to move/resize.
An open-ended take-home/architecture prompt. Walk the structure: folder/component architecture, a data layer (React Query for server state) vs UI state, routing, all async UI states, responsive design, error boundaries, accessibility, testing, and performance. Show breadth and judgment, not one feature.
End-to-end recipe: Vite or Next.js scaffold; TypeScript strict; ESLint+Prettier; Tailwind+Radix or design system; React Query for server state; Zustand for client state; React Hook Form + Zod for forms; React Router or Next router; Sentry+web-vitals for observability; Vitest+Testing Library+MSW for tests; CI with type-check+test+bundle budget. Feature folders; codeowners; ADRs.
Design API first (props that compose well), keep the component unopinionated about styling (className passthrough, slots, asChild pattern), ensure a11y baked in (keyboard, focus, ARIA), memoize where it matters, support controlled + uncontrolled modes, expose imperative ref where needed, document with Storybook + a11y addon, test with both unit (logic) and visual (Chromatic/Percy). Look at Radix/React Aria/shadcn for proven patterns.
A take-home/live exercise judging structure, not just 'does it work'. Set up tooling, organize by feature, separate data/logic/presentation, build small composable components, manage state deliberately, handle loading/error/empty states, write meaningful tests, and document decisions.
Don't roll your own. Use a CRDT (Yjs) or OT engine for conflict-free concurrent edits, a rich-text framework (ProseMirror via TipTap / Slate / Lexical) for the editor, and WebSocket / WebRTC transport with awareness for cursors. Render presence + remote cursors via decorations. Persist server-side. CRDTs are dominant in 2026 for offline-tolerance and decentralized topologies; OT for centralized servers like Google Docs.
An open-ended live-coding prompt — clarify the scope first (it likely means a follow-ups/comments/replies thread or a follow-up tasks list). Then model the data, build a recursive or flat-with-parentId structure, handle add/edit/delete, and cover loading/empty/error and accessibility.