@praxisui/table 9.0.5-rc.13 → 9.0.5-rc.14

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
@@ -249,27 +249,32 @@ const config: TableConfig = {
249
249
  `PraxisTableToolbar` materializes the toolbar as semantic regions rather than one wrapping row:
250
250
 
251
251
  - **identity** — title, subtitle and table context;
252
- - **query** — quick filters, always-visible dynamic filters and projected query shortcuts;
252
+ - **scope** — a small, mutually exclusive and removable set of governed quick filters;
253
+ - **query** — always-visible dynamic filters and projected query shortcuts;
253
254
  - **commands** — collection/business actions, table utilities and authoring entrypoints.
254
255
 
255
256
  The runtime owns the responsive composition through container queries. This is important when a table
256
257
  is rendered inside a drawer, split pane or dashboard card: behavior follows the width actually available
257
- to the table, not only the browser viewport. At wide widths, identity and commands share the first band
258
- and query controls use a stable second band. At compact widths, the regions move as complete units and
258
+ to the table, not only the browser viewport. At wide widths, identity and commands share the first band,
259
+ while scope and query share a stable second band. At compact widths, the regions move as complete units and
259
260
  commands are consolidated under one localized `Mais ações` entrypoint without losing export, column or
260
- density controls.
261
+ density controls. At narrow widths the first band preserves identity and commands before the scope and
262
+ query bands, so keyboard focus follows the same reading order presented visually.
261
263
 
262
264
  Authoring guidance:
263
265
 
264
266
  - use `toolbar.filters.quickFilters` for a small governed scope switch, not as a substitute for every filter;
267
+ one quick filter can be active at a time, and activating the current item again restores the previous criteria;
265
268
  - use `advancedFilters.settings.alwaysVisibleFields` for frequent editable criteria;
266
269
  - keep one clear collection/business action primary; export, columns and density are utilities;
267
270
  - project custom shortcuts through the toolbar slots, but do not target internal layout classes from the host;
268
271
  - validate the component container at `1440`, `1024`, `768`, `480` and `320` px, including long localized labels, zoom and keyboard focus.
269
272
 
270
- Adding filters or actions never requires a host breakpoint. When the command set grows, the compact menu
271
- preserves capability parity and keyboard order while the query region remains independently scroll-free at
272
- the page level.
273
+ Adding supported filters or actions never requires a host breakpoint. When the command set grows, the compact
274
+ menu preserves capability parity and keyboard order. Projected query shortcuts are grouped by the runtime,
275
+ receive a bounded width budget and wrap as one semantic cluster; projected controls must remain intrinsically
276
+ shrinkable and must not declare a fixed minimum width larger than their slot. Hosts must not rely on internal
277
+ selectors to position them. The query region remains independently scroll-free at the page level.
273
278
 
274
279
  The existing `toolbar.layout` fields are materialized by the same runtime: `alignment` aligns the identity
275
280
  and command regions, `padding` and `backgroundColor` project governed chrome, `height` defines the minimum
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-08-13T17:03:40.689Z",
3
+ "generatedAt": "2026-08-13T20:07:32.063Z",
4
4
  "packageName": "@praxisui/table",
5
- "packageVersion": "9.0.5-rc.13",
5
+ "packageVersion": "9.0.5-rc.14",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 3,
@@ -16036,6 +16036,7 @@
16036
16036
  "description": "Configuração de toolbar.filters.* e quickFilters.",
16037
16037
  "rules": [
16038
16038
  "quickFilters[].filter deve seguir a estrutura do filtro suportado.",
16039
+ "quickFilters representa um pequeno seletor de escopo exclusivo e removível; use filtros avançados para critérios combináveis.",
16039
16040
  "enabled depende de behavior.filtering.enabled."
16040
16041
  ],
16041
16042
  "examples": [
@@ -30775,9 +30776,9 @@
30775
30776
  {
30776
30777
  "chunkIndex": 144,
30777
30778
  "chunkKind": "context_pack",
30778
- "content": "{\"componentId\":\"praxis-table\",\"chunkSection\":\"aiConcepts\",\"aiConcepts\":{\"behavior-expansion\":{\"id\":\"behavior-expansion\",\"title\":\"Expansion (Behavior)\",\"description\":\"Configuração de behavior.expansion.* para detail rows schema-driven.\",\"rules\":[\"detail é sempre schema-driven; varie source.mode (inline/resource/resourcePath), não detail.type.\",\"detail.schemaContract.kind/version deve ser informado para validação e migração.\",\"Em virtualização, prefira detail.height.mode=fixed com virtualization.policy=fixed-height-only.\",\"Use eventExposureDefault hashed/redacted por padrão em ambiente corporativo.\"],\"examples\":[\"{ behavior: { expansion: { enabled: true, state: { mode: \\\"controlled\\\" }, detail: { schemaContract: { kind: \\\"praxis.detail.schema\\\", version: \\\"1.0.0\\\" }, source: { mode: \\\"resource\\\", resource: { kind: \\\"ui-composition\\\", id: \\\"customer-detail-v2\\\", version: \\\"2.1.0\\\" } }, rendering: { strategy: \\\"registry\\\", registryId: \\\"praxis.detail.default\\\" } } } } }\"],\"antiPatterns\":[\"{ behavior: { expansion: { detail: { type: \\\"template\\\", templateId: \\\"legacy-id\\\" } } } }\"]},\"appearance\":{\"id\":\"appearance\",\"title\":\"Aparência e Layout\",\"description\":\"Densidade, bordas, cores, tipografia, espaçamento e responsividade.\",\"rules\":[\"appearance.density deve usar valores compact/comfortable/spacious.\",\"Cores devem usar tokens do tema ou hex válido.\",\"responsive.mobile.cardMode deve ser combinado com colunas prioritárias.\",\"Se animations.enabled for true, respeite reduceMotion.\",\"appearance.animations.specific.row e appearance.animations.specific.cell controlam animações condicionais por escopo.\"],\"examples\":[\"{ appearance: { density: \\\"compact\\\", borders: { showRowBorders: true } } }\",\"{ appearance: { typography: { fontSize: \\\"14px\\\" }, spacing: { cellPadding: \\\"8px 16px\\\" } } }\"],\"antiPatterns\":[\"{ appearance: { density: \\\"tiny\\\" } }\"]},\"appearance-details\":{\"id\":\"appearance-details\",\"title\":\"Detalhes de Aparência\",\"description\":\"Bordas, cores, tipografia, spacing, elevation e responsive autoAdjust.\",\"rules\":[\"borders.style deve ser solid/dashed/dotted quando aplicável.\",\"typography.headerFontWeight deve ser string numerica ou token.\",\"responsive.autoAdjust controla ajustes automáticos em telas menores.\"],\"examples\":[\"{ appearance: { borders: { showOuterBorder: true, style: \\\"solid\\\" }, colors: { alternateRowBackground: \\\"#f7f9fc\\\" } } }\",\"{ appearance: { responsive: { mobile: { cardMode: true, priorityColumns: [\\\"name\\\", \\\"status\\\"] } } } }\"],\"antiPatterns\":[\"{ appearance: { borders: { style: \\\"double\\\" } } }\"]},\"toolbar\":{\"id\":\"toolbar\",\"title\":\"Toolbar\",\"description\":\"Configurações gerais da toolbar.\",\"rules\":[\"toolbar.visible controla exibição global da barra.\",\"Use toolbar.layout.alignment para ajustar distribuição.\",\"toolbar.filters.enabled depende de filtering.enabled.\",\"settingsMenu.enabled expõe opções de densidade e colunas.\"],\"examples\":[\"{ toolbar: { visible: true, position: \\\"top\\\", title: \\\"Pedidos\\\" } }\"],\"antiPatterns\":[\"{ toolbar: { position: \\\"left\\\" } }\"]},\"toolbar-layout\":{\"id\":\"toolbar-layout\",\"title\":\"Layout da Toolbar\",\"description\":\"Configuração de toolbar.layout.*\",\"rules\":[\"alignment deve ser start/center/end/space-between.\",\"height e padding devem ser coerentes com o tema.\"],\"examples\":[\"{ toolbar: { layout: { alignment: \\\"space-between\\\", height: 56, showSeparator: true } } }\"],\"antiPatterns\":[\"{ toolbar: { layout: { alignment: \\\"between\\\" } } }\"]},\"toolbar-actions\":{\"id\":\"toolbar-actions\",\"title\":\"Ações da Toolbar\",\"description\":\"Definições de toolbar.actions[].\",\"rules\":[\"toolbar.actions[].id deve ser único.\",\"action deve ser string, não função JS.\",\"type deve ser button/icon/fab/menu.\",\"visibleWhen usa expressao condicional canonica em JSON Logic.\"],\"examples\":[\"{ toolbar: { actions: [{ id: \\\"add\\\", label: \\\"Adicionar\\\", type: \\\"button\\\", action: \\\"create\\\", position: \\\"end\\\" }] } }\",\"{ toolbar: { actions: [{ id: \\\"more\\\", label: \\\"Mais\\\", type: \\\"menu\\\", action: \\\"noop\\\", children: [{ id: \\\"export\\\", label: \\\"Exportar\\\", type: \\\"button\\\", action: \\\"export\\\" }] }] } }\"],\"antiPatterns\":[\"{ actions: [{ action: \\\"() => doSomething()\\\" }] }\"]},\"toolbar-filters\":{\"id\":\"toolbar-filters\",\"title\":\"Filtros da Toolbar\",\"description\":\"Configuração de toolbar.filters.* e quickFilters.\",\"rules\":[\"quickFilters[].filter deve seguir a estrutura do filtro suportado.\",\"enabled depende de behavior.filtering.enabled.\"],\"examples\":[\"{ toolbar: { filters: { enabled: true, quickFilters: [{ id: \\\"active\\\", label: \\\"Ativos\\\", filter: { status: \\\"active\\\" } }] } } }\"],\"antiPatterns\":[\"{ toolbar: { filters: { quickFilters: [{ filter: \\\"status=active\\\" }] } } }\"]},\"toolbar-settings\":{\"id\":\"toolbar-settings\",\"title\":\"Menu de Configuracoes\",\"description\":\"Configuração de toolbar.settingsMenu.*\",\"rules\":[\"settingsMenu.options[].type deve ser toggle/select/action.\",\"options deve listar valores validos quando type for select.\"],\"examples\":[\"{ toolbar: { settingsMenu: { enabled: true, options: [{ id: \\\"density\\\", label: \\\"Densidade\\\", type: \\\"select\\\", options: [\\\"compact\\\", \\\"comfortable\\\", \\\"spacious\\\"] }] } } }\"],\"antiPatterns\":[\"{ settingsMenu: { options: [{ type: \\\"dropdown\\\" }] } }\"]},\"row-actions\":{\"id\":\"row-actions\",\"title\":\"Acoes por Linha\",\"description\":\"Configuração de actions.row.*\",\"rules\":[\"enabled deve estar true para mostrar coluna de ações.\",\"display deve ser menu/buttons/icons.\",\"trigger deve ser hover/always/click.\",\"actions[].action deve ser string.\"],\"examples\":[\"{ actions: { row: { enabled: true, display: \\\"menu\\\", trigger: \\\"hover\\\", actions: [{ id: \\\"edit\\\", label: \\\"Editar\\\", action: \\\"edit\\\" }] } } }\"],\"antiPatterns\":[\"{ actions: { row: { display: \\\"dropdown\\\" } } }\"]},\"row-actions-advanced\":{\"id\":\"row-actions-advanced\",\"title\":\"Acoes por Linha Avancadas\",\"description\":\"Header, overflow, menu e comportamento avançado.\",\"rules\":[\"header.align deve ser start/center/end.\",\"behavior.maxInline deve ser numero ou objeto de breakpoints.\",\"menuIcon e menuButtonColor devem ser valores suportados.\",\"discovery.enabled=false mantem apenas as actions configuradas e bloqueia a descoberta contextual por HATEOAS/capabilities.\"],\"examples\":[\"{ actions: { row: { header: { label: \\\"Ações\\\", align: \\\"end\\\" }, maxVisibleActions: 3, behavior: { enabled: true, maxInline: 2 } } } }\",\"{ actions: { row: { enabled: true, display: \\\"buttons\\\", discovery: { enabled: false }, actions: [{ id: \\\"briefing\\\", label: \\\"Briefing\\\", action: \\\"inspect-surfaces\\\" }] } } }\"],\"antiPatterns\":[\"{ row: { header: { align: \\\"middle\\\" } } }\"]},\"bulk-actions\":{\"id\":\"bulk-actions\",\"title\":\"Acoes em Lote\",\"description\":\"Configuração de actions.bulk.*\",\"rules\":[\"bulk.enabled exige selection.enabled.\",\"floating.position deve ser bottom-right/bottom-left/top-right/top-left.\",\"hideWhenEmpty evita botão flutuante quando nada selecionado.\"],\"examples\":[\"{ actions: { bulk: { enabled: true, position: \\\"toolbar\\\", actions: [{ id: \\\"delete\\\", label: \\\"Excluir\\\", action: \\\"bulk-delete\\\", requiresConfirmation: true }], floating: { position: \\\"bottom-right\\\", hideWhenEmpty: true } } } }\"],\"antiPatterns\":[\"{ actions: { bulk: { enabled: true } } } sem selection.enabled\"]},\"context-actions\":{\"id\":\"context-actions\",\"title\":\"Menu de Contexto\",\"description\":\"Configuração de actions.context.*\",\"rules\":[\"trigger deve ser right-click/long-press/both.\",\"actions[].action deve ser string.\"],\"examples\":[\"{ actions: { context: { enabled: true, trigger: \\\"right-click\\\", actions: [{ id: \\\"copy\\\", label: \\\"Copiar\\\", action: \\\"copy\\\" }] } } }\"],\"antiPatterns\":[\"{ context: { trigger: \\\"click\\\" } }\"]}}}",
30779
+ "content": "{\"componentId\":\"praxis-table\",\"chunkSection\":\"aiConcepts\",\"aiConcepts\":{\"behavior-expansion\":{\"id\":\"behavior-expansion\",\"title\":\"Expansion (Behavior)\",\"description\":\"Configuração de behavior.expansion.* para detail rows schema-driven.\",\"rules\":[\"detail é sempre schema-driven; varie source.mode (inline/resource/resourcePath), não detail.type.\",\"detail.schemaContract.kind/version deve ser informado para validação e migração.\",\"Em virtualização, prefira detail.height.mode=fixed com virtualization.policy=fixed-height-only.\",\"Use eventExposureDefault hashed/redacted por padrão em ambiente corporativo.\"],\"examples\":[\"{ behavior: { expansion: { enabled: true, state: { mode: \\\"controlled\\\" }, detail: { schemaContract: { kind: \\\"praxis.detail.schema\\\", version: \\\"1.0.0\\\" }, source: { mode: \\\"resource\\\", resource: { kind: \\\"ui-composition\\\", id: \\\"customer-detail-v2\\\", version: \\\"2.1.0\\\" } }, rendering: { strategy: \\\"registry\\\", registryId: \\\"praxis.detail.default\\\" } } } } }\"],\"antiPatterns\":[\"{ behavior: { expansion: { detail: { type: \\\"template\\\", templateId: \\\"legacy-id\\\" } } } }\"]},\"appearance\":{\"id\":\"appearance\",\"title\":\"Aparência e Layout\",\"description\":\"Densidade, bordas, cores, tipografia, espaçamento e responsividade.\",\"rules\":[\"appearance.density deve usar valores compact/comfortable/spacious.\",\"Cores devem usar tokens do tema ou hex válido.\",\"responsive.mobile.cardMode deve ser combinado com colunas prioritárias.\",\"Se animations.enabled for true, respeite reduceMotion.\",\"appearance.animations.specific.row e appearance.animations.specific.cell controlam animações condicionais por escopo.\"],\"examples\":[\"{ appearance: { density: \\\"compact\\\", borders: { showRowBorders: true } } }\",\"{ appearance: { typography: { fontSize: \\\"14px\\\" }, spacing: { cellPadding: \\\"8px 16px\\\" } } }\"],\"antiPatterns\":[\"{ appearance: { density: \\\"tiny\\\" } }\"]},\"appearance-details\":{\"id\":\"appearance-details\",\"title\":\"Detalhes de Aparência\",\"description\":\"Bordas, cores, tipografia, spacing, elevation e responsive autoAdjust.\",\"rules\":[\"borders.style deve ser solid/dashed/dotted quando aplicável.\",\"typography.headerFontWeight deve ser string numerica ou token.\",\"responsive.autoAdjust controla ajustes automáticos em telas menores.\"],\"examples\":[\"{ appearance: { borders: { showOuterBorder: true, style: \\\"solid\\\" }, colors: { alternateRowBackground: \\\"#f7f9fc\\\" } } }\",\"{ appearance: { responsive: { mobile: { cardMode: true, priorityColumns: [\\\"name\\\", \\\"status\\\"] } } } }\"],\"antiPatterns\":[\"{ appearance: { borders: { style: \\\"double\\\" } } }\"]},\"toolbar\":{\"id\":\"toolbar\",\"title\":\"Toolbar\",\"description\":\"Configurações gerais da toolbar.\",\"rules\":[\"toolbar.visible controla exibição global da barra.\",\"Use toolbar.layout.alignment para ajustar distribuição.\",\"toolbar.filters.enabled depende de filtering.enabled.\",\"settingsMenu.enabled expõe opções de densidade e colunas.\"],\"examples\":[\"{ toolbar: { visible: true, position: \\\"top\\\", title: \\\"Pedidos\\\" } }\"],\"antiPatterns\":[\"{ toolbar: { position: \\\"left\\\" } }\"]},\"toolbar-layout\":{\"id\":\"toolbar-layout\",\"title\":\"Layout da Toolbar\",\"description\":\"Configuração de toolbar.layout.*\",\"rules\":[\"alignment deve ser start/center/end/space-between.\",\"height e padding devem ser coerentes com o tema.\"],\"examples\":[\"{ toolbar: { layout: { alignment: \\\"space-between\\\", height: 56, showSeparator: true } } }\"],\"antiPatterns\":[\"{ toolbar: { layout: { alignment: \\\"between\\\" } } }\"]},\"toolbar-actions\":{\"id\":\"toolbar-actions\",\"title\":\"Ações da Toolbar\",\"description\":\"Definições de toolbar.actions[].\",\"rules\":[\"toolbar.actions[].id deve ser único.\",\"action deve ser string, não função JS.\",\"type deve ser button/icon/fab/menu.\",\"visibleWhen usa expressao condicional canonica em JSON Logic.\"],\"examples\":[\"{ toolbar: { actions: [{ id: \\\"add\\\", label: \\\"Adicionar\\\", type: \\\"button\\\", action: \\\"create\\\", position: \\\"end\\\" }] } }\",\"{ toolbar: { actions: [{ id: \\\"more\\\", label: \\\"Mais\\\", type: \\\"menu\\\", action: \\\"noop\\\", children: [{ id: \\\"export\\\", label: \\\"Exportar\\\", type: \\\"button\\\", action: \\\"export\\\" }] }] } }\"],\"antiPatterns\":[\"{ actions: [{ action: \\\"() => doSomething()\\\" }] }\"]},\"toolbar-filters\":{\"id\":\"toolbar-filters\",\"title\":\"Filtros da Toolbar\",\"description\":\"Configuração de toolbar.filters.* e quickFilters.\",\"rules\":[\"quickFilters[].filter deve seguir a estrutura do filtro suportado.\",\"quickFilters representa um pequeno seletor de escopo exclusivo e removível; use filtros avançados para critérios combináveis.\",\"enabled depende de behavior.filtering.enabled.\"],\"examples\":[\"{ toolbar: { filters: { enabled: true, quickFilters: [{ id: \\\"active\\\", label: \\\"Ativos\\\", filter: { status: \\\"active\\\" } }] } } }\"],\"antiPatterns\":[\"{ toolbar: { filters: { quickFilters: [{ filter: \\\"status=active\\\" }] } } }\"]},\"toolbar-settings\":{\"id\":\"toolbar-settings\",\"title\":\"Menu de Configuracoes\",\"description\":\"Configuração de toolbar.settingsMenu.*\",\"rules\":[\"settingsMenu.options[].type deve ser toggle/select/action.\",\"options deve listar valores validos quando type for select.\"],\"examples\":[\"{ toolbar: { settingsMenu: { enabled: true, options: [{ id: \\\"density\\\", label: \\\"Densidade\\\", type: \\\"select\\\", options: [\\\"compact\\\", \\\"comfortable\\\", \\\"spacious\\\"] }] } } }\"],\"antiPatterns\":[\"{ settingsMenu: { options: [{ type: \\\"dropdown\\\" }] } }\"]},\"row-actions\":{\"id\":\"row-actions\",\"title\":\"Acoes por Linha\",\"description\":\"Configuração de actions.row.*\",\"rules\":[\"enabled deve estar true para mostrar coluna de ações.\",\"display deve ser menu/buttons/icons.\",\"trigger deve ser hover/always/click.\",\"actions[].action deve ser string.\"],\"examples\":[\"{ actions: { row: { enabled: true, display: \\\"menu\\\", trigger: \\\"hover\\\", actions: [{ id: \\\"edit\\\", label: \\\"Editar\\\", action: \\\"edit\\\" }] } } }\"],\"antiPatterns\":[\"{ actions: { row: { display: \\\"dropdown\\\" } } }\"]},\"row-actions-advanced\":{\"id\":\"row-actions-advanced\",\"title\":\"Acoes por Linha Avancadas\",\"description\":\"Header, overflow, menu e comportamento avançado.\",\"rules\":[\"header.align deve ser start/center/end.\",\"behavior.maxInline deve ser numero ou objeto de breakpoints.\",\"menuIcon e menuButtonColor devem ser valores suportados.\",\"discovery.enabled=false mantem apenas as actions configuradas e bloqueia a descoberta contextual por HATEOAS/capabilities.\"],\"examples\":[\"{ actions: { row: { header: { label: \\\"Ações\\\", align: \\\"end\\\" }, maxVisibleActions: 3, behavior: { enabled: true, maxInline: 2 } } } }\",\"{ actions: { row: { enabled: true, display: \\\"buttons\\\", discovery: { enabled: false }, actions: [{ id: \\\"briefing\\\", label: \\\"Briefing\\\", action: \\\"inspect-surfaces\\\" }] } } }\"],\"antiPatterns\":[\"{ row: { header: { align: \\\"middle\\\" } } }\"]},\"bulk-actions\":{\"id\":\"bulk-actions\",\"title\":\"Acoes em Lote\",\"description\":\"Configuração de actions.bulk.*\",\"rules\":[\"bulk.enabled exige selection.enabled.\",\"floating.position deve ser bottom-right/bottom-left/top-right/top-left.\",\"hideWhenEmpty evita botão flutuante quando nada selecionado.\"],\"examples\":[\"{ actions: { bulk: { enabled: true, position: \\\"toolbar\\\", actions: [{ id: \\\"delete\\\", label: \\\"Excluir\\\", action: \\\"bulk-delete\\\", requiresConfirmation: true }], floating: { position: \\\"bottom-right\\\", hideWhenEmpty: true } } } }\"],\"antiPatterns\":[\"{ actions: { bulk: { enabled: true } } } sem selection.enabled\"]},\"context-actions\":{\"id\":\"context-actions\",\"title\":\"Menu de Contexto\",\"description\":\"Configuração de actions.context.*\",\"rules\":[\"trigger deve ser right-click/long-press/both.\",\"actions[].action deve ser string.\"],\"examples\":[\"{ actions: { context: { enabled: true, trigger: \\\"right-click\\\", actions: [{ id: \\\"copy\\\", label: \\\"Copiar\\\", action: \\\"copy\\\" }] } } }\"],\"antiPatterns\":[\"{ context: { trigger: \\\"click\\\" } }\"]}}}",
30779
30780
  "sourcePointer": "projects/praxis-table/src/lib/ai/table-context-pack.ts",
30780
- "contentHash": "d5538c651ed8883fdf89d5bad8b5cd45e912912913ca352a249a02d927b40eac",
30781
+ "contentHash": "53d73757e5371b6d7de9c66090fbec49c0866649166fe4e28f040f564b3f07c3",
30781
30782
  "sourceKind": "component_definition",
30782
30783
  "sourceId": "praxis-table",
30783
30784
  "corpusVersion": "1.0.0"
@@ -29,7 +29,7 @@ reading_time: 16
29
29
  estimated_setup_time: 35
30
30
  version: "1.0"
31
31
  related_docs:
32
- - "table-overview"
32
+ - "praxis-table-json-api"
33
33
  - "dynamic-filter-payload-contract"
34
34
  - "dynamic-filter-range-filters-guide"
35
35
  - "dynamic-fields-inline-components-guide"
@@ -91,6 +91,21 @@ No Praxis, o filtro dinâmico é uma pipeline de seis etapas:
91
91
  - persistência local do estado do DTO e das preferências de exibição com chaves `filter-dto:<key>` e `filter-config:<key>`;
92
92
  - heurísticas que convertem `controlType` genérico para inline canônico quando a feature pede experiência compacta.
93
93
 
94
+ Na toolbar da tabela, essa responsabilidade é materializada em quatro regiões
95
+ semânticas governadas pela largura do próprio container:
96
+
97
+ - `identity`: identidade e contexto da coleção;
98
+ - `scope`: quick filters mutuamente exclusivos e removíveis;
99
+ - `query`: campos de filtro e atalhos projetados;
100
+ - `commands`: ações de negócio, utilidades e authoring.
101
+
102
+ Dentro de `PraxisFilter`, `query` se divide em `criteria` e
103
+ `query-auxiliary`. A primeira região contém os campos selecionados e sempre
104
+ visíveis. A segunda mantém tags/atalhos e comandos de gerenciamento como um
105
+ cluster único. O reflow move regiões completas e preserva ordem visual, ordem de
106
+ teclado e paridade de comandos; hosts não devem reconstruir essa composição com
107
+ breakpoints locais.
108
+
94
109
  Esse acoplamento existe em `projects/praxis-table/src/lib/components/praxis-filter/praxis-filter.component.ts` e `projects/praxis-table/src/lib/services/filter-config.service.ts`.
95
110
 
96
111
  ### 2. `praxis-dynamic-fields`: superfície dos controles
@@ -153,6 +168,12 @@ O runtime persiste:
153
168
 
154
169
  Isso permite restaurar seleção de campos, preferências visuais e estado operacional do filtro.
155
170
 
171
+ Tags fornecidas por `tags` são presets governados e não pertencem ao conjunto
172
+ editável de atalhos salvos pelo usuário. O runtime permite aplicá-las e removê-las,
173
+ mas não renomeá-las ou excluí-las. O `patch` de cada tag deve usar os nomes e
174
+ shapes canônicos do `FilterDTO`; um campo desconhecido não ganha semântica apenas
175
+ por estar presente no JSON do host.
176
+
156
177
  ### Etapa 4. Emissão de payload
157
178
 
158
179
  No modo avançado, `onAdvancedChange(event)` trabalha sobre `event.formData`. Os eventos `change` e `submit` são o contrato que o host normalmente observa para disparar integração com a API.
@@ -28,7 +28,7 @@ reading_time: 18
28
28
  estimated_setup_time: 45
29
29
  version: "1.0"
30
30
  related_docs:
31
- - "table-overview"
31
+ - "praxis-table-json-api"
32
32
  - "dynamic-filter-architecture-overview"
33
33
  - "dynamic-filter-payload-contract"
34
34
  - "dynamic-filter-editor-settings-guide"
@@ -125,6 +125,44 @@ e emite o novo payload para evitar filtro invisível. Use `alwaysVisibleFields`
125
125
  apenas para campos realmente fixos, porque eles não entram nessa remoção rápida
126
126
  do usuário.
127
127
 
128
+ #### Preservar a hierarquia da consulta na toolbar
129
+
130
+ O host declara a semântica, mas não posiciona controles com CSS próprio. O
131
+ `praxis-filter` organiza a consulta em duas regiões internas:
132
+
133
+ - **critérios**: campos sempre visíveis e campos adicionados por
134
+ `selectedFieldIds`;
135
+ - **auxiliar**: atalhos salvos/tags e comandos de gerenciamento, como adicionar
136
+ filtros, limpar critérios e abrir o formulário avançado.
137
+
138
+ Em containers largos, as duas regiões podem compartilhar a mesma faixa. Quando
139
+ o espaço diminui, a região auxiliar desce como um bloco completo; atalhos e
140
+ comandos não devem se espalhar por linhas diferentes nem comprimir campos de
141
+ data, intervalo ou lookup abaixo da largura utilizável. Em containers estreitos,
142
+ os critérios passam para uma coluna e o cluster auxiliar pode quebrar
143
+ internamente, preservando a ordem de leitura e de teclado.
144
+
145
+ Essa adaptação usa a largura do container da tabela, não apenas a viewport. Por
146
+ isso, o mesmo contrato continua válido dentro de páginas, cards, drawers e split
147
+ panes. Não crie breakpoints no host nem projete atalhos dentro da região de
148
+ campos: use os inputs e slots públicos, e deixe o runtime materializar a
149
+ geometria. Valide pelo menos os estados sem valor, preenchido, foco, erro e
150
+ disabled em tema claro/escuro, zoom de 200% e labels localizados longos.
151
+
152
+ Atalhos declarados em `tags` devem usar exatamente as chaves e os shapes do DTO
153
+ de filtro descoberto. Um atalho de faixa salarial, por exemplo, deve escrever o
154
+ mesmo campo de intervalo materializado pelo controle inline; criar um alias
155
+ apenas no host produz critério invisível. Tags predefinidas são somente leitura
156
+ quanto a renomear e excluir, mas continuam acionáveis e removíveis pelo operador.
157
+ O host deve observar `submit` quando atalhos precisam disparar consulta imediata;
158
+ `change` permanece a cadência de edição dos campos.
159
+
160
+ Controles projetados no slot `[toolbar]` recebem orçamento limitado e podem
161
+ quebrar dentro do cluster de consulta. Eles devem aceitar redução de largura e
162
+ não podem impor `min-width` maior que o slot. Se a operação precisar manter
163
+ largura intrínseca rígida, materialize-a como ação governada/overflow em vez de
164
+ forçar geometria local.
165
+
128
166
  #### Padronizar `materialDesign` dos campos de filtro
129
167
 
130
168
  O `praxis-filter` normaliza a metadata efetiva de filtros com uma politica