npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@nti_ses/ui-components

v1.6.5

Published

Biblioteca de componentes React TypeScript para projetos da NTI

Readme

@nti_ses/ui-components

Biblioteca completa de componentes React TypeScript para projetos da NTI com suporte a FontAwesome e fontes customizadas (Outfit, Inter, Gibralt).

NPM Version NPM Downloads License: MIT

Instalação

npm install @nti_ses/ui-components

Dependências necessárias (FontAwesome):

npm install @fortawesome/fontawesome-svg-core @fortawesome/free-solid-svg-icons @fortawesome/free-regular-svg-icons @fortawesome/react-fontawesome

Sistema de Design

Fontes Customizadas

  • Outfit - Família display para títulos e elementos principais
  • Inter - Família body para texto de interface e conteúdo
  • Gibralt - Família accent para elementos especiais e destaques

Variáveis CSS Customizáveis

:root {
  /* Fontes */
  --font-family-display: 'Outfit', sans-serif;
  --font-family-body: 'Inter', sans-serif;
  --font-family-accent: 'Gibralt', sans-serif;
  
  /* Cores Principais */
  --nti-color-primary: #0066cc;
  --nti-color-secondary: #64748b;
  --nti-color-success: #10b981;
  --nti-color-warning: #f59e0b;
  --nti-color-danger: #ef4444;
  --nti-color-info: #3b82f6;
  
  /* Espaçamentos */
  --spacing-xs: 4px;
  --spacing-sm: 8px;
  --spacing-md: 12px;
  --spacing-lg: 16px;
  --spacing-xl: 20px;
  --spacing-2xl: 24px;
  
  /* Bordas */
  --border-radius-sm: 0.25rem;
  --border-radius-md: 0.375rem;
  --border-radius-lg: 0.5rem;
  --border-radius-xl: 0.75rem;
  
  /* Sombras */
  --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
  --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
  --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
  --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
}

Componentes Disponíveis

1. Button - Botão Avançado

Botão versátil com múltiplas variantes, ícones, estados de loading e funcionalidades especiais.

Variantes e Tamanhos

import { Button } from '@nti_ses/ui-components';
import { faHome, faUser, faHeart } from '@fortawesome/free-solid-svg-icons';

// Variantes
<Button variant="primary">Primário</Button>
<Button variant="secondary">Secundário</Button>
<Button variant="danger">Perigo</Button>
<Button variant="ghost">Fantasma</Button>

// Tamanhos
<Button size="small">Pequeno</Button>
<Button size="medium">Médio</Button>
<Button size="large">Grande</Button>

// Com ícones
<Button icon={faHome} iconSide="Left">Casa</Button>
<Button icon={faUser} iconSide="Right">Usuário</Button>

// Estados especiais
<Button loading>Carregando...</Button>
<Button disabled>Desabilitado</Button>

// Tipos de botão
<Button type="submit">Enviar</Button>
<Button type="reset">Resetar</Button>
<Button type="button">Botão</Button>

Props Completas

  • variant: 'primary' | 'secondary' | 'danger' | 'ghost'
  • size: 'small' | 'medium' | 'large'
  • icon: FontAwesome IconDefinition
  • iconSide: 'Left' | 'Right'
  • loading: boolean - exibe spinner de carregamento
  • disabled: boolean
  • type: 'button' | 'submit' | 'reset'
  • onClick: (event: React.MouseEvent) => void
  • className: string

2. Card - Sistema Completo de Cartões

Sistema flexível de cartões com múltiplas variantes e subcomponentes especializados.

Variantes Principais

import { 
  Card, CardIcon, CardHeader, CardTitle, CardSubtitle, CardContent, 
  CardFooter, CardAction, CardStatus 
} from '@nti_ses/ui-components';
import { faRocket, faCheck, faWarning, faInfo } from '@fortawesome/free-solid-svg-icons';

// Variantes básicas
<Card variant="default">Card padrão</Card>
<Card variant="outlined">Card com borda</Card>
<Card variant="elevated">Card elevado</Card>
<Card variant="filled">Card preenchido</Card>
<Card variant="gradient">Card com gradiente</Card>

// Variantes especiais
<Card variant="header-colored" headerColor="primary" headerHeight={6}>
  Card com header colorido
</Card>

<Card variant="dashed" dashedColor="warning" dashedWidth="thick">
  Card com borda pontilhada
</Card>

// Variante Feature com ícone destacado (novo!)
<Card variant="feature" size="medium" hover>
  <CardHeader>
    <CardIcon icon={faRocket} variant="primary" />
    <CardTitle>Feature Card</CardTitle>
    <CardSubtitle>Card moderno com ícone destacado</CardSubtitle>
  </CardHeader>
  <CardFooter>
    <CardAction variant="primary">Explorar</CardAction>
  </CardFooter>
</Card>

// Tamanhos e modificadores
<Card size="small" hover shadow>Card pequeno interativo</Card>
<Card size="medium" padding={false}>Card médio sem padding</Card>
<Card size="large" onClick={() => alert('Clicado!')}>Card grande clicável</Card>

Subcomponentes Completos

<Card variant="outlined" hover shadow>
  {/* Header com ícone */}
  <CardHeader icon={faUser} iconPosition="left">
    <CardTitle icon={faHeart} iconPosition="right">
      Perfil do Usuário
    </CardTitle>
    <CardSubtitle>Informações pessoais</CardSubtitle>
  </CardHeader>
  
  {/* Conteúdo principal */}
  <CardContent>
    <p>Conteúdo detalhado do card com informações relevantes.</p>
    
    {/* Status indicators */}
    <CardStatus variant="success" icon={faCheck}>
      Verificado
    </CardStatus>
    <CardStatus variant="warning">
      Pendente
    </CardStatus>
    <CardStatus variant="error">
      Erro
    </CardStatus>
    <CardStatus variant="info">
      Informação
    </CardStatus>
  </CardContent>
  
  {/* Footer com ações */}
  <CardFooter>
    <CardAction 
      variant="primary" 
      size="medium"
      icon={faEdit}
      iconPosition="left"
      onClick={() => console.log('Editar')}
    >
      Editar
    </CardAction>
    
    <CardAction 
      variant="ghost" 
      href="/profile"
      target="_blank"
    >
      Ver Perfil
    </CardAction>
  </CardFooter>
</Card>

Props Avançadas do Card

Propriedades Base:

  • variant: 'default' | 'outlined' | 'elevated' | 'filled' | 'gradient' | 'header-colored' | 'dashed' | 'feature'
  • size: 'small' | 'medium' | 'large'
  • hover: boolean - efeito hover
  • shadow: boolean - sombra do card
  • padding: boolean - padding interno
  • onClick: (event: MouseEvent) => void

Customizações de Borda:

  • borderColor: 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info' | 'gray' | string (hex, rgb, rgba)
  • borderWidth: 'thin' (1px) | 'normal' (2px) | 'thick' (3px) | number (pixels)
  • borderRadius: number - raio das bordas em pixels

Customizações de Sombra:

  • shadowColor: string - cor da sombra (rgba, hex, etc)
  • shadowIntensity: number - intensidade da sombra (0-100, padrão: 100)

Customizações de Fundo:

  • backgroundColor: string - cor de fundo customizada

Variantes Especiais:

  • headerColor: string | cores predefinidas ('primary', 'secondary', 'success', 'warning', 'danger', 'info')
  • headerHeight: number - altura do header em pixels
  • dashedColor: string | cores predefinidas
  • dashedWidth: 'thin' | 'normal' | 'thick' | number

Exemplos de Customizações Avançadas

Card Feature com Borda Colorida:

<Card 
  variant="feature" 
  hover 
  borderColor="primary" 
  borderWidth="thick"
  size="medium"
>
  <CardHeader>
    <CardIcon icon={faRocket} variant="primary" />
    <CardTitle>Seu Título</CardTitle>
    <CardSubtitle>Descrição</CardSubtitle>
  </CardHeader>
  <CardFooter>
    <CardAction variant="primary">Ação</CardAction>
  </CardFooter>
</Card>

Card com Design Customizado Completo:

<Card 
  variant="default"
  hover
  borderColor="#8b5cf6"
  borderWidth={2}
  borderRadius={12}
  backgroundColor="#faf5ff"
  shadow
  shadowColor="rgba(139, 92, 246, 0.2)"
>
  <CardTitle>Design Premium</CardTitle>
  <CardContent>Totalmente customizável</CardContent>
</Card>

Card com Paleta de Cores Harmônica:

<Card
  variant="feature"
  borderColor="success"
  borderWidth={2}
  borderRadius={12}
  backgroundColor="#f0fdf4"
  hover
>
  <CardHeader>
    <CardIcon icon={faCheck} variant="success" />
    <CardTitle>Sucesso</CardTitle>
  </CardHeader>
</Card>

CardIcon - Ícone Destacado para Feature Cards:

import { CardIcon } from '@nti_ses/ui-components';
import { faDatabase } from '@fortawesome/free-solid-svg-icons';

// Usando cores predefinidas
<CardIcon icon={faDatabase} variant="primary" />

// Usando cores customizadas
<CardIcon 
  icon={faDatabase} 
  backgroundColor="#8b5cf6" 
  iconColor="#ffffff"
/>

3. Dropdown - Menu Dropdown Avançado

Menu dropdown com múltiplos triggers, posicionamento inteligente e tipos de item.

Configurações de Trigger e Posicionamento

import { Dropdown } from '@nti_ses/ui-components';

const menuItems = [
  { key: '1', label: 'Editar', icon: faEdit, onClick: () => console.log('Edit') },
  { key: '2', label: 'Compartilhar', description: 'Enviar para outros usuários' },
  { key: '3', type: 'divider' },
  { key: '4', type: 'header', label: 'Ações Perigosas' },
  { key: '5', label: 'Excluir', danger: true, disabled: false },
];

// Diferentes triggers
<Dropdown items={menuItems} trigger="click">Click</Dropdown>
<Dropdown items={menuItems} trigger="hover">Hover</Dropdown>
<Dropdown items={menuItems} trigger="contextMenu">Right Click</Dropdown>
<Dropdown items={menuItems} trigger={['click', 'hover']}>Múltiplos</Dropdown>

// Posicionamentos
<Dropdown items={menuItems} placement="bottom-start">Bottom Start</Dropdown>
<Dropdown items={menuItems} placement="bottom-end">Bottom End</Dropdown>
<Dropdown items={menuItems} placement="top-start">Top Start</Dropdown>
<Dropdown items={menuItems} placement="top-end">Top End</Dropdown>
<Dropdown items={menuItems} placement="left">Left</Dropdown>
<Dropdown items={menuItems} placement="right">Right</Dropdown>

Configurações Avançadas

<Dropdown
  items={menuItems}
  trigger="click"
  placement="bottom-start"
  
  // Aparência
  arrow={true}
  maxHeight={300}
  minWidth={200}
  
  // Comportamento
  closeOnSelect={true}
  closeOnClickOutside={true}
  closeOnEscape={true}
  
  // Estado controlado
  open={isOpen}
  defaultOpen={false}
  onOpenChange={setIsOpen}
  onSelect={(item) => console.log('Selected:', item)}
  
  // Classes customizáveis
  className="custom-trigger"
  dropdownClassName="custom-dropdown"
  itemClassName="custom-item"
>
  <Button>Menu Avançado</Button>
</Dropdown>

4. Footer - Rodapé Completo

Rodapé flexível com suporte a logos, links, copyright e diferentes estilos visuais.

Configurações Visuais

import { Footer } from '@nti_ses/ui-components';

const logos = [
  { 
    key: '1', 
    image: '/partner1.png', 
    alt: 'Parceiro 1', 
    href: 'https://partner1.com',
    target: '_blank'
  },
  { 
    key: '2', 
    text: 'Parceiro 2', 
    href: 'https://partner2.com' 
  }
];

const links = [
  { key: '1', label: 'Privacidade', href: '/privacy', icon: faShield },
  { key: '2', label: 'Termos', href: '/terms' },
  { key: '3', label: 'Suporte', href: '/support', target: '_blank' },
  { key: '4', label: 'API', href: '/api-docs' }
];

// Diferentes estilos
<Footer
  logos={logos}
  links={links}
  copyright="© 2024 NTI SES. Todos os direitos reservados."
  backgroundColor="white"
  textColor="dark"
/>

<Footer
  logos={logos}
  links={links}
  copyright="© 2024 NTI SES. Todos os direitos reservados."
  backgroundColor="dark"
  textColor="light"
/>

<Footer
  logos={logos}
  links={links}
  copyright="© 2024 NTI SES. Todos os direitos reservados."
  backgroundColor="primary"
  textColor="light"
/>

5. Header - Cabeçalho de Navegação

Cabeçalho responsivo com logo, navegação, botão de ação e menu mobile.

Configurações Completas

import { Header } from '@nti_ses/ui-components';

const logo = {
  text: 'Sistema NTI',
  icon: faBuilding, // Opcional
  image: '/logo.png', // Opcional
  href: '/dashboard'
};

const navigation = [
  { 
    key: 'dashboard', 
    label: 'Dashboard', 
    icon: faTachometerAlt,
    href: '/dashboard', 
    active: true 
  },
  { 
    key: 'users', 
    label: 'Usuários', 
    href: '/users',
    disabled: false
  },
  { 
    key: 'reports', 
    label: 'Relatórios', 
    icon: faChartBar,
    href: '/reports' 
  }
];

const actionButton = {
  label: 'Login',
  icon: faUser,
  variant: 'primary', // 'primary' | 'secondary' | 'ghost'
  disabled: false
};

// Variantes
<Header
  logo={logo}
  navigation={navigation}
  actionButton={actionButton}
  variant="default" // 'default' | 'transparent'
  sticky={true}
  showMobileMenu={true}
  
  // Callbacks
  onNavigationClick={(item) => console.log('Nav:', item)}
  onActionClick={() => console.log('Action clicked')}
  onLogoClick={() => console.log('Logo clicked')}
/>

6. Input - Campo de Input Avançado

Input com múltiplas funcionalidades, validação, ícones e estados especiais.

Tipos e Variantes

import { Input } from '@nti_ses/ui-components';
import { faUser, faEnvelope, faLock, faSearch, faPhone } from '@fortawesome/free-solid-svg-icons';

// Tipos diferentes
<Input type="text" label="Nome" placeholder="Digite seu nome" />
<Input type="email" label="Email" placeholder="[email protected]" />
<Input type="password" label="Senha" showPassword />
<Input type="number" label="Idade" placeholder="25" />
<Input type="tel" label="Telefone" placeholder="(11) 99999-9999" />
<Input type="url" label="Website" placeholder="https://..." />
<Input type="search" label="Buscar" placeholder="Pesquisar..." />
<Input type="date" label="Data de Nascimento" />
<Input type="time" label="Horário" />
<Input type="datetime-local" label="Data e Hora" />

// Variantes visuais
<Input variant="default" label="Padrão" />
<Input variant="filled" label="Preenchido" />
<Input variant="outlined" label="Com Borda" />
<Input variant="ghost" label="Fantasma" />

// Tamanhos
<Input size="small" label="Pequeno" />
<Input size="medium" label="Médio" />
<Input size="large" label="Grande" />

Funcionalidades Avançadas

// Com ícones
<Input 
  label="Usuário"
  leftIcon={faUser}
  placeholder="Nome de usuário"
  clearable
/>

<Input 
  label="Buscar"
  leftIcon={faSearch}
  rightIcon={faFilter}
  onIconClick={(position) => console.log('Icon clicked:', position)}
/>

// Com addons (texto adicional)
<Input 
  label="Website"
  leftAddon="https://"
  rightAddon=".com"
  placeholder="meusite"
/>

<Input 
  label="Preço"
  leftAddon="R$"
  type="number"
  placeholder="0,00"
/>

// Estados de validação
<Input 
  label="Email"
  type="email"
  error="Email é obrigatório"
  required
/>

<Input 
  label="Senha"
  type="password"
  success="Senha forte!"
  showPassword
/>

<Input 
  label="Confirmação"
  warning="Senhas não coincidem"
/>

// Funcionalidades especiais
<Input 
  label="Biografia"
  maxLength={200}
  counter // Mostra contador de caracteres
  helperText="Descreva brevemente sobre você"
/>

<Input 
  label="Carregando dados..."
  loading
  disabled
/>

<Input 
  label="Campo limpo"
  clearable
  onClear={() => console.log('Campo limpo!')}
/>

7. Pagination - Paginação Completa

Componente completo de paginação com navegação, informações e configurações flexíveis.

Configurações Básicas

import { Pagination } from '@nti_ses/ui-components';

// Configuração básica
<Pagination
  currentPage={1}
  totalPages={10}
  onPageChange={(page) => console.log('Page:', page)}
/>

// Com informações dos dados
<Pagination
  currentPage={2}
  totalPages={20}
  totalItems={500}
  pageSize={25}
  onPageChange={(page) => console.log('Page:', page)}
  showInfo={true}
/>

// Com seletor de itens por página
<Pagination
  currentPage={1}
  totalPages={15}
  totalItems={300}
  pageSize={20}
  itemsPerPageOptions={[10, 20, 50, 100]}
  onPageChange={(page) => console.log('Page:', page)}
  onPageSizeChange={(size) => console.log('Page size:', size)}
  showInfo={true}
/>

Configurações Avançadas

<Pagination
  currentPage={5}
  totalPages={100}
  totalItems={2000}
  pageSize={20}
  
  // Controles de visualização
  showFirstLast={true}
  showPrevNext={true}
  showNumbers={true}
  showInfo={true}
  showJumper={true} // Campo para pular para página específica
  
  // Comportamento
  siblingCount={2} // Páginas ao lado da atual
  boundaryCount={1} // Páginas no início e fim
  
  // Estilo
  size="medium" // 'small' | 'medium' | 'large'
  variant="default" // 'default' | 'outlined' | 'minimal'
  disabled={false}
  
  // Labels customizáveis
  labels={{
    first: 'Primeira',
    previous: 'Anterior',
    next: 'Próxima',
    last: 'Última',
    page: 'Página',
    of: 'de',
    items: 'itens',
    showing: 'Mostrando',
    to: 'até',
    jumpTo: 'Ir para',
    itemsPerPage: 'itens por página'
  }}
  
  onPageChange={(page) => console.log('Page:', page)}
  onPageSizeChange={(size) => console.log('Page size:', size)}
/>

8. Select - Seleção Avançada

Select com busca, seleção múltipla, agrupamento e funcionalidades avançadas.

Configurações Básicas

import { Select } from '@nti_ses/ui-components';

const basicOptions = [
  { value: '1', label: 'Opção 1' },
  { value: '2', label: 'Opção 2' },
  { value: '3', label: 'Opção 3', disabled: true },
];

// Select básico
<Select
  label="Selecione uma opção"
  options={basicOptions}
  placeholder="Escolha..."
  onChange={(value) => console.log(value)}
/>

// Select múltiplo
<Select
  label="Seleção múltipla"
  options={basicOptions}
  multiple={true}
  maxSelectedDisplay={2}
  onChange={(values) => console.log(values)}
/>

Funcionalidades Avançadas

const advancedOptions = [
  { 
    value: '1', 
    label: 'Usuário Admin', 
    description: 'Acesso total ao sistema',
    icon: faUserShield,
    group: 'Administradores'
  },
  { 
    value: '2', 
    label: 'Usuário Editor', 
    description: 'Pode editar conteúdo',
    icon: faUserEdit,
    group: 'Editores'
  },
  { 
    value: '3', 
    label: 'Usuário Visualizador', 
    description: 'Apenas visualização',
    icon: faUserCheck,
    group: 'Visualizadores'
  }
];

<Select
  label="Tipo de Usuário"
  options={advancedOptions}
  
  // Funcionalidades
  searchable={true}
  clearable={true}
  multiple={false}
  
  // Aparência
  leftIcon={faUsers}
  variant="outlined" // 'default' | 'filled' | 'outlined' | 'ghost'
  size="medium" // 'small' | 'medium' | 'large'
  
  // Comportamento
  maxHeight={250}
  
  // Textos customizáveis
  placeholder="Selecione o tipo de usuário..."
  searchPlaceholder="Buscar tipos..."
  noOptionsText="Nenhum tipo encontrado"
  loadingText="Carregando tipos..."
  
  // Estados
  loading={false}
  disabled={false}
  error="Campo obrigatório"
  // success="Seleção válida"
  // warning="Atenção na seleção"
  
  // Callbacks
  onChange={(value) => console.log('Selected:', value)}
  onSearch={(term) => console.log('Search:', term)}
  onOpen={() => console.log('Opened')}
  onClose={() => console.log('Closed')}
  
  helperText="Selecione o nível de acesso apropriado"
/>

9. Typography - Sistema de Tipografia

Sistema completo de tipografia com 3 fontes customizadas e múltiplas variações.

Hierarquia de Títulos

import { Typography } from '@nti_ses/ui-components';

// Hierarquia completa
<Typography variant="display" family="display" weight="bold">
  Display Title
</Typography>

<Typography variant="h1" family="display" weight="semibold">
  Título Principal (H1)
</Typography>

<Typography variant="h2" family="display" weight="medium">
  Título Secundário (H2)
</Typography>

<Typography variant="h3" family="display">
  Título Terciário (H3)
</Typography>

<Typography variant="h4">
  Título Quaternário (H4)
</Typography>

<Typography variant="h5">
  Título Quinário (H5)
</Typography>

<Typography variant="h6">
  Título Sênario (H6)
</Typography>

Texto de Corpo e Especiais

// Texto de corpo
<Typography variant="body1" family="body">
  Texto principal do corpo usando Inter. Lorem ipsum dolor sit amet.
</Typography>

<Typography variant="body2" family="body" color="muted">
  Texto secundário menor com cor mais suave.
</Typography>

// Textos especiais
<Typography variant="caption" size="sm" color="muted">
  Legenda ou texto explicativo pequeno
</Typography>

<Typography variant="overline" weight="medium" color="secondary">
  TEXTO SOBRELINHADO PARA CATEGORIAS
</Typography>

<Typography variant="accent" family="accent" weight="bold" color="primary">
  Texto de destaque com fonte Gibralt
</Typography>

Combinações de Propriedades

// Famílias de fonte
<Typography family="display">Outfit para títulos e display</Typography>
<Typography family="body">Inter para corpo e interface</Typography>
<Typography family="accent">Gibralt para acentos especiais</Typography>

// Pesos de fonte
<Typography weight="light">Texto leve</Typography>
<Typography weight="normal">Texto normal</Typography>
<Typography weight="medium">Texto médio</Typography>
<Typography weight="semibold">Texto semi-negrito</Typography>
<Typography weight="bold">Texto negrito</Typography>
<Typography weight="extrabold">Texto extra-negrito</Typography>

// Tamanhos customizados
<Typography size="xs">Texto extra pequeno</Typography>
<Typography size="sm">Texto pequeno</Typography>
<Typography size="md">Texto médio</Typography>
<Typography size="lg">Texto grande</Typography>
<Typography size="xl">Texto extra grande</Typography>
<Typography size="2xl">Texto 2x grande</Typography>
<Typography size="3xl">Texto 3x grande</Typography>
<Typography size="4xl">Texto 4x grande</Typography>
<Typography size="5xl">Texto 5x grande</Typography>

// Cores semânticas
<Typography color="primary">Cor primária</Typography>
<Typography color="secondary">Cor secundária</Typography>
<Typography color="muted">Cor suavizada</Typography>
<Typography color="inverse">Cor inversa</Typography>
<Typography color="inherit">Cor herdada</Typography>

// Alinhamentos
<Typography align="left">Alinhado à esquerda</Typography>
<Typography align="center">Centralizado</Typography>
<Typography align="right">Alinhado à direita</Typography>
<Typography align="justify">Justificado</Typography>

// Componente customizado
<Typography 
  variant="h2" 
  component="span" 
  family="accent" 
  weight="bold" 
  color="primary"
>
  Título renderizado como span
</Typography>

Exemplos Práticos Completos

Dashboard Administrativo

import React, { useState } from 'react';
import {
  Header, Footer, Card, CardHeader, CardTitle, CardContent, CardFooter, CardAction,
  Typography, Pagination, Select, Input, Button, Dropdown
} from '@nti_ses/ui-components';
import {
  faUser, faChartBar, faCog, faSearch, faFilter, faEllipsisV,
  faEdit, faTrash, faEye, faPlus
} from '@fortawesome/free-solid-svg-icons';

function AdminDashboard() {
  const [currentPage, setCurrentPage] = useState(1);
  const [pageSize, setPageSize] = useState(10);
  const [filterStatus, setFilterStatus] = useState('all');
  
  const navigationItems = [
    { key: 'dashboard', label: 'Dashboard', icon: faChartBar, href: '/dashboard', active: true },
    { key: 'users', label: 'Usuários', icon: faUser, href: '/users' },
    { key: 'settings', label: 'Configurações', icon: faCog, href: '/settings' },
  ];

  const statusOptions = [
    { value: 'all', label: 'Todos os Status' },
    { value: 'active', label: 'Ativos' },
    { value: 'inactive', label: 'Inativos' },
    { value: 'pending', label: 'Pendentes' },
  ];

  const actionMenuItems = [
    { key: 'view', label: 'Visualizar', icon: faEye },
    { key: 'edit', label: 'Editar', icon: faEdit },
    { key: 'divider', type: 'divider' },
    { key: 'delete', label: 'Excluir', icon: faTrash, danger: true },
  ];

  return (
    <div className="min-h-screen flex flex-col bg-gray-50">
      <Header
        logo={{ text: 'Admin Panel', icon: faCog }}
        navigation={navigationItems}
        actionButton={{ label: 'Perfil', variant: 'ghost', icon: faUser }}
        sticky
        variant="default"
      />
      
      <main className="flex-1 container mx-auto p-6">
        {/* Header da página */}
        <div className="mb-8">
          <Typography variant="h1" family="display" weight="bold" className="mb-2">
            Dashboard Administrativo
          </Typography>
          <Typography variant="body1" color="muted">
            Gerencie usuários, monitore atividades e configure o sistema
          </Typography>
        </div>
        
        {/* Cards de métricas */}
        <div className="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8">
          <Card variant="filled" hover className="bg-blue-50">
            <CardContent className="text-center p-6">
              <Typography variant="h2" family="display" color="primary" weight="bold" className="mb-2">
                1,234
              </Typography>
              <Typography variant="body2" color="muted">
                Usuários Totais
              </Typography>
            </CardContent>
          </Card>
          
          <Card variant="filled" hover className="bg-green-50">
            <CardContent className="text-center p-6">
              <Typography variant="h2" family="display" weight="bold" className="mb-2 text-green-600">
                987
              </Typography>
              <Typography variant="body2" color="muted">
                Usuários Ativos
              </Typography>
            </CardContent>
          </Card>
          
          <Card variant="filled" hover className="bg-orange-50">
            <CardContent className="text-center p-6">
              <Typography variant="h2" family="display" weight="bold" className="mb-2 text-orange-600">
                45
              </Typography>
              <Typography variant="body2" color="muted">
                Pendentes
              </Typography>
            </CardContent>
          </Card>
          
          <Card variant="filled" hover className="bg-purple-50">
            <CardContent className="text-center p-6">
              <Typography variant="h2" family="display" weight="bold" className="mb-2 text-purple-600">
                89%
              </Typography>
              <Typography variant="body2" color="muted">
                Taxa de Ativação
              </Typography>
            </CardContent>
          </Card>
        </div>

        {/* Seção de gerenciamento */}
        <Card variant="outlined" className="mb-6">
          <CardHeader>
            <CardTitle icon={faUser} iconPosition="left">
              Gerenciamento de Usuários
            </CardTitle>
          </CardHeader>
          <CardContent>
            {/* Filtros e ações */}
            <div className="flex flex-wrap gap-4 mb-6">
              <Input
                leftIcon={faSearch}
                placeholder="Buscar usuários..."
                clearable
                className="flex-1 min-w-64"
              />
              
              <Select
                options={statusOptions}
                value={filterStatus}
                onChange={setFilterStatus}
                leftIcon={faFilter}
                placeholder="Filtrar status"
                className="w-48"
              />
              
              <Button variant="primary" icon={faPlus} iconSide="Left">
                Novo Usuário
              </Button>
              
              <Dropdown
                items={actionMenuItems}
                placement="bottom-end"
                onSelect={(item) => console.log('Bulk action:', item)}
              >
                <Button variant="ghost" icon={faEllipsisV} />
              </Dropdown>
            </div>
            
            {/* Lista de usuários */}
            <div className="space-y-3">
              {[1, 2, 3, 4, 5].map((item) => (
                <Card key={item} variant="outlined" hover className="p-4">
                  <div className="flex items-center justify-between">
                    <div className="flex items-center space-x-4">
                      <div className="w-10 h-10 bg-gray-200 rounded-full flex items-center justify-center">
                        <Typography weight="medium">U{item}</Typography>
                      </div>
                      <div>
                        <Typography variant="body1" weight="medium">
                          Usuário {item}
                        </Typography>
                        <Typography variant="body2" color="muted">
                          usuario{item}@empresa.com
                        </Typography>
                      </div>
                    </div>
                    
                    <div className="flex items-center gap-3">
                      <span className={`px-3 py-1 rounded-full text-sm font-medium ${
                        item % 2 === 0 
                          ? 'bg-green-100 text-green-800' 
                          : 'bg-yellow-100 text-yellow-800'
                      }`}>
                        {item % 2 === 0 ? 'Ativo' : 'Pendente'}
                      </span>
                      
                      <Typography variant="caption" color="muted">
                        Último acesso: há {item} dia{item > 1 ? 's' : ''}
                      </Typography>
                      
                      <Dropdown
                        items={actionMenuItems}
                        placement="bottom-end"
                        onSelect={(action) => console.log('User action:', action, 'for user', item)}
                      >
                        <Button variant="ghost" size="small" icon={faEllipsisV} />
                      </Dropdown>
                    </div>
                  </div>
                </Card>
              ))}
            </div>
            
            {/* Paginação */}
            <div className="mt-6">
              <Pagination
                currentPage={currentPage}
                totalPages={25}
                totalItems={250}
                pageSize={pageSize}
                itemsPerPageOptions={[10, 25, 50, 100]}
                showInfo={true}
                showJumper={true}
                onPageChange={setCurrentPage}
                onPageSizeChange={setPageSize}
                labels={{
                  showing: 'Mostrando',
                  to: 'até',
                  of: 'de',
                  items: 'usuários',
                  itemsPerPage: 'por página'
                }}
              />
            </div>
          </CardContent>
        </Card>
      </main>
      
      <Footer
        links={[
          { key: 'docs', label: 'Documentação', href: '/docs' },
          { key: 'api', label: 'API', href: '/api' },
          { key: 'support', label: 'Suporte', href: '/support' },
        ]}
        copyright="© 2024 NTI SES. Todos os direitos reservados."
        backgroundColor="white"
        textColor="dark"
      />
    </div>
  );
}

Formulário de Cadastro Avançado

import React, { useState } from 'react';
import {
  Card, CardHeader, CardTitle, CardContent, CardFooter,
  Input, Select, Button, Typography
} from '@nti_ses/ui-components';
import {
  faUser, faEnvelope, faLock, faPhone, faMapMarkerAlt,
  faBuilding, faCalendarAlt, faEye
} from '@fortawesome/free-solid-svg-icons';

function AdvancedRegistrationForm() {
  const [formData, setFormData] = useState({
    firstName: '',
    lastName: '',
    email: '',
    password: '',
    confirmPassword: '',
    phone: '',
    birthDate: '',
    address: '',
    company: '',
    role: '',
    department: ''
  });

  const [errors, setErrors] = useState({});
  const [loading, setLoading] = useState(false);

  const roleOptions = [
    { value: 'admin', label: 'Administrador', description: 'Acesso total ao sistema' },
    { value: 'manager', label: 'Gerente', description: 'Gerenciamento de equipe' },
    { value: 'employee', label: 'Funcionário', description: 'Acesso básico' },
    { value: 'intern', label: 'Estagiário', description: 'Acesso limitado' }
  ];

  const departmentOptions = [
    { value: 'it', label: 'Tecnologia da Informação', group: 'Técnico' },
    { value: 'dev', label: 'Desenvolvimento', group: 'Técnico' },
    { value: 'design', label: 'Design', group: 'Criativo' },
    { value: 'marketing', label: 'Marketing', group: 'Criativo' },
    { value: 'sales', label: 'Vendas', group: 'Comercial' },
    { value: 'support', label: 'Suporte', group: 'Comercial' },
    { value: 'hr', label: 'Recursos Humanos', group: 'Administrativo' },
    { value: 'finance', label: 'Financeiro', group: 'Administrativo' }
  ];

  const handleSubmit = async (e) => {
    e.preventDefault();
    setLoading(true);
    
    // Simular envio
    setTimeout(() => {
      setLoading(false);
      console.log('Form submitted:', formData);
    }, 2000);
  };

  return (
    <div className="min-h-screen bg-gray-50 py-12">
      <div className="container mx-auto px-4">
        <div className="max-w-2xl mx-auto">
          <div className="text-center mb-8">
            <Typography variant="h1" family="display" weight="bold" className="mb-4">
              Cadastro de Usuário
            </Typography>
            <Typography variant="body1" color="muted">
              Preencha as informações abaixo para criar sua conta
            </Typography>
          </div>

          <Card variant="outlined" shadow>
            <CardHeader>
              <CardTitle icon={faUser} iconPosition="left">
                Informações Pessoais
              </CardTitle>
            </CardHeader>
            
            <CardContent>
              <form onSubmit={handleSubmit} className="space-y-6">
                {/* Nome */}
                <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                  <Input
                    label="Nome"
                    leftIcon={faUser}
                    placeholder="João"
                    required
                    error={errors.firstName}
                    value={formData.firstName}
                    onChange={(e) => setFormData({...formData, firstName: e.target.value})}
                  />
                  
                  <Input
                    label="Sobrenome"
                    placeholder="Silva"
                    required
                    error={errors.lastName}
                    value={formData.lastName}
                    onChange={(e) => setFormData({...formData, lastName: e.target.value})}
                  />
                </div>

                {/* Email e Telefone */}
                <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                  <Input
                    label="Email"
                    type="email"
                    leftIcon={faEnvelope}
                    placeholder="[email protected]"
                    required
                    error={errors.email}
                    value={formData.email}
                    onChange={(e) => setFormData({...formData, email: e.target.value})}
                    helperText="Será usado para login"
                  />
                  
                  <Input
                    label="Telefone"
                    type="tel"
                    leftIcon={faPhone}
                    placeholder="(11) 99999-9999"
                    value={formData.phone}
                    onChange={(e) => setFormData({...formData, phone: e.target.value})}
                  />
                </div>

                {/* Senhas */}
                <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                  <Input
                    label="Senha"
                    type="password"
                    leftIcon={faLock}
                    showPassword
                    required
                    error={errors.password}
                    value={formData.password}
                    onChange={(e) => setFormData({...formData, password: e.target.value})}
                    helperText="Mínimo 8 caracteres"
                  />
                  
                  <Input
                    label="Confirmar Senha"
                    type="password"
                    leftIcon={faLock}
                    showPassword
                    required
                    error={errors.confirmPassword}
                    value={formData.confirmPassword}
                    onChange={(e) => setFormData({...formData, confirmPassword: e.target.value})}
                  />
                </div>

                {/* Data de nascimento e Endereço */}
                <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                  <Input
                    label="Data de Nascimento"
                    type="date"
                    leftIcon={faCalendarAlt}
                    value={formData.birthDate}
                    onChange={(e) => setFormData({...formData, birthDate: e.target.value})}
                  />
                  
                  <Input
                    label="Endereço"
                    leftIcon={faMapMarkerAlt}
                    placeholder="Rua, número, bairro"
                    value={formData.address}
                    onChange={(e) => setFormData({...formData, address: e.target.value})}
                  />
                </div>

                {/* Informações profissionais */}
                <div className="border-t pt-6">
                  <Typography variant="h3" weight="medium" className="mb-4">
                    Informações Profissionais
                  </Typography>
                  
                  <div className="space-y-4">
                    <Input
                      label="Empresa"
                      leftIcon={faBuilding}
                      placeholder="Nome da empresa"
                      value={formData.company}
                      onChange={(e) => setFormData({...formData, company: e.target.value})}
                    />
                    
                    <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                      <Select
                        label="Cargo/Função"
                        options={roleOptions}
                        placeholder="Selecione seu cargo"
                        searchable
                        value={formData.role}
                        onChange={(value) => setFormData({...formData, role: value})}
                        error={errors.role}
                      />
                      
                      <Select
                        label="Departamento"
                        options={departmentOptions}
                        placeholder="Selecione o departamento"
                        searchable
                        value={formData.department}
                        onChange={(value) => setFormData({...formData, department: value})}
                      />
                    </div>
                  </div>
                </div>
              </form>
            </CardContent>
            
            <CardFooter className="flex justify-between">
              <Button variant="ghost">
                Cancelar
              </Button>
              
              <Button 
                variant="primary" 
                loading={loading}
                onClick={handleSubmit}
                disabled={!formData.firstName || !formData.email || !formData.password}
              >
                {loading ? 'Criando conta...' : 'Criar Conta'}
              </Button>
            </CardFooter>
          </Card>
        </div>
      </div>
    </div>
  );
}

Sistema de Comentários

import React, { useState } from 'react';
import {
  Card, CardHeader, CardTitle, CardContent, CardFooter,
  Typography, Input, Button, Dropdown
} from '@nti_ses/ui-components';
import {
  faHeart, faReply, faFlag, faEllipsisV, faThumbsUp,
  faShare, faEdit, faTrash
} from '@fortawesome/free-solid-svg-icons';

function CommentSystem() {
  const [newComment, setNewComment] = useState('');
  const [replyTo, setReplyTo] = useState(null);

  const commentActions = [
    { key: 'edit', label: 'Editar', icon: faEdit },
    { key: 'divider', type: 'divider' },
    { key: 'report', label: 'Reportar', icon: faFlag },
    { key: 'delete', label: 'Excluir', icon: faTrash, danger: true },
  ];

  const comments = [
    {
      id: 1,
      author: 'Ana Silva',
      avatar: '/avatar1.jpg',
      content: 'Excelente artigo! As informações sobre componentes React foram muito úteis.',
      timestamp: '2 horas atrás',
      likes: 12,
      replies: 3,
      liked: true
    },
    {
      id: 2,
      author: 'Carlos Santos',
      avatar: '/avatar2.jpg',
      content: 'Concordo com a Ana. Gostaria de ver mais exemplos práticos de implementação.',
      timestamp: '1 hora atrás',
      likes: 5,
      replies: 0,
      liked: false
    }
  ];

  return (
    <div className="max-w-4xl mx-auto p-6 space-y-6">
      <Typography variant="h2" family="display" weight="bold">
        Comentários ({comments.length})
      </Typography>

      {/* Novo comentário */}
      <Card variant="outlined">
        <CardContent>
          <Input
            placeholder="Deixe seu comentário..."
            value={newComment}
            onChange={(e) => setNewComment(e.target.value)}
            multiline
            rows={3}
            className="mb-4"
          />
        </CardContent>
        <CardFooter className="flex justify-between">
          <Typography variant="caption" color="muted">
            {newComment.length}/500 caracteres
          </Typography>
          <div className="space-x-2">
            <Button variant="ghost" size="small">
              Cancelar
            </Button>
            <Button 
              variant="primary" 
              size="small"
              disabled={!newComment.trim()}
            >
              Comentar
            </Button>
          </div>
        </CardFooter>
      </Card>

      {/* Lista de comentários */}
      <div className="space-y-4">
        {comments.map((comment) => (
          <Card key={comment.id} variant="outlined" hover>
            <CardContent>
              <div className="flex items-start space-x-4">
                <div className="w-10 h-10 bg-gray-200 rounded-full flex items-center justify-center">
                  <Typography variant="caption" weight="bold">
                    {comment.author.split(' ').map(n => n[0]).join('')}
                  </Typography>
                </div>
                
                <div className="flex-1">
                  <div className="flex items-center justify-between mb-2">
                    <div>
                      <Typography variant="body1" weight="medium">
                        {comment.author}
                      </Typography>
                      <Typography variant="caption" color="muted">
                        {comment.timestamp}
                      </Typography>
                    </div>
                    
                    <Dropdown
                      items={commentActions}
                      placement="bottom-end"
                      trigger="click"
                    >
                      <Button variant="ghost" size="small" icon={faEllipsisV} />
                    </Dropdown>
                  </div>
                  
                  <Typography variant="body1" className="mb-3">
                    {comment.content}
                  </Typography>
                  
                  <div className="flex items-center space-x-4">
                    <Button 
                      variant="ghost" 
                      size="small" 
                      icon={faThumbsUp}
                      className={comment.liked ? 'text-blue-600' : ''}
                    >
                      {comment.likes}
                    </Button>
                    
                    <Button 
                      variant="ghost" 
                      size="small" 
                      icon={faReply}
                      onClick={() => setReplyTo(comment.id)}
                    >
                      Responder
                    </Button>
                    
                    <Button variant="ghost" size="small" icon={faShare}>
                      Compartilhar
                    </Button>
                    
                    {comment.replies > 0 && (
                      <Typography variant="caption" color="muted">
                        {comment.replies} resposta{comment.replies > 1 ? 's' : ''}
                      </Typography>
                    )}
                  </div>
                </div>
              </div>
              
              {/* Formulário de resposta */}
              {replyTo === comment.id && (
                <div className="mt-4 ml-14 border-l-2 border-gray-200 pl-4">
                  <Input
                    placeholder={`Respondendo para ${comment.author}...`}
                    multiline
                    rows={2}
                    className="mb-3"
                  />
                  <div className="flex justify-end space-x-2">
                    <Button 
                      variant="ghost" 
                      size="small"
                      onClick={() => setReplyTo(null)}
                    >
                      Cancelar
                    </Button>
                    <Button variant="primary" size="small">
                      Responder
                    </Button>
                  </div>
                </div>
              )}
            </CardContent>
          </Card>
        ))}
      </div>
    </div>
  );
}

Guia de Acessibilidade

Navegação por Teclado

Todos os componentes suportam navegação completa por teclado:

// Exemplos de teclas suportadas
<Button>Tab para focar, Enter/Space para ativar</Button>
<Select>Arrow keys para navegar opções, Enter para selecionar</Select>
<Dropdown>Esc para fechar, Arrow keys para navegação</Dropdown>
<Pagination>Tab entre controles, Enter para navegar</Pagination>
<Input>Tab para focar, teclas normais para inserir texto</Input>

Screen Reader Support

// Exemplos com ARIA labels apropriados
<Button aria-label="Fechar modal">×</Button>
<Input aria-describedby="help-text" aria-invalid={hasError} />
<Select aria-expanded={isOpen} aria-haspopup="listbox" />
<Pagination aria-label="Navegação de páginas" />

Contraste e Cores

// Componentes seguem WCAG 2.1 AA
<Typography color="primary">Contraste 4.5:1+</Typography>
<Button variant="danger">Cores acessíveis</Button>
<Input error="Indicação clara de erro" />

Testes e Qualidade

Testes Automatizados

# Executar todos os testes
npm test

# Testes com coverage
npm run test:coverage

# Testes em modo watch
npm run test:watch

# Testes E2E
npm run test:e2e

Linting e Formatação

# ESLint
npm run lint

# Prettier
npm run format

# TypeScript check
npm run type-check

Personalização Avançada

Temas Customizados

/* Tema customizado */
.my-app {
  --nti-color-primary: #8b5cf6;
  --nti-color-secondary: #06b6d4;
  --font-family-display: 'Custom Display Font', sans-serif;
  --border-radius-md: 0.75rem;
}

Classes CSS Customizadas

// Sobrescrevendo estilos específicos
<Button className="custom-button bg-gradient-to-r from-purple-500 to-pink-500">
  Botão Gradiente
</Button>

<Card className="custom-card shadow-2xl border-2 border-purple-200">
  Card Personalizado
</Card>

Performance e Otimização

Bundle Size

  • Tree-shaking: Importe apenas os componentes necessários
  • Lazy loading: Componentes carregados sob demanda
  • CSS otimizado: Estilos minificados e comprimidos
// Import otimizado
import { Button, Input } from '@nti_ses/ui-components';

// Evite imports genéricos
// import * from '@nti_ses/ui-components';

Memoização

import React, { memo } from 'react';
import { Button } from '@nti_ses/ui-components';

const OptimizedComponent = memo(({ data }) => (
  <div>
    {data.map(item => (
      <Button key={item.id}>{item.label}</Button>
    ))}
  </div>
));

Roadmap e Próximas Funcionalidades

Q1 2025 (Em Desenvolvimento)

  • [x] Componentes básicos (Button, Input, Card, etc.)
  • [x] Sistema de tipografia com 3 fontes (Outfit, Inter, Gibralt)
  • [x] Temas e variáveis CSS customizáveis
  • [x] Sistema de paginação avançado
  • [x] Header e Footer responsivos
  • [ ] Modal/Dialog - Sistema completo de modais com backdrop, animações e acessibilidade
  • [ ] Toast/Notification - Sistema de notificações com posicionamento e auto-dismiss
  • [ ] DateRange/Period - Seletor de período com data início/fim e presets configuráveis
  • [ ] Testes Jest - Implementação completa de testes unitários para todos os componentes

Q2 2025

  • [ ] Table/DataTable - Tabela avançada com ordenação, filtros, paginação e seleção múltipla
  • [ ] Tabs - Sistema de abas com orientação horizontal/vertical e lazy loading
  • [ ] Upload/FileInput - Upload de arquivos com drag-and-drop, preview e validação
  • [ ] Breadcrumb - Navegação breadcrumb com separadores customizáveis
  • [ ] Skeleton - Loading states com skeleton screens animados
  • [ ] Progress - Indicadores de progresso (linear e circular) com animações

Q3 2025

  • [ ] Theme System - Tema dark/light automático com transições suaves
  • [ ] Animations - Micro-interações e animações com Framer Motion
  • [ ] Chart/Graph - Componentes de gráficos básicos (line, bar, pie)
  • [ ] Form Builder - Formulários dinâmicos com validação e schema
  • [ ] Autocomplete - Input com sugestões, busca e seleção múltipla
  • [ ] Badge - Indicadores, labels e status badges

Q4 2025

  • [ ] Calendar - Calendário completo com eventos, agenda e diferentes visualizações
  • [ ] RichText Editor - Editor de texto rico com formatação e plugins
  • [ ] Map Integration - Componente de mapas com markers e interações
  • [ ] Data Visualization - Dashboards e métricas com gráficos avançados
  • [ ] Advanced Search - Componente de busca com filtros e facetas
  • [ ] A11y Audit - Auditoria completa de acessibilidade WCAG 2.1

2026 - Futuro

  • [ ] Mobile Components - Adaptações específicas para mobile e touch
  • [ ] Advanced Layouts - Layouts complexos (Split, Resizable, Dock)
  • [ ] Virtualization - Listas e tabelas virtualizadas para grandes datasets
  • [ ] Internationalization - Suporte completo i18n com RTL
  • [ ] PWA Support - Funcionalidades específicas para Progressive Web Apps
  • [ ] AI Integration - Componentes com integração de IA (autocomplete, suggestions)

Contribuição e Desenvolvimento

Setup Local

git clone https://github.com/nti_ses/ui-components.git
cd ui-components
npm install
npm run dev

Estrutura do Projeto

src/
├── components/
│   ├── Button/
│   │   ├── Button.tsx
│   │   ├── Button.types.ts
│   │   ├── Button.scss
│   │   └── Button.stories.tsx
│   ├── Card/
│   │   ├── Card.tsx
│   │   ├── Card.types.ts
│   │   ├── Card.scss
│   │   └── Card.stories.tsx
│   ├── Input/
│   │   ├── Input.tsx
│   │   ├── Input.types.ts
│   │   ├── Input.scss
│   │   └── Input.stories.tsx
│   └── ...
└── styles/
    ├── fonts/
        ├── gibralt/
        ├── Inter/
        ├── Outfit/
    ├── fonts.scss
    ├── global.scss
    ├── tokens.scss
    └── typography.scss

Criando Novos Componentes

# Script para gerar novo componente
npm run generate:component MyComponent

# Cria:
# - src/components/MyComponent/MyComponent.tsx
# - src/components/MyComponent/MyComponent.types.ts
# - src/components/MyComponent/MyComponent.scss
# - src/components/MyComponent/MyComponent.stories.tsx
# - src/components/MyComponent/index.ts

Padrões de Código

  • TypeScript: Tipagem estrita obrigatória
  • SCSS Modules: Estilos componentizados
  • Storybook: Documentação visual
  • Jest + Testing Library: Testes unitários
  • ESLint + Prettier: Padronização de código

Suporte e Comunidade

Documentação

Suporte

  • Issues: Reporte bugs e solicite features
  • Discussions: Perguntas e discussões da comunidade
  • Email: [email protected]
  • Slack: #ui-components

Licença

MIT © 2024 NTI SES - Todos os direitos reservados.


Esta biblioteca está em desenvolvimento ativo. Para atualizações e novas funcionalidades, acompanhe o changelog e as releases.