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

vale-design-system

v1.1.0

Published

Design System do Vale — App de estudos. Gerado a partir do arquivo Figma (Foundations + Components).

Downloads

325

Readme

Vale Design System

Design system em React + TypeScript + Tailwind CSS, gerado a partir do arquivo Figma Vale — App de estudos — páginas Foundations, Components e Fluxo do App - mobile (as ~30 telas do app, adaptadas em components/templates/ — ver "Do Figma para o código" abaixo).

Publicado no npm: vale-design-system (npm install vale-design-system).

Stack

  • React 18 + TypeScript — componentes tipados de ponta a ponta.
  • Tailwind CSS — estilização via tokens (ver tailwind.config.ts), sem valores mágicos.
  • Radix UI — primitivas acessíveis por baixo dos componentes interativos (Dialog, Switch, Progress, Label, Collapsible).
  • class-variance-authority (cva) — variantes tipadas (variant, size…) em vez de strings soltas.
  • Storybook 8 — uma story por componente, com o addon de acessibilidade (@storybook/addon-a11y) rodando em cada uma.
  • Vite — dev server e build.

Estrutura de pastas

src/
├── tokens/          Cores, tipografia, espaçamento, raio e sombra — os valores crus,
│                    portados 1:1 das variáveis/estilos do Figma (Foundations). Inclui
│                    `semanticDark` — tokens de dark mode, não vêm do Figma (ver abaixo).
├── foundations/     Fundações usáveis em código: primitivo de Tipografia (<Text/>)
│                    + stories de documentação (Colors, Spacing, Radius, Shadows, Logo).
├── icons/           Ícones SVG (traço 1.5px, grade 24×24 — Foundations → Icons).
├── assets/          Assets reais exportados do Figma — NÃO publicados no pacote npm
│                    (ver "Assets" abaixo):
│   ├── companions/  18 fotos (3 estágios × 6 cores) do Egg Card.
│   ├── brand/       Ícone do app (SVG) e wordmark "Vale" (PNG, 3 cores).
│   └── screens/     4 ilustrações de tela (Splash, Vale, Fim de sessão, Hoje),
│                    só pras stories/demo dos templates renderizarem algo real.
├── components/      Componentes de UI, em Atomic Design:
│   ├── atoms/       Button, Input, Textarea, Select, Chip, Toggle, SegmentedControl,
│   │                ProgressBar, ProgressRing, LoadingBar, NumberBlock, NavItem,
│   │                ColorSwatch, LinkChip, Sparkline, Notice, StepDots, ThemeToggle —
│   │                não dependem de outro componente do DS.
│   ├── molecules/   Card, MonthStrip, EggCard, CompanionCard, CompanionBubble, InfoBox,
│   │                SessionHistoryItem, TrendStat, AchievementListItem, SettingsRow,
│   │                EmptyState — compõem átomos.
│   ├── organisms/   Navbar, Modal, SettingsSection, AchievementGroup — compõem
│   │                átomos/moléculas em blocos completos de tela.
│   └── templates/   As ~16 telas de "Fluxo do App - mobile" (Splash, Onboarding,
│                    Escolha do personagem, Login, Hoje, Detalhe do item, Sessão em
│                    foco, Fim de sessão, Plano/Carreira, Novo item, Vale, Progresso,
│                    Certificados, Ajustes) — telas completas, prontas pra importar
│                    direto no app final (ver doc comment em `templates/index.ts`).
├── hooks/           `useTheme` — toggle de dark mode persistido (não vem do Figma).
├── lib/             Utilitário `cn()` (clsx + tailwind-merge).
├── test/            `setup.ts` — configuração global do Vitest (jest-dom, jest-axe,
│                    mock de matchMedia pro jsdom).
├── index.ts         Ponto de entrada da biblioteca publicada no npm.
├── App.tsx          Demo viva combinando os componentes (tela "Hoje").
└── index.css        Diretivas do Tailwind + tokens de tema (light/dark) + import das
                     fontes (Fraunces, Poppins).

Cada componente vive em sua própria pasta com três arquivos: Componente.tsx, Componente.stories.tsx e index.ts (barrel export).

Tokens semânticos

tokens/colors.ts expõe duas camadas, no mesmo espírito da coleção "Cor" no Figma:

  • palette — primitivos crus (roxo, grafite, salvia…), nomeados como no Figma.
  • semantic — papéis (primary, textSecondary, success…) que apontam para a palette.

Componentes devem consumir apenas os tokens semânticos (via classes Tailwind como bg-primary, text-text-secondary, border-border) — nunca a palette diretamente. Isso significa que a paleta pode mudar (rebrand, dark mode) sem tocar em nenhum componente.

O mesmo padrão vale para espaçamento (spacing), raio (radius) e sombra (shadows): os valores vêm de tokens/*.ts e são expostos ao Tailwind em tailwind.config.ts.

Dark mode

Não vem do Figma — o arquivo só define um tema claro. Infraestrutura própria:

  • tokens/colors.ts (semanticDark) define um conjunto deliberadamente restrito de overrides escuros: só tokens neutros (superfície, borda, texto, desabilitado) e a família *OnSurface (cor de marca usada como texto direto sobre a superfície) mudam por tema. Fills de marca e tintas *Subtle/*Strong (Chip, Card concluído) mantêm um valor só, porque seu contraste interno não depende do tema da página — só do próprio fundo, que não muda. Cada valor tem sua razão de contraste comentada no código.
  • Variáveis CSS (index.css) + withOpacity() (tailwind.config.ts) fazem as classes existentes (bg-surface, text-text-secondary…) mudarem de cor sob .dark em <html>, sem precisar de dark: em nenhum componente.
  • hooks/useTheme.ts + <ThemeToggle />: alternância persistida (localStorage) com fallback para prefers-color-scheme e script anti-flash em index.html.
  • Toolbar do Storybook (.storybook/preview.tsx) para pré-visualizar qualquer story nos dois temas.

Assets

src/assets/ tem os assets reais exportados do Figma em 2026-09-09 (fotos do Egg Card, ícone do app, wordmark, +4 ilustrações de tela de assets/screens/) — usados pelo Storybook e pela demo (npm run dev), mas deliberadamente fora do pacote publicado no npm (mesma decisão de sempre: cada template recebe suas imagens via props — backgroundImageSrc, companionImageSrc... — em vez de embutir fotos no pacote). Quem instala via npm install vale-design-system continua fornecendo seu próprio conteúdo, como já era documentado para EggCard. Se quiser usar as imagens reais fora deste repositório, copie src/assets/companions/, src/assets/brand/ e src/assets/screens/.

Acessibilidade

  • Todo componente interativo usa uma primitiva Radix por baixo (foco, Escape, roles ARIA e aria-* corretos vêm de fábrica) em vez de reimplementar teclado/ARIA na mão.
  • Nenhum estado é só visual: disabled é o atributo nativo, error vira aria-invalid + aria-describedby no Input, selected vira aria-current="page" no NavItem.
  • Foco visível global (:focus-visible) em index.css — nunca removido sem substituto.
  • Alvo de toque mínimo de 44×44px (min-h-touch/min-w-touch) nos componentes interativos, documentando a regra de acessibilidade do Figma (Foundations → Accessibility).
  • O Storybook roda com @storybook/addon-a11y (test: "error" em .storybook/preview.tsx), então qualquer PR que adicionar uma story com violação de acessibilidade falha visivelmente no painel de Accessibility.
  • Todo componente tem um teste jest-axe (toHaveNoViolations) no CI — a mesma checagem do addon do Storybook, mas rodável sem navegador (ver "Testes" abaixo).

Testes

npm test roda Vitest + Testing Library + jest-dom + jest-axe (jsdom, sem navegador). Cada componente tem um Componente.test.tsx ao lado do seu .tsx, cobrindo:

  • Renderização e interação — o que um usuário realmente vê/faz (clicar, digitar, abrir/fechar), não detalhes de implementação.
  • Comportamento de acessibilidade que o próprio componente promete no seu doc comment (aria-current, aria-invalid+aria-describedby, disabled nativo…) — não só que ele existe, mas que reage certo a props/interação.
  • jest-axe em cada variante relevante — captura os mesmos problemas que o addon de a11y do Storybook, só que sem precisar abrir o navegador.

Dois arquivos testam infraestrutura em vez de um componente:

  • src/lib/utils.test.ts — regressão direta do bug do cn() documentado em utils.ts (classes de tamanho de fonte sendo confundidas com cor de texto).
  • src/tokens/colors.test.ts — calcula contraste WCAG de verdade (fórmula da própria spec, não uma lib externa) para cada par texto/fundo em semantic/semanticDark. Foi assim que os três bugs de contraste do dark mode foram achados nesta sessão — este teste existe pra eles não voltarem.
npm test              # roda uma vez (CI)
npm run test:watch    # modo watch, pra desenvolvimento
npm run test:coverage # com relatório de cobertura (v8)

Como rodar

npm install

# Storybook — catálogo de componentes com Foundations + Components
npm run storybook

# Vite — demo viva combinando os componentes numa tela
npm run dev

# Build de produção da demo (dist/ a partir de index.html)
npm run build

# Build da biblioteca publicável (dist/index.js, index.cjs, index.d.ts, style.css)
npm run build:lib

# Publicar uma nova versão no npm (roda build:lib via prepublishOnly)
npm version patch   # ou minor/major
npm publish

Do Figma para o código — mapeamento

| Figma (Components) | Código | Camada | |-------------------------|--------------------------------------------|-----------| | Button | components/atoms/Button | átomo | | Input | components/atoms/Input | átomo | | Chip | components/atoms/Chip | átomo | | Toggle | components/atoms/Toggle | átomo | | Progress Bar | components/atoms/ProgressBar | átomo | | Progress Ring | components/atoms/ProgressRing | átomo | | Number Block | components/atoms/NumberBlock | átomo | | Nav Item | components/atoms/NavItem | átomo | | (não vem do Figma) | components/atoms/ThemeToggle | átomo | | Card | components/molecules/Card | molécula | | Month Strip | components/molecules/MonthStrip | molécula | | Egg Card | components/molecules/EggCard | molécula | | Navbar | components/organisms/Navbar | organismo | | Modal | components/organisms/Modal | organismo |

Cada mapeamento também é documentado no cabeçalho JSDoc do respectivo arquivo .tsx, com o link de volta para a seção correspondente no Figma.

Fluxo do App - mobile (adicionado 2026-09-09)

Novos átomos/moléculas/organismos extraídos das telas, mais as 15 telas completas (components/templates/) que os compõem — a página em si tem ~30 frames, mas várias são o mesmo template em estados diferentes (primeiro acesso vs. depois de algumas horas de estudo, pausado vs. tocando...), não telas novas. Ver o doc comment de cada arquivo para o link exato de volta ao frame do Figma.

| Template | Frames do Figma cobertos | |----------------------------------|-----------------------------------------------------------------------------| | SplashScreen | Splash | | OnboardingIntroScreen | Onboarding 1 de 4, Onboarding 2 de 4 | | OnboardingCourseFormScreen | Onboarding 3 de 4 (estado vazio/preenchido) | | CharacterSelectionScreen | Escolha do personagem (+ 5 variantes de cor) | | LoginScreen | Login opcional | | HomeScreen | Hoje primeiro acesso / após algumas horas de estudo | | ItemDetailScreen | Detalhe do item primeiro acesso / após algumas horas de estudo | | FocusSessionScreen | Sessão em foco pausada / dar play | | SessionEndScreen | Fim de sessão | | PlanScreen | Plano, Carreira (mesma estrutura, conteúdo diferente) | | NewItemScreen | Novo plano - cursos, Novo carreira - ações de carreira | | VaultScreen | Vale primeiro acesso / após algumas horas de estudo | | ProgressScreen | Progresso primeiro acesso / após algumas horas de estudo | | CertificatesScreen | Certificados primeiro acesso (vazio) / após algumas horas de estudo | | SettingsScreen | Ajustes |

Novos átomos: Textarea, Select, SegmentedControl, LoadingBar, ColorSwatch, LinkChip, Sparkline, Notice, StepDots. Novas moléculas: CompanionCard, CompanionBubble, InfoBox, SessionHistoryItem, TrendStat, AchievementListItem, SettingsRow, EmptyState. Novos organismos: SettingsSection, AchievementGroup. Button ganhou as variantes amber/outline/outlineMuted e ProgressRing ganhou tone/valueVariant — ambos documentados no porquê no próprio arquivo (não são do Figma "Components", são overrides específicos do fluxo do app).