Files
vue-practice/CHALLENGE.md
T
2026-05-12 21:33:51 -04:00

1.7 KiB
Raw Blame History

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: 2535 minutes


Core requirements

  • Accept a variant prop: primary, secondary, danger — each should have visually distinct styles
  • Accept a size prop: sm, md, lg — affects padding and font size
  • Accept a disabled prop — visually and functionally disables the button
  • Accept a loading prop — shows a loading indicator and prevents interaction
  • Use a default slot for button label content
  • Explicitly declare a click emit

Accessibility requirements

  • Use a native <button> element — not a <div>
  • When loading is true, set aria-busy="true" and aria-disabled="true"
  • When disabled is true, use the native disabled attribute (not just styling)
  • Ensure visible focus styles are not removed — outline: none without a replacement is a fail

Bonus points

  • Add an optional icon slot for a leading icon
  • Type all props with TypeScript
  • Add a full-width prop that makes the button width: 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 defineProps and defineEmits correctly with script setup syntax?
  • Do you use a computed to 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 12 minutes talking through your approach out loud. Interviewers value reasoning over speed.