@aspprev/versi-ds 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +116 -396
- package/dist/charts.js +1 -1
- package/dist/{chunk-OWXG2A4N.js → chunk-ATWH3MA6.js} +1 -1
- package/dist/chunk-ATWH3MA6.js.map +1 -0
- package/dist/{chunk-CWIPMGCA.js → chunk-ET2BGHTO.js} +2 -1
- package/dist/chunk-ET2BGHTO.js.map +1 -0
- package/dist/{chunk-BY4HJZFJ.js → chunk-FR5W52XU.js} +283 -23
- package/dist/chunk-FR5W52XU.js.map +1 -0
- package/dist/chunk-H4BBKKRZ.js +380 -0
- package/dist/chunk-H4BBKKRZ.js.map +1 -0
- package/dist/{chunk-2ACDV5D5.js → chunk-JSPXVXUY.js} +1 -1
- package/dist/chunk-JSPXVXUY.js.map +1 -0
- package/dist/{chunk-OPUUOVCL.js → chunk-PIXRKI25.js} +84 -10
- package/dist/chunk-PIXRKI25.js.map +1 -0
- package/dist/{chunk-6MXHE5MD.js → chunk-V66QL3TD.js} +1 -1
- package/dist/chunk-V66QL3TD.js.map +1 -0
- package/dist/chunk-YCW3REQK.js +3102 -0
- package/dist/chunk-YCW3REQK.js.map +1 -0
- package/dist/core.d.ts +23 -4
- package/dist/core.js +12 -6
- package/dist/countries.js +1 -1
- package/dist/documents.d.ts +81 -1
- package/dist/documents.js +14 -4
- package/dist/forms.d.ts +26 -2
- package/dist/forms.js +5 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +30 -12
- package/dist/manifest.json +9 -9
- package/dist/overlays.js +1 -1
- package/dist/styles.css +1 -1
- package/package.json +27 -19
- package/dist/chunk-2ACDV5D5.js.map +0 -1
- package/dist/chunk-6MXHE5MD.js.map +0 -1
- package/dist/chunk-A3PA5H7L.js +0 -3099
- package/dist/chunk-A3PA5H7L.js.map +0 -1
- package/dist/chunk-BY4HJZFJ.js.map +0 -1
- package/dist/chunk-CWIPMGCA.js.map +0 -1
- package/dist/chunk-OPUUOVCL.js.map +0 -1
- package/dist/chunk-OWXG2A4N.js.map +0 -1
- package/dist/chunk-XGWGBD7X.js +0 -45
- package/dist/chunk-XGWGBD7X.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,463 +1,183 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Versi Design System
|
|
2
2
|
|
|
3
|
-
Biblioteca
|
|
3
|
+
Biblioteca React de componentes, tokens, temas e utilitários para padronizar as interfaces dos produtos ASPPrev.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
O [Storybook](#storybook) é a documentação visual oficial: nele você pode explorar componentes, foundations, temas, padrões de composição e estados acessíveis.
|
|
6
6
|
|
|
7
|
-
##
|
|
8
|
-
|
|
9
|
-
1. Instale o pacote e as dependências das camadas que vai usar.
|
|
10
|
-
2. Importe os estilos uma vez na entrada da aplicação.
|
|
11
|
-
3. Configure fonte, tema e preferências no elemento `html`.
|
|
12
|
-
4. Comece pelos exemplos de componentes e formulários abaixo.
|
|
13
|
-
5. Consulte o Storybook para explorar variantes, estados e propriedades.
|
|
14
|
-
|
|
15
|
-
## Instalação e consumo
|
|
16
|
-
|
|
17
|
-
Depois da publicação:
|
|
7
|
+
## Instalação
|
|
18
8
|
|
|
19
9
|
```bash
|
|
20
10
|
npm install @aspprev/versi-ds react react-dom
|
|
21
11
|
```
|
|
22
12
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
```tsx
|
|
26
|
-
import { Button } from "@aspprev/versi-ds/core";
|
|
27
|
-
import "@aspprev/versi-ds/styles.css";
|
|
28
|
-
import "@aspprev/versi-ds/themes.css"; // paletas opcionais, depois dos estilos
|
|
29
|
-
|
|
30
|
-
export function Example() {
|
|
31
|
-
return <Button>Continuar</Button>;
|
|
32
|
-
}
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
O CSS já está compilado: consumidores não precisam instalar Tailwind nem escanear o pacote. Importe-o uma vez na entrada da aplicação. Ele inclui estilos base/reset do Tailwind; carregue as personalizações da aplicação depois dos estilos do DS.
|
|
36
|
-
|
|
37
|
-
Os componentes básicos não exigem um provider global. Alguns controles precisam de contexto específico, como Formik nos formulários. Se a aplicação já usa React, preserve a versão compatível instalada em vez de adicionar uma segunda cópia.
|
|
38
|
-
|
|
39
|
-
## Entrypoints públicos
|
|
40
|
-
|
|
41
|
-
Todos os sufixos abaixo pertencem a `@aspprev/versi-ds`.
|
|
42
|
-
|
|
43
|
-
| Entrada | Conteúdo | Peers adicionais |
|
|
44
|
-
| ------------- | -------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
|
|
45
|
-
| raiz | API completa de compatibilidade | Instale todos os peers opcionais |
|
|
46
|
-
| `/core` | Botões, tipografia, superfícies, avisos, avatares, imagens, tooltips, paginação, tabelas, status, layout e primitivas acessíveis | Nenhum |
|
|
47
|
-
| `/forms` | Input/InputStandalone, InputSelect, TextArea, InputPhone, SelectCountry, SelectMulti, DatePicker, RadioGroup, RadioCardGroup | `formik`, `date-fns`, `react-number-format` |
|
|
48
|
-
| `/charts` | LazyApexChart, TimeSeriesChart, InteractiveDonutChart, TimeRangeSelector e utilitários | `apexcharts`, `react-apexcharts` |
|
|
49
|
-
| `/overlays` | Modal, InputSwitch, AccessibilityPreferencesPanel, HighContrastToggle | `@headlessui/react` |
|
|
50
|
-
| `/documents` | BoletoBarCode e DocumentItem | `jsbarcode` |
|
|
51
|
-
| `/countries` | COUNTRY_OPTIONS, PHONE_COUNTRY_OPTIONS, getCountryOptions, getCountryFlagUrl, filterCountryOptions e tipos | Nenhum |
|
|
52
|
-
| `/styles.css` | Tokens, modos, componentes e utilitários compilados | — |
|
|
53
|
-
| `/themes.css` | Presets de paletas | — |
|
|
13
|
+
Requisitos do pacote:
|
|
54
14
|
|
|
55
|
-
|
|
15
|
+
- Node.js `>=20.19.0`;
|
|
16
|
+
- React `>=18.2.0 <20`;
|
|
17
|
+
- React DOM `>=18.2.0 <20`.
|
|
56
18
|
|
|
57
|
-
|
|
19
|
+
As integrações abaixo são opcionais e só precisam ser instaladas pelas entradas que as utilizam: `@headlessui/react`, `apexcharts`, `date-fns`, `formik`, `jsbarcode`, `react-apexcharts` e `react-number-format`.
|
|
58
20
|
|
|
59
|
-
|
|
21
|
+
## Uso
|
|
60
22
|
|
|
61
|
-
|
|
62
|
-
# Formulários
|
|
63
|
-
npm install formik@^2.4.9 date-fns@^4.1.0 react-number-format@^5.4.4
|
|
64
|
-
|
|
65
|
-
# Gráficos
|
|
66
|
-
npm install apexcharts@5.3.6 react-apexcharts@^1.9.0
|
|
23
|
+
Importe o CSS global uma vez na entrada da aplicação:
|
|
67
24
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
# Código de barras
|
|
72
|
-
npm install jsbarcode@^3.12.3
|
|
25
|
+
```tsx
|
|
26
|
+
import "@aspprev/versi-ds/styles.css";
|
|
27
|
+
import "@aspprev/versi-ds/themes.css";
|
|
73
28
|
```
|
|
74
29
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
`CountrySelect`, `MultiSelect`, `PhoneInput`, `Datepicker` e `CheckBox` permanecem aliases depreciados. Prefira `SelectCountry`, `SelectMulti`, `InputPhone`, `DatePicker` e `Checkbox`. Não use deep imports de componentes em `dist` ou `src`.
|
|
78
|
-
|
|
79
|
-
## Escolhendo os componentes
|
|
80
|
-
|
|
81
|
-
| Necessidade | Componentes |
|
|
82
|
-
| ----------------------------- | ----------------------------------------------------------------------------------------------------- |
|
|
83
|
-
| Ações e navegação | Button, Pagination, PageTabsHeader |
|
|
84
|
-
| Texto e hierarquia | Typography, PageHeading, TextGroup, Divider |
|
|
85
|
-
| Estrutura | Surface, ModalCard, FormGrid, FormActions, InfoGrid, InfoItem, FilterBar |
|
|
86
|
-
| Avisos, status e carregamento | Notice, StatusBadge, DomainStatusBadge, PageState, LoadingDots, CircularLoading |
|
|
87
|
-
| Identidade e apoio visual | Avatar, ThemedImage, IconProvider, Tooltip |
|
|
88
|
-
| Texto, seleção e datas | Input, InputStandalone, InputSelect, TextArea, SelectMulti, DatePicker |
|
|
89
|
-
| Países e telefones | SelectCountry, InputPhone |
|
|
90
|
-
| Opções e valores graduais | Checkbox, RadioGroup, RadioCardGroup, InputSwitch, Slider, InputSlider |
|
|
91
|
-
| Dados tabulares | Table, MobileCardTable |
|
|
92
|
-
| Visualizações | TimeSeriesChart, InteractiveDonutChart, TimeRangeSelector, LazyApexChart |
|
|
93
|
-
| Diálogos e documentos | Modal, DocumentItem, BoletoBarCode |
|
|
94
|
-
| Acessibilidade | SkipLink, FocusNavigationMode, FormErrorNavigation, AccessibilityPreferencesPanel, HighContrastToggle |
|
|
95
|
-
|
|
96
|
-
Essa tabela organiza os componentes por finalidade. Consulte os entrypoints para escolher o import: Checkbox está em `/core`, RadioGroup em `/forms` e InputSwitch em `/overlays`, por exemplo.
|
|
97
|
-
|
|
98
|
-
## Componentes básicos na prática
|
|
30
|
+
Use componentes pela raiz ou por um entrypoint público:
|
|
99
31
|
|
|
100
32
|
```tsx
|
|
101
|
-
import {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
StatusBadge,
|
|
105
|
-
Surface,
|
|
106
|
-
Typography,
|
|
107
|
-
} from "@aspprev/versi-ds/core";
|
|
33
|
+
import { Button, Surface, Typography } from "@aspprev/versi-ds";
|
|
34
|
+
import { Input, OtpCodeInput } from "@aspprev/versi-ds/forms";
|
|
35
|
+
import { FileDropzone, QRCode } from "@aspprev/versi-ds/documents";
|
|
108
36
|
|
|
109
37
|
export function Resumo() {
|
|
110
38
|
return (
|
|
111
|
-
<Surface tone="card" padding="default"
|
|
112
|
-
<Typography element="
|
|
113
|
-
|
|
114
|
-
</Typography>
|
|
115
|
-
<Typography semanticRole="body">
|
|
116
|
-
Confira as informações antes de continuar.
|
|
39
|
+
<Surface tone="card" padding="default">
|
|
40
|
+
<Typography element="h1" semanticRole="section-title">
|
|
41
|
+
Meu cadastro
|
|
117
42
|
</Typography>
|
|
118
|
-
<
|
|
119
|
-
Atualizado
|
|
120
|
-
</StatusBadge>
|
|
121
|
-
<Notice type="info">
|
|
122
|
-
Você pode revisar os dados a qualquer momento.
|
|
123
|
-
</Notice>
|
|
124
|
-
<Button type="button" variant="outline" color="primary">
|
|
125
|
-
Revisar
|
|
126
|
-
</Button>
|
|
43
|
+
<Button type="button">Continuar</Button>
|
|
127
44
|
</Surface>
|
|
128
45
|
);
|
|
129
46
|
}
|
|
130
47
|
```
|
|
131
48
|
|
|
132
|
-
|
|
133
|
-
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
134
|
-
| Button | `variant`: flat/outline/plain; `color`: primary/secondary/tertiary/danger/warning; `size`: small/medium/large; `width`: auto/full; `loading`, `loadingLabel`, `disabled` |
|
|
135
|
-
| Typography | `element`: elemento HTML; `semanticRole`: page-title/section-title/body/label/caption/helper; `size`, `weight`, `variant` |
|
|
136
|
-
| Surface | `tone`: card/subtle/muted/disabled/info/success/warning/danger/transparent; `padding`: none/compact/default; `elevation`: none/sm/md; `radius`: none/sm/md |
|
|
137
|
-
| Notice | `type`: info/primary/secondary/tertiary/gray/success/warning/danger; `onDismiss`, `icon`, `rounded` |
|
|
138
|
-
| StatusBadge | `tone`: neutral/info/success/warning/danger; `appearance`: outline/soft/solid; `size`: sm/md |
|
|
139
|
-
|
|
140
|
-
Em Typography, `semanticRole` define a apresentação; `element` define a semântica HTML. Use `element="h1"` para o título principal e níveis coerentes para as seções. Uma etiqueta de status precisa de texto compreensível, além da cor.
|
|
141
|
-
|
|
142
|
-
Para uma ação em andamento, use `loading` e um `loadingLabel` descritivo no Button. Dentro de formulários, declare `type="submit"` para enviar e `type="button"` para as demais ações.
|
|
143
|
-
|
|
144
|
-
## Formulários
|
|
145
|
-
|
|
146
|
-
Use Input quando o estado pertence ao Formik e InputStandalone quando a aplicação fornece `value` e `onChange` diretamente. A aplicação define a validação e o envio; o DS apresenta os controles e seus estados.
|
|
147
|
-
|
|
148
|
-
### Formulário com Formik
|
|
149
|
-
|
|
150
|
-
```tsx
|
|
151
|
-
import { Form, Formik } from "formik";
|
|
152
|
-
import { Button, FormActions, FormGrid } from "@aspprev/versi-ds/core";
|
|
153
|
-
import { Input, InputSelect } from "@aspprev/versi-ds/forms";
|
|
154
|
-
|
|
155
|
-
type Valores = { nome: string; categoria: string };
|
|
156
|
-
|
|
157
|
-
export function Cadastro({
|
|
158
|
-
salvar,
|
|
159
|
-
}: {
|
|
160
|
-
salvar: (values: Valores) => Promise<void>;
|
|
161
|
-
}) {
|
|
162
|
-
return (
|
|
163
|
-
<Formik<Valores>
|
|
164
|
-
initialValues={{ nome: "", categoria: "" }}
|
|
165
|
-
validate={(values) => {
|
|
166
|
-
const errors: Partial<Record<keyof Valores, string>> = {};
|
|
167
|
-
if (!values.nome.trim()) errors.nome = "Informe seu nome.";
|
|
168
|
-
if (!values.categoria) errors.categoria = "Selecione uma categoria.";
|
|
169
|
-
return errors;
|
|
170
|
-
}}
|
|
171
|
-
onSubmit={salvar}
|
|
172
|
-
>
|
|
173
|
-
{({ isSubmitting }) => (
|
|
174
|
-
<Form>
|
|
175
|
-
<FormGrid columns={2}>
|
|
176
|
-
<Input name="nome" label="Nome completo" autoComplete="name" />
|
|
177
|
-
<InputSelect
|
|
178
|
-
name="categoria"
|
|
179
|
-
label="Categoria"
|
|
180
|
-
options={[
|
|
181
|
-
{ label: "Pessoa física", value: "pessoa-fisica" },
|
|
182
|
-
{ label: "Pessoa jurídica", value: "pessoa-juridica" },
|
|
183
|
-
]}
|
|
184
|
-
/>
|
|
185
|
-
</FormGrid>
|
|
186
|
-
<FormActions align="end">
|
|
187
|
-
<Button
|
|
188
|
-
type="submit"
|
|
189
|
-
loading={isSubmitting}
|
|
190
|
-
loadingLabel="Salvando cadastro"
|
|
191
|
-
>
|
|
192
|
-
Salvar
|
|
193
|
-
</Button>
|
|
194
|
-
</FormActions>
|
|
195
|
-
</Form>
|
|
196
|
-
)}
|
|
197
|
-
</Formik>
|
|
198
|
-
);
|
|
199
|
-
}
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
O `name` deve corresponder à chave em `initialValues`. Os erros integrados aparecem quando o campo está marcado como tocado (`touched`). Forneça `label`; o placeholder é um exemplo de preenchimento, não substitui o rótulo.
|
|
203
|
-
|
|
204
|
-
FormGrid usa uma coluna em telas menores e aplica `columns` a partir do breakpoint `tablet` (1024 px). FormActions organiza as ações em coluna no mobile e em linha nas telas maiores.
|
|
205
|
-
|
|
206
|
-
### Campo controlado sem contexto Formik
|
|
207
|
-
|
|
208
|
-
```tsx
|
|
209
|
-
import { useState } from "react";
|
|
210
|
-
import { InputStandalone } from "@aspprev/versi-ds/forms";
|
|
211
|
-
|
|
212
|
-
export function Busca() {
|
|
213
|
-
const [termo, setTermo] = useState("");
|
|
214
|
-
return (
|
|
215
|
-
<InputStandalone
|
|
216
|
-
name="busca"
|
|
217
|
-
label="Buscar por nome"
|
|
218
|
-
value={termo}
|
|
219
|
-
onChange={(event) => setTermo(event.target.value)}
|
|
220
|
-
/>
|
|
221
|
-
);
|
|
222
|
-
}
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
Input e InputStandalone oferecem máscaras como `cpf`, `cnpj`, `cep`, `phone`, `date` e `currency`. A máscara auxilia a digitação; a aplicação ainda deve validar e normalizar o valor exigido pela sua API. Use InputPhone para seleção internacional de país e DDI.
|
|
226
|
-
|
|
227
|
-
## Diálogos controlados
|
|
228
|
-
|
|
229
|
-
```tsx
|
|
230
|
-
import { useState } from "react";
|
|
231
|
-
import { Button } from "@aspprev/versi-ds/core";
|
|
232
|
-
import { Modal } from "@aspprev/versi-ds/overlays";
|
|
233
|
-
|
|
234
|
-
export function Detalhes() {
|
|
235
|
-
const [aberto, setAberto] = useState(false);
|
|
236
|
-
return (
|
|
237
|
-
<>
|
|
238
|
-
<Button type="button" onClick={() => setAberto(true)}>
|
|
239
|
-
Ver detalhes
|
|
240
|
-
</Button>
|
|
241
|
-
<Modal
|
|
242
|
-
isOpen={aberto}
|
|
243
|
-
onClose={() => setAberto(false)}
|
|
244
|
-
title="Detalhes do cadastro"
|
|
245
|
-
showIcon={false}
|
|
246
|
-
>
|
|
247
|
-
<p>Informações complementares do cadastro.</p>
|
|
248
|
-
<Button type="button" onClick={() => setAberto(false)}>
|
|
249
|
-
Fechar
|
|
250
|
-
</Button>
|
|
251
|
-
</Modal>
|
|
252
|
-
</>
|
|
253
|
-
);
|
|
254
|
-
}
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
Mantenha o estado de abertura na aplicação e forneça um título significativo. ModalCard é uma superfície visual; use Modal quando precisar do comportamento de diálogo.
|
|
258
|
-
|
|
259
|
-
## Servidor e navegador
|
|
260
|
-
|
|
261
|
-
As entradas de componentes, inclusive `/core` e a raiz, declaram `"use client"`: agrupam componentes com hooks/contexto. Podem participar de SSR em aplicações React, mas não são entradas exclusivas de React Server Components. Funções dessas entradas devem ser chamadas no contexto cliente em aplicações RSC. `/countries` permanece sem diretiva cliente e pode ser usado no servidor. Callbacks e estado devem ser definidos em um componente cliente.
|
|
262
|
-
|
|
263
|
-
## Temas, acessibilidade e fontes
|
|
264
|
-
|
|
265
|
-
Os tokens canônicos ficam em `tokens/design-system.tokens.json`. Edite essa fonte e execute `npm run tokens:generate`; não edite os arquivos gerados manualmente.
|
|
266
|
-
|
|
267
|
-
```html
|
|
268
|
-
<html
|
|
269
|
-
data-color-scheme="dark"
|
|
270
|
-
data-ds-theme="verde3"
|
|
271
|
-
data-contrast="high"
|
|
272
|
-
data-contrast-theme="dark"
|
|
273
|
-
data-font-scale="large"
|
|
274
|
-
data-motion="reduce"
|
|
275
|
-
></html>
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
| Atributo | Valores |
|
|
279
|
-
| --------------------- | ------------------------------------------------------------------------------------------------------------- |
|
|
280
|
-
| `data-color-scheme` | `light`, `dark` |
|
|
281
|
-
| `data-ds-theme` | `default`, `azul1`, `azul2`, `azul3`, `laranja1`, `laranja2`, `verde1`, `verde2`, `verde3`, `verde4`, `rosa1` |
|
|
282
|
-
| `data-contrast` | `normal`, `high` |
|
|
283
|
-
| `data-contrast-theme` | `light`, `dark` (esquema do alto contraste) |
|
|
284
|
-
| `data-font-scale` | `default`, `large`, `extra-large` |
|
|
285
|
-
| `data-motion` | `full`, `reduce` |
|
|
286
|
-
|
|
287
|
-
As preferências são controladas pelo consumidor, que também cuida da persistência e sincronização. As classes legadas das paletas continuam disponíveis. Tokens de cores usam triplets RGB para aceitar opacidade.
|
|
288
|
-
|
|
289
|
-
O pacote não distribui nem baixa fontes. Configure `--font-nunito-sans` ou sobrescreva `--font-family-base`; sem Nunito Sans disponível, o navegador usa `sans-serif`. O Storybook carrega Nunito Sans pelo Google Fonts e precisa de rede para reproduzir essa tipografia nas referências visuais existentes. O consumidor pode hospedar a própria fonte; não há dependência de `next/font`.
|
|
290
|
-
|
|
291
|
-
### Alterar o tema em execução
|
|
292
|
-
|
|
293
|
-
No navegador, atualize os atributos do elemento raiz:
|
|
294
|
-
|
|
295
|
-
```ts
|
|
296
|
-
const root = document.documentElement;
|
|
297
|
-
root.dataset.colorScheme = "dark";
|
|
298
|
-
root.dataset.dsTheme = "azul1";
|
|
299
|
-
root.dataset.contrast = "normal";
|
|
300
|
-
root.dataset.contrastTheme = "dark";
|
|
301
|
-
root.dataset.fontScale = "large";
|
|
302
|
-
root.dataset.motion = "reduce";
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
Use o `html` para que diálogos e listas renderizados fora da árvore do componente recebam o mesmo tema. Aplique as preferências conhecidas antes da primeira pintura quando houver SSR. Para acompanhar o tema do sistema, a aplicação deve resolver a preferência para `light` ou `dark`.
|
|
49
|
+
### Entrypoints
|
|
306
50
|
|
|
307
|
-
|
|
51
|
+
| Entry point | Conteúdo |
|
|
52
|
+
| --- | --- |
|
|
53
|
+
| `@aspprev/versi-ds` | API principal e componentes mais usados |
|
|
54
|
+
| `/core` | componentes base, layout, status, tabela e hooks |
|
|
55
|
+
| `/forms` | campos Formik e controlados, seleção e OTP |
|
|
56
|
+
| `/documents` | documentos, upload, FileViewer e QRCode |
|
|
57
|
+
| `/overlays` | modal, preferências e camadas interativas |
|
|
58
|
+
| `/charts` | gráficos e seletores de período |
|
|
59
|
+
| `/countries` | países, telefones e bandeiras |
|
|
60
|
+
| `/styles.css` | estilos e tokens base |
|
|
61
|
+
| `/themes.css` | presets de tema |
|
|
308
62
|
|
|
309
|
-
|
|
63
|
+
Evite deep imports. Use somente os entrypoints públicos documentados no `package.json`.
|
|
310
64
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
```css
|
|
314
|
-
.resumo-cadastro {
|
|
315
|
-
color: rgb(var(--content-primary));
|
|
316
|
-
background-color: rgb(var(--surface-page));
|
|
317
|
-
border: 1px solid rgb(var(--border-default));
|
|
318
|
-
padding: var(--spacing-md);
|
|
319
|
-
border-radius: var(--border-radius-md);
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
.resumo-cadastro:focus-visible {
|
|
323
|
-
outline: 2px solid rgb(var(--focus-ring));
|
|
324
|
-
outline-offset: 2px;
|
|
325
|
-
}
|
|
326
|
-
```
|
|
65
|
+
## Organização do Design System
|
|
327
66
|
|
|
328
|
-
|
|
67
|
+
- **Components**: controles de ação, formulários, feedback, navegação, dados, documentos, overlays e layout.
|
|
68
|
+
- **Foundations**: cores, tipografia, espaçamento e sombras derivados dos tokens.
|
|
69
|
+
- **Themes**: esquema claro/escuro, contraste, escala tipográfica e presets de identidade.
|
|
70
|
+
- **Hooks e utilitários**: breakpoints, acessibilidade, preferências e posicionamento.
|
|
71
|
+
- **Countries e charts**: dados de países/bandeiras e integrações de gráficos.
|
|
329
72
|
|
|
330
|
-
|
|
73
|
+
Os tokens canônicos ficam em `tokens/design-system.tokens.json`. Arquivos CSS gerados não devem ser editados manualmente.
|
|
331
74
|
|
|
332
|
-
|
|
75
|
+
## Storybook
|
|
333
76
|
|
|
334
|
-
|
|
77
|
+
Instale as dependências e inicie a documentação visual:
|
|
335
78
|
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
--font-family-base: var(--font-nunito-sans), sans-serif;
|
|
340
|
-
}
|
|
79
|
+
```bash
|
|
80
|
+
npm install
|
|
81
|
+
npm run storybook
|
|
341
82
|
```
|
|
342
83
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
### Boas práticas de acessibilidade
|
|
346
|
-
|
|
347
|
-
- Use títulos em ordem, rótulos de campos e texto que explique status e erros.
|
|
348
|
-
- Mantenha foco visível e verifique Tab, Enter, Espaço e Escape nos controles interativos.
|
|
349
|
-
- Teste claro, escuro e alto contraste, além de fonte ampliada e movimento reduzido.
|
|
350
|
-
- Em ações com ícone sem texto, forneça um nome acessível, como `aria-label`.
|
|
351
|
-
- Verifique o conteúdo da aplicação com leitor de tela; a composição e os textos também influenciam a acessibilidade.
|
|
352
|
-
|
|
353
|
-
## Países e bandeiras locais
|
|
354
|
-
|
|
355
|
-
A lista contém 250 países/territórios. `COUNTRY_OPTIONS` e `PHONE_COUNTRY_OPTIONS` são a mesma lista; `getCountryOptions()` retorna uma cópia editável. Os componentes usam a lista automaticamente quando `options`/`countries` são omitidos. Por isso, `/forms` e a raiz incluem os dados; `/core` não os exige.
|
|
84
|
+
O servidor usa a porta `6006`. Para a configuração standalone:
|
|
356
85
|
|
|
357
|
-
```
|
|
358
|
-
|
|
359
|
-
import { SelectCountry, InputPhone } from "@aspprev/versi-ds/forms";
|
|
360
|
-
|
|
361
|
-
<Formik
|
|
362
|
-
initialValues={{ pais: "Brasil", telefone: { ddi: 55, ddd: "", numero: "" } }}
|
|
363
|
-
onSubmit={() => {}}
|
|
364
|
-
>
|
|
365
|
-
<form>
|
|
366
|
-
<SelectCountry
|
|
367
|
-
name="pais"
|
|
368
|
-
label="País"
|
|
369
|
-
countryList={{ mode: "include", codes: ["BR", "PT", "US"] }}
|
|
370
|
-
/>
|
|
371
|
-
<InputPhone
|
|
372
|
-
name="telefone"
|
|
373
|
-
label="Telefone"
|
|
374
|
-
countryList={{ mode: "exclude", codes: ["US"] }}
|
|
375
|
-
/>
|
|
376
|
-
</form>
|
|
377
|
-
</Formik>;
|
|
86
|
+
```bash
|
|
87
|
+
npm run storybook:standalone
|
|
378
88
|
```
|
|
379
89
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
90
|
+
A árvore da documentação é organizada assim:
|
|
91
|
+
|
|
92
|
+
```text
|
|
93
|
+
Getting Started
|
|
94
|
+
├── Introduction
|
|
95
|
+
├── Installation
|
|
96
|
+
├── Usage
|
|
97
|
+
└── Contributing
|
|
98
|
+
|
|
99
|
+
Foundations
|
|
100
|
+
├── Overview
|
|
101
|
+
├── Colors
|
|
102
|
+
├── Typography
|
|
103
|
+
├── Spacing
|
|
104
|
+
└── Shadows
|
|
105
|
+
|
|
106
|
+
Components
|
|
107
|
+
├── Actions
|
|
108
|
+
├── Forms
|
|
109
|
+
├── Feedback
|
|
110
|
+
├── Data Display
|
|
111
|
+
├── Documents
|
|
112
|
+
├── Navigation
|
|
113
|
+
├── Overlay
|
|
114
|
+
├── Layout
|
|
115
|
+
└── Accessibility
|
|
116
|
+
|
|
117
|
+
Patterns
|
|
118
|
+
├── Forms
|
|
119
|
+
└── Feedback
|
|
120
|
+
|
|
121
|
+
Themes
|
|
122
|
+
├── Overview
|
|
123
|
+
├── Comparison
|
|
124
|
+
└── ThemeLab
|
|
125
|
+
|
|
126
|
+
Guidelines
|
|
127
|
+
├── Accessibility
|
|
128
|
+
└── Usage
|
|
386
129
|
```
|
|
387
130
|
|
|
388
|
-
|
|
131
|
+
A toolbar permite comparar esquema de cores, preset, contraste, escala de fonte e movimento reduzido. O addon de acessibilidade permanece disponível para inspeção manual e os testes automatizados usam Axe nos cenários visuais.
|
|
389
132
|
|
|
390
133
|
## Desenvolvimento e validação
|
|
391
134
|
|
|
392
135
|
```bash
|
|
393
|
-
npm install
|
|
394
136
|
npm run tokens:check
|
|
395
|
-
npm run check:governance
|
|
396
137
|
npm run typecheck
|
|
397
|
-
npm run build
|
|
398
138
|
npm test
|
|
399
|
-
npm run
|
|
139
|
+
npm run build
|
|
400
140
|
npm run build-storybook
|
|
401
|
-
npx playwright install chromium
|
|
402
141
|
npm run test:visual
|
|
403
142
|
npm run check:package
|
|
404
|
-
npm run
|
|
405
|
-
npm pack --dry-run
|
|
143
|
+
npm run prepack
|
|
406
144
|
```
|
|
407
145
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
Use `npm run storybook` (6006) ou `npm run storybook:standalone` (6007). Playwright inicia seu próprio servidor; `STORYBOOK_DS_PORT` altera a porta. As referências visuais existentes são Chromium/Windows, desktop e mobile. Revise diferenças antes de usar `npm run test:visual:update`. Axe e testes automatizados não substituem revisão manual com leitor de tela.
|
|
411
|
-
|
|
412
|
-
No Storybook, abra o grupo `Design System` e escolha um componente. Use suas stories para comparar estados e variantes, e os controles para experimentar as propriedades disponíveis. A barra de ferramentas altera esquema de cores, paleta, contraste, escala da fonte e movimento. O `ThemeLab/Playground` reúne a exploração dos temas; o painel de acessibilidade ajuda na inspeção de cada cenário.
|
|
413
|
-
|
|
414
|
-
`prepack` verifica tokens, governança, TypeScript, build, tamanho e conteúdo antes de empacotar. O tarball inclui somente `dist/`, `README.md` e o `package.json` obrigatório do npm. Stories, testes, documentação interna e ferramentas não são publicados. Sourcemaps em `dist` são intencionais para diagnóstico.
|
|
146
|
+
O script `prepack` valida tokens, governança, segurança, TypeScript, build, tamanho e conteúdo do pacote. O projeto não possui um script `lint` separado.
|
|
415
147
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
O repositório inclui uma aplicação React/Vite em `examples/pilot`, com cadastro,
|
|
419
|
-
validação de formulário, países/telefone, tabela, modal e controles de aparência.
|
|
420
|
-
Ela instala o DS a partir do tarball e usa apenas os entrypoints públicos.
|
|
421
|
-
|
|
422
|
-
Na raiz do repositório:
|
|
148
|
+
Para testar o exemplo integrado:
|
|
423
149
|
|
|
424
150
|
```bash
|
|
425
151
|
npm run pilot:prepare
|
|
426
|
-
npm run pilot
|
|
152
|
+
npm run test:pilot
|
|
427
153
|
```
|
|
428
154
|
|
|
429
|
-
|
|
430
|
-
`npm run test:pilot`. As instruções completas estão em `examples/pilot/README.md`.
|
|
431
|
-
O exemplo não faz parte do pacote npm e seus dados ficam somente na memória da página.
|
|
155
|
+
Antes de uma publicação, gere um tarball local com `npm pack` e valide sua instalação nos consumidores.
|
|
432
156
|
|
|
433
|
-
##
|
|
157
|
+
## Temas
|
|
434
158
|
|
|
435
|
-
|
|
436
|
-
| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
|
|
437
|
-
| Componentes sem estilo | Importe styles.css uma vez na entrada da aplicação e verifique regras que o sobrescrevem. |
|
|
438
|
-
| Uma classe Tailwind própria não funciona | O CSS do pacote inclui as classes dos componentes; compile as classes da sua aplicação ou use CSS próprio. |
|
|
439
|
-
| Erro ao resolver Formik, Headless UI ou outra integração | Instale os peers da camada importada. A entrada raiz precisa do conjunto completo. |
|
|
440
|
-
| Erro de contexto Formik | Envolva os controles integrados em Formik; para Input controlado, use InputStandalone. |
|
|
441
|
-
| Bandeiras não aparecem | Confirme que /flags/br.svg responde no domínio da aplicação e copie dist/flags para os arquivos públicos. |
|
|
442
|
-
| SelectCountry não mostra o valor inicial | Na lista padrão, use Brasil como valor; BR é o código de filtragem ISO-2. |
|
|
443
|
-
| Diálogo ou dropdown com tema diferente | Aplique os atributos de tema no html para alcançar também os elementos renderizados fora da árvore do componente. |
|
|
444
|
-
| Fonte diferente do Storybook | Carregue a fonte desejada e configure --font-nunito-sans; a fonte não acompanha o pacote. |
|
|
445
|
-
| Erro de hooks em aplicação RSC | Defina estado e callbacks em um componente cliente; consulte a seção sobre servidor e navegador. |
|
|
159
|
+
As preferências são controladas pelo consumidor no elemento `html`:
|
|
446
160
|
|
|
447
|
-
|
|
161
|
+
```ts
|
|
162
|
+
const root = document.documentElement;
|
|
163
|
+
root.dataset.colorScheme = "dark";
|
|
164
|
+
root.dataset.dsTheme = "azul1";
|
|
165
|
+
root.dataset.contrast = "high";
|
|
166
|
+
root.dataset.fontScale = "large";
|
|
167
|
+
root.dataset.motion = "reduce";
|
|
168
|
+
```
|
|
448
169
|
|
|
449
|
-
|
|
170
|
+
Os valores válidos estão documentados em **Themes/Overview** no Storybook. Prefira tokens semânticos, como `--surface-page`, `--content-primary`, `--border-default` e `--focus-ring`, em vez de copiar valores de uma paleta.
|
|
450
171
|
|
|
451
|
-
|
|
452
|
-
| --------------------------------- | ------------------------------------------------------- |
|
|
453
|
-
| docs/API-PUBLICA-CONTROLES.md | Contratos dos controles, estado, teclado e dependências |
|
|
454
|
-
| docs/COMPONENTES-CLIENT-SERVER.md | Fronteiras cliente e servidor |
|
|
455
|
-
| docs/THEMELAB-E-GLOBALS-CSS.md | Temas e personalização do CSS |
|
|
456
|
-
| tokens/README.md | Fonte e geração dos tokens |
|
|
457
|
-
| docs/GOVERNANCA-DESIGN-SYSTEM.md | Contribuição, versionamento e publicação |
|
|
458
|
-
| docs/EVOLUCAO-DESIGN-SYSTEM.md | Histórico de mudanças e validações |
|
|
172
|
+
## Contribuição
|
|
459
173
|
|
|
460
|
-
|
|
461
|
-
# versi-design-system
|
|
174
|
+
Ao criar ou alterar um componente:
|
|
462
175
|
|
|
176
|
+
1. reutilize tokens e componentes existentes;
|
|
177
|
+
2. mantenha a API tipada e compatível com React;
|
|
178
|
+
3. garanta foco visível, teclado, nomes acessíveis, erros e estados de carregamento;
|
|
179
|
+
4. crie ou atualize stories com estados relevantes;
|
|
180
|
+
5. adicione testes unitários, de interação e de acessibilidade quando aplicável;
|
|
181
|
+
6. execute `npm run prepack` antes de gerar o pacote.
|
|
463
182
|
|
|
183
|
+
Detalhes de contratos, governança e segurança ficam na pasta `docs/`. A documentação de uso visual deve permanecer principalmente no Storybook.
|
package/dist/charts.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/document-item/DocumentItem.tsx"],"sourcesContent":["import classNames from \"classnames\";\nimport type { HTMLAttributes, ReactNode } from \"react\";\n\nexport interface DocumentItemDetail {\n label: ReactNode;\n value: ReactNode;\n}\n\nexport interface DocumentItemProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"title\"> {\n title: ReactNode;\n label?: ReactNode;\n description?: ReactNode;\n details?: DocumentItemDetail[];\n status?: ReactNode;\n actions?: ReactNode;\n illustration?: ReactNode;\n variant?: \"plain\" | \"subtle\";\n titleClassName?: string;\n}\n\nexport function DocumentItem({\n title,\n label,\n description,\n details = [],\n status,\n actions,\n illustration,\n variant = \"plain\",\n titleClassName,\n className,\n ...rest\n}: DocumentItemProps) {\n return (\n <div\n className={classNames(\n \"flex min-w-0 flex-col gap-4 rounded-md tablet:flex-row tablet:items-center tablet:justify-between\",\n variant === \"subtle\" && \"bg-surface-subtle p-4 tablet:p-5\",\n className,\n )}\n {...rest}\n >\n <div className=\"min-w-0 flex-1 space-y-3\">\n <div className=\"min-w-0\">\n {label && (\n <p className=\"text-sm text-content-secondary\">{label}</p>\n )}\n <p\n className={classNames(\n \"break-words text-content-primary\",\n titleClassName,\n )}\n >\n {title}\n </p>\n {description && (\n <div className=\"mt-1 break-words text-sm text-content-secondary\">\n {description}\n </div>\n )}\n </div>\n\n {(details.length > 0 || status) && (\n <div className=\"flex flex-wrap items-start gap-x-8 gap-y-3\">\n {details.map((detail, index) => (\n <div key={index} className=\"min-w-0\">\n <p className=\"text-sm text-content-secondary\">{detail.label}</p>\n <div className=\"break-words font-semibold text-content-primary\">\n {detail.value}\n </div>\n </div>\n ))}\n {status && <div className=\"min-w-0\">{status}</div>}\n </div>\n )}\n </div>\n\n {illustration && (\n <div className=\"hidden shrink-0 desktop:block\" aria-hidden=\"true\">\n {illustration}\n </div>\n )}\n\n {actions && (\n <div className=\"flex w-full shrink-0 flex-col gap-2 tablet:w-auto tablet:flex-row tablet:flex-wrap tablet:justify-end\">\n {actions}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;AAAA,OAAO,gBAAgB;AA4Cf,SAEI,KAFJ;AAvBD,SAAS,aAAa,IAYP;AAZO,eAC3B;AAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,CAAC;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA;AAAA,EA/BF,IAqB6B,IAWxB,iBAXwB,IAWxB;AAAA,IAVH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAGA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA,YAAY,YAAY;AAAA,QACxB;AAAA,MACF;AAAA,OACI,OANL;AAAA,MAQC;AAAA,6BAAC,SAAI,WAAU,4BACb;AAAA,+BAAC,SAAI,WAAU,WACZ;AAAA,qBACC,oBAAC,OAAE,WAAU,kCAAkC,iBAAM;AAAA,YAEvD;AAAA,cAAC;AAAA;AAAA,gBACC,WAAW;AAAA,kBACT;AAAA,kBACA;AAAA,gBACF;AAAA,gBAEC;AAAA;AAAA,YACH;AAAA,YACC,eACC,oBAAC,SAAI,WAAU,mDACZ,uBACH;AAAA,aAEJ;AAAA,WAEE,QAAQ,SAAS,KAAK,WACtB,qBAAC,SAAI,WAAU,8CACZ;AAAA,oBAAQ,IAAI,CAAC,QAAQ,UACpB,qBAAC,SAAgB,WAAU,WACzB;AAAA,kCAAC,OAAE,WAAU,kCAAkC,iBAAO,OAAM;AAAA,cAC5D,oBAAC,SAAI,WAAU,kDACZ,iBAAO,OACV;AAAA,iBAJQ,KAKV,CACD;AAAA,YACA,UAAU,oBAAC,SAAI,WAAU,WAAW,kBAAO;AAAA,aAC9C;AAAA,WAEJ;AAAA,QAEC,gBACC,oBAAC,SAAI,WAAU,iCAAgC,eAAY,QACxD,wBACH;AAAA,QAGD,WACC,oBAAC,SAAI,WAAU,yGACZ,mBACH;AAAA;AAAA;AAAA,EAEJ;AAEJ;","names":[]}
|
|
@@ -306,9 +306,10 @@ var Tooltip = ({
|
|
|
306
306
|
var Tooltip_default = Tooltip;
|
|
307
307
|
|
|
308
308
|
export {
|
|
309
|
+
breakpoints,
|
|
309
310
|
useBreakpoint,
|
|
310
311
|
mergeAriaDescribedBy,
|
|
311
312
|
getFloatingLayerClass,
|
|
312
313
|
Tooltip_default
|
|
313
314
|
};
|
|
314
|
-
//# sourceMappingURL=chunk-
|
|
315
|
+
//# sourceMappingURL=chunk-ET2BGHTO.js.map
|