Component API Design for Frontend Interviews: Props, Events, Trade-offs

How to present props, events, composition, and accessibility trade-offs in UI interviews.
18 minuiapi-designreactcompositioninterviews

This guide is part of the FrontendAtlas frontend interview preparation roadmap, focused on interview questions, practical trade-offs, and high-signal decision patterns.

In UI interviews, you’re often asked to build reusable components like a Dropdown, Tabs, or a Modal. The real test isn’t just “can you make it work once” — it’s whether your API design feels scalable in a real codebase. Interviewers want to see if another developer could pick up your component, plug it in, and extend it without rewriting everything. In this guide, we’ll walk through patterns that signal maturity and thoughtfulness — the kind of answers that stand out in a high-pressure interview.

1. Controlled vs uncontrolled

Show that you know both patterns. Controlled = parent manages state. Uncontrolled = component manages state.

<!-- Controlled input -->
<TextField value={value} onChange={setValue} />

<!-- Uncontrolled input with default -->
<TextField defaultValue="hello" onChange={v => console.log(v)} />

2. Composition over configuration

Instead of a million props, show you’d allow composition. This always earns points.

<!-- ❌ Too rigid -->
<Modal title="Delete?" showCancel showConfirm />

<!-- ✅ Flexible, scales with content -->
<Modal>
  <Modal.Header>Delete item</Modal.Header>
  <Modal.Body>This cannot be undone.</Modal.Body>
  <Modal.Footer>
    <Button variant="ghost">Cancel</Button>
    <Button variant="danger">Delete</Button>
  </Modal.Footer>
</Modal>

3. Event naming & payloads

Interviewers look for clarity. Don’t just return raw events — return useful detail.

function Select({ value, onChange }) {
  // onChange({ value, label, reason })
}

4. Accessibility baked in

  • Correct roles (role="dialog", role="tablist").
  • Keyboard handling (Escape, Tab, Arrow keys).
  • Focus management (send focus in, restore on close).
<div role="dialog" aria-modal="true" aria-labelledby="dlgTitle">
  <h2 id="dlgTitle">Confirm Delete</h2>
</div>

5. Styling surface

Show you’d make styling flexible but not chaotic.

<Button variant="danger" size="lg">Delete</Button>
.btn {
  --btn-bg: #1f2937;
  --btn-fg: #fff;
  background: var(--btn-bg);
  color: var(--btn-fg);
}

6. Async state awareness

Front-end is async by nature. Interviews love when you call this out.

<Button onClick={async () => {
  setLoading(true);
  await api.delete();
  setLoading(false);
}}>
  {loading ? "Deleting..." : "Delete"}
</Button>

7. Practice drill

Take any common widget (Tabs, Dropdown, or Modal) and practice evolving it step by step. The goal isn’t a production-ready library — it’s to show layered thinking under interview pressure.

  1. Start with MVP. Build the absolute minimum: one tab switches content, one dropdown selects an item, one modal opens and closes. ✅ Shows you can ship fast.
  2. Add controlled vs uncontrolled options. Controlled = parent passes state + callback. Uncontrolled = component manages its own state. ✅ Signals you understand real-world flexibility.
  3. Add clear events. Don’t just fire raw DOM events — surface meaningful ones like onChange, onSelect, or onOpenChange. ✅ Interviewers look for APIs that would scale in a team.
  4. Layer in accessibility (a11y). Add roles (role="tablist", role="dialog"), keyboard handling (Arrow keys, Escape), and focus management. ✅ Easy bonus points — most candidates forget this.
  5. Make it styleable. Add a variant prop (e.g., primary, danger) or expose CSS variables. ✅ Shows you think about design systems, not just isolated code.

💡 Pro tip: narrate your steps out loud (“First I’ll make it work, then I’ll add a controlled mode, then keyboard support”). This makes your process clear and interviewers will often guide you toward what they care about most.

Wrap-up

In a UI interview, don’t stop at “it works.” Explain how the API scales: what’s controlled vs uncontrolled, what events fire, and how consumers style/compose it. That’s what separates a quick demo from a component a team can actually ship.

  • Name the contract: “Props: open, defaultOpen, onOpenChange. Events: onSelect. Slots: trigger, content.”
  • Call out a11y & keyboard: roles, focus management, Escape/Arrow keys, visible focus.
  • Show the styling story: variants or CSS variables; how a design system would theme it.
  • Mention performance: lazy mount, avoid layout thrash, prefer transform/opacity for animations.
  • State your trade-offs: “I kept state local for simplicity; I’d expose a controlled mode for complex use.”

👉 Keep narrating as you go. If you run out of time, close with: “MVP works; next I’d add focus trap, type-ahead, and a controlled mode with onOpenChange.”

Want focused practice? Try the coding drills next, or skim client-side system design patterns.