Design System: Como criar componentes reutilizáveis
Um design system é fundamental para manter consistência em aplicações web modernas. Neste artigo, vamos explorar como criar e implementar um design system eficiente.
O que é um Design System?
Um design system é uma coleção de componentes reutilizáveis, guiados por padrões claros, que podem ser unidos para construir qualquer quantidade de aplicações.
Componentes principais:
- Tokens de design: Cores, tipografia, espaçamentos
- Componentes base: Buttons, inputs, cards
- Padrões de layout: Grid systems, containers
- Documentação: Guias de uso e exemplos
Criando um Button Component
Vamos começar com um componente básico - um botão:
// components/ui/Button.tsx
import { ReactNode } from 'react';
import { cva, type VariantProps } from 'class-variance-authority';
const buttonVariants = cva(
'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50',
{
variants: {
variant: {
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
outline: 'border border-input hover:bg-accent hover:text-accent-foreground',
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
ghost: 'hover:bg-accent hover:text-accent-foreground',
link: 'text-primary underline-offset-4 hover:underline',
},
size: {
default: 'h-10 px-4 py-2',
sm: 'h-9 rounded-md px-3',
lg: 'h-11 rounded-md px-8',
icon: 'h-10 w-10',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
}
);
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
children: ReactNode;
}
export function Button({ className, variant, size, children, ...props }: ButtonProps) {
return (
<button
className={cn(buttonVariants({ variant, size, className }))}
{...props}
>
{children}
</button>
);
}
Tokens de Design
Defina seus tokens de design no Tailwind config:
// tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
primary: {
50: '#eff6ff',
500: '#3b82f6',
900: '#1e3a8a',
},
secondary: {
50: '#f8fafc',
500: '#64748b',
900: '#0f172a',
},
},
fontFamily: {
sans: ['Inter', 'sans-serif'],
mono: ['JetBrains Mono', 'monospace'],
},
spacing: {
'18': '4.5rem',
'88': '22rem',
},
},
},
};
Documentação com Storybook
Use Storybook para documentar seus componentes:
// Button.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';
const meta: Meta<typeof Button> = {
title: 'Components/Button',
component: Button,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
argTypes: {
variant: {
control: { type: 'select' },
options: ['default', 'destructive', 'outline', 'secondary', 'ghost', 'link'],
},
},
};
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {
args: {
children: 'Button',
},
};
export const Secondary: Story = {
args: {
variant: 'secondary',
children: 'Button',
},
};
Versionamento e Distribuição
- NPM Package: Publique como pacote npm
- Monorepo: Use Lerna ou NX
- Git Submodules: Para projetos internos
- CDN: Para distribuição rápida
Testes
Garanta qualidade com testes:
// Button.test.tsx
import { render, screen } from '@testing-library/react';
import { Button } from './Button';
describe('Button', () => {
it('renders button with text', () => {
render(<Button>Click me</Button>);
expect(screen.getByRole('button', { name: /click me/i })).toBeInTheDocument();
});
it('applies variant styles', () => {
render(<Button variant="secondary">Secondary</Button>);
const button = screen.getByRole('button');
expect(button).toHaveClass('bg-secondary');
});
});
Conclusão
Um design system bem estruturado economiza tempo de desenvolvimento, garante consistência visual e melhora a experiência do usuário. Comece pequeno e evolua gradualmente.
Lembre-se: um design system é um produto vivo que deve evoluir com suas necessidades.

Comentários
0 ComentáriosSeja o primeiro a comentar neste artigo.