Voltar ao blog
Design
09/02/2026
13 min

Design Systems: Como Criar Componentes Reutilizáveis e Escaláveis

Aprenda a construir um design system completo: tokens de design, componentes, documentação e governança para escalar produtos digitais.

E
Equipe Inteligencialy
Autor
Design Systems: Como Criar Componentes Reutilizáveis e Escaláveis

Design Systems transformaram a forma como construímos produtos digitais. Em vez de reinventar a roda em cada projeto, empresas como Google (Material Design), IBM (Carbon) e Shopify (Polaris) criaram sistemas que garantem consistência, velocidade e qualidade.

O Que é um Design System?

Um Design System é uma coleção de componentes reutilizáveis, guiados por padrões claros, que podem ser montados para construir qualquer número de aplicações.

Componentes de um Design System

  1. Design Tokens: Valores de design (cores, tipografia, espaçamento)
  2. Componentes UI: Botões, inputs, cards, modais
  3. Padrões: Layouts, navegação, formulários
  4. Documentação: Como usar cada componente
  5. Ferramentas: Bibliotecas, plugins, templates

Benefícios de um Design System

Para o Negócio

  • Velocidade: Desenvolvimento 3x mais rápido
  • Consistência: Experiência unificada em todos os produtos
  • Escalabilidade: Facilita crescimento do time e produtos
  • Redução de Custos: Menos retrabalho e bugs

Para Designers

  • Eficiência: Foco em problemas complexos
  • Colaboração: Linguagem comum com dev
  • Qualidade: Padrões já testados
  • Evolução: Melhorias beneficiam todos os produtos

Para Developers

  • Produtividade: Componentes prontos para usar
  • Manutenibilidade: Código centralizado e documentado
  • Onboarding: Novos devs produtivos rapidamente
  • Testes: Componentes já testados

Fundamentos: Design Tokens

Design tokens são os átomos do seu design system. São valores nomeados que representam decisões de design.

Estrutura de Tokens

/* colors.css */
:root {
  /* Primitive tokens */
  --color-blue-50: #eff6ff;
  --color-blue-500: #3b82f6;
  --color-blue-900: #1e3a8a;
  
  /* Semantic tokens */
  --color-primary: var(--color-blue-500);
  --color-primary-hover: var(--color-blue-600);
  --color-text-primary: var(--gray-900);
  --color-text-secondary: var(--gray-600);
  
  /* Component tokens */
  --button-bg-primary: var(--color-primary);
  --button-text-primary: white;
}

Categorias de Tokens

Cores

export const colors = {
  // Brand
  primary: { ... },
  secondary: { ... },
  
  // Neutrals
  gray: { 50: '#f9fafb', ..., 900: '#111827' },
  
  // Semantic
  success: { ... },
  error: { ... },
  warning: { ... },
  info: { ... },
};

Tipografia

export const typography = {
  fontFamily: {
    sans: ['Inter', 'system-ui', 'sans-serif'],
    mono: ['JetBrains Mono', 'monospace'],
  },
  fontSize: {
    xs: '0.75rem',
    sm: '0.875rem',
    base: '1rem',
    lg: '1.125rem',
    xl: '1.25rem',
    '2xl': '1.5rem',
    // ...
  },
  fontWeight: {
    normal: 400,
    medium: 500,
    semibold: 600,
    bold: 700,
  },
  lineHeight: {
    tight: 1.25,
    normal: 1.5,
    relaxed: 1.75,
  },
};

Espaçamento

export const spacing = {
  0: '0',
  1: '0.25rem',   // 4px
  2: '0.5rem',    // 8px
  3: '0.75rem',   // 12px
  4: '1rem',      // 16px
  6: '1.5rem',    // 24px
  8: '2rem',      // 32px
  12: '3rem',     // 48px
  16: '4rem',     // 64px
  // ...
};

Construindo Componentes

Anatomia de um Componente

Um bom componente de design system deve ter:

  1. API Clara: Props intuitivas e bem documentadas
  2. Flexibilidade: Suporta diferentes use cases
  3. Acessibilidade: WCAG 2.1 AA no mínimo
  4. Performance: Otimizado e leve
  5. Testes: Cobertura de casos de uso

Exemplo: Button Component

import { cva, type VariantProps } from 'class-variance-authority';

const buttonVariants = cva(
  // Base styles
  'inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50',
  {
    variants: {
      variant: {
        primary: 'bg-primary text-white hover:bg-primary-hover',
        secondary: 'bg-secondary text-white hover:bg-secondary-hover',
        outline: 'border border-gray-300 hover:bg-gray-50',
        ghost: 'hover:bg-gray-100',
      },
      size: {
        sm: 'h-9 px-3 text-sm',
        md: 'h-10 px-4',
        lg: 'h-11 px-6 text-lg',
      },
    },
    defaultVariants: {
      variant: 'primary',
      size: 'md',
    },
  }
);

interface ButtonProps 
  extends React.ButtonHTMLAttributes<HTMLButtonElement>,
    VariantProps<typeof buttonVariants> {
  loading?: boolean;
  icon?: React.ReactNode;
}

export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
  ({ className, variant, size, loading, icon, children, ...props }, ref) => {
    return (
      <button
        ref={ref}
        className={cn(buttonVariants({ variant, size, className }))}
        disabled={loading || props.disabled}
        {...props}
      >
        {loading ? <Spinner /> : icon}
        {children}
      </button>
    );
  }
);

Button.displayName = 'Button';

Exemplo: Input Component

interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
  label?: string;
  error?: string;
  helperText?: string;
  leftIcon?: React.ReactNode;
  rightIcon?: React.ReactNode;
}

export const Input = React.forwardRef<HTMLInputElement, InputProps>(
  ({ label, error, helperText, leftIcon, rightIcon, className, ...props }, ref) => {
    return (
      <div className="w-full">
        {label && (
          <label className="block text-sm font-medium mb-1">
            {label}
          </label>
        )}
        <div className="relative">
          {leftIcon && (
            <div className="absolute left-3 top-1/2 -translate-y-1/2">
              {leftIcon}
            </div>
          )}
          <input
            ref={ref}
            className={cn(
              'w-full px-3 py-2 border rounded-md',
              'focus:outline-none focus:ring-2 focus:ring-primary',
              error && 'border-error focus:ring-error',
              leftIcon && 'pl-10',
              rightIcon && 'pr-10',
              className
            )}
            {...props}
          />
          {rightIcon && (
            <div className="absolute right-3 top-1/2 -translate-y-1/2">
              {rightIcon}
            </div>
          )}
        </div>
        {error && (
          <p className="text-sm text-error mt-1">{error}</p>
        )}
        {helperText && !error && (
          <p className="text-sm text-gray-600 mt-1">{helperText}</p>
        )}
      </div>
    );
  }
);

Documentação

Storybook

Storybook é a ferramenta padrão para documentar 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,
  tags: ['autodocs'],
  argTypes: {
    variant: {
      control: 'select',
      options: ['primary', 'secondary', 'outline', 'ghost'],
    },
    size: {
      control: 'select',
      options: ['sm', 'md', 'lg'],
    },
  },
};

export default meta;
type Story = StoryObj<typeof Button>;

export const Primary: Story = {
  args: {
    children: 'Button',
    variant: 'primary',
  },
};

export const WithIcon: Story = {
  args: {
    children: 'Button',
    icon: <ArrowRight />,
  },
};

export const Loading: Story = {
  args: {
    children: 'Button',
    loading: true,
  },
};

Governança

Versionamento Semântico

  • Major (1.0.0): Breaking changes
  • Minor (0.1.0): Novos features backwards compatible
  • Patch (0.0.1): Bug fixes

Contribution Guidelines

## Como Contribuir

### Adicionando um Componente

1. Crie o componente em `src/components/`
2. Adicione testes em `__tests__/`
3. Crie stories no Storybook
4. Atualize a documentação
5. Abra um PR com o template apropriado

### Padrões de Código

- TypeScript strict mode
- Acessibilidade WCAG 2.1 AA
- Cobertura de testes > 80%
- Suporte a temas (light/dark)

Distribuição

NPM Package

{
  "name": "@company/design-system",
  "version": "1.0.0",
  "main": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": "./dist/index.js",
    "./styles": "./dist/styles.css"
  },
  "peerDependencies": {
    "react": "^18.0.0",
    "react-dom": "^18.0.0"
  }
}

Tree Shaking

Garanta que componentes não usados não sejam incluídos no bundle:

// index.ts
export { Button } from './Button';
export { Input } from './Input';
export { Card } from './Card';
// ...

// Uso (apenas Button será incluído no bundle)
import { Button } from '@company/design-system';

Manutenção e Evolução

Métricas de Adoção

  • Quantos projetos usam o DS?
  • Quais componentes são mais usados?
  • Onde ainda há inconsistências?

Feedback Loop

  • Reuniões mensais com stakeholders
  • Canal dedicado no Slack/Teams
  • Office hours para dúvidas
  • RFCs para grandes mudanças

Cases de Sucesso

Mindra Design System

Criamos um design system completo para a plataforma Mindra:

  • 50+ componentes reutilizáveis
  • 3 temas (light, dark, high contrast)
  • Redução de 60% no tempo de desenvolvimento
  • Consistência em 5 produtos diferentes

Conclusão

Um Design System bem implementado é um dos melhores investimentos que uma empresa pode fazer. Ele acelera desenvolvimento, garante consistência e melhora a qualidade dos produtos.

Quer criar um Design System para sua empresa? A Inteligencialy tem expertise em construir sistemas escaláveis e bem documentados. Entre em contato!

Tags

Design SystemUI/UXFrontendComponentes