@xiriframework/xiri-ng 0.2.48 → 0.2.49
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 +1346 -588
- package/fesm2022/xiriframework-xiri-ng.mjs.map +1 -1
- package/package.json +1 -1
- package/skills/xiri-ng-expert/SKILL.md +7 -2
- package/skills/xiri-ng-expert/references/components.md +30 -0
- package/styles/_accessibility.scss +24 -0
- package/styles/_mixins.scss +8 -0
- package/styles/grid.scss +33 -0
- package/styles/material-components.scss +11 -3
- package/types/xiriframework-xiri-ng.d.ts +277 -12
- package/types/xiriframework-xiri-ng.d.ts.map +1 -1
package/package.json
CHANGED
|
@@ -98,7 +98,7 @@ components: XiriDynData[] = [
|
|
|
98
98
|
// card | buttonline | table | cardlink | links | form | query
|
|
99
99
|
// stepper | header | list | spacer | container | infopoint | multiprogress
|
|
100
100
|
// imagetext | tabs | expansion | infotext | html | stat | empty-state
|
|
101
|
-
// timeline | page-header | section | divider | stat-grid | toolbar
|
|
101
|
+
// timeline | page-header | section | divider | stat-grid | multi-stat | toolbar
|
|
102
102
|
// description-list | barchart (barchart benötigt zusätzlich `mode`)
|
|
103
103
|
```
|
|
104
104
|
|
|
@@ -292,7 +292,12 @@ stepperSettings = {
|
|
|
292
292
|
```html
|
|
293
293
|
<xiri-stat [settings]="{ value: 1234, label: 'Umsatz', prefix: '€', color: 'primary',
|
|
294
294
|
trend: { value: 12, direction: 'up' } }"/>
|
|
295
|
-
|
|
295
|
+
<!-- Mehrere zusammengehörige Zahlen → EINE multi-stat statt mehrerer stat nebeneinander
|
|
296
|
+
oder eines stat-grid. Items horizontal (Standard), responsiv, klickbar (item.link). -->
|
|
297
|
+
<xiri-multi-stat [settings]="{ title: 'Bestellungen', icon: 'shopping_cart',
|
|
298
|
+
items: [ { value: 12, label: 'Offen', icon: 'inventory', color: 'orange', link: '/Orders?status=open' },
|
|
299
|
+
{ value: 45, label: 'Fertig', color: 'green', trend: { value: 5, direction: 'up' } } ] }"/>
|
|
300
|
+
<xiri-stat-grid [settings]="{ stats: [...], columns: 4, title: 'KPIs' }"/> <!-- nur für eigenständige KPI-Karten -->
|
|
296
301
|
<xiri-timeline [settings]="{ items: [...], orientation: 'vertical' }"/>
|
|
297
302
|
<xiri-barchart mode="simple" [settings]="{ title: 'Weekly', yMin: 0, yMax: 12, color: 'purple',
|
|
298
303
|
bars: [{ label: 'M', name: 'Monday', value: 3 }, ...] }"/>
|
|
@@ -632,6 +632,9 @@ interface XiriStatSettings {
|
|
|
632
632
|
prefix?: string;
|
|
633
633
|
suffix?: string;
|
|
634
634
|
color?: XiriColor;
|
|
635
|
+
reference?: string; // muted Benchmark-/Anker-Zeile neben dem Wert
|
|
636
|
+
link?: string; // macht den Wert klickbar (routerLink + Query-Params);
|
|
637
|
+
// v. a. pro Zahl in xiri-multi-stat
|
|
635
638
|
compact?: boolean; // Skipt eigene mat-card-Hülle, kleinere Schrift —
|
|
636
639
|
// für Stats die in einer äußeren Card geschachtelt sind
|
|
637
640
|
// (Card-in-Card-Look vermeiden).
|
|
@@ -643,8 +646,35 @@ interface XiriStatTrend {
|
|
|
643
646
|
}
|
|
644
647
|
```
|
|
645
648
|
|
|
649
|
+
### xiri-multi-stat
|
|
650
|
+
|
|
651
|
+
**Standard für mehrere zusammengehörige Zahlen.** Nimm **eine** `xiri-multi-stat`
|
|
652
|
+
statt mehrerer `xiri-stat` nebeneinander (eigene xcol-Spalten) oder `xiri-stat-grid`
|
|
653
|
+
(N Karten), wenn die Zahlen inhaltlich zusammengehören: gemeinsamer Header,
|
|
654
|
+
kompakter, responsiv (Items brechen auf schmalen Breiten sauber um, die Trennlinie
|
|
655
|
+
am Reihenanfang wird ausgeblendet).
|
|
656
|
+
|
|
657
|
+
```typescript
|
|
658
|
+
@input.required settings: XiriMultiStatSettings;
|
|
659
|
+
|
|
660
|
+
interface XiriMultiStatSettings {
|
|
661
|
+
items?: XiriStatSettings[]; // je Zahl eine XiriStatSettings (value/label/icon/
|
|
662
|
+
// color/prefix/suffix/trend/link — link macht sie klickbar)
|
|
663
|
+
title?: string; // Header-Titel
|
|
664
|
+
icon?: string; // Header-Icon
|
|
665
|
+
iconColor?: XiriColor;
|
|
666
|
+
verticalItems?: boolean; // Standard horizontal (Icon links neben Wert/Label);
|
|
667
|
+
// true = gestapelt (Icon oben)
|
|
668
|
+
url?: string; // AJAX: lädt items per POST (Card-Muster),
|
|
669
|
+
// Header bleibt sofort sichtbar
|
|
670
|
+
reload?: boolean; // manueller Reload-Button (nur zusammen mit url)
|
|
671
|
+
}
|
|
672
|
+
```
|
|
673
|
+
|
|
646
674
|
### xiri-stat-grid
|
|
647
675
|
|
|
676
|
+
Für mehrere **eigenständige** Stat-Karten. Zusammengehörige Zahlen → `xiri-multi-stat`.
|
|
677
|
+
|
|
648
678
|
```typescript
|
|
649
679
|
@input.required settings: XiriStatGridSettings;
|
|
650
680
|
|
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
// Global Accessibility Styles
|
|
3
3
|
// ============================================
|
|
4
4
|
|
|
5
|
+
// Base line-height for body text (WCAG 1.4.12 recommendation).
|
|
6
|
+
// Only body + native headings — Material components set their own
|
|
7
|
+
// line-height (sometimes 1) deliberately, do not override those here.
|
|
8
|
+
body {
|
|
9
|
+
line-height: 1.5;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
h1, h2, h3, h4, h5, h6 {
|
|
13
|
+
line-height: 1.25;
|
|
14
|
+
}
|
|
15
|
+
|
|
5
16
|
// Focus-visible indicator for keyboard navigation
|
|
6
17
|
// Uses :focus-visible to only show on keyboard focus, not mouse clicks
|
|
7
18
|
*:focus-visible {
|
|
@@ -33,6 +44,19 @@
|
|
|
33
44
|
// Material handles this internally, no override needed
|
|
34
45
|
}
|
|
35
46
|
|
|
47
|
+
// Windows High Contrast Mode / forced-colors basics
|
|
48
|
+
@media (forced-colors: active) {
|
|
49
|
+
*:focus-visible {
|
|
50
|
+
outline: 2px solid;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// State conveyed only via background-color would otherwise disappear;
|
|
54
|
+
// keep it legible with an explicit border.
|
|
55
|
+
.xiri-chip-display {
|
|
56
|
+
border: 1px solid;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
36
60
|
// Skip link for keyboard users
|
|
37
61
|
.xiri-skip-link {
|
|
38
62
|
position: absolute;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// ============================================
|
|
2
|
+
// Shared Mixins
|
|
3
|
+
// ============================================
|
|
4
|
+
|
|
5
|
+
// Fixed-width digits for numeric columns / counters (avoids layout jitter).
|
|
6
|
+
@mixin xiri-tabular-nums {
|
|
7
|
+
font-variant-numeric: tabular-nums;
|
|
8
|
+
}
|
package/styles/grid.scss
CHANGED
|
@@ -21,6 +21,11 @@
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
.xrow-cq {
|
|
25
|
+
container-type: inline-size;
|
|
26
|
+
container-name: xrow;
|
|
27
|
+
}
|
|
28
|
+
|
|
24
29
|
.xcol {
|
|
25
30
|
grid-column-end: span 12;
|
|
26
31
|
max-width: 100%;
|
|
@@ -68,6 +73,34 @@
|
|
|
68
73
|
}
|
|
69
74
|
}
|
|
70
75
|
|
|
76
|
+
// Reset viewport-based spans for .xrow-cq children (specificity 0,2,0 beats the
|
|
77
|
+
// always-active .xcol-{bp}-{i} media rule above at 0,1,0), so a container narrower
|
|
78
|
+
// than the viewport breakpoint falls back to the mobile default instead of inheriting
|
|
79
|
+
// a span meant for a wide viewport. The @container rules below share this same
|
|
80
|
+
// specificity and come later in source order, so they win once the container matches.
|
|
81
|
+
.xrow-cq > [class*='xcol-'] {
|
|
82
|
+
grid-column-end: span 12;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@each $abbr, $size in $breakpoints {
|
|
86
|
+
@container xrow (min-width: #{$size}) {
|
|
87
|
+
// Container query variants — opt-in via .xrow-cq
|
|
88
|
+
@for $i from 1 through 12 {
|
|
89
|
+
.xrow-cq > .xcol-#{$abbr}-#{$i} {
|
|
90
|
+
grid-column-end: span $i;
|
|
91
|
+
}
|
|
92
|
+
.xrow-cq > .xcol-middle-#{$abbr}-#{$i} {
|
|
93
|
+
grid-column-start: math.ceil(calc((12 - $i )/2)) + 1;
|
|
94
|
+
grid-column-end: math.ceil(calc((12 - $i )/2)) + $i + 1;
|
|
95
|
+
}
|
|
96
|
+
.xrow-cq > .xcol-right-#{$abbr}-#{$i} {
|
|
97
|
+
grid-column-start: calc(12 - $i + 1);
|
|
98
|
+
grid-column-end: 13;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
71
104
|
.x-none, .x-xs-none {
|
|
72
105
|
display: none !important;
|
|
73
106
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
@use 'sass:list';
|
|
2
2
|
@use 'sass:map';
|
|
3
3
|
@use 'colors' as *;
|
|
4
|
+
@use 'mixins';
|
|
4
5
|
|
|
5
6
|
// ============================================
|
|
6
7
|
// Color Variant Mixins
|
|
@@ -109,7 +110,7 @@ mat-icon {
|
|
|
109
110
|
// ============================================
|
|
110
111
|
.mat-small-icon-button {
|
|
111
112
|
--mat-icon-button-state-layer-size: 28px;
|
|
112
|
-
--mat-icon-button-touch-target-size:
|
|
113
|
+
--mat-icon-button-touch-target-size: 44px; // WCAG 2.5.5: Hit-Area ≥ 44px, Icon bleibt klein
|
|
113
114
|
--mat-icon-button-icon-size: 18px;
|
|
114
115
|
|
|
115
116
|
.mat-icon {
|
|
@@ -122,7 +123,7 @@ mat-icon {
|
|
|
122
123
|
|
|
123
124
|
.mat-medium-icon-button {
|
|
124
125
|
--mat-icon-button-state-layer-size: 36px;
|
|
125
|
-
--mat-icon-button-touch-target-size:
|
|
126
|
+
--mat-icon-button-touch-target-size: 44px; // WCAG 2.5.5: Hit-Area ≥ 44px, Icon bleibt klein
|
|
126
127
|
--mat-icon-button-icon-size: 22px;
|
|
127
128
|
|
|
128
129
|
.mat-icon {
|
|
@@ -174,12 +175,19 @@ td.align-right .xiri-chips-display {
|
|
|
174
175
|
display: inline-block;
|
|
175
176
|
padding: 2px 8px;
|
|
176
177
|
border-radius: 12px;
|
|
177
|
-
font-size:
|
|
178
|
+
font-size: var(--xiri-font-size-helper);
|
|
178
179
|
line-height: 1.6;
|
|
179
180
|
background-color: var(--surface-variant, #DEE3EB);
|
|
180
181
|
color: var(--on-surface-variant, #42474E);
|
|
181
182
|
}
|
|
182
183
|
|
|
184
|
+
// ============================================
|
|
185
|
+
// Tabular Numbers Utility
|
|
186
|
+
// ============================================
|
|
187
|
+
.xiri-tabular-nums {
|
|
188
|
+
@include mixins.xiri-tabular-nums;
|
|
189
|
+
}
|
|
190
|
+
|
|
183
191
|
// ============================================
|
|
184
192
|
// Tab Body Content Padding
|
|
185
193
|
// ============================================
|