You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1.9 KiB

Reusable Button Component Prompt

Create or improve a reusable Button component for fe-digitaltwin-v2. Inspect src/shared/components/ui/button.tsx, cn(), and nearby usages first. Extend the existing primitive instead of creating a competing button.

React contract

  • Extend native button attributes.
  • Forward an HTMLButtonElement ref.
  • Accept className, children, type, and typed variant/size props.
  • Preserve asChild composition if the current primitive supports it.
  • Add only these requested additions: <new variants or behavior, or "none">.
  • Keep navigation outside the component; links compose through asChild.

Styling theme: decisive action

  • Primary buttons are visually prominent but compact.
  • Secondary, outline, ghost, link, and destructive variants communicate action hierarchy through semantic project tokens.
  • Use the existing rounded shape and Sora medium-weight label.
  • Hover changes color subtly; active may compress slightly without layout shift.
  • Focus uses focus-visible:ring-2 focus-visible:ring-ring.
  • Disabled and loading states remain readable and cannot trigger duplicate actions.
  • Icon-only buttons have a square touch target and an accessible label.

Required states and behavior

  • <default label and optional leading/trailing icon>
  • Loading: <loading label or spinner behavior>
  • Disabled: native disabled behavior and no click callback.
  • Keyboard: Space and Enter follow native button behavior.
  • Dark mode: rely on semantic tokens rather than raw colors.

Acceptance criteria

  1. Existing button usages remain compatible.
  2. Every variant has default, hover, focus-visible, active, and disabled styling.
  3. Loading content does not significantly change the button width.
  4. Icon-only usage requires an accessible name.
  5. The implementation is typed, ref-forwarding, and composable.

Run focused linting allowed by the repository instructions and finish with a simple TL;DR.