@praxisui/list 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.
- package/README.md +61 -6
- package/docs/2026-03-executive-list-platform-backlog.md +140 -0
- package/docs/2026-03-executive-list-reference-checklist.md +110 -0
- package/docs/2026-04-navigation-open-route-release-note.md +40 -0
- package/docs/adr/2026-03-list-authoring-protocol.md +98 -0
- package/docs/adr/2026-03-list-inline-expansion-v1.md +309 -0
- package/fesm2022/praxisui-list.mjs +3009 -273
- package/index.d.ts +114 -26
- package/package.json +9 -3
- package/src/lib/components/praxis-list-skin-preview.json-api.md +459 -0
- package/src/lib/editors/praxis-list-config-editor.json-api.md +523 -0
- package/src/lib/praxis-list.json-api.md +953 -0
package/README.md
CHANGED
|
@@ -96,6 +96,7 @@ import { PraxisList } from '@praxisui/list';
|
|
|
96
96
|
(itemClick)="onItem($event)"
|
|
97
97
|
(actionClick)="onAction($event)"
|
|
98
98
|
(selectionChange)="onSelection($event)"
|
|
99
|
+
(exportAction)="onExport($event)"
|
|
99
100
|
/>
|
|
100
101
|
`,
|
|
101
102
|
})
|
|
@@ -122,14 +123,31 @@ export class ListDemoComponent {
|
|
|
122
123
|
{ id: 'favorite', icon: 'favorite', label: 'Like' },
|
|
123
124
|
{ id: 'buy', icon: 'shopping_cart', kind: 'button', buttonVariant: 'stroked', label: 'Buy' },
|
|
124
125
|
],
|
|
126
|
+
export: {
|
|
127
|
+
enabled: true,
|
|
128
|
+
formats: ['csv', 'json'],
|
|
129
|
+
general: { scope: 'auto', includeFields: ['id', 'name', 'price'] },
|
|
130
|
+
},
|
|
125
131
|
} satisfies import('@praxisui/list').PraxisListConfig;
|
|
126
132
|
|
|
127
133
|
onItem(e: any) { console.log('itemClick', e); }
|
|
128
134
|
onAction(e: any) { console.log('actionClick', e); }
|
|
129
135
|
onSelection(e: any) { console.log('selectionChange', e); }
|
|
136
|
+
onExport(e: any) { console.log('exportAction', e); }
|
|
130
137
|
}
|
|
131
138
|
```
|
|
132
139
|
|
|
140
|
+
## Collection Export
|
|
141
|
+
|
|
142
|
+
`@praxisui/list` uses the shared collection export contract from `@praxisui/core`, the same platform surface used by table exports.
|
|
143
|
+
|
|
144
|
+
- `export.enabled` renders the export action menu.
|
|
145
|
+
- `export.formats` accepts `csv`, `json`, `excel`, `pdf`, and `print`.
|
|
146
|
+
- `export.general.scope` accepts `auto`, `selected`, `filtered`, `currentPage`, and `all`.
|
|
147
|
+
- Local CSV/JSON exports run in the browser with formula escaping from `PraxisCollectionExportService`.
|
|
148
|
+
- Remote `filtered`/`all` exports and advanced formats require a host-level `PRAXIS_COLLECTION_EXPORT_PROVIDER`.
|
|
149
|
+
- Deferred exports and provider failures surface visible feedback through snackbar and live-region status.
|
|
150
|
+
|
|
133
151
|
## Runtime Contract (Data Mode and Precedence)
|
|
134
152
|
|
|
135
153
|
Effective data mode resolution follows `ListDataService.stream()`:
|
|
@@ -151,6 +169,8 @@ Decision matrix (runtime today):
|
|
|
151
169
|
|
|
152
170
|
Important behavior:
|
|
153
171
|
- pagination/search/sort controls from `ui.*` are rendered only when `dataSource.resourcePath` is defined.
|
|
172
|
+
- remote pagination uses Angular Material `mat-paginator` to keep the same paginator chrome and accessibility behavior used by the dynamic table.
|
|
173
|
+
- when `ui.showRange` is `false`, the Material range text is hidden but the remote footer still exposes the total count.
|
|
154
174
|
- remote mode uses `GenericCrudService.filter(query, pageable)` and falls back to `getAll()` when `/filter` fails.
|
|
155
175
|
|
|
156
176
|
## Runtime Status Matrix (High-Impact Paths)
|
|
@@ -288,7 +308,7 @@ actions: [
|
|
|
288
308
|
- `showIf`: use Json Logic. Example: `{ "==": [{ "var": "row.status" }, "active"] }`.
|
|
289
309
|
- `emitPayload`: authoring field in the config/editor; current runtime `actionClick` emission does not change shape based on this field.
|
|
290
310
|
|
|
291
|
-
### Global actions
|
|
311
|
+
### Global actions
|
|
292
312
|
|
|
293
313
|
```ts
|
|
294
314
|
actions: [
|
|
@@ -296,13 +316,34 @@ actions: [
|
|
|
296
316
|
id: 'favorite',
|
|
297
317
|
icon: 'favorite',
|
|
298
318
|
label: 'Favorite',
|
|
299
|
-
|
|
300
|
-
|
|
319
|
+
globalAction: {
|
|
320
|
+
actionId: 'api.post',
|
|
321
|
+
payload: { url: '/api/favorite', body: { id: '${item.id}' } }
|
|
322
|
+
}
|
|
301
323
|
}
|
|
302
324
|
]
|
|
303
325
|
```
|
|
304
326
|
|
|
305
|
-
When `
|
|
327
|
+
When `globalAction` is set, `actionClick` is **not emitted** by default. Use `emitLocal: true` to emit both.
|
|
328
|
+
|
|
329
|
+
For internal navigation from a row or item button, use `navigation.openRoute` and bind the selected item id into `query` or `state`:
|
|
330
|
+
|
|
331
|
+
```ts
|
|
332
|
+
actions: [
|
|
333
|
+
{
|
|
334
|
+
id: 'details',
|
|
335
|
+
icon: 'open_in_new',
|
|
336
|
+
label: 'Open details',
|
|
337
|
+
globalAction: {
|
|
338
|
+
actionId: 'navigation.openRoute',
|
|
339
|
+
payload: {
|
|
340
|
+
path: '/clientes/detalhe',
|
|
341
|
+
query: { id: '${item.id}' },
|
|
342
|
+
},
|
|
343
|
+
},
|
|
344
|
+
}
|
|
345
|
+
]
|
|
346
|
+
```
|
|
306
347
|
|
|
307
348
|
### Confirmation and loading
|
|
308
349
|
|
|
@@ -312,14 +353,16 @@ actions: [
|
|
|
312
353
|
id: 'delete',
|
|
313
354
|
icon: 'delete',
|
|
314
355
|
label: 'Delete',
|
|
315
|
-
|
|
356
|
+
globalAction: {
|
|
357
|
+
actionId: 'api.patch',
|
|
358
|
+
payload: { url: '/api/items/${item.id}', body: { active: false } },
|
|
359
|
+
},
|
|
316
360
|
showLoading: true,
|
|
317
361
|
confirmation: {
|
|
318
362
|
title: 'Confirm deletion',
|
|
319
363
|
message: 'Are you sure you want to delete this item?',
|
|
320
364
|
type: 'danger',
|
|
321
365
|
},
|
|
322
|
-
globalPayload: { url: '/api/items/${item.id}', body: { active: false } },
|
|
323
366
|
}
|
|
324
367
|
]
|
|
325
368
|
```
|
|
@@ -337,6 +380,18 @@ Outputs:
|
|
|
337
380
|
- `(actionClick)`: `{ actionId, item, index }`
|
|
338
381
|
- `(selectionChange)`: `{ mode, value, items, ids? }`
|
|
339
382
|
|
|
383
|
+
## Agentic Authoring & Manifest
|
|
384
|
+
|
|
385
|
+
`@praxisui/list` publishes `PRAXIS_LIST_AUTHORING_MANIFEST` as the executable authoring contract for list/card configuration.
|
|
386
|
+
|
|
387
|
+
- **Component ID:** `praxis-list`
|
|
388
|
+
- **Config Schema:** `PraxisListConfig`
|
|
389
|
+
- **Editable targets:** the manifest exposes explicit targets for template slots, text, avatar, badge, item actions, empty state, selection, layout, row layout, data binding, interaction, expansion, rules, metadata, skin, toolbar UI, collection export, localization, accessibility and declarative event mappings.
|
|
390
|
+
- **Operation families:** operations cover the required list authoring brief plus supported extensions for metadata, local/remote data, row layout, skin, interaction/expansion, conditional rules, executive template slots, features, skeleton, toolbar UI, export, i18n, accessibility and declarative event mappings.
|
|
391
|
+
- **Validation:** deterministic validators cover field binding, stable action/rule/section IDs, destructive action removal, remote resource binding, local/remote precedence, enum support, query/sort support, row layout placement reachability, expansion schema safety, Json Logic, global actions, declared-only runtime warnings and editor round-trip preservation.
|
|
392
|
+
- **Examples/evals:** fixtures cover every operation family in the manifest, including title/subtitle binding, action creation/update/removal, status badge, selection mode, missing field rejection, skin, toolbar, export, accessibility, event mapping, row layout, expansion, data modes, i18n, empty state and conditional row styling.
|
|
393
|
+
- **Declared-only semantics:** fields documented as declared-only remain authorable only as config/editor round-trip fields and are guarded by `declared-only-runtime-warning`; the manifest does not claim runtime behavior that the component does not implement.
|
|
394
|
+
|
|
340
395
|
## Known limitations and mismatches
|
|
341
396
|
|
|
342
397
|
1. `layout.virtualScroll` and `layout.stickySectionHeader` exist in the contract/editor, but have no runtime implementation.
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Backlog Tecnico — Executive List Platform
|
|
2
|
+
|
|
3
|
+
Data: 2026-03-20
|
|
4
|
+
Escopo: `projects/praxis-list`
|
|
5
|
+
Status: draft
|
|
6
|
+
|
|
7
|
+
## Objetivo
|
|
8
|
+
|
|
9
|
+
Evoluir a `praxis-list` para suportar listas executivas com fidelidade visual ao layout de referencia em `praxis-ui-landing-page/issues/playground/problemas/referencia-list`, sem criar uma API publica paralela (`V2`) e sem depender de hacks baseados em `html` inline, parsing por quebra de linha ou CSS acoplado a `nth-child`.
|
|
10
|
+
|
|
11
|
+
## Principios
|
|
12
|
+
|
|
13
|
+
- Manter a API publica em `PraxisListConfig`.
|
|
14
|
+
- Introduzir um modelo interno normalizado unico para o runtime.
|
|
15
|
+
- Reaproveitar da `praxis-table` o desenho correto de seguranca e resolucao remota.
|
|
16
|
+
- Tratar a linha da list como composicao de slots renderizaveis, nao como HTML livre.
|
|
17
|
+
- Priorizar a solucao correta de plataforma, nao remendos de demo.
|
|
18
|
+
|
|
19
|
+
## Fase 1 — Base Contratual e Runtime
|
|
20
|
+
|
|
21
|
+
Objetivo: suportar a linha fechada da referencia sem hacks.
|
|
22
|
+
|
|
23
|
+
### Itens
|
|
24
|
+
|
|
25
|
+
- Expandir `TemplateType` com `metric`, `compose` e `component`.
|
|
26
|
+
- Evoluir `TemplateDef.props` para suportar `metric`, `compose` e `component`.
|
|
27
|
+
- Adicionar `layout.rowLayout`.
|
|
28
|
+
- Adicionar `rules.itemStyles`.
|
|
29
|
+
- Adicionar `rules.slotOverrides`.
|
|
30
|
+
- Criar `NormalizedListRuntimeConfig`.
|
|
31
|
+
- Criar `normalizeListConfig()`.
|
|
32
|
+
- Criar `normalizeTemplateNode()` e `normalizeTemplating()`.
|
|
33
|
+
- Criar `normalizeLayout()`.
|
|
34
|
+
- Atualizar o runtime da list para renderizar `metric`.
|
|
35
|
+
- Atualizar o runtime da list para renderizar `compose`.
|
|
36
|
+
- Aplicar `rules.itemStyles` no container do item.
|
|
37
|
+
- Aplicar `rules.slotOverrides` por slot.
|
|
38
|
+
|
|
39
|
+
### Criterios de aceite
|
|
40
|
+
|
|
41
|
+
- A linha consegue alinhar colunas de forma estavel entre todos os itens.
|
|
42
|
+
- O conteudo das colunas fica centralizado verticalmente.
|
|
43
|
+
- As metricas `SALDO`, `LIMITE DISPONIVEL` e `RISCO` nao dependem de `nth-child`.
|
|
44
|
+
- O risco pode variar cor e icone por regra.
|
|
45
|
+
|
|
46
|
+
## Fase 2 — Renderers Canonicos da Linha Executiva
|
|
47
|
+
|
|
48
|
+
Objetivo: reduzir verbosidade e eliminar `html` inline no cenario executivo.
|
|
49
|
+
|
|
50
|
+
### Itens
|
|
51
|
+
|
|
52
|
+
- Criar renderer `account-identity`.
|
|
53
|
+
- Criar renderer `executive-metric`.
|
|
54
|
+
- Criar renderer `executive-trailing`.
|
|
55
|
+
- Criar registry interno de renderers da list.
|
|
56
|
+
- Fazer `TemplateDef.type = 'component'` resolver via registry.
|
|
57
|
+
- Migrar `PraxisListDocPageComponent` para o contrato canônico novo.
|
|
58
|
+
- Remover dependencia de `executiveNameHtml`, `executiveSubtitleHtml` e `executiveTrailingHtml`.
|
|
59
|
+
- Reduzir CSS hardcoded da `executive-inline-skin`.
|
|
60
|
+
|
|
61
|
+
### Criterios de aceite
|
|
62
|
+
|
|
63
|
+
- O cenario `Executive expansion` usa renderers canônicos para identidade, metricas e trailing.
|
|
64
|
+
- O template nao depende mais de `innerHTML` para a linha executiva.
|
|
65
|
+
- A skin volta a ser refinamento visual, nao mecanismo principal.
|
|
66
|
+
|
|
67
|
+
## Fase 3 — Expansao Schema-Driven e Detail Remoto
|
|
68
|
+
|
|
69
|
+
Objetivo: suportar a referencia aberta e preparar cenarios reais.
|
|
70
|
+
|
|
71
|
+
### Itens
|
|
72
|
+
|
|
73
|
+
- Evoluir `ListExpansionSectionDef` com `metadata` e `component`.
|
|
74
|
+
- Evoluir `expansion` com `dataSource`, `schemaContract` e `rendering`.
|
|
75
|
+
- Implementar `expansion.dataSource.mode = inline`.
|
|
76
|
+
- Implementar `expansion.dataSource.mode = resource`.
|
|
77
|
+
- Implementar `expansion.dataSource.mode = resourcePath`.
|
|
78
|
+
- Implementar interpolacao por `paramsMap`.
|
|
79
|
+
- Implementar `resourceAllowList`.
|
|
80
|
+
- Bloquear `resourcePath` absoluto ou com scheme.
|
|
81
|
+
- Implementar cache por item expandido.
|
|
82
|
+
- Implementar cancelamento ao colapsar.
|
|
83
|
+
- Implementar sanitizacao de schema com `allowedNodes`.
|
|
84
|
+
- Implementar shell visual `attached` para detail row.
|
|
85
|
+
|
|
86
|
+
### Criterios de aceite
|
|
87
|
+
|
|
88
|
+
- A list suporta detalhe lazy por item expandido.
|
|
89
|
+
- A politica de seguranca opera em fail-closed.
|
|
90
|
+
- O detail remoto pode ser carregado por `resourcePath` relativo com allowlist.
|
|
91
|
+
- A estrutura aberta da referencia pode ser reproduzida sem hardcode por tela.
|
|
92
|
+
|
|
93
|
+
## Fase 4 — Testes, Docs e Governanca
|
|
94
|
+
|
|
95
|
+
Objetivo: consolidar a plataforma.
|
|
96
|
+
|
|
97
|
+
### Itens
|
|
98
|
+
|
|
99
|
+
- Criar specs para o normalizador de config.
|
|
100
|
+
- Criar specs para `metric`, `compose` e `component`.
|
|
101
|
+
- Criar specs para `rules`.
|
|
102
|
+
- Criar specs para `expansion.resourcePath`.
|
|
103
|
+
- Criar regressao visual/estrutural do cenario executivo.
|
|
104
|
+
- Atualizar `README.md` da list.
|
|
105
|
+
- Atualizar a documentacao JSON API da list.
|
|
106
|
+
- Documentar regras de seguranca da expansao remota.
|
|
107
|
+
|
|
108
|
+
### Criterios de aceite
|
|
109
|
+
|
|
110
|
+
- A cobertura de testes protege a normalizacao, renderizacao e seguranca.
|
|
111
|
+
- A doc page reflete o contrato canonico.
|
|
112
|
+
- O backlog desta rodada deixa de ser apenas analise e vira plataforma verificavel.
|
|
113
|
+
|
|
114
|
+
## Ordem Recomendada
|
|
115
|
+
|
|
116
|
+
1. Fase 1 completa
|
|
117
|
+
2. Fase 2 completa
|
|
118
|
+
3. Fase 3 completa
|
|
119
|
+
4. Fase 4 completa
|
|
120
|
+
|
|
121
|
+
## Decisoes Ja Tomadas
|
|
122
|
+
|
|
123
|
+
- Nao criar `PraxisListConfigV2`.
|
|
124
|
+
- Evoluir o contrato atual.
|
|
125
|
+
- Introduzir modelo interno normalizado.
|
|
126
|
+
- Reaproveitar o padrao de seguranca da `praxis-table` para detail remoto.
|
|
127
|
+
|
|
128
|
+
## Riscos Conhecidos
|
|
129
|
+
|
|
130
|
+
- Crescimento do template principal da list se a normalizacao nao vier antes dos renderers.
|
|
131
|
+
- Acoplamento excessivo a CSS se `metric` e `compose` forem introduzidos sem `rowLayout`.
|
|
132
|
+
- Duplicacao conceitual com a `praxis-table` se a expansao remota da list ignorar `schemaContract` e `resourceAllowList`.
|
|
133
|
+
|
|
134
|
+
## Definicao de Pronto desta iniciativa
|
|
135
|
+
|
|
136
|
+
- Linha executiva fechada identica a referencia.
|
|
137
|
+
- Linha executiva aberta identica a referencia.
|
|
138
|
+
- Variacoes do mesmo padrao possiveis via contrato.
|
|
139
|
+
- Sem `html` inline como mecanismo principal.
|
|
140
|
+
- Sem hacks de `nth-child` e pseudo-elementos como contrato.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Checklist de Aderencia — Referencia Executive List
|
|
2
|
+
|
|
3
|
+
Data: 2026-03-20
|
|
4
|
+
Escopo: `projects/praxis-list`
|
|
5
|
+
Status: draft
|
|
6
|
+
|
|
7
|
+
## Referencia
|
|
8
|
+
|
|
9
|
+
- Fechado: `praxis-ui-landing-page/issues/playground/problemas/referencia-list/fechado.png`
|
|
10
|
+
- Aberto: `praxis-ui-landing-page/issues/playground/problemas/referencia-list/aberto.png`
|
|
11
|
+
|
|
12
|
+
## Objetivo
|
|
13
|
+
|
|
14
|
+
Confirmar, ponto a ponto, que a evolucao proposta para a `praxis-list` cobre a referencia visual de forma 1:1 e ainda permite variacoes controladas do mesmo padrao.
|
|
15
|
+
|
|
16
|
+
## Checklist Estrutural
|
|
17
|
+
|
|
18
|
+
- [ ] A linha funciona como grade estavel de colunas.
|
|
19
|
+
- [ ] Todas as linhas compartilham o mesmo alinhamento horizontal entre colunas.
|
|
20
|
+
- [ ] O conteudo interno das colunas fica centralizado verticalmente.
|
|
21
|
+
- [ ] A linha suporta variacao discreta de borda/tom por severidade.
|
|
22
|
+
|
|
23
|
+
## Checklist de Identidade
|
|
24
|
+
|
|
25
|
+
- [ ] O codigo/monograma da conta aparece em capsula dedicada.
|
|
26
|
+
- [ ] O titulo principal suporta icone decorativo adjacente.
|
|
27
|
+
- [ ] O subtitulo suporta badge de segmento.
|
|
28
|
+
- [ ] O subtitulo suporta composicao `tipo de conta + desde ano`.
|
|
29
|
+
- [ ] O bloco de identidade e reutilizavel como renderer proprio.
|
|
30
|
+
|
|
31
|
+
## Checklist de Metricas
|
|
32
|
+
|
|
33
|
+
- [ ] `SALDO` suporta label pequena + valor forte.
|
|
34
|
+
- [ ] `LIMITE DISPONIVEL` suporta valor + barra inline + legenda.
|
|
35
|
+
- [ ] `RISCO` suporta icone + valor + barra + legenda.
|
|
36
|
+
- [ ] `RISCO` suporta variacao de icone por regra.
|
|
37
|
+
- [ ] `RISCO` suporta variacao de cor por regra.
|
|
38
|
+
- [ ] A barra de progresso pode variar por regra.
|
|
39
|
+
- [ ] O alinhamento das metricas e identico entre linhas.
|
|
40
|
+
|
|
41
|
+
## Checklist de Trailing
|
|
42
|
+
|
|
43
|
+
- [ ] O trailing suporta alertas agregados.
|
|
44
|
+
- [ ] O trailing suporta owner resumido.
|
|
45
|
+
- [ ] O trailing suporta icones de acao.
|
|
46
|
+
- [ ] O trailing suporta chevron de expansao.
|
|
47
|
+
- [ ] A ordem visual do trailing e estavel.
|
|
48
|
+
- [ ] O trailing pode ser empacotado como renderer reutilizavel.
|
|
49
|
+
|
|
50
|
+
## Checklist de Expansao
|
|
51
|
+
|
|
52
|
+
- [ ] A linha expandida fica visualmente anexada a linha principal.
|
|
53
|
+
- [ ] A expansao suporta layout em 3 colunas.
|
|
54
|
+
- [ ] `ALERTAS` suporta bloco de informacao destacado.
|
|
55
|
+
- [ ] `PRODUTOS CONTRATADOS` suporta chips.
|
|
56
|
+
- [ ] `PROXIMOS EVENTOS` suporta timeline.
|
|
57
|
+
- [ ] O shell da expansao pode ser configurado sem hardcode por tela.
|
|
58
|
+
|
|
59
|
+
## Checklist de Detail Remoto
|
|
60
|
+
|
|
61
|
+
- [ ] A expansao pode operar com dados inline.
|
|
62
|
+
- [ ] A expansao pode operar com `resource`.
|
|
63
|
+
- [ ] A expansao pode operar com `resourcePath`.
|
|
64
|
+
- [ ] O `resourcePath` suporta `paramsMap`.
|
|
65
|
+
- [ ] O `resourcePath` exige `resourceAllowList`.
|
|
66
|
+
- [ ] O runtime bloqueia URL absoluta ou com scheme.
|
|
67
|
+
- [ ] O runtime sanitiza schema remoto por `schemaContract.allowedNodes`.
|
|
68
|
+
|
|
69
|
+
## Checklist de Variacoes
|
|
70
|
+
|
|
71
|
+
- [ ] A mesma estrutura suporta portfolios diferentes.
|
|
72
|
+
- [ ] As metricas suportam layouts diferentes sem hacks.
|
|
73
|
+
- [ ] O trailing suporta diferentes combinacoes de alertas/owner/acoes.
|
|
74
|
+
- [ ] O bloco de identidade suporta variacao de badge, subtitulo e adornos.
|
|
75
|
+
- [ ] A expansao suporta sections declarativas adicionais.
|
|
76
|
+
|
|
77
|
+
## Cobertura Esperada do Contrato
|
|
78
|
+
|
|
79
|
+
### Cobertura completa
|
|
80
|
+
|
|
81
|
+
- `layout.rowLayout`
|
|
82
|
+
- `templating.metric`
|
|
83
|
+
- `templating.compose`
|
|
84
|
+
- `rules.itemStyles`
|
|
85
|
+
- `rules.slotOverrides`
|
|
86
|
+
- `expansion.dataSource`
|
|
87
|
+
- `expansion.schemaContract`
|
|
88
|
+
- `expansion.rendering`
|
|
89
|
+
|
|
90
|
+
### Cobertura completa, mas recomendando renderer dedicado
|
|
91
|
+
|
|
92
|
+
- `account-identity`
|
|
93
|
+
- `executive-metric`
|
|
94
|
+
- `executive-trailing`
|
|
95
|
+
|
|
96
|
+
## Sinais de Solucao Incorreta
|
|
97
|
+
|
|
98
|
+
- Uso de `html` inline como mecanismo principal de composicao.
|
|
99
|
+
- Dependencia de `nth-child` para semantica do contrato.
|
|
100
|
+
- Barras desenhadas apenas por pseudo-elemento sem dado semantico.
|
|
101
|
+
- Variacoes visuais dependentes de CSS acoplado ao cenario demo.
|
|
102
|
+
- Detail remoto sem `resourceAllowList`.
|
|
103
|
+
|
|
104
|
+
## Definicao de Aderencia Concluida
|
|
105
|
+
|
|
106
|
+
- [ ] Fechado 1:1
|
|
107
|
+
- [ ] Aberto 1:1
|
|
108
|
+
- [ ] Variacoes controladas suportadas
|
|
109
|
+
- [ ] Sem hacks estruturais
|
|
110
|
+
- [ ] Composicao canônica reutilizavel
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Release Note — Navigation Open Route
|
|
2
|
+
|
|
3
|
+
Data: 2026-04-23
|
|
4
|
+
Escopo: `projects/praxis-list`
|
|
5
|
+
Status: concluido
|
|
6
|
+
|
|
7
|
+
## Resumo
|
|
8
|
+
|
|
9
|
+
A `praxis-list` agora documenta e demonstra o contrato canônico `navigation.openRoute` para acoes de item.
|
|
10
|
+
O mesmo item que dispara `surface.open` também pode abrir uma rota interna, levando `item.id` no `query` ou no `state`.
|
|
11
|
+
|
|
12
|
+
## O que foi alinhado
|
|
13
|
+
|
|
14
|
+
- Runtime de demonstração com uma action de item que abre `/components-showcase/surface-open-guide`.
|
|
15
|
+
- Spec unitária da demo ajustada para refletir o contrato real de `GlobalActionService.executeRef(...)`.
|
|
16
|
+
- Playwright de demonstração validando navegação real no browser.
|
|
17
|
+
- README e documentação JSON API da lista com exemplo de `navigation.openRoute`.
|
|
18
|
+
- Manifesto de IA da lista com exemplo sugestivo de action interna usando `item.id`.
|
|
19
|
+
|
|
20
|
+
## Contrato de uso
|
|
21
|
+
|
|
22
|
+
Exemplo canônico:
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
{
|
|
26
|
+
actionId: 'navigation.openRoute',
|
|
27
|
+
payload: {
|
|
28
|
+
path: '/components-showcase/surface-open-guide',
|
|
29
|
+
query: { funcionarioId: '${item.id}' },
|
|
30
|
+
state: { funcionarioId: '${item.id}', source: 'surface-open-list-demo' },
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Status do suporte
|
|
36
|
+
|
|
37
|
+
- `navigation.openRoute`: ativo no core e consumido pela `praxis-list`.
|
|
38
|
+
- `surface.open`: permanece como contrato canônico para abertura de superfÃcies.
|
|
39
|
+
- `actionClick`: continua sendo o evento local da lista quando `emitLocal` estiver habilitado.
|
|
40
|
+
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# ADR: Protocolo Canônico de Autoria do `praxis-list`
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Aceito.
|
|
6
|
+
|
|
7
|
+
## Problema
|
|
8
|
+
|
|
9
|
+
`praxis-list` evoluiu com múltiplas superfícies de autoria e aplicação:
|
|
10
|
+
|
|
11
|
+
- editor visual;
|
|
12
|
+
- edição JSON/manual;
|
|
13
|
+
- host runtime;
|
|
14
|
+
- integrações futuras com playground e IA.
|
|
15
|
+
|
|
16
|
+
Antes desta mudança, o boundary principal era implícito em `PraxisListConfig`, com lógica de normalização e apply espalhada entre editor e host. Isso criava fragilidade arquitetural, side effects opacos e risco de divergência entre superfícies.
|
|
17
|
+
|
|
18
|
+
## Decisão
|
|
19
|
+
|
|
20
|
+
O contrato canônico de autoria de `praxis-list` passa a ser `ListAuthoringDocument`.
|
|
21
|
+
|
|
22
|
+
Regras normativas:
|
|
23
|
+
|
|
24
|
+
1. O boundary principal de autoria é `ListAuthoringDocument`.
|
|
25
|
+
2. `PraxisListConfig` continua sendo a projeção canônica de runtime, não o protocolo primário de autoria.
|
|
26
|
+
3. O host deve aplicar documentos via:
|
|
27
|
+
- parse;
|
|
28
|
+
- validate;
|
|
29
|
+
- build apply plan;
|
|
30
|
+
- executor runtime fino.
|
|
31
|
+
4. O editor visual e o editor JSON devem produzir e consumir `ListAuthoringDocument`.
|
|
32
|
+
5. Regras de normalização, validação e inferência autoral pertencem à capability pública; o editor visual só pode projetar/hidratar estado transitório de UI.
|
|
33
|
+
6. `applyConfigFromAdapter(...)` é mantido apenas por compatibilidade e deve delegar ao protocolo canônico.
|
|
34
|
+
7. Inferência de schema não deve ficar escondida como side effect arquitetural opaco; ela deve ser uma etapa explícita do apply/runtime e sua decisão deve nascer do `ListApplyPlan`.
|
|
35
|
+
8. Não forçamos `bindings` vazios no documento enquanto não houver requisito real fora de `config`.
|
|
36
|
+
|
|
37
|
+
## Contrato novo
|
|
38
|
+
|
|
39
|
+
O protocolo é composto por:
|
|
40
|
+
|
|
41
|
+
- `ListAuthoringDocument`
|
|
42
|
+
- `ListValidationContext`
|
|
43
|
+
- `ListProjectionContext`
|
|
44
|
+
- `ListRuntimeContext`
|
|
45
|
+
- `ListApplyPlan`
|
|
46
|
+
|
|
47
|
+
Capability pública:
|
|
48
|
+
|
|
49
|
+
- `createListAuthoringDocument(...)`
|
|
50
|
+
- `parseLegacyOrListDocument(...)`
|
|
51
|
+
- `normalizeListAuthoringDocument(...)`
|
|
52
|
+
- `validateListAuthoringDocument(...)`
|
|
53
|
+
- `toCanonicalListConfig(...)`
|
|
54
|
+
- `buildListApplyPlan(...)`
|
|
55
|
+
- `serializeListAuthoringDocument(...)`
|
|
56
|
+
|
|
57
|
+
## Boundary de Apply
|
|
58
|
+
|
|
59
|
+
O host não deve usar `applyDocument(target, doc)` como boundary principal.
|
|
60
|
+
|
|
61
|
+
O fluxo correto é:
|
|
62
|
+
|
|
63
|
+
1. receber payload;
|
|
64
|
+
2. converter para `ListAuthoringDocument`;
|
|
65
|
+
3. validar;
|
|
66
|
+
4. construir `ListApplyPlan`;
|
|
67
|
+
5. executar o plano no runtime.
|
|
68
|
+
|
|
69
|
+
O executor do host é responsável apenas por efeitos de runtime:
|
|
70
|
+
|
|
71
|
+
- aplicar config;
|
|
72
|
+
- rebinding de seleção;
|
|
73
|
+
- reaplicar skin;
|
|
74
|
+
- persistir config quando necessário;
|
|
75
|
+
- executar inferência de schema explicitamente.
|
|
76
|
+
|
|
77
|
+
## Compatibilidade legada
|
|
78
|
+
|
|
79
|
+
Compatibilidade continua suportada para payloads legados baseados em `config`.
|
|
80
|
+
|
|
81
|
+
Regra:
|
|
82
|
+
|
|
83
|
+
- quando houver `document`, ele tem precedência;
|
|
84
|
+
- quando houver apenas `config`, o host/editor convertem para `ListAuthoringDocument`.
|
|
85
|
+
|
|
86
|
+
## Consequências
|
|
87
|
+
|
|
88
|
+
Benefícios:
|
|
89
|
+
|
|
90
|
+
- unificação entre editor visual, editor JSON e host;
|
|
91
|
+
- apply declarativo e mais auditável;
|
|
92
|
+
- menor risco de divergência conceitual com `praxis-table`;
|
|
93
|
+
- base melhor para playground e fluxos de IA.
|
|
94
|
+
|
|
95
|
+
Tradeoff:
|
|
96
|
+
|
|
97
|
+
- aumenta a disciplina de contrato;
|
|
98
|
+
- exige manutenção explícita da documentação e dos testes dos fluxos de autoria.
|