@topjoao/top-design-system 0.1.0-beta.17 → 0.1.0-beta.18

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
@@ -111,18 +111,26 @@ entrada `/plugin` também fornece as declarações globais usadas pela IDE.
111
111
 
112
112
  ## TopNavBar
113
113
 
114
- Barra de navegação corporativa com breadcrumbs, menu hierárquico, busca e
115
- ações opcionais. A aplicação consumidora fornece os dados do menu, define a
116
- página ativa e decide o que acontece em cada evento.
114
+ Barra de navegação responsiva inspirada no AppSidebar do TopLicita. O
115
+ componente fornece apenas layout e interação: a aplicação consumidora continua
116
+ responsável por rotas, permissões, sessão, cliente/órgão, busca remota,
117
+ favoritos, Aia, suporte e integrações. Nenhuma dessas ações é executada pela
118
+ biblioteca; todas são comunicadas por eventos.
117
119
 
118
120
  ```vue
119
121
  <script setup lang="ts">
120
122
  import { ref } from 'vue'
121
- import { TopNavBar, type TopNavItem } from '@topjoao/top-design-system'
123
+ import {
124
+ TopNavBar,
125
+ type TopNavAction,
126
+ type TopNavItem,
127
+ type TopNavSection,
128
+ } from '@topjoao/top-design-system'
122
129
 
123
130
  const clienteAtual = ref('prefeitura-a')
131
+ const favorito = ref(false)
124
132
 
125
- const secoes = [
133
+ const secoes: TopNavSection[] = [
126
134
  {
127
135
  id: 'planejamento',
128
136
  label: 'Planejamento',
@@ -140,15 +148,12 @@ const secoes = [
140
148
  ]
141
149
 
142
150
  function navegar(item: TopNavItem) {
143
- // Ex.: router.push(item.to)
151
+ if (item.to) router.push(item.to)
144
152
  }
145
153
 
146
- function buscarNoMenu(query: string) {
147
- // Filtre ou consulte os itens permitidos para este usuário.
154
+ function executarIntegracao(action: TopNavAction) {
155
+ // Abra a integração identificada por action.id.
148
156
  }
149
-
150
- function alternarAssistente() {}
151
- function abrirSuporte() {}
152
157
  </script>
153
158
 
154
159
  <template>
@@ -158,50 +163,173 @@ function abrirSuporte() {}
158
163
  searchable
159
164
  show-aia
160
165
  show-support
166
+ show-favorite-toggle
167
+ :favorite-active="favorito"
168
+ :actions="[
169
+ { id: 'integracoes', label: 'Integrações', icon: 'pi pi-th-large' },
170
+ ]"
171
+ :user="{ name: 'João Silva', subtitle: 'Administrador', initials: 'JS' }"
172
+ :user-menu-items="[
173
+ { id: 'perfil', label: 'Meu perfil', icon: 'pi pi-user' },
174
+ { id: 'sair', label: 'Sair', icon: 'pi pi-sign-out' },
175
+ ]"
161
176
  @navigate="navegar"
162
- @search="buscarNoMenu"
163
- @toggle-aia="alternarAssistente"
164
- @open-support="abrirSuporte"
177
+ @search="consultarMenusPermitidos"
178
+ @toggle-aia="alternarAia"
179
+ @open-support="abrirCentralSuporte"
180
+ @toggle-favorite="favorito = !favorito"
181
+ @action="executarIntegracao"
182
+ @user-action="executarAcaoDaSessao"
165
183
  >
166
- <template #brand>
184
+ <template #brand="{ compact }">
167
185
  <img src="/logo.svg" alt="Minha organização">
186
+ <span v-if="!compact">Sistema de Contratações</span>
168
187
  </template>
169
188
 
170
- <template #context>
189
+ <template #context="{ compact }">
171
190
  <select v-model="clienteAtual" aria-label="Cliente atual">
172
191
  <option value="prefeitura-a">Prefeitura A</option>
173
192
  <option value="prefeitura-b">Prefeitura B</option>
174
193
  </select>
194
+ <span v-if="!compact">Poder Executivo</span>
175
195
  </template>
176
196
  </TopNavBar>
177
197
  </template>
178
198
  ```
179
199
 
180
- `activeItemId` gera automaticamente o breadcrumb da página ativa, incluindo os
181
- ancestrais e dropdowns de cada nível. Por exemplo, um item `calendario` dentro
182
- de `Programação` em `Planejamento` resulta em `Início / Navegação /
183
- Planejamento / Programação / Calendário`.
200
+ ### Menu e breadcrumbs
201
+
202
+ `sections` aceita uma árvore de profundidade arbitrária. Cada nó usa
203
+ `TopNavItem` (`id`, `label`, `to?`, `icon?`, `disabled?`, `children?`, `data?`).
204
+ Seções sem filhos são removidas e um `children: []` nunca cria um painel vazio.
205
+ No desktop, a primeira coluna do painel mestre–detalhe tem `16rem`; os itens de
206
+ cada nível são repartidos em colunas de `18rem`, no máximo dez por coluna.
207
+ Subníveis aparecem sempre à direita do nível de origem.
208
+
209
+ Breadcrumbs estão habilitados por padrão e começam por `Início / Navegação`.
210
+ Há duas formas de fornecer a trilha:
211
+
212
+ - informe `breadcrumbs` com itens `TopNavBreadcrumb`; `sectionId` liga o item a
213
+ uma seção e `menuId` liga a qualquer nó com filhos;
214
+ - omita `breadcrumbs` e informe `activeItemId`; a trilha é derivada da árvore.
215
+
216
+ Por exemplo, `calendario` dentro de `Programação` em `Planejamento` gera
217
+ `Início / Navegação / Planejamento / Programação / Calendário`. A rota ativa
218
+ não recebe fundo permanente nos menus desktop; somente hover e o ramo que está
219
+ sendo explorado recebem destaque.
220
+
221
+ ### Props
222
+
223
+ | Prop | Tipo / padrão | Finalidade |
224
+ |---|---|---|
225
+ | `sections` | `TopNavSection[]` / `[]` | Árvore de navegação já filtrada pela aplicação. |
226
+ | `breadcrumbs` | `TopNavBreadcrumb[]` / `[]` | Trilha explícita; vazia permite derivação por `activeItemId`. |
227
+ | `homeItem` | `TopNavItem` / `Início` | Item inicial emitido ao clicar em Início. |
228
+ | `navigationLabel` | `string` / `Navegação` | Rótulo do menu mestre. |
229
+ | `activeItemId` | `string` | Nó atual, usado no breadcrumb e no Drawer. |
230
+ | `searchable` | `boolean` / `false` | Habilita busca desktop e busca própria do Drawer. |
231
+ | `searchValue` | `string` | Valor opcionalmente controlado com `v-model:search-value`. |
232
+ | `searchResults` | `TopNavItem[]` | Resultados controlados; sem a prop, a árvore é filtrada localmente. |
233
+ | `searchPlaceholder` | `string` | Placeholder das duas buscas. |
234
+ | `showAia`, `showSupport` | `boolean` / `false` | Exibem as ações opcionais. |
235
+ | `aiaActive` | `boolean` / `false` | Estado visual do botão Aia. |
236
+ | `aiaLabel`, `supportLabel` | `string` | Textos acessíveis e rótulos do Drawer. |
237
+ | `actions` | `TopNavAction[]` / `[]` | Ações genéricas, como integrações, emitidas por `action`. |
238
+ | `user` | `TopNavUser` | Dados exclusivamente visuais do usuário. |
239
+ | `userMenuItems` | `TopNavUserMenuItem[]` | Opções emitidas por `user-action`; suporta separadores. |
240
+ | `favoriteItems` | `TopNavItem[]` / `[]` | Favoritos fornecidos pelo pai para dropdown e Drawer. |
241
+ | `showFavoriteToggle` | `boolean` / `false` | Exibe a estrela da página atual. |
242
+ | `favoriteActive` | `boolean` / `false` | Estado visual da estrela atual. |
243
+ | `mobileOpen` | `boolean` | Controle opcional com `v-model:mobile-open`. |
244
+ | `appearance` | `TopNavBarAppearance` | Tokens visuais locais descritos abaixo. |
245
+
246
+ ### Eventos
247
+
248
+ | Evento | Payload | Quando ocorre |
249
+ |---|---|---|
250
+ | `navigate` | `TopNavItem` | Início, menu, resultado ou favorito é selecionado. |
251
+ | `search` | `string` | A consulta muda no desktop ou no Drawer. |
252
+ | `update:searchValue` | `string` | Atualização de `v-model:search-value`. |
253
+ | `update:mobileOpen` | `boolean` | Atualização de `v-model:mobile-open`. |
254
+ | `toggle-aia` | — | A ação Aia é acionada. |
255
+ | `open-support` | — | A ação de suporte é acionada. |
256
+ | `toggle-favorite` | — | A estrela da página atual é acionada. |
257
+ | `action` | `TopNavAction` | Uma ação genérica/integração é acionada. |
258
+ | `user-action` | `TopNavUserMenuItem` | Uma opção de usuário é selecionada. |
259
+ | `user-click` | `TopNavUser \| undefined` | A área de usuário sem menu é acionada. |
184
260
 
185
- Para personalizar a aparência, use nomes orientados ao que é exibido: `textColor`
186
- para textos e ícones principais, `mutedTextColor` para detalhes secundários,
187
- `menuTextColor` para o conteúdo dos dropdowns, além de `headerBackground`,
188
- `breadcrumbBackground`, `menuBackground`, `accentColor`, `borderColor`, `radius`
189
- e `height`.
261
+ `Ctrl+K` e `Cmd+K` abrem/focam a busca. Em telas menores que `1024px`, o
262
+ atalho abre primeiro o Drawer e foca a busca móvel. `Escape` fecha os painéis.
263
+
264
+ ### Slots
190
265
 
191
266
  | Slot | Uso |
192
267
  |---|---|
193
- | `brand` | Marca, logo ou nome do sistema. |
194
- | `context` | Contexto de operação: cliente, órgão, ambiente, exercício ou escopo. |
195
- | `actions` | Ações adicionais à direita da barra. |
196
- | `user-menu` | Conteúdo adicional ou substituto para a área de usuário. |
197
- | `search-results` | Apresentação personalizada dos resultados da busca. |
198
- | `breadcrumb-actions` | Ações junto à página atual, como favoritos. |
199
- | `mobile-footer` | Conteúdo adicional no menu mobile. |
200
-
201
- Eventos: `navigate`, `search`, `toggle-aia`, `open-support`,
202
- `toggle-favorite` e `user-action`. A barra não navega, persiste estado ou chama
203
- serviços por conta própria. Quando `searchable` está ativo, `Ctrl+K` (ou `⌘K`
204
- no macOS) move o foco para a pesquisa; `Escape` fecha o painel de busca.
268
+ | `brand` | Marca; recebe `{ compact }`. |
269
+ | `context`, `scope` ou `client` | Contexto operacional; aliases com prioridade nessa ordem e `{ compact }`. |
270
+ | `context-compact` | Variante explícita usada no último estágio de overflow. |
271
+ | `actions` | Conteúdo adicional do cabeçalho; recebe `{ compact, close }`. |
272
+ | `aia-icon`, `support-icon` | Ícones customizados das ações quadradas. |
273
+ | `user` | Conteúdo do gatilho de usuário; recebe `{ user, compact }`. |
274
+ | `user-menu` | Painel de usuário; recebe `{ items, select }`. |
275
+ | `search-results` | Resultados customizados; recebe `{ items, select }`. |
276
+ | `breadcrumb-actions` | Ações adicionais no fim da segunda faixa. |
277
+ | `drawer-header` | Cabeçalho inteiro; recebe `{ close }`. |
278
+ | `drawer-brand` | Marca do Drawer; por padrão reutiliza `brand`. |
279
+ | `drawer-search` | Busca inteira; recebe `{ query, update, clear }`. |
280
+ | `drawer-actions` | Ações; recebe `{ actions, select, close }`. |
281
+ | `drawer-before-menu`, `drawer-after-menu` | Conteúdo antes/depois do trilho rolável. |
282
+ | `drawer-menu` | Substitui a árvore; recebe `{ sections, select, close }`. |
283
+ | `drawer-user` | Rodapé de usuário; recebe `{ user, open, toggle }`. |
284
+ | `drawer-footer` | Conteúdo final adicional; recebe `{ close }`. |
285
+
286
+ ### Aparência e responsividade
287
+
288
+ `appearance` aceita `headerBackground`, `breadcrumbBackground`,
289
+ `drawerBackground`, `drawerFooterBackground`, `textColor`, `mutedTextColor`,
290
+ `accentColor`, `menuBackground`, `menuTextColor`, `menuHoverBackground`,
291
+ `menuExploredBackground`, `borderColor`, `menuBorderColor` (a borda externa de
292
+ 6px), `menuOutlineColor`, `radius`, `drawerRadius`, `headerHeight` (`height` é
293
+ mantido como alias), `drawerWidth`, `shadow`, `fontFamily`, `fontSize`,
294
+ `secondaryFontSize`, `captionFontSize`, `lineHeight`, `fontWeight`,
295
+ `strongFontWeight`, `actionSize`, `headerPadding`, `mobileHeaderPadding`,
296
+ `breadcrumbPadding`, `mobileBreadcrumbPadding`, `menuItemPadding`,
297
+ `itemLineHeight`, `sectionWidth`, `columnWidth` e `contextCompactWidth`.
298
+
299
+ A biblioteca não fixa tipografia inline. Por padrão, família, tamanho, peso e
300
+ altura de linha são herdados da aplicação consumidora. Além disso, `appearance`
301
+ só cria variáveis inline para propriedades que foram realmente informadas; os
302
+ valores fiéis ao AppSidebar existem apenas como *fallbacks* no CSS. Assim, um
303
+ tema global pode controlar o componente sem precisar usar `!important`:
304
+
305
+ ```css
306
+ :root {
307
+ --top-nav-font-family: var(--app-font-family);
308
+ --top-nav-font-size: var(--app-font-size);
309
+ --top-nav-strong-font-weight: 600;
310
+ --top-nav-action-size: 2.5rem;
311
+ --top-nav-header-padding: 0.625rem 1.5rem;
312
+ --top-nav-menu-item-padding: 0.5rem 0.75rem;
313
+ --top-nav-section-width: 16rem;
314
+ --top-nav-column-width: 18rem;
315
+ }
316
+ ```
317
+
318
+ As variáveis globais também alcançam o Drawer teleportado. Um valor passado por
319
+ `appearance` tem precedência local e não altera os demais tokens do tema.
320
+
321
+ O breakpoint móvel é `1024px`. No desktop, um `ResizeObserver` reaplica a mesma
322
+ sequência progressiva do AppSidebar: ações colapsam abaixo de `1440px`, busca
323
+ vira ícone abaixo de `1320px`, nome do usuário some abaixo de `1180px` e, se o
324
+ conteúdo ainda transbordar, o contexto recebe `compact: true`. O último estágio
325
+ também limita o contêiner do contexto a `3.25rem`; use `context-compact` quando
326
+ quiser controlar exatamente o que permanece visível.
327
+
328
+ Abaixo de `1024px`, a navegação desktop desaparece e o Drawer do PrimeVue assume.
329
+ Ele mantém cabeçalho, busca, ações, trilho translúcido rolável, árvore recursiva,
330
+ favoritos e usuário. A transição `menu-expand` existe somente dentro do Drawer;
331
+ os dropdowns desktop abrem sem animação e suas áreas de hover incluem o espaço
332
+ entre gatilho e painel.
205
333
 
206
334
  ## TopButton
207
335