@praxisui/table 8.0.0-beta.2 → 8.0.0-beta.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +81 -8
  2. package/docs/DSL-Extensions-Guide.md +23 -0
  3. package/docs/adr/2026-03-dynamic-filter-cross-lib-coupling.md +107 -0
  4. package/docs/adr/2026-03-filter-drawer-adapter-light-entrypoint.md +105 -0
  5. package/docs/adr/2026-03-table-editor-idfield-decision.md +85 -0
  6. package/docs/column-resize-reorder-implementation-plan.md +338 -0
  7. package/docs/column-resize-reorder-review-prompt.md +34 -0
  8. package/docs/dynamic-filter-architecture-overview.md +207 -0
  9. package/docs/dynamic-filter-backend-contract-cheatsheet.md +167 -0
  10. package/docs/dynamic-filter-editor-settings-guide.md +229 -0
  11. package/docs/dynamic-filter-host-integration-guide.md +217 -0
  12. package/docs/dynamic-filter-payload-contract.md +331 -0
  13. package/docs/dynamic-filter-range-filters-guide.md +289 -0
  14. package/docs/dynamic-filter-troubleshooting-guide.md +220 -0
  15. package/docs/dynamic-inline-filter-catalog.md +147 -0
  16. package/docs/e2e-column-drag-playwright.md +62 -0
  17. package/docs/expandable-rows-enterprise-big-leagues-plan.md +1080 -0
  18. package/docs/json-logic-operators-and-helpers.md +57 -0
  19. package/docs/local-data-mode-precedence.md +12 -0
  20. package/docs/local-data-pre-implementation-baseline.md +22 -0
  21. package/docs/local-data-preimplementation-go-no-go.md +39 -0
  22. package/docs/local-data-support-implementation-plan.md +524 -0
  23. package/docs/local-data-support-pr-package.md +66 -0
  24. package/docs/localization-persistence-merge.md +22 -0
  25. package/docs/performance-hardening-v2-implementation-plan.md +479 -0
  26. package/docs/playground-scenario-curation-plan.md +482 -0
  27. package/docs/playground-scenario-second-opinion-prompt.md +121 -0
  28. package/docs/playground-scenario-second-opinion-review.md +234 -0
  29. package/docs/release-notes-p1-hardening.md +76 -0
  30. package/docs/table-authoring-document-completeness-checklist.md +120 -0
  31. package/docs/table-editor-capability-review-prompt.md +349 -0
  32. package/docs/visual-rules-editor-transition.md +29 -0
  33. package/fesm2022/{praxisui-table-table-ai.adapter-DxjDaQqy.mjs → praxisui-table-table-ai.adapter-fS74fZ7o.mjs} +14 -5
  34. package/fesm2022/praxisui-table.mjs +3650 -324
  35. package/index.d.ts +120 -51
  36. package/package.json +15 -9
  37. package/src/lib/praxis-table.json-api.md +1315 -0
@@ -0,0 +1,167 @@
1
+ ---
2
+ title: "Dynamic Filter Backend Contract Cheatsheet"
3
+ slug: "dynamic-filter-backend-contract-cheatsheet"
4
+ description: "Cheatsheet canônico do contrato backend do filtro dinamico, resumindo endpoints, formas de payload, ranges, erros e configuracoes do metadata-starter relevantes para hosts."
5
+ doc_type: "reference"
6
+ document_kind: "host-guide"
7
+ component: "table"
8
+ category: "integration"
9
+ audience:
10
+ - "host"
11
+ - "frontend"
12
+ - "backend"
13
+ - "architect"
14
+ level: "advanced"
15
+ status: "active"
16
+ owner: "praxis-ui"
17
+ tags:
18
+ - "dynamic-filter"
19
+ - "backend"
20
+ - "cheatsheet"
21
+ - "metadata-starter"
22
+ - "payload"
23
+ order: 33
24
+ icon: "rule_folder"
25
+ toc: true
26
+ sidebar: true
27
+ search_boost: 1.18
28
+ reading_time: 14
29
+ estimated_setup_time: 20
30
+ version: "1.0"
31
+ related_docs:
32
+ - "dynamic-filter-payload-contract"
33
+ - "dynamic-filter-range-filters-guide"
34
+ - "dynamic-fields-inline-filter-runtime-contract"
35
+ - "dynamic-filter-troubleshooting-guide"
36
+ keywords:
37
+ - "POST /filter"
38
+ - "POST /filter/cursor"
39
+ - "FILTER_PAYLOAD_INVALID"
40
+ source_of_truth:
41
+ - "../praxis-metadata-starter/src/main/java/org/praxisplatform/uischema/controller/base/AbstractResourceQueryController.java"
42
+ - "../praxis-metadata-starter/src/main/java/org/praxisplatform/uischema/filter/web/FilterRequestBodyAdvice.java"
43
+ - "../praxis-metadata-starter/src/main/java/org/praxisplatform/uischema/filter/range/RangePayloadNormalizer.java"
44
+ - "../praxis-metadata-starter/src/main/java/org/praxisplatform/uischema/rest/exceptionhandler/GlobalExceptionHandler.java"
45
+ - "../praxis-metadata-starter/docs/examples/filter-dto.md"
46
+ - "../praxis-metadata-starter/docs/guides/FILTROS-E-PAGINACAO.md"
47
+ last_updated: "2026-03-07"
48
+ ---
49
+
50
+ # Dynamic Filter Backend Contract Cheatsheet
51
+
52
+ ## Objetivo
53
+
54
+ Resumir, em formato operacional, o que um host precisa saber sobre o contrato backend do filtro dinâmico.
55
+
56
+ ## Pré-requisitos
57
+
58
+ - Conhecimento básico de `GenericFilterDTO`.
59
+ - Leitura do contrato de payload e do guia de ranges.
60
+
61
+ ## Quando usar
62
+
63
+ Use este documento como referência rápida em implementação, revisão de payload e troubleshooting.
64
+
65
+ ## Endpoints principais
66
+
67
+ - `POST /filter`
68
+ - `POST /filter/cursor`
69
+ - `POST /locate`
70
+ - `POST /options/filter`
71
+
72
+ Todos pertencem à superfície resource-oriented padrão de `AbstractResourceQueryController`.
73
+
74
+ ## Pipeline backend
75
+
76
+ 1. request body chega ao controller;
77
+ 2. `FilterRequestBodyAdvice` intercepta o body;
78
+ 3. `RangePayloadNormalizer` canonicaliza ranges;
79
+ 4. Jackson desserializa no `GenericFilterDTO`;
80
+ 5. `GenericSpecificationsBuilder` monta a consulta;
81
+ 6. erros retornam `400` quando houver violação de payload.
82
+
83
+ ```mermaid
84
+ sequenceDiagram
85
+ participant Host
86
+ participant Controller as AbstractResourceQueryController
87
+ participant Advice as FilterRequestBodyAdvice
88
+ participant Normalizer as RangePayloadNormalizer
89
+ participant DTO as GenericFilterDTO
90
+ participant Builder as GenericSpecificationsBuilder
91
+
92
+ Host->>Controller: POST /filter
93
+ Controller->>Advice: intercept request body
94
+ Advice->>Normalizer: canonicalize ranges
95
+ Normalizer->>DTO: canonical payload ready
96
+ DTO->>Builder: build specification
97
+ Builder-->>Controller: query result or FILTER_PAYLOAD_INVALID
98
+ Controller-->>Host: response payload or HTTP 400
99
+ ```
100
+
101
+ ## Shapes aceitos para range
102
+
103
+ ### Lista canônica
104
+
105
+ - `[min]`
106
+ - `[min, max]`
107
+ - `[null, max]`
108
+
109
+ ### Objeto canônico
110
+
111
+ - monetário: `{ minPrice, maxPrice, currency? }`
112
+ - data: `{ startDate, endDate }`
113
+ - numérico genérico: `{ min, max }`
114
+
115
+ ## Formatos inválidos por padrão
116
+
117
+ - escalar puro: `1500`
118
+ - lista com 3 valores
119
+ - objeto sem nenhum limite efetivo
120
+ - fontes conflitantes para o mesmo bound
121
+
122
+ ## Operações de range relevantes
123
+
124
+ - `BETWEEN`
125
+ - `BETWEEN_EXCLUSIVE`
126
+ - `NOT_BETWEEN`
127
+ - `OUTSIDE_RANGE`
128
+
129
+ Resumo:
130
+
131
+ - `BETWEEN`: inclusivo e aceita bound parcial;
132
+ - `BETWEEN_EXCLUSIVE`: exige dois bounds e usa exclusão;
133
+ - `NOT_BETWEEN`: nega o intervalo;
134
+ - `OUTSIDE_RANGE`: fora da faixa.
135
+
136
+ ## Código de erro relevante
137
+
138
+ Para payload inválido de filtro:
139
+
140
+ - HTTP `400`
141
+ - `errors[].properties.code = FILTER_PAYLOAD_INVALID`
142
+
143
+ ## Regras práticas para hosts
144
+
145
+ 1. Envie DTO limpo, sem metadata de UI.
146
+ 2. Prefira objeto ou lista canônica para range.
147
+ 3. Não envie payload escalar para operações de range.
148
+ 4. Não dependa de aliases alternativos como estilo principal.
149
+ 5. Compare sempre a operação backend com o shape enviado.
150
+
151
+ ## Exemplo curto
152
+
153
+ ```json
154
+ {
155
+ "salaryRange": {
156
+ "minPrice": 6500,
157
+ "maxPrice": 15000
158
+ },
159
+ "status": ["ACTIVE", "PENDING"]
160
+ }
161
+ ```
162
+
163
+ Resultado esperado:
164
+
165
+ - `salaryRange` pode ser normalizado para `[6500,15000]`;
166
+ - `status` segue como lista para operação compatível;
167
+ - payload inválido resulta em `400`.
@@ -0,0 +1,229 @@
1
+ ---
2
+ title: "Dynamic Filter Editor Settings Guide"
3
+ slug: "dynamic-filter-editor-settings-guide"
4
+ description: "Guia detalhado do editor de configuracoes do filtro dinamico, cobrindo campos always visible, metadata overrides, variantes inline, painel avancado e governanca operacional."
5
+ doc_type: "reference"
6
+ document_kind: "host-guide"
7
+ component: "table"
8
+ category: "components"
9
+ audience:
10
+ - "host"
11
+ - "frontend"
12
+ - "architect"
13
+ level: "advanced"
14
+ status: "active"
15
+ owner: "praxis-ui"
16
+ tags:
17
+ - "dynamic-filter"
18
+ - "filter-settings"
19
+ - "always-visible"
20
+ - "metadata-overrides"
21
+ - "editor"
22
+ order: 30
23
+ icon: "settings_suggest"
24
+ toc: true
25
+ sidebar: true
26
+ search_boost: 1.15
27
+ reading_time: 22
28
+ estimated_setup_time: 40
29
+ version: "1.0"
30
+ related_docs:
31
+ - "dynamic-filter-host-integration-guide"
32
+ - "dynamic-inline-filter-catalog"
33
+ - "dynamic-fields-inline-components-guide"
34
+ - "table-overview"
35
+ keywords:
36
+ - "advancedOpenMode"
37
+ - "advancedClearButtonsEnabled"
38
+ - "alwaysVisibleFieldMetadataOverrides"
39
+ - "useInlineDateRangeVariant"
40
+ source_of_truth:
41
+ - "projects/praxis-table/src/lib/filter-settings/filter-settings.component.ts"
42
+ - "projects/praxis-table/src/lib/services/filter-config.service.ts"
43
+ - "projects/praxis-table/src/lib/components/praxis-filter/praxis-filter.component.ts"
44
+ last_updated: "2026-03-07"
45
+ ---
46
+
47
+ # Dynamic Filter Editor Settings Guide
48
+
49
+ ## Objetivo
50
+
51
+ Documentar o papel do editor/configurador do filtro dinâmico como camada de governança da feature, e não apenas como tela auxiliar.
52
+
53
+ ## Pré-requisitos
54
+
55
+ - Conhecimento de `advancedFilters.settings`.
56
+ - Entendimento básico de `controlType` inline e toolbar compacta.
57
+ - Familiaridade com a diferença entre metadata original e overrides do host.
58
+
59
+ ## Quando usar
60
+
61
+ Use este guia para:
62
+
63
+ - padronizar o editor do filtro em ambientes enterprise;
64
+ - explicar como o host altera a UX sem alterar o DTO original;
65
+ - decidir quais flags inline ativar;
66
+ - documentar a política de always visible fields.
67
+
68
+ ## Papel do editor
69
+
70
+ O `filter-settings` não é cosmético. Ele governa:
71
+
72
+ - quais campos ficam sempre visíveis;
73
+ - quais campos podem ser escolhidos pelo usuário;
74
+ - quais variantes inline são permitidas;
75
+ - como o painel avançado abre;
76
+ - como clear buttons e métricas operam.
77
+
78
+ Em termos arquiteturais, ele é o ponto onde a experiência do filtro deixa de ser “schema puro” e passa a ser “schema + política do produto”.
79
+
80
+ ## Grupos principais de configuração
81
+
82
+ ### Always visible
83
+
84
+ Campos centrais:
85
+
86
+ - `alwaysVisibleFields`
87
+ - `alwaysVisibleFieldMetadataOverrides`
88
+ - `selectedFieldIds`
89
+
90
+ Use esse grupo para controlar a barra compacta principal.
91
+
92
+ ### Operação
93
+
94
+ Campos centrais:
95
+
96
+ - `changeDebounceMs`
97
+ - `allowSaveTags`
98
+ - `showAdvanced`
99
+ - `mode`
100
+
101
+ Esse grupo controla como o filtro reage, não só como ele parece.
102
+
103
+ ### Variantes inline
104
+
105
+ Flags principais:
106
+
107
+ - `useInlineSearchableSelectVariant`
108
+ - `useInlineRangeVariant`
109
+ - `useInlineDateVariant`
110
+ - `useInlineDateRangeVariant`
111
+ - `useInlineTimeVariant`
112
+ - `useInlineTimeRangeVariant`
113
+ - `useInlineTreeSelectVariant`
114
+
115
+ Essas flags são decisivas para a documentação porque vários `controlType` agora migram para a experiência compacta por padrão, e o host usa essas chaves como opt-out explícito quando precisa preservar o renderer tradicional.
116
+
117
+ ### Painel avançado
118
+
119
+ Campos centrais:
120
+
121
+ - `overlayVariant`
122
+ - `overlayBackdrop`
123
+ - `advancedOpenMode`
124
+ - `advancedClearButtonsEnabled`
125
+
126
+ Esse grupo define a experiência do formulário avançado e precisa ser documentado junto com a jornada de uso.
127
+
128
+ ## Always visible fields em profundidade
129
+
130
+ ### O que são
131
+
132
+ São os campos “pinned” do filtro, exibidos antes da grade ampliada e antes dos campos opcionais escolhidos pelo usuário.
133
+
134
+ ### Quando usar
135
+
136
+ Escolha campos que tenham:
137
+
138
+ - alta frequência de uso;
139
+ - leitura rápida;
140
+ - valor decisório forte;
141
+ - compatibilidade com layout compacto.
142
+
143
+ ### Quando evitar
144
+
145
+ Evite promover para always visible campos que:
146
+
147
+ - tenham interação longa e pouco frequente;
148
+ - dependam de catálogos remotos lentos;
149
+ - exijam overlay complexo para valor baixo de uso;
150
+ - prejudiquem a leitura do conjunto da barra.
151
+
152
+ ## Metadata overrides
153
+
154
+ `alwaysVisibleFieldMetadataOverrides` existe para ajustes controlados sobre campos fixados.
155
+
156
+ Use quando o campo precisar:
157
+
158
+ - label mais curta;
159
+ - outro `controlType`;
160
+ - clear button diferente;
161
+ - largura e auto-size específicos;
162
+ - hints e aria labels adequados ao modo compacto.
163
+
164
+ Não use para:
165
+
166
+ - reinventar o contrato do DTO;
167
+ - alterar o significado semântico do campo;
168
+ - criar divergência editorial entre barra compacta e formulário avançado sem documentação.
169
+
170
+ ## Política de variantes inline
171
+
172
+ ### Regra recomendada
173
+
174
+ Inline é o padrão do `praxis-filter` quando existe equivalente dedicado para a barra compacta.
175
+
176
+ Sugestão prática:
177
+
178
+ - mantenha `useInlineRangeVariant` e `useInlineDateVariant` no padrão inline;
179
+ - mantenha `useInlineDateRangeVariant` no padrão inline e faça opt-out apenas quando o host precisar do renderer dedicado por densidade ou fluxo operacional;
180
+ - mantenha `useInlineTimeVariant` e `useInlineTimeRangeVariant` no padrão inline, validando densidade e clareza de rótulo no host real;
181
+ - mantenha `useInlineSearchableSelectVariant` no padrão inline, mas faça opt-out se o endpoint, paginação ou volume remoto exigirem o renderer dedicado;
182
+ - mantenha `useInlineTreeSelectVariant` no padrão inline para seleção hierárquica compacta e faça opt-out quando o fluxo depender da leitura expandida do componente dedicado.
183
+
184
+ ## Advanced open mode
185
+
186
+ `advancedOpenMode` define se o filtro avançado abre em:
187
+
188
+ - `modal`
189
+ - `drawer`
190
+
191
+ Regra recomendada:
192
+
193
+ - `modal` quando o contexto exige foco e baixa simultaneidade;
194
+ - `drawer` quando a tabela precisa continuar visível e comparável durante o refinamento do filtro.
195
+
196
+ ## Clear buttons avançados
197
+
198
+ `advancedClearButtonsEnabled` não é detalhe cosmético. Ele interfere na velocidade de limpeza do formulário e na previsibilidade da UX.
199
+
200
+ Recomendação:
201
+
202
+ - mantenha `true` por padrão em ambientes enterprise;
203
+ - desabilite apenas quando houver conflito com um design de formulário altamente controlado.
204
+
205
+ ## Sinais operacionais importantes
206
+
207
+ O editor também conversa com preocupações de operação:
208
+
209
+ - `logLevel`
210
+ - `enablePerformanceMetrics`
211
+
212
+ Esses campos ajudam a transformar o filtro em feature observável em vez de caixa-preta.
213
+
214
+ ## Erros editoriais comuns
215
+
216
+ 1. Ativar todas as variantes inline ao mesmo tempo.
217
+ 2. Tratar `alwaysVisibleFieldMetadataOverrides` como escape hatch permanente.
218
+ 3. Criar toolbar compacta mais complexa que o formulário avançado.
219
+ 4. Não documentar por que certos campos foram fixados e outros não.
220
+ 5. Ignorar diferenças de layout entre desktop, tablet e mobile.
221
+
222
+ ## Recomendação de governança
223
+
224
+ Para documentação extensa e sustentável:
225
+
226
+ 1. registre a política de always visible por produto;
227
+ 2. documente quais flags inline estão aprovadas;
228
+ 3. trate overrides como exceção auditável;
229
+ 4. mantenha catálogo visual e settings guide sincronizados.
@@ -0,0 +1,217 @@
1
+ ---
2
+ title: "Dynamic Filter Host Integration Guide"
3
+ slug: "dynamic-filter-host-integration-guide"
4
+ description: "Guia operacional para integrar o filtro dinamico em hosts Praxis, cobrindo bindings da tabela, persistencia, eventos, settings e envio do DTO ao backend."
5
+ doc_type: "guide"
6
+ document_kind: "host-guide"
7
+ component: "table"
8
+ category: "integration"
9
+ audience:
10
+ - "host"
11
+ - "frontend"
12
+ - "architect"
13
+ level: "advanced"
14
+ status: "active"
15
+ owner: "praxis-ui"
16
+ tags:
17
+ - "dynamic-filter"
18
+ - "host"
19
+ - "praxis-table"
20
+ - "integration"
21
+ - "settings"
22
+ order: 29
23
+ icon: "integration_instructions"
24
+ toc: true
25
+ sidebar: true
26
+ search_boost: 1.15
27
+ reading_time: 18
28
+ estimated_setup_time: 45
29
+ version: "1.0"
30
+ related_docs:
31
+ - "table-overview"
32
+ - "dynamic-filter-architecture-overview"
33
+ - "dynamic-filter-payload-contract"
34
+ - "dynamic-filter-editor-settings-guide"
35
+ - "dynamic-inline-filter-catalog"
36
+ keywords:
37
+ - "alwaysVisibleFields"
38
+ - "selectedFieldIds"
39
+ - "allowSaveTags"
40
+ - "changeDebounceMs"
41
+ source_of_truth:
42
+ - "projects/praxis-table/src/lib/praxis-table.html"
43
+ - "projects/praxis-table/src/lib/components/praxis-filter/praxis-filter.component.ts"
44
+ - "projects/praxis-table/src/lib/services/filter-config.service.ts"
45
+ last_updated: "2026-03-07"
46
+ ---
47
+
48
+ # Dynamic Filter Host Integration Guide
49
+
50
+ ## Objetivo
51
+
52
+ Mostrar como um host integra o filtro dinâmico no contexto real da `table`, incluindo bindings de configuração, eventos emitidos, persistência local e envio do payload ao backend.
53
+
54
+ ## Pré-requisitos
55
+
56
+ - Conhecimento básico de `TableConfig` e `@praxisui/table`.
57
+ - Backend já expondo schema e endpoint de filtro.
58
+ - Entendimento prévio do contrato de payload e de ranges.
59
+
60
+ ## Quando usar
61
+
62
+ Use este guia para:
63
+
64
+ - plugar o filtro em uma tabela nova;
65
+ - padronizar configuração de `advancedFilters.settings`;
66
+ - decidir quais campos ficam sempre visíveis;
67
+ - alinhar debounce, tags e comportamento do painel avançado.
68
+
69
+ ## Integração mínima
70
+
71
+ No runtime da tabela, o `praxis-filter` já é montado pela própria `praxis-table`.
72
+
73
+ O host normalmente atua via `config.behavior.filtering.advancedFilters.settings`, alimentando bindings como:
74
+
75
+ - `alwaysVisibleFields`
76
+ - `alwaysVisibleFieldMetadataOverrides`
77
+ - `selectedFieldIds`
78
+ - `allowSaveTags`
79
+ - `changeDebounceMs`
80
+ - `showFilterSettings`
81
+
82
+ O template da tabela também encaminha:
83
+
84
+ - `resourcePath`
85
+ - `filterId`
86
+ - `formId`
87
+ - `persistenceKey`
88
+ - `fieldMetadata`
89
+ - `enableCustomization` (opt-in; default canônico `false`)
90
+
91
+ O host deve pensar a integração na ordem abaixo.
92
+
93
+ ```mermaid
94
+ flowchart TD
95
+ config["Load TableConfig"] --> bindings["Resolve bindings and effective data mode"]
96
+ bindings --> render["praxis-table mounts praxis-filter when advanced filtering is enabled"]
97
+ render --> schema["PraxisFilter uses provided fieldMetadata or resolves schema via /schemas/filtered"]
98
+ schema --> settings["Apply advancedFilters.settings and persisted filter state"]
99
+ settings --> events["Observe submit/change/clear/tags/meta events"]
100
+ events --> backend["Send DTO to /filter or /filter/cursor"]
101
+ ```
102
+
103
+ ## Fluxo de integração recomendado
104
+
105
+ ### 1. Definir o DTO e o schema do filtro
106
+
107
+ O host precisa garantir que a fonte de metadata do filtro e o backend estejam alinhados.
108
+
109
+ Sem isso, o runtime até renderiza o formulário, mas o payload não será previsível.
110
+
111
+ ### 2. Configurar `advancedFilters.settings`
112
+
113
+ Essas chaves são as mais importantes na prática:
114
+
115
+ - `alwaysVisibleFields`: fixa campos prioritários na barra do filtro;
116
+ - `alwaysVisibleFieldMetadataOverrides`: permite ajustar label, `controlType`, clear button e outros detalhes para campos sempre visíveis;
117
+ - `selectedFieldIds`: controla os extras escolhidos pelo usuário;
118
+ - `allowSaveTags`: habilita tags persistidas/visíveis;
119
+ - `changeDebounceMs`: regula a cadência de emissão de `change` e `submit`.
120
+
121
+ ### 3. Definir política do painel avançado
122
+
123
+ Os principais knobs são:
124
+
125
+ - `advancedOpenMode`: `modal` ou `drawer`;
126
+ - `advancedClearButtonsEnabled`: liga ou desliga clear buttons nos campos do formulário avançado;
127
+ - `showFilterSettings`: normalmente atrelado a `enableCustomization` quando o host opta por expor customização runtime.
128
+
129
+ ### 4. Observar os eventos corretos
130
+
131
+ Os eventos principais para integração são:
132
+
133
+ - `submit`: use para busca explícita;
134
+ - `change`: use para filtros reativos com debounce;
135
+ - `clear`: reseta o estado do filtro;
136
+ - `tagsChange`: sincroniza chips persistidos/salvos;
137
+ - `selectedFieldIdsChange`: acompanha customização de campos visíveis;
138
+ - `metaChanged` e `schemaStatusChange`: importantes para observabilidade e reconciliação de schema.
139
+
140
+ ## Exemplo mental de integração
141
+
142
+ O fluxo típico é:
143
+
144
+ 1. host carrega `TableConfig`;
145
+ 2. `praxis-table` resolve o metadata do filtro;
146
+ 3. `praxis-filter` renderiza toolbar compacta e/ou formulário avançado;
147
+ 4. usuário altera valores;
148
+ 5. host observa `submit` ou `change`;
149
+ 6. host envia DTO para `/filter` ou `/filter/cursor`.
150
+
151
+ ## Persistência local
152
+
153
+ O runtime já persiste dois grupos de informação:
154
+
155
+ - estado operacional do filtro em `filter-dto:<key>`;
156
+ - preferências/configuração em `filter-config:<key>`.
157
+
158
+ Isso tem duas implicações:
159
+
160
+ 1. a doc do host precisa deixar claro o papel do `persistenceKey`;
161
+ 2. o reset de preferências precisa considerar DTO e config, não só um deles.
162
+
163
+ ## Estratégia de UX recomendada
164
+
165
+ ### Campos sempre visíveis
166
+
167
+ Use `alwaysVisibleFields` apenas para filtros de alta frequência e leitura rápida:
168
+
169
+ - status;
170
+ - período principal;
171
+ - faixa monetária;
172
+ - texto livre;
173
+ - owner/departamento em operações recorrentes.
174
+
175
+ ### Metadata overrides
176
+
177
+ Use `alwaysVisibleFieldMetadataOverrides` quando o mesmo campo precisar:
178
+
179
+ - de label mais curta;
180
+ - de `controlType` inline canônico;
181
+ - de `clearButton` diferente;
182
+ - de `inlineAutoSize` próprio.
183
+
184
+ ### Debounce
185
+
186
+ Regra prática:
187
+
188
+ - `300ms` é o default saudável;
189
+ - cenários com backend pesado ou selects remotos podem pedir números maiores;
190
+ - evite debounce muito baixo em filtros que disparam chamadas remotas frequentes.
191
+
192
+ ## Tags salvas
193
+
194
+ `allowSaveTags` muda a experiência do filtro, não só a UI dos chips.
195
+
196
+ Quando habilitar:
197
+
198
+ - defina claramente se as tags são só visuais ou se representam presets reais;
199
+ - documente como elas afetam a recuperação do estado na próxima sessão;
200
+ - valide se faz sentido no contexto da sua tabela, porque nem todo filtro enterprise deve permitir salvar seleções ad hoc.
201
+
202
+ ## Erros comuns de integração
203
+
204
+ 1. Configurar `alwaysVisibleFields` com nomes que não existem no schema.
205
+ 2. Misturar nomes de `controlType` fora do contrato publicado com nomes canônicos.
206
+ 3. Persistir estado com `persistenceKey` instável.
207
+ 4. Escutar só `change` e esquecer estratégia de envio ao backend.
208
+ 5. Ativar demasiados campos sempre visíveis e destruir a legibilidade da toolbar.
209
+
210
+ ## Recomendação de rollout
211
+
212
+ Para uma nova tabela enterprise:
213
+
214
+ 1. comece com poucos `alwaysVisibleFields`;
215
+ 2. use overrides só onde a barra compacta realmente precisa;
216
+ 3. valide payload com backend antes de abrir opções avançadas;
217
+ 4. só então ligue tags, settings editor e variantes inline mais complexas.