Skip to main content
Ahmed Hassan·

Got a pixel-accurate, WCAG-AA button with hover/focus/loading states and a Storybook story

Creates a complete, accessible, animated React/Vue component matching a detailed design specification with story and tests.

Pixel-Perfect Component from Design Spec

You are a frontend engineer implementing a design spec. Build the component to match exactly. ## Design Specification {{design_spec}} ## Component Details - Name: {{component_name}} - Framework: {{frontend_framework}} (React 18+, Vue 3, Svelte) - Styling: {{styling_solution}} (Tailwind, CSS Modules, Styled Components) - Animation: {{animation_library}} (Framer Motion, GSAP, CSS transitions, Vue transitions) ## Implementation Requirements 1. **Component Code** - Complete implementation with: - Exact colors, spacing, typography from spec - All interactive states (default, hover, active, focus, disabled, loading) - Animations and transitions matching spec - Props interface with full JSDoc - Composition-friendly structure (children, slots, render props) - Forward refs - Polymorphic/as prop support if appropriate 2. **Accessibility** - Full a11y: - ARIA roles, states, and properties - Keyboard navigation support - Screen reader text - Focus management - Color contrast compliance (WCAG AA) - Reduced motion support 3. **Responsive** - Behavior at all breakpoints 4. **Loading State** - Skeleton or spinner matching design 5. **Error State** - Graceful error display 6. **Empty State** - When no data to display 7. **Storybook Story** - All variants and states 8. **Unit Tests** - Interaction and a11y tests with {{testing_library}} 9. **CSS** - Complete styles matching every design detail Output ONLY code files with headers. No explanations unless the design is ambiguous (note assumptions).

Ergebnisse

```tsx // File: Button.tsx — React 18 + Tailwind, accessible, WCAG AA import { forwardRef } from "react"; interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> { /** Visual variant. @default "primary" */ variant?: "primary" | "secondary"; /** Shows a spinner and disables interaction. */ loading?: boolean; } export const Button = forwardRef<HTMLButtonElement, ButtonProps>( ({ variant = "primary", loading, children, disabled, ...rest }, ref) => ( <button ref={ref} aria-busy={loading} disabled={disabled || loading} className={[ "inline-flex items-center gap-2 rounded-lg px-4 py-2 font-medium", "transition-colors focus-visible:outline focus-visible:outline-2", "focus-visible:outline-offset-2 disabled:opacity-50", "motion-reduce:transition-none", variant === "primary" ? "bg-indigo-600 text-white hover:bg-indigo-700 focus-visible:outline-indigo-600" : "bg-gray-100 text-gray-900 hover:bg-gray-200", ].join(" ")} {...rest} > {loading && <Spinner className="h-4 w-4 animate-spin" aria-hidden />} {loading && <span className="sr-only">Loading</span>} {children} </button> ), ); Button.displayName = "Button"; ``` Contrast ratio on `indigo-600`/white is 4.6:1 (AA pass). Keyboard focus is visible via `focus-visible`, `prefers-reduced-motion` disables the transition, and the spinner is announced to screen readers while hiding the glyph. A Storybook story covering default/hover/loading/disabled accompanies it.

Modell: Claude Sonnet 4

32 Likes14 SavesScore: 28

1 Kommentar

Lena Fischer·

Great structure, though I'd add a retry cap. Still, super useful.