@1doc/1ds-react
Biblioteca de componentes React do 1DS Design System.
📚 Documentação viva (Storybook): https://1dsux.vercel.app
Instalação
pnpm add @1doc/1ds-react @1doc/1ds-tokens
@1doc/1ds-tokens é peerDependency — o app instala e importa os CSS de
tokens diretamente (ver abaixo).
Configuração
[!IMPORTANT] Importe o CSS dos tokens no ponto de entrada da aplicação (
main.tsx), nesta ordem. Sem esses imports, os componentes ficam sem estilo.
import "@1doc/1ds-tokens/css/primitives.css";
import "@1doc/1ds-tokens/css/semantic.css";
import "@1doc/1ds-tokens/css/theme-1doc.css"; // tema da sua marca (ver Temas)
Os caminhos dist/css/... continuam funcionando, mas prefira os subpaths
estáveis css/... acima.
Uso
import { Button } from "@1doc/1ds-react";
function App() {
return (
<Button variant="primary" onClick={() => console.log("Click")}>
Clique aqui
</Button>
);
}
Componentes
Accordion · Alert · Avatar/AvatarGroup · Badge · Breadcrumb · Button · Card · Checkbox · Chips · ConfirmDialog · DataTable · DatePicker · Divider · Dropdown · EmptyState · FileInput · Grid · Icon · Input · Link · Logo · Modal · MultiSelect · PageHeader · Pagination · PhoneInput · Portal · ProgressBar · Radio · Select · Skeleton · Spinner · Stepper · Switch · Tabs · Tag · Text · Textarea · TimePicker · Toast/ToastStack · Tooltip
Props e exemplos de cada componente: Storybook (link acima) ou os .d.ts
(JSDoc em português em todas as props).
[!NOTE] As interfaces de props são estritas (sem
[key: string]: any): typo de prop é erro de compilação. Atributos arbitrários (data-*etc.) não são repassados ao DOM pelos componentes — antes compilavam mas eram silenciosamente descartados; agora o TypeScript avisa.
Ícones
Os ícones internos dos componentes (chevrons, calendário, setas de ordenação, ×, etc.) funcionam out-of-the-box — cada componente importa seus glifos diretamente (tree-shakeable, só o que é usado entra no bundle).
Para ícones do seu app (<Icon icon="...">, startIcon, Tab.icon...),
há dois caminhos:
// 1) Recomendado: objeto importado (tree-shakeable, typo = erro de compilação)
import { faHouse } from "@fortawesome/free-solid-svg-icons";
<Icon icon={faHouse} />;
// 2) Por nome (string): exige registrar os ícones na library UMA vez no bootstrap
import { library } from "@1doc/1ds-react";
import { faHouse, faGear } from "@fortawesome/free-solid-svg-icons";
library.add(faHouse, faGear);
<Icon icon="house" />;
[!WARNING] Evite
library.add(fas)(pacote inteiro): adiciona ~900 kB ao bundle. Registre apenas os ícones que o app usa, ou prefira objetos importados. Use packs FontAwesome na faixa 6.x (compatível com o svg-core do DS).
Temas
Tema via atributo data-theme no <html>. Utilitários em @1doc/1ds-react:
setTheme · getTheme · initTheme · onThemeChange · registerTheme ·
getAvailableThemes.
| Marca | Light (arquivo / setTheme) | Dark |
|---|---|---|
| 1Doc | theme-1doc.css / "1doc" | theme-1doc-dark.css / "1doc-dark" |
| Green | theme-1ds-green.css / "1ds-green" | theme-1ds-green-dark.css / "1ds-green-dark" |
| Orange | theme-1ds-orange.css / "1ds-orange" | theme-1ds-orange-dark.css / "1ds-orange-dark" |
| Purple | theme-1ds-purple.css / "1ds-purple" | theme-1ds-purple-dark.css / "1ds-purple-dark" |
| Red | theme-1ds-red.css / "1ds-red" | theme-1ds-red-dark.css / "1ds-red-dark" |
| Yellow | theme-1ds-yellow.css / "1ds-yellow" | theme-1ds-yellow-dark.css / "1ds-yellow-dark" |
Alto contraste (acessibilidade, fora da matriz de marcas): theme-1doc-high-contrast.css /
"1doc-high-contrast" — fundo preto, texto branco, interativo amarelo. O DS não o aplica
sozinho; ver a seção "Alto contraste" do README de @1doc/1ds-tokens para seguir
prefers-contrast: more.
O CSS do tema escolhido precisa estar importado para o
setThemeter efeito. Todos os temas podem ser carregados juntos (cada um é escopado em[data-theme="..."]) — a troca em runtime é atômica.
Tema de marca própria (white-label)
Crie um CSS com [data-theme="minha-marca"] sobrescrevendo os 25 tokens
--umds-theme-* (contrato idêntico aos 12 temas oficiais — o mínimo para a
cor de marca são os 4 primary-*), carregue-o após o semantic.css e
registre o tema para o utilitário aceitá-lo (validação + persistência):
import { registerTheme, initTheme, setTheme } from "@1doc/1ds-react";
registerTheme("minha-marca");
registerTheme("minha-marca-dark");
initTheme(); // restaura tema persistido (inclusive custom, já registrado)
setTheme("minha-marca");
Formulários
Todos os campos participam do submit nativo (<form> + FormData) via prop
name — Select/DatePicker/TimePicker/MultiSelect emitem hidden inputs;
PhoneInput emite também {name}_ddi; FileInput mantém os File no input.
Contrato de validação uniforme: invalid/errorMessage/helperText
(com aria-describedby).
Em viewports ≤640px os campos de texto sobem automaticamente para fonte 16px (evita o zoom do Safari iOS ao focar).
Modo touch (densidade)
Para apps mobile/touch, ative o modo touch — os alvos de toque dos controles interativos (botões, campos, checkboxes, paginação, calendário…) sobem para ≥44px, aumentando controle e espaçamento juntos:
import { setDensity } from "@1doc/1ds-react";
setDensity("touch"); // <html data-density="touch">
setDensity("default"); // volta ao padrão desktop
Elementos inline compactos (Tag, Chips) mantêm o tamanho — em contextos touch, dê espaçamento entre eles no layout.
Toasts
import { ToastStack, toast } from "@1doc/1ds-react";
// 1× na raiz do app:
<ToastStack position="top-right" />;
// em qualquer handler:
toast({ message: "Salvo!", variant: "positive" });