@xiriframework/xiri-ng 0.2.26 → 0.2.28
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/fesm2022/xiriframework-xiri-ng.mjs +210 -210
- package/fesm2022/xiriframework-xiri-ng.mjs.map +1 -1
- package/package.json +3 -2
- package/skills/xiri-ng-expert/SKILL.md +393 -0
- package/skills/xiri-ng-expert/evals/evals.json +64 -0
- package/skills/xiri-ng-expert/references/components.md +918 -0
- package/skills/xiri-ng-expert/references/dyncomponent.md +130 -0
- package/skills/xiri-ng-expert/references/form-fields.md +282 -0
- package/skills/xiri-ng-expert/references/setup.md +177 -0
- package/skills/xiri-ng-expert/references/table.md +277 -0
- package/skills/xiri-ng-expert/references/theming-i18n.md +120 -0
- package/types/xiriframework-xiri-ng.d.ts.map +1 -1
|
@@ -0,0 +1,918 @@
|
|
|
1
|
+
# Components — xiri-ng Reference
|
|
2
|
+
|
|
3
|
+
Kompakt-Signaturen aller Komponenten die in `public-api.ts` exportiert werden. Inputs + Outputs mit Typen.
|
|
4
|
+
|
|
5
|
+
## Form & Dialog
|
|
6
|
+
|
|
7
|
+
### xiri-form
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
@input.required settings: XiriFormSettings;
|
|
11
|
+
|
|
12
|
+
interface XiriFormSettings {
|
|
13
|
+
load?: boolean; // Auto-load url im ngOnInit
|
|
14
|
+
url: string;
|
|
15
|
+
fields?: XiriFormField[]; // Init-Fields wenn load=false
|
|
16
|
+
buttons?: XiriButton[];
|
|
17
|
+
header?: string;
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Outputs: keine.
|
|
22
|
+
|
|
23
|
+
### xiri-dialog (via MatDialog)
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
dialog.open(XiriDialogComponent, {
|
|
27
|
+
data: XiriDialogSettings,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
interface XiriDialogSettings {
|
|
31
|
+
url?: string;
|
|
32
|
+
size?: string; // Default '600px'
|
|
33
|
+
type: 'form' | 'data' | 'question' | 'waiting' | 'table';
|
|
34
|
+
data?: any;
|
|
35
|
+
filter?: any;
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Bei `type: 'table'` wird der Backend-`content` (mit `data` + `fields`) direkt als `XiriRawTableSettings` an die eingebettete `xiri-raw-table` durchgereicht. Optionales `showHeader: true` im content (Backend: `dialog.Dialog.WithTableHeader()`) aktiviert die Spalten-Header-Zeile — Default aus.
|
|
40
|
+
|
|
41
|
+
### xiri-query
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
@input.required settings: XiriQuerySettings;
|
|
45
|
+
@input dyncomponent: TemplateRef<any>;
|
|
46
|
+
|
|
47
|
+
interface XiriQuerySettings {
|
|
48
|
+
fields?: XiriFormField[];
|
|
49
|
+
dyn?: XiriDynData[]; // Initiale Komponenten (Results)
|
|
50
|
+
url?: string; // POST-URL bei Filter-Change
|
|
51
|
+
buttonline?: XiriDynData;
|
|
52
|
+
extra?: any;
|
|
53
|
+
saveState?: boolean;
|
|
54
|
+
saveStateId?: string;
|
|
55
|
+
collapsed?: boolean;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@output change: EventEmitter<any>; // debounced 300ms
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### xiri-alert (via MatDialog)
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
dialog.open(XiriAlertComponent, {
|
|
65
|
+
data: { header: string; text: string; icon: string; buttons: XiriButton[] },
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Cards & Links
|
|
70
|
+
|
|
71
|
+
### xiri-card
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
@input.required settings: XiriCardSettings;
|
|
75
|
+
|
|
76
|
+
interface XiriCardSettings {
|
|
77
|
+
url?: string; // POST mit null → Load
|
|
78
|
+
reload?: boolean;
|
|
79
|
+
data?: any;
|
|
80
|
+
fields?: XiriTableField[]; // Card als Mini-Table
|
|
81
|
+
components?: XiriDynData[]; // Multi-Component-Modus (xcol-Grid mit Sub-Components)
|
|
82
|
+
header?: string;
|
|
83
|
+
headerSub?: string;
|
|
84
|
+
headerIcon?: string;
|
|
85
|
+
headerIconColor?: XiriColor;
|
|
86
|
+
buttonsTop?: XiriButtonlineSettings;
|
|
87
|
+
buttonsBottom?: XiriButtonlineSettings;
|
|
88
|
+
dense?: number;
|
|
89
|
+
forceMinWidth?: boolean;
|
|
90
|
+
showHeader?: boolean; // Default false. Bei true zeigt die eingebettete
|
|
91
|
+
// xiri-raw-table die <thead>-Zeile mit Spalten-Headern.
|
|
92
|
+
// Backend setzt es via card.*Card.WithTableHeader().
|
|
93
|
+
collapsible?: boolean;
|
|
94
|
+
collapsed?: boolean;
|
|
95
|
+
maxHeight?: string;
|
|
96
|
+
padding?: string; // 'xs'|'sm'|'md'|'lg'|'xl' Token oder CSS-Wert.
|
|
97
|
+
// Wirkt nur im Multi-Component-Modus.
|
|
98
|
+
// Default 'md'. Auf xs-Viewport (<576px) immer 8px.
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Render-Reihenfolge im Card-Body:**
|
|
103
|
+
|
|
104
|
+
1. Wenn `components` befüllt ist → `<xiri-dyncomponent class="xrow">` (Multi-Component-Modus). Layout pro Sub-Component via `display: 'xcol-…'` auf jedem `XiriDynData`-Eintrag. Card-Header bleibt darüber. Beispiel:
|
|
105
|
+
```ts
|
|
106
|
+
{
|
|
107
|
+
header: 'Activity', headerIcon: 'show_chart', headerIconColor: 'primary',
|
|
108
|
+
components: [
|
|
109
|
+
{ type: 'barchart', mode: 'simple', display: 'xcol-12', data: { /* XiriBarChartSettings */ } },
|
|
110
|
+
{ type: 'stat', display: 'xcol-6', data: { value: '18h', label: 'Today', compact: true } },
|
|
111
|
+
{ type: 'stat', display: 'xcol-6', data: { value: '32h', label: 'Last 7 days', compact: true } },
|
|
112
|
+
],
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
2. Sonst wenn `data` + `fields` vorhanden → bestehendes `xiri-raw-table`-Rendering (Mini-Table-Card).
|
|
116
|
+
3. Sonst → bestehendes Content-Rendering.
|
|
117
|
+
|
|
118
|
+
Das **Vorhandensein** von `components` schaltet automatisch in den Multi-Component-Modus — kein eigener `cardType` nötig.
|
|
119
|
+
|
|
120
|
+
#### `compact?: boolean` auf Sub-Components
|
|
121
|
+
|
|
122
|
+
Die folgenden Components zeichnen sonst eine eigene `<mat-card>` mit Schatten — in einer `xiri-card` ergibt das einen Card-in-Card-Look. `compact: true` lässt die innere mat-card weg:
|
|
123
|
+
|
|
124
|
+
| Type | Settings-Interface | Wo |
|
|
125
|
+
| --- | --- | --- |
|
|
126
|
+
| `stat` | `XiriStatSettings.compact` | jede Stat-Verwendung |
|
|
127
|
+
| `barchart` | `XiriBarChartSettings.compact` | jede BarChart-Verwendung |
|
|
128
|
+
| `cardlink` | `XiriCardlinkSettings.compact` | jede Cardlink-Verwendung |
|
|
129
|
+
| `imagetext` | `XiriImagetextSettings.compact` | jede Imagetext-Verwendung |
|
|
130
|
+
| `infopoint` | `XiriInfopointSettings.compact` | jede InfoPoint-Verwendung |
|
|
131
|
+
| `links` | `XiriLinksSettings.compact` | jede Links-Verwendung |
|
|
132
|
+
| `multiprogress` | `XiriMultiprogressSettings.compact` | jede MultiProgress-Verwendung |
|
|
133
|
+
|
|
134
|
+
Implementierung pro Component: `[class.compact]` auf dem Host, `:host(.compact)`-Selectoren in SCSS (transparenter Background, kein Schatten, reduziertes Padding).
|
|
135
|
+
|
|
136
|
+
### xiri-cardlink
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
@input.required settings: XiriCardlinkSettings;
|
|
140
|
+
|
|
141
|
+
interface XiriCardlinkSettings {
|
|
142
|
+
link: string;
|
|
143
|
+
icon?: string;
|
|
144
|
+
iconSet: string;
|
|
145
|
+
text?: string;
|
|
146
|
+
sub?: string;
|
|
147
|
+
compact?: boolean; // Skipt eigene mat-card-Hülle (nesting in xiri-card).
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### xiri-links
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
@input.required settings: XiriLinksSettings;
|
|
155
|
+
|
|
156
|
+
interface XiriLinksSettings {
|
|
157
|
+
data: XiriButton[];
|
|
158
|
+
header?: string;
|
|
159
|
+
headerSub?: string;
|
|
160
|
+
headerIcon?: string;
|
|
161
|
+
headerIconColor?: XiriColor;
|
|
162
|
+
compact?: boolean; // Skipt eigene mat-card-Hülle (nesting in xiri-card).
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Buttons
|
|
167
|
+
|
|
168
|
+
### xiri-button
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
@input.required button: XiriButton;
|
|
172
|
+
@input disabled: boolean = false;
|
|
173
|
+
@input filterData: any = undefined;
|
|
174
|
+
@input url: string = undefined; // Override button.url
|
|
175
|
+
|
|
176
|
+
@output result: EventEmitter<XiriButtonResult>;
|
|
177
|
+
|
|
178
|
+
interface XiriButtonResult {
|
|
179
|
+
button: XiriButton;
|
|
180
|
+
result: any;
|
|
181
|
+
done: boolean;
|
|
182
|
+
loading: boolean;
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**Custom-Payload (`button.data`):** Für `action: 'api'` und `action: 'download'` baut die Button-Komponente den POST-Body als `{ ...filterData, ...button.data }`. `data` ist `Record<string, any>`. Klassisches Beispiel: CSV-Download-Buttons des `xiri-go`-Tabellen-Builders setzen `data: { _csv: true }`, das Backend (`LoadFilterData`) erkennt das Flag und liefert CSV statt Web-JSON. Backend-Setter: `button.WithData(map[string]any{...})` (siehe xiri-go-expert).
|
|
187
|
+
|
|
188
|
+
### xiri-buttonline
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
@input.required settings: XiriButtonlineSettings;
|
|
192
|
+
@input disabled: boolean = false;
|
|
193
|
+
@input filterData: any = undefined;
|
|
194
|
+
|
|
195
|
+
@output result: EventEmitter<XiriButtonResult>;
|
|
196
|
+
|
|
197
|
+
interface XiriButtonlineSettings {
|
|
198
|
+
buttons: XiriButton[];
|
|
199
|
+
class: string; // z.B. 'small'
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### xiri-buttonstyle (interne Hilfskomponente)
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
@input.required button: XiriButton;
|
|
207
|
+
@input.required disabled: boolean;
|
|
208
|
+
@input loading: boolean = false;
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### XiriButton
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
interface XiriButton {
|
|
215
|
+
text: string;
|
|
216
|
+
type: string; // 'raised' | 'flat' | 'fab' | 'icon' | 'stroked' | 'mini-fab' | …
|
|
217
|
+
action: string; // 'api' | 'dialog' | 'download' | 'link' | 'back' |
|
|
218
|
+
// 'close' | 'return' | 'menu' | …
|
|
219
|
+
|
|
220
|
+
default?: boolean;
|
|
221
|
+
url?: string;
|
|
222
|
+
hide?: boolean;
|
|
223
|
+
color?: XiriColor;
|
|
224
|
+
icon?: string;
|
|
225
|
+
iconColor?: XiriColor;
|
|
226
|
+
fontIcon?: string;
|
|
227
|
+
fontSet?: string;
|
|
228
|
+
class?: string;
|
|
229
|
+
hint?: string;
|
|
230
|
+
tabIndex?: number;
|
|
231
|
+
inline?: boolean;
|
|
232
|
+
disabled?: boolean;
|
|
233
|
+
|
|
234
|
+
data?: any;
|
|
235
|
+
target?: string;
|
|
236
|
+
loading?: boolean;
|
|
237
|
+
filename?: string;
|
|
238
|
+
|
|
239
|
+
// Send-Buttons (z.B. in Tables)
|
|
240
|
+
check?: any[];
|
|
241
|
+
send?: any[];
|
|
242
|
+
|
|
243
|
+
// action: 'menu'
|
|
244
|
+
menuItems?: {
|
|
245
|
+
action: string;
|
|
246
|
+
url?: string;
|
|
247
|
+
icon?: string;
|
|
248
|
+
color?: string;
|
|
249
|
+
text?: string;
|
|
250
|
+
data?: any;
|
|
251
|
+
}[];
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Wizard
|
|
256
|
+
|
|
257
|
+
### xiri-stepper
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
@input.required settings: XiriStepperSettings;
|
|
261
|
+
|
|
262
|
+
interface XiriStepperSettings {
|
|
263
|
+
url?: string; // Default-URL für Steps
|
|
264
|
+
steps: XiriStepperStep[];
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
interface XiriStepperStep {
|
|
268
|
+
url?: string;
|
|
269
|
+
title: string;
|
|
270
|
+
fields: XiriFormField[];
|
|
271
|
+
data?: any;
|
|
272
|
+
extra?: any;
|
|
273
|
+
buttons: XiriButton[];
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### xiri-done
|
|
278
|
+
|
|
279
|
+
Keine Inputs / Outputs. Zeigt ein Success-Checkmark-Icon.
|
|
280
|
+
|
|
281
|
+
### xiri-error
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
@input.required text: string;
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## Headers, Page-Header, Toolbar, Section, Divider
|
|
288
|
+
|
|
289
|
+
### xiri-header
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
@input.required settings: XiriHeaderSettings;
|
|
293
|
+
|
|
294
|
+
interface XiriHeaderSettings {
|
|
295
|
+
text: string;
|
|
296
|
+
color: string;
|
|
297
|
+
size: string; // 'h1' | 'h2' | 'h3' | …
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### xiri-page-header
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
@input.required settings: XiriPageHeaderSettings;
|
|
305
|
+
|
|
306
|
+
interface XiriPageHeaderSettings {
|
|
307
|
+
title: string;
|
|
308
|
+
subtitle?: string;
|
|
309
|
+
icon?: string;
|
|
310
|
+
iconColor?: string;
|
|
311
|
+
buttons?: XiriButtonlineSettings;
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### xiri-toolbar
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
@input.required settings: XiriToolbarSettings;
|
|
319
|
+
@input filterData: any = undefined;
|
|
320
|
+
|
|
321
|
+
interface XiriToolbarSettings {
|
|
322
|
+
title?: string;
|
|
323
|
+
icon?: string;
|
|
324
|
+
search?: boolean | { placeholder?: string };
|
|
325
|
+
buttons?: XiriButtonlineSettings;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
@output searchChanged: EventEmitter<string>;
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### xiri-section
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
@input.required settings: XiriSectionSettings;
|
|
335
|
+
@input dyncomponent: TemplateRef<any>;
|
|
336
|
+
|
|
337
|
+
interface XiriSectionSettings {
|
|
338
|
+
title?: string;
|
|
339
|
+
subtitle?: string;
|
|
340
|
+
icon?: string;
|
|
341
|
+
iconColor?: string;
|
|
342
|
+
collapsible?: boolean;
|
|
343
|
+
collapsed?: boolean;
|
|
344
|
+
buttons?: XiriButtonlineSettings;
|
|
345
|
+
components?: XiriDynData[]; // rekursive Nested-Komponenten
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### xiri-divider
|
|
350
|
+
|
|
351
|
+
```typescript
|
|
352
|
+
@input.required settings: XiriDividerSettings;
|
|
353
|
+
|
|
354
|
+
interface XiriDividerSettings {
|
|
355
|
+
text?: string;
|
|
356
|
+
icon?: string;
|
|
357
|
+
spacing?: 'compact' | 'normal' | 'large';
|
|
358
|
+
}
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
## Listen, Infos, Fortschritt
|
|
362
|
+
|
|
363
|
+
### xiri-list
|
|
364
|
+
|
|
365
|
+
```typescript
|
|
366
|
+
@input.required settings: XiriListSettings;
|
|
367
|
+
|
|
368
|
+
interface XiriListSettings {
|
|
369
|
+
sections: XiriListSection[];
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
interface XiriListSection {
|
|
373
|
+
name: string;
|
|
374
|
+
data: XiriListItem[];
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
interface XiriListItem {
|
|
378
|
+
name: string;
|
|
379
|
+
info: string;
|
|
380
|
+
icon: string;
|
|
381
|
+
iconSet?: string;
|
|
382
|
+
iconColor: XiriColor;
|
|
383
|
+
url: string;
|
|
384
|
+
hasFavorite?: boolean;
|
|
385
|
+
isFavorite?: boolean;
|
|
386
|
+
favoriteUrl?: string;
|
|
387
|
+
favoriteHint?: string;
|
|
388
|
+
}
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### xiri-infopoint
|
|
392
|
+
|
|
393
|
+
```typescript
|
|
394
|
+
@input.required settings: XiriInfopointSettings;
|
|
395
|
+
|
|
396
|
+
interface XiriInfopointSettings {
|
|
397
|
+
text: string;
|
|
398
|
+
info: string;
|
|
399
|
+
url?: string;
|
|
400
|
+
urlParams?: object;
|
|
401
|
+
icon: string;
|
|
402
|
+
iconSet?: string;
|
|
403
|
+
iconColor: XiriColor;
|
|
404
|
+
dense?: boolean;
|
|
405
|
+
compact?: boolean; // Skipt eigene mat-card-Hülle (nesting in xiri-card).
|
|
406
|
+
}
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### xiri-multiprogress
|
|
410
|
+
|
|
411
|
+
```typescript
|
|
412
|
+
@input.required settings: XiriMultiprogressSettings;
|
|
413
|
+
|
|
414
|
+
interface XiriMultiprogressSettings {
|
|
415
|
+
data: XiriMultiprogressItem[];
|
|
416
|
+
header?: string;
|
|
417
|
+
headerIcon?: string;
|
|
418
|
+
headerIconColor?: XiriColor;
|
|
419
|
+
show?: number; // initiale Zahl sichtbarer Items
|
|
420
|
+
compact?: boolean; // Skipt eigene mat-card-Hülle (nesting in xiri-card).
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
interface XiriMultiprogressItem {
|
|
424
|
+
text: string;
|
|
425
|
+
value: string;
|
|
426
|
+
progress: number; // 0-100
|
|
427
|
+
color?: XiriColor;
|
|
428
|
+
}
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### xiri-imagetext
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
@input.required settings: XiriImagetextSettings;
|
|
435
|
+
|
|
436
|
+
interface XiriImagetextSettings {
|
|
437
|
+
url: string;
|
|
438
|
+
info: string;
|
|
439
|
+
header?: string;
|
|
440
|
+
headerSub?: string;
|
|
441
|
+
headerIcon?: string;
|
|
442
|
+
headerIconColor?: XiriColor;
|
|
443
|
+
compact?: boolean; // Skipt eigene mat-card-Hülle (nesting in xiri-card).
|
|
444
|
+
}
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
## Search & Navigation
|
|
448
|
+
|
|
449
|
+
### xiri-search
|
|
450
|
+
|
|
451
|
+
```typescript
|
|
452
|
+
@input placeholder: string = '';
|
|
453
|
+
@input open: boolean = false;
|
|
454
|
+
@input reset: number = -1; // Trigger-Reset bei Änderung
|
|
455
|
+
@input escape: boolean = true;
|
|
456
|
+
@input focus: number = -1; // Trigger-Focus bei Änderung
|
|
457
|
+
@input text: string = '';
|
|
458
|
+
|
|
459
|
+
@output changed: EventEmitter<string>; // debounced 200ms
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
### xiri-sidenav
|
|
463
|
+
|
|
464
|
+
```typescript
|
|
465
|
+
@input settings: XiriSidebarSettings;
|
|
466
|
+
|
|
467
|
+
interface XiriSidebarSettings {
|
|
468
|
+
prefix: string; // Route-Prefix zum Überspringen
|
|
469
|
+
fields: XiriNavigationField[];
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
interface XiriNavigationField {
|
|
473
|
+
name: string;
|
|
474
|
+
link?: string;
|
|
475
|
+
icon: string;
|
|
476
|
+
iconSet?: string;
|
|
477
|
+
extern?: string;
|
|
478
|
+
active?: boolean;
|
|
479
|
+
path?: string;
|
|
480
|
+
regex?: RegExp;
|
|
481
|
+
menu?: boolean;
|
|
482
|
+
showSubmenu?: boolean;
|
|
483
|
+
sub?: XiriNavigationField[];
|
|
484
|
+
}
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
### xiri-breadcrumb
|
|
488
|
+
|
|
489
|
+
```typescript
|
|
490
|
+
@input.required settings: XiriBreadcrumbItem[];
|
|
491
|
+
|
|
492
|
+
interface XiriBreadcrumbItem {
|
|
493
|
+
label: string;
|
|
494
|
+
link?: string;
|
|
495
|
+
icon?: string;
|
|
496
|
+
extern?: boolean;
|
|
497
|
+
}
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
## Tabs & Expansion
|
|
501
|
+
|
|
502
|
+
### xiri-tabs
|
|
503
|
+
|
|
504
|
+
```typescript
|
|
505
|
+
@input.required settings: XiriTabsSettings;
|
|
506
|
+
@input filterData: any;
|
|
507
|
+
@input dyncomponent: TemplateRef<any>;
|
|
508
|
+
|
|
509
|
+
interface XiriTabsSettings {
|
|
510
|
+
tabs: XiriTabSettings[];
|
|
511
|
+
selectedIndex?: number;
|
|
512
|
+
dynamicHeight?: boolean;
|
|
513
|
+
animationDuration?: string;
|
|
514
|
+
lazy?: boolean; // Content erst bei tab-select
|
|
515
|
+
unload?: boolean; // Content bei deselect zerstören
|
|
516
|
+
headerPosition?: 'above' | 'below';
|
|
517
|
+
alignTabs?: 'start' | 'center' | 'end';
|
|
518
|
+
stretchTabs?: boolean;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
interface XiriTabSettings {
|
|
522
|
+
label: string;
|
|
523
|
+
icon?: string;
|
|
524
|
+
disabled?: boolean;
|
|
525
|
+
data: XiriDynData[];
|
|
526
|
+
lazy?: boolean;
|
|
527
|
+
unload?: boolean;
|
|
528
|
+
}
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
### xiri-expansion
|
|
532
|
+
|
|
533
|
+
```typescript
|
|
534
|
+
@input.required settings: XiriExpansionSettings;
|
|
535
|
+
@input filterData: any;
|
|
536
|
+
@input dyncomponent: TemplateRef<any>;
|
|
537
|
+
|
|
538
|
+
interface XiriExpansionSettings {
|
|
539
|
+
panels: XiriExpansionPanelSettings[];
|
|
540
|
+
multi?: boolean;
|
|
541
|
+
displayMode?: 'default' | 'flat';
|
|
542
|
+
togglePosition?: 'before' | 'after';
|
|
543
|
+
hideToggle?: boolean;
|
|
544
|
+
lazy?: boolean;
|
|
545
|
+
unload?: boolean;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
interface XiriExpansionPanelSettings {
|
|
549
|
+
title: string;
|
|
550
|
+
description?: string;
|
|
551
|
+
icon?: string;
|
|
552
|
+
disabled?: boolean;
|
|
553
|
+
expanded?: boolean;
|
|
554
|
+
data: XiriDynData[];
|
|
555
|
+
lazy?: boolean;
|
|
556
|
+
unload?: boolean;
|
|
557
|
+
}
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
## Skeleton & Empty-State
|
|
561
|
+
|
|
562
|
+
### xiri-skeleton
|
|
563
|
+
|
|
564
|
+
```typescript
|
|
565
|
+
@input type: XiriSkeletonType = 'text';
|
|
566
|
+
// 'text' | 'circle' | 'rect' | 'table-row'
|
|
567
|
+
|
|
568
|
+
@input width: string = '100%';
|
|
569
|
+
@input height: string = '1em';
|
|
570
|
+
@input lines: number = 1;
|
|
571
|
+
@input columns: number = 4; // für 'table-row'
|
|
572
|
+
@input animate: boolean = true;
|
|
573
|
+
@input fill: boolean = false;
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
### xiri-empty-state
|
|
577
|
+
|
|
578
|
+
```typescript
|
|
579
|
+
@input.required settings: XiriEmptyStateSettings;
|
|
580
|
+
|
|
581
|
+
interface XiriEmptyStateSettings {
|
|
582
|
+
icon?: string;
|
|
583
|
+
iconColor?: XiriColor;
|
|
584
|
+
title?: string;
|
|
585
|
+
description?: string;
|
|
586
|
+
button?: XiriButton;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
@output buttonResult: EventEmitter<XiriButtonResult>;
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
## Stats & Timeline & Description-List
|
|
593
|
+
|
|
594
|
+
### xiri-stat
|
|
595
|
+
|
|
596
|
+
```typescript
|
|
597
|
+
@input.required settings: XiriStatSettings;
|
|
598
|
+
|
|
599
|
+
interface XiriStatSettings {
|
|
600
|
+
value: string | number;
|
|
601
|
+
label: string;
|
|
602
|
+
icon?: string;
|
|
603
|
+
iconColor?: XiriColor;
|
|
604
|
+
trend?: XiriStatTrend;
|
|
605
|
+
prefix?: string;
|
|
606
|
+
suffix?: string;
|
|
607
|
+
color?: XiriColor;
|
|
608
|
+
compact?: boolean; // Skipt eigene mat-card-Hülle, kleinere Schrift —
|
|
609
|
+
// für Stats die in einer äußeren Card geschachtelt sind
|
|
610
|
+
// (Card-in-Card-Look vermeiden).
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
interface XiriStatTrend {
|
|
614
|
+
value: number;
|
|
615
|
+
direction: 'up' | 'down' | 'neutral';
|
|
616
|
+
}
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
### xiri-stat-grid
|
|
620
|
+
|
|
621
|
+
```typescript
|
|
622
|
+
@input.required settings: XiriStatGridSettings;
|
|
623
|
+
|
|
624
|
+
interface XiriStatGridSettings {
|
|
625
|
+
stats: XiriStatSettings[];
|
|
626
|
+
columns?: number;
|
|
627
|
+
title?: string;
|
|
628
|
+
}
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
### xiri-timeline
|
|
632
|
+
|
|
633
|
+
```typescript
|
|
634
|
+
@input.required settings: XiriTimelineSettings;
|
|
635
|
+
|
|
636
|
+
interface XiriTimelineSettings {
|
|
637
|
+
items: XiriTimelineItem[];
|
|
638
|
+
orientation?: 'horizontal' | 'vertical';
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
interface XiriTimelineItem {
|
|
642
|
+
title: string;
|
|
643
|
+
description?: string;
|
|
644
|
+
datetime?: string;
|
|
645
|
+
icon?: string;
|
|
646
|
+
iconColor?: XiriColor;
|
|
647
|
+
}
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
### xiri-description-list
|
|
651
|
+
|
|
652
|
+
```typescript
|
|
653
|
+
@input.required settings: XiriDescriptionListSettings;
|
|
654
|
+
|
|
655
|
+
interface XiriDescriptionListSettings {
|
|
656
|
+
items: XiriDescriptionListItem[];
|
|
657
|
+
columns?: 1 | 2 | 3;
|
|
658
|
+
layout?: 'horizontal' | 'stacked';
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
interface XiriDescriptionListItem {
|
|
662
|
+
label: string;
|
|
663
|
+
value: string;
|
|
664
|
+
icon?: string;
|
|
665
|
+
color?: string;
|
|
666
|
+
type?: 'text' | 'link' | 'html' | 'badge';
|
|
667
|
+
}
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
### xiri-barchart
|
|
671
|
+
|
|
672
|
+
```typescript
|
|
673
|
+
@input mode: XiriBarChartMode = 'simple'; // 'simple' | 'stacked' | 'heatmap'
|
|
674
|
+
@input.required settings: XiriBarChartSettings;
|
|
675
|
+
|
|
676
|
+
interface XiriBarChartSettings {
|
|
677
|
+
title?: string;
|
|
678
|
+
yMin?: number;
|
|
679
|
+
yMax?: number;
|
|
680
|
+
color?: XiriColor; // Default-Farbe (simple/heatmap)
|
|
681
|
+
bars?: XiriBarChartBar[]; // simple + stacked
|
|
682
|
+
points?: XiriBarChartPoint[]; // heatmap
|
|
683
|
+
compact?: boolean; // Skipt eigene mat-card-Hülle (nesting in xiri-card).
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
interface XiriBarChartBar {
|
|
687
|
+
label: string; // Achsen-Label (kurz)
|
|
688
|
+
value?: number; // simple
|
|
689
|
+
segments?: XiriBarChartSegment[]; // stacked
|
|
690
|
+
name?: string; // optionaler Tooltip-Name (Vollbezeichnung)
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
interface XiriBarChartSegment {
|
|
694
|
+
value: number;
|
|
695
|
+
color?: XiriColor;
|
|
696
|
+
name?: string; // Tooltip-Name pro Segment ("Low strain" …)
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
interface XiriBarChartPoint {
|
|
700
|
+
time: number; // unix milliseconds
|
|
701
|
+
value: number;
|
|
702
|
+
name?: string; // optionaler Tooltip-Name (z. B. "Repeat #3")
|
|
703
|
+
}
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
**Rendering:** Verwendet **echarts v6**. Die Library deklariert `echarts` als optionale `peerDependency` — Apps installieren `echarts` nur, wenn sie `xiri-barchart` (oder `type: 'barchart'`) verwenden. Der Component lädt echarts lazy via `await import('echarts')` (eigener Bundle-Chunk).
|
|
707
|
+
|
|
708
|
+
**Tooltip:** Pro Mode eigener Formatter. Wenn `bar.name` / `segment.name` / `point.name` gesetzt sind, erscheinen sie im Tooltip; sonst Fallback auf `label` bzw. echarts-Default. Demo-Pattern: `label: 'M', name: 'Monday'` → X-Achse zeigt "M", Tooltip zeigt "Monday".
|
|
709
|
+
|
|
710
|
+
**Resize:** intern via `ResizeObserver` — kein manuelles `resize()` nötig.
|
|
711
|
+
|
|
712
|
+
**Im dyncomponent:** `{ type: 'barchart', mode: 'stacked', data: XiriBarChartSettings }`.
|
|
713
|
+
|
|
714
|
+
### xiri-linechart
|
|
715
|
+
|
|
716
|
+
```typescript
|
|
717
|
+
@input.required settings: XiriLineChartSettings;
|
|
718
|
+
|
|
719
|
+
interface XiriLineChartSettings {
|
|
720
|
+
title?: string;
|
|
721
|
+
xLabels: string[];
|
|
722
|
+
lines: XiriLineChartLine[];
|
|
723
|
+
yMin?: number;
|
|
724
|
+
yMax?: number;
|
|
725
|
+
smooth?: boolean; // alle Linien als geglättete Kurve
|
|
726
|
+
compact?: boolean;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
interface XiriLineChartLine {
|
|
730
|
+
name: string;
|
|
731
|
+
values: number[]; // Werte parallel zu xLabels
|
|
732
|
+
color?: XiriColor;
|
|
733
|
+
dashed?: boolean;
|
|
734
|
+
area?: boolean; // Fläche unter der Linie füllen
|
|
735
|
+
}
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
Im dyncomponent: `{ type: 'linechart', data: XiriLineChartSettings }`.
|
|
739
|
+
|
|
740
|
+
### xiri-piechart
|
|
741
|
+
|
|
742
|
+
```typescript
|
|
743
|
+
@input.required settings: XiriPieChartSettings;
|
|
744
|
+
|
|
745
|
+
interface XiriPieChartSettings {
|
|
746
|
+
title?: string;
|
|
747
|
+
slices: XiriPieChartSlice[];
|
|
748
|
+
donut?: boolean; // Ring statt Pie
|
|
749
|
+
nightingale?: boolean; // Rose-Style: Slice-Radien skalieren mit Wert
|
|
750
|
+
nightingaleType?: 'radius' | 'area'; // Default 'radius'
|
|
751
|
+
compact?: boolean;
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
interface XiriPieChartSlice {
|
|
755
|
+
name: string;
|
|
756
|
+
value: number;
|
|
757
|
+
color?: XiriColor;
|
|
758
|
+
}
|
|
759
|
+
```
|
|
760
|
+
|
|
761
|
+
Im dyncomponent: `{ type: 'piechart', data: XiriPieChartSettings }`.
|
|
762
|
+
|
|
763
|
+
### xiri-gaugechart
|
|
764
|
+
|
|
765
|
+
```typescript
|
|
766
|
+
@input.required settings: XiriGaugeChartSettings;
|
|
767
|
+
|
|
768
|
+
interface XiriGaugeChartSettings {
|
|
769
|
+
title?: string;
|
|
770
|
+
value: number;
|
|
771
|
+
min?: number; // Default 0
|
|
772
|
+
max?: number; // Default 100
|
|
773
|
+
color?: XiriColor;
|
|
774
|
+
label?: string; // Einheits-Label unter dem Wert ('%', 'GB', …)
|
|
775
|
+
compact?: boolean;
|
|
776
|
+
}
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
Im dyncomponent: `{ type: 'gaugechart', data: XiriGaugeChartSettings }`.
|
|
780
|
+
|
|
781
|
+
### xiri-heatmap
|
|
782
|
+
|
|
783
|
+
```typescript
|
|
784
|
+
@input.required settings: XiriHeatmapSettings;
|
|
785
|
+
|
|
786
|
+
interface XiriHeatmapSettings {
|
|
787
|
+
title?: string;
|
|
788
|
+
xLabels: string[];
|
|
789
|
+
yLabels: string[];
|
|
790
|
+
cells: XiriHeatmapCell[]; // [{x: number, y: number, value: number}]
|
|
791
|
+
min?: number;
|
|
792
|
+
max?: number;
|
|
793
|
+
colorRange?: [string, string]; // CSS low → high (Default light → purple)
|
|
794
|
+
showValues?: boolean; // Werte in Zellen anzeigen
|
|
795
|
+
compact?: boolean;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
interface XiriHeatmapCell { x: number; y: number; value: number; label?: string; }
|
|
799
|
+
```
|
|
800
|
+
|
|
801
|
+
Im dyncomponent: `{ type: 'heatmap', data: XiriHeatmapSettings }`.
|
|
802
|
+
|
|
803
|
+
### xiri-calendar
|
|
804
|
+
|
|
805
|
+
```typescript
|
|
806
|
+
@input.required settings: XiriCalendarSettings;
|
|
807
|
+
|
|
808
|
+
interface XiriCalendarSettings {
|
|
809
|
+
title?: string;
|
|
810
|
+
range: string | [string, string]; // 'YYYY' oder ['YYYY-MM-DD', 'YYYY-MM-DD']
|
|
811
|
+
cells: XiriCalendarCell[]; // [{date: 'YYYY-MM-DD', value: number}]
|
|
812
|
+
min?: number;
|
|
813
|
+
max?: number;
|
|
814
|
+
colorRange?: [string, string]; // Default light-green → dark-green (GitHub-Style)
|
|
815
|
+
cellSize?: number; // px (Default 16, compact 12)
|
|
816
|
+
compact?: boolean;
|
|
817
|
+
}
|
|
818
|
+
```
|
|
819
|
+
|
|
820
|
+
Im dyncomponent: `{ type: 'calendar', data: XiriCalendarSettings }`.
|
|
821
|
+
|
|
822
|
+
### xiri-tree
|
|
823
|
+
|
|
824
|
+
```typescript
|
|
825
|
+
@input.required settings: XiriTreeSettings;
|
|
826
|
+
|
|
827
|
+
interface XiriTreeSettings {
|
|
828
|
+
title?: string;
|
|
829
|
+
root: XiriTreeNode;
|
|
830
|
+
orient?: 'LR' | 'RL' | 'TB' | 'BT'; // Default 'LR'
|
|
831
|
+
layout?: 'orthogonal' | 'radial'; // Default 'orthogonal'
|
|
832
|
+
compact?: boolean;
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
interface XiriTreeNode {
|
|
836
|
+
name: string;
|
|
837
|
+
value?: number;
|
|
838
|
+
children?: XiriTreeNode[];
|
|
839
|
+
collapsed?: boolean; // initial eingeklappt
|
|
840
|
+
}
|
|
841
|
+
```
|
|
842
|
+
|
|
843
|
+
Im dyncomponent: `{ type: 'tree', data: XiriTreeSettings }`.
|
|
844
|
+
|
|
845
|
+
### xiri-sankey
|
|
846
|
+
|
|
847
|
+
```typescript
|
|
848
|
+
@input.required settings: XiriSankeySettings;
|
|
849
|
+
|
|
850
|
+
interface XiriSankeySettings {
|
|
851
|
+
title?: string;
|
|
852
|
+
nodes: { name: string; color?: XiriColor }[];
|
|
853
|
+
links: { source: string; target: string; value: number }[];
|
|
854
|
+
orient?: 'horizontal' | 'vertical'; // Default 'horizontal'
|
|
855
|
+
compact?: boolean;
|
|
856
|
+
}
|
|
857
|
+
```
|
|
858
|
+
|
|
859
|
+
Im dyncomponent: `{ type: 'sankey', data: XiriSankeySettings }`.
|
|
860
|
+
|
|
861
|
+
### xiri-gantt
|
|
862
|
+
|
|
863
|
+
Echarts-Custom-Series-basierter Gantt. Zeiten in unix milliseconds.
|
|
864
|
+
|
|
865
|
+
```typescript
|
|
866
|
+
@input.required settings: XiriGanttSettings;
|
|
867
|
+
|
|
868
|
+
interface XiriGanttSettings {
|
|
869
|
+
title?: string;
|
|
870
|
+
rows: string[]; // Y-Achsen-Kategorien (top-down)
|
|
871
|
+
tasks: XiriGanttTask[];
|
|
872
|
+
rangeStart?: number; // unix ms (optional X-Achsen-Range)
|
|
873
|
+
rangeEnd?: number;
|
|
874
|
+
compact?: boolean;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
interface XiriGanttTask {
|
|
878
|
+
row: number; // Index in rows[]
|
|
879
|
+
name: string;
|
|
880
|
+
start: number; // unix ms
|
|
881
|
+
end: number; // unix ms
|
|
882
|
+
color?: XiriColor;
|
|
883
|
+
}
|
|
884
|
+
```
|
|
885
|
+
|
|
886
|
+
Im dyncomponent: `{ type: 'gantt', data: XiriGanttSettings }`.
|
|
887
|
+
|
|
888
|
+
### xiri-echarts-host (geteilte Basis)
|
|
889
|
+
|
|
890
|
+
Internes Plumbing für alle echarts-basierten Charts. Public exportiert, falls eigene Custom-Charts gebaut werden sollen.
|
|
891
|
+
|
|
892
|
+
```typescript
|
|
893
|
+
@input.required option: any; // Vollständige echarts-Option
|
|
894
|
+
@input compact: boolean = false;
|
|
895
|
+
@input title?: string;
|
|
896
|
+
@input headerIcon?: string;
|
|
897
|
+
@input headerIconColor?: XiriColor;
|
|
898
|
+
@input chartHeight: string = '200px';
|
|
899
|
+
```
|
|
900
|
+
|
|
901
|
+
Übernimmt: Lazy `await import('echarts')`, ResizeObserver, mat-card-Hülle (mit Compact-Modus = flat), Title-Header, Error-Display. Re-render via `effect` auf `option()`.
|
|
902
|
+
|
|
903
|
+
Eigenes Chart bauen:
|
|
904
|
+
|
|
905
|
+
```typescript
|
|
906
|
+
@Component({
|
|
907
|
+
selector: 'app-my-chart',
|
|
908
|
+
template: `<xiri-echarts-host [option]="option()" [compact]="compact()" [title]="settings().title"/>`,
|
|
909
|
+
imports: [XiriEchartsHostComponent]
|
|
910
|
+
})
|
|
911
|
+
export class MyChart {
|
|
912
|
+
settings = input.required<MySettings>();
|
|
913
|
+
compact = computed(() => !!this.settings().compact);
|
|
914
|
+
option = computed(() => buildMyEchartsOption(this.settings(), this.compact()));
|
|
915
|
+
}
|
|
916
|
+
```
|
|
917
|
+
|
|
918
|
+
Helper-Funktionen aus `lib/echarts/`: `resolveColor(token, fallback)` — XiriColor → CSS-Wert; `escapeHtml(s)` — für Tooltip-Strings.
|