@foxbit-group/caelum
v1.2.0
Published
Foxbit UI component library built on shadcn/ui
Keywords
Readme
Caelum
Biblioteca de componentes UI da Foxbit construida sobre shadcn/ui. Serve como fonte unica da verdade para todos os componentes de interface nos projetos da Foxbit.
Por que o Caelum existe?
graph LR
subgraph ANTES["Antes"]
A1[Projeto A] -->|shadcn local| C1[components/ui/button]
A1 -->|shadcn local| C2[components/ui/dialog]
B1[Projeto B] -->|shadcn local| C3[components/ui/button]
B1 -->|shadcn local| C4[components/ui/dialog]
D1[Projeto C] -->|shadcn local| C5[components/ui/button]
D1 -->|shadcn local| C6[components/ui/dialog]
end
subgraph DEPOIS["Depois"]
A2[Projeto A] -->|import| PKG["@foxbit-group/caelum"]
B2[Projeto B] -->|import| PKG
D2[Projeto C] -->|import| PKG
end
style ANTES fill:#1b1b1b,stroke:#f23a46,color:#f2f2f2
style DEPOIS fill:#1b1b1b,stroke:#02c070,color:#f2f2f2
style PKG fill:#ff6e00,stroke:#ff6e00,color:#ffffffProblemas que resolve:
- Componentes shadcn duplicados e divergentes entre projetos
- Estilos inconsistentes entre diferentes aplicacoes
- Dificuldade para atualizar ou trocar a lib de componentes
- Dependencia do shadcn espalhada em multiplos repositorios
Beneficios:
- Uma unica fonte da verdade para componentes UI
- Tema Foxbit (light/dark) pre-configurado com tokens Norma
- Troca de lib facilitada: altera internals do Caelum, mantem assinaturas
- Versionamento: consumers pinnam versao e atualizam quando quiserem
Instalacao
pnpm add @foxbit-group/caelumSetup no projeto consumer
flowchart TD
A["pnpm add @foxbit-group/caelum"] --> B{Qual framework?}
B -->|Next.js| C["Importar CSS no layout.tsx"]
B -->|Vite + React| D["Importar CSS no main.tsx"]
C --> E["import '@foxbit-group/caelum/styles.css'"]
D --> E
E --> F["Usar componentes"]
F --> G["import { Button } from '@foxbit-group/caelum'"]
style A fill:#ff6e00,stroke:#ff6e00,color:#fff
style G fill:#02c070,stroke:#02c070,color:#fffNext.js
// app/layout.tsx
import '@foxbit-group/caelum/styles.css'
import './globals.css' // seus estilos locais (se houver)
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="pt-BR">
<body>{children}</body>
</html>
)
}Vite + React
// src/main.tsx
import '@foxbit-group/caelum/styles.css'
import './index.css' // seus estilos locais (se houver)
import { createRoot } from 'react-dom/client'
import { App } from './App'
createRoot(document.getElementById('root')!).render(<App />)Usar componentes
import { Button, Card, CardHeader, CardTitle, CardContent, Input, Dialog } from '@foxbit-group/caelum'
export function LoginForm() {
return (
<Card>
<CardHeader>
<CardTitle>Entrar</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<Input placeholder="Email" type="email" />
<Input placeholder="Senha" type="password" />
<Button className="w-full">Entrar</Button>
</CardContent>
</Card>
)
}Tema e Dark Mode
O Caelum vem com o tema Foxbit pre-configurado, mapeado a partir dos tokens do design system Norma.
flowchart LR
subgraph Norma["Design System Norma"]
NT1["foxbit-exchange-light.css"]
NT2["foxbit-exchange-dark.css"]
end
subgraph Caelum["Caelum Theme Layer"]
CT["theme.css"]
end
subgraph ShadcnVars["Variaveis shadcn/ui"]
V1["--color-primary"]
V2["--color-background"]
V3["--color-destructive"]
V4["..."]
end
NT1 --> CT
NT2 --> CT
CT --> V1
CT --> V2
CT --> V3
CT --> V4
style Norma fill:#303030,stroke:#9c9c9c,color:#f2f2f2
style Caelum fill:#ff6e00,stroke:#ff6e00,color:#fff
style ShadcnVars fill:#252525,stroke:#464646,color:#f2f2f2Ativar dark mode
O tema dark e ativado pela classe .dark no <html> ou pelo atributo [data-theme="dark"] (compativel com o padrao existente da plataforma).
Com next-themes (Next.js):
import { ThemeProvider } from 'next-themes'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="pt-BR" suppressHydrationWarning>
<body>
<ThemeProvider attribute="class" defaultTheme="dark">
{children}
</ThemeProvider>
</body>
</html>
)
}Com data-theme (compativel com plataforma existente):
<html data-theme="dark">Paleta de cores
| Token | Light | Dark | Uso |
|-------|-------|------|-----|
| primary | #ff6e00 | #ff6e00 | Botoes principais, links, foco |
| background | #ffffff | #1b1b1b | Fundo da pagina |
| foreground | #212529 | #f2f2f2 | Texto principal |
| card | #f7f7f7 | #252525 | Fundo de cards |
| muted | #f7f7f7 | #303030 | Fundos secundarios |
| muted-foreground | #737e88 | #9c9c9c | Texto secundario |
| destructive | #ff4747 | #f23a46 | Erros, acoes destrutivas |
| border | #ececec | #303030 | Bordas |
| input | #d9d9d9 | #464646 | Borda de inputs |
| ring | #ff6e00 | #ff6e00 | Anel de foco |
Sobrescrever tokens
Voce pode sobrescrever qualquer token no CSS do projeto consumer:
:root {
--caelum-primary: #your-color;
--caelum-radius: 0.75rem;
}Componentes disponiveis
Todos os 37 componentes do shadcn/ui estao incluidos:
| Categoria | Componentes | |-----------|-------------| | Layout | AspectRatio, Card, Resizable, ScrollArea, Separator | | Formularios | Button, Checkbox, Form, Input, InputOTP, Label, RadioGroup, Select, Slider, Switch, Textarea | | Data Display | Avatar, Badge, Calendar, Table, Progress, Skeleton | | Feedback | Alert, AlertDialog, Dialog, Drawer, Sheet, Toast, Sonner, Tooltip | | Navegacao | Breadcrumb, Command, ContextMenu, DropdownMenu, HoverCard, Menubar, NavigationMenu, Pagination, Popover, Tabs | | Outros | Accordion, Carousel, Collapsible, Toggle, ToggleGroup |
Hooks
| Hook | Descricao |
|------|-----------|
| useToast | Gerenciar toasts programaticamente |
| useIsMobile | Detectar breakpoint mobile (< 768px) |
Utilitarios
| Utilitario | Descricao |
|------------|-----------|
| cn() | Merge de classes Tailwind (clsx + tailwind-merge) |
Arquitetura
graph TD
subgraph Caelum["@foxbit-group/caelum"]
direction TB
INDEX["src/index.ts<br/>Barrel export"] --> COMPONENTS
INDEX --> HOOKS
INDEX --> UTILS
subgraph COMPONENTS["components/ui/"]
B["Button"]
D["Dialog"]
I["Input"]
MORE["... +34 componentes"]
end
subgraph HOOKS["hooks/"]
UT["useToast"]
UM["useIsMobile"]
end
subgraph UTILS["lib/"]
CN["cn()"]
end
STYLES["styles/globals.css"] --> THEME["styles/theme.css"]
THEME --> LIGHT[":root (light)"]
THEME --> DARK[".dark (dark)"]
end
subgraph BUILD["Build Output (dist/)"]
JS["index.js (ESM)"]
CJS["index.cjs (CJS)"]
DTS["index.d.ts"]
CSS["styles.css"]
end
INDEX -->|tsup| JS
INDEX -->|tsup| CJS
INDEX -->|tsup| DTS
STYLES -->|tailwindcss| CSS
subgraph CONSUMERS["Projetos Consumer"]
NEXT["Next.js App"]
VITE["Vite App"]
end
JS --> NEXT
JS --> VITE
CSS --> NEXT
CSS --> VITE
style Caelum fill:#1b1b1b,stroke:#ff6e00,color:#f2f2f2
style BUILD fill:#252525,stroke:#464646,color:#f2f2f2
style CONSUMERS fill:#252525,stroke:#02c070,color:#f2f2f2Estrutura de arquivos
caelum/
├── src/
│ ├── components/
│ │ └── ui/ # 37 componentes shadcn/ui
│ │ ├── accordion.tsx
│ │ ├── alert.tsx
│ │ ├── alert-dialog.tsx
│ │ ├── button.tsx
│ │ ├── ...
│ │ └── tooltip.tsx
│ ├── hooks/
│ │ ├── use-toast.ts
│ │ └── use-mobile.ts
│ ├── lib/
│ │ └── utils.ts # cn()
│ ├── styles/
│ │ ├── globals.css # Entry CSS (Tailwind v4)
│ │ └── theme.css # Tokens Foxbit light/dark
│ └── index.ts # Barrel export
├── dist/ # Build output
│ ├── index.js # ESM (~103KB)
│ ├── index.cjs # CJS (~121KB)
│ ├── index.d.ts # TypeScript types
│ └── styles.css # CSS compilado (~47KB)
├── package.json
├── tsconfig.json
├── tsup.config.ts
├── .npmrc
├── .nvmrc
└── .gitignoreDesenvolvimento
Pre-requisitos
- Node.js >= 20 (ver
.nvmrc) - pnpm
Comandos
# Instalar dependencias
pnpm install
# Build completo (JS + Types)
pnpm build
# Build CSS
pnpm build:css
# Watch mode (JS apenas)
pnpm dev
# Type check
pnpm typecheckAdicionar um novo componente
flowchart TD
A["Criar arquivo em<br/>src/components/ui/novo.tsx"] --> B["Implementar componente<br/>seguindo padrao shadcn"]
B --> C["Exportar em<br/>src/index.ts"]
C --> D["pnpm build && pnpm build:css"]
D --> E["Publicar nova versao"]
style A fill:#303030,stroke:#9c9c9c,color:#f2f2f2
style E fill:#02c070,stroke:#02c070,color:#fff- Crie o componente em
src/components/ui/novo-componente.tsx - Adicione o export em
src/index.ts - Rode
pnpm buildpara validar - Publique uma nova versao
Publicacao
npmjs.com (CI automatizado)
A publicacao e feita automaticamente via GitHub Actions quando uma tag v* e criada.
sequenceDiagram
participant Dev as Desenvolvedor
participant GH as GitHub
participant CI as GitHub Actions
participant NPM as npmjs.com
Dev->>Dev: pnpm version patch/minor/major
Dev->>GH: git push --follow-tags
GH->>CI: Tag v* dispara workflow
CI->>CI: pnpm install
CI->>CI: pnpm typecheck && pnpm lint
CI->>CI: pnpm build && pnpm build:css
CI->>NPM: pnpm publish
NPM-->>Dev: Pacote publicado
Note over Dev,NPM: Consumers atualizam com<br/>pnpm update @foxbit-group/caelum# Bump de versao (cria tag automaticamente)
# patch: 0.1.0 -> 0.1.1 (bugfix)
# minor: 0.1.0 -> 0.2.0 (novo componente)
# major: 0.1.0 -> 1.0.0 (breaking change)
pnpm version patch # ou minor, major
# Push com a tag — CI publica automaticamente
git push --follow-tagsFluxo de migracao de um projeto existente
Para projetos que ja usam shadcn/ui localmente:
flowchart TD
A["1. Instalar @foxbit-group/caelum"] --> B["2. Importar styles.css no root"]
B --> C["3. Trocar imports locais"]
C --> D["4. Remover components/ui/ local"]
D --> E["5. Remover dependencias shadcn<br/>do package.json"]
E --> F["6. Testar tudo"]
C -.->|Antes| C1["import { Button } from '@/components/ui/button'"]
C -.->|Depois| C2["import { Button } from '@foxbit-group/caelum'"]
style A fill:#ff6e00,stroke:#ff6e00,color:#fff
style F fill:#02c070,stroke:#02c070,color:#fff
style C1 fill:#493a3c,stroke:#f23a46,color:#f2f2f2
style C2 fill:#354743,stroke:#02c070,color:#f2f2f2Checklist de migracao
- [ ] Instalar
@foxbit-group/caelum - [ ] Adicionar
import '@foxbit-group/caelum/styles.css'no entry point - [ ] Buscar e substituir todos os imports de
@/components/ui/para@foxbit-group/caelum - [ ] Remover pasta
components/ui/local - [ ] Remover
@radix-ui/*,class-variance-authority,cmdk,vaul, etc. dopackage.json - [ ] Remover
components.json(config do shadcn CLI) - [ ] Rodar testes e validar visualmente
Stack tecnica
| Tecnologia | Versao | Uso | |------------|--------|-----| | Tailwind CSS | v4 | Estilizacao | | shadcn/ui | latest | Base dos componentes | | Radix UI | latest | Primitivos acessiveis | | tsup | v8 | Bundler (ESM + CJS + DTS) | | TypeScript | v5 | Tipagem | | class-variance-authority | v0.7 | Variantes de componentes | | tailwind-merge | v3 | Merge inteligente de classes | | Lucide | latest | Icones |
FAQ
Posso usar classes Tailwind nos componentes do Caelum?
Sim. Todos os componentes aceitam className e o merge e feito via cn() (tailwind-merge). O CSS ja vem compilado no styles.css, entao as classes dos componentes funcionam sem configuracao extra no consumer. Para classes Tailwind customizadas no seu projeto, voce ainda precisa do seu proprio setup de Tailwind.
E se eu precisar de um componente que nao existe no Caelum?
Crie-o localmente no seu projeto. Quando fizer sentido compartilhar, abra um PR no Caelum para adiciona-lo.
O Caelum funciona com Server Components (RSC)?
Sim. Componentes que usam hooks ou event handlers tem a diretiva "use client" incluida automaticamente no bundle. Componentes puramente visuais (Card, Badge, Table, etc.) funcionam como Server Components.
Como atualizar o Caelum no meu projeto?
pnpm update @foxbit-group/caelumPosso customizar um componente especifico sem mexer no Caelum?
Sim. Use className para sobrescrever estilos, ou encapsule o componente do Caelum em um wrapper local com a customizacao necessaria.
