@topjoao/top-design-system 0.1.9 → 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 CHANGED
@@ -1,37 +1,37 @@
1
1
  # TopSolutions Design System
2
2
 
3
3
  Biblioteca de componentes Vue 3, estilos e tokens visuais compartilhados pela
4
- TopSolutions.
5
-
6
- ## Índice
7
-
8
- - [Instalação e configuração](#instalação)
9
- - [Tema e tokens](#tema-topsolutions)
10
- - [Integração com Nuxt e Vue 3](#uso-com-nuxt)
11
- - [Componentes](#componentes-publicos)
12
- - [Tipos e exports públicos](#tipos-e-exports-públicos)
13
- - [Desenvolvimento da biblioteca](#desenvolvimento-da-biblioteca)
14
-
15
- ## Componentes públicos
16
-
17
- | Componente | Finalidade | `v-model` |
18
- |---|---|---|
19
- | `TopButton` | Botão com estilos e estados da marca. | — |
20
- | `TopConfirmDialog` | Confirmação modal controlada pela aplicação. | `boolean` |
21
- | `TopDatePicker` | Campo de data, múltiplas datas ou intervalo. | `Date`/array de `Date` |
22
- | `TopFileUpload` | Escolha, validação e prévia de arquivos; não faz upload. | `File`/`File[]`/`null` |
23
- | `TopInputText` | Campo textual com label, erro e acessibilidade. | `string` |
4
+ TopSolutions.
5
+
6
+ ## Índice
7
+
8
+ - [Instalação e configuração](#instalação)
9
+ - [Tema e tokens](#tema-topsolutions)
10
+ - [Integração com Nuxt e Vue 3](#uso-com-nuxt)
11
+ - [Componentes](#componentes-publicos)
12
+ - [Tipos e exports públicos](#tipos-e-exports-públicos)
13
+ - [Desenvolvimento da biblioteca](#desenvolvimento-da-biblioteca)
14
+
15
+ ## Componentes públicos
16
+
17
+ | Componente | Finalidade | `v-model` |
18
+ |---|---|---|
19
+ | `TopButton` | Botão com estilos e estados da marca. | — |
20
+ | `TopConfirmDialog` | Confirmação modal controlada pela aplicação. | `boolean` |
21
+ | `TopDatePicker` | Campo de data, múltiplas datas ou intervalo. | `Date`/array de `Date` |
22
+ | `TopFileUpload` | Escolha, validação e prévia de arquivos; não faz upload. | `File`/`File[]`/`null` |
23
+ | `TopInputText` | Campo textual com label, erro e acessibilidade. | `string` |
24
24
  | `TopTextArea` | Campo de texto multilinha com label, erro e altura configurável. | `string` |
25
- | `TopInputNumber` | Campo numérico localizado, com moeda, limites e incrementos. | `number \| null` |
26
- | `TopNavBar` | Navegação responsiva, breadcrumbs, favoritos e Drawer. | `searchValue` e `mobileOpen` opcionais |
27
- | `TopSelect` | Autocomplete pesquisável com paginação virtual. | opção/opções |
28
- | `TopTabs` | Abas com painéis nomeados. | `string \| number` |
29
- | `TopToast` | Renderizador de notificações do serviço Toast do PrimeVue. | — |
25
+ | `TopInputNumber` | Campo numérico localizado, com moeda, limites e incrementos. | `number \| null` |
26
+ | `TopNavBar` | Navegação responsiva, breadcrumbs, favoritos e Drawer. | `searchValue` e `mobileOpen` opcionais |
27
+ | `TopSelect` | Autocomplete pesquisável com paginação virtual. | opção/opções |
28
+ | `TopTabs` | Abas com painéis nomeados. | `string \| number` |
29
+ | `TopToast` | Renderizador de notificações do serviço Toast do PrimeVue. | — |
30
30
 
31
31
  ## Instalação
32
32
 
33
33
  ```bash
34
- npm install @topjoao/top-design-system
34
+ npm install @topjoao/top-design-system
35
35
  ```
36
36
 
37
37
  A aplicação consumidora deve possuir Vue 3, PrimeVue, PrimeIcons e
@@ -46,24 +46,24 @@ oficial da TopSolutions. Configure-o uma vez na aplicação consumidora:
46
46
  import PrimeVue from 'primevue/config'
47
47
  import { TopSolutionsPreset } from '@topjoao/top-design-system'
48
48
 
49
- app.use(PrimeVue, {
50
- theme: {
51
- preset: TopSolutionsPreset,
52
- options: {
53
- darkModeSelector: '.dark',
54
- cssLayer: {
55
- name: 'primevue',
56
- order: 'primevue',
57
- },
58
- },
59
- },
60
- })
61
- ```
62
-
63
- A camada `primevue` mantém os estilos estruturais do tema abaixo dos padrões do
64
- Design System e das classes utilitárias da aplicação. Com isso, propriedades
65
- como `headerClass` e `contentClass` conseguem sobrescrever os valores padrão sem
66
- `!important`.
49
+ app.use(PrimeVue, {
50
+ theme: {
51
+ preset: TopSolutionsPreset,
52
+ options: {
53
+ darkModeSelector: '.dark',
54
+ cssLayer: {
55
+ name: 'primevue',
56
+ order: 'primevue',
57
+ },
58
+ },
59
+ },
60
+ })
61
+ ```
62
+
63
+ A camada `primevue` mantém os estilos estruturais do tema abaixo dos padrões do
64
+ Design System e das classes utilitárias da aplicação. Com isso, propriedades
65
+ como `headerClass` e `contentClass` conseguem sobrescrever os valores padrão sem
66
+ `!important`.
67
67
 
68
68
  Para ativar o modo escuro, adicione ou remova `.dark` uma única vez no elemento
69
69
  `<html>` da aplicação. Os componentes usam tokens semânticos de superfície, texto e
@@ -270,16 +270,16 @@ sendo explorado recebem destaque.
270
270
  | `showAia`, `showSupport` | `boolean` / `false` | Exibem as ações opcionais. |
271
271
  | `aiaActive` | `boolean` / `false` | Estado visual do botão Aia. |
272
272
  | `aiaLabel`, `supportLabel` | `string` | Textos acessíveis e rótulos do Drawer. |
273
- | `actions` | `TopNavAction[]` / `[]` | Ações genéricas, como integrações, emitidas por `action`. |
274
- | `client` | `TopNavClient` | Organização, cliente ou escopo ativo exibido no cabeçalho e como contexto do usuário no rodapé do Drawer; não cria ação nem seletor. |
275
- | `user` | `TopNavUser` | Dados exclusivamente visuais do usuário. |
273
+ | `actions` | `TopNavAction[]` / `[]` | Ações genéricas, como integrações, emitidas por `action`. |
274
+ | `client` | `TopNavClient` | Organização, cliente ou escopo ativo exibido no cabeçalho e como contexto do usuário no rodapé do Drawer; não cria ação nem seletor. |
275
+ | `user` | `TopNavUser` | Dados exclusivamente visuais do usuário. |
276
276
  | `userMenuItems` | `TopNavUserMenuItem[]` | Opções emitidas por `user-action`; suporta separadores. |
277
277
  | `favoriteItems` | `TopNavItem[]` / `[]` | Favoritos fornecidos pelo pai para dropdown e Drawer. |
278
278
  | `showFavoriteToggle` | `boolean` / `false` | Exibe a estrela da página atual. |
279
279
  | `favoriteActive` | `boolean` / `false` | Estado visual da estrela atual. |
280
- | `mobileOpen` | `boolean` | Controle opcional com `v-model:mobile-open`. |
281
- | `appearance` | `TopNavBarAppearance` | Tokens visuais locais descritos abaixo. |
282
- | `spacing` | `TopNavBarSpacing` | Espaçamento do conteúdo no cabeçalho e breadcrumbs; preserva os padrões atuais quando omitido. |
280
+ | `mobileOpen` | `boolean` | Controle opcional com `v-model:mobile-open`. |
281
+ | `appearance` | `TopNavBarAppearance` | Tokens visuais locais descritos abaixo. |
282
+ | `spacing` | `TopNavBarSpacing` | Espaçamento do conteúdo no cabeçalho e breadcrumbs; preserva os padrões atuais quando omitido. |
283
283
 
284
284
  ### Eventos
285
285
 
@@ -304,7 +304,7 @@ atalho abre primeiro o Drawer e foca a busca móvel. `Escape` fecha os painéis.
304
304
  | Slot | Uso |
305
305
  |---|---|
306
306
  | `brand` | Marca; recebe `{ compact }`. |
307
- | `context`, `scope` ou `client` | Contexto operacional; aliases com prioridade nessa ordem, recebem `{ client, compact }`. O slot `client` substitui a apresentação padrão da prop `client`. |
307
+ | `context`, `scope` ou `client` | Contexto operacional; aliases com prioridade nessa ordem, recebem `{ client, compact }`. O slot `client` substitui a apresentação padrão da prop `client`. |
308
308
  | `context-compact` | Variante explícita usada no último estágio de overflow. |
309
309
  | `actions` | Conteúdo adicional do cabeçalho; recebe `{ compact, close }`. |
310
310
  | `aia-icon`, `support-icon` | Ícones customizados das ações quadradas. |
@@ -318,53 +318,53 @@ atalho abre primeiro o Drawer e foca a busca móvel. `Escape` fecha os painéis.
318
318
  | `drawer-actions` | Ações; recebe `{ actions, select, close }`. |
319
319
  | `drawer-before-menu`, `drawer-after-menu` | Conteúdo antes/depois do trilho rolável. |
320
320
  | `drawer-menu` | Substitui a árvore; recebe `{ sections, select, close }`. |
321
- | `drawer-user` | Rodapé de usuário; recebe `{ user, client, open, toggle }`. |
322
- | `drawer-footer` | Conteúdo final adicional; recebe `{ close }`. |
323
-
324
- ### Faixa de favoritos
325
-
326
- No desktop, `favoriteItems` aparece primeiro em uma faixa horizontal abaixo dos
327
- breadcrumbs. A biblioteca mede uma cópia invisível da faixa com
328
- `ResizeObserver`: se a largura real não couber, ela é substituída pelo dropdown
329
- `Favoritos`. O mesmo dropdown é usado depois que a página passa de `120px` de
330
- scroll e a faixa retorna apenas ao chegar a `24px` ou menos. Os valores evitam
331
- oscilações perto do topo e reproduzem o comportamento do AppSidebar.
332
-
333
- ### Aparência e responsividade
334
-
335
- Use `spacing` para criar uma zona segura horizontal sem limitar o fundo das
336
- duas faixas. Os valores são aplicados no elemento raiz como
337
- `--top-nav-header-padding` e `--top-nav-breadcrumb-padding`; o cabeçalho e o
338
- breadcrumb continuam ocupando toda a largura da viewport.
339
- Em telas móveis, esses valores também são usados, salvo se a aplicação já
340
- definir as variáveis específicas `--top-nav-header-padding-mobile` ou
341
- `--top-nav-breadcrumb-padding-mobile`.
342
-
343
- ```vue
344
- <TopNavBar
345
- :spacing="{
346
- headerPadding: '0.625rem max(2rem, calc((100vw - 80rem) / 2 + 2rem))',
347
- breadcrumbPadding: '0.25rem max(2rem, calc((100vw - 80rem) / 2 + 2rem))',
348
- }"
349
- />
350
- ```
351
-
352
- `appearance` é propositalmente pequeno e semântico. Use `colors` para
353
- `navigation`, `text`, `mutedText`, `accent`, `border`, `menuText`,
354
- `mobileActiveText` e `favoritesText`; `surfaces` para `breadcrumb`, `drawer`,
355
- `drawerFooter`, `menu`, `menuHover`, `menuExplored`, `mobileActive`,
356
- `favorites` e `currentPage`; `borders` para `menu` (a borda externa de 6px),
357
- `menuOutline`, `mobileDivider`, `favorites` e `currentPage`; `shape` para
358
- `radius`, `drawerRadius`, `shadow` e `favoritesShadow`; e `focus` para
359
- `onDark` e `onLight`.
360
-
361
- ```ts
362
- const appearance = {
363
- colors: { navigation: '#09090b', text: '#f4f4f5', border: 'rgb(255 255 255 / 14%)' },
364
- surfaces: { drawer: '#09090b', menu: '#18181b', menuHover: '#27272a' },
365
- shape: { radius: '8px', shadow: '0 12px 30px rgb(0 0 0 / 25%)' },
366
- }
367
- ```
321
+ | `drawer-user` | Rodapé de usuário; recebe `{ user, client, open, toggle }`. |
322
+ | `drawer-footer` | Conteúdo final adicional; recebe `{ close }`. |
323
+
324
+ ### Faixa de favoritos
325
+
326
+ No desktop, `favoriteItems` aparece primeiro em uma faixa horizontal abaixo dos
327
+ breadcrumbs. A biblioteca mede uma cópia invisível da faixa com
328
+ `ResizeObserver`: se a largura real não couber, ela é substituída pelo dropdown
329
+ `Favoritos`. O mesmo dropdown é usado depois que a página passa de `120px` de
330
+ scroll e a faixa retorna apenas ao chegar a `24px` ou menos. Os valores evitam
331
+ oscilações perto do topo e reproduzem o comportamento do AppSidebar.
332
+
333
+ ### Aparência e responsividade
334
+
335
+ Use `spacing` para criar uma zona segura horizontal sem limitar o fundo das
336
+ duas faixas. Os valores são aplicados no elemento raiz como
337
+ `--top-nav-header-padding` e `--top-nav-breadcrumb-padding`; o cabeçalho e o
338
+ breadcrumb continuam ocupando toda a largura da viewport.
339
+ Em telas móveis, esses valores também são usados, salvo se a aplicação já
340
+ definir as variáveis específicas `--top-nav-header-padding-mobile` ou
341
+ `--top-nav-breadcrumb-padding-mobile`.
342
+
343
+ ```vue
344
+ <TopNavBar
345
+ :spacing="{
346
+ headerPadding: '0.625rem max(2rem, calc((100vw - 80rem) / 2 + 2rem))',
347
+ breadcrumbPadding: '0.25rem max(2rem, calc((100vw - 80rem) / 2 + 2rem))',
348
+ }"
349
+ />
350
+ ```
351
+
352
+ `appearance` é propositalmente pequeno e semântico. Use `colors` para
353
+ `navigation`, `text`, `mutedText`, `accent`, `border`, `menuText`,
354
+ `mobileActiveText` e `favoritesText`; `surfaces` para `breadcrumb`, `drawer`,
355
+ `drawerFooter`, `menu`, `menuHover`, `menuExplored`, `mobileActive`,
356
+ `favorites` e `currentPage`; `borders` para `menu` (a borda externa de 6px),
357
+ `menuOutline`, `mobileDivider`, `favorites` e `currentPage`; `shape` para
358
+ `radius`, `drawerRadius`, `shadow` e `favoritesShadow`; e `focus` para
359
+ `onDark` e `onLight`.
360
+
361
+ ```ts
362
+ const appearance = {
363
+ colors: { navigation: '#09090b', text: '#f4f4f5', border: 'rgb(255 255 255 / 14%)' },
364
+ surfaces: { drawer: '#09090b', menu: '#18181b', menuHover: '#27272a' },
365
+ shape: { radius: '8px', shadow: '0 12px 30px rgb(0 0 0 / 25%)' },
366
+ }
367
+ ```
368
368
 
369
369
  A biblioteca não fixa tipografia inline. Por padrão, família, tamanho, peso e
370
370
  altura de linha são herdados da aplicação consumidora. Além disso, `appearance`
@@ -377,33 +377,33 @@ tema global pode controlar o componente sem precisar usar `!important`:
377
377
  --top-nav-font-family: var(--app-font-family);
378
378
  --top-nav-font-size: var(--app-font-size);
379
379
  --top-nav-strong-font-weight: 600;
380
- --top-nav-action-size: 2.5rem;
381
- --top-nav-header-padding: 0.625rem 1.5rem;
382
- --top-nav-breadcrumb-padding: 0.25rem 1.5rem;
383
- --top-nav-menu-item-padding: 0.5rem 0.75rem;
380
+ --top-nav-action-size: 2.5rem;
381
+ --top-nav-header-padding: 0.625rem 1.5rem;
382
+ --top-nav-breadcrumb-padding: 0.25rem 1.5rem;
383
+ --top-nav-menu-item-padding: 0.5rem 0.75rem;
384
384
  --top-nav-section-width: 16rem;
385
385
  --top-nav-column-width: 18rem;
386
386
  --top-nav-mobile-active-bg: #fff;
387
- --top-nav-mobile-active-fg: #025a84;
388
- --top-nav-mobile-divider: rgb(255 255 255 / 20%);
389
- --top-nav-mobile-item-gap: 0.25rem;
390
- --top-nav-mobile-submenu-padding: 0.5rem 0 0.375rem 0.35rem;
391
- --top-nav-favorites-bg: #f8fafc;
392
- --top-nav-favorites-fg: #0f172a;
393
- --top-nav-favorites-border: #e2e8f0;
394
- --top-nav-favorites-shadow: 0 1px 2px rgb(15 23 42 / 6%);
395
- --top-nav-focus-ring: #dbeafe;
396
- --top-nav-focus-ring-light: #1d4ed8;
397
- --top-nav-current-bg: rgb(255 255 255 / 10%);
398
- --top-nav-current-border: rgb(255 255 255 / 15%);
399
- --top-nav-menu-scrollbar-thumb: #94a3b8;
400
- }
387
+ --top-nav-mobile-active-fg: #025a84;
388
+ --top-nav-mobile-divider: rgb(255 255 255 / 20%);
389
+ --top-nav-mobile-item-gap: 0.25rem;
390
+ --top-nav-mobile-submenu-padding: 0.5rem 0 0.375rem 0.35rem;
391
+ --top-nav-favorites-bg: #f8fafc;
392
+ --top-nav-favorites-fg: #0f172a;
393
+ --top-nav-favorites-border: #e2e8f0;
394
+ --top-nav-favorites-shadow: 0 1px 2px rgb(15 23 42 / 6%);
395
+ --top-nav-focus-ring: #dbeafe;
396
+ --top-nav-focus-ring-light: #1d4ed8;
397
+ --top-nav-current-bg: rgb(255 255 255 / 10%);
398
+ --top-nav-current-border: rgb(255 255 255 / 15%);
399
+ --top-nav-menu-scrollbar-thumb: #94a3b8;
400
+ }
401
401
  ```
402
402
 
403
- As variáveis globais também alcançam o Drawer teleportado. Use-as para ajustes
404
- estruturais — tipografia, larguras, alturas, padding e espaçamentos do menu —
405
- em vez de props no componente. Um valor passado por `appearance` tem precedência
406
- local e não altera os demais tokens do tema.
403
+ As variáveis globais também alcançam o Drawer teleportado. Use-as para ajustes
404
+ estruturais — tipografia, larguras, alturas, padding e espaçamentos do menu —
405
+ em vez de props no componente. Um valor passado por `appearance` tem precedência
406
+ local e não altera os demais tokens do tema.
407
407
 
408
408
  O breakpoint móvel é `1024px`. No desktop, um `ResizeObserver` reaplica a mesma
409
409
  sequência progressiva do AppSidebar: ações colapsam abaixo de `1440px`, busca
@@ -412,15 +412,15 @@ conteúdo ainda transbordar, o contexto recebe `compact: true`. O último estág
412
412
  também limita o contêiner do contexto a `3.25rem`; use `context-compact` quando
413
413
  quiser controlar exatamente o que permanece visível.
414
414
 
415
- Abaixo de `1024px`, a navegação desktop desaparece e o Drawer do PrimeVue assume.
416
- Ele mantém cabeçalho, busca, ações, trilho translúcido rolável, árvore recursiva,
417
- favoritos e usuário. No rodapé, a foto e o nome do usuário formam a primeira
418
- linha; o cliente atual aparece abaixo e o subtítulo do cliente recebe uma
419
- etiqueta quando houver. A transição `menu-expand` existe somente dentro do Drawer;
420
- os dropdowns desktop abrem sem animação e suas áreas de hover incluem o espaço
421
- entre gatilho e painel. Nessa largura, os breadcrumbs deixam de rolar
422
- horizontalmente: eles quebram em linhas e o bloco da página atual ocupa sua
423
- própria linha para permanecer legível.
415
+ Abaixo de `1024px`, a navegação desktop desaparece e o Drawer do PrimeVue assume.
416
+ Ele mantém cabeçalho, busca, ações, trilho translúcido rolável, árvore recursiva,
417
+ favoritos e usuário. No rodapé, a foto e o nome do usuário formam a primeira
418
+ linha; o cliente atual aparece abaixo e o subtítulo do cliente recebe uma
419
+ etiqueta quando houver. A transição `menu-expand` existe somente dentro do Drawer;
420
+ os dropdowns desktop abrem sem animação e suas áreas de hover incluem o espaço
421
+ entre gatilho e painel. Nessa largura, os breadcrumbs deixam de rolar
422
+ horizontalmente: eles quebram em linhas e o bloco da página atual ocupa sua
423
+ própria linha para permanecer legível.
424
424
 
425
425
  ## TopButton
426
426
 
@@ -442,8 +442,8 @@ Exemplo
442
442
 
443
443
  | Prop | Tipo | Padrão |
444
444
  |---|---|---|
445
- | `tooltip` | `string` | `''` |
446
- | `tooltipClass` | `string` | `'text-xs'` |
445
+ | `tooltip` | `string` | `''` |
446
+ | `tooltipClass` | `string` | `'text-xs'` |
447
447
  | `label` | `string` | `''` |
448
448
  | `icon` | `string` | `''` |
449
449
  | `loading` | `boolean` | `false` |
@@ -455,43 +455,43 @@ Exemplo
455
455
  | `unstyled` | `boolean` | `false` |
456
456
  | `type` | `'button' \| 'submit' \| 'reset'` | `'button'` |
457
457
 
458
- O componente emite `click` sem payload. O slot nomeado `icon` não recebe
459
- parâmetros e substitui a prop `icon` — útil para SVGs, `HugeiconsIcon` ou um
460
- ícone com estado próprio. `secondary` permanece como atalho compatível para
461
- `severity="secondary"` e tem precedência sobre `severity`.
462
-
463
- O botão clicável interno expõe a classe estável `top-button__control`, que pode
464
- ser usada para customizar globalmente qualquer característica dos `TopButton`,
465
- como tipografia, cores, espaçamento, dimensões e bordas. Defina a regra no CSS
466
- global da aplicação, carregado depois do CSS do Design System:
467
-
468
- ```css
469
- .top-button__control {
470
- font-size: 0.875rem;
471
- font-weight: 600;
472
- min-height: 44px;
473
- padding: 0.75rem 1rem;
474
- border-radius: 0.5rem;
475
- }
476
- ```
477
-
478
- Em um projeto com Tailwind, a mesma regra pode usar `@apply`:
479
-
480
- ```css
481
- @layer components {
482
- .top-button__control {
483
- @apply min-h-11 rounded-lg px-4 py-3 text-sm font-semibold;
484
- }
485
- }
486
- ```
487
-
488
- A classe `top-button__control` atua no botão clicável, enquanto `top-button`
489
- atua no elemento externo que o envolve. A prop `class` continua disponível para
490
- customizar somente uma ocorrência. Algumas regras internas que usam
491
- `!important` podem exigir maior especificidade ou `!important` para serem
492
- sobrescritas.
493
-
494
- ## TopConfirmDialog
458
+ O componente emite `click` sem payload. O slot nomeado `icon` não recebe
459
+ parâmetros e substitui a prop `icon` — útil para SVGs, `HugeiconsIcon` ou um
460
+ ícone com estado próprio. `secondary` permanece como atalho compatível para
461
+ `severity="secondary"` e tem precedência sobre `severity`.
462
+
463
+ O botão clicável interno expõe a classe estável `top-button__control`, que pode
464
+ ser usada para customizar globalmente qualquer característica dos `TopButton`,
465
+ como tipografia, cores, espaçamento, dimensões e bordas. Defina a regra no CSS
466
+ global da aplicação, carregado depois do CSS do Design System:
467
+
468
+ ```css
469
+ .top-button__control {
470
+ font-size: 0.875rem;
471
+ font-weight: 600;
472
+ min-height: 44px;
473
+ padding: 0.75rem 1rem;
474
+ border-radius: 0.5rem;
475
+ }
476
+ ```
477
+
478
+ Em um projeto com Tailwind, a mesma regra pode usar `@apply`:
479
+
480
+ ```css
481
+ @layer components {
482
+ .top-button__control {
483
+ @apply min-h-11 rounded-lg px-4 py-3 text-sm font-semibold;
484
+ }
485
+ }
486
+ ```
487
+
488
+ A classe `top-button__control` atua no botão clicável, enquanto `top-button`
489
+ atua no elemento externo que o envolve. A prop `class` continua disponível para
490
+ customizar somente uma ocorrência. Algumas regras internas que usam
491
+ `!important` podem exigir maior especificidade ou `!important` para serem
492
+ sobrescritas.
493
+
494
+ ## TopConfirmDialog
495
495
 
496
496
  Diálogo de confirmação baseado no `Dialog` do PrimeVue e nos botões do Design
497
497
  System. A visibilidade é controlada por `v-model`; a aplicação consumidora
@@ -589,16 +589,16 @@ const dataNascimento = ref<Date | null>(null)
589
589
  | `showButtonBar` | `boolean` | `false` |
590
590
  | `appendTo` | `'body' \| 'self' \| HTMLElement` | `'body'` |
591
591
 
592
- Eventos: `update:modelValue`, `input`, `change`, `date-select`, `show`, `hide`,
593
- `today-click`, `clear-click`, `month-change`, `year-change`, `focus`, `blur` e
594
- `keydown`. Os slots do `DatePicker` do PrimeVue são repassados pelo wrapper,
595
- incluindo `date`, `header`, `footer`, `buttonbar`, `inputicon`, `dropdownicon`,
596
- `previcon` e `nexticon`.
597
-
598
- O slot `date` recebe as props de dia disponibilizadas pelo `DatePicker`; os
599
- slots de ícone recebem as props correspondentes do PrimeVue. Os slots `header`,
600
- `footer` e `buttonbar` permitem substituir essas regiões. Todos são apenas
601
- repassados: o wrapper preserva as props e o comportamento do componente-base.
592
+ Eventos: `update:modelValue`, `input`, `change`, `date-select`, `show`, `hide`,
593
+ `today-click`, `clear-click`, `month-change`, `year-change`, `focus`, `blur` e
594
+ `keydown`. Os slots do `DatePicker` do PrimeVue são repassados pelo wrapper,
595
+ incluindo `date`, `header`, `footer`, `buttonbar`, `inputicon`, `dropdownicon`,
596
+ `previcon` e `nexticon`.
597
+
598
+ O slot `date` recebe as props de dia disponibilizadas pelo `DatePicker`; os
599
+ slots de ícone recebem as props correspondentes do PrimeVue. Os slots `header`,
600
+ `footer` e `buttonbar` permitem substituir essas regiões. Todos são apenas
601
+ repassados: o wrapper preserva as props e o comportamento do componente-base.
602
602
 
603
603
  `required` adiciona o atributo nativo e o asterisco visual; a validação continua
604
604
  sob responsabilidade da aplicação. `error` ativa o estado inválido, associa a
@@ -654,123 +654,123 @@ function enviarArquivos(files: File[]) {
654
654
  | `removeLabel` | `string` | `'Remover'` |
655
655
  | `loading` | `boolean` | `false` |
656
656
 
657
- Eventos: `update:modelValue`, `select`, `change`, `remove`, `clear` e `error`.
658
- Erros de tipo, tamanho e quantidade possuem `code`, `message` e o `file`
659
- relacionado. Os slots `empty` e `preview` permitem customizar a área vazia e a
660
- pré-visualização. Os métodos `choose()` e `clear()` ficam disponíveis pela ref
661
- do componente.
662
-
663
- | Slot | Parâmetros recebidos | Uso |
664
- |---|---|---|
665
- | `empty` | `{ choose, disabled }` | Substitui a área vazia. Chame `choose()` para abrir o seletor nativo. |
666
- | `preview` | `{ file, index, url }` | Substitui a miniatura. `url` é uma object URL apenas para imagens; nos demais casos, é `''`. |
667
-
668
- ```vue
669
- <TopFileUpload ref="upload" v-model="anexos" multiple>
670
- <template #empty="{ choose, disabled }">
671
- <button type="button" :disabled="disabled" @click="choose()">Anexar documentos</button>
672
- </template>
673
- <template #preview="{ file, url }">
674
- <img v-if="url" :src="url" :alt="file.name">
675
- <span v-else>{{ file.name }}</span>
676
- </template>
677
- </TopFileUpload>
678
- ```
679
-
680
- `accept` aceita extensões (`.pdf`), MIME types (`application/pdf`) e curingas
681
- MIME (`image/*`), separados por vírgula. `maxFileSize` é contado em bytes. Em
682
- modo simples, a última seleção válida substitui a anterior; com `multiple`,
683
- arquivos válidos são acumulados sem duplicar nome, tipo e tamanho.
684
-
685
- ## TopInputNumber
686
-
687
- Campo numérico baseado no `InputNumber` do PrimeVue, com a mesma estrutura de
688
- label, erro e acessibilidade dos demais campos. Por padrão usa `pt-BR`. No modo
689
- `decimal`, o usuário informa explicitamente o separador decimal; no modo
690
- `currency`, a máscara de centavos vem habilitada e transforma `12345` em
691
- `R$ 123,45`. O `v-model` permanece sempre numérico (`number`) ou `null` quando
692
- vazio.
693
-
694
- ```vue
695
- <script setup lang="ts">
696
- import { ref } from 'vue'
697
- import { TopInputNumber } from '@topjoao/top-design-system'
698
-
699
- const quantidade = ref<number | null>(null)
700
- const valorUnitario = ref<number | null>(null)
701
- </script>
702
-
703
- <template>
704
- <TopInputNumber
705
- v-model="quantidade"
706
- label="Quantidade"
707
- :min="1"
708
- :min-fraction-digits="2"
709
- :max-fraction-digits="4"
710
- required
711
- />
712
-
713
- <TopInputNumber
714
- v-model="valorUnitario"
715
- label="Valor unitário"
716
- mode="currency"
717
- currency="BRL"
718
- :min-fraction-digits="2"
719
- :max-fraction-digits="2"
720
- />
721
- </template>
722
- ```
723
-
724
- | Prop | Tipo | Padrão | Finalidade |
725
- |---|---|---|---|
726
- | `modelValue` | `number \| null` | `null` | Valor numérico controlado. |
727
- | `label` / `placeholder` | `string` | `''` / `''` | Rótulo e texto auxiliar do campo. |
728
- | `required` | `boolean` | `false` | Asterisco visual e atributo nativo obrigatório. |
729
- | `error` | `string` | `''` | Mensagem e estado inválido. |
730
- | `invalid` | `boolean` | `false` | Força estado inválido sem mostrar mensagem. |
731
- | `disabled` / `readonly` | `boolean` | `false` / `false` | Remove interação / preserva leitura sem desabilitar. |
732
- | `locale` | `string` | `'pt-BR'` | Locale para separadores e moeda. |
733
- | `mode` | `'decimal' \| 'currency'` | `'decimal'` | Formatação decimal ou monetária. |
734
- | `currency` / `currencyDisplay` | `string` / `'symbol' \| 'code' \| 'name'` | `undefined` / `'symbol'` | Código ISO 4217 e modo de exibição da moeda. |
735
- | `currencyInputMode` | `'decimal' \| 'cents'` | `'cents'` | Controla a entrada monetária; `decimal` desliga a máscara mesmo quando `cents` é `true`. Não afeta `mode="decimal"`. |
736
- | `cents` | `boolean` | `true` | Habilita a máscara automática somente em `mode="currency"`; `false` usa o `InputNumber` padrão. |
737
- | `centsFractionDigits` | `number` | `undefined` (efetivo: `2`) | Primeira opção para definir as casas da máscara monetária. |
738
- | `currencyFractionDigits` | `number` | `undefined` | Fallback de casas da máscara, usado depois de `centsFractionDigits`. |
739
- | `useGrouping` / `format` | `boolean` | `true` / `true` | Separadores de milhar e formatação do valor. |
740
- | `minFractionDigits` / `maxFractionDigits` | `number` | `undefined` | Precisão do PrimeVue. Sem `maxFractionDigits`, o modo decimal aceita até 20 casas; a máscara monetária usa esse valor como último fallback antes de `2`. |
741
- | `min` / `max` / `step` | `number` | `undefined` / `undefined` / `1` | Limites e passo dos botões/teclado. |
742
- | `showButtons` / `buttonLayout` | `boolean` / `'stacked' \| 'horizontal' \| 'vertical'` | `false` / `'stacked'` | Exibe e organiza os controles de incremento. |
743
- | `allowEmpty` / `showClear` / `highlightOnFocus` | `boolean` | `true` / `false` / `false` | Permite limpar, mostra ícone de limpeza e seleciona valor ao focar. |
744
-
745
- Eventos: `update:modelValue` (`number | null`), `input`, `focus` e `blur`. No
746
- fluxo padrão do `InputNumber`, o componente também repassa `value-change`.
747
- Atributos adicionais, como `name`, `autocomplete`, `aria-*` e `data-*`, são
748
- repassados ao controle interno.
749
-
750
- Quando a máscara de centavos não está ativa, os slots do `InputNumber` também
751
- são repassados: `incrementbutton` e
752
- `decrementbutton` recebem `{ listeners }`; `incrementicon` e `decrementicon`
753
- substituem os ícones; `clearicon` recebe `{ clearCallback }`.
754
-
755
- Para reproduzir a digitação monetária do TopLicita, a máscara de centavos já
756
- vem ativa em `mode="currency"`. O usuário digita somente dígitos: `12345`
757
- resulta em `R$ 123,45` e o `v-model` recebe `123.45`. Para exigir a vírgula
758
- decimal digitada pelo usuário, passe `:cents="false"` ou
759
- `currency-input-mode="decimal"`.
760
- Como a máscara controla o texto enquanto o usuário digita, nesse modo os
761
- botões incrementais, o ícone de limpeza e seus slots do `InputNumber` não são
762
- renderizados.
763
-
764
- ```vue
765
- <TopInputNumber
766
- v-model="valorUnitario"
767
- label="Valor unitário"
768
- mode="currency"
769
- currency="BRL"
770
- />
771
- ```
772
-
773
- ## TopInputText
657
+ Eventos: `update:modelValue`, `select`, `change`, `remove`, `clear` e `error`.
658
+ Erros de tipo, tamanho e quantidade possuem `code`, `message` e o `file`
659
+ relacionado. Os slots `empty` e `preview` permitem customizar a área vazia e a
660
+ pré-visualização. Os métodos `choose()` e `clear()` ficam disponíveis pela ref
661
+ do componente.
662
+
663
+ | Slot | Parâmetros recebidos | Uso |
664
+ |---|---|---|
665
+ | `empty` | `{ choose, disabled }` | Substitui a área vazia. Chame `choose()` para abrir o seletor nativo. |
666
+ | `preview` | `{ file, index, url }` | Substitui a miniatura. `url` é uma object URL apenas para imagens; nos demais casos, é `''`. |
667
+
668
+ ```vue
669
+ <TopFileUpload ref="upload" v-model="anexos" multiple>
670
+ <template #empty="{ choose, disabled }">
671
+ <button type="button" :disabled="disabled" @click="choose()">Anexar documentos</button>
672
+ </template>
673
+ <template #preview="{ file, url }">
674
+ <img v-if="url" :src="url" :alt="file.name">
675
+ <span v-else>{{ file.name }}</span>
676
+ </template>
677
+ </TopFileUpload>
678
+ ```
679
+
680
+ `accept` aceita extensões (`.pdf`), MIME types (`application/pdf`) e curingas
681
+ MIME (`image/*`), separados por vírgula. `maxFileSize` é contado em bytes. Em
682
+ modo simples, a última seleção válida substitui a anterior; com `multiple`,
683
+ arquivos válidos são acumulados sem duplicar nome, tipo e tamanho.
684
+
685
+ ## TopInputNumber
686
+
687
+ Campo numérico baseado no `InputNumber` do PrimeVue, com a mesma estrutura de
688
+ label, erro e acessibilidade dos demais campos. Por padrão usa `pt-BR`. No modo
689
+ `decimal`, o usuário informa explicitamente o separador decimal; no modo
690
+ `currency`, a máscara de centavos vem habilitada e transforma `12345` em
691
+ `R$ 123,45`. O `v-model` permanece sempre numérico (`number`) ou `null` quando
692
+ vazio.
693
+
694
+ ```vue
695
+ <script setup lang="ts">
696
+ import { ref } from 'vue'
697
+ import { TopInputNumber } from '@topjoao/top-design-system'
698
+
699
+ const quantidade = ref<number | null>(null)
700
+ const valorUnitario = ref<number | null>(null)
701
+ </script>
702
+
703
+ <template>
704
+ <TopInputNumber
705
+ v-model="quantidade"
706
+ label="Quantidade"
707
+ :min="1"
708
+ :min-fraction-digits="2"
709
+ :max-fraction-digits="4"
710
+ required
711
+ />
712
+
713
+ <TopInputNumber
714
+ v-model="valorUnitario"
715
+ label="Valor unitário"
716
+ mode="currency"
717
+ currency="BRL"
718
+ :min-fraction-digits="2"
719
+ :max-fraction-digits="2"
720
+ />
721
+ </template>
722
+ ```
723
+
724
+ | Prop | Tipo | Padrão | Finalidade |
725
+ |---|---|---|---|
726
+ | `modelValue` | `number \| null` | `null` | Valor numérico controlado. |
727
+ | `label` / `placeholder` | `string` | `''` / `''` | Rótulo e texto auxiliar do campo. |
728
+ | `required` | `boolean` | `false` | Asterisco visual e atributo nativo obrigatório. |
729
+ | `error` | `string` | `''` | Mensagem e estado inválido. |
730
+ | `invalid` | `boolean` | `false` | Força estado inválido sem mostrar mensagem. |
731
+ | `disabled` / `readonly` | `boolean` | `false` / `false` | Remove interação / preserva leitura sem desabilitar. |
732
+ | `locale` | `string` | `'pt-BR'` | Locale para separadores e moeda. |
733
+ | `mode` | `'decimal' \| 'currency'` | `'decimal'` | Formatação decimal ou monetária. |
734
+ | `currency` / `currencyDisplay` | `string` / `'symbol' \| 'code' \| 'name'` | `undefined` / `'symbol'` | Código ISO 4217 e modo de exibição da moeda. |
735
+ | `currencyInputMode` | `'decimal' \| 'cents'` | `'cents'` | Controla a entrada monetária; `decimal` desliga a máscara mesmo quando `cents` é `true`. Não afeta `mode="decimal"`. |
736
+ | `cents` | `boolean` | `true` | Habilita a máscara automática somente em `mode="currency"`; `false` usa o `InputNumber` padrão. |
737
+ | `centsFractionDigits` | `number` | `undefined` (efetivo: `2`) | Primeira opção para definir as casas da máscara monetária. |
738
+ | `currencyFractionDigits` | `number` | `undefined` | Fallback de casas da máscara, usado depois de `centsFractionDigits`. |
739
+ | `useGrouping` / `format` | `boolean` | `true` / `true` | Separadores de milhar e formatação do valor. |
740
+ | `minFractionDigits` / `maxFractionDigits` | `number` | `undefined` | Precisão do PrimeVue. Sem `maxFractionDigits`, o modo decimal aceita até 20 casas; a máscara monetária usa esse valor como último fallback antes de `2`. |
741
+ | `min` / `max` / `step` | `number` | `undefined` / `undefined` / `1` | Limites e passo dos botões/teclado. |
742
+ | `showButtons` / `buttonLayout` | `boolean` / `'stacked' \| 'horizontal' \| 'vertical'` | `false` / `'stacked'` | Exibe e organiza os controles de incremento. |
743
+ | `allowEmpty` / `showClear` / `highlightOnFocus` | `boolean` | `true` / `false` / `false` | Permite limpar, mostra ícone de limpeza e seleciona valor ao focar. |
744
+
745
+ Eventos: `update:modelValue` (`number | null`), `input`, `focus` e `blur`. No
746
+ fluxo padrão do `InputNumber`, o componente também repassa `value-change`.
747
+ Atributos adicionais, como `name`, `autocomplete`, `aria-*` e `data-*`, são
748
+ repassados ao controle interno.
749
+
750
+ Quando a máscara de centavos não está ativa, os slots do `InputNumber` também
751
+ são repassados: `incrementbutton` e
752
+ `decrementbutton` recebem `{ listeners }`; `incrementicon` e `decrementicon`
753
+ substituem os ícones; `clearicon` recebe `{ clearCallback }`.
754
+
755
+ Para reproduzir a digitação monetária do TopLicita, a máscara de centavos já
756
+ vem ativa em `mode="currency"`. O usuário digita somente dígitos: `12345`
757
+ resulta em `R$ 123,45` e o `v-model` recebe `123.45`. Para exigir a vírgula
758
+ decimal digitada pelo usuário, passe `:cents="false"` ou
759
+ `currency-input-mode="decimal"`.
760
+ Como a máscara controla o texto enquanto o usuário digita, nesse modo os
761
+ botões incrementais, o ícone de limpeza e seus slots do `InputNumber` não são
762
+ renderizados.
763
+
764
+ ```vue
765
+ <TopInputNumber
766
+ v-model="valorUnitario"
767
+ label="Valor unitário"
768
+ mode="currency"
769
+ currency="BRL"
770
+ />
771
+ ```
772
+
773
+ ## TopInputText
774
774
 
775
775
  Campo textual baseado no `InputText` do PrimeVue. O `v-model` é sempre
776
776
  `string`, inclusive para códigos, documentos e identificadores compostos
@@ -800,6 +800,7 @@ const codigo = ref('001234')
800
800
  | Prop | Tipo | Padrão |
801
801
  |---|---|---|
802
802
  | `modelValue` | `string` | `''` |
803
+ | `type` | `string` | `'text'` |
803
804
  | `label` | `string` | `''` |
804
805
  | `placeholder` | `string` | `''` |
805
806
  | `required` | `boolean` | `false` |
@@ -810,6 +811,7 @@ const codigo = ref('001234')
810
811
  Atributos e eventos nativos adicionais, como `name`, `maxlength`,
811
812
  `autocomplete`, `inputmode`, `pattern`, `aria-*`, `data-*`, `focus` e `blur`,
812
813
  são repassados ao elemento `input` interno.
814
+ Use `type="email"` ou `type="password"` para os respectivos campos.
813
815
 
814
816
  ## TopTextArea
815
817
 
@@ -896,43 +898,43 @@ function searchCustomers({ query }: { query: string }) {
896
898
  </template>
897
899
  ```
898
900
 
899
- | Prop | Tipo | Padrão |
900
- |---|---|---|
901
- | `modelValue` | `SelectOption \| SelectOption[] \| null` | `null` |
902
- | `options` | `array` | `[]` |
901
+ | Prop | Tipo | Padrão |
902
+ |---|---|---|
903
+ | `modelValue` | `SelectOption \| SelectOption[] \| null` | `null` |
904
+ | `options` | `array` | `[]` |
903
905
  | `optionLabel` | `string \| function` | `'label'` |
904
906
  | `optionKey` | `string` | `'id'` |
905
907
  | `optionPrefix` | `string` | `''` |
906
908
  | `showOptionPrefix` | `boolean` | `false` |
907
909
  | `showSelectedPrefix` | `boolean` | `false` |
908
910
  | `loading` / `disabled` / `invalid` | `boolean` | `false` |
909
- | `placeholder` | `string` | `'Pesquisar...'` |
911
+ | `placeholder` | `string` | `'Pesquisar...'` |
910
912
  | `minQueryLength` | `number` | `1` |
911
913
  | `multiple` / `forceSelection` | `boolean` | `false` / `true` |
912
914
  | `panelWidth` / `scrollHeight` | `string` | `null` / `'250px'` |
913
- | `emptyMessage` / `loadingMessage` | `string` | `'Nenhum resultado encontrado.'` / `'Carregando...'` |
915
+ | `emptyMessage` / `loadingMessage` | `string` | `'Nenhum resultado encontrado.'` / `'Carregando...'` |
914
916
  | `closeOnSelect` | `boolean` | `false` |
915
917
 
916
918
  Eventos: `update:modelValue`, `search`, `loadMore`, `clear`, `select` e
917
919
  `change`.
918
920
 
919
- Slots: `icon`, `option`, `selected-item`, `chip`, `empty`, `option-group` e
920
- `footer`. O slot `icon` recebe `loading`; sem ele, o componente mostra uma lupa
921
- ou um indicador de carregamento. Quando um slot não é informado, o componente usa sua apresentação padrão.
922
- O texto das opções é limitado visualmente pela largura disponível do painel,
923
- sem corte por quantidade fixa de caracteres; o tooltip padrão exibe o valor
924
- completo quando `showTooltip` está ativo.
925
-
926
- | Slot | Parâmetros recebidos | Uso |
927
- |---|---|---|
928
- | `icon` | `{ loading }` | Ícone à esquerda do campo. |
929
- | `option` | Props nativas, mais `{ option, label, prefix, query }` | Linha de uma opção. |
930
- | `selected-item` | Props nativas, incluindo `item` | Valor único escolhido. |
931
- | `chip` | Props nativas, incluindo `value` e `removeCallback` | Tag no modo múltiplo. |
932
- | `empty` | — | Conteúdo quando não há opções; também substitui o loading padrão. |
933
- | `option-group` | Props nativas, incluindo `option` | Cabeçalho de um grupo. |
934
- | `footer` | Props nativas do AutoComplete | Rodapé do painel. |
935
-
921
+ Slots: `icon`, `option`, `selected-item`, `chip`, `empty`, `option-group` e
922
+ `footer`. O slot `icon` recebe `loading`; sem ele, o componente mostra uma lupa
923
+ ou um indicador de carregamento. Quando um slot não é informado, o componente usa sua apresentação padrão.
924
+ O texto das opções é limitado visualmente pela largura disponível do painel,
925
+ sem corte por quantidade fixa de caracteres; o tooltip padrão exibe o valor
926
+ completo quando `showTooltip` está ativo.
927
+
928
+ | Slot | Parâmetros recebidos | Uso |
929
+ |---|---|---|
930
+ | `icon` | `{ loading }` | Ícone à esquerda do campo. |
931
+ | `option` | Props nativas, mais `{ option, label, prefix, query }` | Linha de uma opção. |
932
+ | `selected-item` | Props nativas, incluindo `item` | Valor único escolhido. |
933
+ | `chip` | Props nativas, incluindo `value` e `removeCallback` | Tag no modo múltiplo. |
934
+ | `empty` | — | Conteúdo quando não há opções; também substitui o loading padrão. |
935
+ | `option-group` | Props nativas, incluindo `option` | Cabeçalho de um grupo. |
936
+ | `footer` | Props nativas do AutoComplete | Rodapé do painel. |
937
+
936
938
  `search` recebe `{ originalEvent, query }` nas consultas digitadas e quando o
937
939
  botão abre o dropdown sem opções carregadas; se já houver opções, a abertura
938
940
  pelo botão reutiliza essa lista. Atualize `options` com os resultados.
@@ -989,111 +991,111 @@ const tabs: TopTabItem[] = [
989
991
  Cada `TopTabItem` possui `value`, `label` e `disabled?`. O `value` deve ser
990
992
  único e identifica tanto a seleção quanto o slot do painel; por exemplo,
991
993
  `value: 'documentos'` utiliza `#documentos`. Cada slot recebe `tab` e `active`.
992
- O componente emite somente `update:modelValue`. Atributos adicionais, incluindo
993
- as opções de passthrough do PrimeVue, são repassados ao componente `Tabs`.
994
-
995
- ## TopToast
996
-
997
- `TopToast` personaliza o renderizador do serviço `Toast` do PrimeVue. Registre
998
- `ToastService` uma vez, renderize um único `TopToast` perto da raiz e dispare
999
- mensagens com `useToast`. Ele não recebe uma lista de mensagens por prop.
1000
-
1001
- ```ts
1002
- // main.ts
1003
- import PrimeVue from 'primevue/config'
1004
- import ToastService from 'primevue/toastservice'
1005
- import { createApp } from 'vue'
1006
- import App from './App.vue'
1007
-
1008
- createApp(App).use(PrimeVue).use(ToastService).mount('#app')
1009
- ```
1010
-
1011
- ```vue
1012
- <script setup lang="ts">
1013
- import { useToast } from 'primevue/usetoast'
1014
- import { TopButton, TopToast } from '@topjoao/top-design-system'
1015
-
1016
- const toast = useToast()
1017
- const abrirCadastro = () => { /* navegue para o cadastro */ }
1018
-
1019
- function salvar() {
1020
- toast.add({
1021
- severity: 'success', summary: 'Cadastro concluído', detail: 'As alterações foram salvas.', life: 5000,
1022
- data: {
1023
- footer: 'Protocolo: CAD-2026-0042',
1024
- action: { label: 'Ver cadastro', icon: 'pi pi-arrow-right', onClick: () => abrirCadastro() },
1025
- },
1026
- })
1027
- }
1028
- </script>
1029
-
1030
- <template>
1031
- <TopToast :base-z-index="30000" />
1032
- <TopButton label="Salvar" @click="salvar" />
1033
- </template>
1034
- ```
1035
-
1036
- | Prop | Tipo | Padrão | Finalidade |
1037
- |---|---|---|---|
1038
- | `baseZIndex` | `number` | `30000` | Camada base das notificações. |
1039
-
1040
- Além das opções usuais de `ToastMessageOptions` do PrimeVue (`severity`,
1041
- `summary`, `detail`, `life`, `closable` etc.), `data` aceita `TopToastData`:
1042
-
1043
- | Campo | Tipo | Efeito |
1044
- |---|---|---|
1045
- | `data.footer` | `string \| number` | Texto discreto abaixo da mensagem. |
1046
- | `data.action.label` | `string` | Rótulo da ação. |
1047
- | `data.action.icon` | `string` opcional | Classe de ícone PrimeIcons. |
1048
- | `data.action.onClick` | `() => void` opcional | Função chamada ao clicar na ação. |
1049
-
1050
- | Slot | Parâmetros recebidos | Uso |
1051
- |---|---|---|
1052
- | `action` | `{ action, message, run }` | Substitui o botão; execute `run()` para chamar `action.onClick`. |
1053
- | `footer` | `{ message, footer }` | Substitui o rodapé. |
1054
-
1055
- ## Tipos e exports públicos
1056
-
1057
- O pacote raiz exporta todos os componentes, `TopSolutionsPreset`, `colors` e
1058
- os tipos abaixo. Use `import type` para não acrescentar código ao bundle.
1059
-
1060
- ```ts
1061
- import {
1062
- colors,
1063
- TopSolutionsPreset,
1064
- type TopButtonSeverity,
1065
- type TopDatePickerSelectionMode,
1066
- type TopDatePickerValue,
1067
- type TopFileUploadError,
1068
- type TopFileUploadValue,
1069
- type TopInputNumberValue,
1070
- type TopInputNumberMode,
1071
- type TopInputNumberButtonLayout,
1072
- type TopInputNumberCurrencyInputMode,
1073
- type TopNavItem,
1074
- type TopNavSection,
1075
- type TopTabItem,
1076
- type TopToastData,
1077
- } from '@topjoao/top-design-system'
1078
- ```
1079
-
1080
- `TopNavItem` descreve um nó (`id`, `label`, `to?`, `icon?`, `disabled?`,
1081
- `children?`, `data?`); `TopNavSection` é o mesmo contrato com `children`
1082
- obrigatório. `TopNavAction`, `TopNavUser`, `TopNavClient` e
1083
- `TopNavUserMenuItem` correspondem às props de mesmo nome. A aparência da barra
1084
- é definida por `TopNavBarAppearance` e seus subtipos exportados:
1085
- `TopNavBarColors`, `TopNavBarSurfaces`, `TopNavBarBorders`, `TopNavBarShape` e
1086
- `TopNavBarFocus`. `TopNavBarSpacing` tipa as propriedades opcionais
1087
- `headerPadding` e `breadcrumbPadding` da prop `spacing`.
1088
-
1089
- `TopInputNumberValue`, `TopInputNumberMode`, `TopInputNumberButtonLayout` e
1090
- `TopInputNumberCurrencyInputMode`
1091
- tipam, respectivamente, o valor, o modo de formatação, o layout dos botões e o
1092
- modo de entrada monetária do campo numérico. `colors` expõe as escalas
1093
- imutáveis `primary`, `secondary`, `success`, `warn` e
1094
- `danger`, cada uma com tons de `50` a `950`.
1095
-
1096
- ## Desenvolvimento da biblioteca
994
+ O componente emite somente `update:modelValue`. Atributos adicionais, incluindo
995
+ as opções de passthrough do PrimeVue, são repassados ao componente `Tabs`.
996
+
997
+ ## TopToast
998
+
999
+ `TopToast` personaliza o renderizador do serviço `Toast` do PrimeVue. Registre
1000
+ `ToastService` uma vez, renderize um único `TopToast` perto da raiz e dispare
1001
+ mensagens com `useToast`. Ele não recebe uma lista de mensagens por prop.
1002
+
1003
+ ```ts
1004
+ // main.ts
1005
+ import PrimeVue from 'primevue/config'
1006
+ import ToastService from 'primevue/toastservice'
1007
+ import { createApp } from 'vue'
1008
+ import App from './App.vue'
1009
+
1010
+ createApp(App).use(PrimeVue).use(ToastService).mount('#app')
1011
+ ```
1012
+
1013
+ ```vue
1014
+ <script setup lang="ts">
1015
+ import { useToast } from 'primevue/usetoast'
1016
+ import { TopButton, TopToast } from '@topjoao/top-design-system'
1017
+
1018
+ const toast = useToast()
1019
+ const abrirCadastro = () => { /* navegue para o cadastro */ }
1020
+
1021
+ function salvar() {
1022
+ toast.add({
1023
+ severity: 'success', summary: 'Cadastro concluído', detail: 'As alterações foram salvas.', life: 5000,
1024
+ data: {
1025
+ footer: 'Protocolo: CAD-2026-0042',
1026
+ action: { label: 'Ver cadastro', icon: 'pi pi-arrow-right', onClick: () => abrirCadastro() },
1027
+ },
1028
+ })
1029
+ }
1030
+ </script>
1031
+
1032
+ <template>
1033
+ <TopToast :base-z-index="30000" />
1034
+ <TopButton label="Salvar" @click="salvar" />
1035
+ </template>
1036
+ ```
1037
+
1038
+ | Prop | Tipo | Padrão | Finalidade |
1039
+ |---|---|---|---|
1040
+ | `baseZIndex` | `number` | `30000` | Camada base das notificações. |
1041
+
1042
+ Além das opções usuais de `ToastMessageOptions` do PrimeVue (`severity`,
1043
+ `summary`, `detail`, `life`, `closable` etc.), `data` aceita `TopToastData`:
1044
+
1045
+ | Campo | Tipo | Efeito |
1046
+ |---|---|---|
1047
+ | `data.footer` | `string \| number` | Texto discreto abaixo da mensagem. |
1048
+ | `data.action.label` | `string` | Rótulo da ação. |
1049
+ | `data.action.icon` | `string` opcional | Classe de ícone PrimeIcons. |
1050
+ | `data.action.onClick` | `() => void` opcional | Função chamada ao clicar na ação. |
1051
+
1052
+ | Slot | Parâmetros recebidos | Uso |
1053
+ |---|---|---|
1054
+ | `action` | `{ action, message, run }` | Substitui o botão; execute `run()` para chamar `action.onClick`. |
1055
+ | `footer` | `{ message, footer }` | Substitui o rodapé. |
1056
+
1057
+ ## Tipos e exports públicos
1058
+
1059
+ O pacote raiz exporta todos os componentes, `TopSolutionsPreset`, `colors` e
1060
+ os tipos abaixo. Use `import type` para não acrescentar código ao bundle.
1061
+
1062
+ ```ts
1063
+ import {
1064
+ colors,
1065
+ TopSolutionsPreset,
1066
+ type TopButtonSeverity,
1067
+ type TopDatePickerSelectionMode,
1068
+ type TopDatePickerValue,
1069
+ type TopFileUploadError,
1070
+ type TopFileUploadValue,
1071
+ type TopInputNumberValue,
1072
+ type TopInputNumberMode,
1073
+ type TopInputNumberButtonLayout,
1074
+ type TopInputNumberCurrencyInputMode,
1075
+ type TopNavItem,
1076
+ type TopNavSection,
1077
+ type TopTabItem,
1078
+ type TopToastData,
1079
+ } from '@topjoao/top-design-system'
1080
+ ```
1081
+
1082
+ `TopNavItem` descreve um nó (`id`, `label`, `to?`, `icon?`, `disabled?`,
1083
+ `children?`, `data?`); `TopNavSection` é o mesmo contrato com `children`
1084
+ obrigatório. `TopNavAction`, `TopNavUser`, `TopNavClient` e
1085
+ `TopNavUserMenuItem` correspondem às props de mesmo nome. A aparência da barra
1086
+ é definida por `TopNavBarAppearance` e seus subtipos exportados:
1087
+ `TopNavBarColors`, `TopNavBarSurfaces`, `TopNavBarBorders`, `TopNavBarShape` e
1088
+ `TopNavBarFocus`. `TopNavBarSpacing` tipa as propriedades opcionais
1089
+ `headerPadding` e `breadcrumbPadding` da prop `spacing`.
1090
+
1091
+ `TopInputNumberValue`, `TopInputNumberMode`, `TopInputNumberButtonLayout` e
1092
+ `TopInputNumberCurrencyInputMode`
1093
+ tipam, respectivamente, o valor, o modo de formatação, o layout dos botões e o
1094
+ modo de entrada monetária do campo numérico. `colors` expõe as escalas
1095
+ imutáveis `primary`, `secondary`, `success`, `warn` e
1096
+ `danger`, cada uma com tons de `50` a `950`.
1097
+
1098
+ ## Desenvolvimento da biblioteca
1097
1099
 
1098
1100
  ```bash
1099
1101
  npm install
@@ -1133,14 +1135,14 @@ Para gerar um pacote local instalável:
1133
1135
  npm pack
1134
1136
  ```
1135
1137
 
1136
- Para publicar uma nova versão estável, primeiro incremente a versão seguindo o
1137
- versionamento semântico; versões já publicadas no npm não podem ser
1138
- sobrescritas. Use `patch`, `minor` ou `major` conforme o impacto da mudança.
1139
-
1140
- ```bash
1141
- npm version patch --no-git-tag-version
1142
- npm publish --access public --tag latest
1143
- ```
1144
-
1145
- A tag `latest` é a padrão do npm. Assim, consumidores instalam a versão estável
1146
- simplesmente com `npm install @topjoao/top-design-system`.
1138
+ Para publicar uma nova versão estável, primeiro incremente a versão seguindo o
1139
+ versionamento semântico; versões já publicadas no npm não podem ser
1140
+ sobrescritas. Use `patch`, `minor` ou `major` conforme o impacto da mudança.
1141
+
1142
+ ```bash
1143
+ npm version patch --no-git-tag-version
1144
+ npm publish --access public --tag latest
1145
+ ```
1146
+
1147
+ A tag `latest` é a padrão do npm. Assim, consumidores instalam a versão estável
1148
+ simplesmente com `npm install @topjoao/top-design-system`.