ads-nuxt 0.1.1 → 0.1.3

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.
Files changed (74) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +577 -546
  3. package/app/app.config.ts +25 -25
  4. package/app/assets/ads/checkbox-check.svg +5 -5
  5. package/app/assets/ads/checkbox-minus.svg +5 -5
  6. package/app/assets/brand/farmarcas.svg +6 -6
  7. package/app/assets/brand/radar.svg +9 -9
  8. package/app/assets/css/component-tokens.css +403 -403
  9. package/app/assets/css/main.css +617 -617
  10. package/app/components/AdsBadge.vue +48 -48
  11. package/app/components/AdsBroadcast.vue +45 -45
  12. package/app/components/AdsButton.vue +569 -569
  13. package/app/components/AdsButtonGroup.vue +39 -39
  14. package/app/components/AdsButtonMenu.vue +48 -48
  15. package/app/components/AdsCard.vue +117 -117
  16. package/app/components/AdsCharttip.vue +78 -78
  17. package/app/components/AdsCheckbox.vue +77 -77
  18. package/app/components/AdsDatePicker.vue +473 -473
  19. package/app/components/AdsDropdownMenu.vue +19 -19
  20. package/app/components/AdsEmptyState.vue +58 -58
  21. package/app/components/AdsFarmarcasPill.vue +74 -74
  22. package/app/components/AdsFeatureCard.vue +217 -217
  23. package/app/components/AdsFileCard.vue +101 -101
  24. package/app/components/AdsFilterDropdown.vue +174 -174
  25. package/app/components/AdsFilterOption.vue +72 -72
  26. package/app/components/AdsFilterSelect.vue +202 -202
  27. package/app/components/AdsFooter.vue +25 -25
  28. package/app/components/AdsInput.vue +143 -143
  29. package/app/components/AdsListDropdown.vue +44 -44
  30. package/app/components/AdsLoading.vue +109 -109
  31. package/app/components/AdsMenuBar.vue +103 -103
  32. package/app/components/AdsMetricCard.vue +119 -119
  33. package/app/components/AdsMiniPill.vue +40 -40
  34. package/app/components/AdsModal.vue +157 -157
  35. package/app/components/AdsMonthPicker.vue +80 -80
  36. package/app/components/AdsNavbarApp.vue +67 -67
  37. package/app/components/AdsNavbarDesk.vue +62 -62
  38. package/app/components/AdsNotabilityPill.vue +27 -27
  39. package/app/components/AdsNumberInput.vue +166 -166
  40. package/app/components/AdsPagination.vue +91 -91
  41. package/app/components/AdsProductTag.vue +61 -61
  42. package/app/components/AdsRadio.vue +70 -70
  43. package/app/components/AdsSearchInput.vue +113 -113
  44. package/app/components/AdsSegmentedTabs.vue +28 -28
  45. package/app/components/AdsSideMenu.vue +101 -101
  46. package/app/components/AdsSmalltip.vue +44 -44
  47. package/app/components/AdsSteptip.vue +101 -101
  48. package/app/components/AdsSwitch.vue +59 -59
  49. package/app/components/AdsTable.vue +100 -100
  50. package/app/components/AdsTableToolbar.vue +44 -44
  51. package/app/components/AdsTabs.vue +51 -51
  52. package/app/components/AdsTextarea.vue +109 -109
  53. package/app/components/AdsToast.vue +181 -181
  54. package/app/components/AdsTooltip.vue +66 -66
  55. package/app/components/InvertedTooltip.vue +40 -40
  56. package/app/components/OverlayLoading.vue +173 -173
  57. package/app/components/ProgressBarLoading.vue +256 -256
  58. package/app/composables/useOverlayLoading.ts +66 -66
  59. package/app/locale/pt-br.ts +6 -6
  60. package/app/plugins/ads-toast.client.ts +24 -24
  61. package/app/theme/ads-theme.ts +370 -370
  62. package/app/theme/component-tokens.json +402 -402
  63. package/app/theme/component-tokens.ts +815 -815
  64. package/app/types/overlay-loading.types.ts +26 -26
  65. package/app/utils/ads-filter-select.ts +172 -172
  66. package/app/utils/ads-table.ts +204 -204
  67. package/app/utils/calendar-date.ts +128 -128
  68. package/app/utils/category-role.ts +45 -45
  69. package/app/utils/money.ts +77 -77
  70. package/app/utils/notability.ts +8 -8
  71. package/app/utils/parser.ts +134 -134
  72. package/app/utils/percentage.ts +54 -54
  73. package/nuxt.config.ts +31 -32
  74. package/package.json +55 -46
package/README.md CHANGED
@@ -1,546 +1,577 @@
1
- # ads-nuxt
2
-
3
- **Alquimia Design System (ADS)** para Nuxt, construído sobre o [Nuxt UI](https://ui.nuxt.com) v4 e o Tailwind CSS v4.
4
-
5
- O pacote é uma **Nuxt Layer**: ao estendê-lo, seu projeto recebe de uma vez os componentes `Ads*`, os tokens de design (cores, espaçamento, raios, sombras, tipografia), o tema do Nuxt UI customizado, os utilitários de formatação em pt-BR e a fonte Inter.
6
-
7
- [![npm](https://img.shields.io/npm/v/ads-nuxt.svg)](https://www.npmjs.com/package/ads-nuxt)
8
- [![license](https://img.shields.io/npm/l/ads-nuxt.svg)](./LICENSE)
9
-
10
- ---
11
-
12
- ## Sumário
13
-
14
- - [Recursos](#recursos)
15
- - [Requisitos](#requisitos)
16
- - [Instalação](#instalação)
17
- - [Configuração](#configuração)
18
- - [Uso rápido](#uso-rápido)
19
- - [Componentes](#componentes)
20
- - [Exemplos](#exemplos)
21
- - [Tokens de design](#tokens-de-design)
22
- - [Tema do Nuxt UI](#tema-do-nuxt-ui)
23
- - [Composables](#composables)
24
- - [Utilitários](#utilitários)
25
- - [Localização (pt-BR)](#localização-pt-br)
26
- - [Desenvolvimento](#desenvolvimento)
27
- - [Estrutura do projeto](#estrutura-do-projeto)
28
- - [Licença](#licença)
29
-
30
- ---
31
-
32
- ## Recursos
33
-
34
- - **Mais de 50 componentes** prontos para produção, com prefixo `Ads` (auto-importados pelo Nuxt).
35
- - **Tokens em três camadas** (primitivos → semânticos → de componente), expostos como variáveis CSS `--ads-*` e como cores do Tailwind (`ads-*`).
36
- - **Tema do Nuxt UI** pré-configurado: botão, input, calendário, select, toast e tooltip já seguem o visual ADS.
37
- - **Fonte Inter** configurada via `@nuxt/fonts`.
38
- - **Ícones Lucide** via `@nuxt/icon` (use `i-lucide-*`).
39
- - **Utilitários pt-BR**: moeda (BRL), porcentagem, datas, notabilidade e filtros.
40
- - **Playground** com documentação viva de todos os componentes e tokens.
41
- - Estados “congeláveis” (`state`) nos componentes, pensados para documentação e testes visuais.
42
-
43
- ## Requisitos
44
-
45
- | Dependência | Versão |
46
- | ----------- | --------- |
47
- | Node.js | 20+ (recomendado 22) |
48
- | Nuxt | `^4.0.0` |
49
- | Vue | `^3.5.18` |
50
-
51
- `nuxt` e `vue` são *peer dependencies*. As demais (`@nuxt/ui`, `@nuxt/fonts`, `@nuxt/icon`, `@vueuse/nuxt`, `tailwindcss`, ícones Lucide) já vêm como dependências do pacote.
52
-
53
- ## Instalação
54
-
55
- ```bash
56
- # pnpm
57
- pnpm add ads-nuxt
58
-
59
- # npm
60
- npm install ads-nuxt
61
-
62
- # yarn
63
- yarn add ads-nuxt
64
- ```
65
-
66
- ## Configuração
67
-
68
- Estenda a layer no `nuxt.config.ts` do seu projeto:
69
-
70
- ```ts
71
- // nuxt.config.ts
72
- export default defineNuxtConfig({
73
- extends: ["ads-nuxt"],
74
- });
75
- ```
76
-
77
- Isso já registra automaticamente:
78
-
79
- - os módulos `@nuxt/ui`, `@nuxt/fonts`, `@nuxt/icon` e `@vueuse/nuxt`;
80
- - o CSS global (Tailwind, Nuxt UI, cores e tokens de componente);
81
- - a fonte **Inter** (pesos 300, 400, 500, 700 e 800);
82
- - a coleção de ícones **lucide**;
83
- - o `app.config.ts` com o tema ADS para o Nuxt UI;
84
- - o plugin de toast e o locale pt-BR.
85
-
86
- > **Modo de cor:** a layer define `ui.colorMode: false` — o ADS é um sistema de tema claro. Se precisar sobrescrever, redefina no `nuxt.config.ts` do seu projeto.
87
-
88
- ### Envolva o app com `UApp`
89
-
90
- O Nuxt UI exige o componente `UApp` para toasts, tooltips e overlays funcionarem:
91
-
92
- ```vue
93
- <!-- app/app.vue -->
94
- <template>
95
- <UApp :locale="uiLocale" :tooltip="{ delayDuration: 400 }" :toaster="adsToaster">
96
- <NuxtPage />
97
- </UApp>
98
- </template>
99
-
100
- <script setup lang="ts">
101
- import { uiLocale } from "ads-nuxt/app/locale/pt-br";
102
- import { adsToaster } from "ads-nuxt/app/theme/ads-theme";
103
- </script>
104
- ```
105
-
106
- `adsToaster` posiciona os toasts no canto superior direito, sem barra de progresso, no padrão ADS.
107
-
108
- ## Uso rápido
109
-
110
- Os componentes são auto-importados, sem `import` manual:
111
-
112
- ```vue
113
- <template>
114
- <AdsCard title="Cadastro" description="Preencha os dados abaixo.">
115
- <div class="flex flex-col gap-4">
116
- <AdsInput v-model="nome" label="Nome" placeholder="Digite seu nome" />
117
- <AdsButton type="filled" label="Salvar" leading icon="i-lucide-save" />
118
- </div>
119
- </AdsCard>
120
- </template>
121
-
122
- <script setup lang="ts">
123
- const nome = ref("");
124
- </script>
125
- ```
126
-
127
- ## Componentes
128
-
129
- ### Ações
130
-
131
- | Componente | Descrição |
132
- | ---------------- | --------- |
133
- | `AdsButton` | Botão (`filled`, `outline`, `unfilled`, `secondary`, `ia`) em 2 tamanhos e 8 cores. Suporta ícones, `loading` e `to` (vira link). |
134
- | `AdsButtonGroup` | Agrupa botões. |
135
- | `AdsButtonMenu` | Botão com menu de ações. |
136
-
137
- ### Formulários
138
-
139
- | Componente | Descrição |
140
- | ----------------- | --------- |
141
- | `AdsInput` | Campo de texto/número com label, hint, erro, info, ícone e sufixo. |
142
- | `AdsNumberInput` | Campo numérico dedicado. |
143
- | `AdsTextarea` | Área de texto. |
144
- | `AdsSearchInput` | Campo de busca. |
145
- | `AdsCheckbox` | Checkbox com estado indeterminado. |
146
- | `AdsRadio` | Botão de rádio. |
147
- | `AdsSwitch` | Alternador (toggle). |
148
- | `AdsDatePicker` | Seletor de data ou intervalo, com `min`, `max` e `maximumDays`. |
149
- | `AdsMonthPicker` | Seletor de mês. |
150
- | `AdsFilterSelect` | Filtro com seleção (checkbox, radio ou mês). |
151
- | `AdsFilterDropdown` / `AdsFilterOption` | Dropdown de filtros e suas opções. |
152
-
153
- ### Navegação
154
-
155
- | Componente | Descrição |
156
- | ----------------- | --------- |
157
- | `AdsNavbarDesk` / `AdsNavbarApp` | Barra de navegação desktop e mobile. |
158
- | `AdsSideMenu` | Menu lateral. |
159
- | `AdsMenuBar` | Barra de menu. |
160
- | `AdsTabs` | Abas em formato de link. |
161
- | `AdsSegmentedTabs`| Abas segmentadas. |
162
- | `AdsPagination` | Paginação com reticências automáticas (`v-model:page`). |
163
- | `AdsDropdownMenu` / `AdsListDropdown` | Menus suspensos. |
164
- | `AdsFooter` | Rodapé. |
165
-
166
- ### Exibição de dados
167
-
168
- | Componente | Descrição |
169
- | ----------------- | --------- |
170
- | `AdsTable` | Tabela baseada no `UTable`, com densidade, zebra, bordas, degradê por nível, `sticky`, loading e estado vazio. |
171
- | `AdsTableToolbar` | Barra de ferramentas da tabela. |
172
- | `AdsCard` | Cartão genérico. |
173
- | `AdsMetricCard` | Cartão de métrica/indicador. |
174
- | `AdsFeatureCard` | Cartão de funcionalidade. |
175
- | `AdsFileCard` | Cartão de arquivo. |
176
- | `AdsEmptyState` | Estado vazio. |
177
-
178
- ### Indicadores e status
179
-
180
- | Componente | Descrição |
181
- | -------------------- | --------- |
182
- | `AdsBadge` | Contador ou ponto (`mini`) em 7 cores. |
183
- | `AdsPill` | Pílula de status (`default`, `success`, `attention`, `warning`, `new`, `blocked`, `innovation`, `neutral`) em tom `primary` ou `secondary`. |
184
- | `AdsMiniPill` | Versão compacta da pílula. |
185
- | `AdsNotabilityPill` | Pílula de notabilidade. |
186
- | `AdsFarmarcasPill` | Pílula de marca Farmarcas. |
187
- | `AdsProductTag` | Tag de produto. |
188
-
189
- ### Feedback e overlays
190
-
191
- | Componente | Descrição |
192
- | ----------------- | --------- |
193
- | `AdsModal` | Modal (`dialog` ou `sheet`) com 5 tamanhos, ações padrão e slots. |
194
- | `AdsToast` | Aviso em faixa (`banner`) ou reporte escuro (`status`). |
195
- | `AdsBroadcast` | Comunicado em destaque. |
196
- | `AdsTooltip` | Tooltip. |
197
- | `AdsSmalltip` / `AdsSteptip` / `AdsCharttip` | Variações de tooltip (compacta, em passos e para gráficos). |
198
- | `AdsLoading` | Indicador de carregamento. |
199
- | `ProgressBarLoading` | Barra de progresso. |
200
- | `OverlayLoading` | Overlay de carregamento/sucesso/erro (usado por `useOverlayLoading`). |
201
-
202
- ## Exemplos
203
-
204
- ### Botões
205
-
206
- ```vue
207
- <AdsButton type="filled" label="Salvar" />
208
- <AdsButton type="outline" color="success" label="Aprovar" />
209
- <AdsButton type="unfilled" size="sm" label="Cancelar" />
210
- <AdsButton type="ia" label="Gerar com IA" leading icon="i-lucide-sparkles" />
211
- <AdsButton type="filled" label="Enviando" loading />
212
- <AdsButton type="filled" label="Ir para o painel" to="/painel" />
213
- ```
214
-
215
- | Prop | Valores |
216
- | ------------ | ------- |
217
- | `type` | `filled` \| `outline` \| `unfilled` \| `secondary` \| `ia` |
218
- | `color` | `primary` \| `success` \| `attention` \| `warning` \| `new` \| `innovation` \| `blocked` \| `neutral` |
219
- | `size` | `md` \| `sm` |
220
- | `nativeType` | `button` \| `submit` \| `reset` (a prop `type` é o visual do ADS) |
221
-
222
- ### Campos de formulário
223
-
224
- ```vue
225
- <AdsInput
226
- v-model="preco"
227
- label="Preço"
228
- hint="Valor unitário"
229
- suffix="R$"
230
- type="number"
231
- :error="erro"
232
- />
233
- ```
234
-
235
- Estados disponíveis via `state` (útil para documentação): `default`, `active`, `focus`, `error`, `disabled` e `ai`.
236
-
237
- ### Modal
238
-
239
- ```vue
240
- <template>
241
- <AdsButton label="Excluir" color="warning" @click="aberto = true" />
242
-
243
- <AdsModal
244
- v-model:open="aberto"
245
- title="Excluir item"
246
- description="Essa ação não pode ser desfeita."
247
- cancel-label="Cancelar"
248
- confirm-label="Excluir"
249
- @confirm="excluir"
250
- @cancel="aberto = false"
251
- />
252
- </template>
253
-
254
- <script setup lang="ts">
255
- const aberto = ref(false);
256
- const excluir = () => {
257
- /* ... */
258
- aberto.value = false;
259
- };
260
- </script>
261
- ```
262
-
263
- Eventos: `confirm`, `cancel` e `dismiss` (com o motivo `"esc"` ou `"outside"`). Slots: `default`, `title` e `footer`.
264
-
265
- ### Toast
266
-
267
- Como componente em linha:
268
-
269
- ```vue
270
- <AdsToast status="success" title="Tudo certo" message="Alterações salvas." />
271
- <AdsToast status="error" message="Falha ao salvar." action-label="Tentar novamente" />
272
- <AdsToast appearance="status" status="neutral" title="Relatório" subtitle="Explicação opcional" />
273
- ```
274
-
275
- Como toast flutuante, usando o `useToast` do Nuxt UI (as cores de status e os ícones do ADS são aplicados automaticamente pelo plugin da layer):
276
-
277
- ```ts
278
- const toast = useToast();
279
-
280
- toast.add({
281
- title: "Salvo",
282
- description: "Suas alterações foram salvas.",
283
- color: "success",
284
- });
285
- ```
286
-
287
- ### Pílulas e badges
288
-
289
- ```vue
290
- <AdsPill status="success" label="Ativo" />
291
- <AdsPill status="warning" tone="secondary" label="Atrasado" icon="i-lucide-alert-triangle" />
292
- <AdsBadge color="primary" :value="5" />
293
- <AdsBadge color="warning" mini />
294
- ```
295
-
296
- ### Paginação e abas
297
-
298
- ```vue
299
- <AdsPagination v-model:page="pagina" :total-pages="20" />
300
-
301
- <AdsTabs v-model="aba" :items="itens" />
302
- ```
303
-
304
- ### Tabela
305
-
306
- ```vue
307
- <AdsTable
308
- :data="linhas"
309
- :columns="colunas"
310
- density="md"
311
- striped
312
- :loading="carregando"
313
- empty-label="Nenhum resultado encontrado"
314
- />
315
- ```
316
-
317
- Para montar colunas, a layer exporta helpers em `app/utils/ads-table.ts`, como `adsTableColumn`, `adsTablePinned`, `adsTableGroup`, `adsTableVariationClass` e `adsTableTreeIndent`.
318
-
319
- ### Seletor de datas
320
-
321
- ```vue
322
- <!-- Data única -->
323
- <AdsDatePicker v-model="data" min="2026-01-01" />
324
-
325
- <!-- Intervalo (máximo de 31 dias) -->
326
- <AdsDatePicker range v-model:start="inicio" v-model:end="fim" :maximum-days="31" />
327
- ```
328
-
329
- As datas trafegam como string `YYYY-MM-DD`.
330
-
331
- ## Tokens de design
332
-
333
- Os tokens vêm do Figma do ADS e estão organizados em três camadas:
334
-
335
- 1. **Primitivos** — valores brutos (escalas de cor, espaçamentos).
336
- 2. **Semânticos** — intenção de uso (`--ads-surface-*`, `--ads-text-*`, `--ads-border-*`, `--ads-status-*`).
337
- 3. **De componente** — ajustes finos por componente (`--ads-button-*`, `--ads-modal-*`, `--ads-tooltip-*`…).
338
-
339
- ### Variáveis CSS
340
-
341
- ```css
342
- .meu-card {
343
- background: var(--ads-surface-main);
344
- color: var(--ads-text-secondary);
345
- border-radius: var(--ads-button-radius);
346
- box-shadow: var(--ads-shadow-level-3);
347
- }
348
- ```
349
-
350
- ### Classes Tailwind
351
-
352
- As variáveis semânticas também estão mapeadas como cores do Tailwind (`--color-ads-*`):
353
-
354
- ```html
355
- <div class="bg-ads-surface-main border-ads-border-width-thin"></div>
356
- ```
357
-
358
- ### Escalas de cor
359
-
360
- | Escala | Uso |
361
- | ------------------ | --- |
362
- | `primary` / `secondary` | Azul do Radar Pricing, de 50 a 950 (base `#006ff7`). |
363
- | `success` | Verde de sucesso (base `#15c57e`). |
364
- | Neutros | `neutralLight`, `neutralMid` e `neutralDark`. |
365
- | Status | `success`, `attention`, `warning`, `new`, `innovation`, `blocked`. |
366
-
367
- ### Espaçamento
368
-
369
- | Token | px | Token | px | Token | px |
370
- | ------ | --- | ------ | --- | ------ | --- |
371
- | quark | 4 | sm | 32 | xxxl | 120 |
372
- | nano | 8 | rg | 40 | huge | 160 |
373
- | xxxs | 12 | md | 48 | giant | 200 |
374
- | xxs | 16 | lg | 56 | | |
375
- | xs | 24 | xl / xxl | 64 / 80 | | |
376
-
377
- Os mesmos valores estão disponíveis em TypeScript, em `app/theme/ads-tokens.ts` (`adsSpacing`, `adsRadarPricing`, `adsRadarBase`, `adsNeutralLight`, `adsNeutralMid`, `adsNeutralDark`, `adsSuccess`…).
378
-
379
- ### Personalizando tokens de componente
380
-
381
- Os tokens de componente são gerados a partir de `app/theme/component-tokens.json` para `component-tokens.css`. Para ajustar no seu projeto sem editar o pacote, sobrescreva a variável CSS depois do CSS da layer:
382
-
383
- ```css
384
- :root {
385
- --ads-button-radius: 4px;
386
- --ads-button-primary: #0050b3;
387
- }
388
- ```
389
-
390
- ## Tema do Nuxt UI
391
-
392
- O `app.config.ts` da layer customiza os seguintes componentes do Nuxt UI para seguir o ADS:
393
-
394
- `button`, `input`, `inputDate`, `calendar`, `select`, `selectMenu`, `toast`, `toaster` e `tooltip`.
395
-
396
- Por ser uma layer, você pode estender ou sobrescrever no `app.config.ts` do seu projeto:
397
-
398
- ```ts
399
- // app/app.config.ts
400
- export default defineAppConfig({
401
- ui: {
402
- button: {
403
- slots: {
404
- base: "rounded-md",
405
- },
406
- },
407
- },
408
- });
409
- ```
410
-
411
- ## Composables
412
-
413
- ### `useOverlayLoading`
414
-
415
- Exibe um overlay de tela cheia para carregamento, sucesso, erro, busca ou informação, com barra de progresso opcional.
416
-
417
- ```ts
418
- const overlay = useOverlayLoading();
419
-
420
- overlay.show({
421
- variant: "loading",
422
- title: "Processando",
423
- description: "Isso pode levar alguns segundos.",
424
- showProgress: true,
425
- progress: 10,
426
- });
427
-
428
- overlay.update({ progress: 60 });
429
-
430
- overlay.update({ variant: "success", title: "Concluído!" });
431
-
432
- overlay.close();
433
- ```
434
-
435
- | Método | Descrição |
436
- | ----------------- | --------- |
437
- | `show(options)` | Abre o overlay (fecha o anterior, se houver) e retorna o id. |
438
- | `update(options)` | Mescla novas props no overlay aberto. |
439
- | `close()` | Fecha o overlay. |
440
- | `isOpen()` | Indica se há overlay aberto. |
441
- | `getCurrentId()` | Retorna o id do overlay atual. |
442
-
443
- Opções (`OverlayLoadingOptions`):
444
-
445
- | Opção | Tipo |
446
- | ----------------- | ---- |
447
- | `variant` | `"loading"` \| `"success"` \| `"error"` \| `"search"` \| `"info"` |
448
- | `title`, `description`, `hint` | `string` |
449
- | `showProgress`, `progress` | `boolean`, `number` |
450
- | `iconSrc` | `string` |
451
- | `actionLabel`, `onAction` | rótulo e callback de ação |
452
- | `onUserClose` | callback ao usuário fechar |
453
- | `closableVariants`| `("success" \| "error")[]` — variantes que o usuário pode fechar |
454
-
455
- ## Utilitários
456
-
457
- Todos ficam em `app/utils` e são auto-importados pelo Nuxt.
458
-
459
- | Arquivo | Funções principais |
460
- | --------------------- | ------------------ |
461
- | `money.ts` | `numberToBRL`, `numberToCompactBRL`, `parseStringMoneyToFloat`, `formatPriceInput`, `parsePriceInput` |
462
- | `percentage.ts` | `formatPercentage`, `formatPercentageWithDecimals`, `formatPercentagePtBr` |
463
- | `parser.ts` | `parseToPercentage`, `parsePercentageToFloat`, `getTodayDateString`, `formatDateOnlyToPtBr`, `formatDateToPtBr`, `daysBetweenDateOnly`, `daysFromTodayToDateOnly`, `normalizePercentage` |
464
- | `calendar-date.ts` | Conversão entre `string` e `CalendarDate` (`@internationalized/date`) e helpers de intervalo |
465
- | `notability.ts` | `formatNotability` |
466
- | `category-role.ts` | `CATEGORY_ROLES`, `formatCategoryRole`, `parseCategoryRole` |
467
- | `ads-filter-select.ts`| Helpers para `AdsFilterSelect` (agrupamento, seleção, rótulos, meses) |
468
- | `ads-table.ts` | Helpers e tipos para `AdsTable` |
469
-
470
- ```ts
471
- numberToBRL(1234.5); // "R$ 1.234,50"
472
- numberToBRL(-10); // "R$ -10,00"
473
- numberToBRL(null); // "-"
474
- numberToCompactBRL(2_500_000); // valor compacto em milhões
475
- ```
476
-
477
- ## Localização (pt-BR)
478
-
479
- A layer inclui `app/locale/pt-br.ts`, que exporta o locale do Nuxt UI para português do Brasil (calendário, meses e rótulos):
480
-
481
- ```ts
482
- import { uiLocale, UI_LOCALE_CODE } from "ads-nuxt/app/locale/pt-br";
483
- // UI_LOCALE_CODE === "pt-BR"
484
- ```
485
-
486
- Passe-o ao `UApp` como mostrado em [Configuração](#configuração).
487
-
488
- ## Desenvolvimento
489
-
490
- Este repositório usa **pnpm** e contém um **playground** Nuxt com a documentação interativa dos componentes e dos tokens.
491
-
492
- ```bash
493
- git clone https://github.com/jbfarmarcas/alquimia-design-system.git
494
- cd alquimia-design-system
495
- pnpm install
496
-
497
- pnpm dev # playground em http://localhost:3010
498
- pnpm build # build do playground
499
- pnpm preview # preview do build
500
- ```
501
-
502
- Páginas do playground:
503
-
504
- | Rota | Conteúdo |
505
- | ------------------------- | -------- |
506
- | `/design-system` | Catálogo de componentes com demos e código |
507
- | `/design-system/tabelas` | Variações de tabela |
508
- | `/design-system/tokens` | Editor visual dos tokens de componente |
509
-
510
- ### Docker
511
-
512
- ```bash
513
- docker compose up
514
- ```
515
-
516
- ### Publicação
517
-
518
- O pacote publica apenas `app/` e `nuxt.config.ts` (campo `files`), com acesso público:
519
-
520
- ```bash
521
- pnpm publish
522
- ```
523
-
524
- ## Estrutura do projeto
525
-
526
- ```
527
- .
528
- ├── app/ # Conteúdo publicado no npm (a layer)
529
- │ ├── app.config.ts # Tema do Nuxt UI
530
- │ ├── assets/ # CSS, SVGs de marca e animações
531
- │ ├── components/ # Componentes Ads*
532
- │ ├── composables/ # useOverlayLoading
533
- │ ├── constants/ # Constantes (swatches de cor)
534
- │ ├── locale/ # Locale pt-BR
535
- │ ├── plugins/ # Plugin de toast
536
- │ ├── theme/ # Tokens e temas (TS/JSON)
537
- │ ├── types/ # Tipos compartilhados
538
- │ └── utils/ # Utilitários de formatação e helpers
539
- ├── playground/ # App de documentação (não publicado)
540
- ├── nuxt.config.ts # Entrada da layer
541
- └── package.json
542
- ```
543
-
544
- ## Licença
545
-
546
- [MIT](./LICENSE) © 2026 Farmarcas
1
+ # ads-nuxt
2
+
3
+ **Alquimia Design System (ADS)** para Nuxt, construído sobre o [Nuxt UI](https://ui.nuxt.com) v4 e o Tailwind CSS v4.
4
+
5
+ O pacote é uma **Nuxt Layer**: ao estendê-lo, seu projeto recebe de uma vez os componentes `Ads*`, os tokens de design (cores, espaçamento, raios, sombras, tipografia), o tema do Nuxt UI customizado, os utilitários de formatação em pt-BR e a fonte Inter.
6
+
7
+ [![npm](https://img.shields.io/npm/v/ads-nuxt.svg)](https://www.npmjs.com/package/ads-nuxt)
8
+ [![license](https://img.shields.io/npm/l/ads-nuxt.svg)](./LICENSE)
9
+
10
+ ---
11
+
12
+ ## Sumário
13
+
14
+ - [Recursos](#recursos)
15
+ - [Requisitos](#requisitos)
16
+ - [Instalação](#instalação)
17
+ - [Configuração](#configuração)
18
+ - [Uso rápido](#uso-rápido)
19
+ - [Componentes](#componentes)
20
+ - [Exemplos](#exemplos)
21
+ - [Tokens de design](#tokens-de-design)
22
+ - [Tema do Nuxt UI](#tema-do-nuxt-ui)
23
+ - [Composables](#composables)
24
+ - [Utilitários](#utilitários)
25
+ - [Localização (pt-BR)](#localização-pt-br)
26
+ - [Desenvolvimento](#desenvolvimento)
27
+ - [Estrutura do projeto](#estrutura-do-projeto)
28
+ - [Licença](#licença)
29
+
30
+ ---
31
+
32
+ ## Recursos
33
+
34
+ - **Mais de 50 componentes** prontos para produção, com prefixo `Ads` (auto-importados pelo Nuxt).
35
+ - **Tokens em três camadas** (primitivos → semânticos → de componente), expostos como variáveis CSS `--ads-*` e como cores do Tailwind (`ads-*`).
36
+ - **Tema do Nuxt UI** pré-configurado: botão, input, calendário, select, toast e tooltip já seguem o visual ADS.
37
+ - **Fonte Inter** configurada via `@nuxt/fonts`.
38
+ - **Ícones Lucide** via `@nuxt/icon` (use `i-lucide-*`).
39
+ - **Utilitários pt-BR**: moeda (BRL), porcentagem, datas, notabilidade e filtros.
40
+ - **Playground** com documentação viva de todos os componentes e tokens.
41
+ - Estados “congeláveis” (`state`) nos componentes, pensados para documentação e testes visuais.
42
+
43
+ ## Requisitos
44
+
45
+ | Dependência | Versão |
46
+ | ----------- | --------- |
47
+ | Node.js | 20+ (recomendado 22) |
48
+ | Nuxt | `^4.0.0` |
49
+ | Vue | `^3.5.18` |
50
+ | `@nuxt/ui` | `^4.3.0` |
51
+ | `tailwindcss` | `^4.0.15` |
52
+ | `@nuxt/icon` | `^2.2.0` |
53
+ | `@nuxt/fonts` | `^0.12.1` ou `^0.14.0` |
54
+ | `@vueuse/nuxt` e `@vueuse/core` | `^14.0.0` |
55
+ | `@internationalized/date` | `^3.12.4` |
56
+
57
+ Todas são *peer dependencies*: ficam a cargo do seu projeto, que escolhe a versão. Assim o app não ganha uma segunda cópia do Nuxt UI nem do Tailwind. Se o projeto já usa o Nuxt UI v4, normalmente já tem quase tudo. Os ícones Lucide (`@iconify-json/lucide`) vêm como dependência do pacote.
58
+
59
+ ## Instalação
60
+
61
+ ```bash
62
+ # pnpm
63
+ pnpm add ads-nuxt @nuxt/ui @nuxt/fonts @nuxt/icon @vueuse/core @vueuse/nuxt @internationalized/date tailwindcss
64
+
65
+ # npm
66
+ npm install ads-nuxt @nuxt/ui @nuxt/fonts @nuxt/icon @vueuse/core @vueuse/nuxt @internationalized/date tailwindcss
67
+
68
+ # yarn
69
+ yarn add ads-nuxt @nuxt/ui @nuxt/fonts @nuxt/icon @vueuse/core @vueuse/nuxt @internationalized/date tailwindcss
70
+ ```
71
+
72
+ Se algum desses pacotes já estiver no `package.json`, o comando só mantém a versão existente. Para conferir que não há cópia duplicada: `pnpm why @nuxt/ui` deve mostrar uma única versão.
73
+
74
+ ### Skill para o agente de IA (opcional)
75
+
76
+ O repositório traz a skill `ads-nuxt`, que ensina o agente do seu projeto (Cursor, Claude Code e outros) a usar o ADS: componentes, tokens, utilitários e armadilhas conhecidas.
77
+
78
+ ```bash
79
+ npx skills add jbfarmarcas/alquimia-design-system --skill ads-nuxt # instalar
80
+ npx skills update ads-nuxt # atualizar
81
+ npx skills remove ads-nuxt # remover
82
+ ```
83
+
84
+ Rode na raiz do projeto que usa o `ads-nuxt`. A skill entra em `.agents/skills/ads-nuxt` e o projeto ganha um `skills-lock.json`. Faça commit dos dois e rode `update` depois de atualizar o pacote.
85
+
86
+ ## Configuração
87
+
88
+ Estenda a layer no `nuxt.config.ts` do seu projeto:
89
+
90
+ ```ts
91
+ // nuxt.config.ts
92
+ export default defineNuxtConfig({
93
+ extends: ["ads-nuxt"],
94
+ });
95
+ ```
96
+
97
+ Isso já registra automaticamente:
98
+
99
+ - os módulos `@nuxt/ui`, `@nuxt/fonts`, `@nuxt/icon` e `@vueuse/nuxt`;
100
+ - o CSS global (Tailwind, Nuxt UI, cores e tokens de componente);
101
+ - a fonte **Inter** (pesos 300, 400, 500, 700 e 800);
102
+ - a coleção de ícones **lucide**;
103
+ - o `app.config.ts` com o tema ADS para o Nuxt UI;
104
+ - o plugin de toast e o locale pt-BR.
105
+
106
+ > **Modo de cor:** a layer define `ui.colorMode: false` — o ADS é um sistema de tema claro. Se precisar sobrescrever, redefina no `nuxt.config.ts` do seu projeto.
107
+
108
+ ### Envolva o app com `UApp`
109
+
110
+ O Nuxt UI exige o componente `UApp` para toasts, tooltips e overlays funcionarem:
111
+
112
+ ```vue
113
+ <!-- app/app.vue -->
114
+ <template>
115
+ <UApp :locale="uiLocale" :tooltip="{ delayDuration: 400 }" :toaster="adsToaster">
116
+ <NuxtPage />
117
+ </UApp>
118
+ </template>
119
+
120
+ <script setup lang="ts">
121
+ import { uiLocale } from "ads-nuxt/app/locale/pt-br";
122
+ import { adsToaster } from "ads-nuxt/app/theme/ads-theme";
123
+ </script>
124
+ ```
125
+
126
+ `adsToaster` posiciona os toasts no canto superior direito, sem barra de progresso, no padrão ADS.
127
+
128
+ ## Uso rápido
129
+
130
+ Os componentes são auto-importados, sem `import` manual:
131
+
132
+ ```vue
133
+ <template>
134
+ <AdsCard title="Cadastro">
135
+ <div class="flex flex-col gap-4">
136
+ <AdsInput v-model="nome" label="Nome" placeholder="Digite seu nome" />
137
+ <AdsButton type="filled" label="Salvar" leading icon="i-lucide-save" />
138
+ </div>
139
+ </AdsCard>
140
+ </template>
141
+
142
+ <script setup lang="ts">
143
+ const nome = ref("");
144
+ </script>
145
+ ```
146
+
147
+ ## Componentes
148
+
149
+ ### Ações
150
+
151
+ | Componente | Descrição |
152
+ | ---------------- | --------- |
153
+ | `AdsButton` | Botão (`filled`, `outline`, `unfilled`, `secondary`, `ia`) em 2 tamanhos e 8 cores. Suporta ícones, `loading` e `to` (vira link). |
154
+ | `AdsButtonGroup` | Agrupa botões. |
155
+ | `AdsButtonMenu` | Botão com menu de ações. |
156
+
157
+ ### Formulários
158
+
159
+ | Componente | Descrição |
160
+ | ----------------- | --------- |
161
+ | `AdsInput` | Campo de texto/número com label, hint, erro, info, ícone e sufixo. |
162
+ | `AdsNumberInput` | Campo numérico dedicado. |
163
+ | `AdsTextarea` | Área de texto. |
164
+ | `AdsSearchInput` | Campo de busca. |
165
+ | `AdsCheckbox` | Checkbox com estado indeterminado. |
166
+ | `AdsRadio` | Botão de rádio. |
167
+ | `AdsSwitch` | Alternador (toggle). |
168
+ | `AdsDatePicker` | Seletor de data ou intervalo, com `min`, `max` e `maximumDays`. |
169
+ | `AdsMonthPicker` | Seletor de mês. |
170
+ | `AdsFilterSelect` | Filtro com seleção (checkbox, radio ou mês). |
171
+ | `AdsFilterDropdown` / `AdsFilterOption` | Dropdown de filtros e suas opções. |
172
+
173
+ ### Navegação
174
+
175
+ | Componente | Descrição |
176
+ | ----------------- | --------- |
177
+ | `AdsNavbarDesk` / `AdsNavbarApp` | Barra de navegação desktop e mobile. |
178
+ | `AdsSideMenu` | Menu lateral. |
179
+ | `AdsMenuBar` | Barra de menu. |
180
+ | `AdsTabs` | Abas em formato de link. |
181
+ | `AdsSegmentedTabs`| Abas segmentadas. |
182
+ | `AdsPagination` | Paginação com reticências automáticas (`v-model:page`). |
183
+ | `AdsDropdownMenu` / `AdsListDropdown` | Menus suspensos. |
184
+ | `AdsFooter` | Rodapé. |
185
+
186
+ ### Exibição de dados
187
+
188
+ | Componente | Descrição |
189
+ | ----------------- | --------- |
190
+ | `AdsTable` | Tabela baseada no `UTable`, com densidade, zebra, bordas, degradê por nível, `sticky`, loading e estado vazio. |
191
+ | `AdsTableToolbar` | Barra de ferramentas da tabela. |
192
+ | `AdsCard` | Cartão genérico. |
193
+ | `AdsMetricCard` | Cartão de métrica/indicador. |
194
+ | `AdsFeatureCard` | Cartão de funcionalidade. |
195
+ | `AdsFileCard` | Cartão de arquivo. |
196
+ | `AdsEmptyState` | Estado vazio. |
197
+
198
+ ### Indicadores e status
199
+
200
+ | Componente | Descrição |
201
+ | -------------------- | --------- |
202
+ | `AdsBadge` | Contador ou ponto (`mini`) em 7 cores. |
203
+ | `AdsPill` | Pílula de status (`default`, `success`, `attention`, `warning`, `new`, `blocked`, `innovation`, `neutral`) em tom `primary` ou `secondary`. |
204
+ | `AdsMiniPill` | Versão compacta da pílula. |
205
+ | `AdsNotabilityPill` | Pílula de notabilidade. |
206
+ | `AdsFarmarcasPill` | Pílula de marca Farmarcas. |
207
+ | `AdsProductTag` | Tag de produto. |
208
+
209
+ ### Feedback e overlays
210
+
211
+ | Componente | Descrição |
212
+ | ----------------- | --------- |
213
+ | `AdsModal` | Modal (`dialog` ou `sheet`) com 5 tamanhos, ações padrão e slots. |
214
+ | `AdsToast` | Aviso em faixa (`banner`) ou reporte escuro (`status`). |
215
+ | `AdsBroadcast` | Comunicado em destaque. |
216
+ | `AdsTooltip` | Tooltip. |
217
+ | `AdsSmalltip` / `AdsSteptip` / `AdsCharttip` | Variações de tooltip (compacta, em passos e para gráficos). |
218
+ | `AdsLoading` | Indicador de carregamento. |
219
+ | `ProgressBarLoading` | Barra de progresso. |
220
+ | `OverlayLoading` | Overlay de carregamento/sucesso/erro (usado por `useOverlayLoading`). |
221
+
222
+ ## Exemplos
223
+
224
+ ### Botões
225
+
226
+ ```vue
227
+ <AdsButton type="filled" label="Salvar" />
228
+ <AdsButton type="outline" color="success" label="Aprovar" />
229
+ <AdsButton type="unfilled" size="sm" label="Cancelar" />
230
+ <AdsButton type="ia" label="Gerar com IA" leading icon="i-lucide-sparkles" />
231
+ <AdsButton type="filled" label="Enviando" loading />
232
+ <AdsButton type="filled" label="Ir para o painel" to="/painel" />
233
+ ```
234
+
235
+ | Prop | Valores |
236
+ | ------------ | ------- |
237
+ | `type` | `filled` \| `outline` \| `unfilled` \| `secondary` \| `ia` |
238
+ | `color` | `primary` \| `success` \| `attention` \| `warning` \| `new` \| `innovation` \| `blocked` \| `neutral` |
239
+ | `size` | `md` \| `sm` |
240
+ | `nativeType` | `button` \| `submit` \| `reset` (a prop `type` é o visual do ADS) |
241
+
242
+ ### Campos de formulário
243
+
244
+ ```vue
245
+ <AdsInput
246
+ v-model="preco"
247
+ label="Preço"
248
+ hint="Valor unitário"
249
+ suffix="R$"
250
+ type="number"
251
+ :error="erro"
252
+ />
253
+ ```
254
+
255
+ Estados disponíveis via `state` (útil para documentação): `default`, `active`, `focus`, `error`, `disabled` e `ai`.
256
+
257
+ ### Modal
258
+
259
+ ```vue
260
+ <template>
261
+ <AdsButton label="Excluir" color="warning" @click="aberto = true" />
262
+
263
+ <AdsModal
264
+ v-model:open="aberto"
265
+ title="Excluir item"
266
+ description="Essa ação não pode ser desfeita."
267
+ cancel-label="Cancelar"
268
+ confirm-label="Excluir"
269
+ @confirm="excluir"
270
+ @cancel="aberto = false"
271
+ />
272
+ </template>
273
+
274
+ <script setup lang="ts">
275
+ const aberto = ref(false);
276
+ const excluir = () => {
277
+ /* ... */
278
+ aberto.value = false;
279
+ };
280
+ </script>
281
+ ```
282
+
283
+ Eventos: `confirm`, `cancel` e `dismiss` (com o motivo `"esc"` ou `"outside"`). Slots: `default`, `title` e `footer`.
284
+
285
+ ### Toast
286
+
287
+ Como componente em linha:
288
+
289
+ ```vue
290
+ <AdsToast status="success" title="Tudo certo" message="Alterações salvas." />
291
+ <AdsToast status="error" message="Falha ao salvar." action-label="Tentar novamente" />
292
+ <AdsToast appearance="status" status="neutral" title="Relatório" subtitle="Explicação opcional" />
293
+ ```
294
+
295
+ Como toast flutuante, usando o `useToast` do Nuxt UI (as cores de status e os ícones do ADS são aplicados automaticamente pelo plugin da layer):
296
+
297
+ ```ts
298
+ const toast = useToast();
299
+
300
+ toast.add({
301
+ title: "Salvo",
302
+ description: "Suas alterações foram salvas.",
303
+ color: "success",
304
+ });
305
+ ```
306
+
307
+ ### Pílulas e badges
308
+
309
+ ```vue
310
+ <AdsPill status="success" label="Ativo" />
311
+ <AdsPill status="warning" tone="secondary" label="Atrasado" icon="i-lucide-alert-triangle" />
312
+ <AdsBadge color="primary" :value="5" />
313
+ <AdsBadge color="warning" mini />
314
+ ```
315
+
316
+ ### Paginação e abas
317
+
318
+ ```vue
319
+ <AdsPagination v-model:page="pagina" :total-pages="20" />
320
+
321
+ <AdsTabs v-model="aba" :items="itens" />
322
+ ```
323
+
324
+ ### Tabela
325
+
326
+ ```vue
327
+ <AdsTable
328
+ :data="linhas"
329
+ :columns="colunas"
330
+ density="md"
331
+ striped
332
+ :loading="carregando"
333
+ empty-label="Nenhum resultado encontrado"
334
+ />
335
+ ```
336
+
337
+ Para montar colunas, a layer exporta helpers em `app/utils/ads-table.ts`, como `adsTableColumn`, `adsTablePinned`, `adsTableGroup`, `adsTableVariationClass` e `adsTableTreeIndent`.
338
+
339
+ ### Seletor de datas
340
+
341
+ ```vue
342
+ <!-- Data única -->
343
+ <AdsDatePicker v-model="data" min="2026-01-01" />
344
+
345
+ <!-- Intervalo (máximo de 31 dias) -->
346
+ <AdsDatePicker range v-model:start="inicio" v-model:end="fim" :maximum-days="31" />
347
+ ```
348
+
349
+ As datas trafegam como string `YYYY-MM-DD`.
350
+
351
+ ## Tokens de design
352
+
353
+ Os tokens vêm do Figma do ADS e estão organizados em três camadas:
354
+
355
+ 1. **Primitivos** — valores brutos (escalas de cor, espaçamentos).
356
+ 2. **Semânticos** — intenção de uso (`--ads-surface-*`, `--ads-text-*`, `--ads-border-*`, `--ads-status-*`).
357
+ 3. **De componente** — ajustes finos por componente (`--ads-button-*`, `--ads-modal-*`, `--ads-tooltip-*`…).
358
+
359
+ ### Variáveis CSS
360
+
361
+ ```css
362
+ .meu-card {
363
+ background: var(--ads-surface-main);
364
+ color: var(--ads-text-secondary);
365
+ border-radius: var(--ads-button-radius);
366
+ box-shadow: var(--ads-shadow-level-3);
367
+ }
368
+ ```
369
+
370
+ ### Classes Tailwind
371
+
372
+ As variáveis semânticas também estão mapeadas como cores do Tailwind (`--color-ads-*`):
373
+
374
+ ```html
375
+ <div class="bg-ads-surface-main border-ads-border-width-thin"></div>
376
+ ```
377
+
378
+ ### Escalas de cor
379
+
380
+ | Escala | Uso |
381
+ | ------------------ | --- |
382
+ | `primary` / `secondary` | Azul do Radar Pricing, de 50 a 950 (base `#006ff7`). |
383
+ | `success` | Verde de sucesso (base `#15c57e`). |
384
+ | Neutros | `neutralLight`, `neutralMid` e `neutralDark`. |
385
+ | Status | `success`, `attention`, `warning`, `new`, `innovation`, `blocked`. |
386
+
387
+ ### Espaçamento
388
+
389
+ | Token | px | Token | px | Token | px |
390
+ | ------ | --- | ------ | --- | ------ | --- |
391
+ | quark | 4 | sm | 32 | xxxl | 120 |
392
+ | nano | 8 | rg | 40 | huge | 160 |
393
+ | xxxs | 12 | md | 48 | giant | 200 |
394
+ | xxs | 16 | lg | 56 | | |
395
+ | xs | 24 | xl / xxl | 64 / 80 | | |
396
+
397
+ Os mesmos valores estão disponíveis em TypeScript, em `app/theme/ads-tokens.ts` (`adsSpacing`, `adsRadarPricing`, `adsRadarBase`, `adsNeutralLight`, `adsNeutralMid`, `adsNeutralDark`, `adsSuccess`…).
398
+
399
+ ### Personalizando tokens de componente
400
+
401
+ Os tokens de componente são gerados a partir de `app/theme/component-tokens.json` para `component-tokens.css`. Para ajustar no seu projeto sem editar o pacote, sobrescreva a variável CSS depois do CSS da layer:
402
+
403
+ ```css
404
+ :root {
405
+ --ads-button-radius: 4px;
406
+ --ads-button-primary: #0050b3;
407
+ }
408
+ ```
409
+
410
+ ## Tema do Nuxt UI
411
+
412
+ O `app.config.ts` da layer customiza os seguintes componentes do Nuxt UI para seguir o ADS:
413
+
414
+ `button`, `input`, `inputDate`, `calendar`, `select`, `selectMenu`, `toast`, `toaster` e `tooltip`.
415
+
416
+ Por ser uma layer, você pode estender ou sobrescrever no `app.config.ts` do seu projeto:
417
+
418
+ ```ts
419
+ // app/app.config.ts
420
+ export default defineAppConfig({
421
+ ui: {
422
+ button: {
423
+ slots: {
424
+ base: "rounded-md",
425
+ },
426
+ },
427
+ },
428
+ });
429
+ ```
430
+
431
+ ## Composables
432
+
433
+ ### `useOverlayLoading`
434
+
435
+ Exibe um overlay de tela cheia para carregamento, sucesso, erro, busca ou informação, com barra de progresso opcional.
436
+
437
+ ```ts
438
+ const overlay = useOverlayLoading();
439
+
440
+ overlay.show({
441
+ variant: "loading",
442
+ title: "Processando",
443
+ description: "Isso pode levar alguns segundos.",
444
+ showProgress: true,
445
+ progress: 10,
446
+ });
447
+
448
+ overlay.update({ progress: 60 });
449
+
450
+ overlay.update({ variant: "success", title: "Concluído!" });
451
+
452
+ overlay.close();
453
+ ```
454
+
455
+ | Método | Descrição |
456
+ | ----------------- | --------- |
457
+ | `show(options)` | Abre o overlay (fecha o anterior, se houver) e retorna o id. |
458
+ | `update(options)` | Mescla novas props no overlay aberto. |
459
+ | `close()` | Fecha o overlay. |
460
+ | `isOpen()` | Indica se há overlay aberto. |
461
+ | `getCurrentId()` | Retorna o id do overlay atual. |
462
+
463
+ Opções (`OverlayLoadingOptions`):
464
+
465
+ | Opção | Tipo |
466
+ | ----------------- | ---- |
467
+ | `variant` | `"loading"` \| `"success"` \| `"error"` \| `"search"` \| `"info"` |
468
+ | `title`, `description`, `hint` | `string` |
469
+ | `showProgress`, `progress` | `boolean`, `number` |
470
+ | `iconSrc` | `string` |
471
+ | `actionLabel`, `onAction` | rótulo e callback de ação |
472
+ | `onUserClose` | callback ao usuário fechar |
473
+ | `closableVariants`| `("success" \| "error")[]` — variantes que o usuário pode fechar |
474
+
475
+ ## Utilitários
476
+
477
+ Todos ficam em `app/utils` e são auto-importados pelo Nuxt.
478
+
479
+ | Arquivo | Funções principais |
480
+ | --------------------- | ------------------ |
481
+ | `money.ts` | `numberToBRL`, `numberToCompactBRL`, `parseStringMoneyToFloat`, `formatPriceInput`, `parsePriceInput` |
482
+ | `percentage.ts` | `formatPercentage`, `formatPercentageWithDecimals`, `formatPercentagePtBr` |
483
+ | `parser.ts` | `parseToPercentage`, `parsePercentageToFloat`, `getTodayDateString`, `formatDateOnlyToPtBr`, `formatDateToPtBr`, `daysBetweenDateOnly`, `daysFromTodayToDateOnly`, `normalizePercentage` |
484
+ | `calendar-date.ts` | Conversão entre `string` e `CalendarDate` (`@internationalized/date`) e helpers de intervalo |
485
+ | `notability.ts` | `formatNotability` |
486
+ | `category-role.ts` | `CATEGORY_ROLES`, `formatCategoryRole`, `parseCategoryRole` |
487
+ | `ads-filter-select.ts`| Helpers para `AdsFilterSelect` (agrupamento, seleção, rótulos, meses) |
488
+ | `ads-table.ts` | Helpers e tipos para `AdsTable` |
489
+
490
+ ```ts
491
+ numberToBRL(1234.5); // "R$ 1.234,50"
492
+ numberToBRL(-10); // "R$ -10,00"
493
+ numberToBRL(null); // "-"
494
+ numberToCompactBRL(2_500_000); // valor compacto em milhões
495
+ ```
496
+
497
+ ## Localização (pt-BR)
498
+
499
+ A layer inclui `app/locale/pt-br.ts`, que exporta o locale do Nuxt UI para português do Brasil (calendário, meses e rótulos):
500
+
501
+ ```ts
502
+ import { uiLocale, UI_LOCALE_CODE } from "ads-nuxt/app/locale/pt-br";
503
+ // UI_LOCALE_CODE === "pt-BR"
504
+ ```
505
+
506
+ Passe-o ao `UApp` como mostrado em [Configuração](#configuração).
507
+
508
+ ## Desenvolvimento
509
+
510
+ Este repositório usa **pnpm** e contém um **playground** Nuxt com a documentação interativa dos componentes e dos tokens.
511
+
512
+ ```bash
513
+ git clone https://github.com/jbfarmarcas/alquimia-design-system.git
514
+ cd alquimia-design-system
515
+ pnpm install
516
+
517
+ pnpm dev # playground em http://localhost:3010
518
+ pnpm build # build do playground
519
+ pnpm preview # preview do build
520
+
521
+ pnpm skill:reference # regenera skills/ads-nuxt/reference.md a partir de app/
522
+ pnpm skill:check # falha se o reference.md estiver desatualizado
523
+ ```
524
+
525
+ Páginas do playground:
526
+
527
+ | Rota | Conteúdo |
528
+ | ------------------------- | -------- |
529
+ | `/design-system/instalacao` | Manual de instalação da biblioteca |
530
+ | `/design-system` | Catálogo de componentes com demos e código |
531
+ | `/design-system/tabelas` | Variações de tabela |
532
+ | `/design-system/tokens` | Editor visual dos tokens de componente |
533
+
534
+ ### Docker
535
+
536
+ ```bash
537
+ docker compose up --build
538
+ ```
539
+
540
+ A imagem executa o build de produção do playground (`pnpm build`) e serve o resultado em `http://localhost:3010`. Não há hot reload no container: para desenvolver, use `pnpm dev`.
541
+
542
+ ### Publicação
543
+
544
+ O pacote publica apenas `app/` e `nuxt.config.ts` (campo `files`), com acesso público:
545
+
546
+ A publicação é feita pelo GitHub Actions (`.github/workflows/publish.yml`), com Trusted Publishing (sem token). Para lançar uma versão:
547
+
548
+ ```bash
549
+ npm version patch --ignore-scripts # ou minor / major: cria o commit e a tag vX.Y.Z
550
+ git push --follow-tags
551
+ ```
552
+
553
+ ## Estrutura do projeto
554
+
555
+ ```
556
+ .
557
+ ├── app/ # Conteúdo publicado no npm (a layer)
558
+ │ ├── app.config.ts # Tema do Nuxt UI
559
+ │ ├── assets/ # CSS, SVGs de marca e animações
560
+ │ ├── components/ # Componentes Ads*
561
+ │ ├── composables/ # useOverlayLoading
562
+ │ ├── constants/ # Constantes (swatches de cor)
563
+ │ ├── locale/ # Locale pt-BR
564
+ │ ├── plugins/ # Plugin de toast
565
+ │ ├── theme/ # Tokens e temas (TS/JSON)
566
+ │ ├── types/ # Tipos compartilhados
567
+ │ └── utils/ # Utilitários de formatação e helpers
568
+ ├── playground/ # App de documentação (não publicado)
569
+ ├── skills/ads-nuxt/ # Skill para agentes de IA (SKILL.md + reference.md gerado)
570
+ ├── scripts/ # generate-skill-reference.mjs (pnpm skill:reference)
571
+ ├── nuxt.config.ts # Entrada da layer
572
+ └── package.json
573
+ ```
574
+
575
+ ## Licença
576
+
577
+ [MIT](./LICENSE) © 2026 Farmarcas