Instalação
Como consumir @bacdmy/ui em apps Next.js.
1. Autenticação no GitHub Packages
- Crie um Personal Access Token (classic) no GitHub com o escopo
read:packages. Se o pacote for privado, inclua tambémrepo. - No app consumidor, o
.npmrccommitado deve ter só o registry do escopo:
@bacdmy:registry=https://npm.pkg.github.comNão coloque _authToken no .npmrc do repositório. Uma linha com ${NODE_AUTH_TOKEN} vazio sobrescreve o PAT do ~/.npmrc e causa E401.
Local
Coloque o PAT no ~/.npmrc do usuário:
//npm.pkg.github.com/:_authToken=ghp_…Vercel / CI
Defina a env NODE_AUTH_TOKEN (PAT com read:packages) e injete o token no Install Command (ou num preinstall), por exemplo:
echo "//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}" >> .npmrc && pnpm install2. Instalar
pnpm add @bacdmy/ui@0.0.1Ícones: Tabler (não Lucide)
Este design system usa @tabler/icons-react (Tabler Icons), não Lucide. Os primitivos do pacote já importam ícones Tabler; nos apps consumidores, use o mesmo pacote para manter consistência visual e de API.
- Importe como
IconXyz(ex.:IconPlus,IconChevronDown). - Não instale
lucide-reactnem misture bibliotecas de ícones no mesmo app. - Se o app ainda não tiver a dependência:
pnpm add @tabler/icons-react.
import { IconPlus, IconChevronDown } from '@tabler/icons-react'
<Button>
<IconPlus data-icon="inline-start" />
Novo
</Button>3. next.config
O pacote exporta TypeScript fonte. Transpile no Next:
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
transpilePackages: ['@bacdmy/ui']
}
export default nextConfig4. Estilos
No CSS global do app (depois de configurar Tailwind v4):
@import '@bacdmy/ui/styles';
/* CSS específico do app (blog, marketing…) abaixo */O CSS do pacote mapeia @theme assim: --font-sans, --font-heading e --font-mono ← --font-geist-mono. Sem as variáveis no <html>, as classes font-sans / font-heading / font-mono não resolvem.
5. Importar componentes
import { Button, Logo } from '@bacdmy/ui'
// ou por caminho:
import { Button } from '@bacdmy/ui/button'6. Fontes
O design system não embute arquivos de fonte. Cada app carrega Inter, Inter Tight e Geist Mono com next/font/google e publica CSS variables no <html>.
O que cada variável alimenta
--font-sans→ corpo / UI (font-sans, default dohtml)--font-heading→ títulos (font-heading, Logo labels, headings)--font-geist-mono→ código / mono (font-monono tema aponta para essa variável)
Layout do app
import { Geist_Mono, Inter, Inter_Tight } from 'next/font/google'
import { cn } from '@bacdmy/ui' // ou '@/lib/utils'
const inter = Inter({ subsets: ['latin'], variable: '--font-sans' })
const interTight = Inter_Tight({
subsets: ['latin'],
variable: '--font-heading',
weight: 'variable'
})
const geistMono = Geist_Mono({
variable: '--font-geist-mono',
subsets: ['latin']
})
export default function RootLayout({ children }) {
return (
<html
lang="pt-BR"
className={cn(
'h-full antialiased',
geistMono.variable,
inter.variable,
interTight.variable,
'font-sans'
)}
suppressHydrationWarning
>
<body className="min-h-full flex flex-col">{children}</body>
</html>
)
}As classes *.variable do next/font injetam --font-* no elemento. font-sans no html aplica a família de corpo como default. Não redefina essas variáveis no CSS do app — o pacote já as consome em @bacdmy/ui/styles.