@niods/design-system
v1.12.0
Published
Design System tokens and CSS foundation
Downloads
2,354
Readme
NioDS — Design System Core
Sistema de design da Nio. Este repositório contém os tokens de design e os componentes CSS da camada Core — compartilhada entre todos os produtos web e mobile da Nio.
- Pacote npm: @niods/design-system
- CDN: jsDelivr
Índice
- Instalação
- Uso via CDN
- Tema dark
- Componentes disponíveis
- Desenvolvimento local
- Contribuindo
- Arquitetura e decisões técnicas
Instalação
npm install @niods/design-systemDepois, importe o CSS no ponto de entrada da sua aplicação:
import '@niods/design-system';Uso via CDN
Para projetos que não usam npm, os arquivos estão disponíveis via jsDelivr.
Versão fixada (recomendado para produção):
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@niods/[email protected]/dist/design-system.min.css">Sempre a versão mais recente (recomendado para desenvolvimento):
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@niods/design-system@latest/dist/design-system.min.css">Use versão fixada em produção. A URL com
@latestsempre aponta para o release mais recente e pode introduzir mudanças inesperadas sem controle de versão no seu projeto.
Tema dark
O NioDS suporta tema dark via atributo data-theme="dark" no elemento raiz do documento. Os tokens de cor são sobrescritos automaticamente.
<html data-theme="dark">Para alternar o tema via JavaScript:
document.documentElement.setAttribute('data-theme', 'dark');
document.documentElement.removeAttribute('data-theme'); // volta para lightComponentes disponíveis
Todos os componentes usam a convenção de classe ds-{componente} com variantes e estados via atributos data-*.
Button
<!-- Primário -->
<button class="ds-button" data-kind="primary">Confirmar</button>
<!-- Secundário -->
<button class="ds-button" data-kind="secondary">Cancelar</button>
<!-- Terciário -->
<button class="ds-button" data-kind="tertiary">Saiba mais</button>
<!-- Danger -->
<button class="ds-button" data-kind="danger">Excluir</button>
<!-- Conversion -->
<button class="ds-button" data-kind="conversion">Assinar agora</button>
<!-- Desabilitado -->
<button class="ds-button" data-kind="primary" data-state="disabled">Confirmar</button>
<!-- Com ícone à esquerda -->
<button class="ds-button" data-kind="primary" data-icon="start">
<span class="ds-button__icon"><i class="ph ph-check"></i></span>
Confirmar
</button>
<!-- Com ícone à direita -->
<button class="ds-button" data-kind="primary" data-icon="end">
Próximo
<span class="ds-button__icon"><i class="ph ph-arrow-right"></i></span>
</button>ButtonGroup
<div class="ds-button-group">
<button class="ds-button" data-kind="secondary">Opção 1</button>
<button class="ds-button" data-kind="secondary">Opção 2</button>
<button class="ds-button" data-kind="secondary">Opção 3</button>
</div>Input
<!-- Padrão -->
<div class="ds-form-field">
<label class="ds-form-field__label" for="email">E-mail</label>
<input class="ds-input" id="email" type="email" placeholder="[email protected]">
</div>
<!-- Com erro -->
<div class="ds-form-field" data-state="error">
<label class="ds-form-field__label" for="email-error">E-mail</label>
<input class="ds-input" id="email-error" type="email" aria-invalid="true" aria-describedby="email-error-msg">
<span class="ds-form-field__message" id="email-error-msg">E-mail inválido.</span>
</div>
<!-- Desabilitado -->
<div class="ds-form-field" data-state="disabled">
<label class="ds-form-field__label" for="email-disabled">E-mail</label>
<input class="ds-input" id="email-disabled" type="email" disabled>
</div>Desenvolvimento local
Pré-requisitos
- Node.js 20+
- npm 10+
Setup
git clone https://github.com/brunonio/ds-ui-kit.git
cd ds-ui-kit
npm installComandos disponíveis
| Comando | O que faz |
|---|---|
| npm run build | Gera o dist/ completo (tokens + CSS) |
| npm run tokens:build | Gera só os arquivos de tokens em dist/tokens/ |
| npm run lint | Roda o Stylelint em src/**/*.css |
| npm run lint:fix | Roda o Stylelint com correção automática |
Playground
O diretório playground/ contém um arquivo HTML para visualizar os componentes localmente com os tokens aplicados. Para usar, rode o build primeiro e abra o arquivo no browser:
npm run build
open playground/button.htmlContribuindo
Fluxo de trabalho
- Crie um branch a partir da
main - Faça as alterações
- Abra um pull request para
main - O CI roda automaticamente: validação de tokens, lint e build
- Após aprovação e merge, o semantic-release publica a nova versão automaticamente
Commits convencionais
Todos os commits precisam seguir o padrão Conventional Commits. O CI bloqueia o merge de PRs com commits fora do padrão.
| Prefixo | Quando usar | Bump gerado |
|---|---|---|
| feat: | Nova funcionalidade ou componente | minor |
| fix: | Correção de bug | patch |
| feat!: ou BREAKING CHANGE | Mudança que quebra compatibilidade | major |
| chore: | Manutenção, dependências | nenhum |
| docs: | Documentação | nenhum |
| ci: | Mudanças no CI | nenhum |
| refactor: | Refatoração sem mudança de comportamento | nenhum |
Adicionando componentes
- Crie o arquivo CSS em
src/components/{componente}.css - Importe no
src/index.css - Siga o padrão de custom properties locais do
button.csscomo referência - Use
data-*para variantes e estados, nunca classes modificadoras BEM (--) - Garanta foco via
:focus-visiblecomvar(--color-keyboard-focus) - Use tokens de motion em todas as
transition
Adicionando tokens
Siga sempre a hierarquia core → semantic → theme. Nunca referencie um token core diretamente em CSS de componente.
- Valor bruto vai em
tokens/core/ - Significado semântico vai em
tokens/semantic/ - Sobrescrita de tema dark vai em
tokens/themes/dark.json
Arquitetura e decisões técnicas
Esta seção documenta decisões tomadas intencionalmente. Está dividida em padrões que devem ser seguidos e decisões que podem parecer incorretas mas têm contexto.
Padrões estabelecidos
Tokens — Arquitetura em três camadas: core → semantic → theme
Arquivos: tokens/core/, tokens/semantic/, tokens/themes/
Os tokens core definem os valores brutos da paleta. Os tokens semantic referenciam o core e atribuem significado (color.primary.background aponta para colors.verde-neon.925). Os tokens de theme sobrescrevem apenas os semânticos, nunca os core diretamente.
Ao criar novos tokens, sempre respeitar essa hierarquia. Nunca referenciar um token core diretamente em CSS de componente.
CSS — Estados via atributos data-*, não classes modificadoras
Os componentes usam data-kind="primary", data-state="disabled", data-icon="start" em vez de classes modificadoras BEM (ds-button--primary). Enforçado pela regra DS011 do stylelint-plugin-ds.
Nunca adicionar classes modificadoras com -- em componentes do design system.
Plugin Stylelint customizado
Diretório: stylelint-plugin-ds/
Regras que bloqueiam o CI com severity: error:
| Regra | O que enforça |
|---|---|
| DS010 | Classes de componente devem ter prefixo ds- |
| DS011 | Proibido modificadores BEM com -- |
| DS013 | :hover e :active em ds-* devem ter guard :not([data-state="disabled"]) |
| DS014 | Usar :focus-visible, não :focus |
| DS015 | outline em :focus-visible deve referenciar --color-keyboard-focus |
| DS020 | transition deve usar tokens --motion-duration-* e --motion-easing-* |
Regras com severity: warning (reportam, não bloqueiam): DS001 (cores raw), DS002 (espaçamento raw), DS003 (border-radius raw), DS004 (border-width raw), DS030/031 (tipografia sem tokens).
Ao adicionar novas regras, seguir o padrão de numeração e criar a documentação correspondente em stylelint-plugin-ds/docs/.
CI — Validação de commits convencionais em todo PR
Todo PR para main passa por validação de formato de commit convencional. Commits que não seguem o padrão bloqueiam o merge. Commits de merge são automaticamente ignorados.
Decisões que parecem incorretas mas são intencionais
CI — Commit da pasta dist/ no branch do PR
O CI commita os arquivos de dist/ diretamente no branch do PR após o build. Intencional — permite que revisores inspecionem as alterações nos arquivos gerados diretamente na interface do GitHub, sem precisar fazer checkout e rodar o build localmente.
O risco de race condition em pushes paralelos é conhecido e aceito dado o fluxo atual com revisão humana antes de novos pushes.
Release — semantic-release como sistema oficial
O fluxo de release passa exclusivamente pelo semantic-release, que analisa os commits convencionais e publica automaticamente no npm após cada merge na main.
Não usar npm run changeset ou qualquer outra ferramenta de release manual — isso geraria versões paralelas inconsistentes com o histórico do semantic-release.
