@odd-studio/ui
v1.0.0
Published
Biblioteca de componentes React + Tailwind profissional, minimalista e sofisticada
Maintainers
Readme
🎨 Odd Prototype UI
Biblioteca de componentes React + Tailwind com estilo visual profissional, minimalista e sofisticado.
📦 Instalação
npm install @odd-prototype/ui🚀 Configuração
1. Configure o Tailwind
Adicione o caminho dos componentes no seu tailwind.config.js:
module.exports = {
content: [
"./src/**/*.{js,jsx,ts,tsx}",
"./node_modules/@odd-prototype/ui/**/*.{js,jsx}"
],
// Extenda com as configurações do Odd Prototype UI
presets: [require('@odd-prototype/ui/tailwind.config.js')],
}2. Importe os estilos
No arquivo principal da sua aplicação (ex: index.js ou App.js):
import '@odd-prototype/ui/src/styles.css';📚 Componentes
Button
Botões com estilo profissional e variantes.
import { Button } from '@odd-prototype/ui';
// Botão primário (padrão)
<Button onClick={handleClick}>
Salvar Proposta
</Button>
// Botão secundário
<Button variant="secondary" size="large">
Cancelar
</Button>
// Botão texto
<Button variant="text" size="small">
Ver detalhes
</Button>
// Botão full width
<Button fullWidth>
Criar Nova Proposta
</Button>
// Botão desabilitado
<Button disabled>
Processando...
</Button>Props:
variant:'primary'|'secondary'|'text'(padrão:'primary')size:'small'|'medium'|'large'(padrão:'medium')fullWidth:boolean(padrão:false)disabled:boolean(padrão:false)onClick:Function
Card
Containers para agrupar conteúdo relacionado.
import { Card } from '@bencao/ui';
// Card simples
<Card>
<h3>Resumo de Vendas</h3>
<p>Conteúdo do card...</p>
</Card>
// Card com estrutura completa
<Card>
<Card.Header>
<h2>Análise de Desempenho</h2>
</Card.Header>
<Card.Body>
<p>Conteúdo principal...</p>
</Card.Body>
<Card.Footer>
<Button>Exportar Relatório</Button>
</Card.Footer>
</Card>
// Card sem padding ou sombra
<Card noPadding noShadow>
<img src="chart.png" alt="Gráfico" />
</Card>Props:
noPadding:boolean- Remove padding internonoShadow:boolean- Remove sombra
Input
Campos de entrada com labels e validação.
import { Input } from '@bencao/ui';
// Input básico
<Input
label="Nome do Cliente"
placeholder="Digite o nome..."
value={name}
onChange={(e) => setName(e.target.value)}
/>
// Input com erro
<Input
label="Email"
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
error={true}
errorMessage="Email inválido"
/>
// Input com texto de ajuda
<Input
label="Valor da Proposta"
type="number"
helperText="Valor em reais (R$)"
/>
// Select
<Input.Select
label="Status"
options={[
{ value: 'negociacao', label: 'Em Negociação' },
{ value: 'faturado', label: 'Faturado' },
]}
value={status}
onChange={(e) => setStatus(e.target.value)}
/>
// Textarea
<Input.Textarea
label="Observações"
rows={4}
value={notes}
onChange={(e) => setNotes(e.target.value)}
/>Props:
label:string- Label do inputtype:string- Tipo do input (padrão:'text')placeholder:stringvalue:stringonChange:Functiondisabled:booleanerror:booleanerrorMessage:stringhelperText:stringfullWidth:boolean(padrão:true)
MetricCard
Cards para exibir métricas e KPIs.
import { MetricCard } from '@bencao/ui';
// Métrica simples
<MetricCard
value="R$ 125.000"
label="Faturamento Total"
/>
// Métrica com variante de cor
<MetricCard
value="87"
suffix="%"
label="Taxa de Conversão"
variant="excellent"
/>
// Métrica com tendência
<MetricCard
value="23"
label="Propostas em Negociação"
trend="+15% vs mês anterior"
trendDirection="up"
/>
// Grid de métricas
<MetricCard.Grid columns={4} gap="20px">
<MetricCard value="45" label="Propostas" />
<MetricCard value="R$ 2.3M" label="Valor Total" />
<MetricCard value="76%" label="Taxa Sucesso" variant="good" />
<MetricCard value="12" label="Em Aberto" />
</MetricCard.Grid>Props:
value:string|number- Valor principallabel:string- Label da métricaprefix:string- Prefixo (ex: "R$")suffix:string- Sufixo (ex: "%")variant:'default'|'excellent'|'good'|'average'|'poor'trend:string- Texto de tendênciatrendDirection:'up'|'down'|'neutral'
StatusBadge
Badges para exibir status de propostas.
import { StatusBadge } from '@bencao/ui';
// Status predefinidos
<StatusBadge status="negociacao" />
<StatusBadge status="aguardando" />
<StatusBadge status="faturado" />
<StatusBadge status="perdida" />
<StatusBadge status="standby" />
<StatusBadge status="anulada" />
// Status customizado
<StatusBadge
status="custom"
label="Em Análise"
color="#3498db"
/>
// Badge genérico
<StatusBadge.Badge variant="success">
Aprovado
</StatusBadge.Badge>
<StatusBadge.Badge variant="warning">
Atenção
</StatusBadge.Badge>Props:
status:'negociacao'|'aguardando'|'faturado'|'perdida'|'standby'|'anulada'|'custom'label:string- Texto customizado (obrigatório se status='custom')color:string- Cor customizada (obrigatório se status='custom')
Table
Tabelas responsivas com estilo profissional.
import { Table } from '@bencao/ui';
<Table>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Cliente</Table.HeaderCell>
<Table.HeaderCell align="right">Valor</Table.HeaderCell>
<Table.HeaderCell>Status</Table.HeaderCell>
<Table.HeaderCell align="center">Ações</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row hoverable onClick={() => handleView(id)}>
<Table.Cell>Empresa ABC</Table.Cell>
<Table.Cell align="right" numeric>R$ 50.000</Table.Cell>
<Table.Cell>
<StatusBadge status="negociacao" />
</Table.Cell>
<Table.Cell align="center">
<Button size="small">Ver</Button>
</Table.Cell>
</Table.Row>
</Table.Body>
</Table>Props:
hoverable:boolean- Hover nas linhas (padrão:true)striped:boolean- Linhas zebradas- TableCell:
align:'left'|'center'|'right'numeric:boolean- Usa fonte monospace
BrandTag
Logo/marca da aplicação.
import { BrandTag } from '@bencao/ui';
// Tag simples
<BrandTag />
// Tag com texto customizado
<BrandTag text="BENDITO" size="large" />
// Logo completo com título
<BrandTag.Logo
title="Sistema de Propostas"
subtitle="Gestão Comercial"
size="medium"
/>Props:
text:string(padrão:'BENÇÃO')size:'small'|'medium'|'large'
Alert
Mensagens de alerta e notificações.
import { Alert } from '@bencao/ui';
// Alerta de informação
<Alert variant="info" title="Informação">
Dados salvos com sucesso!
</Alert>
// Alerta de aviso
<Alert variant="warning">
Verifique os campos obrigatórios antes de continuar.
</Alert>
// Alerta de sucesso
<Alert variant="success" title="Sucesso!">
Proposta criada e enviada ao cliente.
</Alert>
// Alerta de erro dismissível
<Alert
variant="danger"
title="Erro"
dismissible
onDismiss={() => setShowAlert(false)}
>
Não foi possível salvar os dados.
</Alert>Props:
variant:'info'|'warning'|'success'|'danger'title:stringdismissible:booleanonDismiss:Function
Layout Components
Container
Container responsivo com max-width padrão (1400px).
import { Container } from '@bencao/ui';
<Container>
<h1>Minha Aplicação</h1>
{/* Conteúdo */}
</Container>
// Sem padding lateral
<Container noPadding>
{/* Conteúdo */}
</Container>Divider
Linha divisória horizontal.
import { Divider } from '@bencao/ui';
// Divider simples
<Divider />
// Divider com texto
<Divider text="OU" />
// Divider mais escuro
<Divider weight="dark" />Section
Seção com espaçamento padrão.
import { Section } from '@bencao/ui';
<Section title="Análise de Desempenho">
{/* Conteúdo da seção */}
</Section>🎨 Cores Disponíveis (Tailwind)
Cores Principais
bg-bencao-black // #1a1a1a
bg-bencao-gray-dark // #333333
bg-bencao-gray-medium // #666666
bg-bencao-gray-light // #e5e5e5
bg-bencao-bg-main // #fafafa (background padrão)
bg-bencao-bg-card // #ffffff (background de cards)
bg-bencao-bg-alt // #f8f9fa (background alternativo)Cores de Status
text-status-negociacao // #8b5a87 (roxo acinzentado)
text-status-aguardando // #4a7c8c (azul esverdeado)
text-status-faturado // #6b8f71 (verde oliva)
text-status-perdida // #a0725c (terracota)
text-status-standby // #7a7a7a (cinza médio)
text-status-anulada // #999999 (cinza claro)Cores de Eficiência
text-efficiency-excellent // #27ae60
text-efficiency-good // #2ecc71
text-efficiency-average // #f39c12
text-efficiency-poor // #e74c3c📐 Tamanhos de Texto (Tailwind)
text-h1 // 2.25rem (36px)
text-h2 // 1.25rem (20px)
text-h3 // 1rem (16px)
text-body // 1rem
text-subtitle // 1.1rem
text-label // 0.875rem (14px)
text-small // 0.75rem (12px)📏 Espaçamentos (Tailwind)
p-section // 32px
p-card // 24px
p-header // 32px
p-element // 16px
p-related // 20px🎯 Exemplo de Aplicação Completa
import React, { useState } from 'react';
import {
Container,
Section,
BrandTag,
Card,
Button,
Input,
MetricCard,
Table,
StatusBadge,
Alert
} from '@odd-prototype/ui';
function App() {
const [showAlert, setShowAlert] = useState(true);
return (
<Container>
{/* Header */}
<Section>
<BrandTag.Logo
title="Sistema de Propostas"
subtitle="Gestão Comercial"
/>
</Section>
{/* Alert */}
{showAlert && (
<Alert
variant="success"
dismissible
onDismiss={() => setShowAlert(false)}
>
Bem-vinda ao sistema!
</Alert>
)}
{/* Métricas */}
<Section title="Dashboard">
<MetricCard.Grid columns={4}>
<MetricCard value="45" label="Propostas" />
<MetricCard value="R$ 2.3M" label="Valor Total" />
<MetricCard
value="76"
suffix="%"
label="Taxa de Sucesso"
variant="excellent"
/>
<MetricCard value="12" label="Em Aberto" />
</MetricCard.Grid>
</Section>
{/* Formulário */}
<Section title="Nova Proposta">
<Card>
<div className="grid grid-cols-2 gap-4">
<Input
label="Nome do Cliente"
placeholder="Digite o nome..."
/>
<Input.Select
label="Status"
options={[
{ value: 'negociacao', label: 'Em Negociação' },
{ value: 'faturado', label: 'Faturado' }
]}
/>
</div>
<div className="mt-4">
<Input.Textarea
label="Descrição"
rows={4}
/>
</div>
<div className="mt-6 flex gap-3">
<Button>Salvar</Button>
<Button variant="secondary">Cancelar</Button>
</div>
</Card>
</Section>
{/* Tabela */}
<Section title="Propostas Recentes">
<Card noPadding>
<Table>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Cliente</Table.HeaderCell>
<Table.HeaderCell align="right">Valor</Table.HeaderCell>
<Table.HeaderCell>Status</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>Empresa ABC</Table.Cell>
<Table.Cell align="right" numeric>
R$ 50.000
</Table.Cell>
<Table.Cell>
<StatusBadge status="negociacao" />
</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
</Card>
</Section>
</Container>
);
}
export default App;🎨 Filosofia de Design
A biblioteca Odd Prototype UI segue princípios de design minimalista e profissional:
- Tipografia limpa: Uso da fonte Inter para interface clara e legível
- Cores sofisticadas: Paleta dessaturada e profissional
- Espaçamento generoso: Respiração visual adequada
- Sombras sutis: Apenas o necessário para profundidade
- Transições suaves: Interações fluidas de 200ms
- Uppercase estratégico: Labels e títulos em maiúsculas para hierarquia
📄 Licença
MIT © Odd Prototype Team
🤝 Contribuindo
Contribuições são bem-vindas! Por favor, abra uma issue ou pull request.
Desenvolvido com ❤️ pela equipe Odd Prototype
