@topjoao/top-design-system 0.1.0-beta.9 → 0.1.1-beta.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 +750 -52
- package/dist/TopToast-BI4cWWtd.js +3024 -0
- package/dist/TopToast-BI4cWWtd.js.map +1 -0
- package/dist/TopToast-tPhTQRza.cjs +2 -0
- package/dist/TopToast-tPhTQRza.cjs.map +1 -0
- package/dist/components/TopAccordion.vue.d.ts +48 -0
- package/dist/components/TopAccordionNavigator.vue.d.ts +35 -0
- package/dist/components/TopAccordionPanel.vue.d.ts +42 -0
- package/dist/components/TopAccordionSummary.vue.d.ts +23 -0
- package/dist/components/TopButton.vue.d.ts +4 -1
- package/dist/components/TopConfirmDialog.vue.d.ts +1 -1
- package/dist/components/TopDatePicker.vue.d.ts +81 -0
- package/dist/components/TopFileUpload.vue.d.ts +88 -0
- package/dist/components/TopInputNumber.vue.d.ts +89 -0
- package/dist/components/TopNavBar.vue.d.ts +288 -0
- package/dist/components/TopSelect.vue.d.ts +4 -4
- package/dist/components/TopTabs.vue.d.ts +34 -0
- package/dist/components/TopToast.vue.d.ts +2 -10
- package/dist/components/internal/TopNavMobileTree.vue.d.ts +20 -0
- package/dist/components/internal/topAccordion.d.ts +14 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.js +10 -10
- package/dist/nuxt.cjs +1 -1
- package/dist/nuxt.cjs.map +1 -1
- package/dist/nuxt.js +40 -0
- package/dist/nuxt.js.map +1 -1
- package/dist/plugin.cjs +1 -1
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.ts +18 -0
- package/dist/plugin.js +4 -4
- package/dist/plugin.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/types/toast.d.ts +17 -0
- package/package.json +4 -2
- package/dist/TopToast-B376KudO.cjs +0 -2
- package/dist/TopToast-B376KudO.cjs.map +0 -1
- package/dist/TopToast-YNoWv10q.js +0 -673
- package/dist/TopToast-YNoWv10q.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,12 +1,36 @@
|
|
|
1
1
|
# TopSolutions Design System
|
|
2
2
|
|
|
3
3
|
Biblioteca de componentes Vue 3, estilos e tokens visuais compartilhados pela
|
|
4
|
-
TopSolutions.
|
|
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
|
+
| `TopInputNumber` | Campo numérico localizado, com moeda, limites e incrementos. | `number \| null` |
|
|
25
|
+
| `TopNavBar` | Navegação responsiva, breadcrumbs, favoritos e Drawer. | `searchValue` e `mobileOpen` opcionais |
|
|
26
|
+
| `TopSelect` | Autocomplete pesquisável com paginação virtual. | opção/opções |
|
|
27
|
+
| `TopTabs` | Abas com painéis nomeados. | `string \| number` |
|
|
28
|
+
| `TopToast` | Renderizador de notificações do serviço Toast do PrimeVue. | — |
|
|
5
29
|
|
|
6
30
|
## Instalação
|
|
7
31
|
|
|
8
32
|
```bash
|
|
9
|
-
npm install @topjoao/top-design-system
|
|
33
|
+
npm install @topjoao/top-design-system
|
|
10
34
|
```
|
|
11
35
|
|
|
12
36
|
A aplicação consumidora deve possuir Vue 3, PrimeVue, PrimeIcons e
|
|
@@ -29,6 +53,16 @@ app.use(PrimeVue, {
|
|
|
29
53
|
})
|
|
30
54
|
```
|
|
31
55
|
|
|
56
|
+
Para ativar o modo escuro, adicione ou remova `.dark` uma única vez no elemento
|
|
57
|
+
`<html>` da aplicação. Os componentes usam tokens semânticos de superfície, texto e
|
|
58
|
+
borda fornecidos por `style.css`; não é necessário passar classes `dark:` em cada
|
|
59
|
+
uso. A aplicação pode substituir esses tokens após importar o CSS da biblioteca.
|
|
60
|
+
|
|
61
|
+
Os tokens públicos de campos são `--top-field-background`,
|
|
62
|
+
`--top-field-background-readonly`, `--top-field-background-disabled`,
|
|
63
|
+
`--top-field-text`, `--top-field-label`, `--top-field-placeholder`,
|
|
64
|
+
`--top-field-border`, `--top-field-border-hover` e `--top-field-icon`.
|
|
65
|
+
|
|
32
66
|
O preset é independente dos ajustes de layout próprios do TopLicita; ele
|
|
33
67
|
contém apenas tokens semânticos compartilháveis, como cores primárias, neutras,
|
|
34
68
|
sucesso, alerta e erro.
|
|
@@ -99,6 +133,264 @@ createApp(App).use(TopSolutionsDesignSystem).mount('#app')
|
|
|
99
133
|
Após o registro, os componentes podem ser utilizados sem importação manual. A
|
|
100
134
|
entrada `/plugin` também fornece as declarações globais usadas pela IDE.
|
|
101
135
|
|
|
136
|
+
## TopNavBar
|
|
137
|
+
|
|
138
|
+
Barra de navegação responsiva inspirada no AppSidebar do TopLicita. O
|
|
139
|
+
componente fornece apenas layout e interação: a aplicação consumidora continua
|
|
140
|
+
responsável por rotas, permissões, sessão, cliente/órgão, busca remota,
|
|
141
|
+
favoritos, Aia, suporte e integrações. Nenhuma dessas ações é executada pela
|
|
142
|
+
biblioteca; todas são comunicadas por eventos.
|
|
143
|
+
|
|
144
|
+
```vue
|
|
145
|
+
<script setup lang="ts">
|
|
146
|
+
import { ref } from 'vue'
|
|
147
|
+
import {
|
|
148
|
+
TopNavBar,
|
|
149
|
+
type TopNavAction,
|
|
150
|
+
type TopNavItem,
|
|
151
|
+
type TopNavSection,
|
|
152
|
+
} from '@topjoao/top-design-system'
|
|
153
|
+
|
|
154
|
+
const clienteAtual = ref('prefeitura-a')
|
|
155
|
+
const favorito = ref(false)
|
|
156
|
+
|
|
157
|
+
const secoes: TopNavSection[] = [
|
|
158
|
+
{
|
|
159
|
+
id: 'planejamento',
|
|
160
|
+
label: 'Planejamento',
|
|
161
|
+
icon: 'pi pi-book',
|
|
162
|
+
children: [
|
|
163
|
+
{
|
|
164
|
+
id: 'programacao',
|
|
165
|
+
label: 'Programação',
|
|
166
|
+
children: [
|
|
167
|
+
{ id: 'calendario', label: 'Calendário', to: '/programacao/calendario' },
|
|
168
|
+
],
|
|
169
|
+
},
|
|
170
|
+
],
|
|
171
|
+
},
|
|
172
|
+
]
|
|
173
|
+
|
|
174
|
+
function navegar(item: TopNavItem) {
|
|
175
|
+
if (item.to) router.push(item.to)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function executarIntegracao(action: TopNavAction) {
|
|
179
|
+
// Abra a integração identificada por action.id.
|
|
180
|
+
}
|
|
181
|
+
</script>
|
|
182
|
+
|
|
183
|
+
<template>
|
|
184
|
+
<TopNavBar
|
|
185
|
+
:sections="secoes"
|
|
186
|
+
active-item-id="calendario"
|
|
187
|
+
searchable
|
|
188
|
+
show-aia
|
|
189
|
+
show-support
|
|
190
|
+
show-favorite-toggle
|
|
191
|
+
:favorite-active="favorito"
|
|
192
|
+
:actions="[
|
|
193
|
+
{ id: 'integracoes', label: 'Integrações', icon: 'pi pi-th-large' },
|
|
194
|
+
]"
|
|
195
|
+
:user="{ name: 'João Silva', subtitle: 'Administrador', initials: 'JS' }"
|
|
196
|
+
:user-menu-items="[
|
|
197
|
+
{ id: 'perfil', label: 'Meu perfil', icon: 'pi pi-user' },
|
|
198
|
+
{ id: 'sair', label: 'Sair', icon: 'pi pi-sign-out' },
|
|
199
|
+
]"
|
|
200
|
+
@navigate="navegar"
|
|
201
|
+
@search="consultarMenusPermitidos"
|
|
202
|
+
@toggle-aia="alternarAia"
|
|
203
|
+
@open-support="abrirCentralSuporte"
|
|
204
|
+
@toggle-favorite="favorito = !favorito"
|
|
205
|
+
@action="executarIntegracao"
|
|
206
|
+
@user-action="executarAcaoDaSessao"
|
|
207
|
+
>
|
|
208
|
+
<template #brand="{ compact }">
|
|
209
|
+
<img src="/logo.svg" alt="Minha organização">
|
|
210
|
+
<span v-if="!compact">Sistema de Contratações</span>
|
|
211
|
+
</template>
|
|
212
|
+
|
|
213
|
+
<template #context="{ compact }">
|
|
214
|
+
<select v-model="clienteAtual" aria-label="Cliente atual">
|
|
215
|
+
<option value="prefeitura-a">Prefeitura A</option>
|
|
216
|
+
<option value="prefeitura-b">Prefeitura B</option>
|
|
217
|
+
</select>
|
|
218
|
+
<span v-if="!compact">Poder Executivo</span>
|
|
219
|
+
</template>
|
|
220
|
+
</TopNavBar>
|
|
221
|
+
</template>
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Menu e breadcrumbs
|
|
225
|
+
|
|
226
|
+
`sections` aceita uma árvore de profundidade arbitrária. Cada nó usa
|
|
227
|
+
`TopNavItem` (`id`, `label`, `to?`, `icon?`, `disabled?`, `children?`, `data?`).
|
|
228
|
+
Seções sem filhos são removidas e um `children: []` nunca cria um painel vazio.
|
|
229
|
+
No desktop, a primeira coluna do painel mestre–detalhe tem `16rem`; os itens de
|
|
230
|
+
cada nível são repartidos em colunas de `18rem`, no máximo dez por coluna.
|
|
231
|
+
Subníveis aparecem sempre à direita do nível de origem.
|
|
232
|
+
|
|
233
|
+
Breadcrumbs estão habilitados por padrão e começam por `Início / Navegação`.
|
|
234
|
+
Há duas formas de fornecer a trilha:
|
|
235
|
+
|
|
236
|
+
- informe `breadcrumbs` com itens `TopNavBreadcrumb`; `sectionId` liga o item a
|
|
237
|
+
uma seção e `menuId` liga a qualquer nó com filhos;
|
|
238
|
+
- omita `breadcrumbs` e informe `activeItemId`; a trilha é derivada da árvore.
|
|
239
|
+
|
|
240
|
+
Por exemplo, `calendario` dentro de `Programação` em `Planejamento` gera
|
|
241
|
+
`Início / Navegação / Planejamento / Programação / Calendário`. A rota ativa
|
|
242
|
+
não recebe fundo permanente nos menus desktop; somente hover e o ramo que está
|
|
243
|
+
sendo explorado recebem destaque.
|
|
244
|
+
|
|
245
|
+
### Props
|
|
246
|
+
|
|
247
|
+
| Prop | Tipo / padrão | Finalidade |
|
|
248
|
+
|---|---|---|
|
|
249
|
+
| `sections` | `TopNavSection[]` / `[]` | Árvore de navegação já filtrada pela aplicação. |
|
|
250
|
+
| `breadcrumbs` | `TopNavBreadcrumb[]` / `[]` | Trilha explícita; vazia permite derivação por `activeItemId`. |
|
|
251
|
+
| `homeItem` | `TopNavItem` / `Início` | Item inicial emitido ao clicar em Início. |
|
|
252
|
+
| `navigationLabel` | `string` / `Navegação` | Rótulo do menu mestre. |
|
|
253
|
+
| `activeItemId` | `string` | Nó atual, usado no breadcrumb e no Drawer. |
|
|
254
|
+
| `searchable` | `boolean` / `false` | Habilita busca desktop e busca própria do Drawer. |
|
|
255
|
+
| `searchValue` | `string` | Valor opcionalmente controlado com `v-model:search-value`. |
|
|
256
|
+
| `searchResults` | `TopNavItem[]` | Resultados controlados; sem a prop, a árvore é filtrada localmente. |
|
|
257
|
+
| `searchPlaceholder` | `string` | Placeholder das duas buscas. |
|
|
258
|
+
| `showAia`, `showSupport` | `boolean` / `false` | Exibem as ações opcionais. |
|
|
259
|
+
| `aiaActive` | `boolean` / `false` | Estado visual do botão Aia. |
|
|
260
|
+
| `aiaLabel`, `supportLabel` | `string` | Textos acessíveis e rótulos do Drawer. |
|
|
261
|
+
| `actions` | `TopNavAction[]` / `[]` | Ações genéricas, como integrações, emitidas por `action`. |
|
|
262
|
+
| `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. |
|
|
263
|
+
| `user` | `TopNavUser` | Dados exclusivamente visuais do usuário. |
|
|
264
|
+
| `userMenuItems` | `TopNavUserMenuItem[]` | Opções emitidas por `user-action`; suporta separadores. |
|
|
265
|
+
| `favoriteItems` | `TopNavItem[]` / `[]` | Favoritos fornecidos pelo pai para dropdown e Drawer. |
|
|
266
|
+
| `showFavoriteToggle` | `boolean` / `false` | Exibe a estrela da página atual. |
|
|
267
|
+
| `favoriteActive` | `boolean` / `false` | Estado visual da estrela atual. |
|
|
268
|
+
| `mobileOpen` | `boolean` | Controle opcional com `v-model:mobile-open`. |
|
|
269
|
+
| `appearance` | `TopNavBarAppearance` | Tokens visuais locais descritos abaixo. |
|
|
270
|
+
|
|
271
|
+
### Eventos
|
|
272
|
+
|
|
273
|
+
| Evento | Payload | Quando ocorre |
|
|
274
|
+
|---|---|---|
|
|
275
|
+
| `navigate` | `TopNavItem` | Início, menu, resultado ou favorito é selecionado. |
|
|
276
|
+
| `search` | `string` | A consulta muda no desktop ou no Drawer. |
|
|
277
|
+
| `update:searchValue` | `string` | Atualização de `v-model:search-value`. |
|
|
278
|
+
| `update:mobileOpen` | `boolean` | Atualização de `v-model:mobile-open`. |
|
|
279
|
+
| `toggle-aia` | — | A ação Aia é acionada. |
|
|
280
|
+
| `open-support` | — | A ação de suporte é acionada. |
|
|
281
|
+
| `toggle-favorite` | — | A estrela da página atual é acionada. |
|
|
282
|
+
| `action` | `TopNavAction` | Uma ação genérica/integração é acionada. |
|
|
283
|
+
| `user-action` | `TopNavUserMenuItem` | Uma opção de usuário é selecionada. |
|
|
284
|
+
| `user-click` | `TopNavUser \| undefined` | A área de usuário sem menu é acionada. |
|
|
285
|
+
|
|
286
|
+
`Ctrl+K` e `Cmd+K` abrem/focam a busca. Em telas menores que `1024px`, o
|
|
287
|
+
atalho abre primeiro o Drawer e foca a busca móvel. `Escape` fecha os painéis.
|
|
288
|
+
|
|
289
|
+
### Slots
|
|
290
|
+
|
|
291
|
+
| Slot | Uso |
|
|
292
|
+
|---|---|
|
|
293
|
+
| `brand` | Marca; recebe `{ compact }`. |
|
|
294
|
+
| `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`. |
|
|
295
|
+
| `context-compact` | Variante explícita usada no último estágio de overflow. |
|
|
296
|
+
| `actions` | Conteúdo adicional do cabeçalho; recebe `{ compact, close }`. |
|
|
297
|
+
| `aia-icon`, `support-icon` | Ícones customizados das ações quadradas. |
|
|
298
|
+
| `user` | Conteúdo do gatilho de usuário; recebe `{ user, compact }`. |
|
|
299
|
+
| `user-menu` | Painel de usuário; recebe `{ items, select }`. |
|
|
300
|
+
| `search-results` | Resultados customizados; recebe `{ items, select }`. |
|
|
301
|
+
| `breadcrumb-actions` | Ações adicionais no fim da segunda faixa. |
|
|
302
|
+
| `drawer-header` | Cabeçalho inteiro; recebe `{ close }`. |
|
|
303
|
+
| `drawer-brand` | Marca do Drawer; por padrão reutiliza `brand`. |
|
|
304
|
+
| `drawer-search` | Busca inteira; recebe `{ query, update, clear }`. |
|
|
305
|
+
| `drawer-actions` | Ações; recebe `{ actions, select, close }`. |
|
|
306
|
+
| `drawer-before-menu`, `drawer-after-menu` | Conteúdo antes/depois do trilho rolável. |
|
|
307
|
+
| `drawer-menu` | Substitui a árvore; recebe `{ sections, select, close }`. |
|
|
308
|
+
| `drawer-user` | Rodapé de usuário; recebe `{ user, client, open, toggle }`. |
|
|
309
|
+
| `drawer-footer` | Conteúdo final adicional; recebe `{ close }`. |
|
|
310
|
+
|
|
311
|
+
### Faixa de favoritos
|
|
312
|
+
|
|
313
|
+
No desktop, `favoriteItems` aparece primeiro em uma faixa horizontal abaixo dos
|
|
314
|
+
breadcrumbs. A biblioteca mede uma cópia invisível da faixa com
|
|
315
|
+
`ResizeObserver`: se a largura real não couber, ela é substituída pelo dropdown
|
|
316
|
+
`Favoritos`. O mesmo dropdown é usado depois que a página passa de `120px` de
|
|
317
|
+
scroll e a faixa retorna apenas ao chegar a `24px` ou menos. Os valores evitam
|
|
318
|
+
oscilações perto do topo e reproduzem o comportamento do AppSidebar.
|
|
319
|
+
|
|
320
|
+
### Aparência e responsividade
|
|
321
|
+
|
|
322
|
+
`appearance` é propositalmente pequeno e semântico. Use `colors` para
|
|
323
|
+
`navigation`, `text`, `mutedText`, `accent`, `border`, `menuText`,
|
|
324
|
+
`mobileActiveText` e `favoritesText`; `surfaces` para `breadcrumb`, `drawer`,
|
|
325
|
+
`drawerFooter`, `menu`, `menuHover`, `menuExplored`, `mobileActive`,
|
|
326
|
+
`favorites` e `currentPage`; `borders` para `menu` (a borda externa de 6px),
|
|
327
|
+
`menuOutline`, `mobileDivider`, `favorites` e `currentPage`; `shape` para
|
|
328
|
+
`radius`, `drawerRadius`, `shadow` e `favoritesShadow`; e `focus` para
|
|
329
|
+
`onDark` e `onLight`.
|
|
330
|
+
|
|
331
|
+
```ts
|
|
332
|
+
const appearance = {
|
|
333
|
+
colors: { navigation: '#09090b', text: '#f4f4f5', border: 'rgb(255 255 255 / 14%)' },
|
|
334
|
+
surfaces: { drawer: '#09090b', menu: '#18181b', menuHover: '#27272a' },
|
|
335
|
+
shape: { radius: '8px', shadow: '0 12px 30px rgb(0 0 0 / 25%)' },
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
A biblioteca não fixa tipografia inline. Por padrão, família, tamanho, peso e
|
|
340
|
+
altura de linha são herdados da aplicação consumidora. Além disso, `appearance`
|
|
341
|
+
só cria variáveis inline para propriedades que foram realmente informadas; os
|
|
342
|
+
valores fiéis ao AppSidebar existem apenas como *fallbacks* no CSS. Assim, um
|
|
343
|
+
tema global pode controlar o componente sem precisar usar `!important`:
|
|
344
|
+
|
|
345
|
+
```css
|
|
346
|
+
:root {
|
|
347
|
+
--top-nav-font-family: var(--app-font-family);
|
|
348
|
+
--top-nav-font-size: var(--app-font-size);
|
|
349
|
+
--top-nav-strong-font-weight: 600;
|
|
350
|
+
--top-nav-action-size: 2.5rem;
|
|
351
|
+
--top-nav-header-padding: 0.625rem 1.5rem;
|
|
352
|
+
--top-nav-menu-item-padding: 0.5rem 0.75rem;
|
|
353
|
+
--top-nav-section-width: 16rem;
|
|
354
|
+
--top-nav-column-width: 18rem;
|
|
355
|
+
--top-nav-mobile-active-bg: #fff;
|
|
356
|
+
--top-nav-mobile-active-fg: #025a84;
|
|
357
|
+
--top-nav-mobile-divider: rgb(255 255 255 / 20%);
|
|
358
|
+
--top-nav-mobile-item-gap: 0.25rem;
|
|
359
|
+
--top-nav-mobile-submenu-padding: 0.5rem 0 0.375rem 0.35rem;
|
|
360
|
+
--top-nav-favorites-bg: #f8fafc;
|
|
361
|
+
--top-nav-favorites-fg: #0f172a;
|
|
362
|
+
--top-nav-favorites-border: #e2e8f0;
|
|
363
|
+
--top-nav-favorites-shadow: 0 1px 2px rgb(15 23 42 / 6%);
|
|
364
|
+
--top-nav-focus-ring: #dbeafe;
|
|
365
|
+
--top-nav-focus-ring-light: #1d4ed8;
|
|
366
|
+
--top-nav-current-bg: rgb(255 255 255 / 10%);
|
|
367
|
+
--top-nav-current-border: rgb(255 255 255 / 15%);
|
|
368
|
+
--top-nav-menu-scrollbar-thumb: #94a3b8;
|
|
369
|
+
}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
As variáveis globais também alcançam o Drawer teleportado. Use-as para ajustes
|
|
373
|
+
estruturais — tipografia, larguras, alturas, padding e espaçamentos do menu —
|
|
374
|
+
em vez de props no componente. Um valor passado por `appearance` tem precedência
|
|
375
|
+
local e não altera os demais tokens do tema.
|
|
376
|
+
|
|
377
|
+
O breakpoint móvel é `1024px`. No desktop, um `ResizeObserver` reaplica a mesma
|
|
378
|
+
sequência progressiva do AppSidebar: ações colapsam abaixo de `1440px`, busca
|
|
379
|
+
vira ícone abaixo de `1320px`, nome do usuário some abaixo de `1180px` e, se o
|
|
380
|
+
conteúdo ainda transbordar, o contexto recebe `compact: true`. O último estágio
|
|
381
|
+
também limita o contêiner do contexto a `3.25rem`; use `context-compact` quando
|
|
382
|
+
quiser controlar exatamente o que permanece visível.
|
|
383
|
+
|
|
384
|
+
Abaixo de `1024px`, a navegação desktop desaparece e o Drawer do PrimeVue assume.
|
|
385
|
+
Ele mantém cabeçalho, busca, ações, trilho translúcido rolável, árvore recursiva,
|
|
386
|
+
favoritos e usuário. No rodapé, a foto e o nome do usuário formam a primeira
|
|
387
|
+
linha; o cliente atual aparece abaixo e o subtítulo do cliente recebe uma
|
|
388
|
+
etiqueta quando houver. A transição `menu-expand` existe somente dentro do Drawer;
|
|
389
|
+
os dropdowns desktop abrem sem animação e suas áreas de hover incluem o espaço
|
|
390
|
+
entre gatilho e painel. Nessa largura, os breadcrumbs deixam de rolar
|
|
391
|
+
horizontalmente: eles quebram em linhas e o bloco da página atual ocupa sua
|
|
392
|
+
própria linha para permanecer legível.
|
|
393
|
+
|
|
102
394
|
## TopButton
|
|
103
395
|
|
|
104
396
|
Exemplo
|
|
@@ -107,6 +399,7 @@ Exemplo
|
|
|
107
399
|
<template>
|
|
108
400
|
<TopButton label="Salvar" icon="pi pi-save" @click="salvar" />
|
|
109
401
|
<TopButton label="Cancelar" secondary />
|
|
402
|
+
<TopButton label="Excluir" severity="danger" />
|
|
110
403
|
|
|
111
404
|
<TopButton label="Consultar" outlined>
|
|
112
405
|
<template #icon>
|
|
@@ -125,12 +418,16 @@ Exemplo
|
|
|
125
418
|
| `loading` | `boolean` | `false` |
|
|
126
419
|
| `class` | `string` | `''` |
|
|
127
420
|
| `outlined` | `boolean` | `false` |
|
|
421
|
+
| `severity` | `'primary' \| 'secondary' \| 'success' \| 'warn' \| 'danger'` | `'primary'` |
|
|
128
422
|
| `secondary` | `boolean` | `false` |
|
|
129
423
|
| `disabled` | `boolean` | `false` |
|
|
130
424
|
| `unstyled` | `boolean` | `false` |
|
|
131
425
|
| `type` | `'button' \| 'submit' \| 'reset'` | `'button'` |
|
|
132
426
|
|
|
133
|
-
O componente emite `click` sem payload
|
|
427
|
+
O componente emite `click` sem payload. O slot nomeado `icon` não recebe
|
|
428
|
+
parâmetros e substitui a prop `icon` — útil para SVGs, `HugeiconsIcon` ou um
|
|
429
|
+
ícone com estado próprio. `secondary` permanece como atalho compatível para
|
|
430
|
+
`severity="secondary"` e tem precedência sobre `severity`.
|
|
134
431
|
|
|
135
432
|
## TopConfirmDialog
|
|
136
433
|
|
|
@@ -179,48 +476,277 @@ não fecha automaticamente o diálogo, permitindo que a aplicação aguarde uma
|
|
|
179
476
|
operação assíncrona. Os slots `message` e default permitem substituir a mensagem
|
|
180
477
|
textual.
|
|
181
478
|
|
|
182
|
-
##
|
|
479
|
+
## TopDatePicker
|
|
480
|
+
|
|
481
|
+
Seletor de datas baseado no `DatePicker` do PrimeVue. O valor permanece como
|
|
482
|
+
`Date` (ou arrays de `Date` nos modos `multiple` e `range`); `dateFormat` altera
|
|
483
|
+
somente a apresentação no campo e não converte o `v-model` para texto.
|
|
484
|
+
No modo padrão (`single` com `dd/mm/yy`), a digitação recebe automaticamente a
|
|
485
|
+
máscara brasileira `dd/mm/aaaa`.
|
|
486
|
+
|
|
487
|
+
```vue
|
|
488
|
+
<script setup lang="ts">
|
|
489
|
+
import { ref } from 'vue'
|
|
490
|
+
import { TopDatePicker } from '@topjoao/top-design-system'
|
|
491
|
+
|
|
492
|
+
const dataNascimento = ref<Date | null>(null)
|
|
493
|
+
</script>
|
|
494
|
+
|
|
495
|
+
<template>
|
|
496
|
+
<TopDatePicker
|
|
497
|
+
v-model="dataNascimento"
|
|
498
|
+
label="Data de nascimento"
|
|
499
|
+
placeholder="Selecione a data"
|
|
500
|
+
:max-date="new Date()"
|
|
501
|
+
required
|
|
502
|
+
error="Informe uma data válida."
|
|
503
|
+
@date-select="validarData"
|
|
504
|
+
/>
|
|
505
|
+
</template>
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
| Prop | Tipo | Padrão |
|
|
509
|
+
|---|---|---|
|
|
510
|
+
| `modelValue` | `Date \| Date[] \| (Date \| null)[] \| null` | `null` |
|
|
511
|
+
| `label` | `string` | `''` |
|
|
512
|
+
| `placeholder` | `string` | `'dd/mm/aaaa'` |
|
|
513
|
+
| `required` | `boolean` | `false` |
|
|
514
|
+
| `error` | `string` | `''` |
|
|
515
|
+
| `invalid` | `boolean` | `false` |
|
|
516
|
+
| `disabled` | `boolean` | `false` |
|
|
517
|
+
| `readonly` | `boolean` | `false` |
|
|
518
|
+
| `selectionMode` | `'single' \| 'multiple' \| 'range'` | `'single'` |
|
|
519
|
+
| `dateFormat` | `string` | `'dd/mm/yy'` |
|
|
520
|
+
| `minDate` / `maxDate` | `Date` | `undefined` |
|
|
521
|
+
| `showIcon` | `boolean` | `true` |
|
|
522
|
+
| `iconDisplay` | `'button' \| 'input'` | `'input'` |
|
|
523
|
+
| `manualInput` | `boolean` | `true` |
|
|
524
|
+
| `showButtonBar` | `boolean` | `false` |
|
|
525
|
+
| `appendTo` | `'body' \| 'self' \| HTMLElement` | `'body'` |
|
|
526
|
+
|
|
527
|
+
Eventos: `update:modelValue`, `input`, `change`, `date-select`, `show`, `hide`,
|
|
528
|
+
`today-click`, `clear-click`, `month-change`, `year-change`, `focus`, `blur` e
|
|
529
|
+
`keydown`. Os slots do `DatePicker` do PrimeVue são repassados pelo wrapper,
|
|
530
|
+
incluindo `date`, `header`, `footer`, `buttonbar`, `inputicon`, `dropdownicon`,
|
|
531
|
+
`previcon` e `nexticon`.
|
|
183
532
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
533
|
+
O slot `date` recebe as props de dia disponibilizadas pelo `DatePicker`; os
|
|
534
|
+
slots de ícone recebem as props correspondentes do PrimeVue. Os slots `header`,
|
|
535
|
+
`footer` e `buttonbar` permitem substituir essas regiões. Todos são apenas
|
|
536
|
+
repassados: o wrapper preserva as props e o comportamento do componente-base.
|
|
537
|
+
|
|
538
|
+
`required` adiciona o atributo nativo e o asterisco visual; a validação continua
|
|
539
|
+
sob responsabilidade da aplicação. `error` ativa o estado inválido, associa a
|
|
540
|
+
mensagem ao input com atributos ARIA e a exibe abaixo do campo. `readonly`
|
|
541
|
+
impede edição e seleção sem desabilitar o controle, enquanto `disabled` remove a
|
|
542
|
+
interação. No modo escuro, o campo usa os tokens públicos `--top-field-*`.
|
|
543
|
+
|
|
544
|
+
## TopFileUpload
|
|
545
|
+
|
|
546
|
+
Seletor de arquivos baseado no `FileUpload` do PrimeVue. O componente valida e
|
|
547
|
+
apresenta os arquivos, mas não os envia: a aplicação consumidora controla o
|
|
548
|
+
upload por `v-model` e pelos eventos.
|
|
549
|
+
|
|
550
|
+
```vue
|
|
551
|
+
<script setup lang="ts">
|
|
552
|
+
import { ref } from 'vue'
|
|
553
|
+
import { TopFileUpload } from '@topjoao/top-design-system'
|
|
554
|
+
|
|
555
|
+
const anexos = ref<File[]>([])
|
|
556
|
+
|
|
557
|
+
function enviarArquivos(files: File[]) {
|
|
558
|
+
// Envie os arquivos usando o serviço da aplicação.
|
|
559
|
+
}
|
|
560
|
+
</script>
|
|
561
|
+
|
|
562
|
+
<template>
|
|
563
|
+
<TopFileUpload
|
|
564
|
+
v-model="anexos"
|
|
565
|
+
label="Anexos"
|
|
566
|
+
accept=".pdf,image/*"
|
|
567
|
+
multiple
|
|
568
|
+
:max-file-size="5 * 1024 * 1024"
|
|
569
|
+
:max-files="5"
|
|
570
|
+
required
|
|
571
|
+
@select="enviarArquivos"
|
|
572
|
+
/>
|
|
573
|
+
</template>
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
| Prop | Tipo | Padrão |
|
|
577
|
+
|---|---|---|
|
|
578
|
+
| `modelValue` | `File \| File[] \| null` | `null` |
|
|
579
|
+
| `label` | `string` | `''` |
|
|
580
|
+
| `placeholder` | `string` | `'Arraste e solte o arquivo aqui'` |
|
|
581
|
+
| `required` | `boolean` | `false` |
|
|
582
|
+
| `disabled` | `boolean` | `false` |
|
|
583
|
+
| `accept` | `string` | `''` |
|
|
584
|
+
| `multiple` | `boolean` | `false` |
|
|
585
|
+
| `maxFileSize` | `number \| null` (bytes) | `null` |
|
|
586
|
+
| `maxFiles` | `number \| null` | `null` |
|
|
587
|
+
| `error` | `string` | `''` |
|
|
588
|
+
| `selectLabel` | `string` | `'Selecionar arquivo'` |
|
|
589
|
+
| `removeLabel` | `string` | `'Remover'` |
|
|
590
|
+
| `loading` | `boolean` | `false` |
|
|
591
|
+
|
|
592
|
+
Eventos: `update:modelValue`, `select`, `change`, `remove`, `clear` e `error`.
|
|
593
|
+
Erros de tipo, tamanho e quantidade possuem `code`, `message` e o `file`
|
|
594
|
+
relacionado. Os slots `empty` e `preview` permitem customizar a área vazia e a
|
|
595
|
+
pré-visualização. Os métodos `choose()` e `clear()` ficam disponíveis pela ref
|
|
596
|
+
do componente.
|
|
597
|
+
|
|
598
|
+
| Slot | Parâmetros recebidos | Uso |
|
|
599
|
+
|---|---|---|
|
|
600
|
+
| `empty` | `{ choose, disabled }` | Substitui a área vazia. Chame `choose()` para abrir o seletor nativo. |
|
|
601
|
+
| `preview` | `{ file, index, url }` | Substitui a miniatura. `url` é uma object URL apenas para imagens; nos demais casos, é `''`. |
|
|
602
|
+
|
|
603
|
+
```vue
|
|
604
|
+
<TopFileUpload ref="upload" v-model="anexos" multiple>
|
|
605
|
+
<template #empty="{ choose, disabled }">
|
|
606
|
+
<button type="button" :disabled="disabled" @click="choose()">Anexar documentos</button>
|
|
607
|
+
</template>
|
|
608
|
+
<template #preview="{ file, url }">
|
|
609
|
+
<img v-if="url" :src="url" :alt="file.name">
|
|
610
|
+
<span v-else>{{ file.name }}</span>
|
|
611
|
+
</template>
|
|
612
|
+
</TopFileUpload>
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
`accept` aceita extensões (`.pdf`), MIME types (`application/pdf`) e curingas
|
|
616
|
+
MIME (`image/*`), separados por vírgula. `maxFileSize` é contado em bytes. Em
|
|
617
|
+
modo simples, a última seleção válida substitui a anterior; com `multiple`,
|
|
618
|
+
arquivos válidos são acumulados sem duplicar nome, tipo e tamanho.
|
|
619
|
+
|
|
620
|
+
## TopInputNumber
|
|
621
|
+
|
|
622
|
+
Campo numérico baseado no `InputNumber` do PrimeVue, com a mesma estrutura de
|
|
623
|
+
label, erro e acessibilidade dos demais campos. Por padrão usa `pt-BR`. No modo
|
|
624
|
+
`decimal`, o usuário informa explicitamente o separador decimal; no modo
|
|
625
|
+
`currency`, a máscara de centavos vem habilitada e transforma `12345` em
|
|
626
|
+
`R$ 123,45`. O `v-model` permanece sempre numérico (`number`) ou `null` quando
|
|
627
|
+
vazio.
|
|
187
628
|
|
|
188
629
|
```vue
|
|
189
630
|
<script setup lang="ts">
|
|
190
631
|
import { ref } from 'vue'
|
|
191
|
-
import {
|
|
632
|
+
import { TopInputNumber } from '@topjoao/top-design-system'
|
|
192
633
|
|
|
193
|
-
const
|
|
634
|
+
const quantidade = ref<number | null>(null)
|
|
635
|
+
const valorUnitario = ref<number | null>(null)
|
|
194
636
|
</script>
|
|
195
637
|
|
|
196
638
|
<template>
|
|
197
|
-
<
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
639
|
+
<TopInputNumber
|
|
640
|
+
v-model="quantidade"
|
|
641
|
+
label="Quantidade"
|
|
642
|
+
:min="1"
|
|
643
|
+
:min-fraction-digits="2"
|
|
644
|
+
:max-fraction-digits="4"
|
|
202
645
|
required
|
|
203
|
-
|
|
204
|
-
|
|
646
|
+
/>
|
|
647
|
+
|
|
648
|
+
<TopInputNumber
|
|
649
|
+
v-model="valorUnitario"
|
|
650
|
+
label="Valor unitário"
|
|
651
|
+
mode="currency"
|
|
652
|
+
currency="BRL"
|
|
653
|
+
:min-fraction-digits="2"
|
|
654
|
+
:max-fraction-digits="2"
|
|
205
655
|
/>
|
|
206
656
|
</template>
|
|
207
657
|
```
|
|
208
658
|
|
|
209
|
-
| Prop | Tipo | Padrão |
|
|
210
|
-
|
|
211
|
-
| `modelValue` | `
|
|
212
|
-
| `label` | `string` | `''` |
|
|
213
|
-
| `
|
|
214
|
-
| `
|
|
215
|
-
| `
|
|
216
|
-
| `disabled` | `boolean` | `false` |
|
|
217
|
-
| `
|
|
659
|
+
| Prop | Tipo | Padrão | Finalidade |
|
|
660
|
+
|---|---|---|---|
|
|
661
|
+
| `modelValue` | `number \| null` | `null` | Valor numérico controlado. |
|
|
662
|
+
| `label` / `placeholder` | `string` | `''` / `''` | Rótulo e texto auxiliar do campo. |
|
|
663
|
+
| `required` | `boolean` | `false` | Asterisco visual e atributo nativo obrigatório. |
|
|
664
|
+
| `error` | `string` | `''` | Mensagem e estado inválido. |
|
|
665
|
+
| `invalid` | `boolean` | `false` | Força estado inválido sem mostrar mensagem. |
|
|
666
|
+
| `disabled` / `readonly` | `boolean` | `false` / `false` | Remove interação / preserva leitura sem desabilitar. |
|
|
667
|
+
| `locale` | `string` | `'pt-BR'` | Locale para separadores e moeda. |
|
|
668
|
+
| `mode` | `'decimal' \| 'currency'` | `'decimal'` | Formatação decimal ou monetária. |
|
|
669
|
+
| `currency` / `currencyDisplay` | `string` / `'symbol' \| 'code' \| 'name'` | `undefined` / `'symbol'` | Código ISO 4217 e modo de exibição da moeda. |
|
|
670
|
+
| `currencyInputMode` | `'decimal' \| 'cents'` | `'cents'` | Controla a entrada monetária; `decimal` desliga a máscara mesmo quando `cents` é `true`. Não afeta `mode="decimal"`. |
|
|
671
|
+
| `cents` | `boolean` | `true` | Habilita a máscara automática somente em `mode="currency"`; `false` usa o `InputNumber` padrão. |
|
|
672
|
+
| `centsFractionDigits` | `number` | `undefined` (efetivo: `2`) | Primeira opção para definir as casas da máscara monetária. |
|
|
673
|
+
| `currencyFractionDigits` | `number` | `undefined` | Fallback de casas da máscara, usado depois de `centsFractionDigits`. |
|
|
674
|
+
| `useGrouping` / `format` | `boolean` | `true` / `true` | Separadores de milhar e formatação do valor. |
|
|
675
|
+
| `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`. |
|
|
676
|
+
| `min` / `max` / `step` | `number` | `undefined` / `undefined` / `1` | Limites e passo dos botões/teclado. |
|
|
677
|
+
| `showButtons` / `buttonLayout` | `boolean` / `'stacked' \| 'horizontal' \| 'vertical'` | `false` / `'stacked'` | Exibe e organiza os controles de incremento. |
|
|
678
|
+
| `allowEmpty` / `showClear` / `highlightOnFocus` | `boolean` | `true` / `false` / `false` | Permite limpar, mostra ícone de limpeza e seleciona valor ao focar. |
|
|
679
|
+
|
|
680
|
+
Eventos: `update:modelValue` (`number | null`), `input`, `focus` e `blur`. No
|
|
681
|
+
fluxo padrão do `InputNumber`, o componente também repassa `value-change`.
|
|
682
|
+
Atributos adicionais, como `name`, `autocomplete`, `aria-*` e `data-*`, são
|
|
683
|
+
repassados ao controle interno.
|
|
684
|
+
|
|
685
|
+
Quando a máscara de centavos não está ativa, os slots do `InputNumber` também
|
|
686
|
+
são repassados: `incrementbutton` e
|
|
687
|
+
`decrementbutton` recebem `{ listeners }`; `incrementicon` e `decrementicon`
|
|
688
|
+
substituem os ícones; `clearicon` recebe `{ clearCallback }`.
|
|
218
689
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
690
|
+
Para reproduzir a digitação monetária do TopLicita, a máscara de centavos já
|
|
691
|
+
vem ativa em `mode="currency"`. O usuário digita somente dígitos: `12345`
|
|
692
|
+
resulta em `R$ 123,45` e o `v-model` recebe `123.45`. Para exigir a vírgula
|
|
693
|
+
decimal digitada pelo usuário, passe `:cents="false"` ou
|
|
694
|
+
`currency-input-mode="decimal"`.
|
|
695
|
+
Como a máscara controla o texto enquanto o usuário digita, nesse modo os
|
|
696
|
+
botões incrementais, o ícone de limpeza e seus slots do `InputNumber` não são
|
|
697
|
+
renderizados.
|
|
222
698
|
|
|
223
|
-
|
|
699
|
+
```vue
|
|
700
|
+
<TopInputNumber
|
|
701
|
+
v-model="valorUnitario"
|
|
702
|
+
label="Valor unitário"
|
|
703
|
+
mode="currency"
|
|
704
|
+
currency="BRL"
|
|
705
|
+
/>
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
## TopInputText
|
|
709
|
+
|
|
710
|
+
Campo textual baseado no `InputText` do PrimeVue. O `v-model` é sempre
|
|
711
|
+
`string`, inclusive para códigos, documentos e identificadores compostos
|
|
712
|
+
somente por dígitos; por exemplo, `"001234"` preserva os zeros à esquerda.
|
|
713
|
+
|
|
714
|
+
```vue
|
|
715
|
+
<script setup lang="ts">
|
|
716
|
+
import { ref } from 'vue'
|
|
717
|
+
import { TopInputText } from '@topjoao/top-design-system'
|
|
718
|
+
|
|
719
|
+
const codigo = ref('001234')
|
|
720
|
+
</script>
|
|
721
|
+
|
|
722
|
+
<template>
|
|
723
|
+
<TopInputText
|
|
724
|
+
id="codigo"
|
|
725
|
+
v-model="codigo"
|
|
726
|
+
label="Código"
|
|
727
|
+
placeholder="Digite o código"
|
|
728
|
+
required
|
|
729
|
+
maxlength="10"
|
|
730
|
+
autocomplete="off"
|
|
731
|
+
/>
|
|
732
|
+
</template>
|
|
733
|
+
```
|
|
734
|
+
|
|
735
|
+
| Prop | Tipo | Padrão |
|
|
736
|
+
|---|---|---|
|
|
737
|
+
| `modelValue` | `string` | `''` |
|
|
738
|
+
| `label` | `string` | `''` |
|
|
739
|
+
| `placeholder` | `string` | `''` |
|
|
740
|
+
| `required` | `boolean` | `false` |
|
|
741
|
+
| `error` | `string` | `''` |
|
|
742
|
+
| `disabled` | `boolean` | `false` |
|
|
743
|
+
| `readonly` | `boolean` | `false` |
|
|
744
|
+
|
|
745
|
+
Atributos e eventos nativos adicionais, como `name`, `maxlength`,
|
|
746
|
+
`autocomplete`, `inputmode`, `pattern`, `aria-*`, `data-*`, `focus` e `blur`,
|
|
747
|
+
são repassados ao elemento `input` interno.
|
|
748
|
+
|
|
749
|
+
## TopSelect
|
|
224
750
|
|
|
225
751
|
Seletor pesquisável baseado no `AutoComplete` do PrimeVue. Ele é genérico: a
|
|
226
752
|
aplicação fornece os itens, executa a busca e decide qualquer apresentação de
|
|
@@ -260,33 +786,201 @@ function searchCustomers({ query }: { query: string }) {
|
|
|
260
786
|
</template>
|
|
261
787
|
```
|
|
262
788
|
|
|
263
|
-
| Prop | Tipo | Padrão |
|
|
264
|
-
|---|---|---|
|
|
265
|
-
| `
|
|
789
|
+
| Prop | Tipo | Padrão |
|
|
790
|
+
|---|---|---|
|
|
791
|
+
| `modelValue` | `SelectOption \| SelectOption[] \| null` | `null` |
|
|
792
|
+
| `options` | `array` | `[]` |
|
|
266
793
|
| `optionLabel` | `string \| function` | `'label'` |
|
|
267
794
|
| `optionKey` | `string` | `'id'` |
|
|
268
795
|
| `optionPrefix` | `string` | `''` |
|
|
269
796
|
| `showOptionPrefix` | `boolean` | `false` |
|
|
270
797
|
| `showSelectedPrefix` | `boolean` | `false` |
|
|
271
798
|
| `loading` / `disabled` / `invalid` | `boolean` | `false` |
|
|
272
|
-
| `placeholder` | `string` | `'
|
|
799
|
+
| `placeholder` | `string` | `'Pesquisar...'` |
|
|
273
800
|
| `minQueryLength` | `number` | `1` |
|
|
274
801
|
| `multiple` / `forceSelection` | `boolean` | `false` / `true` |
|
|
275
802
|
| `panelWidth` / `scrollHeight` | `string` | `null` / `'250px'` |
|
|
276
|
-
| `emptyMessage` / `loadingMessage` | `string` |
|
|
803
|
+
| `emptyMessage` / `loadingMessage` | `string` | `'Nenhum resultado encontrado.'` / `'Carregando...'` |
|
|
277
804
|
| `closeOnSelect` | `boolean` | `false` |
|
|
278
805
|
|
|
279
806
|
Eventos: `update:modelValue`, `search`, `loadMore`, `clear`, `select` e
|
|
280
807
|
`change`.
|
|
281
808
|
|
|
282
|
-
Slots: `icon`, `option`, `selected-item`, `chip`, `empty`, `option-group` e
|
|
283
|
-
`footer`. O slot `icon` recebe `loading`; sem ele, o componente mostra uma lupa
|
|
284
|
-
ou um indicador de carregamento. Quando um slot não é informado, o componente usa sua apresentação padrão.
|
|
285
|
-
O texto das opções é limitado visualmente pela largura disponível do painel,
|
|
286
|
-
sem corte por quantidade fixa de caracteres; o tooltip padrão exibe o valor
|
|
287
|
-
completo quando `showTooltip` está ativo.
|
|
809
|
+
Slots: `icon`, `option`, `selected-item`, `chip`, `empty`, `option-group` e
|
|
810
|
+
`footer`. O slot `icon` recebe `loading`; sem ele, o componente mostra uma lupa
|
|
811
|
+
ou um indicador de carregamento. Quando um slot não é informado, o componente usa sua apresentação padrão.
|
|
812
|
+
O texto das opções é limitado visualmente pela largura disponível do painel,
|
|
813
|
+
sem corte por quantidade fixa de caracteres; o tooltip padrão exibe o valor
|
|
814
|
+
completo quando `showTooltip` está ativo.
|
|
815
|
+
|
|
816
|
+
| Slot | Parâmetros recebidos | Uso |
|
|
817
|
+
|---|---|---|
|
|
818
|
+
| `icon` | `{ loading }` | Ícone à esquerda do campo. |
|
|
819
|
+
| `option` | Props nativas, mais `{ option, label, prefix, query }` | Linha de uma opção. |
|
|
820
|
+
| `selected-item` | Props nativas, incluindo `item` | Valor único escolhido. |
|
|
821
|
+
| `chip` | Props nativas, incluindo `value` e `removeCallback` | Tag no modo múltiplo. |
|
|
822
|
+
| `empty` | — | Conteúdo quando não há opções; também substitui o loading padrão. |
|
|
823
|
+
| `option-group` | Props nativas, incluindo `option` | Cabeçalho de um grupo. |
|
|
824
|
+
| `footer` | Props nativas do AutoComplete | Rodapé do painel. |
|
|
825
|
+
|
|
826
|
+
`search` recebe `{ originalEvent, query }` a cada consulta; atualize `options`
|
|
827
|
+
com os resultados. `loadMore` repassa o evento do virtual scroller para busca
|
|
828
|
+
paginar. Pela ref, `hideDropdown()` fecha o painel.
|
|
829
|
+
|
|
830
|
+
## TopTabs
|
|
831
|
+
|
|
832
|
+
Navegação em abas baseada em `Tabs`, `TabList`, `Tab`, `TabPanels` e `TabPanel`
|
|
833
|
+
do PrimeVue, com estrutura simplificada e estilos dos temas claro e escuro do
|
|
834
|
+
Design System.
|
|
288
835
|
|
|
289
|
-
|
|
836
|
+
```vue
|
|
837
|
+
<script setup lang="ts">
|
|
838
|
+
import { ref } from 'vue'
|
|
839
|
+
import {
|
|
840
|
+
TopTabs,
|
|
841
|
+
type TopTabItem,
|
|
842
|
+
type TopTabValue,
|
|
843
|
+
} from '@topjoao/top-design-system'
|
|
844
|
+
|
|
845
|
+
const activeTab = ref<TopTabValue>('dados')
|
|
846
|
+
const tabs: TopTabItem[] = [
|
|
847
|
+
{ value: 'dados', label: 'Dados' },
|
|
848
|
+
{ value: 'documentos', label: 'Documentos' },
|
|
849
|
+
{ value: 'auditoria', label: 'Auditoria', disabled: true },
|
|
850
|
+
]
|
|
851
|
+
</script>
|
|
852
|
+
|
|
853
|
+
<template>
|
|
854
|
+
<TopTabs v-model="activeTab" :tabs="tabs">
|
|
855
|
+
<template #dados>
|
|
856
|
+
Dados gerais do processo
|
|
857
|
+
</template>
|
|
858
|
+
|
|
859
|
+
<template #documentos>
|
|
860
|
+
Documentos anexados
|
|
861
|
+
</template>
|
|
862
|
+
|
|
863
|
+
<template #auditoria>
|
|
864
|
+
Histórico de auditoria
|
|
865
|
+
</template>
|
|
866
|
+
</TopTabs>
|
|
867
|
+
</template>
|
|
868
|
+
```
|
|
869
|
+
|
|
870
|
+
| Prop | Tipo | Padrão |
|
|
871
|
+
|---|---|---|
|
|
872
|
+
| `modelValue` | `string \| number` | obrigatório |
|
|
873
|
+
| `tabs` | `TopTabItem[]` | obrigatório |
|
|
874
|
+
| `lazy` | `boolean` | `false` |
|
|
875
|
+
| `scrollable` | `boolean` | `true` |
|
|
876
|
+
|
|
877
|
+
Cada `TopTabItem` possui `value`, `label` e `disabled?`. O `value` deve ser
|
|
878
|
+
único e identifica tanto a seleção quanto o slot do painel; por exemplo,
|
|
879
|
+
`value: 'documentos'` utiliza `#documentos`. Cada slot recebe `tab` e `active`.
|
|
880
|
+
O componente emite somente `update:modelValue`. Atributos adicionais, incluindo
|
|
881
|
+
as opções de passthrough do PrimeVue, são repassados ao componente `Tabs`.
|
|
882
|
+
|
|
883
|
+
## TopToast
|
|
884
|
+
|
|
885
|
+
`TopToast` personaliza o renderizador do serviço `Toast` do PrimeVue. Registre
|
|
886
|
+
`ToastService` uma vez, renderize um único `TopToast` perto da raiz e dispare
|
|
887
|
+
mensagens com `useToast`. Ele não recebe uma lista de mensagens por prop.
|
|
888
|
+
|
|
889
|
+
```ts
|
|
890
|
+
// main.ts
|
|
891
|
+
import PrimeVue from 'primevue/config'
|
|
892
|
+
import ToastService from 'primevue/toastservice'
|
|
893
|
+
import { createApp } from 'vue'
|
|
894
|
+
import App from './App.vue'
|
|
895
|
+
|
|
896
|
+
createApp(App).use(PrimeVue).use(ToastService).mount('#app')
|
|
897
|
+
```
|
|
898
|
+
|
|
899
|
+
```vue
|
|
900
|
+
<script setup lang="ts">
|
|
901
|
+
import { useToast } from 'primevue/usetoast'
|
|
902
|
+
import { TopButton, TopToast } from '@topjoao/top-design-system'
|
|
903
|
+
|
|
904
|
+
const toast = useToast()
|
|
905
|
+
const abrirCadastro = () => { /* navegue para o cadastro */ }
|
|
906
|
+
|
|
907
|
+
function salvar() {
|
|
908
|
+
toast.add({
|
|
909
|
+
severity: 'success', summary: 'Cadastro concluído', detail: 'As alterações foram salvas.', life: 5000,
|
|
910
|
+
data: {
|
|
911
|
+
footer: 'Protocolo: CAD-2026-0042',
|
|
912
|
+
action: { label: 'Ver cadastro', icon: 'pi pi-arrow-right', onClick: () => abrirCadastro() },
|
|
913
|
+
},
|
|
914
|
+
})
|
|
915
|
+
}
|
|
916
|
+
</script>
|
|
917
|
+
|
|
918
|
+
<template>
|
|
919
|
+
<TopToast :base-z-index="30000" />
|
|
920
|
+
<TopButton label="Salvar" @click="salvar" />
|
|
921
|
+
</template>
|
|
922
|
+
```
|
|
923
|
+
|
|
924
|
+
| Prop | Tipo | Padrão | Finalidade |
|
|
925
|
+
|---|---|---|---|
|
|
926
|
+
| `baseZIndex` | `number` | `30000` | Camada base das notificações. |
|
|
927
|
+
|
|
928
|
+
Além das opções usuais de `ToastMessageOptions` do PrimeVue (`severity`,
|
|
929
|
+
`summary`, `detail`, `life`, `closable` etc.), `data` aceita `TopToastData`:
|
|
930
|
+
|
|
931
|
+
| Campo | Tipo | Efeito |
|
|
932
|
+
|---|---|---|
|
|
933
|
+
| `data.footer` | `string \| number` | Texto discreto abaixo da mensagem. |
|
|
934
|
+
| `data.action.label` | `string` | Rótulo da ação. |
|
|
935
|
+
| `data.action.icon` | `string` opcional | Classe de ícone PrimeIcons. |
|
|
936
|
+
| `data.action.onClick` | `() => void` opcional | Função chamada ao clicar na ação. |
|
|
937
|
+
|
|
938
|
+
| Slot | Parâmetros recebidos | Uso |
|
|
939
|
+
|---|---|---|
|
|
940
|
+
| `action` | `{ action, message, run }` | Substitui o botão; execute `run()` para chamar `action.onClick`. |
|
|
941
|
+
| `footer` | `{ message, footer }` | Substitui o rodapé. |
|
|
942
|
+
|
|
943
|
+
## Tipos e exports públicos
|
|
944
|
+
|
|
945
|
+
O pacote raiz exporta todos os componentes, `TopSolutionsPreset`, `colors` e
|
|
946
|
+
os tipos abaixo. Use `import type` para não acrescentar código ao bundle.
|
|
947
|
+
|
|
948
|
+
```ts
|
|
949
|
+
import {
|
|
950
|
+
colors,
|
|
951
|
+
TopSolutionsPreset,
|
|
952
|
+
type TopButtonSeverity,
|
|
953
|
+
type TopDatePickerSelectionMode,
|
|
954
|
+
type TopDatePickerValue,
|
|
955
|
+
type TopFileUploadError,
|
|
956
|
+
type TopFileUploadValue,
|
|
957
|
+
type TopInputNumberValue,
|
|
958
|
+
type TopInputNumberMode,
|
|
959
|
+
type TopInputNumberButtonLayout,
|
|
960
|
+
type TopInputNumberCurrencyInputMode,
|
|
961
|
+
type TopNavItem,
|
|
962
|
+
type TopNavSection,
|
|
963
|
+
type TopTabItem,
|
|
964
|
+
type TopToastData,
|
|
965
|
+
} from '@topjoao/top-design-system'
|
|
966
|
+
```
|
|
967
|
+
|
|
968
|
+
`TopNavItem` descreve um nó (`id`, `label`, `to?`, `icon?`, `disabled?`,
|
|
969
|
+
`children?`, `data?`); `TopNavSection` é o mesmo contrato com `children`
|
|
970
|
+
obrigatório. `TopNavAction`, `TopNavUser`, `TopNavClient` e
|
|
971
|
+
`TopNavUserMenuItem` correspondem às props de mesmo nome. A aparência da barra
|
|
972
|
+
é definida por `TopNavBarAppearance` e seus subtipos exportados:
|
|
973
|
+
`TopNavBarColors`, `TopNavBarSurfaces`, `TopNavBarBorders`, `TopNavBarShape` e
|
|
974
|
+
`TopNavBarFocus`.
|
|
975
|
+
|
|
976
|
+
`TopInputNumberValue`, `TopInputNumberMode`, `TopInputNumberButtonLayout` e
|
|
977
|
+
`TopInputNumberCurrencyInputMode`
|
|
978
|
+
tipam, respectivamente, o valor, o modo de formatação, o layout dos botões e o
|
|
979
|
+
modo de entrada monetária do campo numérico. `colors` expõe as escalas
|
|
980
|
+
imutáveis `primary`, `secondary`, `success`, `warn` e
|
|
981
|
+
`danger`, cada uma com tons de `50` a `950`.
|
|
982
|
+
|
|
983
|
+
## Desenvolvimento da biblioteca
|
|
290
984
|
|
|
291
985
|
```bash
|
|
292
986
|
npm install
|
|
@@ -311,10 +1005,10 @@ publicado.
|
|
|
311
1005
|
npm run storybook
|
|
312
1006
|
```
|
|
313
1007
|
|
|
314
|
-
Abra `http://localhost:6006` para acessar as histórias de `TopButton`,
|
|
315
|
-
`TopConfirmDialog`, `TopInputText` e `
|
|
316
|
-
barra superior para alternar o preview entre tema claro e escuro.
|
|
317
|
-
versão estática da documentação, execute:
|
|
1008
|
+
Abra `http://localhost:6006` para acessar as histórias de `TopButton`,
|
|
1009
|
+
`TopConfirmDialog`, `TopDatePicker`, `TopInputText`, `TopInputNumber`, `TopSelect` e `TopTabs`. Use o botão de
|
|
1010
|
+
contraste na barra superior para alternar o preview entre tema claro e escuro.
|
|
1011
|
+
Para gerar a versão estática da documentação, execute:
|
|
318
1012
|
|
|
319
1013
|
```bash
|
|
320
1014
|
npm run build-storybook
|
|
@@ -326,10 +1020,14 @@ Para gerar um pacote local instalável:
|
|
|
326
1020
|
npm pack
|
|
327
1021
|
```
|
|
328
1022
|
|
|
329
|
-
Para publicar uma nova versão
|
|
330
|
-
publicadas no npm não podem ser
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
npm
|
|
335
|
-
|
|
1023
|
+
Para publicar uma nova versão estável, primeiro incremente a versão seguindo o
|
|
1024
|
+
versionamento semântico; versões já publicadas no npm não podem ser
|
|
1025
|
+
sobrescritas. Use `patch`, `minor` ou `major` conforme o impacto da mudança.
|
|
1026
|
+
|
|
1027
|
+
```bash
|
|
1028
|
+
npm version patch --no-git-tag-version
|
|
1029
|
+
npm publish --access public --tag latest
|
|
1030
|
+
```
|
|
1031
|
+
|
|
1032
|
+
A tag `latest` é a padrão do npm. Assim, consumidores instalam a versão estável
|
|
1033
|
+
simplesmente com `npm install @topjoao/top-design-system`.
|