@lmvz-ds/components 0.24.0 → 0.26.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.
Files changed (140) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/cjs/{ds.constants-DSnxZ3ia.js → ds.constants-8fh6ItAF.js} +1 -1
  3. package/cjs/{index-lW-SEvL7.js → index-BCFBLj0e.js} +1 -1
  4. package/cjs/index.cjs.js +196 -2
  5. package/cjs/lmvz-action.cjs.entry.js +1 -1
  6. package/cjs/lmvz-button-group.cjs.entry.js +183 -0
  7. package/cjs/lmvz-button_2.cjs.entry.js +198 -0
  8. package/cjs/lmvz-card.cjs.entry.js +2 -2
  9. package/cjs/lmvz-checkbox.cjs.entry.js +5 -5
  10. package/cjs/lmvz-chip.cjs.entry.js +4 -4
  11. package/cjs/lmvz-components.cjs.js +3 -3
  12. package/cjs/lmvz-header_2.cjs.entry.js +2 -2
  13. package/cjs/lmvz-input.cjs.entry.js +3 -3
  14. package/cjs/lmvz-menuitem.cjs.entry.js +3 -3
  15. package/cjs/lmvz-modal.cjs.entry.js +5 -5
  16. package/cjs/lmvz-radio.cjs.entry.js +334 -0
  17. package/cjs/lmvz-select.cjs.entry.js +4 -4
  18. package/cjs/lmvz-snackbar.cjs.entry.js +83 -0
  19. package/cjs/lmvz-toggle.cjs.entry.js +7 -5
  20. package/cjs/loader.cjs.js +2 -2
  21. package/cjs/{reactive-controller-host-BOFg4vL-.js → reactive-controller-host-DrtMkMd7.js} +1 -1
  22. package/collection/api/ds.constants.js +4 -1
  23. package/collection/collection-manifest.json +3 -1
  24. package/collection/components/lmvz-button/lmvz-button.css +8 -8
  25. package/collection/components/lmvz-button-group/lmvz-button-group.css +1 -1
  26. package/collection/components/lmvz-card/lmvz-card.css +11 -11
  27. package/collection/components/lmvz-checkbox/lmvz-checkbox.css +8 -11
  28. package/collection/components/lmvz-checkbox/lmvz-checkbox.js +2 -2
  29. package/collection/components/lmvz-chip/lmvz-chip.css +3 -3
  30. package/collection/components/lmvz-icon/lmvz-icon.js +1 -1
  31. package/collection/components/lmvz-input/lmvz-input.css +5 -9
  32. package/collection/components/lmvz-menuitem/lmvz-menuitem.css +3 -3
  33. package/collection/components/lmvz-modal/lmvz-modal.css +21 -15
  34. package/collection/components/lmvz-modal/lmvz-modal.js +2 -2
  35. package/collection/components/lmvz-radio/lmvz-radio.css +182 -0
  36. package/collection/components/lmvz-radio/lmvz-radio.js +487 -0
  37. package/collection/components/lmvz-select/lmvz-select.css +3 -3
  38. package/collection/components/lmvz-select/lmvz-select.js +1 -1
  39. package/collection/components/lmvz-snackbar/lmvz-snackbar.css +101 -0
  40. package/collection/components/lmvz-snackbar/lmvz-snackbar.js +266 -0
  41. package/collection/components/lmvz-snackbar/public.js +1 -0
  42. package/collection/components/lmvz-snackbar/snackbar-controller.js +194 -0
  43. package/collection/components/lmvz-toggle/lmvz-toggle.css +4 -9
  44. package/collection/components/lmvz-toggle/lmvz-toggle.js +3 -3
  45. package/collection/index.js +1 -0
  46. package/collection/integration/header-integration/header-integration.js +1 -1
  47. package/collection/styles/fragments/_focus-within.css +13 -0
  48. package/collection/utils/radio/radio-group-controller.js +160 -0
  49. package/components/index.d.ts +4 -0
  50. package/components/index.d.ts.bak +4 -0
  51. package/components/index.js +1 -1
  52. package/components/lmvz-action.js +1 -1
  53. package/components/lmvz-button-group.js +1 -1
  54. package/components/lmvz-button.js +1 -1
  55. package/components/lmvz-card.js +1 -1
  56. package/components/lmvz-checkbox.js +1 -1
  57. package/components/lmvz-chip.js +1 -1
  58. package/components/lmvz-header.js +1 -1
  59. package/components/lmvz-icon.js +1 -1
  60. package/components/lmvz-input.js +1 -1
  61. package/components/lmvz-menuitem.js +1 -1
  62. package/components/lmvz-modal.js +1 -1
  63. package/components/lmvz-radio.d.ts +11 -0
  64. package/components/lmvz-radio.d.ts.bak +11 -0
  65. package/components/lmvz-radio.js +1 -0
  66. package/components/lmvz-select.js +1 -1
  67. package/components/lmvz-snackbar.d.ts +11 -0
  68. package/components/lmvz-snackbar.d.ts.bak +11 -0
  69. package/components/lmvz-snackbar.js +1 -0
  70. package/components/lmvz-toggle.js +1 -1
  71. package/components/{p-slgmfnHm.js → p-BOzeYzKk.js} +1 -1
  72. package/components/{p-Cg2XX_J-.js → p-DYa3zcGE.js} +1 -1
  73. package/components/{p-DOTK1OW3.js → p-JAKQdFhF.js} +1 -1
  74. package/components/{p-CcnyKhAw.js → p-WLZ7VWNX.js} +1 -1
  75. package/components/{p-CK8cAKcB.js → p-c7OzBK8f.js} +1 -1
  76. package/components/{p-DSvYtVoD.js → p-lsUdmjdw.js} +1 -1
  77. package/esm/{ds.constants-Bmi89ll1.js → ds.constants-BOOwq5dE.js} +1 -1
  78. package/esm/{index-Aa_425iY.js → index-CKYszC64.js} +1 -1
  79. package/esm/index.js +198 -1
  80. package/esm/lmvz-action.entry.js +1 -1
  81. package/esm/lmvz-button-group.entry.js +181 -0
  82. package/esm/lmvz-button_2.entry.js +195 -0
  83. package/esm/lmvz-card.entry.js +2 -2
  84. package/esm/lmvz-checkbox.entry.js +5 -5
  85. package/esm/lmvz-chip.entry.js +4 -4
  86. package/esm/lmvz-components.js +4 -4
  87. package/esm/lmvz-header_2.entry.js +2 -2
  88. package/esm/lmvz-input.entry.js +3 -3
  89. package/esm/lmvz-menuitem.entry.js +3 -3
  90. package/esm/lmvz-modal.entry.js +5 -5
  91. package/esm/lmvz-radio.entry.js +332 -0
  92. package/esm/lmvz-select.entry.js +4 -4
  93. package/esm/lmvz-snackbar.entry.js +81 -0
  94. package/esm/lmvz-toggle.entry.js +7 -5
  95. package/esm/loader.js +3 -3
  96. package/esm/{reactive-controller-host-CroMsXdS.js → reactive-controller-host-ZrGf1F2-.js} +1 -1
  97. package/hydrate/index.js +467 -19
  98. package/hydrate/index.mjs +467 -19
  99. package/lmvz-components/index.esm.js +1 -1
  100. package/lmvz-components/lmvz-components.esm.js +1 -1
  101. package/lmvz-components/{p-d1dacf7e.entry.js → p-01aeca60.entry.js} +1 -1
  102. package/lmvz-components/p-0a37e0f2.entry.js +1 -0
  103. package/lmvz-components/p-14c3d837.entry.js +1 -0
  104. package/lmvz-components/{p-4263c9b2.entry.js → p-24e63b0a.entry.js} +1 -1
  105. package/lmvz-components/p-25f045b2.entry.js +1 -0
  106. package/lmvz-components/{p-f6d1d9df.entry.js → p-3da301a6.entry.js} +1 -1
  107. package/lmvz-components/p-40228d48.entry.js +1 -0
  108. package/lmvz-components/p-4da9073a.entry.js +1 -0
  109. package/lmvz-components/p-6de9981f.entry.js +1 -0
  110. package/lmvz-components/{p-6f8cbc4f.entry.js → p-758078db.entry.js} +1 -1
  111. package/lmvz-components/{p-88adb9fa.entry.js → p-8dae99f1.entry.js} +1 -1
  112. package/lmvz-components/p-BOOwq5dE.js +1 -0
  113. package/lmvz-components/{p-BRl6zKXT.js → p-CwX1wKkM.js} +1 -1
  114. package/lmvz-components/{p-a7c3074a.entry.js → p-e1eaa7a2.entry.js} +1 -1
  115. package/lmvz-components/p-f5cece32.entry.js +1 -0
  116. package/lmvz-components/p-fe607f10.entry.js +1 -0
  117. package/manifest.json +892 -205
  118. package/package.json +9 -1
  119. package/types/api/ds.constants.d.ts +9 -1
  120. package/types/components/lmvz-radio/lmvz-radio.d.ts +42 -0
  121. package/types/components/lmvz-snackbar/lmvz-snackbar.d.ts +21 -0
  122. package/types/components/lmvz-snackbar/public.d.ts +2 -0
  123. package/types/components/lmvz-snackbar/snackbar-controller.d.ts +32 -0
  124. package/types/components.d.ts +237 -1
  125. package/types/index.d.ts +1 -0
  126. package/types/stencil-public-runtime.d.ts +1 -0
  127. package/types/utils/radio/radio-group-controller.d.ts +26 -0
  128. package/assets/icons/checkmark.svg +0 -4
  129. package/assets/icons/close-sm.svg +0 -3
  130. package/cjs/lmvz-button_3.cjs.entry.js +0 -375
  131. package/collection/assets/icons/checkmark.svg +0 -4
  132. package/collection/assets/icons/close-sm.svg +0 -3
  133. package/esm/lmvz-button_3.entry.js +0 -371
  134. package/lmvz-components/p-2824a56b.entry.js +0 -1
  135. package/lmvz-components/p-3846ba08.entry.js +0 -1
  136. package/lmvz-components/p-4f5c3c4a.entry.js +0 -1
  137. package/lmvz-components/p-Bmi89ll1.js +0 -1
  138. package/lmvz-components/p-b3b04d46.entry.js +0 -1
  139. package/lmvz-components/p-fefefc54.entry.js +0 -1
  140. /package/lmvz-components/{p-Aa_425iY.js → p-CKYszC64.js} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # @lmvz-ds/components
2
2
 
3
+ ## 0.26.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 80f5b7d: Snackbar Komponente und Controller hinzugefügt.
8
+
9
+ ### Patch Changes
10
+
11
+ - 1c0f1e5: Design Tokens aktualisiert
12
+ - 72c4ec5: Design Tokens aktualisiert
13
+
14
+ ## 0.25.0
15
+
16
+ ### Minor Changes
17
+
18
+ - 5780fd2: Add `lmvz-radio` — accessible, form-associated radio button component with FACE support, full ARIA model, forced-colors, and Angular value accessor binding
19
+
20
+ ### Patch Changes
21
+
22
+ - 64bffb7: Design Tokens aktualisiert
23
+ - 1dcb478: Design Tokens aktualisiert
24
+
3
25
  ## 0.24.0
4
26
 
5
27
  ## 0.23.0
@@ -4,7 +4,7 @@ const sizes = ['xs', 'sm', 'md', 'lg'];
4
4
  const textSizes = [...sizes, 'xl'];
5
5
  const inputTypes = ['text', 'email', 'password', 'tel', 'url', 'search', 'number'];
6
6
  const iconSizes = [...sizes, 'inherit'];
7
- const iconWeights = ['thin', 'medium', 'bold', 'filled'];
7
+ const iconWeights = ['thin', 'medium', 'bold'];
8
8
  const chipTypes = ['active', 'warning', 'success', 'error', 'neutral'];
9
9
  const chipSizes = ['default', 'small'];
10
10
 
@@ -4,7 +4,7 @@ const NAMESPACE = 'lmvz-components';
4
4
  const BUILD = /* lmvz-components */ { hotModuleReplacement: false, hydratedSelectorName: "hydrated", lazyLoad: true, propChangeCallback: true, slotRelocation: true, state: true, updatable: true};
5
5
 
6
6
  /*
7
- Stencil Client Platform v4.43.4 | MIT Licensed | https://stenciljs.com
7
+ Stencil Client Platform v4.43.5 | MIT Licensed | https://stenciljs.com
8
8
  */
9
9
 
10
10
  var Build = {
package/cjs/index.cjs.js CHANGED
@@ -1,12 +1,205 @@
1
1
  'use strict';
2
2
 
3
3
  var ariaLoader = require('./aria-loader-BRo2FTGh.js');
4
- var ds_constants = require('./ds.constants-DSnxZ3ia.js');
4
+ var ds_constants = require('./ds.constants-8fh6ItAF.js');
5
5
  var icons = require('./icons-BQASWgk-.js');
6
6
  require('./svg-BMBduILB.js');
7
7
  require('./logger-DsM6xg6V.js');
8
8
 
9
-
9
+ const PRIORITY_MAP = {
10
+ low: 0,
11
+ normal: 1,
12
+ high: 2,
13
+ };
14
+ const STATUS_DURATION = {
15
+ success: 5000,
16
+ warning: 5000,
17
+ error: 8000,
18
+ };
19
+ let idCounter = 0;
20
+ function nextId() {
21
+ idCounter += 1;
22
+ return `snackbar-${idCounter}`;
23
+ }
24
+ function resolveHostElement() {
25
+ if (typeof document === 'undefined') {
26
+ return undefined;
27
+ }
28
+ const existing = document.querySelector('[data-snackbar-host]');
29
+ if (existing) {
30
+ return existing;
31
+ }
32
+ const el = document.createElement('lmvz-snackbar');
33
+ el.setAttribute('data-snackbar-host', '');
34
+ document.body.appendChild(el);
35
+ return el;
36
+ }
37
+ class SnackbarController {
38
+ hostEl = undefined;
39
+ active = undefined;
40
+ getHost() {
41
+ if (this.hostEl !== undefined && !this.hostEl.isConnected) {
42
+ this.hostEl = undefined;
43
+ }
44
+ if (this.hostEl === undefined) {
45
+ this.hostEl = resolveHostElement();
46
+ }
47
+ return this.hostEl;
48
+ }
49
+ clearTimer(entry) {
50
+ if (entry.timerId !== undefined) {
51
+ clearTimeout(entry.timerId);
52
+ entry.timerId = undefined;
53
+ }
54
+ }
55
+ scheduleTimer(entry, delayMs) {
56
+ if (delayMs <= 0) {
57
+ return;
58
+ }
59
+ entry.timerStartedAt = Date.now();
60
+ entry.timerId = setTimeout(() => {
61
+ if (this.active !== undefined && this.active.id === entry.id) {
62
+ this.dismissActive(entry, 'timeout');
63
+ }
64
+ }, delayMs);
65
+ }
66
+ dismissActive(entry, reason) {
67
+ this.clearTimer(entry);
68
+ const host = entry.hostEl;
69
+ host.removeEventListener('pointerenter', entry.onPointerEnter);
70
+ host.removeEventListener('pointerleave', entry.onPointerLeave);
71
+ host.removeEventListener('focusin', entry.onFocusIn);
72
+ host.removeEventListener('focusout', entry.onFocusOut);
73
+ if (entry.onActionListener) {
74
+ host.removeEventListener('lmvzAction', entry.onActionListener);
75
+ }
76
+ host.hide?.();
77
+ if (this.active?.id === entry.id) {
78
+ this.active = undefined;
79
+ }
80
+ if (reason !== 'action') {
81
+ host.dispatchEvent(new CustomEvent('lmvzClose', { detail: { reason }, bubbles: true, composed: true }));
82
+ }
83
+ entry.resolve({ reason });
84
+ }
85
+ pauseTimer(entry) {
86
+ entry.pauseCount += 1;
87
+ if (entry.pauseCount > 1 || entry.timerId === undefined) {
88
+ return;
89
+ }
90
+ const elapsed = entry.timerStartedAt !== undefined ? Date.now() - entry.timerStartedAt : 0;
91
+ entry.remaining = Math.max(0, entry.remaining - elapsed);
92
+ entry.timerStartedAt = undefined;
93
+ this.clearTimer(entry);
94
+ }
95
+ resumeTimer(entry) {
96
+ if (entry.pauseCount > 0) {
97
+ entry.pauseCount -= 1;
98
+ }
99
+ if (entry.pauseCount > 0) {
100
+ return;
101
+ }
102
+ if (entry.remaining > 0) {
103
+ this.scheduleTimer(entry, entry.remaining);
104
+ }
105
+ }
106
+ applyToHost(host, options) {
107
+ host.setAttribute('status', options.status ?? 'success');
108
+ if (options.actionLabel !== undefined) {
109
+ host.setAttribute('action-label', options.actionLabel);
110
+ }
111
+ else {
112
+ host.removeAttribute('action-label');
113
+ }
114
+ }
115
+ open(options) {
116
+ const incomingPriority = PRIORITY_MAP[options.priority ?? 'normal'];
117
+ if (this.active !== undefined && incomingPriority < this.active.priority) {
118
+ let swallowResolve;
119
+ const closed = new Promise((resolve) => {
120
+ swallowResolve = resolve;
121
+ });
122
+ swallowResolve({ reason: 'swallowed' });
123
+ const id = nextId();
124
+ return {
125
+ id,
126
+ closed,
127
+ dismiss() {
128
+ },
129
+ };
130
+ }
131
+ if (this.active !== undefined) {
132
+ this.dismissActive(this.active, 'overridden');
133
+ }
134
+ const host = this.getHost();
135
+ if (host === undefined) {
136
+ const id = nextId();
137
+ let ssrResolve;
138
+ const closed = new Promise((resolve) => {
139
+ ssrResolve = resolve;
140
+ });
141
+ ssrResolve({ reason: 'swallowed' });
142
+ return { id, closed, dismiss() { } };
143
+ }
144
+ const id = nextId();
145
+ const status = options.status ?? 'success';
146
+ const durationMs = options.duration === 0 ? 0 : (options.duration ?? STATUS_DURATION[status]);
147
+ let entryResolve;
148
+ const closed = new Promise((resolve) => {
149
+ entryResolve = resolve;
150
+ });
151
+ const entry = {
152
+ id,
153
+ priority: incomingPriority,
154
+ resolve: entryResolve,
155
+ timerId: undefined,
156
+ remaining: durationMs,
157
+ timerStartedAt: undefined,
158
+ pauseCount: 0,
159
+ hostEl: host,
160
+ onPointerEnter: () => this.pauseTimer(entry),
161
+ onPointerLeave: () => this.resumeTimer(entry),
162
+ onFocusIn: () => this.pauseTimer(entry),
163
+ onFocusOut: () => this.resumeTimer(entry),
164
+ };
165
+ this.active = entry;
166
+ host.addEventListener('pointerenter', entry.onPointerEnter);
167
+ host.addEventListener('pointerleave', entry.onPointerLeave);
168
+ host.addEventListener('focusin', entry.onFocusIn);
169
+ host.addEventListener('focusout', entry.onFocusOut);
170
+ this.applyToHost(host, options);
171
+ const onAction = () => {
172
+ if (this.active !== undefined && this.active.id === id) {
173
+ options.onAction?.();
174
+ this.dismissActive(entry, 'action');
175
+ }
176
+ };
177
+ entry.onActionListener = onAction;
178
+ host.addEventListener('lmvzAction', onAction, { once: true });
179
+ host.show?.();
180
+ queueMicrotask(() => host.setAttribute('message', options.message));
181
+ if (durationMs > 0) {
182
+ this.scheduleTimer(entry, durationMs);
183
+ }
184
+ return {
185
+ id,
186
+ closed,
187
+ dismiss: () => {
188
+ if (this.active?.id === id) {
189
+ this.dismissActive(entry, 'manual');
190
+ }
191
+ },
192
+ };
193
+ }
194
+ dismiss(id) {
195
+ if (!this.active) {
196
+ return;
197
+ }
198
+ if (!id || this.active.id === id) {
199
+ this.dismissActive(this.active, 'manual');
200
+ }
201
+ }
202
+ }
10
203
 
11
204
  exports.ARIA_VALIDATION_RUNTIME_CHANGED_EVENT = ariaLoader.ARIA_VALIDATION_RUNTIME_CHANGED_EVENT;
12
205
  exports.disableAriaValidation = ariaLoader.disableAriaValidation;
@@ -23,3 +216,4 @@ exports.textSizes = ds_constants.textSizes;
23
216
  exports.getRegisteredIconProvider = icons.getRegisteredIconProvider;
24
217
  exports.registerIconProvider = icons.registerIconProvider;
25
218
  exports.typedIconFromSet = icons.typedIconFromSet;
219
+ exports.SnackbarController = SnackbarController;
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-lW-SEvL7.js');
3
+ var index = require('./index-BCFBLj0e.js');
4
4
 
5
5
  const lmvzActionCss = () => `:host{display:block}`;
6
6
 
@@ -0,0 +1,183 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index-BCFBLj0e.js');
4
+ var ariaLoader = require('./aria-loader-BRo2FTGh.js');
5
+ var component = require('./component-C7cavwmZ.js');
6
+
7
+ /**
8
+ * Returns a function that delegates to the given predicate/filter and negates its result.
9
+ * The returned function preserves the input function's types, arguments and timing.
10
+ *
11
+ * @param delegate - The predicate/filter function to negate.
12
+ * @returns A function that returns the negated result.
13
+ */
14
+ function negate(delegate) {
15
+ return (...args) => {
16
+ const result = delegate(...args);
17
+ return ariaLoader.isPromise(result) ? result.then((res) => !res) : !result;
18
+ };
19
+ }
20
+
21
+ const lmvzButtonGroupCss = () => `:host{display:flex;justify-content:flex-end;gap:var(--lmvz-component-input-gap-md, clamp(0.5rem, 0.44rem + 0.26vw, 0.75rem));font:var(--lmvz-typography-body-md, 400 clamp(0.88rem, 0.84rem + 0.13vw, 1rem) / 1.5 Router);flex-wrap:wrap}::slotted([hidden]){display:none !important}`;
22
+
23
+ const LmvzButtonGroup = class {
24
+ constructor(hostRef) {
25
+ index.registerInstance(this, hostRef);
26
+ }
27
+ actionsSlot;
28
+ validationMessageCache = [];
29
+ actionsStateObserver;
30
+ get primaryEnabledAction() {
31
+ return this.enabledButtons.find(isPrimaryAction) ?? this.enabledButtons[0];
32
+ }
33
+ get hasActions() {
34
+ return this.assignedButtons.some((element) => isVisible(element) && isActionButton(element) && !isDisabledButton(element));
35
+ }
36
+ componentDidLoad() {
37
+ this.handleActionsSlotChange();
38
+ }
39
+ disconnectedCallback() {
40
+ this.actionsStateObserver?.disconnect();
41
+ }
42
+ get assignedElements() {
43
+ return this.actionsSlot?.assignedElements({ flatten: true }) ?? [];
44
+ }
45
+ get assignedButtons() {
46
+ return this.assignedElements.filter(isActionButton);
47
+ }
48
+ get visibleButtons() {
49
+ return this.assignedButtons.filter(isVisible);
50
+ }
51
+ get enabledButtons() {
52
+ return this.visibleButtons.filter(negate(isDisabledButton));
53
+ }
54
+ getActionValidationResult() {
55
+ if (!this.visibleButtons.length) {
56
+ return [];
57
+ }
58
+ const primaryActions = this.visibleButtons.filter(isPrimaryAction);
59
+ const secondaryActions = this.visibleButtons.filter(isSecondaryAction);
60
+ const issues = [];
61
+ const order = this.visibleButtons.toReversed();
62
+ if (primaryActions.length !== 1)
63
+ issues.push('LmvzModal actions slot must contain exactly one primary action.');
64
+ if (secondaryActions.length > 1)
65
+ issues.push(`LmvzModal actions slot must contain at most one secondary action (received ${secondaryActions.length})`);
66
+ if (primaryActions.length) {
67
+ const primaryAction = primaryActions[0];
68
+ const secondaryAction = secondaryActions[0];
69
+ if (order.indexOf(primaryAction) !== 0)
70
+ issues.push('Primary action must be the last focusable element in the actions slot (i.e. rightmost button).');
71
+ if (secondaryAction && order.indexOf(secondaryAction) !== 1)
72
+ issues.push('Secondary action must be the second-to-last focusable element in the actions slot (i.e. left of primary button).');
73
+ }
74
+ else if (secondaryActions.length) {
75
+ const secondaryAction = secondaryActions[0];
76
+ if (order.indexOf(secondaryAction) !== 0)
77
+ issues.push('Secondary action must be the last focusable element in the actions slot when no primary action is present (i.e. rightmost button).');
78
+ }
79
+ return issues;
80
+ }
81
+ handleActionsSlotChange = () => {
82
+ this.observeActionState();
83
+ this.syncActionsState();
84
+ };
85
+ observeActionState() {
86
+ if (typeof MutationObserver === 'undefined')
87
+ return;
88
+ this.actionsStateObserver?.disconnect();
89
+ if (!this.assignedButtons.length)
90
+ return;
91
+ this.actionsStateObserver = new MutationObserver(() => {
92
+ this.syncActionsState();
93
+ });
94
+ this.assignedButtons.forEach((element) => {
95
+ this.actionsStateObserver?.observe(element, {
96
+ attributes: true,
97
+ attributeFilter: ['disabled', 'hidden', 'variant'],
98
+ });
99
+ });
100
+ }
101
+ syncActionsState() {
102
+ const assignedElements = this.assignedElements;
103
+ assignedElements.forEach((element) => {
104
+ const isAllowedAction = ['LMVZ-BUTTON', 'BUTTON'].includes(element.tagName.toUpperCase());
105
+ if (isAllowedAction)
106
+ return;
107
+ if (!element.hasAttribute('hidden')) {
108
+ element.setAttribute('hidden', '');
109
+ }
110
+ if (element.getAttribute('aria-hidden') !== 'true') {
111
+ element.setAttribute('aria-hidden', 'true');
112
+ }
113
+ });
114
+ this.checkActions();
115
+ const length = this.visibleButtons.length;
116
+ for (let i = 0; i < length; i++) {
117
+ const variant = i === length - 1 ? 'primary' : i === length - 2 ? 'secondary' : 'tertiary';
118
+ const element = this.visibleButtons.at(i);
119
+ if (!element)
120
+ continue;
121
+ if (isLmvzButton(element)) {
122
+ if (!element.getAttribute('variant'))
123
+ element.setAttribute('variant', variant);
124
+ }
125
+ else {
126
+ element.classList.add(variant);
127
+ }
128
+ }
129
+ this.focusPrimaryAction();
130
+ }
131
+ focusPrimaryAction() {
132
+ const focusTarget = this.primaryEnabledAction;
133
+ if (!focusTarget || typeof window === 'undefined')
134
+ return;
135
+ window.requestAnimationFrame(() => {
136
+ if (component.canReceiveFocus(focusTarget)) {
137
+ focusTarget.focus();
138
+ }
139
+ });
140
+ }
141
+ checkActions() {
142
+ if (!ariaLoader.isAriaValidationEnabled())
143
+ return;
144
+ const issues = this.getActionValidationResult();
145
+ if (!issues.length) {
146
+ return;
147
+ }
148
+ issues.forEach((issue) => {
149
+ if (this.validationMessageCache.includes(issue))
150
+ return;
151
+ console.warn(issue);
152
+ this.validationMessageCache.push(issue);
153
+ });
154
+ }
155
+ render() {
156
+ return (index.h(index.Host, { key: '56b60821ecaa2301d13e78d621e873aa74cd170e' }, index.h("slot", { key: 'e6a1422950fa5b0026356b7788a607a690116186', ref: (element) => (this.actionsSlot = element), onSlotchange: this.handleActionsSlotChange })));
157
+ }
158
+ };
159
+ function isActionButton(element) {
160
+ return ['LMVZ-BUTTON', 'BUTTON'].includes(element.tagName.toUpperCase());
161
+ }
162
+ function isLmvzButton(element) {
163
+ return element?.tagName.toUpperCase() === 'LMVZ-BUTTON';
164
+ }
165
+ function isDisabledButton(element) {
166
+ return element.hasAttribute('disabled') || element.disabled === true;
167
+ }
168
+ function isVisible(element) {
169
+ return !element.hasAttribute('hidden');
170
+ }
171
+ function getActionVariant(element) {
172
+ const variant = element.getAttribute('variant') ?? element.variant;
173
+ return variant === 'primary' || variant === 'secondary' || variant === 'tertiary' ? variant : 'secondary';
174
+ }
175
+ function isPrimaryAction(element) {
176
+ return getActionVariant(element) === 'primary';
177
+ }
178
+ function isSecondaryAction(element) {
179
+ return getActionVariant(element) === 'secondary';
180
+ }
181
+ LmvzButtonGroup.style = lmvzButtonGroupCss();
182
+
183
+ exports.lmvz_button_group = LmvzButtonGroup;
@@ -0,0 +1,198 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index-BCFBLj0e.js');
4
+ var index$1 = require('./index-Bp6Dd2i1.js');
5
+ var reactiveControllerHost = require('./reactive-controller-host-DrtMkMd7.js');
6
+ var elementActivationController = require('./element-activation-controller-DC_6T0Rt.js');
7
+ var component = require('./component-C7cavwmZ.js');
8
+ var svg = require('./svg-BMBduILB.js');
9
+ var icons = require('./icons-BQASWgk-.js');
10
+ require('./aria-loader-BRo2FTGh.js');
11
+ require('./logger-DsM6xg6V.js');
12
+
13
+ const lmvzButtonCss = () => ` @layer lmvz-ds.reset, lmvz-ds.theme, lmvz-ds.components, lmvz-ds.overrides; @layer lmvz-ds.theme { @font-face { font-family: Router; src: local('RouterBook-Regular'), local('Router-Book'), url('/assets/fonts/Router-Book.woff') format('woff'); font-weight: 400; } @font-face { font-family: Router; src: local('RouterMedium-Regular'), local('Router-Medium'), url('/assets/fonts/Router-Medium.woff') format('woff'); font-weight: 500; } @font-face { font-family: Router; src: local('RouterBold-Regular'), local('Router-Bold'), url('/assets/fonts/Router-Bold.woff') format('woff'); font-weight: 700; } } @layer lmvz-ds.reset { body { margin: 0; } h1, h2, h3, h4, h5, h6 { margin: 0; } *[hidden] { display: none !important; } } :host { button { --lmvz-button-color: var(--lmvz-component-color, var(--lmvz-semantic-color-int-on-secondary, #000000)); --lmvz-button-padding-inline: var(--lmvz-button-padding, var(--lmvz-component-input-padding-md, clamp(0.88rem, 0.84rem + 0.13vw, 1rem))); --lmvz-button-padding-block: var(--lmvz-button-padding, var(--lmvz-component-input-padding-md, clamp(0.88rem, 0.84rem + 0.13vw, 1rem))); --lmvz-button-gap: var(--lmvz-component-input-gap-md, clamp(0.5rem, 0.44rem + 0.26vw, 0.75rem)); --lmvz-button-min-height: var(--lmvz-component-input-size-md, clamp(2.5rem, 2.44rem + 0.26vw, 2.75rem)); --lmvz-button-font: var(--lmvz-typography-body-md-strong, 500 clamp(0.88rem, 0.84rem + 0.13vw, 1rem) / 1.5 Router); --lmvz-button-radius: var(--lmvz-component-input-radius-default, 999px); --lmvz-button-border-width: 0; --lmvz-button-border-color: transparent; --lmvz-button-background: var(--lmvz-semantic-color-int-secondary, #f0f0f0); display: inline-flex; align-items: center; justify-content: center; gap: var(--lmvz-button-gap); padding-block: var(--lmvz-button-padding-block); padding-inline: var(--lmvz-button-padding-inline); min-height: var(--lmvz-button-min-height); border-radius: var(--lmvz-button-radius); border: var(--lmvz-button-border-width) solid var(--lmvz-button-border-color); background-color: var(--lmvz-button-background); color: var(--lmvz-button-color); cursor: pointer; font: var(--lmvz-button-font); text-align: center; text-decoration: none; white-space: nowrap; transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease; } button > * { font: inherit; color: inherit; } button:focus-visible { outline: var(--lmvz-ds-outline, 1px solid #0e7ab4); outline-offset: var(--lmvz-ds-outline-offset, clamp(0.25rem, 0.19rem + 0.26vw, 0.5rem)); } button:is([disabled], .disabled) { cursor: not-allowed; pointer-events: none; opacity: var(--lmvz-component-input-disabled-opacity, 40%); } button:not([disabled]):hover { --lmvz-button-background: var(--lmvz-semantic-color-int-secondary-hover, #e0e0e0); } button:not([disabled]):active { --lmvz-button-background: var(--lmvz-semantic-color-int-secondary-active, #d4d4d4); } button.primary { --lmvz-button-background: var(--lmvz-semantic-color-int-primary, #000000); --lmvz-button-color: var(--lmvz-semantic-color-int-on-primary, #ffffff); --lmvz-button-border-width: 0; --lmvz-button-border-color: transparent; } button.primary:not([disabled], .disabled):hover { --lmvz-button-background: var(--lmvz-semantic-color-int-primary-hover, #2e2e2e); } button.primary:not([disabled], .disabled):active { --lmvz-button-background: var(--lmvz-semantic-color-int-primary-active, #545454); } button.secondary { --lmvz-button-background: var(--lmvz-semantic-color-int-secondary, #f0f0f0); --lmvz-button-color: var(--lmvz-semantic-color-int-on-secondary, #000000); --lmvz-button-border-width: 0; --lmvz-button-border-color: transparent; } button.secondary:not([disabled], .disabled):hover { --lmvz-button-background: var(--lmvz-semantic-color-int-secondary-hover, #e0e0e0); --lmvz-button-color: var(--lmvz-semantic-color-int-on-secondary-hover, #000000); } button.secondary:not([disabled], .disabled):active { --lmvz-button-background: var(--lmvz-semantic-color-int-secondary-active, #d4d4d4); --lmvz-button-color: var(--lmvz-semantic-color-int-on-secondary-active, #000000); } button.tertiary { --lmvz-button-background: var(--lmvz-semantic-color-int-tertiary, #ffffff); --lmvz-button-color: var(--lmvz-semantic-color-int-on-tertiary, #000000); } button.tertiary:not([disabled], .disabled):hover { --lmvz-button-background: var(--lmvz-semantic-color-int-tertiary-hover, #f0f0f0); --lmvz-button-color: var(--lmvz-semantic-color-int-on-tertiary-hover, #000000); } button.tertiary:not([disabled], .disabled):active { --lmvz-button-background: var(--lmvz-semantic-color-int-tertiary-active, #e0e0e0); --lmvz-button-color: var(--lmvz-semantic-color-int-on-tertiary-active, #000000); } button.small { --lmvz-button-padding-inline: var(--lmvz-component-input-padding-sm, clamp(0.75rem, 0.72rem + 0.13vw, 0.88rem)); --lmvz-button-padding-block: var(--lmvz-component-input-padding-sm, clamp(0.75rem, 0.72rem + 0.13vw, 0.88rem)); --lmvz-button-gap: var(--lmvz-component-input-gap-sm, clamp(0.38rem, 0.31rem + 0.26vw, 0.63rem)); --lmvz-button-min-height: var(--lmvz-component-input-size-sm, clamp(2rem, 1.94rem + 0.26vw, 2.25rem)); --lmvz-button-font: var(--lmvz-typography-body-sm-strong, 500 clamp(0.69rem, 0.67rem + 0.06vw, 0.75rem) / 1.5 Router); } button.large { --lmvz-button-padding-inline: var(--lmvz-component-input-padding-lg, clamp(1rem, 0.94rem + 0.26vw, 1.25rem)); --lmvz-button-padding-block: var(--lmvz-component-input-padding-lg, clamp(1rem, 0.94rem + 0.26vw, 1.25rem)); --lmvz-button-gap: var(--lmvz-component-input-gap-lg, clamp(0.75rem, 0.69rem + 0.26vw, 1rem)); --lmvz-button-min-height: var(--lmvz-component-input-size-lg, clamp(2.75rem, 2.69rem + 0.26vw, 3rem)); --lmvz-button-font: var(--lmvz-typography-body-lg-strong, 500 clamp(1rem, 0.97rem + 0.13vw, 1.13rem) / 1.5 Router); } display: inline-block; } ::slotted(*) { --lmvz-component-color: var(--lmvz-button-color); } `;
14
+
15
+ const LmvzButton = class extends reactiveControllerHost.ReactiveControllerHost {
16
+ get el() { return index.getElement(this); }
17
+ validationEl;
18
+ inheritedAttributes = {};
19
+ formEl = null;
20
+ formButtonEl = null;
21
+ lmvzActivation;
22
+ get ti() {
23
+ return 0;
24
+ }
25
+ scale = 'default';
26
+ variant;
27
+ disabled = false;
28
+ type = 'button';
29
+ form;
30
+ formMethod;
31
+ name;
32
+ value;
33
+ constructor(hostRef) {
34
+ super();
35
+ index.registerInstance(this, hostRef);
36
+ this.lmvzActivation = index.createEvent(this, "lmvzActivation", 7);
37
+ this.addController(new reactiveControllerHost.AriaValidationController(this));
38
+ this.addController(new elementActivationController.ElementActivationController(this, {
39
+ localHandler: this.handleClick.bind(this),
40
+ keys: ['Enter'],
41
+ }));
42
+ }
43
+ connectedCallback() {
44
+ this.inheritedAttributes = component.inheritAriaAttributes(this.el);
45
+ super.connectedCallback();
46
+ }
47
+ disconnectedCallback() {
48
+ this.formButtonEl?.remove();
49
+ this.formButtonEl = null;
50
+ this.formEl = null;
51
+ super.disconnectedCallback();
52
+ }
53
+ renderHiddenButton() {
54
+ if (this.type !== 'submit') {
55
+ this.formButtonEl?.remove();
56
+ this.formButtonEl = null;
57
+ this.formEl = null;
58
+ return;
59
+ }
60
+ const formEl = component.findFormByRef(this.form, this.el);
61
+ if (!formEl) {
62
+ this.formButtonEl?.remove();
63
+ this.formButtonEl = null;
64
+ this.formEl = null;
65
+ return;
66
+ }
67
+ this.formEl = formEl;
68
+ const formButtonEl = this.formButtonEl ?? document.createElement('button');
69
+ formButtonEl.type = 'submit';
70
+ formButtonEl.style.display = 'none';
71
+ formButtonEl.disabled = this.disabled;
72
+ formButtonEl.name = this.name ?? '';
73
+ formButtonEl.value = this.value ?? '';
74
+ if (this.formMethod) {
75
+ formButtonEl.setAttribute('formmethod', this.formMethod);
76
+ }
77
+ else {
78
+ formButtonEl.removeAttribute('formmethod');
79
+ }
80
+ if (this.formButtonEl !== formButtonEl) {
81
+ this.formButtonEl = formButtonEl;
82
+ }
83
+ if (formButtonEl.parentElement !== formEl) {
84
+ formButtonEl.remove();
85
+ formEl.appendChild(formButtonEl);
86
+ }
87
+ }
88
+ submitForm(ev) {
89
+ if (this.formEl && this.formButtonEl) {
90
+ ev.preventDefault();
91
+ this.formButtonEl.click();
92
+ }
93
+ }
94
+ handleClick = (ev) => {
95
+ if (this.type === 'submit') {
96
+ this.submitForm(ev);
97
+ }
98
+ };
99
+ render() {
100
+ this.renderHiddenButton();
101
+ return (index.h(index.Host, { key: '8196de85afc3878c6f38e582d7c031f5d19bcd36', "aria-disabled": this.disabled ? 'true' : null }, index.h("button", { key: '8d73f979fa227de22a03403a2a3938684911060a', ref: (e) => (this.validationEl = e), part: "button", disabled: this.disabled, type: this.type, class: index$1.classNames(this.variant ?? 'secondary', { [this.scale ?? '']: !!this.scale, disabled: this.disabled }), ...this.inheritedAttributes }, index.h("slot", { key: '18e91a2f94ba0d7e5cf13150191003e2f0b2a03a' }))));
102
+ }
103
+ static get delegatesFocus() { return true; }
104
+ };
105
+ LmvzButton.style = lmvzButtonCss();
106
+
107
+ const lmvzIconCss = () => `.sc-lmvz-icon-h{--lmvz-icon-color:var(--lmvz-component-color, var(--lmvz-semantic-color-on-surface-input-primary, #000000));--lmvz-icon-size:var(--lmvz-component-size, var(--lmvz-component-icon-size-md, clamp(1rem, 0.94rem + 0.26vw, 1.25rem)));display:inline-block;line-height:0;svg{display:block;height:var(--lmvz-icon-size);width:auto}svg path{stroke:var(--lmvz-icon-color);fill:none}}[size='xs'].sc-lmvz-icon-h{svg{--lmvz-icon-size:var(--lmvz-component-icon-size-xs, clamp(0.75rem, 0.72rem + 0.13vw, 0.88rem))}}[size='sm'].sc-lmvz-icon-h{svg{--lmvz-icon-size:var(--lmvz-component-icon-size-sm, clamp(0.88rem, 0.84rem + 0.13vw, 1rem))}}[size='md'].sc-lmvz-icon-h{svg{--lmvz-icon-size:var(--lmvz-component-icon-size-md, clamp(1rem, 0.94rem + 0.26vw, 1.25rem))}}[size='lg'].sc-lmvz-icon-h{svg{--lmvz-icon-size:var(--lmvz-component-icon-size-lg, clamp(1.5rem, 1.44rem + 0.26vw, 1.75rem))}}[size='inherit'].sc-lmvz-icon-h{svg{height:var(--lmvz-component-size, inherit)}}[weight='light'].sc-lmvz-icon-h{svg path{stroke-width:1}}[weight='medium'].sc-lmvz-icon-h{svg path{stroke-width:1.5}}[weight='bold'].sc-lmvz-icon-h{svg path{stroke-width:2}}[weight='filled'].sc-lmvz-icon-h{svg path{stroke-width:2;fill:var(--lmvz-icon-color)}}`;
108
+
109
+ const LmvzIcon = class extends reactiveControllerHost.ReactiveControllerHost {
110
+ intersectionObserver;
111
+ ariaValidationController = new reactiveControllerHost.AriaValidationController(this);
112
+ get el() { return index.getElement(this); }
113
+ validationEl;
114
+ icon;
115
+ weight = 'medium';
116
+ size = 'md';
117
+ iconset;
118
+ iconData;
119
+ visible = false;
120
+ ariaLabel;
121
+ get ariaHidden() {
122
+ return !this.ariaLabel;
123
+ }
124
+ constructor(hostRef) {
125
+ super();
126
+ index.registerInstance(this, hostRef);
127
+ this.addController(this.ariaValidationController);
128
+ }
129
+ connectedCallback() {
130
+ this.waitUntilVisible(() => {
131
+ this.visible = true;
132
+ this.loadIconPathData();
133
+ });
134
+ super.connectedCallback();
135
+ }
136
+ disconnectedCallback() {
137
+ if (this.intersectionObserver && typeof this.intersectionObserver.disconnect === 'function') {
138
+ this.intersectionObserver.disconnect();
139
+ }
140
+ this.intersectionObserver = undefined;
141
+ super.disconnectedCallback();
142
+ }
143
+ async loadIconPathData() {
144
+ const { icon, iconset, visible } = this;
145
+ if (!icon || !visible) {
146
+ return;
147
+ }
148
+ const maybeIcon = svg.parseSvgString(icon);
149
+ if (maybeIcon) {
150
+ this.iconData = maybeIcon;
151
+ return;
152
+ }
153
+ this.iconData = await icons.resolveIconSvg({
154
+ icon,
155
+ iconset,
156
+ });
157
+ }
158
+ componentDidRender() {
159
+ this.validationEl = this.el.querySelector('svg');
160
+ this.ariaValidationController.revalidateAria();
161
+ super.componentDidRender();
162
+ }
163
+ render() {
164
+ return index.h(index.Host, { key: '03b4391d02a77409257bcda51c2b65ad9a9e0a0c', role: "img", "aria-hidden": `${this.ariaHidden}`, innerHTML: this.iconData });
165
+ }
166
+ waitUntilVisible(callback, rootMargin = 50) {
167
+ if (typeof window === 'undefined' || !window.IntersectionObserver) {
168
+ callback();
169
+ return;
170
+ }
171
+ this.intersectionObserver = new IntersectionObserver((entries) => {
172
+ entries.some((entry) => {
173
+ if (entry.isIntersecting) {
174
+ if (this.intersectionObserver && typeof this.intersectionObserver.disconnect === 'function') {
175
+ this.intersectionObserver.disconnect();
176
+ }
177
+ this.intersectionObserver = undefined;
178
+ callback();
179
+ return true;
180
+ }
181
+ return false;
182
+ });
183
+ }, { rootMargin: `${rootMargin}px` });
184
+ this.intersectionObserver.observe(this.el);
185
+ }
186
+ static get watchers() { return {
187
+ "icon": [{
188
+ "loadIconPathData": 0
189
+ }],
190
+ "iconset": [{
191
+ "loadIconPathData": 0
192
+ }]
193
+ }; }
194
+ };
195
+ LmvzIcon.style = lmvzIconCss();
196
+
197
+ exports.lmvz_button = LmvzButton;
198
+ exports.lmvz_icon = LmvzIcon;