@praxisui/list 9.0.0-beta.1 → 9.0.0-beta.2
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 +78 -371
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "List"
|
|
3
3
|
slug: "list-overview"
|
|
4
|
-
description: "
|
|
4
|
+
description: "Public npm documentation for @praxisui/list: configurable list/card/tile layouts, templating slots, local or remote data, actions, export and selection."
|
|
5
5
|
doc_type: "reference"
|
|
6
6
|
document_kind: "component-overview"
|
|
7
7
|
component: "list"
|
|
@@ -24,7 +24,7 @@ icon: "view_list"
|
|
|
24
24
|
toc: true
|
|
25
25
|
sidebar: true
|
|
26
26
|
search_boost: 1.0
|
|
27
|
-
reading_time:
|
|
27
|
+
reading_time: 5
|
|
28
28
|
estimated_setup_time: 15
|
|
29
29
|
version: "1.0"
|
|
30
30
|
related_docs:
|
|
@@ -35,36 +35,14 @@ keywords:
|
|
|
35
35
|
- "grouping"
|
|
36
36
|
- "selection"
|
|
37
37
|
- "templating"
|
|
38
|
-
last_updated: "2026-
|
|
38
|
+
last_updated: "2026-06-16"
|
|
39
39
|
---
|
|
40
40
|
|
|
41
|
-
# @praxisui/list
|
|
41
|
+
# @praxisui/list
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
`@praxisui/list` renders configurable list, card and tile experiences for Praxis UI Angular applications. Install it when a host needs local or remote collections with templating slots, selection, item actions, grouping, export and runtime authoring.
|
|
44
44
|
|
|
45
|
-
|
|
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
|
-
|
|
55
|
-
Angular list/cards component for enterprise apps. Supports local or remote data, multiple layout variants, templating slots, actions, grouping and selection.
|
|
56
|
-
|
|
57
|
-
## Rich Content Convergence
|
|
58
|
-
|
|
59
|
-
- `mapListTemplateToRichContentP0(...)` exposes the canonical bridge from the current list templating vocabulary to the shared rich-content P0 contract in `@praxisui/core`.
|
|
60
|
-
- The bridge is intentionally narrow in `1.0`: `text`, `icon`, `image`, `chip -> badge`, `metric`, and `compose`.
|
|
61
|
-
- Legacy/runtime-only list templates such as `component`, `slot`, `html`, `rating`, `currency`, and `date` remain outside the shared rich-content `1.0` contract until their semantic normalization is closed.
|
|
62
|
-
|
|
63
|
-
## Customization Mode Contract
|
|
64
|
-
|
|
65
|
-
- `enableCustomization` is the canonical public input for runtime customization mode.
|
|
66
|
-
- Customization mode controls the in-app editor and AI assistant only. It does not change the list data mode.
|
|
67
|
-
- New hosts and generated snippets should use `enableCustomization`.
|
|
45
|
+
The package owns list presentation and the list config contract. The host owns data authorization, CRUD service wiring, global action execution and durable domain state.
|
|
68
46
|
|
|
69
47
|
## Install
|
|
70
48
|
|
|
@@ -72,21 +50,24 @@ Angular list/cards component for enterprise apps. Supports local or remote data,
|
|
|
72
50
|
npm i @praxisui/list@latest
|
|
73
51
|
```
|
|
74
52
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
- `
|
|
78
|
-
- `@praxisui/core
|
|
79
|
-
-
|
|
80
|
-
|
|
53
|
+
Peer dependencies:
|
|
54
|
+
|
|
55
|
+
- `@angular/common`, `@angular/core`, `@angular/forms`, `@angular/router`, `@angular/material` `^21.0.0`
|
|
56
|
+
- `@praxisui/core`, `@praxisui/dynamic-fields`, `@praxisui/rich-content`, `@praxisui/settings-panel`, `@praxisui/ai` `^9.0.0-beta.1`
|
|
57
|
+
- `rxjs` `>=7 <9`
|
|
58
|
+
|
|
59
|
+
Runtime dependency included by the package:
|
|
81
60
|
|
|
82
|
-
|
|
61
|
+
- `immer` `^10.1.1`
|
|
62
|
+
|
|
63
|
+
## Minimal Local List
|
|
83
64
|
|
|
84
65
|
```ts
|
|
85
66
|
import { Component } from '@angular/core';
|
|
86
|
-
import { PraxisList } from '@praxisui/list';
|
|
67
|
+
import { PraxisList, type PraxisListConfig } from '@praxisui/list';
|
|
87
68
|
|
|
88
69
|
@Component({
|
|
89
|
-
selector: 'app-list
|
|
70
|
+
selector: 'app-products-list',
|
|
90
71
|
standalone: true,
|
|
91
72
|
imports: [PraxisList],
|
|
92
73
|
template: `
|
|
@@ -96,373 +77,99 @@ import { PraxisList } from '@praxisui/list';
|
|
|
96
77
|
(itemClick)="onItem($event)"
|
|
97
78
|
(actionClick)="onAction($event)"
|
|
98
79
|
(selectionChange)="onSelection($event)"
|
|
99
|
-
(exportAction)="onExport($event)"
|
|
100
80
|
/>
|
|
101
81
|
`,
|
|
102
82
|
})
|
|
103
|
-
export class
|
|
104
|
-
config = {
|
|
83
|
+
export class ProductsListComponent {
|
|
84
|
+
readonly config: PraxisListConfig = {
|
|
105
85
|
id: 'products-list',
|
|
106
|
-
dataSource: {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
86
|
+
dataSource: {
|
|
87
|
+
data: [
|
|
88
|
+
{ id: 1, name: 'Phone', price: 699 },
|
|
89
|
+
{ id: 2, name: 'Laptop', price: 1499 },
|
|
90
|
+
],
|
|
91
|
+
},
|
|
110
92
|
layout: { variant: 'list', lines: 2, dividers: 'between' },
|
|
111
93
|
selection: { mode: 'single', return: 'item', compareBy: 'id' },
|
|
112
94
|
templating: {
|
|
113
|
-
leading: { type: 'image', expr: '${item.image}', imageAlt: 'Product image' },
|
|
114
95
|
primary: { type: 'text', expr: '${item.name}' },
|
|
115
|
-
secondary: { type: 'currency', expr: '${item.price}
|
|
116
|
-
meta: { type: 'rating', expr: '${item.rating}' },
|
|
117
|
-
trailing: { type: 'chip', expr: 'In stock', color: 'primary' },
|
|
118
|
-
features: [
|
|
119
|
-
{ icon: 'grade', expr: '${item.rating}' },
|
|
120
|
-
],
|
|
96
|
+
secondary: { type: 'currency', expr: '${item.price}|USD' },
|
|
121
97
|
},
|
|
122
98
|
actions: [
|
|
123
|
-
{ id: '
|
|
124
|
-
{ id: 'buy', icon: 'shopping_cart', kind: 'button', buttonVariant: 'stroked', label: 'Buy' },
|
|
99
|
+
{ id: 'details', icon: 'open_in_new', label: 'Details' },
|
|
125
100
|
],
|
|
126
|
-
|
|
127
|
-
enabled: true,
|
|
128
|
-
formats: ['csv', 'json'],
|
|
129
|
-
general: { scope: 'auto', includeFields: ['id', 'name', 'price'] },
|
|
130
|
-
},
|
|
131
|
-
} satisfies import('@praxisui/list').PraxisListConfig;
|
|
101
|
+
};
|
|
132
102
|
|
|
133
|
-
onItem(
|
|
134
|
-
onAction(
|
|
135
|
-
onSelection(
|
|
136
|
-
onExport(e: any) { console.log('exportAction', e); }
|
|
103
|
+
onItem(event: unknown): void {}
|
|
104
|
+
onAction(event: unknown): void {}
|
|
105
|
+
onSelection(event: unknown): void {}
|
|
137
106
|
}
|
|
138
107
|
```
|
|
139
108
|
|
|
140
|
-
##
|
|
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
|
-
|
|
151
|
-
## Runtime Contract (Data Mode and Precedence)
|
|
152
|
-
|
|
153
|
-
Effective data mode resolution follows `ListDataService.stream()`:
|
|
154
|
-
|
|
155
|
-
1. if `dataSource.data` exists, local mode is used;
|
|
156
|
-
2. else if `dataSource.resourcePath` exists and `GenericCrudService` is available, remote mode is used;
|
|
157
|
-
3. otherwise, empty mode is used.
|
|
158
|
-
|
|
159
|
-
Critical rule:
|
|
160
|
-
- local data has precedence over remote when both `dataSource.data` and `dataSource.resourcePath` are present.
|
|
161
|
-
|
|
162
|
-
Decision matrix (runtime today):
|
|
163
|
-
|
|
164
|
-
| `dataSource.data` | `dataSource.resourcePath` | Resolved mode | Data pipeline | Main surface |
|
|
165
|
-
| --- | --- | --- | --- | --- |
|
|
166
|
-
| array | any value | local | local array only | list/cards/tiles |
|
|
167
|
-
| missing/null | filled | remote | `/filter` with fallback `getAll()` on failure | list/cards/tiles + remote controls |
|
|
168
|
-
| missing/null | missing/empty | empty | none | empty state |
|
|
169
|
-
|
|
170
|
-
Important behavior:
|
|
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.
|
|
174
|
-
- remote mode uses `GenericCrudService.filter(query, pageable)` and falls back to `getAll()` when `/filter` fails.
|
|
175
|
-
|
|
176
|
-
## Runtime Status Matrix (High-Impact Paths)
|
|
177
|
-
|
|
178
|
-
| JSON path | Runtime status | Notes |
|
|
179
|
-
| --- | --- | --- |
|
|
180
|
-
| `dataSource.data` | Active | Local mode source. |
|
|
181
|
-
| `dataSource.resourcePath` | Active | Remote mode source. |
|
|
182
|
-
| `layout.virtualScroll` | Declared-only | Accepted in config/editor but no runtime binding yet. |
|
|
183
|
-
| `layout.stickySectionHeader` | Declared-only | Accepted in config/editor but no runtime sticky behavior yet. |
|
|
184
|
-
| `actions[].emitPayload` | Declared-only | Authoring field only; `actionClick` payload shape is fixed. |
|
|
185
|
-
| `events.*` | Declared-only | Declarative mapping only; no dynamic event router in runtime. |
|
|
186
|
-
| `a11y.highContrast` / `a11y.reduceMotion` | Declared-only | No visual/runtime enforcement yet. |
|
|
187
|
-
|
|
188
|
-
## Pagina de documentacao viva (showcase completo)
|
|
189
|
-
|
|
190
|
-
Para documentar o componente com exemplos live (layout, templating, selecao, acoes, skins e snippets),
|
|
191
|
-
use o componente `praxis-list-doc-page`:
|
|
192
|
-
|
|
193
|
-
```html
|
|
194
|
-
<praxis-list-doc-page></praxis-list-doc-page>
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
```ts
|
|
198
|
-
import { Component } from '@angular/core';
|
|
199
|
-
import { PraxisListDocPageComponent } from '@praxisui/list';
|
|
200
|
-
|
|
201
|
-
@Component({
|
|
202
|
-
selector: 'app-list-doc-host',
|
|
203
|
-
standalone: true,
|
|
204
|
-
imports: [PraxisListDocPageComponent],
|
|
205
|
-
template: `<praxis-list-doc-page />`,
|
|
206
|
-
})
|
|
207
|
-
export class ListDocHostComponent {}
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
Cobertura da pagina:
|
|
211
|
-
- Variantes `list`, `cards`, `tiles`.
|
|
212
|
-
- `density`, `lines`, `model`, `groupBy`, `dividers`.
|
|
213
|
-
- Slots `leading`, `primary`, `secondary`, `meta`, `trailing`, `sectionHeader`, `emptyState`.
|
|
214
|
-
- Tipos de template `text`, `icon`, `image`, `chip`, `rating`, `currency`, `date`, `html`.
|
|
215
|
-
- Selecao (`none`, `single`, `multiple`) com `FormControl` externo.
|
|
216
|
-
- Acoes com `showIf`, estilos `icon/button` e log de eventos.
|
|
217
|
-
- Skins `elevated`, `pill-soft`, `glass`, `gradient-tile`, `custom`.
|
|
218
|
-
- Snippets para host, config JSON e contrato remoto com `resourcePath`.
|
|
109
|
+
## Remote Data
|
|
219
110
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
- `listId` é obrigatório para salvar/carregar configurações.
|
|
223
|
-
- A chave usada no storage é `praxis-list-config-<component_id>` (via `ComponentKeyService`).
|
|
224
|
-
- Use `componentInstanceId` quando houver múltiplas listas com o mesmo `listId` na mesma rota.
|
|
225
|
-
|
|
226
|
-
## Remote Data (resourcePath)
|
|
227
|
-
|
|
228
|
-
Provide `dataSource.resourcePath` to fetch data and (optionally) infer templating from backend schema.
|
|
111
|
+
Use `dataSource.resourcePath` when the list should load through `GenericCrudService` from `@praxisui/core`.
|
|
229
112
|
|
|
230
113
|
```html
|
|
231
|
-
<praxis-list
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
## Layout Variants
|
|
242
|
-
|
|
243
|
-
- `list` (default): Material list with optional selection and dividers.
|
|
244
|
-
- `cards`: Card grid layout with the same templating slots.
|
|
245
|
-
- `tiles`: Modern grid layout (image + title + meta), ideal for catalogs.
|
|
246
|
-
|
|
247
|
-
Layout options (`config.layout`):
|
|
248
|
-
- `lines`: 1 | 2 | 3 controls visible text lines.
|
|
249
|
-
- `dividers`: 'none' | 'between' | 'all'.
|
|
250
|
-
- `groupBy`: string key to group items; section headers can be templated via `templating.sectionHeader`.
|
|
251
|
-
- `pageSize`, `density`, `model` are runtime-active.
|
|
252
|
-
- `virtualScroll` and `stickySectionHeader` are currently declared-only (no runtime binding yet).
|
|
253
|
-
|
|
254
|
-
## Config Merging Behavior
|
|
255
|
-
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.
|
|
256
|
-
|
|
257
|
-
## Templating Slots
|
|
258
|
-
|
|
259
|
-
Every slot accepts a `TemplateDef` with `type`, `expr`, optional `class` and `style`.
|
|
260
|
-
- `leading`: 'icon' | 'image' | 'text' | 'chip' | 'rating' | 'html' with optional `badge`.
|
|
261
|
-
- `primary`: 'text' | 'html' | 'date' | 'currency'.
|
|
262
|
-
- `secondary`: same as primary; shown when `lines > 1`.
|
|
263
|
-
- `meta`: small text or chip/rating/icon/image rendered inline or on the side (`metaPlacement`).
|
|
264
|
-
- `trailing`: optional trailing text/chip/icon/image.
|
|
265
|
-
- `features`: array of `{ icon?, expr }` rendered below primary/secondary; control with `featuresVisible` and `featuresMode` ('icons+labels' | 'icons-only' | 'labels-only').
|
|
266
|
-
|
|
267
|
-
Expressions use `${...}` to read from `item` (e.g., `${item.name}`). For `currency`, you may pass code/locale as `|USD` or `|USD:en-US`. When `config.i18n.locale` and `config.i18n.currency` are present, `date`, `number` and `currency` can omit args and use those defaults.
|
|
268
|
-
|
|
269
|
-
Nota de plataforma:
|
|
270
|
-
- o contrato público da list continua sendo templating/DSL + `config.i18n`.
|
|
271
|
-
- quando `config.i18n.localization`, `config.i18n.locale` e `config.i18n.currency` estiverem presentes, os pipes `date`, `number` e `currency` reaproveitam os defaults canônicos do core quando os argumentos são omitidos.
|
|
272
|
-
- `valuePresentation` não é um bloco público authorável da list.
|
|
273
|
-
|
|
274
|
-
### Rating props
|
|
275
|
-
|
|
276
|
-
```json
|
|
277
|
-
{
|
|
278
|
-
"templating": {
|
|
279
|
-
"meta": {
|
|
280
|
-
"type": "rating",
|
|
281
|
-
"expr": "${item.rating}",
|
|
282
|
-
"props": { "rating": { "max": 5, "size": 16, "color": "primary" } }
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
### Colors
|
|
289
|
-
|
|
290
|
-
`color` accepts:
|
|
291
|
-
- theme colors (`primary`, `accent`, `warn`)
|
|
292
|
-
- M3 tokens (`var(--md-sys-color-*)`)
|
|
293
|
-
- custom colors (hex/rgb). The in-app editor offers a color picker.
|
|
294
|
-
|
|
295
|
-
## Actions
|
|
296
|
-
|
|
297
|
-
Configure contextual item actions via `config.actions`:
|
|
298
|
-
|
|
299
|
-
```ts
|
|
300
|
-
actions: [
|
|
301
|
-
{ id: 'edit', icon: 'edit', label: 'Edit' },
|
|
302
|
-
{ id: 'delete', icon: 'delete', color: 'warn', showIf: { "==": [{ "var": "row.status" }, "active"] } },
|
|
303
|
-
{ id: 'details', kind: 'button', buttonVariant: 'raised', label: 'Details' },
|
|
304
|
-
]
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
- `kind`: 'icon' (default) or 'button'.
|
|
308
|
-
- `showIf`: use Json Logic. Example: `{ "==": [{ "var": "row.status" }, "active"] }`.
|
|
309
|
-
- `emitPayload`: authoring field in the config/editor; current runtime `actionClick` emission does not change shape based on this field.
|
|
310
|
-
|
|
311
|
-
### Global actions
|
|
312
|
-
|
|
313
|
-
```ts
|
|
314
|
-
actions: [
|
|
315
|
-
{
|
|
316
|
-
id: 'favorite',
|
|
317
|
-
icon: 'favorite',
|
|
318
|
-
label: 'Favorite',
|
|
319
|
-
globalAction: {
|
|
320
|
-
actionId: 'api.post',
|
|
321
|
-
payload: { url: '/api/favorite', body: { id: '${item.id}' } }
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
]
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
When `globalAction` is set, `actionClick` is **not emitted** by default. Use `emitLocal: true` to emit both.
|
|
328
|
-
Prefer structured `payload` in visual authoring. `payloadExpr` remains an explicit advanced escape hatch in
|
|
329
|
-
`GlobalActionRef`; when present without `payload`, the runtime forwards the ref to `GlobalActionService` without
|
|
330
|
-
synthetic `{ item, index }` payload so the global action can evaluate the expression against its own execution context.
|
|
331
|
-
Changing `actionId` in the editor clears stale payload from the previous action.
|
|
332
|
-
|
|
333
|
-
## Conditional rules
|
|
334
|
-
|
|
335
|
-
`rules.itemStyles` and `rules.slotOverrides` use Json Logic in the row context (`{ row: item }`). Existing flat rule fields are still supported, and the runtime also accepts canonical effect arrays aligned with `PraxisRuntimeConditionalEffectRule`.
|
|
336
|
-
|
|
337
|
-
```ts
|
|
338
|
-
rules: {
|
|
339
|
-
itemStyles: [
|
|
340
|
-
{
|
|
341
|
-
id: 'risk-critical',
|
|
342
|
-
condition: { "===": [{ "var": "row.risk" }, "critical"] },
|
|
343
|
-
effects: [
|
|
344
|
-
{
|
|
345
|
-
kind: 'item-style',
|
|
346
|
-
class: 'risk-critical',
|
|
347
|
-
border: '2px solid #b00020',
|
|
348
|
-
background: '#fde7ec',
|
|
349
|
-
},
|
|
350
|
-
],
|
|
351
|
-
},
|
|
352
|
-
],
|
|
353
|
-
slotOverrides: [
|
|
354
|
-
{
|
|
355
|
-
id: 'risk-icon',
|
|
356
|
-
slot: 'trailing',
|
|
357
|
-
condition: { "===": [{ "var": "row.risk" }, "critical"] },
|
|
358
|
-
effects: [
|
|
359
|
-
{
|
|
360
|
-
kind: 'slot-override',
|
|
361
|
-
template: { type: 'icon', expr: 'priority_high', color: 'warn' },
|
|
362
|
-
class: 'risk-icon',
|
|
363
|
-
},
|
|
364
|
-
],
|
|
365
|
-
},
|
|
366
|
-
],
|
|
367
|
-
}
|
|
114
|
+
<praxis-list
|
|
115
|
+
listId="employees"
|
|
116
|
+
[config]="{
|
|
117
|
+
id: 'employees',
|
|
118
|
+
dataSource: { resourcePath: 'employees', sort: ['name,asc'] },
|
|
119
|
+
layout: { variant: 'cards', lines: 2, groupBy: 'department' },
|
|
120
|
+
templating: { primary: { type: 'text', expr: '${item.name}' } }
|
|
121
|
+
}"
|
|
122
|
+
/>
|
|
368
123
|
```
|
|
369
124
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
For internal navigation from a row or item button, use `navigation.openRoute` and bind the selected item id into `query` or `state`:
|
|
373
|
-
|
|
374
|
-
```ts
|
|
375
|
-
actions: [
|
|
376
|
-
{
|
|
377
|
-
id: 'details',
|
|
378
|
-
icon: 'open_in_new',
|
|
379
|
-
label: 'Open details',
|
|
380
|
-
globalAction: {
|
|
381
|
-
actionId: 'navigation.openRoute',
|
|
382
|
-
payload: {
|
|
383
|
-
path: '/clientes/detalhe',
|
|
384
|
-
query: { id: '${item.id}' },
|
|
385
|
-
},
|
|
386
|
-
},
|
|
387
|
-
}
|
|
388
|
-
]
|
|
389
|
-
```
|
|
125
|
+
Data mode resolution is deterministic:
|
|
390
126
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
actions: [
|
|
395
|
-
{
|
|
396
|
-
id: 'delete',
|
|
397
|
-
icon: 'delete',
|
|
398
|
-
label: 'Delete',
|
|
399
|
-
globalAction: {
|
|
400
|
-
actionId: 'api.patch',
|
|
401
|
-
payload: { url: '/api/items/${item.id}', body: { active: false } },
|
|
402
|
-
},
|
|
403
|
-
showLoading: true,
|
|
404
|
-
confirmation: {
|
|
405
|
-
title: 'Confirm deletion',
|
|
406
|
-
message: 'Are you sure you want to delete this item?',
|
|
407
|
-
type: 'danger',
|
|
408
|
-
},
|
|
409
|
-
}
|
|
410
|
-
]
|
|
411
|
-
```
|
|
127
|
+
- `dataSource.data` wins and uses local mode.
|
|
128
|
+
- `dataSource.resourcePath` uses remote mode when no local data is present.
|
|
129
|
+
- no local data and no resource path renders the empty state.
|
|
412
130
|
|
|
413
|
-
|
|
131
|
+
Remote controls are rendered when `resourcePath` is present. The runtime uses `/filter` through `GenericCrudService.filter(query, pageable)` and falls back to `getAll()` when `/filter` fails.
|
|
414
132
|
|
|
415
|
-
|
|
416
|
-
- `mode`: 'none' | 'single' | 'multiple'.
|
|
417
|
-
- `compareBy`: property used to track items.
|
|
418
|
-
- `return`: 'value' | 'item' | 'id' for `selectionChange` payload.
|
|
419
|
-
- Bind to an external `FormControl` via `formControlName`/`formControlPath` when using `form`.
|
|
133
|
+
## Main Inputs And Outputs
|
|
420
134
|
|
|
421
|
-
|
|
422
|
-
- `
|
|
423
|
-
- `
|
|
424
|
-
- `
|
|
135
|
+
- `config: PraxisListConfig`: list/card/tile configuration.
|
|
136
|
+
- `listId: string`: required stable id for persisted configuration.
|
|
137
|
+
- `componentInstanceId?: string`: disambiguates repeated instances on the same route.
|
|
138
|
+
- `configPersistenceStrategy: 'local-first' | 'input-first'`: config restore precedence.
|
|
139
|
+
- `queryContext?: PraxisDataQueryContext`: runtime query context projected into remote data.
|
|
140
|
+
- `form?: FormGroup`: external form context for selection/form bindings.
|
|
141
|
+
- `enableCustomization: boolean`: opens editor and semantic assistant affordances.
|
|
142
|
+
- `itemClick`, `actionClick`, `selectionChange`, `exportAction`: public events.
|
|
425
143
|
|
|
426
|
-
##
|
|
144
|
+
## Configuration Highlights
|
|
427
145
|
|
|
428
|
-
|
|
146
|
+
- Layout variants: `list`, `cards`, `tiles`.
|
|
147
|
+
- Runtime-active layout fields include `lines`, `dividers`, `groupBy`, `pageSize`, `density` and `model`.
|
|
148
|
+
- Templating slots include `leading`, `primary`, `secondary`, `meta`, `trailing`, `features`, `sectionHeader` and `emptyState`.
|
|
149
|
+
- Template expressions use `${item.field}`. Currency/date/number templates can use config i18n defaults.
|
|
150
|
+
- Selection supports `none`, `single` and `multiple`, with return modes `value`, `item` or `id`.
|
|
151
|
+
- Item actions can emit local events or delegate to `GlobalActionService`; collection export uses the shared `@praxisui/core` contract for `csv`, `json`, `excel`, `pdf` and `print`.
|
|
429
152
|
|
|
430
|
-
|
|
431
|
-
- **Config Schema:** `PraxisListConfig`
|
|
432
|
-
- **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.
|
|
433
|
-
- **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.
|
|
434
|
-
- **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.
|
|
435
|
-
- **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.
|
|
436
|
-
- **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.
|
|
153
|
+
## Known Runtime Boundaries
|
|
437
154
|
|
|
438
|
-
|
|
155
|
+
Some config paths are currently editor/round-trip fields only: `layout.virtualScroll`, `layout.stickySectionHeader`, `actions[].emitPayload`, `events.*`, `a11y.highContrast` and `a11y.reduceMotion`.
|
|
439
156
|
|
|
440
|
-
|
|
157
|
+
Do not document those as active runtime behavior in app-specific guides until the component implements them.
|
|
441
158
|
|
|
442
|
-
|
|
443
|
-
- Business-rule, policy, compliance, publication, materialization or enforcement prompts are routed to governed `domain-rules/intake` handoff and are not applied as local list configuration.
|
|
444
|
-
- Free JSON patches from the backend are rejected. Local apply remains blocked until the response is compiled from a manifest-backed `componentEditPlan` validated against `PRAXIS_LIST_AUTHORING_MANIFEST`.
|
|
445
|
-
- `ListAiAdapter.applyPatch(...)` remains available for legacy/editor internals, but the new assistant turn flow does not use it as an ungoverned patch path.
|
|
159
|
+
## Authoring
|
|
446
160
|
|
|
447
|
-
|
|
161
|
+
`enableCustomization` opens the canonical list editor and semantic assistant flow. `PRAXIS_LIST_AUTHORING_MANIFEST` is the executable authoring contract for template slots, actions, empty state, selection, layout, data binding, rules, skin, export, localization, accessibility and declared-only warnings.
|
|
448
162
|
|
|
449
|
-
|
|
450
|
-
2. `actions[].emitPayload` is accepted in config/editor, but does not change current `actionClick` payload format.
|
|
451
|
-
3. `events.*` is declarative-only (no runtime dynamic routing).
|
|
452
|
-
4. `a11y.highContrast` and `a11y.reduceMotion` are declarative-only at this stage.
|
|
453
|
-
5. In remote mode, `/filter -> getAll()` fallback can increase network cost on large datasets.
|
|
163
|
+
Free JSON patches from AI flows are not the public authoring contract; local apply must be compiled from a manifest-backed `componentEditPlan`.
|
|
454
164
|
|
|
455
|
-
##
|
|
165
|
+
## Public API Snapshot
|
|
456
166
|
|
|
457
|
-
|
|
458
|
-
- Runtime implementation:
|
|
459
|
-
- `projects/praxis-list/src/lib/components/praxis-list.component.ts`
|
|
460
|
-
- `projects/praxis-list/src/lib/components/praxis-list.component.html`
|
|
461
|
-
- `projects/praxis-list/src/lib/services/list-data.service.ts`
|
|
462
|
-
- Runtime specs:
|
|
463
|
-
- `projects/praxis-list/src/lib/components/praxis-list.component.spec.ts`
|
|
464
|
-
- `projects/praxis-list/src/lib/services/list-data.service.spec.ts`
|
|
167
|
+
Main exports include `PraxisList`, editor components, `PraxisListConfig`, list data services, templating/rich-content/selection adapters, metadata provider, list i18n helpers, AI capabilities, `PRAXIS_LIST_AUTHORING_MANIFEST` and `PraxisListDocPageComponent`.
|
|
465
168
|
|
|
466
|
-
##
|
|
169
|
+
## Official Links
|
|
467
170
|
|
|
468
|
-
|
|
171
|
+
- Documentation: https://praxisui.dev/components/list
|
|
172
|
+
- Live demo: https://praxis-ui-4e602.web.app
|
|
173
|
+
- Quickstart repository: https://github.com/codexrodrigues/praxis-ui-quickstart
|
|
174
|
+
- API quickstart repository: https://github.com/codexrodrigues/praxis-api-quickstart-public
|
|
175
|
+
- Source and issues: https://github.com/codexrodrigues/praxis-ui-angular
|
package/package.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@praxisui/list",
|
|
3
|
-
"version": "9.0.0-beta.
|
|
3
|
+
"version": "9.0.0-beta.2",
|
|
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
8
|
"@angular/material": "^21.0.0",
|
|
9
|
-
"@praxisui/dynamic-fields": "^9.0.0-beta.
|
|
9
|
+
"@praxisui/dynamic-fields": "^9.0.0-beta.2",
|
|
10
10
|
"rxjs": ">=7 <9",
|
|
11
11
|
"@angular/forms": "^21.0.0",
|
|
12
12
|
"@angular/router": "^21.0.0",
|
|
13
|
-
"@praxisui/ai": "^9.0.0-beta.
|
|
14
|
-
"@praxisui/core": "^9.0.0-beta.
|
|
15
|
-
"@praxisui/rich-content": "^9.0.0-beta.
|
|
16
|
-
"@praxisui/settings-panel": "^9.0.0-beta.
|
|
13
|
+
"@praxisui/ai": "^9.0.0-beta.2",
|
|
14
|
+
"@praxisui/core": "^9.0.0-beta.2",
|
|
15
|
+
"@praxisui/rich-content": "^9.0.0-beta.2",
|
|
16
|
+
"@praxisui/settings-panel": "^9.0.0-beta.2"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"tslib": "^2.3.0",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"repository": {
|
|
27
27
|
"type": "git",
|
|
28
|
-
"url": "https://github.com/codexrodrigues/praxis-ui-angular"
|
|
28
|
+
"url": "git+https://github.com/codexrodrigues/praxis-ui-angular.git"
|
|
29
29
|
},
|
|
30
30
|
"homepage": "https://praxisui.dev",
|
|
31
31
|
"bugs": {
|