@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xiriframework/xiri-ng",
3
- "version": "0.2.48",
3
+ "version": "0.2.49",
4
4
  "description": "Angular UI component library for the Xiri Framework",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -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
- <xiri-stat-grid [settings]="{ stats: [...], columns: 4, title: 'KPIs' }"/>
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: 28px;
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: 36px;
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: 12px;
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
  // ============================================