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.