1.7 KiB
1.7 KiB
Mock challenge: BaseButton component
Build a reusable Vue 3 button component suitable for a design system. Focus on API design, accessibility, and Vue 3 best practices.
Suggested time: 25–35 minutes
Core requirements
- Accept a
variantprop:primary,secondary,danger— each should have visually distinct styles - Accept a
sizeprop:sm,md,lg— affects padding and font size - Accept a
disabledprop — visually and functionally disables the button - Accept a
loadingprop — shows a loading indicator and prevents interaction - Use a default
slotfor button label content - Explicitly declare a
clickemit
Accessibility requirements
- Use a native
<button>element — not a<div> - When
loadingis true, setaria-busy="true"andaria-disabled="true" - When
disabledis true, use the nativedisabledattribute (not just styling) - Ensure visible focus styles are not removed —
outline: nonewithout a replacement is a fail
Bonus points
- Add an optional
iconslot for a leading icon - Type all props with TypeScript
- Add a
full-widthprop that makes the buttonwidth: 100% - Write at least one Vitest unit test — e.g. that the click event does not fire when disabled
Things they'll be watching for
- Do you use
definePropsanddefineEmitscorrectly with script setup syntax? - Do you use a
computedto derive CSS classes from props, or inline ternaries everywhere? - Do you handle the loading state gracefully — preventing double-clicks, communicating state to screen readers?
- Do you narrate your thinking as you go?
Tip: Before writing any code, spend 1–2 minutes talking through your approach out loud. Interviewers value reasoning over speed.