@praxisui/list 10.0.0-rc.4 → 10.0.0-rc.40

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/package.json CHANGED
@@ -1,19 +1,20 @@
1
1
  {
2
2
  "name": "@praxisui/list",
3
- "version": "10.0.0-rc.4",
3
+ "version": "10.0.0-rc.40",
4
4
  "description": "List components and helpers for Praxis UI.",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0",
7
7
  "@angular/core": "^21.0.0",
8
+ "@angular/cdk": "^21.0.0",
8
9
  "@angular/material": "^21.0.0",
9
- "@praxisui/dynamic-fields": "^10.0.0-rc.4",
10
+ "@praxisui/dynamic-fields": "^10.0.0-rc.40",
10
11
  "rxjs": ">=7 <9",
11
12
  "@angular/forms": "^21.0.0",
12
13
  "@angular/router": "^21.0.0",
13
- "@praxisui/ai": "^10.0.0-rc.4",
14
- "@praxisui/core": "^10.0.0-rc.4",
15
- "@praxisui/rich-content": "^10.0.0-rc.4",
16
- "@praxisui/settings-panel": "^10.0.0-rc.4"
14
+ "@praxisui/ai": "^10.0.0-rc.40",
15
+ "@praxisui/core": "^10.0.0-rc.40",
16
+ "@praxisui/rich-content": "^10.0.0-rc.40",
17
+ "@praxisui/settings-panel": "^10.0.0-rc.40"
17
18
  },
18
19
  "dependencies": {
19
20
  "tslib": "^2.3.0",
@@ -104,11 +104,13 @@ Este documento e a referencia canonica da API JSON de praxis-list.
104
104
  | ------------ | ------------- | ------------- | ------- | ------------- | ---------------------------------------------------------------------------- |
105
105
  | `id` | not-specified | not-specified | n/a | Declared-only | preservado no contrato, sem efeito direto |
106
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 |
107
+ | `layout` | not-specified | not-specified | n/a | Partial | maioria ativa (`rowLayout`, `virtualScroll`, `itemAppearance`); `stickySectionHeader` sem binding funcional |
108
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 |
109
+ | `selection` | not-specified | not-specified | n/a | Active | binding, `showControl` e shape do payload de selecao |
110
+ | `templating` | not-specified | not-specified | n/a | Partial | quase completo (`compose`, `metric`, `datetime`, `relative` ativos); `type='slot'` sem renderer |
111
+ | `rules` | not-specified | not-specified | n/a | Active | `itemStyles` (com `tone` semântico) e `slotOverrides` condicionais por linha |
112
+ | `actions` | not-specified | not-specified | n/a | Partial | quase completo (`placement='actions'|'trailing'|'menu'`, `kind='icon'|'button'|'menu-item'`); `emitPayload` sem consumo no runtime |
113
+ | `itemActions`| not-specified | not-specified | n/a | Active | alias compatível para `actions` |
112
114
  | `i18n` | not-specified | not-specified | n/a | Active | locale/currency para `date/currency` |
113
115
  | `ui` | not-specified | not-specified | n/a | Active | busca/sort/range |
114
116
  | `export` | not-specified | not-specified | n/a | Active | contrato compartilhado de exportação de coleções |
@@ -141,11 +143,13 @@ Este arquivo foi adaptado para o padrao canonico atual sem remover conteudo tecn
141
143
  | Block | Purpose | Required | Merge strategy | Notes |
142
144
  | ------------ | --------------------------------------------------- | -------- | -------------- | -------------------------------------------------------------- |
143
145
  | `dataSource` | Origem de dados, query, sort e paginação | Yes | deep-merge | Base para `ListDataService`. |
144
- | `layout` | Modelo visual e paginação do componente | No | deep-merge | `virtualScroll` e `stickySectionHeader` com cobertura parcial. |
146
+ | `layout` | Modelo visual e paginação do componente | No | deep-merge | `rowLayout`, `virtualScroll` e `itemAppearance` ativos; `stickySectionHeader` declarativo. |
145
147
  | `skin` | Tema visual com classes, css vars e style inline | No | replace-block | Processado por `ListSkinService`. |
146
- | `selection` | Estratégia de seleção e integração com formulário | No | deep-merge | Normaliza modo single/multiple e payload de retorno. |
147
- | `templating` | Slots primário/secundário/meta/trailing | No | deep-merge | Avaliação por template engine + inferência opcional. |
148
- | `actions` | Ações locais e globais por item | No | replace-array | Inclui confirmação opcional e loading por ação. |
148
+ | `selection` | Estratégia de seleção e integração com formulário | No | deep-merge | Normaliza modo single/multiple, `showControl` e payload de retorno. |
149
+ | `templating` | Slots primário/secundário/meta/trailing | No | deep-merge | Avaliação por template engine (`compose`, `metric`, `datetime`, `relative` inclusos) + inferência opcional. |
150
+ | `rules` | Regras condicionais de estilo e override de slot | No | deep-merge | `itemStyles` (com `tone`) e `slotOverrides` avaliados por item. |
151
+ | `actions` | Ações locais, inline, overflow menu e globais | No | replace-array | Suporta `placement` (`actions`, `trailing`, `menu`) e `kind` (`icon`, `button`, `menu-item`). |
152
+ | `itemActions`| Alias compatível de `actions` | No | replace-array | Normalizado para `actions` quando `actions` não for informado. |
149
153
  | `i18n` | Locale/currency para renderizadores `date/currency` | No | deep-merge | Aplica fallback de locale/currency quando ausente. |
150
154
  | `ui` | Busca, ordenação e elementos auxiliares de UX | No | deep-merge | Conecta com stream de pesquisa e estado de página. |
151
155
 
@@ -155,11 +159,13 @@ Este arquivo foi adaptado para o padrao canonico atual sem remover conteudo tecn
155
159
  | ------------ | ------------- | ------------- | ------- | ----------------- | ---------------------------------------------------------------------------- |
156
160
  | `id` | not-specified | not-specified | n/a | component-defined | preservado no contrato, sem efeito direto |
157
161
  | `dataSource` | not-specified | not-specified | n/a | component-defined | origem de dados, query e sort |
158
- | `layout` | not-specified | not-specified | n/a | component-defined | maioria ativa; `stickySectionHeader` e `virtualScroll` sem binding funcional |
162
+ | `layout` | not-specified | not-specified | n/a | component-defined | maioria ativa (`rowLayout`, `virtualScroll`, `itemAppearance`); `stickySectionHeader` sem binding funcional |
159
163
  | `skin` | not-specified | not-specified | n/a | component-defined | classes + css vars + inline style sanitizado |
160
- | `selection` | not-specified | not-specified | n/a | component-defined | binding e shape do payload de selecao |
164
+ | `selection` | not-specified | not-specified | n/a | component-defined | binding, `showControl` e shape do payload de selecao |
161
165
  | `templating` | not-specified | not-specified | n/a | component-defined | quase completo; `type='slot'` sem renderer |
162
- | `actions` | not-specified | not-specified | n/a | component-defined | quase completo; `emitPayload` sem consumo no runtime |
166
+ | `rules` | not-specified | not-specified | n/a | component-defined | `itemStyles` e `slotOverrides` ativos no runtime |
167
+ | `actions` | not-specified | not-specified | n/a | component-defined | quase completo (`placement` e `menu-item` ativos); `emitPayload` sem consumo |
168
+ | `itemActions`| not-specified | not-specified | n/a | component-defined | alias compatível para `actions` |
163
169
  | `i18n` | not-specified | not-specified | n/a | component-defined | locale/currency para `date/currency` |
164
170
  | `ui` | not-specified | not-specified | n/a | component-defined | busca/sort/range |
165
171
  | `a11y` | not-specified | not-specified | n/a | component-defined | aria ativos; `highContrast/reduceMotion` sem efeito |
@@ -325,6 +331,8 @@ Legenda de suporte:
325
331
  - [Skin API](#skin-api)
326
332
  - [Selection API](#selection-api)
327
333
  - [Templating API (deep dive)](#templating-api-deep-dive)
334
+ - [Rules API](#rules-api)
335
+ - [Expansion API](#expansion-api)
328
336
  - [Actions API](#actions-api)
329
337
  - [UI, i18n, a11y e events](#ui-i18n-a11y-e-events)
330
338
  - [Expressoes suportadas (`expr` e `showIf`)](#expressoes-suportadas-expr-e-showif)
@@ -491,8 +499,10 @@ interface PraxisListConfig {
491
499
  selection?: {...};
492
500
  interaction?: {...};
493
501
  templating?: {...};
502
+ rules?: {...};
494
503
  expansion?: {...};
495
504
  actions?: Array<...>;
505
+ itemActions?: Array<...>;
496
506
  i18n?: {
497
507
  locale?: string;
498
508
  currency?: string;
@@ -510,13 +520,15 @@ interface PraxisListConfig {
510
520
  | ------------- | ------------- | ---------------------------------------------------------------------------- |
511
521
  | `id` | Declared-only | preservado no contrato, sem efeito direto |
512
522
  | `dataSource` | Active | origem de dados, query e sort |
513
- | `layout` | Partial | maioria ativa; `stickySectionHeader` e `virtualScroll` sem binding funcional |
523
+ | `layout` | Partial | maioria ativa (`rowLayout`, `virtualScroll`, `itemAppearance`); `stickySectionHeader` sem binding funcional |
514
524
  | `skin` | Active | classes + css vars + inline style sanitizado |
515
- | `selection` | Active | binding e shape do payload de selecao |
525
+ | `selection` | Active | binding, `showControl` e shape do payload de selecao |
516
526
  | `interaction` | Partial | expansao inline V1; apenas `variant=list` |
517
- | `templating` | Partial | quase completo; `type='slot'` sem renderer |
518
- | `expansion` | Partial | detail row tipada da V1 |
519
- | `actions` | Partial | quase completo; `emitPayload` sem consumo no runtime |
527
+ | `templating` | Partial | quase completo (`compose`, `metric`, `datetime`, `relative` ativos); `type='slot'` sem renderer |
528
+ | `rules` | Active | `itemStyles` (com `tone`) e `slotOverrides` condicionais por linha |
529
+ | `expansion` | Partial | detail row tipada da V1 (com pipes avaliados em `itemsExpr`) |
530
+ | `actions` | Partial | quase completo (`placement`, `menu-item` ativos); `emitPayload` sem consumo no runtime |
531
+ | `itemActions` | Active | alias compatível para `actions` |
520
532
  | `i18n` | Active | locale/currency para `date/currency` |
521
533
  | `ui` | Active | busca/sort/range |
522
534
  | `export` | Active | exportação via contrato compartilhado de coleções |
@@ -534,18 +546,27 @@ interface PraxisListConfig {
534
546
 
535
547
  #### Layout API
536
548
 
537
- | Caminho | Status | Observacao |
538
- | ---------------------------- | ------------- | ---------------------------------- |
539
- | `layout.variant` | Active | `list/cards/tiles` |
540
- | `layout.density` | Active | classe `density-*` |
541
- | `layout.itemSpacing` | Active | classe `item-spacing-*` |
542
- | `layout.lines` | Active | linhas de texto + classe `lines-*` |
543
- | `layout.dividers` | Active | divisores no modo `list` |
544
- | `layout.model` | Active | classe `model-*` |
545
- | `layout.groupBy` | Active | agrupamento em `sections$` |
546
- | `layout.pageSize` | Active | page size inicial |
547
- | `layout.stickySectionHeader` | Declared-only | sem sticky runtime |
548
- | `layout.virtualScroll` | Declared-only | sem virtual scroll runtime |
549
+ | Caminho | Status | Observacao |
550
+ | -------------------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------- |
551
+ | `layout.variant` | Active | `list/cards/tiles` |
552
+ | `layout.density` | Active | classe `density-*` |
553
+ | `layout.itemSpacing` | Active | classe `item-spacing-*` |
554
+ | `layout.itemAppearance` | Active | `flat/card` (isola itens em cartões sob `variant: 'list'`) |
555
+ | `layout.lines` | Active | linhas de texto + classe `lines-*` |
556
+ | `layout.dividers` | Active | divisores no modo `list` |
557
+ | `layout.model` | Active | classe `model-*` |
558
+ | `layout.groupBy` | Active | agrupamento em `sections$` |
559
+ | `layout.pageSize` | Active | page size inicial |
560
+ | `layout.rowLayout.type` | Active | `'grid'` para distribuicao colunar explicita dos slots em `variant='list'` |
561
+ | `layout.rowLayout.gap` | Active | gap horizontal entre colunas do `rowLayout` |
562
+ | `layout.rowLayout.align` | Active | alinhamento vertical das celulas (`start/center/end/stretch`) |
563
+ | `layout.rowLayout.columns` | Active | array de colunas `{ id?, slot, width, align?, minWidth?, maxWidth? }` (`leading/primary/secondary/meta/trailing/actions`) |
564
+ | `layout.stickySectionHeader` | Declared-only | sem sticky runtime |
565
+ | `layout.virtualScroll.enabled` | Active | habilita CDK Virtual Scroll (`variant='list'` sem `groupBy`); quando combinado com `interaction.expandable=true`, aplica viewport delimitado com barra de rolagem fina |
566
+ | `layout.virtualScroll.itemSize` | Active | altura estimada por linha em px no CDK Virtual Scroll |
567
+ | `layout.virtualScroll.minBufferPx` | Active | buffer minimo em px |
568
+ | `layout.virtualScroll.maxBufferPx` | Active | buffer maximo em px |
569
+ | `layout.virtualScroll.viewportHeight` | Active | altura do viewport (ex: `360` ou `'360px'`) tanto em virtual scroll quanto no fallback com `expandable=true`|
549
570
 
550
571
  #### Skin API
551
572
 
@@ -569,13 +590,14 @@ Notas de seguranca:
569
590
 
570
591
  #### Selection API
571
592
 
572
- | Caminho | Status | Observacao |
573
- | --------------------------- | ------ | -------------------------------------------------- |
574
- | `selection.mode` | Active | `none/single/multiple` |
575
- | `selection.formControlName` | Active | binding em form externo |
576
- | `selection.formControlPath` | Active | binding em path do form externo |
577
- | `selection.compareBy` | Active | igualdade de seleção e geração de `ids` |
578
- | `selection.return` | Active | `value/item/id` no payload `selectionChange.value` |
593
+ | Caminho | Status | Observacao |
594
+ | --------------------------- | ------ | -------------------------------------------------------------------------------------------------- |
595
+ | `selection.mode` | Active | `none/single/multiple` |
596
+ | `selection.showControl` | Active | exibe/oculta explicitamente o controle visual (`radio`/`checkbox`) sem desabilitar `selection.mode` |
597
+ | `selection.formControlName` | Active | binding em form externo |
598
+ | `selection.formControlPath` | Active | binding em path do form externo |
599
+ | `selection.compareBy` | Active | igualdade de seleção e geração de `ids` |
600
+ | `selection.return` | Active | `value/item/id` no payload `selectionChange.value` |
579
601
 
580
602
  A identidade de renderização é independente da identidade escolhida para a
581
603
  seleção. Registros HATEOAS usam prioritariamente `_links.self.href`, evitando
@@ -634,7 +656,7 @@ Slots suportados:
634
656
 
635
657
  Tipos funcionais no runtime:
636
658
 
637
- - `text`, `icon`, `image`, `chip`, `rating`, `currency`, `date`, `html`, `metric`, `compose`, `component`.
659
+ - `text`, `icon`, `image`, `chip`, `rating`, `currency`, `date`, `datetime`, `relative`, `html`, `metric`, `compose`, `component`.
638
660
 
639
661
  Inferencia opcional:
640
662
 
@@ -661,6 +683,8 @@ Tipo declarado sem renderer dedicado:
661
683
  | `templating.<slot>.badge.expr` | Active | badge em template de imagem |
662
684
  | `templating.<slot>.badge.color` | Active | cor badge |
663
685
  | `templating.<slot>.badge.variant` | Active | variante badge |
686
+ | `templating.<slot>.quickView` | Active | `ResourceQuickViewBinding` governado no slot via `[praxisQuickView]` (`stopPropagation` isola clique/selecao do item) |
687
+ | `templating.<slot>.items[].quickView` | Active | `ResourceQuickViewBinding` individual por subitem em `type = 'compose'` |
664
688
  | `templating.metaPlacement` | Active | `side`/`line` |
665
689
  | `templating.metaPrefixIcon` | Active | icone prefixado em meta textual |
666
690
  | `templating.statusPosition` | Active | `inline`/`top-right` em cards/tiles |
@@ -672,6 +696,22 @@ Tipo declarado sem renderer dedicado:
672
696
  | `templating.featuresMode` | Active | `icons+labels/icons-only/labels-only` |
673
697
  | `templating.skeleton.count` | Active | skeleton durante loading |
674
698
 
699
+ #### Rules API
700
+
701
+ | Caminho | Status | Observacao |
702
+ | ---------------------------------- | ------ | ---------------------------------------------------------------------------------------------- |
703
+ | `rules.itemStyles` | Active | array de regras visuais avaliadas por linha |
704
+ | `rules.itemStyles[].id` | Active | identificador da regra |
705
+ | `rules.itemStyles[].condition` | Active | condição Json Logic (ex: `{"==":[{"var":"row.severidade"},"CRITICA"]}`) ou expressão booleana |
706
+ | `rules.itemStyles[].tone` | Active | tom semântico (`neutral/info/success/warning/danger`) materializado como `.item-tone-*` |
707
+ | `rules.itemStyles[].class` | Active | classes CSS extras adicionadas ao item quando a condição é verdadeira |
708
+ | `rules.itemStyles[].style` | Active | declarações CSS inline adicionadas ao item quando a condição é verdadeira |
709
+ | `rules.slotOverrides` | Active | array de overrides condicionais de template por slot (`leading/primary/secondary/meta/trailing`) |
710
+ | `rules.slotOverrides[].id` | Active | identificador do override |
711
+ | `rules.slotOverrides[].slot` | Active | slot alvo (`leading/primary/secondary/meta/trailing`) |
712
+ | `rules.slotOverrides[].condition` | Active | condição Json Logic ou expressão booleana avaliada por linha |
713
+ | `rules.slotOverrides[].template` | Active | `TemplateDef` substituto para o slot quando a condição for verdadeira |
714
+
675
715
  #### Expansion API
676
716
 
677
717
  | Caminho | Status | Observacao |
@@ -710,9 +750,11 @@ Notas de UX/WCAG:
710
750
  | `actions[].icon` | Active | icone |
711
751
  | `actions[].label` | Active | label/aria-label |
712
752
  | `actions[].color` | Active | tema/cor custom |
713
- | `actions[].kind` | Active | `icon` ou `button` |
753
+ | `actions[].kind` | Active | `icon`, `button` ou `menu-item` (item de menu de overflow `⋮`) |
754
+ | `actions[].placement` | Active | `actions` (default), `trailing` (inline no slot trailing) ou `menu` (agrupado em `mat-menu` de overflow) |
714
755
  | `actions[].buttonVariant` | Active | `stroked/raised/flat` |
715
756
  | `actions[].showIf` | Active | condição Json Logic avaliada no contexto `row` |
757
+ | `itemActions` | Active | alias compatível para `actions` (normalizado automaticamente quando `actions` estiver ausente) |
716
758
  | `actions[].emitPayload` | Declared-only | sem uso no payload de ações nativas; ações `rich-content` hospedadas podem emitir `payload?` próprio |
717
759
  | `actions[].action` | Active | `surface.open` identifica a execução contextual governada quando acompanhada de `recordOpen` |
718
760
  | `actions[].recordOpen` | Active | referência mínima `{ sourceIdentityField, target: { resourceKey, surfaceId } }`; o runtime reconsulta catálogo, item e `_links.surfaces` antes de materializar |
@@ -765,15 +807,21 @@ Semantica de execucao:
765
807
  Suporte principal:
766
808
 
767
809
  - placeholders: `${item.campo}`;
768
- - pipes em placeholder: `bool`, `date`, `map`, `number`;
769
- - pipe top-level `bool` no expr completo.
810
+ - coalescência em placeholders: `${item.displayName ?? item.name ?? item.id}`;
811
+ - pipes em placeholder: `bool`, `date`, `datetime`, `relative`, `map`, `number`, `currency`;
812
+ - pipes top-level pós-expressão: `|bool:True:False`, `|map:k=v`, `|relative:locale`, `|datetime:locale:style`, `|date:locale:style`.
770
813
 
771
814
  Exemplos validos:
772
815
 
773
816
  - `${item.active|bool:Ativo:Inativo}`
774
817
  - `${item.createdAt|date:pt-BR:short}`
818
+ - `${item.occurredAt|datetime:pt-BR:short}`
819
+ - `${item.occurredAt|relative:pt-BR}` (exibe *"há 5 minutos"*)
775
820
  - `${item.status|map:done=Concluido;pending=Pendente}`
776
821
  - `${item.total|number:pt-BR:compact}`
822
+ - `${item.amount|currency:BRL:pt-BR}`
823
+ - `${item.occurredAt}|relative:pt-BR` (pipe top-level)
824
+ - `${item.createdAt}|datetime:pt-BR:short` (pipe top-level)
777
825
 
778
826
  ##### `actions[].showIf`
779
827
 
@@ -821,8 +869,18 @@ AI:
821
869
  | `layout.dividers` | Active | divisor no list |
822
870
  | `layout.model` | Active | classe host |
823
871
  | `layout.groupBy` | Active | agrupamento |
872
+ | `layout.rowLayout` | Active | grid colunar explicito por linha (`variant='list'`) |
873
+ | `layout.rowLayout.type` | Active | `'grid'` |
874
+ | `layout.rowLayout.gap` | Active | gap horizontal entre colunas |
875
+ | `layout.rowLayout.align` | Active | `start/center/end/stretch` |
876
+ | `layout.rowLayout.columns` | Active | array de colunas `{ id?, slot, width, align?, minWidth?, maxWidth? }` |
824
877
  | `layout.stickySectionHeader` | Declared-only | sem sticky runtime |
825
- | `layout.virtualScroll` | Declared-only | sem virtual runtime |
878
+ | `layout.virtualScroll` | Active | CDK Virtual Scroll + bounded scroll fallback com `expandable=true` |
879
+ | `layout.virtualScroll.enabled` | Active | habilita virtual scroll ou viewport delimitado |
880
+ | `layout.virtualScroll.itemSize` | Active | altura por item em px |
881
+ | `layout.virtualScroll.minBufferPx` | Active | buffer minimo em px |
882
+ | `layout.virtualScroll.maxBufferPx` | Active | buffer maximo em px |
883
+ | `layout.virtualScroll.viewportHeight` | Active | altura do viewport (px ou CSS length) |
826
884
  | `layout.pageSize` | Active | pagina remota |
827
885
  | `skin` | Active | bloco de skin |
828
886
  | `skin.type` | Active | classe skin |
@@ -838,6 +896,7 @@ AI:
838
896
  | `skin.inlineStyle` | Active | css inline sanitizado |
839
897
  | `selection` | Active | bloco de selecao |
840
898
  | `selection.mode` | Active | none/single/multiple |
899
+ | `selection.showControl` | Active | visibilidade explicita do radio/checkbox |
841
900
  | `selection.formControlName` | Active | binding form |
842
901
  | `selection.formControlPath` | Active | binding form |
843
902
  | `selection.compareBy` | Active | igualdade de seleção e ids |
@@ -867,6 +926,8 @@ AI:
867
926
  | `templating.<slot>.badge.expr` | Active | badge |
868
927
  | `templating.<slot>.badge.color` | Active | badge |
869
928
  | `templating.<slot>.badge.variant` | Active | badge |
929
+ | `templating.<slot>.quickView` | Active | `ResourceQuickViewBinding` governado no slot |
930
+ | `templating.<slot>.items[].quickView` | Active | `ResourceQuickViewBinding` por subitem de `compose` |
870
931
  | `templating.metaPlacement` | Active | side/line |
871
932
  | `templating.metaPrefixIcon` | Active | prefix icon |
872
933
  | `templating.statusPosition` | Active | inline/top-right |
@@ -883,12 +944,24 @@ AI:
883
944
  | `templating.featuresMode` | Active | icons+labels/icons-only/labels-only |
884
945
  | `templating.skeleton` | Active | skeleton bloco |
885
946
  | `templating.skeleton.count` | Active | skeleton count |
947
+ | `rules` | Active | bloco de regras condicionais por linha |
948
+ | `rules.itemStyles` | Active | estilos condicionais de linha |
949
+ | `rules.itemStyles[].id` | Active | id da regra |
950
+ | `rules.itemStyles[].condition` | Active | condicao Json Logic ou expressao booleana |
951
+ | `rules.itemStyles[].tone` | Active | `neutral/primary/success/warning/danger/muted` |
952
+ | `rules.itemStyles[].class` | Active | classes extras |
953
+ | `rules.itemStyles[].style` | Active | estilo inline extra |
954
+ | `rules.slotOverrides` | Active | overrides condicionais de slot |
955
+ | `rules.slotOverrides[].id` | Active | id do override |
956
+ | `rules.slotOverrides[].slot` | Active | slot alvo |
957
+ | `rules.slotOverrides[].condition` | Active | condicao Json Logic ou expressao booleana |
958
+ | `rules.slotOverrides[].template` | Active | `TemplateDef` substituto |
886
959
  | `expansion` | Partial | detail row governada |
887
960
  | `expansion.sections` | Active | secoes do detail row |
888
961
  | `expansion.sections[].id` | Active | id |
889
962
  | `expansion.sections[].title` | Active | title |
890
963
  | `expansion.sections[].type` | Active | info-list/chip-list/timeline/key-value/metadata/component/rich-content |
891
- | `expansion.sections[].itemsExpr` | Active | expr |
964
+ | `expansion.sections[].itemsExpr` | Active | expr (suporta placeholders com pipes) |
892
965
  | `expansion.sections[].document` | Active | `RichContentDocument` para `rich-content` |
893
966
  | `expansion.sections[].documentExpr` | Active | expr que resolve `RichContentDocument` |
894
967
  | `expansion.sections[].emptyLabel` | Active | empty state da secao |
@@ -899,11 +972,13 @@ AI:
899
972
  | `expansion.rendering.class` | Active | classe do shell |
900
973
  | `expansion.rendering.style` | Active | estilo adicional |
901
974
  | `actions` | Partial | bloco de acoes |
975
+ | `itemActions` | Active | alias compatível para `actions` |
902
976
  | `actions[].id` | Active | id |
903
977
  | `actions[].icon` | Active | icon |
904
978
  | `actions[].label` | Active | label |
905
979
  | `actions[].color` | Active | color |
906
- | `actions[].kind` | Active | icon/button |
980
+ | `actions[].kind` | Active | icon/button/menu-item |
981
+ | `actions[].placement` | Active | actions/trailing/menu |
907
982
  | `actions[].buttonVariant` | Active | raised/flat/stroked |
908
983
  | `actions[].showIf` | Active | visibilidade |
909
984
  | `actions[].emitPayload` | Declared-only | sem efeito runtime |
@@ -958,25 +1033,188 @@ Recomendacao corporativa:
958
1033
  ### Minimal valid
959
1034
 
960
1035
  ```json
961
- {}
1036
+ {
1037
+ "layout": {
1038
+ "variant": "list"
1039
+ },
1040
+ "templating": {
1041
+ "primary": {
1042
+ "type": "text",
1043
+ "expr": "${item.name}"
1044
+ }
1045
+ }
1046
+ }
962
1047
  ```
963
1048
 
964
1049
  ### Typical/common
965
1050
 
966
1051
  ```json
967
- {}
1052
+ {
1053
+ "layout": {
1054
+ "variant": "list",
1055
+ "density": "comfortable",
1056
+ "itemSpacing": "default"
1057
+ },
1058
+ "templating": {
1059
+ "leading": {
1060
+ "type": "icon",
1061
+ "expr": "person"
1062
+ },
1063
+ "primary": {
1064
+ "type": "text",
1065
+ "expr": "${item.nomeCompleto}"
1066
+ },
1067
+ "secondary": {
1068
+ "type": "text",
1069
+ "expr": "${item.cargo} · ${item.departamento}"
1070
+ },
1071
+ "meta": {
1072
+ "type": "date",
1073
+ "expr": "${item.dataAdmissao}"
1074
+ }
1075
+ }
1076
+ }
968
1077
  ```
969
1078
 
970
1079
  ### Advanced
971
1080
 
972
1081
  ```json
973
- {}
1082
+ {
1083
+ "layout": {
1084
+ "variant": "list",
1085
+ "itemAppearance": "card",
1086
+ "itemSpacing": "tight",
1087
+ "virtualScroll": {
1088
+ "enabled": true,
1089
+ "itemSize": 76,
1090
+ "viewportHeight": "360px"
1091
+ }
1092
+ },
1093
+ "skin": {
1094
+ "type": "glass"
1095
+ },
1096
+ "selection": {
1097
+ "mode": "none",
1098
+ "showControl": false
1099
+ },
1100
+ "interaction": {
1101
+ "expandable": true,
1102
+ "expandTrigger": "row+icon",
1103
+ "expandMode": "single"
1104
+ },
1105
+ "templating": {
1106
+ "leading": {
1107
+ "type": "icon",
1108
+ "expr": "${item.severidade|map:CRITICA=warning,ALTA=error_outline,MEDIA=info}",
1109
+ "color": "${item.severidade|map:CRITICA=warn,ALTA=warn,MEDIA=primary}"
1110
+ },
1111
+ "primary": {
1112
+ "type": "text",
1113
+ "expr": "${item.titulo}"
1114
+ },
1115
+ "secondary": {
1116
+ "type": "text",
1117
+ "expr": "${item.localizacao} · Protocolo ${item.protocolo}"
1118
+ },
1119
+ "meta": {
1120
+ "type": "relative",
1121
+ "expr": "${item.abertoEm}"
1122
+ },
1123
+ "metaPlacement": "side"
1124
+ },
1125
+ "rules": {
1126
+ "itemStyles": [
1127
+ {
1128
+ "id": "critical-tone",
1129
+ "condition": { "==": [{ "var": "row.severidade" }, "CRITICA"] },
1130
+ "tone": "danger"
1131
+ }
1132
+ ]
1133
+ },
1134
+ "expansion": {
1135
+ "rendering": {
1136
+ "shell": "attached",
1137
+ "columns": 1
1138
+ },
1139
+ "sections": [
1140
+ {
1141
+ "id": "telemetry",
1142
+ "title": "Telemetria",
1143
+ "type": "key-value",
1144
+ "itemsExpr": "{\"Protocolo\":\"${item.protocolo}\",\"Local\":\"${item.localizacao}\"}"
1145
+ }
1146
+ ]
1147
+ },
1148
+ "actions": [
1149
+ {
1150
+ "id": "dispatch",
1151
+ "label": "Despachar",
1152
+ "icon": "bolt",
1153
+ "kind": "icon",
1154
+ "placement": "trailing",
1155
+ "showIf": { "==": [{ "var": "row.status" }, "ABERTO"] }
1156
+ },
1157
+ {
1158
+ "id": "details",
1159
+ "label": "Ver detalhes",
1160
+ "icon": "visibility",
1161
+ "kind": "menu-item",
1162
+ "placement": "menu"
1163
+ }
1164
+ ]
1165
+ }
974
1166
  ```
975
1167
 
976
1168
  ### Enterprise scenario
977
1169
 
978
1170
  ```json
979
- {}
1171
+ {
1172
+ "dataSource": {
1173
+ "resourcePath": "incidentes",
1174
+ "sort": {
1175
+ "field": "abertoEm",
1176
+ "direction": "desc"
1177
+ }
1178
+ },
1179
+ "layout": {
1180
+ "variant": "list",
1181
+ "itemAppearance": "card",
1182
+ "pageSize": 20
1183
+ },
1184
+ "i18n": {
1185
+ "locale": "pt-BR",
1186
+ "currency": "BRL"
1187
+ },
1188
+ "selection": {
1189
+ "mode": "multiple",
1190
+ "compareBy": "id",
1191
+ "return": "id"
1192
+ },
1193
+ "templating": {
1194
+ "leading": {
1195
+ "type": "chip",
1196
+ "expr": "${item.codigo}",
1197
+ "variant": "outlined"
1198
+ },
1199
+ "primary": {
1200
+ "type": "text",
1201
+ "expr": "${item.nome ?? item.titulo}"
1202
+ },
1203
+ "secondary": {
1204
+ "type": "text",
1205
+ "expr": "${item.resumo}"
1206
+ },
1207
+ "meta": {
1208
+ "type": "datetime",
1209
+ "expr": "${item.dataCriacao}|pt-BR:short"
1210
+ }
1211
+ },
1212
+ "ui": {
1213
+ "showSearch": true,
1214
+ "searchField": "titulo",
1215
+ "showSort": true
1216
+ }
1217
+ }
980
1218
  ```
981
1219
 
982
1220
  ## Known limitations and mismatches