@lmvz-ds/components 0.25.0 → 0.27.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 (158) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/cjs/{reactive-controller-host-DrtMkMd7.js → aria-validation-controller-BMV2tv9-.js} +0 -41
  3. package/cjs/{ds.constants-DSnxZ3ia.js → ds.constants-8fh6ItAF.js} +1 -1
  4. package/cjs/index.cjs.js +196 -2
  5. package/cjs/list-keyboard-controller-CzZdPBeH.js +173 -0
  6. package/cjs/lmvz-button-group.cjs.entry.js +183 -0
  7. package/cjs/lmvz-button_2.cjs.entry.js +199 -0
  8. package/cjs/lmvz-card.cjs.entry.js +1 -1
  9. package/cjs/lmvz-checkbox.cjs.entry.js +8 -4
  10. package/cjs/lmvz-chip.cjs.entry.js +5 -4
  11. package/cjs/lmvz-components.cjs.js +1 -1
  12. package/cjs/lmvz-header_2.cjs.entry.js +7 -51
  13. package/cjs/lmvz-input.cjs.entry.js +3 -2
  14. package/cjs/lmvz-menuitem.cjs.entry.js +4 -3
  15. package/cjs/lmvz-modal.cjs.entry.js +4 -3
  16. package/cjs/lmvz-radio.cjs.entry.js +4 -3
  17. package/cjs/lmvz-select.cjs.entry.js +3 -2
  18. package/cjs/lmvz-snackbar.cjs.entry.js +83 -0
  19. package/cjs/lmvz-tab.cjs.entry.js +31 -0
  20. package/cjs/lmvz-tabs.cjs.entry.js +256 -0
  21. package/cjs/lmvz-toggle.cjs.entry.js +5 -4
  22. package/cjs/loader.cjs.js +1 -1
  23. package/cjs/reactive-controller-host-B_lZtcA6.js +43 -0
  24. package/collection/api/ds.constants.js +4 -1
  25. package/collection/collection-manifest.json +3 -0
  26. package/collection/components/lmvz-button/lmvz-button.css +6 -6
  27. package/collection/components/lmvz-button-group/lmvz-button-group.css +2 -2
  28. package/collection/components/lmvz-card/lmvz-card.css +9 -9
  29. package/collection/components/lmvz-checkbox/lmvz-checkbox.css +14 -12
  30. package/collection/components/lmvz-checkbox/lmvz-checkbox.js +4 -1
  31. package/collection/components/lmvz-chip/lmvz-chip.css +2 -2
  32. package/collection/components/lmvz-header/lmvz-header.js +3 -3
  33. package/collection/components/lmvz-icon/lmvz-icon.js +1 -1
  34. package/collection/components/lmvz-menuitem/lmvz-menuitem.css +1 -1
  35. package/collection/components/lmvz-modal/lmvz-modal.css +4 -16
  36. package/collection/components/lmvz-radio/lmvz-radio.css +4 -4
  37. package/collection/components/lmvz-snackbar/lmvz-snackbar.css +101 -0
  38. package/collection/components/lmvz-snackbar/lmvz-snackbar.js +266 -0
  39. package/collection/components/lmvz-snackbar/public.js +1 -0
  40. package/collection/components/lmvz-snackbar/snackbar-controller.js +194 -0
  41. package/collection/components/lmvz-tab/lmvz-tab.css +148 -0
  42. package/collection/components/lmvz-tab/lmvz-tab.js +125 -0
  43. package/collection/components/lmvz-tabs/lmvz-tabs.css +58 -0
  44. package/collection/components/lmvz-tabs/lmvz-tabs.js +399 -0
  45. package/collection/components/lmvz-toggle/lmvz-toggle.css +2 -2
  46. package/collection/components/lmvz-toggle/lmvz-toggle.js +1 -1
  47. package/collection/index.js +1 -0
  48. package/collection/integration/header-integration/header-integration.js +1 -1
  49. package/collection/utils/aria/list-keyboard-controller.js +151 -28
  50. package/components/index.d.ts +6 -0
  51. package/components/index.d.ts.bak +6 -0
  52. package/components/index.js +1 -1
  53. package/components/lmvz-action.js +1 -1
  54. package/components/lmvz-button-group.js +1 -1
  55. package/components/lmvz-button.js +1 -1
  56. package/components/lmvz-card.js +1 -1
  57. package/components/lmvz-checkbox.js +1 -1
  58. package/components/lmvz-chip.js +1 -1
  59. package/components/lmvz-header.js +1 -1
  60. package/components/lmvz-icon.js +1 -1
  61. package/components/lmvz-input.js +1 -1
  62. package/components/lmvz-menuitem.js +1 -1
  63. package/components/lmvz-modal.js +1 -1
  64. package/components/lmvz-radio.js +1 -1
  65. package/components/lmvz-select.js +1 -1
  66. package/components/lmvz-snackbar.d.ts +11 -0
  67. package/components/lmvz-snackbar.d.ts.bak +11 -0
  68. package/components/lmvz-snackbar.js +1 -0
  69. package/components/lmvz-tab.d.ts +11 -0
  70. package/components/lmvz-tab.d.ts.bak +11 -0
  71. package/components/lmvz-tab.js +1 -0
  72. package/components/lmvz-tabs.d.ts +11 -0
  73. package/components/lmvz-tabs.d.ts.bak +11 -0
  74. package/components/lmvz-tabs.js +1 -0
  75. package/components/lmvz-toggle.js +1 -1
  76. package/components/p-0P2Wb3pE.js +1 -0
  77. package/components/p-2VdcUIrr.js +1 -0
  78. package/components/p-BJEQw1Sz.js +1 -0
  79. package/components/{p-Bb-kEOmU.js → p-Cs7RCOHZ.js} +1 -1
  80. package/components/p-CtaMrBNE.js +1 -0
  81. package/components/p-DjvbwRyl.js +1 -0
  82. package/components/{p-DYr7Jc0V.js → p-c7OzBK8f.js} +1 -1
  83. package/esm/{reactive-controller-host-ZrGf1F2-.js → aria-validation-controller-D-KO0Asb.js} +1 -41
  84. package/esm/{ds.constants-Bmi89ll1.js → ds.constants-BOOwq5dE.js} +1 -1
  85. package/esm/index.js +198 -1
  86. package/esm/list-keyboard-controller-Coi8XfUH.js +171 -0
  87. package/esm/lmvz-button-group.entry.js +181 -0
  88. package/esm/lmvz-button_2.entry.js +196 -0
  89. package/esm/lmvz-card.entry.js +1 -1
  90. package/esm/lmvz-checkbox.entry.js +7 -3
  91. package/esm/lmvz-chip.entry.js +4 -3
  92. package/esm/lmvz-components.js +1 -1
  93. package/esm/lmvz-header_2.entry.js +6 -50
  94. package/esm/lmvz-input.entry.js +2 -1
  95. package/esm/lmvz-menuitem.entry.js +3 -2
  96. package/esm/lmvz-modal.entry.js +3 -2
  97. package/esm/lmvz-radio.entry.js +3 -2
  98. package/esm/lmvz-select.entry.js +2 -1
  99. package/esm/lmvz-snackbar.entry.js +81 -0
  100. package/esm/lmvz-tab.entry.js +29 -0
  101. package/esm/lmvz-tabs.entry.js +254 -0
  102. package/esm/lmvz-toggle.entry.js +4 -3
  103. package/esm/loader.js +1 -1
  104. package/esm/reactive-controller-host-FBuCCcFC.js +41 -0
  105. package/hydrate/index.js +565 -40
  106. package/hydrate/index.mjs +565 -40
  107. package/lmvz-components/index.esm.js +1 -1
  108. package/lmvz-components/lmvz-components.esm.js +1 -1
  109. package/lmvz-components/p-0a37e0f2.entry.js +1 -0
  110. package/lmvz-components/p-25f045b2.entry.js +1 -0
  111. package/lmvz-components/p-43b463bf.entry.js +1 -0
  112. package/lmvz-components/p-4bd71a3c.entry.js +1 -0
  113. package/lmvz-components/p-6484fbc6.entry.js +1 -0
  114. package/lmvz-components/p-6988c3ea.entry.js +1 -0
  115. package/lmvz-components/p-6de9981f.entry.js +1 -0
  116. package/lmvz-components/p-758dbb82.entry.js +1 -0
  117. package/lmvz-components/p-7b15cdce.entry.js +1 -0
  118. package/lmvz-components/p-8874ff19.entry.js +1 -0
  119. package/lmvz-components/p-BOOwq5dE.js +1 -0
  120. package/lmvz-components/p-CtaMrBNE.js +1 -0
  121. package/lmvz-components/p-FBuCCcFC.js +1 -0
  122. package/lmvz-components/p-a5c921dc.entry.js +1 -0
  123. package/lmvz-components/p-bb46a884.entry.js +1 -0
  124. package/lmvz-components/p-bd23eab3.entry.js +1 -0
  125. package/lmvz-components/p-c6228cee.entry.js +1 -0
  126. package/lmvz-components/p-da16ff58.entry.js +1 -0
  127. package/lmvz-components/p-hRb38wX6.js +1 -0
  128. package/manifest.json +858 -186
  129. package/package.json +13 -1
  130. package/types/api/ds.constants.d.ts +9 -1
  131. package/types/components/lmvz-checkbox/lmvz-checkbox.d.ts +1 -0
  132. package/types/components/lmvz-header/lmvz-header.d.ts +2 -2
  133. package/types/components/lmvz-snackbar/lmvz-snackbar.d.ts +21 -0
  134. package/types/components/lmvz-snackbar/public.d.ts +2 -0
  135. package/types/components/lmvz-snackbar/snackbar-controller.d.ts +32 -0
  136. package/types/components/lmvz-tab/lmvz-tab.d.ts +11 -0
  137. package/types/components/lmvz-tabs/lmvz-tabs.d.ts +43 -0
  138. package/types/components.d.ts +212 -1
  139. package/types/index.d.ts +1 -0
  140. package/types/utils/aria/list-keyboard-controller.d.ts +28 -5
  141. package/cjs/lmvz-button_3.cjs.entry.js +0 -375
  142. package/components/p-CCcoDnH-.js +0 -1
  143. package/components/p-CNmHnJ1D.js +0 -1
  144. package/components/p-vUYpZZoR.js +0 -1
  145. package/esm/lmvz-button_3.entry.js +0 -371
  146. package/lmvz-components/p-01aeca60.entry.js +0 -1
  147. package/lmvz-components/p-0dced359.entry.js +0 -1
  148. package/lmvz-components/p-2044a9ac.entry.js +0 -1
  149. package/lmvz-components/p-3c2adbb4.entry.js +0 -1
  150. package/lmvz-components/p-3df070b0.entry.js +0 -1
  151. package/lmvz-components/p-758078db.entry.js +0 -1
  152. package/lmvz-components/p-90f5a19d.entry.js +0 -1
  153. package/lmvz-components/p-Bmi89ll1.js +0 -1
  154. package/lmvz-components/p-CwX1wKkM.js +0 -1
  155. package/lmvz-components/p-acfeae08.entry.js +0 -1
  156. package/lmvz-components/p-c01a6c70.entry.js +0 -1
  157. package/lmvz-components/p-e1eaa7a2.entry.js +0 -1
  158. package/lmvz-components/p-e23d0054.entry.js +0 -1
@@ -0,0 +1,266 @@
1
+ import { Host, h } from "@stencil/core";
2
+ import errorSvg from "@lmvz-ds/icons/assets/alert.svg";
3
+ import infoSvg from "@lmvz-ds/icons/assets/info.svg";
4
+ import warningSvg from "@lmvz-ds/icons/assets/warning.svg";
5
+ const STATUS_SVG = {
6
+ success: infoSvg,
7
+ warning: warningSvg,
8
+ error: errorSvg,
9
+ };
10
+ export class LmvzSnackbar {
11
+ el;
12
+ animationClass = '';
13
+ status = 'success';
14
+ onStatusChange() {
15
+ this.applyAriaLiveAttributes();
16
+ }
17
+ message = '';
18
+ duration;
19
+ priority = 'normal';
20
+ actionLabel;
21
+ lmvzClose;
22
+ connectedCallback() {
23
+ if (typeof document !== 'undefined') {
24
+ this.applyAriaLiveAttributes();
25
+ }
26
+ }
27
+ async show() {
28
+ this.animationClass = '';
29
+ requestAnimationFrame(() => {
30
+ this.animationClass = 'entering';
31
+ });
32
+ }
33
+ async hide() {
34
+ this.animationClass = 'leaving';
35
+ await new Promise((resolve) => {
36
+ const timeout = setTimeout(resolve, 300);
37
+ const onAnimationEnd = () => {
38
+ clearTimeout(timeout);
39
+ this.el.removeEventListener('animationend', onAnimationEnd);
40
+ resolve();
41
+ };
42
+ this.el.addEventListener('animationend', onAnimationEnd);
43
+ });
44
+ }
45
+ applyAriaLiveAttributes() {
46
+ if (this.status === 'error') {
47
+ this.el.setAttribute('role', 'alert');
48
+ this.el.setAttribute('aria-live', 'assertive');
49
+ }
50
+ else {
51
+ this.el.setAttribute('role', 'status');
52
+ this.el.setAttribute('aria-live', 'polite');
53
+ }
54
+ this.el.setAttribute('aria-atomic', 'true');
55
+ }
56
+ handleActionClick = () => {
57
+ this.lmvzClose.emit({ reason: 'action' });
58
+ this.el.dispatchEvent(new CustomEvent('lmvzAction', { bubbles: false, composed: false }));
59
+ };
60
+ render() {
61
+ return (h(Host, { key: '3cf529e3a1971926546758d2e04c3860fde23961', class: this.animationClass }, h("lmvz-icon", { key: '3bc7fb142b19ca4f01c04d33759bcd52cd46c77e', icon: STATUS_SVG[this.status], size: "md", weight: "bold" }), h("span", { key: 'b2d00f1602baefa7f1025d927d66f8867e3e7ce5', class: "message" }, this.message), this.actionLabel && (h("lmvz-button", { key: '92966ab42ef1c5fca044adf5b60a02b54ddcd43a', variant: "tertiary", scale: "small", onLmvzActivation: this.handleActionClick }, this.actionLabel))));
62
+ }
63
+ static get is() { return "lmvz-snackbar"; }
64
+ static get encapsulation() { return "shadow"; }
65
+ static get originalStyleUrls() {
66
+ return {
67
+ "$": ["lmvz-snackbar.css"]
68
+ };
69
+ }
70
+ static get styleUrls() {
71
+ return {
72
+ "$": ["lmvz-snackbar.css"]
73
+ };
74
+ }
75
+ static get properties() {
76
+ return {
77
+ "status": {
78
+ "type": "string",
79
+ "mutable": true,
80
+ "complexType": {
81
+ "original": "Snackbar.Status",
82
+ "resolved": "\"error\" | \"success\" | \"warning\"",
83
+ "references": {
84
+ "Snackbar": {
85
+ "location": "import",
86
+ "path": "../../api",
87
+ "id": "src/api/index.d.ts::Snackbar",
88
+ "referenceLocation": "Snackbar"
89
+ }
90
+ }
91
+ },
92
+ "required": false,
93
+ "optional": false,
94
+ "docs": {
95
+ "tags": [],
96
+ "text": ""
97
+ },
98
+ "getter": false,
99
+ "setter": false,
100
+ "reflect": true,
101
+ "attribute": "status",
102
+ "defaultValue": "'success'"
103
+ },
104
+ "message": {
105
+ "type": "string",
106
+ "mutable": true,
107
+ "complexType": {
108
+ "original": "string",
109
+ "resolved": "string",
110
+ "references": {}
111
+ },
112
+ "required": false,
113
+ "optional": false,
114
+ "docs": {
115
+ "tags": [],
116
+ "text": ""
117
+ },
118
+ "getter": false,
119
+ "setter": false,
120
+ "reflect": false,
121
+ "attribute": "message",
122
+ "defaultValue": "''"
123
+ },
124
+ "duration": {
125
+ "type": "number",
126
+ "mutable": true,
127
+ "complexType": {
128
+ "original": "number",
129
+ "resolved": "number | undefined",
130
+ "references": {}
131
+ },
132
+ "required": false,
133
+ "optional": true,
134
+ "docs": {
135
+ "tags": [],
136
+ "text": ""
137
+ },
138
+ "getter": false,
139
+ "setter": false,
140
+ "reflect": false,
141
+ "attribute": "duration"
142
+ },
143
+ "priority": {
144
+ "type": "string",
145
+ "mutable": true,
146
+ "complexType": {
147
+ "original": "Snackbar.Priority",
148
+ "resolved": "\"high\" | \"low\" | \"normal\" | undefined",
149
+ "references": {
150
+ "Snackbar": {
151
+ "location": "import",
152
+ "path": "../../api",
153
+ "id": "src/api/index.d.ts::Snackbar",
154
+ "referenceLocation": "Snackbar"
155
+ }
156
+ }
157
+ },
158
+ "required": false,
159
+ "optional": true,
160
+ "docs": {
161
+ "tags": [],
162
+ "text": ""
163
+ },
164
+ "getter": false,
165
+ "setter": false,
166
+ "reflect": false,
167
+ "attribute": "priority",
168
+ "defaultValue": "'normal'"
169
+ },
170
+ "actionLabel": {
171
+ "type": "string",
172
+ "mutable": true,
173
+ "complexType": {
174
+ "original": "string",
175
+ "resolved": "string | undefined",
176
+ "references": {}
177
+ },
178
+ "required": false,
179
+ "optional": true,
180
+ "docs": {
181
+ "tags": [],
182
+ "text": ""
183
+ },
184
+ "getter": false,
185
+ "setter": false,
186
+ "reflect": false,
187
+ "attribute": "action-label"
188
+ }
189
+ };
190
+ }
191
+ static get states() {
192
+ return {
193
+ "animationClass": {}
194
+ };
195
+ }
196
+ static get events() {
197
+ return [{
198
+ "method": "lmvzClose",
199
+ "name": "lmvzClose",
200
+ "bubbles": true,
201
+ "cancelable": false,
202
+ "composed": true,
203
+ "docs": {
204
+ "tags": [],
205
+ "text": ""
206
+ },
207
+ "complexType": {
208
+ "original": "{ reason: Snackbar.DismissReason }",
209
+ "resolved": "{ reason: \"timeout\" | \"manual\" | \"action\" | \"overridden\" | \"swallowed\"; }",
210
+ "references": {
211
+ "Snackbar": {
212
+ "location": "import",
213
+ "path": "../../api",
214
+ "id": "src/api/index.d.ts::Snackbar",
215
+ "referenceLocation": "Snackbar"
216
+ }
217
+ }
218
+ }
219
+ }];
220
+ }
221
+ static get methods() {
222
+ return {
223
+ "show": {
224
+ "complexType": {
225
+ "signature": "() => Promise<void>",
226
+ "parameters": [],
227
+ "references": {
228
+ "Promise": {
229
+ "location": "global",
230
+ "id": "global::Promise"
231
+ }
232
+ },
233
+ "return": "Promise<void>"
234
+ },
235
+ "docs": {
236
+ "text": "",
237
+ "tags": []
238
+ }
239
+ },
240
+ "hide": {
241
+ "complexType": {
242
+ "signature": "() => Promise<void>",
243
+ "parameters": [],
244
+ "references": {
245
+ "Promise": {
246
+ "location": "global",
247
+ "id": "global::Promise"
248
+ }
249
+ },
250
+ "return": "Promise<void>"
251
+ },
252
+ "docs": {
253
+ "text": "",
254
+ "tags": []
255
+ }
256
+ }
257
+ };
258
+ }
259
+ static get elementRef() { return "el"; }
260
+ static get watchers() {
261
+ return [{
262
+ "propName": "status",
263
+ "methodName": "onStatusChange"
264
+ }];
265
+ }
266
+ }
@@ -0,0 +1 @@
1
+ export { SnackbarController } from './snackbar-controller';
@@ -0,0 +1,194 @@
1
+ const PRIORITY_MAP = {
2
+ low: 0,
3
+ normal: 1,
4
+ high: 2,
5
+ };
6
+ const STATUS_DURATION = {
7
+ success: 5000,
8
+ warning: 5000,
9
+ error: 8000,
10
+ };
11
+ let idCounter = 0;
12
+ function nextId() {
13
+ idCounter += 1;
14
+ return `snackbar-${idCounter}`;
15
+ }
16
+ function resolveHostElement() {
17
+ if (typeof document === 'undefined') {
18
+ return undefined;
19
+ }
20
+ const existing = document.querySelector('[data-snackbar-host]');
21
+ if (existing) {
22
+ return existing;
23
+ }
24
+ const el = document.createElement('lmvz-snackbar');
25
+ el.setAttribute('data-snackbar-host', '');
26
+ document.body.appendChild(el);
27
+ return el;
28
+ }
29
+ export class SnackbarController {
30
+ hostEl = undefined;
31
+ active = undefined;
32
+ getHost() {
33
+ if (this.hostEl !== undefined && !this.hostEl.isConnected) {
34
+ this.hostEl = undefined;
35
+ }
36
+ if (this.hostEl === undefined) {
37
+ this.hostEl = resolveHostElement();
38
+ }
39
+ return this.hostEl;
40
+ }
41
+ clearTimer(entry) {
42
+ if (entry.timerId !== undefined) {
43
+ clearTimeout(entry.timerId);
44
+ entry.timerId = undefined;
45
+ }
46
+ }
47
+ scheduleTimer(entry, delayMs) {
48
+ if (delayMs <= 0) {
49
+ return;
50
+ }
51
+ entry.timerStartedAt = Date.now();
52
+ entry.timerId = setTimeout(() => {
53
+ if (this.active !== undefined && this.active.id === entry.id) {
54
+ this.dismissActive(entry, 'timeout');
55
+ }
56
+ }, delayMs);
57
+ }
58
+ dismissActive(entry, reason) {
59
+ this.clearTimer(entry);
60
+ const host = entry.hostEl;
61
+ host.removeEventListener('pointerenter', entry.onPointerEnter);
62
+ host.removeEventListener('pointerleave', entry.onPointerLeave);
63
+ host.removeEventListener('focusin', entry.onFocusIn);
64
+ host.removeEventListener('focusout', entry.onFocusOut);
65
+ if (entry.onActionListener) {
66
+ host.removeEventListener('lmvzAction', entry.onActionListener);
67
+ }
68
+ host.hide?.();
69
+ if (this.active?.id === entry.id) {
70
+ this.active = undefined;
71
+ }
72
+ if (reason !== 'action') {
73
+ host.dispatchEvent(new CustomEvent('lmvzClose', { detail: { reason }, bubbles: true, composed: true }));
74
+ }
75
+ entry.resolve({ reason });
76
+ }
77
+ pauseTimer(entry) {
78
+ entry.pauseCount += 1;
79
+ if (entry.pauseCount > 1 || entry.timerId === undefined) {
80
+ return;
81
+ }
82
+ const elapsed = entry.timerStartedAt !== undefined ? Date.now() - entry.timerStartedAt : 0;
83
+ entry.remaining = Math.max(0, entry.remaining - elapsed);
84
+ entry.timerStartedAt = undefined;
85
+ this.clearTimer(entry);
86
+ }
87
+ resumeTimer(entry) {
88
+ if (entry.pauseCount > 0) {
89
+ entry.pauseCount -= 1;
90
+ }
91
+ if (entry.pauseCount > 0) {
92
+ return;
93
+ }
94
+ if (entry.remaining > 0) {
95
+ this.scheduleTimer(entry, entry.remaining);
96
+ }
97
+ }
98
+ applyToHost(host, options) {
99
+ host.setAttribute('status', options.status ?? 'success');
100
+ if (options.actionLabel !== undefined) {
101
+ host.setAttribute('action-label', options.actionLabel);
102
+ }
103
+ else {
104
+ host.removeAttribute('action-label');
105
+ }
106
+ }
107
+ open(options) {
108
+ const incomingPriority = PRIORITY_MAP[options.priority ?? 'normal'];
109
+ if (this.active !== undefined && incomingPriority < this.active.priority) {
110
+ let swallowResolve;
111
+ const closed = new Promise((resolve) => {
112
+ swallowResolve = resolve;
113
+ });
114
+ swallowResolve({ reason: 'swallowed' });
115
+ const id = nextId();
116
+ return {
117
+ id,
118
+ closed,
119
+ dismiss() {
120
+ },
121
+ };
122
+ }
123
+ if (this.active !== undefined) {
124
+ this.dismissActive(this.active, 'overridden');
125
+ }
126
+ const host = this.getHost();
127
+ if (host === undefined) {
128
+ const id = nextId();
129
+ let ssrResolve;
130
+ const closed = new Promise((resolve) => {
131
+ ssrResolve = resolve;
132
+ });
133
+ ssrResolve({ reason: 'swallowed' });
134
+ return { id, closed, dismiss() { } };
135
+ }
136
+ const id = nextId();
137
+ const status = options.status ?? 'success';
138
+ const durationMs = options.duration === 0 ? 0 : (options.duration ?? STATUS_DURATION[status]);
139
+ let entryResolve;
140
+ const closed = new Promise((resolve) => {
141
+ entryResolve = resolve;
142
+ });
143
+ const entry = {
144
+ id,
145
+ priority: incomingPriority,
146
+ resolve: entryResolve,
147
+ timerId: undefined,
148
+ remaining: durationMs,
149
+ timerStartedAt: undefined,
150
+ pauseCount: 0,
151
+ hostEl: host,
152
+ onPointerEnter: () => this.pauseTimer(entry),
153
+ onPointerLeave: () => this.resumeTimer(entry),
154
+ onFocusIn: () => this.pauseTimer(entry),
155
+ onFocusOut: () => this.resumeTimer(entry),
156
+ };
157
+ this.active = entry;
158
+ host.addEventListener('pointerenter', entry.onPointerEnter);
159
+ host.addEventListener('pointerleave', entry.onPointerLeave);
160
+ host.addEventListener('focusin', entry.onFocusIn);
161
+ host.addEventListener('focusout', entry.onFocusOut);
162
+ this.applyToHost(host, options);
163
+ const onAction = () => {
164
+ if (this.active !== undefined && this.active.id === id) {
165
+ options.onAction?.();
166
+ this.dismissActive(entry, 'action');
167
+ }
168
+ };
169
+ entry.onActionListener = onAction;
170
+ host.addEventListener('lmvzAction', onAction, { once: true });
171
+ host.show?.();
172
+ queueMicrotask(() => host.setAttribute('message', options.message));
173
+ if (durationMs > 0) {
174
+ this.scheduleTimer(entry, durationMs);
175
+ }
176
+ return {
177
+ id,
178
+ closed,
179
+ dismiss: () => {
180
+ if (this.active?.id === id) {
181
+ this.dismissActive(entry, 'manual');
182
+ }
183
+ },
184
+ };
185
+ }
186
+ dismiss(id) {
187
+ if (!this.active) {
188
+ return;
189
+ }
190
+ if (!id || this.active.id === id) {
191
+ this.dismissActive(this.active, 'manual');
192
+ }
193
+ }
194
+ }
@@ -0,0 +1,148 @@
1
+
2
+ @layer lmvz-ds.reset, lmvz-ds.theme, lmvz-ds.components, lmvz-ds.overrides;
3
+ /**
4
+ * This defines the order of our lmvz-ds' CSS layers. See readme.md for details.
5
+ * Important: Always import this file _before_ layering your own styles!
6
+ */
7
+ @layer lmvz-ds.reset {
8
+ body {
9
+ margin: 0;
10
+ }
11
+
12
+ h1,
13
+ h2,
14
+ h3,
15
+ h4,
16
+ h5,
17
+ h6 {
18
+ margin: 0;
19
+ }
20
+
21
+ *[hidden] {
22
+ display: none !important;
23
+ }
24
+
25
+ }
26
+ :host {
27
+ display: inline-block;
28
+ flex: none;
29
+ }
30
+ :host([disabled]) {
31
+ cursor: not-allowed;
32
+ pointer-events: none;
33
+ }
34
+ button {
35
+ --lmvz-tab-color: var(--lmvz-semantic-color-int-on-secondary, #000000);
36
+ --lmvz-tab-background: var(--lmvz-semantic-color-int-secondary, #f0f0f0);
37
+
38
+ position: relative;
39
+ display: inline-flex;
40
+ flex-direction: column;
41
+ align-items: center;
42
+ justify-content: center;
43
+ gap: var(--lmvz-component-component-spacing-0-default, 4px);
44
+
45
+ padding-top: var(--lmvz-dimension-8-12, clamp(0.5rem, 0.44rem + 0.26vw, 0.75rem));
46
+ padding-bottom: var(--lmvz-dimension-8-14, clamp(0.5rem, 0.41rem + 0.39vw, 0.88rem));
47
+ padding-inline: var(--lmvz-dimension-16-24, clamp(1rem, 0.88rem + 0.52vw, 1.5rem));
48
+
49
+ border: none;
50
+ border-radius: var(--lmvz-semantic-border-radius-round, 999px);
51
+ background: var(--lmvz-tab-background);
52
+ color: var(--lmvz-tab-color);
53
+
54
+ font: var(--lmvz-typography-body-md-strong, 500 clamp(0.88rem, 0.84rem + 0.13vw, 1rem) / 1.5
55
+ Router);
56
+ cursor: pointer;
57
+ white-space: nowrap;
58
+ transition:
59
+ background-color 0.15s ease,
60
+ color 0.15s ease;
61
+ }
62
+ button:focus-visible {
63
+ outline: var(--lmvz-ds-outline, 1px solid #0e7ab4);
64
+ outline-offset: var(--lmvz-ds-outline-offset, clamp(0.25rem, 0.19rem + 0.26vw, 0.5rem));
65
+ z-index: 1;
66
+ }
67
+ button:disabled {
68
+ opacity: var(--lmvz-component-input-disabled-opacity, 40%);
69
+ pointer-events: none;
70
+ cursor: not-allowed;
71
+ }
72
+ button:hover {
73
+ --lmvz-tab-background: var(--lmvz-semantic-color-int-tertiary-hover, #f0f0f0);
74
+ --lmvz-tab-color: var(--lmvz-semantic-color-int-on-secondary-hover, #000000);
75
+ }
76
+ button:active {
77
+ --lmvz-tab-background: var(--lmvz-semantic-color-int-tertiary-active, #e0e0e0);
78
+ --lmvz-tab-color: var(--lmvz-semantic-color-int-on-secondary-active, #000000);
79
+ }
80
+ :host([has-media]) {
81
+ --lmvz-tab-color: var(--lmvz-semantic-color-int-on-tertiary, #000000);
82
+ --lmvz-tab-background: var(--lmvz-semantic-color-int-tertiary, #ffffff);
83
+ }
84
+ :host([has-media]) button {
85
+ padding-top: var(--lmvz-dimension-16-18, clamp(1rem, 0.97rem + 0.13vw, 1.13rem));
86
+ padding-bottom: var(--lmvz-dimension-12-14, clamp(0.75rem, 0.72rem + 0.13vw, 0.88rem));
87
+ padding-inline: var(--lmvz-dimension-40-48, clamp(2.5rem, 2.38rem + 0.52vw, 3rem));
88
+ border-radius: var(--lmvz-semantic-border-radius-lg, 14px);
89
+ }
90
+ :host([has-media]) button:hover {
91
+ --lmvz-tab-color: var(--lmvz-semantic-color-int-on-tertiary-hover, #000000);
92
+ }
93
+ :host([has-media]) button:active {
94
+ --lmvz-tab-color: var(--lmvz-semantic-color-int-on-tertiary-active, #000000);
95
+ }
96
+ :host([selected]) button {
97
+ --lmvz-tab-color: var(--lmvz-semantic-color-status-on-active, #0e7ab4);
98
+ --lmvz-tab-background: var(--lmvz-semantic-color-status-active, #f6fbfe);
99
+ }
100
+ :host([selected][has-media]) button:hover,
101
+ :host([selected][has-media]) button:active {
102
+ --lmvz-tab-color: var(--lmvz-semantic-color-status-on-active, #0e7ab4);
103
+ }
104
+ .indicator {
105
+ /* TODO: replace with a design token if one is introduced for tab indicator border */
106
+ --lmvz-tab-indicator-size: 4px;
107
+
108
+ position: absolute;
109
+ background: linear-gradient(to right, var(--lmvz-semantic-color-gradient-main-1, #0e7ab4), var(--lmvz-semantic-color-gradient-main-2, #0e7ab4));
110
+ opacity: 0;
111
+ transition: opacity 0.15s ease;
112
+
113
+ /* Horizontal: full-width bar at bottom */
114
+ inset-block-end: 0;
115
+ inset-inline: 0;
116
+ block-size: var(--lmvz-tab-indicator-size);
117
+ border-start-start-radius: 0;
118
+ border-start-end-radius: 0;
119
+ border-end-start-radius: var(--lmvz-tab-indicator-size);
120
+ border-end-end-radius: var(--lmvz-tab-indicator-size);
121
+ }
122
+ :host([selected][has-media]) .indicator {
123
+ opacity: 1;
124
+ }
125
+ :host([vertical]) button {
126
+ border-radius: var(--lmvz-semantic-border-radius-round, 999px);
127
+ }
128
+ :host([vertical]) .indicator {
129
+ /* Vertical: narrow bar at inline-start edge */
130
+ inset-block: 0;
131
+ inset-inline: 0 auto;
132
+ inline-size: var(--lmvz-tab-indicator-size);
133
+ block-size: auto;
134
+ border-radius: 0 var(--lmvz-tab-indicator-size) var(--lmvz-tab-indicator-size) 0;
135
+ background: linear-gradient(to bottom, var(--lmvz-semantic-color-gradient-main-1, #0e7ab4), var(--lmvz-semantic-color-gradient-main-2, #0e7ab4));
136
+ }
137
+ ::slotted(*) {
138
+ --lmvz-component-color: var(--lmvz-tab-color);
139
+ }
140
+ ::slotted(lmvz-icon) {
141
+ --lmvz-component-size: var(--lmvz-dimension-16-18, clamp(1rem, 0.97rem + 0.13vw, 1.13rem));
142
+ }
143
+ :host([has-media]) ::slotted(lmvz-icon) {
144
+ --lmvz-component-size: var(--lmvz-component-icon-size-lg, clamp(1.5rem, 1.44rem + 0.26vw, 1.75rem));
145
+ }
146
+ .label {
147
+ display: contents;
148
+ }