Component Library¶
Guidelines for using and creating components.
Design System¶
Colors¶
The design system uses CSS custom properties:
--primary: #31a8b6; /* Freeze Design teal */
--primary-dark: #2a919d;
--primary-light: #b1e0e8;
--accent: #f87171; /* Call-to-action red */
--foreground: #131117; /* Dark text */
--muted-foreground: #525960;
Typography¶
--text-sm: 0.875rem; /* 14px */
--text-base: 1rem; /* 16px */
--text-lg: 1.125rem; /* 18px */
--font-semibold: 600;
--font-bold: 700;
Spacing¶
Component Patterns¶
Props Interface¶
Always define typed props:
interface ComponentProps {
/** Primary content */
children: React.ReactNode;
/** Visual variant */
variant?: 'primary' | 'secondary';
/** Additional CSS classes */
className?: string;
}
Default Props¶
Use destructuring for defaults:
export function Component({
variant = 'primary',
className = '',
children,
}: ComponentProps) {
// ...
}
Composition¶
Prefer composition over configuration:
// Good
<Card>
<CardHeader>
<CardTitle>Title</CardTitle>
</CardHeader>
<CardContent>Content</CardContent>
</Card>
// Avoid
<Card
title="Title"
content="Content"
showHeader={true}
/>
Creating Stories¶
Every component should have a story:
// Component.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Component } from './Component';
const meta: Meta<typeof Component> = {
title: 'Components/Category/Component',
component: Component,
tags: ['autodocs'],
};
export default meta;
type Story = StoryObj<typeof Component>;
export const Default: Story = {
args: {
children: 'Example',
},
};
export const Secondary: Story = {
args: {
children: 'Example',
variant: 'secondary',
},
};
Accessibility¶
All components must:
- Support keyboard navigation
- Have appropriate ARIA attributes
- Meet WCAG 2.1 AA contrast ratios
- Include
data-testidfor testing