@praxisui/list 1.0.0-beta.8 → 3.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,65 @@
1
+ ---
2
+ title: "List"
3
+ slug: "list-overview"
4
+ description: "Visao geral do @praxisui/list com variantes de lista e cards, slots declarativos, acoes, agrupamento e selecao."
5
+ doc_type: "reference"
6
+ document_kind: "component-overview"
7
+ component: "list"
8
+ category: "components"
9
+ audience:
10
+ - "frontend"
11
+ - "host"
12
+ - "architect"
13
+ level: "intermediate"
14
+ status: "active"
15
+ owner: "praxis-ui"
16
+ tags:
17
+ - "list"
18
+ - "cards"
19
+ - "slots"
20
+ - "selection"
21
+ - "actions"
22
+ order: 40
23
+ icon: "view_list"
24
+ toc: true
25
+ sidebar: true
26
+ search_boost: 1.0
27
+ reading_time: 10
28
+ estimated_setup_time: 15
29
+ version: "1.0"
30
+ related_docs:
31
+ - "host-integration-guide"
32
+ - "consumer-integration-quickstart"
33
+ keywords:
34
+ - "cards"
35
+ - "grouping"
36
+ - "selection"
37
+ - "templating"
38
+ last_updated: "2026-03-07"
39
+ ---
40
+
1
41
  # @praxisui/list — Configurable List/Cards Component
2
42
 
43
+ ## Documentation
44
+
45
+ - Official documentation: https://praxisui.dev
46
+ - Quickstart reference app: https://github.com/codexrodrigues/praxis-ui-quickstart
47
+ - Recommended for: list and card experiences with templating, actions, grouping and selection in enterprise apps
48
+
49
+ ## When to use
50
+
51
+ - Exibir colecoes em formato de lista ou cards com a mesma base de configuracao
52
+ - Habilitar agrupamento, acoes e selecao sem criar um componente bespoke por tela
53
+ - Integrar dados locais ou remotos em experiencias de catalogo e backoffice
54
+
3
55
  Angular list/cards component for enterprise apps. Supports local or remote data, multiple layout variants, templating slots, actions, grouping and selection.
4
56
 
57
+ ## Customization Mode Contract
58
+
59
+ - `enableCustomization` is the canonical public input for runtime customization mode.
60
+ - Customization mode controls the in-app editor and AI assistant only. It does not change the list data mode.
61
+ - New hosts and generated snippets should use `enableCustomization`.
62
+
5
63
  ## Install
6
64
 
7
65
  ```bash
@@ -13,6 +71,7 @@ Peers (install in your app):
13
71
  - `rxjs` (>=7 <9)
14
72
  - `@praxisui/core` (icons, config storage, CRUD service)
15
73
  - Optional: `@praxisui/settings-panel` (to open the in-app list configuration editor)
74
+ - Optional: `@praxisui/dynamic-fields` (color picker used by the in-app editor)
16
75
 
17
76
  ## Quick Start
18
77
 
@@ -26,6 +85,7 @@ import { PraxisList } from '@praxisui/list';
26
85
  imports: [PraxisList],
27
86
  template: `
28
87
  <praxis-list
88
+ listId="products-list"
29
89
  [config]="config"
30
90
  (itemClick)="onItem($event)"
31
91
  (actionClick)="onAction($event)"
@@ -64,12 +124,85 @@ export class ListDemoComponent {
64
124
  }
65
125
  ```
66
126
 
127
+ ## Runtime Contract (Data Mode and Precedence)
128
+
129
+ Effective data mode resolution follows `ListDataService.stream()`:
130
+
131
+ 1. if `dataSource.data` exists, local mode is used;
132
+ 2. else if `dataSource.resourcePath` exists and `GenericCrudService` is available, remote mode is used;
133
+ 3. otherwise, empty mode is used.
134
+
135
+ Critical rule:
136
+ - local data has precedence over remote when both `dataSource.data` and `dataSource.resourcePath` are present.
137
+
138
+ Decision matrix (runtime today):
139
+
140
+ | `dataSource.data` | `dataSource.resourcePath` | Resolved mode | Data pipeline | Main surface |
141
+ | --- | --- | --- | --- | --- |
142
+ | array | any value | local | local array only | list/cards/tiles |
143
+ | missing/null | filled | remote | `/filter` with fallback `getAll()` on failure | list/cards/tiles + remote controls |
144
+ | missing/null | missing/empty | empty | none | empty state |
145
+
146
+ Important behavior:
147
+ - pagination/search/sort controls from `ui.*` are rendered only when `dataSource.resourcePath` is defined.
148
+ - remote mode uses `GenericCrudService.filter(query, pageable)` and falls back to `getAll()` when `/filter` fails.
149
+
150
+ ## Runtime Status Matrix (High-Impact Paths)
151
+
152
+ | JSON path | Runtime status | Notes |
153
+ | --- | --- | --- |
154
+ | `dataSource.data` | Active | Local mode source. |
155
+ | `dataSource.resourcePath` | Active | Remote mode source. |
156
+ | `layout.virtualScroll` | Declared-only | Accepted in config/editor but no runtime binding yet. |
157
+ | `layout.stickySectionHeader` | Declared-only | Accepted in config/editor but no runtime sticky behavior yet. |
158
+ | `actions[].emitPayload` | Declared-only | Authoring field only; `actionClick` payload shape is fixed. |
159
+ | `events.*` | Declared-only | Declarative mapping only; no dynamic event router in runtime. |
160
+ | `a11y.highContrast` / `a11y.reduceMotion` | Declared-only | No visual/runtime enforcement yet. |
161
+
162
+ ## Pagina de documentacao viva (showcase completo)
163
+
164
+ Para documentar o componente com exemplos live (layout, templating, selecao, acoes, skins e snippets),
165
+ use o componente `praxis-list-doc-page`:
166
+
167
+ ```html
168
+ <praxis-list-doc-page></praxis-list-doc-page>
169
+ ```
170
+
171
+ ```ts
172
+ import { Component } from '@angular/core';
173
+ import { PraxisListDocPageComponent } from '@praxisui/list';
174
+
175
+ @Component({
176
+ selector: 'app-list-doc-host',
177
+ standalone: true,
178
+ imports: [PraxisListDocPageComponent],
179
+ template: `<praxis-list-doc-page />`,
180
+ })
181
+ export class ListDocHostComponent {}
182
+ ```
183
+
184
+ Cobertura da pagina:
185
+ - Variantes `list`, `cards`, `tiles`.
186
+ - `density`, `lines`, `model`, `groupBy`, `dividers`.
187
+ - Slots `leading`, `primary`, `secondary`, `meta`, `trailing`, `sectionHeader`, `emptyState`.
188
+ - Tipos de template `text`, `icon`, `image`, `chip`, `rating`, `currency`, `date`, `html`.
189
+ - Selecao (`none`, `single`, `multiple`) com `FormControl` externo.
190
+ - Acoes com `showIf`, estilos `icon/button` e log de eventos.
191
+ - Skins `elevated`, `pill-soft`, `glass`, `gradient-tile`, `custom`.
192
+ - Snippets para host, config JSON e contrato remoto com `resourcePath`.
193
+
194
+ ## Persistência
195
+
196
+ - `listId` é obrigatório para salvar/carregar configurações.
197
+ - A chave usada no storage é `praxis-list-config-<component_id>` (via `ComponentKeyService`).
198
+ - Use `componentInstanceId` quando houver múltiplas listas com o mesmo `listId` na mesma rota.
199
+
67
200
  ## Remote Data (resourcePath)
68
201
 
69
202
  Provide `dataSource.resourcePath` to fetch data and (optionally) infer templating from backend schema.
70
203
 
71
204
  ```html
72
- <praxis-list [config]="{
205
+ <praxis-list listId="employees" [config]="{
73
206
  id: 'employees',
74
207
  dataSource: { resourcePath: 'employees', sort: ['name,asc'] },
75
208
  layout: { variant: 'list', lines: 2, groupBy: 'department' },
@@ -83,25 +216,51 @@ The component uses `GenericCrudService` from `@praxisui/core` when `resourcePath
83
216
 
84
217
  - `list` (default): Material list with optional selection and dividers.
85
218
  - `cards`: Card grid layout with the same templating slots.
219
+ - `tiles`: Modern grid layout (image + title + meta), ideal for catalogs.
86
220
 
87
221
  Layout options (`config.layout`):
88
222
  - `lines`: 1 | 2 | 3 controls visible text lines.
89
223
  - `dividers`: 'none' | 'between' | 'all'.
90
224
  - `groupBy`: string key to group items; section headers can be templated via `templating.sectionHeader`.
91
- - `pageSize`, `virtualScroll`, `density`, `model` for advanced tuning.
225
+ - `pageSize`, `density`, `model` are runtime-active.
226
+ - `virtualScroll` and `stickySectionHeader` are currently declared-only (no runtime binding yet).
227
+
228
+ ## Config Merging Behavior
229
+ Be aware that `applyConfigFromAdapter` replaces the entire `config` object. It does not perform a deep merge. Any local runtime overrides must be re-applied or managed carefully.
92
230
 
93
231
  ## Templating Slots
94
232
 
95
233
  Every slot accepts a `TemplateDef` with `type`, `expr`, optional `class` and `style`.
96
- - `leading`: 'icon' | 'image' with optional `badge`.
97
- - `primary`: 'text' | 'html' | 'date' | 'currency' | 'rating' | 'chip'.
234
+ - `leading`: 'icon' | 'image' | 'text' | 'chip' | 'rating' | 'html' with optional `badge`.
235
+ - `primary`: 'text' | 'html' | 'date' | 'currency'.
98
236
  - `secondary`: same as primary; shown when `lines > 1`.
99
- - `meta`: small text or chip/rating rendered inline or on the side (`metaPlacement`).
100
- - `trailing`: optional trailing text/chip.
237
+ - `meta`: small text or chip/rating/icon/image rendered inline or on the side (`metaPlacement`).
238
+ - `trailing`: optional trailing text/chip/icon/image.
101
239
  - `features`: array of `{ icon?, expr }` rendered below primary/secondary; control with `featuresVisible` and `featuresMode` ('icons+labels' | 'icons-only' | 'labels-only').
102
240
 
103
241
  Expressions use `${...}` to read from `item` (e.g., `${item.name}`). For `currency`, you may pass code/locale as `|:USD` or `|:USD:en-US`.
104
242
 
243
+ ### Rating props
244
+
245
+ ```json
246
+ {
247
+ "templating": {
248
+ "meta": {
249
+ "type": "rating",
250
+ "expr": "${item.rating}",
251
+ "props": { "rating": { "max": 5, "size": 16, "color": "primary" } }
252
+ }
253
+ }
254
+ }
255
+ ```
256
+
257
+ ### Colors
258
+
259
+ `color` accepts:
260
+ - theme colors (`primary`, `accent`, `warn`)
261
+ - M3 tokens (`var(--md-sys-color-*)`)
262
+ - custom colors (hex/rgb). The in-app editor offers a color picker.
263
+
105
264
  ## Actions
106
265
 
107
266
  Configure contextual item actions via `config.actions`:
@@ -115,8 +274,44 @@ actions: [
115
274
  ```
116
275
 
117
276
  - `kind`: 'icon' (default) or 'button'.
118
- - `showIf`: simple equality check is supported (left side must be an `${...}` expression).
119
- - `emitPayload`: choose what the action emits ('item' | 'id' | 'value').
277
+ - `showIf`: simple equality check is supported. Syntax: `"${item.field} == 'value'"`. Left side must be an interpolation expression.
278
+ - `emitPayload`: authoring field in the config/editor; current runtime `actionClick` emission does not change shape based on this field.
279
+
280
+ ### Global actions (command)
281
+
282
+ ```ts
283
+ actions: [
284
+ {
285
+ id: 'favorite',
286
+ icon: 'favorite',
287
+ label: 'Favorite',
288
+ command: 'global:api.post',
289
+ globalPayload: { url: '/api/favorite', body: { id: '${item.id}' } }
290
+ }
291
+ ]
292
+ ```
293
+
294
+ When `command` is set, `actionClick` is **not emitted** by default. Use `emitLocal: true` to emit both.
295
+
296
+ ### Confirmation and loading
297
+
298
+ ```ts
299
+ actions: [
300
+ {
301
+ id: 'delete',
302
+ icon: 'delete',
303
+ label: 'Delete',
304
+ command: 'global:api.patch',
305
+ showLoading: true,
306
+ confirmation: {
307
+ title: 'Confirm deletion',
308
+ message: 'Are you sure you want to delete this item?',
309
+ type: 'danger',
310
+ },
311
+ globalPayload: { url: '/api/items/${item.id}', body: { active: false } },
312
+ }
313
+ ]
314
+ ```
120
315
 
121
316
  ## Selection and Events
122
317
 
@@ -131,6 +326,25 @@ Outputs:
131
326
  - `(actionClick)`: `{ actionId, item, index }`
132
327
  - `(selectionChange)`: `{ mode, value, items, ids? }`
133
328
 
329
+ ## Known limitations and mismatches
330
+
331
+ 1. `layout.virtualScroll` and `layout.stickySectionHeader` exist in the contract/editor, but have no runtime implementation.
332
+ 2. `actions[].emitPayload` is accepted in config/editor, but does not change current `actionClick` payload format.
333
+ 3. `events.*` is declarative-only (no runtime dynamic routing).
334
+ 4. `a11y.highContrast` and `a11y.reduceMotion` are declarative-only at this stage.
335
+ 5. In remote mode, `/filter -> getAll()` fallback can increase network cost on large datasets.
336
+
337
+ ## Source of truth
338
+
339
+ - Canonical contract: `projects/praxis-list/src/lib/praxis-list.json-api.md`
340
+ - Runtime implementation:
341
+ - `projects/praxis-list/src/lib/components/praxis-list.component.ts`
342
+ - `projects/praxis-list/src/lib/components/praxis-list.component.html`
343
+ - `projects/praxis-list/src/lib/services/list-data.service.ts`
344
+ - Runtime specs:
345
+ - `projects/praxis-list/src/lib/components/praxis-list.component.spec.ts`
346
+ - `projects/praxis-list/src/lib/services/list-data.service.spec.ts`
347
+
134
348
  ## License
135
349
 
136
350
  Apache-2.0 — see `LICENSE` in this package or the repository root.