Component Conventions
Scope: Conditional (applies tosrc/**/*.vue, src/**/*.tsx, src/**/*.jsx)Rule ID:
hatch3r-component-conventions
Defines standards for UI component development including structure, naming, styling, state management, form UX, and mandatory accessibility requirements.
Component Structure
Framework-Recommended Syntax
Typed Props and Events
- Define props with typed interfaces (not PropTypes or runtime validation)
- Define emits/events with typed interfaces
- Use TypeScript strict mode — no
anyin component types
Composables/Hooks Over Mixins
State Management
- Use stores (Pinia, Zustand, Redux) for shared state
- Component-local state stays in the component
- Never pass stores directly as props — use composables/hooks to access
Naming Conventions
| Element | Convention | Example |
|---|---|---|
| Component files | PascalCase | UserProfile.vue, QuestPanel.tsx |
| Component names | Match file name | UserProfile, QuestPanel |
| Props | camelCase | userId, isActive |
| Events (Vue) | kebab-case | @update:user, @item-selected |
| Events (React) | camelCase | onUpdateUser, onItemSelected |
Styling
Design Tokens
Use the project’s design tokens for all styling:Styling Approaches
- Prefer utility classes (Tailwind, UnoCSS) or scoped CSS with BEM naming
- No inline styles except for dynamic values that can’t be expressed as classes
- No hardcoded color values — always use tokens
Accessibility (Required)
Animations and Motion
All animations must respectprefers-reduced-motion:
Color Contrast
- Text contrast: ≥ 4.5:1 for normal text (WCAG AA)
- Large text (18px+ or 14px+ bold): ≥ 3:1
- Verify with automated tools (axe-core, Lighthouse)
Keyboard Navigation
- All interactive elements must be keyboard focusable
- Visible focus indicator on all interactive elements
- Use semantic HTML (
<button>,<a>) before reaching for<div>with event handlers
Dynamic Content
High Contrast Mode
- Test components in high contrast mode
- Ensure information is not conveyed by color alone
- Use icons, labels, and patterns in addition to color
State Patterns (Required)
Loading States
Use skeleton screens, not spinners:- Match skeleton layout to loaded content layout
- Apply shimmer/pulse animation to indicate activity
- Load content progressively (show available data immediately)
- Buttons triggering async actions show inline loading indicator and disable
Error States
- Wrap route-level components in error boundaries
- Show inline error messages below failed content with retry action
- Use toast/notification for non-blocking errors (auto-dismiss after 5–8s)
- Never render blank space — always show fallback with explanation and recovery
Empty States
- Display illustration or icon with concise, helpful message
- Include primary action CTA to populate the area
- Provide contextual guidance or links to docs
- Differentiate “no data yet” from “no results found” (with clear-filters action)
Transition States
- Apply optimistic updates for mutations
- Roll back on failure with error toast
- Show pending/saving indicator for in-flight mutations
- Use stale-while-revalidate patterns (display cached data, update in background)
Form UX (Required)
Validation Timing
Error Display
- Show inline error messages directly below field
- Link via
aria-errormessageandaria-invalid="true" - Provide error summary at top of form for screen readers
- Use clear visual error indicator (red border + icon + text)
- Never rely on color alone
Field Patterns
- Group related fields with
<fieldset>and<legend> - Use progressive disclosure for complex forms (expandable sections, multi-step)
- Autofocus first input on form mount
- Tab order follows visual layout order
- Never use positive
tabindexvalues
Submit Behavior
- Disable submit button when form has validation errors
- Show loading indicator during submission
- Prevent double submission (disable button, ignore duplicate events)
- Provide clear success feedback (redirect or success toast)
Accessible Labels
Performance
Target: 60fps
- UI must render at 60fps (≤ 16ms per frame)
- Prefer CSS animations/transitions over JavaScript animations
- Use
will-changesparingly (only for elements that will actually change)
Conditional Rendering
Lazy Loading
Testing
Component Tests
Snapshot Tests
- Snapshot tests for all visual states (default, loading, error, empty)
- Update snapshots only after verifying visual correctness
Accessibility Tests
Reduced Motion Tests
Enforcement
CI gates:- Accessibility tests pass (axe-core, Lighthouse)
- Component tests pass
- No hardcoded color values (lint rule)
- Animations respect
prefers-reduced-motion - Color contrast meets WCAG AA (4.5:1)
- All interactive elements keyboard accessible
- Loading, error, and empty states implemented
- Form validation follows timing rules
- All inputs have visible labels
- No hardcoded colors (uses design tokens)
Related Rules
- Accessibility Standards — WCAG 2.2 AA compliance
- Theming — Dark mode and color system
- Testing Standards — Component testing requirements

