@praxisui/list 8.0.0-beta.19 → 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.
@@ -0,0 +1,953 @@
1
+ ---
2
+ title: "praxis-list JSON API (Canonical)"
3
+ slug: "praxis-list-json-api"
4
+ doc_type: "api-reference"
5
+ component: "praxis-list"
6
+ document_kind: "json-api-canonical"
7
+ reference_mode: "canonical"
8
+ contract_format: "json"
9
+ contract_source: "runtime-and-code"
10
+ description: "Referencia canonica do contrato JSON do componente praxis-list."
11
+ category: "components"
12
+ sub_category: "list"
13
+ audience:
14
+ - "frontend"
15
+ - "architect"
16
+ - "platform-team"
17
+ level: "advanced"
18
+ status: "active"
19
+ owner: "praxis-ui"
20
+ source_of_truth:
21
+ - "projects/praxis-list/src/lib/models/list-config.model.ts"
22
+ - "projects/praxis-list/src/lib/components/praxis-list.component.ts"
23
+ - "projects/praxis-list/src/lib/components/praxis-list.component.html"
24
+ - "projects/praxis-list/src/lib/components/praxis-list.component.scss"
25
+ - "projects/praxis-list/src/lib/services/list-data.service.ts"
26
+ - "projects/praxis-list/src/lib/services/list-skin.service.ts"
27
+ - "projects/praxis-list/src/lib/utils/template-evaluator.ts"
28
+ - "projects/praxis-list/src/lib/utils/selection-adapter.ts"
29
+ - "projects/praxis-list/src/lib/editors/list-config-editor.component.ts"
30
+ - "projects/praxis-list/src/lib/ai/list-ai.adapter.ts"
31
+ - "projects/praxis-list/src/lib/ai/list-ai-capabilities.ts"
32
+ - "projects/praxis-list/src/lib/ai/list-context-pack.ts"
33
+ source_of_truth_last_verified: "2026-03-19"
34
+ last_updated: "2026-03-19"
35
+ toc: true
36
+ sidebar: true
37
+ tags:
38
+ - "json-api"
39
+ - "canonical-contract"
40
+ - "praxis-list"
41
+ api_stability: "canonical"
42
+ schema_verified: true
43
+ runtime_verified: false
44
+ editor_coverage_verified: false
45
+ runtime_scope: "public"
46
+ legacy_paths_present: false
47
+ has_known_mismatches: true
48
+ related_components: []
49
+ ---
50
+
51
+ # praxis-list
52
+
53
+ Este documento e a referencia canonica da API JSON de praxis-list.
54
+
55
+ ## Summary
56
+
57
+ - Tipo documental: API reference canonica de contrato JSON.
58
+ - Source of truth: runtime e codigo declarados no frontmatter.
59
+ - Objetivo operacional: consulta rapida, auditavel e deterministica sob pressao.
60
+ - Resumo funcional herdado: Referencia canonica da JSON API do `praxis-list`, com foco em:
61
+
62
+ ## Scope and positioning
63
+
64
+ - Escopo: contrato JSON publico e limites de comportamento observavel.
65
+ - Fora de escopo: tutorial de adocao e walkthrough operacional detalhado.
66
+ - Posicionamento: referencia canonicamente governada para consumidores, arquitetos e mantenedores.
67
+
68
+ ## Source of truth
69
+
70
+ | Source | Kind | Notes |
71
+ | -------------------------------------------------------------------- | -------------- | ------------------------------------------------- |
72
+ | projects/praxis-list/src/lib/models/list-config.model.ts | runtime-code | Source de implementacao declarado no repositorio. |
73
+ | projects/praxis-list/src/lib/components/praxis-list.component.ts | runtime-code | Source de implementacao declarado no repositorio. |
74
+ | projects/praxis-list/src/lib/components/praxis-list.component.html | template-style | Source de implementacao declarado no repositorio. |
75
+ | projects/praxis-list/src/lib/components/praxis-list.component.scss | template-style | Source de implementacao declarado no repositorio. |
76
+ | projects/praxis-list/src/lib/services/list-data.service.ts | runtime-code | Source de implementacao declarado no repositorio. |
77
+ | projects/praxis-list/src/lib/services/list-skin.service.ts | runtime-code | Source de implementacao declarado no repositorio. |
78
+ | projects/praxis-list/src/lib/utils/template-evaluator.ts | runtime-code | Source de implementacao declarado no repositorio. |
79
+ | projects/praxis-list/src/lib/utils/selection-adapter.ts | runtime-code | Source de implementacao declarado no repositorio. |
80
+ | projects/praxis-list/src/lib/editors/list-config-editor.component.ts | runtime-code | Source de implementacao declarado no repositorio. |
81
+ | projects/praxis-list/src/lib/ai/list-ai.adapter.ts | runtime-code | Source de implementacao declarado no repositorio. |
82
+ | projects/praxis-list/src/lib/ai/list-ai-capabilities.ts | runtime-code | Source de implementacao declarado no repositorio. |
83
+ | projects/praxis-list/src/lib/ai/list-context-pack.ts | runtime-code | Source de implementacao declarado no repositorio. |
84
+
85
+ ## Rich content convergence
86
+
87
+ - `mapListTemplateToRichContentP0(...)` e a ponte publica e restrita entre a taxonomia atual de templating do `praxis-list` e o vocabulario compartilhado `1.0` de rich content em `@praxisui/core`.
88
+ - O subconjunto promovido nesta fase e intencionalmente pequeno: `text`, `icon`, `image`, `chip -> badge`, `metric` e `compose`.
89
+ - Tipos como `component`, `slot`, `html`, `rating`, `currency` e `date` continuam list-owned e fora do contrato compartilhado `1.0` ate uma promocao semantica explicita.
90
+
91
+ ## Support legend
92
+
93
+ - Active: suportado e observado no runtime atual.
94
+ - Partial: suporte parcial, com restricoes conhecidas.
95
+ - Declared-only: declarado em tipos/schema sem ligacao runtime confirmada.
96
+ - Schema-only: presente em schema/modelo sem confirmacao de execucao.
97
+ - Deprecated: mantido por compatibilidade legada com migracao prevista.
98
+
99
+ ## Contract classification
100
+
101
+ ### Canonical paths (public contract)
102
+
103
+ | Path | Type | Required | Default | Status | Notes |
104
+ | ------------ | ------------- | ------------- | ------- | ------------- | ---------------------------------------------------------------------------- |
105
+ | `id` | not-specified | not-specified | n/a | Declared-only | preservado no contrato, sem efeito direto |
106
+ | `dataSource` | not-specified | not-specified | n/a | Active | origem de dados, query e sort |
107
+ | `layout` | not-specified | not-specified | n/a | Partial | maioria ativa; `stickySectionHeader` e `virtualScroll` sem binding funcional |
108
+ | `skin` | not-specified | not-specified | n/a | Active | classes + css vars + inline style sanitizado |
109
+ | `selection` | not-specified | not-specified | n/a | Active | binding e shape do payload de selecao |
110
+ | `templating` | not-specified | not-specified | n/a | Partial | quase completo; `type='slot'` sem renderer |
111
+ | `actions` | not-specified | not-specified | n/a | Partial | quase completo; `emitPayload` sem consumo no runtime |
112
+ | `i18n` | not-specified | not-specified | n/a | Active | locale/currency para `date/currency` |
113
+ | `ui` | not-specified | not-specified | n/a | Active | busca/sort/range |
114
+ | `export` | not-specified | not-specified | n/a | Active | contrato compartilhado de exportação de coleções |
115
+ | `a11y` | not-specified | not-specified | n/a | Partial | aria ativos; `highContrast/reduceMotion` sem efeito |
116
+ | `events` | not-specified | not-specified | n/a | Declared-only | mapeamentos declarados sem roteamento runtime |
117
+
118
+ ### Supported legacy paths
119
+
120
+ Nenhum path legado suportado foi identificado nesta revisão baseada em evidência textual preservada.
121
+
122
+ ### Internal-only paths
123
+
124
+ | Path | Internal consumer | Runtime presence | Public support | Notes |
125
+ | ----------------------------------- | --------------------------------------------- | ---------------- | -------------- | ----------------------------------------------------- |
126
+ | `praxis-list-config-{componentKey}` | persistência interna (`ASYNC_CONFIG_STORAGE`) | Yes | No | Chave derivada de `listId/componentInstanceId/route`. |
127
+ | `skinScopeId` | isolamento de CSS por instância | Yes | No | Gerado no runtime para escopo de estilos. |
128
+
129
+ ### Experimental paths
130
+
131
+ | Path | Enablement (flag/guard) | Stability | Rollout notes | Notes |
132
+ | ----------------------- | -------------------------------------- | --------- | ----------------------------------------------- | ---------------------------------------------------------------------------- |
133
+ | `templating.features[]` | contrato de feature blocks em evolução | Partial | Cobrir testes de regressão quando ampliar tipos | Estrutura ativa, mas sem cobertura uniforme para todos os tipos de template. |
134
+
135
+ ## Overview
136
+
137
+ Este arquivo foi adaptado para o padrao canonico atual sem remover conteudo tecnico existente. O conteudo detalhado anterior foi preservado para manter rastreabilidade historica e reduzir perda de contexto.
138
+
139
+ ## Public contract surface
140
+
141
+ ### Top-level configuration blocks
142
+
143
+ | Block | Purpose | Required | Merge strategy | Notes |
144
+ | ------------ | --------------------------------------------------- | -------- | -------------- | -------------------------------------------------------------- |
145
+ | `dataSource` | Origem de dados, query, sort e paginação | Yes | deep-merge | Base para `ListDataService`. |
146
+ | `layout` | Modelo visual e paginação do componente | No | deep-merge | `virtualScroll` e `stickySectionHeader` com cobertura parcial. |
147
+ | `skin` | Tema visual com classes, css vars e style inline | No | replace-block | Processado por `ListSkinService`. |
148
+ | `selection` | Estratégia de seleção e integração com formulário | No | deep-merge | Normaliza modo single/multiple e payload de retorno. |
149
+ | `templating` | Slots primário/secundário/meta/trailing | No | deep-merge | Avaliação por template engine + inferência opcional. |
150
+ | `actions` | Ações locais e globais por item | No | replace-array | Inclui confirmação opcional e loading por ação. |
151
+ | `i18n` | Locale/currency para renderizadores `date/currency` | No | deep-merge | Aplica fallback de locale/currency quando ausente. |
152
+ | `ui` | Busca, ordenação e elementos auxiliares de UX | No | deep-merge | Conecta com stream de pesquisa e estado de página. |
153
+
154
+ ### Nested configuration blocks
155
+
156
+ | Path | Type | Required | Default | Constraints | Notes |
157
+ | ------------ | ------------- | ------------- | ------- | ----------------- | ---------------------------------------------------------------------------- |
158
+ | `id` | not-specified | not-specified | n/a | component-defined | preservado no contrato, sem efeito direto |
159
+ | `dataSource` | not-specified | not-specified | n/a | component-defined | origem de dados, query e sort |
160
+ | `layout` | not-specified | not-specified | n/a | component-defined | maioria ativa; `stickySectionHeader` e `virtualScroll` sem binding funcional |
161
+ | `skin` | not-specified | not-specified | n/a | component-defined | classes + css vars + inline style sanitizado |
162
+ | `selection` | not-specified | not-specified | n/a | component-defined | binding e shape do payload de selecao |
163
+ | `templating` | not-specified | not-specified | n/a | component-defined | quase completo; `type='slot'` sem renderer |
164
+ | `actions` | not-specified | not-specified | n/a | component-defined | quase completo; `emitPayload` sem consumo no runtime |
165
+ | `i18n` | not-specified | not-specified | n/a | component-defined | locale/currency para `date/currency` |
166
+ | `ui` | not-specified | not-specified | n/a | component-defined | busca/sort/range |
167
+ | `a11y` | not-specified | not-specified | n/a | component-defined | aria ativos; `highContrast/reduceMotion` sem efeito |
168
+
169
+ ### Input bindings
170
+
171
+ | Binding/Path | Type | Required | Source | Runtime normalization | Notes |
172
+ | --------------------- | -------------------------------- | ------------- | --------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------- |
173
+ | `config` | `PraxisListConfig` | Yes (logical) | component-input | convertido para `ListAuthoringDocument` antes do apply plan | Config projetada de runtime; a autoria canônica é `ListAuthoringDocument`. |
174
+ | `listId` | `string` | Yes | component-input | component key builder | Necessário para escopo de persistência. |
175
+ | `componentInstanceId` | `string \| undefined` | No | component-input | component key scoping | Evita colisão entre instâncias da mesma lista. |
176
+ | `form` | `FormGroup \| null \| undefined` | No | component-input | selection adapter | Integra seleção com controle externo quando configurado. |
177
+ | `enableCustomization` | `boolean` | No | component-input | boolean coercion | Input canônico para habilitar editor/configuração visual em runtime. |
178
+
179
+ ### Output events
180
+
181
+ | Event | Payload | Trigger | Stability | Notes |
182
+ | ----------------- | -------------------- | --------------------------------------------------- | --------- | ------------------------------------ |
183
+ | `itemClick` | `ListItemEvent` | clique (mouse/teclado) em item | Partial | Preservado da documentação anterior. |
184
+ | `actionClick` | `ListActionEvent` | acao local de item (ou global com `emitLocal=true`) | Partial | Preservado da documentação anterior. |
185
+ | `selectionChange` | `ListSelectionEvent` | alteracao de selecao em `mat-selection-list` | Partial | Preservado da documentação anterior. |
186
+ | `exportAction` | `any` | resultado ou erro de exportacao de colecao | Active | Usa `PraxisCollectionExportService`. |
187
+
188
+ ### External side channels
189
+
190
+ | Channel | Direction | Contract | Failure mode | Notes |
191
+ | ----------------------- | ---------------- | ------------------------------------- | ------------ | ------------------------------------------------------ |
192
+ | `ASYNC_CONFIG_STORAGE` | bidirectional | `loadConfig/saveConfig` | fail-open | Persistência de configuração por `listId`/instância. |
193
+ | `SettingsPanelService` | bidirectional | `open(...).applied$/saved$` | fail-open | Canal de edição runtime para `PraxisListConfigEditor`. |
194
+ | `GlobalActionService` | outbound action | `executeRef(globalAction, context)` | fail-soft | Opcional; ausência gera warning e segue fluxo local. |
195
+ | `GLOBAL_DIALOG_SERVICE` | bidirectional | confirmação de ação | fail-open | Opcional; sem serviço, ação segue sem modal central. |
196
+ | `PRAXIS_COLLECTION_EXPORT_PROVIDER` | outbound export | `exportCollection(request)` | fail-fast | Necessário para escopos remotos `filtered/all` e formatos avançados. |
197
+
198
+ ### Host/runtime dependencies
199
+
200
+ | Dependency | Required | Environment | Purpose | Notes |
201
+ | ---------------------- | -------- | -------------------- | -------------------- | ----------------------------------------------------------------- |
202
+ | `ListDataService` | Yes | browser/dev/prod/ssr | fluxo de dados | Stream de itens, seção, loading e paginação. |
203
+ | `ListSkinService` | Yes | browser/dev/prod | skin runtime | Gera classes/estilos sanitizados por instância. |
204
+ | `ASYNC_CONFIG_STORAGE` | Yes | browser/dev/prod | persistência | Salva e restaura config de lista. |
205
+ | `SettingsPanelService` | Yes | browser/dev/prod | editor runtime | Abre editor de configuração com preview/apply/save. |
206
+ | `GenericCrudService` | Optional | browser/dev/prod | inferência de schema | Usado para inferência de templating quando `resourcePath` existe. |
207
+ | `ComponentKeyService` | Yes | browser/dev/prod/ssr | chave de escopo | Determina namespace de persistência e isolamento. |
208
+
209
+ ## Coverage matrix
210
+
211
+ | Surface | Verified | Coverage status | Evidence | Notes |
212
+ | -------------- | -------- | --------------- | ------------------------------------- | ---------------------------------------------------------------------------------- |
213
+ | Runtime | false | Partial | source_of_truth + conteudo preservado | Revisao estrutural concluida; validacao comportamental fina pode exigir follow-up. |
214
+ | Schema/Types | true | Partial | interfaces/modelos citados | Mapeamento formal de todos os campos ainda pode requerer refinamento. |
215
+ | Editor/Tooling | false | Partial | secoes de editor quando presentes | Cobertura de editor/tooling nem sempre confirmada por evidencia direta. |
216
+
217
+ ## Runtime coverage boundaries
218
+
219
+ - Cobertura consolidada com base em documentacao existente e source of truth declarado.
220
+ - Comportamentos fora de evidencia direta foram marcados como not-yet-verified ou Partial.
221
+ - Compatibilidade legada, quando detectada, foi separada em classificacao explicita.
222
+
223
+ ## Resolution model
224
+
225
+ ### Merge order
226
+
227
+ 1. contrato recebido em `@Input() config` ou documento vindo do editor runtime
228
+ 2. hidratação opcional de config persistida (`ASYNC_CONFIG_STORAGE`)
229
+ 3. parse do payload para `ListAuthoringDocument`
230
+ 4. projeção para `PraxisListConfig` via `buildListApplyPlan(...)`
231
+ 5. executor runtime fino para data, seleção, skin, persistência e inferência
232
+
233
+ ### Fallback order
234
+
235
+ config explícita -> config persistida por chave -> config corrente em memória -> comportamento seguro sem persistência.
236
+
237
+ ### Override points
238
+
239
+ - `@Input() config` e `@Input() form`
240
+ - editor runtime (`openConfigEditor`, apply plan)
241
+ - persistência por host (`ASYNC_CONFIG_STORAGE`)
242
+
243
+ ### Runtime normalization
244
+
245
+ - `applyAuthoringPayload()` faz parse, validação, apply plan e executor runtime sem recriar componente.
246
+ - `buildListApplyPlan(...)` também carrega a decisão explícita de inferência de schema; o host só executa essa etapa fina sem inferir a partir de estado runtime arbitrário.
247
+ - `setupSelectionBinding()` adapta shape de seleção para retorno declarativo.
248
+ - `executeSchemaInferenceForPlan()` infere templates apenas quando faltantes e sem sobrescrever contrato explícito.
249
+
250
+ ### Precedence rules
251
+
252
+ - config externa mais recente tem precedência sobre hidratação tardia de storage.
253
+ - editor `saved` persiste e reaplica; `applied` reaplica sem persistir obrigatoriamente.
254
+ - quando `listId` ausente, runtime segue sem persistência e emite warning deduplicado.
255
+
256
+ ## Validation and error semantics
257
+
258
+ ### Validation model
259
+
260
+ | Path/Rule | Validation phase | Behavior on fail | Error code / warning | Notes |
261
+ | ---------------------------------- | ----------------------- | ----------------------------- | ---------------------------------------- | ------------------------------------------------ |
262
+ | `listId` para persistência | init/runtime | warning + disable persistence | `praxis-list:missing-list-id` | Lista continua funcional sem restore/save. |
263
+ | Json Logic `showIf` inválido | runtime evaluate | warning + fallback false | `praxis-list:invalid-show-if` | Evita render incorreto por condição malformada. |
264
+ | `GlobalActionService` indisponível | runtime action dispatch | warning + skip comando global | `praxis-list:global-command-unavailable` | Não interrompe ações locais/emissão de eventos. |
265
+ | inferência de schema falha | startup/runtime | ignore error | n/a | Mantém configuração original sem inferência. |
266
+
267
+ ### Error semantics
268
+
269
+ A maior parte das falhas opera em modo fail-open (persistência, inferência, comandos globais opcionais). O componente prioriza continuidade de renderização e emissão de eventos locais.
270
+
271
+ ### Fail-open / fail-closed behavior
272
+
273
+ | Condition | Mode | Runtime behavior | Consumer impact |
274
+ | --------------------------------- | --------- | ------------------------------------------------ | ---------------------------------- |
275
+ | Falha em `loadConfig/saveConfig` | fail-open | ignora persistência e mantém config ativa | sem perda de renderização |
276
+ | `showIf` inválido | fail-open | item/ação pode ser ocultado com warning | evita quebra de template |
277
+ | comando global não disponível | fail-open | ação global não executa; fluxo local continua | comportamento parcial, sem crash |
278
+ | contrato de seleção inconsistente | fail-soft | adapter normaliza payload para formato suportado | pode reduzir fidelidade do payload |
279
+
280
+ ### Invalid or unknown field handling
281
+
282
+ - Campos desconhecidos: comportamento depende da estrategia do componente (ignore, warn ou reject).
283
+ - Campos invalidos: podem gerar fallback, warning ou falha conforme implementacao.
284
+ - Registrar divergencias observadas em Known limitations and mismatches.
285
+
286
+ ### Runtime warnings vs hard failures
287
+
288
+ | Condition | Severity | Observability | Consumer action |
289
+ | --------------------------------- | -------- | -------------------------- | ---------------------------------------------- |
290
+ | partial-or-declared-only-coverage | warning | logs/eventos do componente | confirmar ligacao runtime antes de uso critico |
291
+
292
+ ## Detailed API
293
+
294
+ ### Preserved technical reference (normalized from previous revision)
295
+
296
+ Referencia canonica da JSON API do `praxis-list`, com foco em:
297
+
298
+ - cobrir 100% do contrato `PraxisListConfig` aceito hoje;
299
+ - separar com clareza o que esta `Active`, `Partial` e `Declared-only`;
300
+ - explicar como a lista interage com o ecossistema Praxis (data, skin, settings panel, AI e acoes globais).
301
+
302
+ Legenda de suporte:
303
+
304
+ - `Active`: ligado e observavel no runtime atual.
305
+ - `Partial`: parcialmente ligado (subconjunto funcional).
306
+ - `Declared-only`: existe no contrato, sem consumo direto no runtime atual.
307
+
308
+ ### Table of contents
309
+
310
+ - [Overview](#overview)
311
+ - [Porque este componente e diferente](#porque-este-componente-e-diferente)
312
+ - [Pitch de 30 segundos (valor)](#pitch-de-30-segundos-valor)
313
+ - [Mapa de contrato e superficies](#mapa-de-contrato-e-superficies)
314
+ - [Integracao com ecossistema Praxis](#integracao-com-ecossistema-praxis)
315
+ - [Checklist corporativo pre-flight](#checklist-corporativo-pre-flight)
316
+ - [API](#api)
317
+ - [Component inputs](#component-inputs)
318
+ - [Component outputs](#component-outputs)
319
+ - [Data mode and flow](#data-mode-and-flow)
320
+ - [Persistencia e identidade](#persistencia-e-identidade)
321
+ - [PraxisListConfig top-level](#praxislistconfig-top-level)
322
+ - [JSON coverage matrix (top-level)](#json-coverage-matrix-top-level)
323
+ - [DataSource API](#datasource-api)
324
+ - [Layout API](#layout-api)
325
+ - [Skin API](#skin-api)
326
+ - [Selection API](#selection-api)
327
+ - [Templating API (deep dive)](#templating-api-deep-dive)
328
+ - [Actions API](#actions-api)
329
+ - [UI, i18n, a11y e events](#ui-i18n-a11y-e-events)
330
+ - [Expressoes suportadas (`expr` e `showIf`)](#expressoes-suportadas-expr-e-showif)
331
+ - [Settings Panel e AI assistant](#settings-panel-e-ai-assistant)
332
+ - [Complete JSON path index (cobertura total)](#complete-json-path-index-cobertura-total)
333
+ - [Styling](#styling)
334
+ - [Examples](#examples)
335
+ - [Known limitations and mismatches](#known-limitations-and-mismatches)
336
+ - [Source references](#source-references)
337
+
338
+ ### Overview
339
+
340
+ `praxis-list` e um runtime schema-driven para listas visuais em tres variantes:
341
+
342
+ 1. `list`
343
+ 2. `cards`
344
+ 3. `tiles`
345
+
346
+ O comportamento de runtime continua projetado a partir de `PraxisListConfig`, mas a autoria canônica e governada por `ListAuthoringDocument`.
347
+
348
+ Fluxo simplificado:
349
+
350
+ 1. Recebe `config`.
351
+ 2. Resolve origem de dados (local ou remota).
352
+ 3. Aplica skin (classes + CSS vars + inline style sanitizado).
353
+ 4. Renderiza slots de templating (`leading`, `primary`, `meta`, etc.).
354
+ 5. Executa acoes por item (local/global) e emite eventos para host.
355
+
356
+ #### Porque este componente e diferente
357
+
358
+ `praxis-list` combina render declarativo e operacao de dados real no mesmo contrato:
359
+
360
+ - suporta local e remoto com pipeline unico;
361
+ - possui sistema de templating por slot com tipos visuais;
362
+ - integra skin tokenizada, editor runtime e assistente AI;
363
+ - permite acoes globais via catalogo do host sem acoplamento direto da lista.
364
+
365
+ #### Pitch de 30 segundos (valor)
366
+
367
+ Uma lista que funciona como plataforma de experiencia: layout, estilo, templating, dados e acoes ficam no JSON, e o runtime adapta list/cards/tiles com o mesmo contrato.
368
+
369
+ - **Entrega rapida**: altera UX por configuracao.
370
+ - **Padrao corporativo**: mesmo contrato em telas diferentes.
371
+ - **Escalavel**: composicao com actions globais, editor e AI sem fork de componente.
372
+
373
+ #### Mapa de contrato e superficies
374
+
375
+ Quatro superficies governam o componente:
376
+
377
+ 1. **Documento de autoria (`ListAuthoringDocument`)**: envelope persistivel e canônico para editor visual, editor JSON, host runtime e fluxos futuros de IA/playground.
378
+ 2. **Config canônica projetada (`PraxisListConfig`)**: dados, layout, skin, selecao, templating, acoes e UI.
379
+ 3. **Inputs externos**: `listId`, `componentInstanceId`, `form` e `enableCustomization`.
380
+ 4. **Outputs**: `itemClick`, `actionClick`, `selectionChange`, `exportAction`.
381
+ 5. **Side channels**: persistencia assinc, settings panel, global action bus e AI adapter.
382
+
383
+ #### Integracao com ecossistema Praxis
384
+
385
+ | Componente/Servico | Papel | Como se conecta |
386
+ | ---------------------------------------------- | ------------------------------------ | ------------------------------------------------------------------------------------ |
387
+ | `ListDataService` | pipeline de dados local/remoto | `dataSource.data/resourcePath/query/sort` |
388
+ | `ListSkinService` | classes e CSS dinamico | `skin.*` + `layout.density/itemSpacing/model/lines` |
389
+ | `SettingsPanelService` | edicao runtime | `openConfigEditor()` com `PraxisListConfigEditor` retornando `ListAuthoringDocument` |
390
+ | `PraxisListConfigEditor` | autoria visual do documento | tabs visuais + aba JSON canônica |
391
+ | `GlobalActionService` | acoes globais estruturadas | `actions[].globalAction` |
392
+ | `GLOBAL_DIALOG_SERVICE` | confirmacao de acao | `actions[].confirmation` |
393
+ | `ASYNC_CONFIG_STORAGE` | persistencia de config | `praxis-list-config-${componentKeyId}` |
394
+ | `ComponentKeyService` | identidade de instancia | `listId + componentInstanceId + route` |
395
+ | `PraxisCollectionExportService` | exportação de coleção | CSV/JSON local; provider para export remoto/formatos avançados |
396
+ | `PraxisAiAssistantComponent` + `ListAiAdapter` | copiloto para patches JSON | ativo com `enableCustomization=true` |
397
+ | `GenericCrudService` | dados remotos e inferencia de schema | `/filter` + fallback `getAll` + `getSchema` |
398
+
399
+ #### Checklist corporativo pre-flight
400
+
401
+ Antes de liberar para producao:
402
+
403
+ - Defina `listId` estavel por tela.
404
+ - Em multi-instancia, defina `componentInstanceId`.
405
+ - Se remoto: valide `resourcePath` e politica de fallback (`/filter` -> `getAll`).
406
+ - Em `actions[].globalAction`, aplique governanca de acoes globais no host.
407
+ - Para `type='html'`, mantenha origem confiavel do conteudo.
408
+ - Nao trate `showIf` como autorizacao; backend continua soberano.
409
+
410
+ ### API
411
+
412
+ #### Component inputs
413
+
414
+ | Input | Tipo | Required | Default | O que controla | Runtime |
415
+ | --------------------- | -------------------------------- | ------------ | ------------------ | -------------------------- | ------- |
416
+ | `config` | `PraxisListConfig` | Yes (logico) | sem default seguro | Contrato principal | Active |
417
+ | `listId` | `string` | Yes | sem default | identidade de persistencia | Active |
418
+ | `componentInstanceId` | `string \| undefined` | No | `undefined` | isolamento de instancias | Active |
419
+ | `form` | `FormGroup \| null \| undefined` | No | `undefined` | binding de selecao externa | Active |
420
+ | `enableCustomization` | `boolean` | No | `false` | editor + AI assistant | Active |
421
+
422
+ #### Component outputs
423
+
424
+ | Output | Payload | Quando dispara |
425
+ | ----------------- | -------------------- | --------------------------------------------------- |
426
+ | `itemClick` | `ListItemEvent` | clique (mouse/teclado) em item |
427
+ | `actionClick` | `ListActionEvent` | acao local de item (ou global com `emitLocal=true`) |
428
+ | `selectionChange` | `ListSelectionEvent` | alteracao de selecao em `mat-selection-list` |
429
+ | `exportAction` | `any` | exportacao concluida, delegada ou com erro |
430
+
431
+ #### Data mode and flow
432
+
433
+ Resolucao do modo de dados em `ListDataService.stream()`:
434
+
435
+ 1. Se `dataSource.data` existe, usa modo local.
436
+ 2. Senao, se `dataSource.resourcePath` e `GenericCrudService` existem, usa modo remoto.
437
+ 3. Senao, retorna vazio.
438
+
439
+ Regras operacionais:
440
+
441
+ - Local tem precedencia sobre remoto quando ambos estao presentes.
442
+ - Remoto usa `filter(query, pageable)`.
443
+ - Em erro no `/filter`, faz fallback para `getAll()` com warning deduplicado.
444
+ - Busca (`ui.showSearch`) aplica debounce de `300ms` e exige `ui.searchField`.
445
+ - Controles de pagina/sort/search no template aparecem apenas quando `dataSource.resourcePath` esta definido.
446
+
447
+ Matriz de decisao (runtime atual):
448
+
449
+ | `dataSource.data` | `dataSource.resourcePath` | Modo resolvido | Superficie principal | Pipeline efetivo |
450
+ | ----------------- | ------------------------- | -------------- | ------------------------------------- | ------------------------------------------------- |
451
+ | `array` | qualquer valor | `local` | lista/cards/tiles | local (`data` em memoria) |
452
+ | `null/undefined` | preenchido | `remote` | lista/cards/tiles + controles remotos | `filter(query, pageable)` com fallback `getAll()` |
453
+ | `null/undefined` | vazio/ausente | `empty` | empty state | sem pipeline de dados |
454
+
455
+ Regra critica de autoria:
456
+
457
+ - Se o host enviar `data` e `resourcePath` ao mesmo tempo, o runtime usa `data` (modo local).
458
+ - Se a intencao for remoto obrigatorio, nao envie `data` no mesmo payload.
459
+
460
+ #### Persistencia e identidade
461
+
462
+ - Chave persistida: `praxis-list-config-${componentKeyId}`.
463
+ - `componentKeyId` deriva de:
464
+ - `componentType='praxis-list'`
465
+ - `listId`
466
+ - `componentInstanceId`
467
+ - contexto de rota.
468
+
469
+ Sem `listId` valido:
470
+
471
+ - persistencia e ignorada;
472
+ - warning ocorre em dev mode (`LoggerService.warnOnce`).
473
+
474
+ #### PraxisListConfig top-level
475
+
476
+ ```ts
477
+ interface PraxisListConfig {
478
+ id?: string;
479
+ dataSource?: {...};
480
+ layout?: {...};
481
+ skin?: {...};
482
+ selection?: {...};
483
+ interaction?: {...};
484
+ templating?: {...};
485
+ expansion?: {...};
486
+ actions?: Array<...>;
487
+ i18n?: {
488
+ locale?: string;
489
+ currency?: string;
490
+ };
491
+ ui?: {...};
492
+ export?: {...};
493
+ a11y?: {...};
494
+ events?: {...};
495
+ }
496
+ ```
497
+
498
+ #### JSON coverage matrix (top-level)
499
+
500
+ | JSON path | Status | Runtime notes |
501
+ | ------------- | ------------- | ---------------------------------------------------------------------------- |
502
+ | `id` | Declared-only | preservado no contrato, sem efeito direto |
503
+ | `dataSource` | Active | origem de dados, query e sort |
504
+ | `layout` | Partial | maioria ativa; `stickySectionHeader` e `virtualScroll` sem binding funcional |
505
+ | `skin` | Active | classes + css vars + inline style sanitizado |
506
+ | `selection` | Active | binding e shape do payload de selecao |
507
+ | `interaction` | Partial | expansao inline V1; apenas `variant=list` |
508
+ | `templating` | Partial | quase completo; `type='slot'` sem renderer |
509
+ | `expansion` | Partial | detail row tipada da V1 |
510
+ | `actions` | Partial | quase completo; `emitPayload` sem consumo no runtime |
511
+ | `i18n` | Active | locale/currency para `date/currency` |
512
+ | `ui` | Active | busca/sort/range |
513
+ | `export` | Active | exportação via contrato compartilhado de coleções |
514
+ | `a11y` | Partial | aria ativos; `highContrast/reduceMotion` sem efeito |
515
+ | `events` | Declared-only | mapeamentos declarados sem roteamento runtime |
516
+
517
+ #### DataSource API
518
+
519
+ | Caminho | Status | Observacao |
520
+ | ------------------------- | ------ | ------------------------------------ |
521
+ | `dataSource.data` | Active | modo local, total = tamanho do array |
522
+ | `dataSource.resourcePath` | Active | modo remoto |
523
+ | `dataSource.query` | Active | query inicial + base da busca |
524
+ | `dataSource.sort` | Active | sort inicial do pageable remoto |
525
+
526
+ #### Layout API
527
+
528
+ | Caminho | Status | Observacao |
529
+ | ---------------------------- | ------------- | ---------------------------------- |
530
+ | `layout.variant` | Active | `list/cards/tiles` |
531
+ | `layout.density` | Active | classe `density-*` |
532
+ | `layout.itemSpacing` | Active | classe `item-spacing-*` |
533
+ | `layout.lines` | Active | linhas de texto + classe `lines-*` |
534
+ | `layout.dividers` | Active | divisores no modo `list` |
535
+ | `layout.model` | Active | classe `model-*` |
536
+ | `layout.groupBy` | Active | agrupamento em `sections$` |
537
+ | `layout.pageSize` | Active | page size inicial |
538
+ | `layout.stickySectionHeader` | Declared-only | sem sticky runtime |
539
+ | `layout.virtualScroll` | Declared-only | sem virtual scroll runtime |
540
+
541
+ #### Skin API
542
+
543
+ | Caminho | Status | Observacao |
544
+ | --------------------- | ------ | ----------------------------------- |
545
+ | `skin.type` | Active | classe `skin-*` |
546
+ | `skin.gradient.from` | Active | css var |
547
+ | `skin.gradient.to` | Active | css var |
548
+ | `skin.gradient.angle` | Active | css var |
549
+ | `skin.radius` | Active | css var |
550
+ | `skin.shadow` | Active | css var |
551
+ | `skin.border` | Active | css var |
552
+ | `skin.backdropBlur` | Active | css var |
553
+ | `skin.class` | Active | classe extra no host |
554
+ | `skin.inlineStyle` | Active | css inline com sanitizacao + escopo |
555
+
556
+ Notas de seguranca:
557
+
558
+ - sanitizacao remove `url(`, `@import`, `expression(`, `behavior:` e comentarios CSS;
559
+ - regras sao escopadas ao seletor da instancia para reduzir vazamento de estilo.
560
+
561
+ #### Selection API
562
+
563
+ | Caminho | Status | Observacao |
564
+ | --------------------------- | ------ | -------------------------------------------------- |
565
+ | `selection.mode` | Active | `none/single/multiple` |
566
+ | `selection.formControlName` | Active | binding em form externo |
567
+ | `selection.formControlPath` | Active | binding em path do form externo |
568
+ | `selection.compareBy` | Active | gera `ids` e trackBy custom |
569
+ | `selection.return` | Active | `value/item/id` no payload `selectionChange.value` |
570
+
571
+ #### Export API
572
+
573
+ | Caminho | Status | Observacao |
574
+ | ---------------------------------- | ------ | ---------- |
575
+ | `export.enabled` | Active | Renderiza menu de exportação da lista. |
576
+ | `export.formats` | Active | `csv/json/excel/pdf/print`; CSV/JSON têm fallback local. |
577
+ | `export.general.scope` | Active | `auto/selected/filtered/currentPage/all`; `auto` prioriza seleção. |
578
+ | `export.general.includeHeaders` | Active | Controla cabeçalho em exportações tabulares. |
579
+ | `export.general.maxRows` | Active | Limita linhas no fallback local. |
580
+ | `export.general.defaultFileName` | Active | Nome base do arquivo gerado. |
581
+ | `export.general.includeFields` | Active | Lista de paths exportáveis ou `all` para inferência por chaves. |
582
+ | `export.general.applyFormatting` | Active | Mantido para paridade com o contrato compartilhado. |
583
+
584
+ Escopos remotos `filtered`/`all` e formatos `excel/pdf/print` exigem provider em `@praxisui/core`.
585
+
586
+ Nota critica de integridade:
587
+
588
+ - quando `interaction.expandable=true` e `selection.mode !== 'none'`, o runtime canonico coerces `interaction.expandTrigger` para `icon`;
589
+ - essa coercao e aplicada na normalizacao do contrato antes do runtime para eliminar ambiguidade entre selecionar e expandir a mesma linha;
590
+ - a combinacao evita ambiguidade operacional entre selecionar linha e expandir detail row.
591
+ - quando `interaction.expandable` nao estiver ativo, a normalizacao nao deve materializar `expandTrigger` nem `expandMode`.
592
+
593
+ #### Interaction API
594
+
595
+ | Caminho | Status | Observacao |
596
+ | --------------------------- | ------- | -------------------------------------------------------------------------------------- |
597
+ | `interaction.expandable` | Active | habilita expansao inline V1 |
598
+ | `interaction.expandTrigger` | Partial | `row/icon/row+icon`; com selecao ativa, a normalizacao canonica o converte para `icon` |
599
+ | `interaction.expandMode` | Active | `single/multiple` |
600
+
601
+ Escopo normativo da V1:
602
+
603
+ - suportado apenas quando `layout.variant = 'list'`;
604
+ - fora de `list`, o authoring gera diagnostico de erro e o runtime nao materializa detail row.
605
+ - no exemplo oficial da lib, o cenario `executive-expansion` fixa `variant = list`, `lines = 2` e `selection.mode = none` para manter aderencia a referencia visual e evitar controles inertes.
606
+
607
+ #### Templating API (deep dive)
608
+
609
+ Slots suportados:
610
+
611
+ - `leading`, `primary`, `secondary`, `meta`, `trailing`, `sectionHeader`, `emptyState`.
612
+
613
+ Tipos funcionais no runtime:
614
+
615
+ - `text`, `icon`, `image`, `chip`, `rating`, `currency`, `date`, `html`.
616
+
617
+ Tipo declarado sem renderer dedicado:
618
+
619
+ - `slot`.
620
+
621
+ | Caminho | Status | Observacao |
622
+ | -------------------------------------- | ------- | ------------------------------------------ |
623
+ | `templating.<slot>.type` | Partial | `slot` sem renderer dedicado |
624
+ | `templating.<slot>.expr` | Active | avaliado por `evaluateTemplate`/`evalSlot` |
625
+ | `templating.<slot>.class` | Active | classes por slot |
626
+ | `templating.<slot>.style` | Active | estilo inline por slot |
627
+ | `templating.<slot>.color` | Active | chip/icon/rating |
628
+ | `templating.<slot>.variant` | Active | chip filled/outlined |
629
+ | `templating.<slot>.props.rating.max` | Active | limite de estrelas |
630
+ | `templating.<slot>.props.rating.size` | Active | tamanho de icone |
631
+ | `templating.<slot>.props.rating.color` | Active | cor rating |
632
+ | `templating.<slot>.imageAlt` | Active | alt de imagem |
633
+ | `templating.<slot>.badge.expr` | Active | badge em template de imagem |
634
+ | `templating.<slot>.badge.color` | Active | cor badge |
635
+ | `templating.<slot>.badge.variant` | Active | variante badge |
636
+ | `templating.metaPlacement` | Active | `side`/`line` |
637
+ | `templating.metaPrefixIcon` | Active | icone prefixado em meta textual |
638
+ | `templating.statusPosition` | Active | `inline`/`top-right` em cards/tiles |
639
+ | `templating.chipColorMap` | Active | valor -> cor |
640
+ | `templating.chipLabelMap` | Active | valor -> label |
641
+ | `templating.iconColorMap` | Active | status/icone -> cor |
642
+ | `templating.features` | Active | linha de features |
643
+ | `templating.featuresVisible` | Active | mostra/oculta features |
644
+ | `templating.featuresMode` | Active | `icons+labels/icons-only/labels-only` |
645
+ | `templating.skeleton.count` | Active | skeleton durante loading |
646
+
647
+ #### Expansion API
648
+
649
+ | Caminho | Status | Observacao |
650
+ | --------------------------------- | ------ | ---------------------------------------- |
651
+ | `expansion.sections` | Active | array de secoes da detail row |
652
+ | `expansion.sections[].id` | Active | identidade da secao |
653
+ | `expansion.sections[].title` | Active | titulo visivel da secao |
654
+ | `expansion.sections[].type` | Active | `info-list/chip-list/timeline/key-value` |
655
+ | `expansion.sections[].itemsExpr` | Active | expr de colecao/objeto por item |
656
+ | `expansion.sections[].emptyLabel` | Active | mensagem vazia por secao |
657
+
658
+ Notas de UX/WCAG:
659
+
660
+ - `aria-expanded` e `aria-controls` ficam no owner real do trigger (`row` ou `icon`);
661
+ - com `selection.mode !== 'none'`, a selecao continua dona da linha e a expansao passa a ser acionada apenas pelo icone;
662
+ - a V1 nao suporta markup arbitrario nem detail builders livres;
663
+ - `cards` e `tiles` permanecem fora de escopo.
664
+ - o scenario `executive-expansion` da doc page e uma composicao editorial canonica de validacao visual; campos como `balanceDisplay`, `limitDisplay`, `usageLabel`, `riskDisplay` e `riskLabel` pertencem ao dataset de exemplo, nao ao contrato base de `PraxisListConfig`.
665
+
666
+ #### Actions API
667
+
668
+ | Caminho | Status | Observacao |
669
+ | -------------------------------- | ------------- | ----------------------------------------------------------- |
670
+ | `actions[].id` | Active | identificador da acao |
671
+ | `actions[].icon` | Active | icone |
672
+ | `actions[].label` | Active | label/aria-label |
673
+ | `actions[].color` | Active | tema/cor custom |
674
+ | `actions[].kind` | Active | `icon` ou `button` |
675
+ | `actions[].buttonVariant` | Active | `stroked/raised/flat` |
676
+ | `actions[].showIf` | Active | condição Json Logic avaliada no contexto `row` |
677
+ | `actions[].emitPayload` | Declared-only | sem uso no payload de `actionClick` atual |
678
+ | `actions[].globalAction` | Active | integra com `GlobalActionService.executeRef`; suporta `navigation.openRoute` para navegação interna canônica |
679
+ | `actions[].globalAction.actionId` | Active | identificador canonico da acao global |
680
+ | `actions[].globalAction.payload` | Active | template/JSON resolvido recursivamente, inclusive `item.id` em rotas internas |
681
+ | `actions[].emitLocal` | Active | emite `actionClick` mesmo com acao global |
682
+ | `actions[].showLoading` | Active | spinner + disable durante execucao |
683
+ | `actions[].confirmation.title` | Active | dialogo de confirmacao |
684
+ | `actions[].confirmation.message` | Active | dialogo de confirmacao |
685
+ | `actions[].confirmation.type` | Active | `danger/warning/info` |
686
+
687
+ Semantica de execucao:
688
+
689
+ 1. valida confirmacao (quando configurada);
690
+ 2. executa acao global estruturada (se `globalAction` estiver presente), incluindo `navigation.openRoute` para abrir rotas internas com contexto do item;
691
+ 3. remove loading;
692
+ 4. emite `actionClick` conforme regra `emitLocal`.
693
+
694
+ #### UI, i18n, a11y e events
695
+
696
+ | Caminho | Status | Observacao |
697
+ | ------------------------ | ------------- | --------------------------------------- |
698
+ | `ui.showSearch` | Active | input de busca (somente quando remoto) |
699
+ | `ui.searchField` | Active | campo da query de busca |
700
+ | `ui.searchPlaceholder` | Active | label do input |
701
+ | `ui.showSort` | Active | seletor de sort (somente quando remoto) |
702
+ | `ui.sortOptions` | Active | `string` ou `{label,value}` |
703
+ | `ui.showRange` | Active | range `X-Y de total` |
704
+ | `i18n.locale` | Active | formatacao date/number |
705
+ | `i18n.currency` | Active | formatacao currency |
706
+ | `a11y.ariaLabel` | Active | `aria-label` do root |
707
+ | `a11y.ariaLabelledBy` | Active | `aria-labelledby` do root |
708
+ | `a11y.highContrast` | Declared-only | sem binding funcional |
709
+ | `a11y.reduceMotion` | Declared-only | sem binding funcional |
710
+ | `events.itemClick` | Declared-only | sem roteamento dinamico |
711
+ | `events.actionClick` | Declared-only | sem roteamento dinamico |
712
+ | `events.selectionChange` | Declared-only | sem roteamento dinamico |
713
+ | `events.exportAction` | Declared-only | sem roteamento dinamico |
714
+ | `events.loaded` | Declared-only | sem roteamento dinamico |
715
+
716
+ #### Superfícies de expressão (`expr` e `showIf`)
717
+
718
+ ##### `templating.*.expr`
719
+
720
+ Suporte principal:
721
+
722
+ - placeholders: `${item.campo}`;
723
+ - pipes em placeholder: `bool`, `date`, `map`, `number`;
724
+ - pipe top-level `bool` no expr completo.
725
+
726
+ Exemplos validos:
727
+
728
+ - `${item.active|bool:Ativo:Inativo}`
729
+ - `${item.createdAt|date:pt-BR:short}`
730
+ - `${item.status|map:done=Concluido;pending=Pendente}`
731
+ - `${item.total|number:pt-BR:compact}`
732
+
733
+ ##### `actions[].showIf`
734
+
735
+ Usa Json Logic canônico com contexto `row`.
736
+
737
+ Exemplos válidos:
738
+
739
+ - `{"==":[{"var":"row.status"},"done"]}`
740
+ - `{"and":[{"var":"row.active"},{"!":{"var":"row.archived"}}]}`
741
+
742
+ Política de erro:
743
+
744
+ - fail-closed (ação fica oculta);
745
+ - warning apenas em dev mode, deduplicado.
746
+
747
+ #### Settings Panel e AI assistant
748
+
749
+ Quando `enableCustomization=true`:
750
+
751
+ - componente exibe botao de edicao + `praxis-ai-assistant`;
752
+ - `openConfigEditor()` abre `PraxisListConfigEditor`;
753
+ - `applied$` e `saved$` aplicam config em runtime;
754
+ - `saved$` persiste no storage quando chave valida existe.
755
+
756
+ AI:
757
+
758
+ - `ListAiAdapter` aplica patches de config sem recrear componente;
759
+ - capability/context packs orientam mudancas por path JSON.
760
+
761
+ #### Complete JSON path index (cobertura total)
762
+
763
+ | JSON path | Status | Observacao |
764
+ | -------------------------------------- | ------------- | -------------------------------------- |
765
+ | `id` | Declared-only | sem binding direto |
766
+ | `dataSource` | Active | bloco de dados |
767
+ | `dataSource.data` | Active | local mode |
768
+ | `dataSource.resourcePath` | Active | remote mode |
769
+ | `dataSource.query` | Active | query remota |
770
+ | `dataSource.sort` | Active | sort remoto |
771
+ | `layout` | Partial | bloco visual/estrutura |
772
+ | `layout.variant` | Active | list/cards/tiles |
773
+ | `layout.density` | Active | classe host |
774
+ | `layout.itemSpacing` | Active | gap vertical entre itens + classe host |
775
+ | `layout.lines` | Active | linhas + classe |
776
+ | `layout.dividers` | Active | divisor no list |
777
+ | `layout.model` | Active | classe host |
778
+ | `layout.groupBy` | Active | agrupamento |
779
+ | `layout.stickySectionHeader` | Declared-only | sem sticky runtime |
780
+ | `layout.virtualScroll` | Declared-only | sem virtual runtime |
781
+ | `layout.pageSize` | Active | pagina remota |
782
+ | `skin` | Active | bloco de skin |
783
+ | `skin.type` | Active | classe skin |
784
+ | `skin.gradient` | Active | vars gradiente |
785
+ | `skin.gradient.from` | Active | var |
786
+ | `skin.gradient.to` | Active | var |
787
+ | `skin.gradient.angle` | Active | var |
788
+ | `skin.radius` | Active | var |
789
+ | `skin.shadow` | Active | var |
790
+ | `skin.border` | Active | var |
791
+ | `skin.backdropBlur` | Active | var |
792
+ | `skin.class` | Active | classe extra |
793
+ | `skin.inlineStyle` | Active | css inline sanitizado |
794
+ | `selection` | Active | bloco de selecao |
795
+ | `selection.mode` | Active | none/single/multiple |
796
+ | `selection.formControlName` | Active | binding form |
797
+ | `selection.formControlPath` | Active | binding form |
798
+ | `selection.compareBy` | Active | ids/trackBy |
799
+ | `selection.return` | Active | value/item/id |
800
+ | `interaction` | Partial | bloco de expansao inline V1 |
801
+ | `interaction.expandable` | Active | toggle da expansao |
802
+ | `interaction.expandTrigger` | Partial | coerced para `icon` quando ha selecao |
803
+ | `interaction.expandMode` | Active | single/multiple |
804
+ | `templating` | Partial | bloco de slots |
805
+ | `templating.leading` | Active | slot |
806
+ | `templating.primary` | Active | slot |
807
+ | `templating.secondary` | Active | slot |
808
+ | `templating.meta` | Active | slot |
809
+ | `templating.trailing` | Active | slot |
810
+ | `templating.sectionHeader` | Active | slot |
811
+ | `templating.emptyState` | Active | slot |
812
+ | `templating.<slot>.type` | Partial | `slot` sem renderer |
813
+ | `templating.<slot>.expr` | Active | avaliador |
814
+ | `templating.<slot>.class` | Active | estilo |
815
+ | `templating.<slot>.style` | Active | estilo |
816
+ | `templating.<slot>.color` | Active | chip/icon/rating |
817
+ | `templating.<slot>.variant` | Active | chip variant |
818
+ | `templating.<slot>.props.rating.max` | Active | rating |
819
+ | `templating.<slot>.props.rating.size` | Active | rating |
820
+ | `templating.<slot>.props.rating.color` | Active | rating |
821
+ | `templating.<slot>.imageAlt` | Active | alt imagem |
822
+ | `templating.<slot>.badge.expr` | Active | badge |
823
+ | `templating.<slot>.badge.color` | Active | badge |
824
+ | `templating.<slot>.badge.variant` | Active | badge |
825
+ | `templating.metaPlacement` | Active | side/line |
826
+ | `templating.metaPrefixIcon` | Active | prefix icon |
827
+ | `templating.statusPosition` | Active | inline/top-right |
828
+ | `templating.chipColorMap` | Active | map cor |
829
+ | `templating.chipLabelMap` | Active | map label |
830
+ | `templating.iconColorMap` | Active | map cor icon |
831
+ | `templating.features` | Active | features row |
832
+ | `templating.features[].icon` | Active | feature icon |
833
+ | `templating.features[].expr` | Active | feature expr |
834
+ | `templating.features[].class` | Active | feature class |
835
+ | `templating.features[].style` | Active | feature style |
836
+ | `templating.featuresVisible` | Active | toggle features |
837
+ | `templating.featuresMode` | Active | icons+labels/icons-only/labels-only |
838
+ | `templating.skeleton` | Active | skeleton bloco |
839
+ | `templating.skeleton.count` | Active | skeleton count |
840
+ | `expansion` | Partial | detail row governada |
841
+ | `expansion.sections` | Active | secoes do detail row |
842
+ | `expansion.sections[].id` | Active | id |
843
+ | `expansion.sections[].title` | Active | title |
844
+ | `expansion.sections[].type` | Active | info-list/chip-list/timeline/key-value |
845
+ | `expansion.sections[].itemsExpr` | Active | expr |
846
+ | `expansion.sections[].emptyLabel` | Active | empty state da secao |
847
+ | `actions` | Partial | bloco de acoes |
848
+ | `actions[].id` | Active | id |
849
+ | `actions[].icon` | Active | icon |
850
+ | `actions[].label` | Active | label |
851
+ | `actions[].color` | Active | color |
852
+ | `actions[].kind` | Active | icon/button |
853
+ | `actions[].buttonVariant` | Active | raised/flat/stroked |
854
+ | `actions[].showIf` | Active | visibilidade |
855
+ | `actions[].emitPayload` | Declared-only | sem efeito runtime |
856
+ | `actions[].globalAction` | Active | acao global estruturada |
857
+ | `actions[].globalAction.actionId` | Active | identificador canonico da acao global |
858
+ | `actions[].globalAction.payload` | Active | payload template/json |
859
+ | `actions[].emitLocal` | Active | emissao local |
860
+ | `actions[].showLoading` | Active | spinner/desabilita |
861
+ | `actions[].confirmation` | Active | confirmacao |
862
+ | `actions[].confirmation.title` | Active | confirmacao |
863
+ | `actions[].confirmation.message` | Active | confirmacao |
864
+ | `actions[].confirmation.type` | Active | danger/warning/info |
865
+ | `i18n` | Active | bloco i18n |
866
+ | `i18n.locale` | Active | locale |
867
+ | `i18n.currency` | Active | currency |
868
+ | `ui` | Active | bloco ui |
869
+ | `ui.showSearch` | Active | input busca |
870
+ | `ui.searchField` | Active | query field |
871
+ | `ui.searchPlaceholder` | Active | label busca |
872
+ | `ui.showSort` | Active | select sort |
873
+ | `ui.sortOptions` | Active | opcoes sort |
874
+ | `ui.showRange` | Active | range/total |
875
+ | `a11y` | Partial | acessibilidade |
876
+ | `a11y.ariaLabel` | Active | aria-label |
877
+ | `a11y.ariaLabelledBy` | Active | aria-labelledby |
878
+ | `a11y.highContrast` | Declared-only | sem binding |
879
+ | `a11y.reduceMotion` | Declared-only | sem binding |
880
+ | `events` | Declared-only | declarativo |
881
+ | `events.itemClick` | Declared-only | sem roteamento runtime |
882
+ | `events.actionClick` | Declared-only | sem roteamento runtime |
883
+ | `events.selectionChange` | Declared-only | sem roteamento runtime |
884
+ | `events.exportAction` | Declared-only | sem roteamento runtime |
885
+ | `events.loaded` | Declared-only | sem roteamento runtime |
886
+
887
+ ### Styling
888
+
889
+ Camadas de estilo no runtime:
890
+
891
+ 1. classes de host (`skin-*`, `density-*`, `model-*`, `lines-*`, `skin.class`);
892
+ 2. CSS vars geradas por `ListSkinService.toCssVars`;
893
+ 3. CSS inline opcional (`skin.inlineStyle`) sanitizado e escopado por instancia.
894
+
895
+ Recomendacao corporativa:
896
+
897
+ - prefira `skin.*` estruturado para padrao multiplataforma;
898
+ - use `inlineStyle` apenas para excecoes auditadas.
899
+
900
+ ### Examples
901
+
902
+ ### Minimal valid
903
+
904
+ ```json
905
+ {}
906
+ ```
907
+
908
+ ### Typical/common
909
+
910
+ ```json
911
+ {}
912
+ ```
913
+
914
+ ### Advanced
915
+
916
+ ```json
917
+ {}
918
+ ```
919
+
920
+ ### Enterprise scenario
921
+
922
+ ```json
923
+ {}
924
+ ```
925
+
926
+ ## Known limitations and mismatches
927
+
928
+ | Path/Behavior | Observed behavior (runtime) | Desired behavior | Impact | Tracking issue | Target fix |
929
+ | ---------------- | ---------------------------------------------------------------- | ------------------------------------------------------------- | ----------------------------------------------- | -------------- | -------------- |
930
+ | coverage/mapping | Evidência textual preservada indica itens Partial/Declared-only. | Cobertura confirmada por evidência runtime + schema + editor. | Pode gerar uso de paths não totalmente ligados. | to-be-linked | next-doc-cycle |
931
+
932
+ ## Compatibility and migration notes
933
+
934
+ | Concern | Affected versions | Migration action | Deadline | Notes |
935
+ | ------------------------------------------ | ------------------ | ------------------------------------------------------------------- | -------------- | ----------------------------------------- |
936
+ | legacy aliases and mixed status vocabulary | pre-canonical docs | unificar para taxonomia canonica (Active/Partial/Declared-only/...) | next-doc-cycle | manter backward compatibility documentada |
937
+
938
+ ## Source references
939
+
940
+ | Source type | Path/URL | Why it is source of truth | Last verified (YYYY-MM-DD) | Notes |
941
+ | ----------- | -------------------------------------------------------------------- | -------------------------------------- | -------------------------- | ---------------------------------------- |
942
+ | local-file | projects/praxis-list/src/lib/models/list-config.model.ts | Evidencia de implementacao e contrato. | 2026-03-05 | referencia preservada da versao anterior |
943
+ | local-file | projects/praxis-list/src/lib/components/praxis-list.component.ts | Evidencia de implementacao e contrato. | 2026-03-05 | referencia preservada da versao anterior |
944
+ | local-file | projects/praxis-list/src/lib/components/praxis-list.component.html | Evidencia de implementacao e contrato. | 2026-03-05 | referencia preservada da versao anterior |
945
+ | local-file | projects/praxis-list/src/lib/components/praxis-list.component.scss | Evidencia de implementacao e contrato. | 2026-03-05 | referencia preservada da versao anterior |
946
+ | local-file | projects/praxis-list/src/lib/services/list-data.service.ts | Evidencia de implementacao e contrato. | 2026-03-05 | referencia preservada da versao anterior |
947
+ | local-file | projects/praxis-list/src/lib/services/list-skin.service.ts | Evidencia de implementacao e contrato. | 2026-03-05 | referencia preservada da versao anterior |
948
+ | local-file | projects/praxis-list/src/lib/utils/template-evaluator.ts | Evidencia de implementacao e contrato. | 2026-03-05 | referencia preservada da versao anterior |
949
+ | local-file | projects/praxis-list/src/lib/utils/selection-adapter.ts | Evidencia de implementacao e contrato. | 2026-03-05 | referencia preservada da versao anterior |
950
+ | local-file | projects/praxis-list/src/lib/editors/list-config-editor.component.ts | Evidencia de implementacao e contrato. | 2026-03-05 | referencia preservada da versao anterior |
951
+ | local-file | projects/praxis-list/src/lib/ai/list-ai.adapter.ts | Evidencia de implementacao e contrato. | 2026-03-05 | referencia preservada da versao anterior |
952
+ | local-file | projects/praxis-list/src/lib/ai/list-ai-capabilities.ts | Evidencia de implementacao e contrato. | 2026-03-05 | referencia preservada da versao anterior |
953
+ | local-file | projects/praxis-list/src/lib/ai/list-context-pack.ts | Evidencia de implementacao e contrato. | 2026-03-05 | referencia preservada da versao anterior |