@vonage/vivid 3.13.0 → 3.15.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 (134) hide show
  1. package/accordion/index.js +1 -0
  2. package/accordion-item/index.js +1 -0
  3. package/alert/index.js +1 -0
  4. package/avatar/index.js +1 -0
  5. package/badge/index.js +1 -0
  6. package/banner/index.js +1 -0
  7. package/breadcrumb-item/index.js +1 -0
  8. package/button/index.js +1 -0
  9. package/card/index.js +1 -0
  10. package/checkbox/index.js +4 -0
  11. package/combobox/index.js +1 -0
  12. package/custom-elements.json +1855 -117
  13. package/data-grid/index.js +4 -0
  14. package/dialog/index.js +1 -0
  15. package/empty-state/index.js +14 -0
  16. package/fab/index.js +2 -1
  17. package/header/index.js +1 -1
  18. package/icon/index.js +1 -0
  19. package/index.js +34 -30
  20. package/layout/index.js +1 -1
  21. package/lib/alert/alert.d.ts +4 -6
  22. package/lib/checkbox/checkbox.d.ts +6 -3
  23. package/lib/components.d.ts +2 -0
  24. package/lib/data-grid/data-grid-cell.d.ts +2 -0
  25. package/lib/data-grid/data-grid-row.d.ts +1 -0
  26. package/lib/data-grid/data-grid.d.ts +5 -0
  27. package/lib/empty-state/definition.d.ts +3 -0
  28. package/lib/empty-state/empty-state.d.ts +5 -0
  29. package/lib/empty-state/empty-state.template.d.ts +4 -0
  30. package/lib/empty-state/index.d.ts +1 -0
  31. package/lib/select/select.d.ts +3 -2
  32. package/listbox/index.js +2 -1
  33. package/menu/index.js +4 -3
  34. package/menu-item/index.js +4 -1
  35. package/nav/index.js +1 -1
  36. package/nav-disclosure/index.js +2 -1
  37. package/nav-item/index.js +2 -1
  38. package/note/index.js +2 -1
  39. package/number-field/index.js +2 -1
  40. package/option/index.js +1 -0
  41. package/package.json +1 -1
  42. package/pagination/index.js +15 -312
  43. package/popup/index.js +1 -0
  44. package/progress/index.js +1 -1
  45. package/radio/index.js +1 -1
  46. package/radio-group/index.js +1 -1
  47. package/select/index.js +2 -1
  48. package/shared/definition.js +1 -1
  49. package/shared/definition10.js +1 -1
  50. package/shared/definition11.js +1 -1
  51. package/shared/definition12.js +1 -1
  52. package/shared/definition14.js +1 -1
  53. package/shared/definition15.js +1 -1
  54. package/shared/definition16.js +2 -2
  55. package/shared/definition17.js +1 -1
  56. package/shared/definition18.js +23 -8
  57. package/shared/definition19.js +1 -1
  58. package/shared/definition2.js +1 -1
  59. package/shared/definition20.js +1 -1
  60. package/shared/definition21.js +1 -1
  61. package/shared/definition22.js +217 -11
  62. package/shared/definition23.js +2 -2
  63. package/shared/definition24.js +1 -1
  64. package/shared/definition25.js +39 -76
  65. package/shared/definition26.js +76 -47
  66. package/shared/definition27.js +46 -36
  67. package/shared/definition28.js +39 -49
  68. package/shared/definition29.js +48 -344
  69. package/shared/definition3.js +1 -1
  70. package/shared/definition30.js +273 -288
  71. package/shared/definition31.js +366 -14
  72. package/shared/definition32.js +13 -67
  73. package/shared/definition33.js +66 -21
  74. package/shared/definition34.js +21 -39
  75. package/shared/definition35.js +31 -432
  76. package/shared/definition36.js +432 -76
  77. package/shared/definition37.js +223 -34
  78. package/shared/definition38.js +82 -425
  79. package/shared/definition39.js +30 -628
  80. package/shared/definition4.js +1 -1
  81. package/shared/definition40.js +420 -73
  82. package/shared/definition41.js +530 -484
  83. package/shared/definition42.js +76 -133
  84. package/shared/definition43.js +577 -40
  85. package/shared/definition44.js +135 -20
  86. package/shared/definition45.js +42 -423
  87. package/shared/definition46.js +22 -112
  88. package/shared/definition47.js +440 -18
  89. package/shared/definition48.js +92 -247
  90. package/shared/definition49.js +20 -112
  91. package/shared/definition5.js +1 -1
  92. package/shared/definition50.js +259 -590
  93. package/shared/definition51.js +110 -91
  94. package/shared/definition52.js +602 -67
  95. package/shared/definition53.js +89 -294
  96. package/shared/definition54.js +80 -0
  97. package/shared/definition55.js +305 -0
  98. package/shared/definition6.js +52 -78
  99. package/shared/definition7.js +1 -1
  100. package/shared/definition8.js +1 -1
  101. package/shared/definition9.js +1 -1
  102. package/shared/engine-is-node.js +8 -0
  103. package/shared/es.object.assign.js +1 -1
  104. package/shared/es.regexp.to-string.js +1 -1
  105. package/shared/es.string.includes.js +83 -0
  106. package/shared/form-elements.js +2 -2
  107. package/shared/icon.js +13 -17
  108. package/shared/index.js +1 -1
  109. package/shared/patterns/form-elements/form-elements.d.ts +4 -4
  110. package/shared/string-trim.js +1 -1
  111. package/shared/text-field.js +1 -1
  112. package/shared/to-string.js +1 -1
  113. package/side-drawer/index.js +1 -1
  114. package/slider/index.js +1 -1
  115. package/styles/core/all.css +1 -1
  116. package/styles/core/theme.css +1 -1
  117. package/styles/core/typography.css +1 -1
  118. package/styles/fonts/spezia-variable.css +2 -2
  119. package/styles/tokens/theme-dark.css +4 -4
  120. package/styles/tokens/theme-light.css +4 -4
  121. package/switch/index.js +2 -1
  122. package/tab/index.js +2 -1
  123. package/tab-panel/index.js +1 -1
  124. package/tabs/index.js +4 -3
  125. package/tag/index.js +2 -1
  126. package/tag-group/index.js +1 -1
  127. package/text-anchor/index.js +1 -0
  128. package/text-area/index.js +2 -1
  129. package/text-field/index.js +2 -1
  130. package/toggletip/index.js +2 -1
  131. package/tooltip/index.js +2 -1
  132. package/tree-item/index.js +2 -1
  133. package/tree-view/index.js +1 -1
  134. package/vivid.api.json +210 -0
@@ -1,604 +1,650 @@
1
- import { F as FoundationElement, _ as __decorate, a as attr, o as observable, n as nullableNumberConverter, g as global$1, l as fails$1, k as functionUncurryThis, G as _export, b as __metadata, h as html, r as registerFactory } from './index.js';
1
+ import { Y as DOM, O as Observable, _ as __decorate, a as attr, W as volatile, o as observable, b as __metadata, h as html, r as registerFactory } from './index.js';
2
2
  import { f as focusRegistries } from './definition4.js';
3
- import { t as toString$1 } from './to-string.js';
4
- import { w as whitespaces$1, s as stringTrim } from './string-trim.js';
5
- import './es.regexp.to-string.js';
6
- import { D as Direction, g as getDirection } from './direction.js';
7
- import { l as limit$1 } from './numbers.js';
3
+ import { P as Popup, p as popupRegistries } from './definition20.js';
4
+ import { i as iconRegistries } from './definition3.js';
5
+ import { l as listboxOptionRegistries } from './definition21.js';
6
+ import { A as AffixIconWithTrailing, a as affixIconTemplateFactory } from './affix.js';
7
+ import './focus.js';
8
+ import { e as errorText, f as formElements, F as FormElementSuccessText, a as FormElementHelperText, g as getFeedbackTemplate } from './form-elements.js';
9
+ import { b as ListboxElement, L as Listbox, D as DelegatesARIAListbox, a as Listbox$1 } from './listbox.js';
10
+ import { S as StartEnd } from './start-end.js';
11
+ import { a as applyMixins } from './apply-mixins.js';
8
12
  import { F as FormAssociated } from './form-associated.js';
9
- import { O as Orientation } from './aria.js';
10
- import { a as keyHome, k as keyEnd, b as keyArrowDown, i as keyArrowLeft, c as keyArrowUp, h as keyArrowRight } from './key-codes.js';
13
+ import { S as SelectPosition } from './select.options.js';
14
+ import { u as uniqueId } from './strings.js';
15
+ import { g as keyTab, f as keyEscape, d as keyEnter, k as keyEnd, a as keyHome, e as keySpace, b as keyArrowDown, c as keyArrowUp } from './key-codes.js';
11
16
  import { f as focusTemplateFactory } from './focus2.js';
17
+ import { w as when } from './when.js';
18
+ import { s as slotted } from './slotted.js';
12
19
  import { r as ref } from './ref.js';
13
- import { O as Orientation$1 } from './aria2.js';
14
20
  import { c as classNames } from './class-names.js';
15
21
 
16
- /**
17
- * Converts a pixel coordinate on the track to a percent of the track's range
18
- */
19
- function convertPixelToPercent(pixelPos, minPosition, maxPosition, direction) {
20
- let pct = limit$1(0, 1, (pixelPos - minPosition) / (maxPosition - minPosition));
21
- if (direction === Direction.rtl) {
22
- pct = 1 - pct;
23
- }
24
- return pct;
25
- }
26
-
27
- class _Slider extends FoundationElement {
22
+ class _Select extends ListboxElement {
28
23
  }
29
24
  /**
30
- * A form-associated base class for the {@link @microsoft/fast-foundation#(Slider:class)} component.
25
+ * A form-associated base class for the {@link @microsoft/fast-foundation#(Select:class)} component.
31
26
  *
32
27
  * @internal
33
28
  */
34
- class FormAssociatedSlider extends FormAssociated(_Slider) {
29
+ class FormAssociatedSelect extends FormAssociated(_Select) {
35
30
  constructor() {
36
31
  super(...arguments);
37
- this.proxy = document.createElement("input");
32
+ this.proxy = document.createElement("select");
38
33
  }
39
34
  }
40
35
 
41
36
  /**
42
- * The selection modes of a {@link @microsoft/fast-foundation#(Slider:class)}.
43
- * @public
44
- */
45
- const SliderMode = {
46
- singleValue: "single-value",
47
- };
48
- /**
49
- * A Slider Custom HTML Element.
50
- * Implements the {@link https://www.w3.org/TR/wai-aria-1.1/#slider | ARIA slider }.
37
+ * A Select Custom HTML Element.
38
+ * Implements the {@link https://www.w3.org/TR/wai-aria-1.1/#select | ARIA select }.
51
39
  *
52
- * @slot track - The track of the slider
53
- * @slot track-start - The track-start visual indicator
54
- * @slot thumb - The slider thumb
55
- * @slot - The default slot for labels
56
- * @csspart positioning-region - The region used to position the elements of the slider
57
- * @csspart track-container - The region containing the track elements
58
- * @csspart track-start - The element wrapping the track start slot
59
- * @csspart thumb-container - The thumb container element which is programatically positioned
60
- * @fires change - Fires a custom 'change' event when the slider value changes
40
+ * @slot start - Content which can be provided before the button content
41
+ * @slot end - Content which can be provided after the button content
42
+ * @slot button-container - The element representing the select button
43
+ * @slot selected-value - The selected value
44
+ * @slot indicator - The visual indicator for the expand/collapse state of the button
45
+ * @slot - The default slot for slotted options
46
+ * @csspart control - The element representing the select invoking element
47
+ * @csspart selected-value - The element wrapping the selected value
48
+ * @csspart indicator - The element wrapping the visual indicator
49
+ * @csspart listbox - The listbox element
50
+ * @fires input - Fires a custom 'input' event when the value updates
51
+ * @fires change - Fires a custom 'change' event when the value updates
61
52
  *
62
53
  * @public
63
54
  */
64
- class Slider$1 extends FormAssociatedSlider {
55
+ class Select$1 extends FormAssociatedSelect {
65
56
  constructor() {
66
57
  super(...arguments);
67
58
  /**
68
- * @internal
69
- */
70
- this.direction = Direction.ltr;
71
- /**
72
- * @internal
73
- */
74
- this.isDragging = false;
75
- /**
76
- * @internal
77
- */
78
- this.trackWidth = 0;
79
- /**
80
- * @internal
81
- */
82
- this.trackMinWidth = 0;
83
- /**
84
- * @internal
85
- */
86
- this.trackHeight = 0;
87
- /**
88
- * @internal
89
- */
90
- this.trackLeft = 0;
91
- /**
92
- * @internal
93
- */
94
- this.trackMinHeight = 0;
95
- /**
96
- * Custom function that generates a string for the component's "aria-valuetext" attribute based on the current value.
59
+ * The open attribute.
97
60
  *
98
61
  * @public
99
- */
100
- this.valueTextFormatter = () => null;
101
- /**
102
- * The minimum allowed value.
103
- *
104
- * @defaultValue - 0
105
- * @public
106
62
  * @remarks
107
- * HTML Attribute: min
63
+ * HTML Attribute: open
108
64
  */
109
- this.min = 0; // Map to proxy element.
65
+ this.open = false;
110
66
  /**
111
- * The maximum allowed value.
67
+ * Indicates the initial state of the position attribute.
112
68
  *
113
- * @defaultValue - 10
114
- * @public
115
- * @remarks
116
- * HTML Attribute: max
117
- */
118
- this.max = 10; // Map to proxy element.
119
- /**
120
- * Value to increment or decrement via arrow keys, mouse click or drag.
121
- *
122
- * @public
123
- * @remarks
124
- * HTML Attribute: step
125
- */
126
- this.step = 1; // Map to proxy element.
127
- /**
128
- * The orientation of the slider.
129
- *
130
- * @public
131
- * @remarks
132
- * HTML Attribute: orientation
69
+ * @internal
133
70
  */
134
- this.orientation = Orientation.horizontal;
71
+ this.forcedPosition = false;
135
72
  /**
136
- * The selection mode.
73
+ * The unique id for the internal listbox element.
137
74
  *
138
- * @public
139
- * @remarks
140
- * HTML Attribute: mode
141
- */
142
- this.mode = SliderMode.singleValue;
143
- this.keypressHandler = (e) => {
144
- if (this.readOnly) {
145
- return;
146
- }
147
- if (e.key === keyHome) {
148
- e.preventDefault();
149
- this.value = `${this.min}`;
150
- }
151
- else if (e.key === keyEnd) {
152
- e.preventDefault();
153
- this.value = `${this.max}`;
154
- }
155
- else if (!e.shiftKey) {
156
- switch (e.key) {
157
- case keyArrowRight:
158
- case keyArrowUp:
159
- e.preventDefault();
160
- this.increment();
161
- break;
162
- case keyArrowLeft:
163
- case keyArrowDown:
164
- e.preventDefault();
165
- this.decrement();
166
- break;
167
- }
168
- }
169
- };
170
- this.setupTrackConstraints = () => {
171
- const clientRect = this.track.getBoundingClientRect();
172
- this.trackWidth = this.track.clientWidth;
173
- this.trackMinWidth = this.track.clientLeft;
174
- this.trackHeight = clientRect.bottom;
175
- this.trackMinHeight = clientRect.top;
176
- this.trackLeft = this.getBoundingClientRect().left;
177
- if (this.trackWidth === 0) {
178
- this.trackWidth = 1;
179
- }
180
- };
181
- this.setupListeners = (remove = false) => {
182
- const eventAction = `${remove ? "remove" : "add"}EventListener`;
183
- this[eventAction]("keydown", this.keypressHandler);
184
- this[eventAction]("mousedown", this.handleMouseDown);
185
- this.thumb[eventAction]("mousedown", this.handleThumbMouseDown, {
186
- passive: true,
187
- });
188
- this.thumb[eventAction]("touchstart", this.handleThumbMouseDown, {
189
- passive: true,
190
- });
191
- // removes handlers attached by mousedown handlers
192
- if (remove) {
193
- this.handleMouseDown(null);
194
- this.handleThumbMouseDown(null);
195
- }
196
- };
197
- /**
198
75
  * @internal
199
76
  */
200
- this.initialValue = "";
201
- /**
202
- * Handle mouse moves during a thumb drag operation
203
- * If the event handler is null it removes the events
204
- */
205
- this.handleThumbMouseDown = (event) => {
206
- if (event) {
207
- if (this.readOnly || this.disabled || event.defaultPrevented) {
208
- return;
209
- }
210
- event.target.focus();
211
- }
212
- const eventAction = `${event !== null ? "add" : "remove"}EventListener`;
213
- window[eventAction]("mouseup", this.handleWindowMouseUp);
214
- window[eventAction]("mousemove", this.handleMouseMove, { passive: true });
215
- window[eventAction]("touchmove", this.handleMouseMove, { passive: true });
216
- window[eventAction]("touchend", this.handleWindowMouseUp);
217
- this.isDragging = event !== null;
218
- };
219
- /**
220
- * Handle mouse moves during a thumb drag operation
221
- */
222
- this.handleMouseMove = (e) => {
223
- if (this.readOnly || this.disabled || e.defaultPrevented) {
224
- return;
225
- }
226
- // update the value based on current position
227
- const sourceEvent = window.TouchEvent && e instanceof TouchEvent
228
- ? e.touches[0]
229
- : e;
230
- const eventValue = this.orientation === Orientation.horizontal
231
- ? sourceEvent.pageX - document.documentElement.scrollLeft - this.trackLeft
232
- : sourceEvent.pageY - document.documentElement.scrollTop;
233
- this.value = `${this.calculateNewValue(eventValue)}`;
234
- };
235
- this.calculateNewValue = (rawValue) => {
236
- // update the value based on current position
237
- const newPosition = convertPixelToPercent(rawValue, this.orientation === Orientation.horizontal
238
- ? this.trackMinWidth
239
- : this.trackMinHeight, this.orientation === Orientation.horizontal
240
- ? this.trackWidth
241
- : this.trackHeight, this.direction);
242
- const newValue = (this.max - this.min) * newPosition + this.min;
243
- return this.convertToConstrainedValue(newValue);
244
- };
245
- /**
246
- * Handle a window mouse up during a drag operation
247
- */
248
- this.handleWindowMouseUp = (event) => {
249
- this.stopDragging();
250
- };
251
- this.stopDragging = () => {
252
- this.isDragging = false;
253
- this.handleMouseDown(null);
254
- this.handleThumbMouseDown(null);
255
- };
77
+ this.listboxId = uniqueId("listbox-");
256
78
  /**
79
+ * The max height for the listbox when opened.
257
80
  *
258
- * @param e - MouseEvent or null. If there is no event handler it will remove the events
81
+ * @internal
259
82
  */
260
- this.handleMouseDown = (e) => {
261
- const eventAction = `${e !== null ? "add" : "remove"}EventListener`;
262
- if (e === null || (!this.disabled && !this.readOnly)) {
263
- window[eventAction]("mouseup", this.handleWindowMouseUp);
264
- window.document[eventAction]("mouseleave", this.handleWindowMouseUp);
265
- window[eventAction]("mousemove", this.handleMouseMove);
266
- if (e) {
267
- e.preventDefault();
268
- this.setupTrackConstraints();
269
- e.target.focus();
270
- const controlValue = this.orientation === Orientation.horizontal
271
- ? e.pageX - document.documentElement.scrollLeft - this.trackLeft
272
- : e.pageY - document.documentElement.scrollTop;
273
- this.value = `${this.calculateNewValue(controlValue)}`;
274
- }
275
- }
276
- };
277
- this.convertToConstrainedValue = (value) => {
278
- if (isNaN(value)) {
279
- value = this.min;
280
- }
281
- /**
282
- * The following logic intends to overcome the issue with math in JavaScript with regards to floating point numbers.
283
- * This is needed as the `step` may be an integer but could also be a float. To accomplish this the step is assumed to be a float
284
- * and is converted to an integer by determining the number of decimal places it represent, multiplying it until it is an
285
- * integer and then dividing it to get back to the correct number.
286
- */
287
- let constrainedValue = value - this.min;
288
- const roundedConstrainedValue = Math.round(constrainedValue / this.step);
289
- const remainderValue = constrainedValue -
290
- (roundedConstrainedValue * (this.stepMultiplier * this.step)) /
291
- this.stepMultiplier;
292
- constrainedValue =
293
- remainderValue >= Number(this.step) / 2
294
- ? constrainedValue - remainderValue + Number(this.step)
295
- : constrainedValue - remainderValue;
296
- return constrainedValue + this.min;
297
- };
83
+ this.maxHeight = 0;
298
84
  }
299
- readOnlyChanged() {
300
- if (this.proxy instanceof HTMLInputElement) {
301
- this.proxy.readOnly = this.readOnly;
85
+ /**
86
+ * Sets focus and synchronizes ARIA attributes when the open property changes.
87
+ *
88
+ * @param prev - the previous open value
89
+ * @param next - the current open value
90
+ *
91
+ * @internal
92
+ */
93
+ openChanged(prev, next) {
94
+ if (!this.collapsible) {
95
+ return;
302
96
  }
97
+ if (this.open) {
98
+ this.ariaControls = this.listboxId;
99
+ this.ariaExpanded = "true";
100
+ this.setPositioning();
101
+ this.focusAndScrollOptionIntoView();
102
+ this.indexWhenOpened = this.selectedIndex;
103
+ // focus is directed to the element when `open` is changed programmatically
104
+ DOM.queueUpdate(() => this.focus());
105
+ return;
106
+ }
107
+ this.ariaControls = "";
108
+ this.ariaExpanded = "false";
303
109
  }
304
110
  /**
305
- * The value property, typed as a number.
111
+ * The component is collapsible when in single-selection mode with no size attribute.
112
+ *
113
+ * @internal
114
+ */
115
+ get collapsible() {
116
+ return !(this.multiple || typeof this.size === "number");
117
+ }
118
+ /**
119
+ * The value property.
306
120
  *
307
121
  * @public
308
122
  */
309
- get valueAsNumber() {
310
- return parseFloat(super.value);
123
+ get value() {
124
+ Observable.track(this, "value");
125
+ return this._value;
311
126
  }
312
- set valueAsNumber(next) {
313
- this.value = next.toString();
127
+ set value(next) {
128
+ var _a, _b, _c, _d, _e, _f, _g;
129
+ const prev = `${this._value}`;
130
+ if ((_a = this._options) === null || _a === void 0 ? void 0 : _a.length) {
131
+ const selectedIndex = this._options.findIndex(el => el.value === next);
132
+ const prevSelectedValue = (_c = (_b = this._options[this.selectedIndex]) === null || _b === void 0 ? void 0 : _b.value) !== null && _c !== void 0 ? _c : null;
133
+ const nextSelectedValue = (_e = (_d = this._options[selectedIndex]) === null || _d === void 0 ? void 0 : _d.value) !== null && _e !== void 0 ? _e : null;
134
+ if (selectedIndex === -1 || prevSelectedValue !== nextSelectedValue) {
135
+ next = "";
136
+ this.selectedIndex = selectedIndex;
137
+ }
138
+ next = (_g = (_f = this.firstSelectedOption) === null || _f === void 0 ? void 0 : _f.value) !== null && _g !== void 0 ? _g : next;
139
+ }
140
+ if (prev !== next) {
141
+ this._value = next;
142
+ super.valueChanged(prev, next);
143
+ Observable.notify(this, "value");
144
+ this.updateDisplayValue();
145
+ }
314
146
  }
315
147
  /**
148
+ * Sets the value and display value to match the first selected option.
149
+ *
150
+ * @param shouldEmit - if true, the input and change events will be emitted
151
+ *
316
152
  * @internal
317
153
  */
318
- valueChanged(previous, next) {
319
- super.valueChanged(previous, next);
154
+ updateValue(shouldEmit) {
155
+ var _a, _b;
320
156
  if (this.$fastController.isConnected) {
321
- this.setThumbPositionForOrientation(this.direction);
157
+ this.value = (_b = (_a = this.firstSelectedOption) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : "";
322
158
  }
323
- this.$emit("change");
324
- }
325
- minChanged() {
326
- if (this.proxy instanceof HTMLInputElement) {
327
- this.proxy.min = `${this.min}`;
159
+ if (shouldEmit) {
160
+ this.$emit("input");
161
+ this.$emit("change", this, {
162
+ bubbles: true,
163
+ composed: undefined,
164
+ });
328
165
  }
329
- this.validate();
330
166
  }
331
- maxChanged() {
332
- if (this.proxy instanceof HTMLInputElement) {
333
- this.proxy.max = `${this.max}`;
334
- }
335
- this.validate();
167
+ /**
168
+ * Updates the proxy value when the selected index changes.
169
+ *
170
+ * @param prev - the previous selected index
171
+ * @param next - the next selected index
172
+ *
173
+ * @internal
174
+ */
175
+ selectedIndexChanged(prev, next) {
176
+ super.selectedIndexChanged(prev, next);
177
+ this.updateValue();
178
+ }
179
+ positionChanged(prev, next) {
180
+ this.positionAttribute = next;
181
+ this.setPositioning();
182
+ }
183
+ /**
184
+ * Calculate and apply listbox positioning based on available viewport space.
185
+ *
186
+ * @public
187
+ */
188
+ setPositioning() {
189
+ const currentBox = this.getBoundingClientRect();
190
+ const viewportHeight = window.innerHeight;
191
+ const availableBottom = viewportHeight - currentBox.bottom;
192
+ this.position = this.forcedPosition
193
+ ? this.positionAttribute
194
+ : currentBox.top > availableBottom
195
+ ? SelectPosition.above
196
+ : SelectPosition.below;
197
+ this.positionAttribute = this.forcedPosition
198
+ ? this.positionAttribute
199
+ : this.position;
200
+ this.maxHeight =
201
+ this.position === SelectPosition.above ? ~~currentBox.top : ~~availableBottom;
202
+ }
203
+ /**
204
+ * The value displayed on the button.
205
+ *
206
+ * @public
207
+ */
208
+ get displayValue() {
209
+ var _a, _b;
210
+ Observable.track(this, "displayValue");
211
+ return (_b = (_a = this.firstSelectedOption) === null || _a === void 0 ? void 0 : _a.text) !== null && _b !== void 0 ? _b : "";
336
212
  }
337
- stepChanged() {
338
- if (this.proxy instanceof HTMLInputElement) {
339
- this.proxy.step = `${this.step}`;
213
+ /**
214
+ * Synchronize the `aria-disabled` property when the `disabled` property changes.
215
+ *
216
+ * @param prev - The previous disabled value
217
+ * @param next - The next disabled value
218
+ *
219
+ * @internal
220
+ */
221
+ disabledChanged(prev, next) {
222
+ if (super.disabledChanged) {
223
+ super.disabledChanged(prev, next);
340
224
  }
341
- this.updateStepMultiplier();
342
- this.validate();
225
+ this.ariaDisabled = this.disabled ? "true" : "false";
343
226
  }
344
- orientationChanged() {
345
- if (this.$fastController.isConnected) {
346
- this.setThumbPositionForOrientation(this.direction);
227
+ /**
228
+ * Reset the element to its first selectable option when its parent form is reset.
229
+ *
230
+ * @internal
231
+ */
232
+ formResetCallback() {
233
+ this.setProxyOptions();
234
+ // Call the base class's implementation setDefaultSelectedOption instead of the select's
235
+ // override, in order to reset the selectedIndex without using the value property.
236
+ super.setDefaultSelectedOption();
237
+ if (this.selectedIndex === -1) {
238
+ this.selectedIndex = 0;
347
239
  }
348
240
  }
349
241
  /**
242
+ * Handle opening and closing the listbox when the select is clicked.
243
+ *
244
+ * @param e - the mouse event
350
245
  * @internal
351
246
  */
352
- connectedCallback() {
353
- super.connectedCallback();
354
- this.proxy.setAttribute("type", "range");
355
- this.direction = getDirection(this);
356
- this.updateStepMultiplier();
357
- this.setupTrackConstraints();
358
- this.setupListeners();
359
- this.setupDefaultValue();
360
- this.setThumbPositionForOrientation(this.direction);
247
+ clickHandler(e) {
248
+ // do nothing if the select is disabled
249
+ if (this.disabled) {
250
+ return;
251
+ }
252
+ if (this.open) {
253
+ const captured = e.target.closest(`option,[role=option]`);
254
+ if (captured && captured.disabled) {
255
+ return;
256
+ }
257
+ }
258
+ super.clickHandler(e);
259
+ this.open = this.collapsible && !this.open;
260
+ if (!this.open && this.indexWhenOpened !== this.selectedIndex) {
261
+ this.updateValue(true);
262
+ }
263
+ return true;
361
264
  }
362
265
  /**
266
+ * Handles focus state when the element or its children lose focus.
267
+ *
268
+ * @param e - The focus event
363
269
  * @internal
364
270
  */
365
- disconnectedCallback() {
366
- this.setupListeners(true);
271
+ focusoutHandler(e) {
272
+ var _a;
273
+ super.focusoutHandler(e);
274
+ if (!this.open) {
275
+ return true;
276
+ }
277
+ const focusTarget = e.relatedTarget;
278
+ if (this.isSameNode(focusTarget)) {
279
+ this.focus();
280
+ return;
281
+ }
282
+ if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.includes(focusTarget))) {
283
+ this.open = false;
284
+ if (this.indexWhenOpened !== this.selectedIndex) {
285
+ this.updateValue(true);
286
+ }
287
+ }
367
288
  }
368
289
  /**
369
- * Increment the value by the step
290
+ * Updates the value when an option's value changes.
370
291
  *
371
- * @public
292
+ * @param source - the source object
293
+ * @param propertyName - the property to evaluate
294
+ *
295
+ * @internal
296
+ * @override
372
297
  */
373
- increment() {
374
- const newVal = this.direction !== Direction.rtl && this.orientation !== Orientation.vertical
375
- ? Number(this.value) + Number(this.step)
376
- : Number(this.value) - Number(this.step);
377
- const incrementedVal = this.convertToConstrainedValue(newVal);
378
- const incrementedValString = incrementedVal < Number(this.max) ? `${incrementedVal}` : `${this.max}`;
379
- this.value = incrementedValString;
298
+ handleChange(source, propertyName) {
299
+ super.handleChange(source, propertyName);
300
+ if (propertyName === "value") {
301
+ this.updateValue();
302
+ }
380
303
  }
381
304
  /**
382
- * Decrement the value by the step
305
+ * Synchronize the form-associated proxy and updates the value property of the element.
383
306
  *
384
- * @public
307
+ * @param prev - the previous collection of slotted option elements
308
+ * @param next - the next collection of slotted option elements
309
+ *
310
+ * @internal
385
311
  */
386
- decrement() {
387
- const newVal = this.direction !== Direction.rtl && this.orientation !== Orientation.vertical
388
- ? Number(this.value) - Number(this.step)
389
- : Number(this.value) + Number(this.step);
390
- const decrementedVal = this.convertToConstrainedValue(newVal);
391
- const decrementedValString = decrementedVal > Number(this.min) ? `${decrementedVal}` : `${this.min}`;
392
- this.value = decrementedValString;
312
+ slottedOptionsChanged(prev, next) {
313
+ this.options.forEach(o => {
314
+ const notifier = Observable.getNotifier(o);
315
+ notifier.unsubscribe(this, "value");
316
+ });
317
+ super.slottedOptionsChanged(prev, next);
318
+ this.options.forEach(o => {
319
+ const notifier = Observable.getNotifier(o);
320
+ notifier.subscribe(this, "value");
321
+ });
322
+ this.setProxyOptions();
323
+ this.updateValue();
393
324
  }
394
325
  /**
395
- * Places the thumb based on the current value
326
+ * Prevents focus when size is set and a scrollbar is clicked.
396
327
  *
397
- * @public
398
- * @param direction - writing mode
328
+ * @param e - the mouse event object
329
+ *
330
+ * @override
331
+ * @internal
399
332
  */
400
- setThumbPositionForOrientation(direction) {
401
- const newPct = convertPixelToPercent(Number(this.value), Number(this.min), Number(this.max), direction);
402
- const percentage = (1 - newPct) * 100;
403
- if (this.orientation === Orientation.horizontal) {
404
- this.position = this.isDragging
405
- ? `right: ${percentage}%; transition: none;`
406
- : `right: ${percentage}%; transition: all 0.2s ease;`;
333
+ mousedownHandler(e) {
334
+ var _a;
335
+ if (e.offsetX >= 0 && e.offsetX <= ((_a = this.listbox) === null || _a === void 0 ? void 0 : _a.scrollWidth)) {
336
+ return super.mousedownHandler(e);
407
337
  }
408
- else {
409
- this.position = this.isDragging
410
- ? `bottom: ${percentage}%; transition: none;`
411
- : `bottom: ${percentage}%; transition: all 0.2s ease;`;
338
+ return this.collapsible;
339
+ }
340
+ /**
341
+ * Sets the multiple property on the proxy element.
342
+ *
343
+ * @param prev - the previous multiple value
344
+ * @param next - the current multiple value
345
+ */
346
+ multipleChanged(prev, next) {
347
+ super.multipleChanged(prev, next);
348
+ if (this.proxy) {
349
+ this.proxy.multiple = next;
412
350
  }
413
351
  }
414
352
  /**
415
- * Update the step multiplier used to ensure rounding errors from steps that
416
- * are not whole numbers
353
+ * Updates the selectedness of each option when the list of selected options changes.
354
+ *
355
+ * @param prev - the previous list of selected options
356
+ * @param next - the current list of selected options
357
+ *
358
+ * @override
359
+ * @internal
417
360
  */
418
- updateStepMultiplier() {
419
- const stepString = this.step + "";
420
- const decimalPlacesOfStep = !!(this.step % 1)
421
- ? stepString.length - stepString.indexOf(".") - 1
422
- : 0;
423
- this.stepMultiplier = Math.pow(10, decimalPlacesOfStep);
361
+ selectedOptionsChanged(prev, next) {
362
+ var _a;
363
+ super.selectedOptionsChanged(prev, next);
364
+ (_a = this.options) === null || _a === void 0 ? void 0 : _a.forEach((o, i) => {
365
+ var _a;
366
+ const proxyOption = (_a = this.proxy) === null || _a === void 0 ? void 0 : _a.options.item(i);
367
+ if (proxyOption) {
368
+ proxyOption.selected = o.selected;
369
+ }
370
+ });
424
371
  }
425
- get midpoint() {
426
- return `${this.convertToConstrainedValue((this.max + this.min) / 2)}`;
372
+ /**
373
+ * Sets the selected index to match the first option with the selected attribute, or
374
+ * the first selectable option.
375
+ *
376
+ * @override
377
+ * @internal
378
+ */
379
+ setDefaultSelectedOption() {
380
+ var _a;
381
+ const options = (_a = this.options) !== null && _a !== void 0 ? _a : Array.from(this.children).filter(Listbox.slottedOptionFilter);
382
+ const selectedIndex = options === null || options === void 0 ? void 0 : options.findIndex(el => el.hasAttribute("selected") || el.selected || el.value === this.value);
383
+ if (selectedIndex !== -1) {
384
+ this.selectedIndex = selectedIndex;
385
+ return;
386
+ }
387
+ this.selectedIndex = 0;
388
+ }
389
+ /**
390
+ * Resets and fills the proxy to match the component's options.
391
+ *
392
+ * @internal
393
+ */
394
+ setProxyOptions() {
395
+ if (this.proxy instanceof HTMLSelectElement && this.options) {
396
+ this.proxy.options.length = 0;
397
+ this.options.forEach(option => {
398
+ const proxyOption = option.proxy ||
399
+ (option instanceof HTMLOptionElement ? option.cloneNode() : null);
400
+ if (proxyOption) {
401
+ this.proxy.options.add(proxyOption);
402
+ }
403
+ });
404
+ }
427
405
  }
428
- setupDefaultValue() {
429
- if (typeof this.value === "string") {
430
- if (this.value.length === 0) {
431
- this.initialValue = this.midpoint;
406
+ /**
407
+ * Handle keyboard interaction for the select.
408
+ *
409
+ * @param e - the keyboard event
410
+ * @internal
411
+ */
412
+ keydownHandler(e) {
413
+ super.keydownHandler(e);
414
+ const key = e.key || e.key.charCodeAt(0);
415
+ switch (key) {
416
+ case keySpace: {
417
+ e.preventDefault();
418
+ if (this.collapsible && this.typeAheadExpired) {
419
+ this.open = !this.open;
420
+ }
421
+ break;
422
+ }
423
+ case keyHome:
424
+ case keyEnd: {
425
+ e.preventDefault();
426
+ break;
432
427
  }
433
- else {
434
- const value = parseFloat(this.value);
435
- if (!Number.isNaN(value) && (value < this.min || value > this.max)) {
436
- this.value = this.midpoint;
428
+ case keyEnter: {
429
+ e.preventDefault();
430
+ this.open = !this.open;
431
+ break;
432
+ }
433
+ case keyEscape: {
434
+ if (this.collapsible && this.open) {
435
+ e.preventDefault();
436
+ this.open = false;
437
437
  }
438
+ break;
438
439
  }
440
+ case keyTab: {
441
+ if (this.collapsible && this.open) {
442
+ e.preventDefault();
443
+ this.open = false;
444
+ }
445
+ return true;
446
+ }
447
+ }
448
+ if (!this.open && this.indexWhenOpened !== this.selectedIndex) {
449
+ this.updateValue(true);
450
+ this.indexWhenOpened = this.selectedIndex;
451
+ }
452
+ return !(key === keyArrowDown || key === keyArrowUp);
453
+ }
454
+ connectedCallback() {
455
+ super.connectedCallback();
456
+ this.forcedPosition = !!this.positionAttribute;
457
+ this.addEventListener("contentchange", this.updateDisplayValue);
458
+ }
459
+ disconnectedCallback() {
460
+ this.removeEventListener("contentchange", this.updateDisplayValue);
461
+ super.disconnectedCallback();
462
+ }
463
+ /**
464
+ * Updates the proxy's size property when the size attribute changes.
465
+ *
466
+ * @param prev - the previous size
467
+ * @param next - the current size
468
+ *
469
+ * @override
470
+ * @internal
471
+ */
472
+ sizeChanged(prev, next) {
473
+ super.sizeChanged(prev, next);
474
+ if (this.proxy) {
475
+ this.proxy.size = next;
476
+ }
477
+ }
478
+ /**
479
+ *
480
+ * @internal
481
+ */
482
+ updateDisplayValue() {
483
+ if (this.collapsible) {
484
+ Observable.notify(this, "displayValue");
439
485
  }
440
486
  }
441
487
  }
442
488
  __decorate([
443
- attr({ attribute: "readonly", mode: "boolean" })
444
- ], Slider$1.prototype, "readOnly", void 0);
489
+ attr({ attribute: "open", mode: "boolean" })
490
+ ], Select$1.prototype, "open", void 0);
445
491
  __decorate([
446
- observable
447
- ], Slider$1.prototype, "direction", void 0);
492
+ volatile
493
+ ], Select$1.prototype, "collapsible", null);
448
494
  __decorate([
449
495
  observable
450
- ], Slider$1.prototype, "isDragging", void 0);
496
+ ], Select$1.prototype, "control", void 0);
451
497
  __decorate([
452
- observable
453
- ], Slider$1.prototype, "position", void 0);
498
+ attr({ attribute: "position" })
499
+ ], Select$1.prototype, "positionAttribute", void 0);
454
500
  __decorate([
455
501
  observable
456
- ], Slider$1.prototype, "trackWidth", void 0);
502
+ ], Select$1.prototype, "position", void 0);
457
503
  __decorate([
458
504
  observable
459
- ], Slider$1.prototype, "trackMinWidth", void 0);
460
- __decorate([
461
- observable
462
- ], Slider$1.prototype, "trackHeight", void 0);
463
- __decorate([
464
- observable
465
- ], Slider$1.prototype, "trackLeft", void 0);
466
- __decorate([
467
- observable
468
- ], Slider$1.prototype, "trackMinHeight", void 0);
469
- __decorate([
470
- observable
471
- ], Slider$1.prototype, "valueTextFormatter", void 0);
472
- __decorate([
473
- attr({ converter: nullableNumberConverter })
474
- ], Slider$1.prototype, "min", void 0);
475
- __decorate([
476
- attr({ converter: nullableNumberConverter })
477
- ], Slider$1.prototype, "max", void 0);
478
- __decorate([
479
- attr({ converter: nullableNumberConverter })
480
- ], Slider$1.prototype, "step", void 0);
481
- __decorate([
482
- attr
483
- ], Slider$1.prototype, "orientation", void 0);
484
- __decorate([
485
- attr
486
- ], Slider$1.prototype, "mode", void 0);
487
-
505
+ ], Select$1.prototype, "maxHeight", void 0);
488
506
  /**
489
- * This method keeps a given value within the bounds of a min and max value. If the value
490
- * is larger than the max, the minimum value will be returned. If the value is smaller than the minimum,
491
- * the maximum will be returned. Otherwise, the value is returned un-changed.
492
- */
493
- /**
494
- * Ensures that a value is between a min and max value. If value is lower than min, min will be returned.
495
- * If value is greater than max, max will be returned.
507
+ * Includes ARIA states and properties relating to the ARIA select role.
508
+ *
509
+ * @public
496
510
  */
497
- function limit(min, max, value) {
498
- return Math.min(Math.max(value, min), max);
511
+ class DelegatesARIASelect {
499
512
  }
513
+ __decorate([
514
+ observable
515
+ ], DelegatesARIASelect.prototype, "ariaControls", void 0);
516
+ applyMixins(DelegatesARIASelect, DelegatesARIAListbox);
517
+ applyMixins(Select$1, StartEnd, DelegatesARIASelect);
500
518
 
501
- var css_248z = ":host {\n display: inline-block;\n width: 100%;\n}\n\n:host([orientation=vertical]) {\n height: 100%;\n min-height: calc(var(--_thumb-interaction-indicator-size) * 5);\n}\n\n.control {\n --_thumb-size: 12px;\n --_thumb-interaction-indicator-size: 36px;\n height: var(--_thumb-interaction-indicator-size);\n cursor: pointer;\n outline: none;\n user-select: none;\n}\n@supports selector(:focus-visible) {\n .control:focus {\n outline: none;\n }\n}\n.control .positioning-region {\n position: relative;\n}\n.control .track {\n position: absolute;\n background: var(--_track-background-color);\n border-radius: 4px;\n}\n.control .track .track-start {\n position: absolute;\n left: 0;\n height: 100%;\n background: var(--_track-start-background-color);\n border-radius: 4px;\n}\n.control .thumb-container {\n position: absolute;\n width: var(--_thumb-interaction-indicator-size);\n height: var(--_thumb-interaction-indicator-size);\n cursor: inherit;\n touch-action: none;\n}\n.control .thumb-container::before {\n position: absolute;\n display: block;\n width: var(--_thumb-interaction-indicator-size);\n height: var(--_thumb-interaction-indicator-size);\n background-color: var(--_track-start-background-color);\n border-radius: 50%;\n content: \"\";\n opacity: var(--_thumb-interaction-indicator-alpha, 0);\n transition: opacity 0.2s ease-out 0s;\n}\n.control .thumb-container::after {\n position: absolute;\n display: block;\n width: var(--_thumb-size);\n height: var(--_thumb-size);\n background-color: var(--_track-start-background-color);\n border-radius: 50%;\n content: \"\";\n inset: calc((var(--_thumb-interaction-indicator-size) - var(--_thumb-size)) / 2);\n}\n.control[aria-orientation=horizontal] {\n width: calc(100% - var(--_thumb-size));\n min-width: var(--_thumb-size);\n margin-left: calc(var(--_thumb-size) / 2);\n}\n.control[aria-orientation=horizontal] .track {\n top: calc((var(--_thumb-interaction-indicator-size) - 2px) / 2);\n right: 0;\n left: 0;\n height: 2px;\n}\n.control[aria-orientation=horizontal] .track .mark {\n width: 100%;\n height: 4px;\n}\n.control[aria-orientation=horizontal] .thumb-container {\n transform: translateX(calc(var(--_thumb-interaction-indicator-size) / 2));\n}\n.control[aria-orientation=vertical] {\n height: calc(100% - var(--_thumb-interaction-indicator-size));\n min-height: var(--_thumb-interaction-indicator-size);\n margin-top: calc(var(--_thumb-interaction-indicator-size) / 2);\n}\n.control[aria-orientation=vertical] .positioning-region {\n height: 100%;\n}\n.control[aria-orientation=vertical] .track {\n left: calc((var(--_thumb-interaction-indicator-size) - 2px) / 2);\n width: 2px;\n height: 100%;\n}\n.control[aria-orientation=vertical] .track .mark {\n width: 4px;\n height: 100%;\n}\n.control[aria-orientation=vertical] .track-start {\n top: 0;\n width: 100%;\n height: auto;\n}\n.control[aria-orientation=vertical] .thumb-container {\n transform: translateY(calc(var(--_thumb-interaction-indicator-size) / 2));\n}\n.control.disabled {\n --_track-background-color: var(--vvd-color-neutral-100);\n --_track-start-background-color: var(--vvd-color-neutral-500);\n cursor: not-allowed;\n pointer-events: none;\n}\n.control:not(.disabled) {\n --_track-background-color: var(--vvd-color-neutral-300);\n --_track-start-background-color: var(--vvd-color-canvas-text);\n}\n.control:not(.disabled) .thumb-container:hover {\n --_thumb-interaction-indicator-alpha: 0.12;\n}\n.control:not(.disabled) .thumb-container:active {\n --_thumb-interaction-indicator-alpha: 0.25;\n}\n\n.focus-indicator {\n --focus-inset: -3px;\n --focus-stroke-gap-color: transparent;\n border-radius: 50%;\n}\n.control:not(:focus-visible) .focus-indicator {\n display: none;\n}";
502
-
503
- var global = global$1;
504
- var fails = fails$1;
505
- var uncurryThis = functionUncurryThis;
506
- var toString = toString$1;
507
- var trim = stringTrim.trim;
508
- var whitespaces = whitespaces$1;
509
-
510
- var charAt = uncurryThis(''.charAt);
511
- var $parseFloat$1 = global.parseFloat;
512
- var Symbol = global.Symbol;
513
- var ITERATOR = Symbol && Symbol.iterator;
514
- var FORCED = 1 / $parseFloat$1(whitespaces + '-0') !== -Infinity
515
- // MS Edge 18- broken with boxed symbols
516
- || (ITERATOR && !fails(function () { $parseFloat$1(Object(ITERATOR)); }));
517
-
518
- // `parseFloat` method
519
- // https://tc39.es/ecma262/#sec-parsefloat-string
520
- var numberParseFloat = FORCED ? function parseFloat(string) {
521
- var trimmedString = trim(toString(string));
522
- var result = $parseFloat$1(trimmedString);
523
- return result === 0 && charAt(trimmedString, 0) == '-' ? -0 : result;
524
- } : $parseFloat$1;
525
-
526
- var $ = _export;
527
- var $parseFloat = numberParseFloat;
528
-
529
- // `parseFloat` method
530
- // https://tc39.es/ecma262/#sec-parsefloat-string
531
- $({ global: true, forced: parseFloat != $parseFloat }, {
532
- parseFloat: $parseFloat
533
- });
519
+ var css_248z = "/**\n * Do not edit directly\n * Generated on Tue, 06 Jun 2023 10:38:32 GMT\n */\n@supports selector(:focus-visible) {\n :host(:focus) {\n outline: none;\n }\n}\n:host {\n display: inline-flex;\n flex-direction: column;\n gap: 4px;\n --_low-ink-color: var(--vvd-color-neutral-600);\n}\n\n:host([disabled]) {\n --_low-ink-color: var(--vvd-color-neutral-400);\n}\n\n.label {\n color: var(--vvd-color-canvas-text);\n contain: inline-size;\n font: var(--vvd-typography-base);\n}\n\n.control {\n display: flex;\n align-items: center;\n justify-content: space-between;\n background-color: var(--_appearance-color-fill);\n block-size: calc(1px * (40 + 4 * clamp(-1, var(--vvd-size-density, 0), 2)));\n border-radius: var(--_select-control-border-radius);\n box-shadow: inset 0 0 0 1px var(--_appearance-color-outline);\n color: var(--_appearance-color-text);\n font: var(--vvd-typography-base);\n gap: 8px;\n padding-inline: 16px;\n transition: box-shadow 0.2s, background-color 0.2s;\n}\n.control {\n --_appearance-color-text: var(--vvd-color-canvas-text);\n --_appearance-color-fill: var(--_connotation-color-backdrop);\n --_appearance-color-outline: var(--_connotation-color-intermediate);\n}\n.control.appearance-ghost {\n --_appearance-color-text: var(--_connotation-color-primary);\n --_appearance-color-fill: transparent;\n --_appearance-color-outline: transparent;\n}\n.control:where(:hover, .hover):where(:not(:disabled, .disabled, .readonly)) {\n --_appearance-color-text: var(--vvd-color-canvas-text);\n --_appearance-color-fill: var(--_connotation-color-backdrop);\n --_appearance-color-outline: var(--_connotation-color-firm);\n}\n.control:where(:hover, .hover):where(:not(:disabled, .disabled, .readonly)).appearance-ghost {\n --_appearance-color-text: var(--_connotation-color-primary);\n --_appearance-color-fill: var(--_connotation-color-faint);\n --_appearance-color-outline: transparent;\n}\n.control:where(:disabled, .disabled) {\n --_appearance-color-text: var(--vvd-color-neutral-400);\n --_appearance-color-fill: var(--vvd-color-neutral-200);\n --_appearance-color-outline: var(--vvd-color-neutral-400);\n}\n.control:where(:disabled, .disabled).appearance-ghost {\n --_appearance-color-text: var(--vvd-color-neutral-400);\n --_appearance-color-fill: transparent;\n --_appearance-color-outline: transparent;\n}\n.control:where(.readonly):where(:not(:disabled, .disabled)) {\n --_appearance-color-text: var(--vvd-color-canvas-text);\n --_appearance-color-fill: var(--vvd-color-neutral-100);\n --_appearance-color-outline: var(--vvd-color-neutral-400);\n}\n.control:where(.readonly):where(:not(:disabled, .disabled)).appearance-ghost {\n --_appearance-color-text: var(--vvd-color-neutral-600);\n --_appearance-color-fill: transparent;\n --_appearance-color-outline: transparent;\n}\n.control.connotation-success {\n /* @cssprop [--vvd-select-success-primary=var(--vvd-color-success-500)] */\n --_connotation-color-primary: var(--vvd-select-success-primary, var(--vvd-color-success-500));\n /* @cssprop [--vvd-select-success-backdrop=var(--vvd-color-success-50)] */\n --_connotation-color-backdrop: var(--vvd-select-success-backdrop, var(--vvd-color-success-50));\n /* @cssprop [--vvd-select-success-intermediate=var(--vvd-color-success-500)] */\n --_connotation-color-intermediate: var(--vvd-select-success-intermediate, var(--vvd-color-success-500));\n /* @cssprop [--vvd-select-success-firm=var(--vvd-color-success-600)] */\n --_connotation-color-firm: var(--vvd-select-success-firm, var(--vvd-color-success-600));\n}\n.control.connotation-alert {\n /* @cssprop [--vvd-select-alert-primary=var(--vvd-color-alert-500)] */\n --_connotation-color-primary: var(--vvd-select-alert-primary, var(--vvd-color-alert-500));\n /* @cssprop [--vvd-select-alert-backdrop=var(--vvd-color-alert-50)] */\n --_connotation-color-backdrop: var(--vvd-select-alert-backdrop, var(--vvd-color-alert-50));\n /* @cssprop [--vvd-select-alert-intermediate=var(--vvd-color-alert-500)] */\n --_connotation-color-intermediate: var(--vvd-select-alert-intermediate, var(--vvd-color-alert-500));\n /* @cssprop [--vvd-select-alert-firm=var(--vvd-color-alert-600)] */\n --_connotation-color-firm: var(--vvd-select-alert-firm, var(--vvd-color-alert-600));\n}\n.control:not(.connotation-success, .connotation-alert) {\n /* @cssprop [--vvd-select-accent-primary=var(--vvd-color-canvas-text)] */\n --_connotation-color-primary: var(--vvd-select-accent-primary, var(--vvd-color-canvas-text));\n /* @cssprop [--vvd-select-accent-backdrop=var(--vvd-color-canvas)] */\n --_connotation-color-backdrop: var(--vvd-select-accent-backdrop, var(--vvd-color-canvas));\n /* @cssprop [--vvd-select-accent-intermediate=var(--vvd-color-neutral-500)] */\n --_connotation-color-intermediate: var(--vvd-select-accent-intermediate, var(--vvd-color-neutral-500));\n /* @cssprop [--vvd-select-accent-firm=var(--vvd-color-canvas-text)] */\n --_connotation-color-firm: var(--vvd-select-accent-firm, var(--vvd-color-canvas-text));\n}\n.control-wrapper {\n position: relative;\n}\n.control:not(.disabled) {\n cursor: pointer;\n}\n.control.disabled {\n cursor: not-allowed;\n pointer-events: none;\n}\n.control:not(.shape-pill) {\n --_select-control-border-radius: 6px;\n}\n.control.shape-pill {\n --_select-control-border-radius: 24px;\n}\n\n.list-box {\n display: flex;\n max-height: var(--select-height, 408px);\n flex-direction: column;\n padding: 4px;\n gap: 2px;\n overflow-y: auto;\n}\n\n.selected-value {\n display: flex;\n overflow: hidden;\n flex-grow: 1;\n align-items: center;\n column-gap: 12px;\n white-space: nowrap;\n}\n.selected-value .text {\n overflow: hidden;\n max-inline-size: 100%;\n text-overflow: ellipsis;\n}\n.selected-value .icon {\n flex: 0 0 20px;\n font-size: 20px;\n line-height: 1;\n}\n.control.has-meta .selected-value {\n padding-inline-end: 8px;\n}\n\n::part(popup-base) {\n inline-size: max-content;\n min-inline-size: 100%;\n}\n\n.focus-indicator {\n border-radius: var(--_select-control-border-radius);\n pointer-events: none;\n}\n:host(:not(:focus-visible)) .focus-indicator {\n display: none;\n}";
534
520
 
535
- class Slider extends Slider$1 {
536
- constructor() {
537
- super(...arguments);
538
- this.markers = false;
521
+ let Select = class Select extends Select$1 {
522
+ connectedCallback() {
523
+ super.connectedCallback();
524
+ this._popup.anchor = this._anchor;
539
525
  }
540
- valueChanged(previous, next) {
541
- if (this.$fastController.isConnected) {
542
- const nextAsNumber = parseFloat(next);
543
- const value = limit(this.min, this.max, this['convertToConstrainedValue'](nextAsNumber)).toString();
544
- if (value !== next) {
545
- this.value = value;
546
- return;
547
- }
548
- super.valueChanged(previous, value);
549
- }
526
+ get displayValue() {
527
+ var _a, _b, _c, _d;
528
+ Observable.track(this, 'displayValue');
529
+ return (_d = (_b = (_a = this.firstSelectedOption) === null || _a === void 0 ? void 0 : _a.getAttribute('label')) !== null && _b !== void 0 ? _b : (_c = this.firstSelectedOption) === null || _c === void 0 ? void 0 : _c.text) !== null && _d !== void 0 ? _d : '';
550
530
  }
551
- }
552
- __decorate([attr({
553
- mode: 'boolean'
554
- }), __metadata("design:type", Object)], Slider.prototype, "markers", void 0);
531
+ };
532
+ __decorate([attr, __metadata("design:type", String)], Select.prototype, "appearance", void 0);
533
+ __decorate([attr, __metadata("design:type", String)], Select.prototype, "shape", void 0);
534
+ __decorate([observable, __metadata("design:type", Array)], Select.prototype, "metaSlottedContent", void 0);
535
+ Select = __decorate([errorText, formElements], Select);
536
+ applyMixins(Select, AffixIconWithTrailing, FormElementHelperText, FormElementSuccessText);
555
537
 
556
538
  let _ = t => t,
557
539
  _t,
558
- _t2;
559
- const getClasses = ({
560
- disabled
561
- }) => classNames('control', ['disabled', Boolean(disabled)]);
562
- const getMarkersTemplate = (isHorizontal, numMarkers) => {
563
- const placeholder = isHorizontal ? ['right', 'center', '', '100% repeat-x'] : ['bottom', 'top', '100%', 'repeat-y'];
540
+ _t2,
541
+ _t3,
542
+ _t4;
543
+ const getStateClasses = ({
544
+ shape,
545
+ disabled,
546
+ appearance,
547
+ metaSlottedContent,
548
+ errorValidationMessage,
549
+ successText
550
+ }) => classNames(['disabled', disabled], [`appearance-${appearance}`, Boolean(appearance)], [`shape-${shape}`, Boolean(shape)], ['has-meta', Boolean(metaSlottedContent === null || metaSlottedContent === void 0 ? void 0 : metaSlottedContent.length)], ['error connotation-alert', Boolean(errorValidationMessage)], ['success connotation-success', !!successText]);
551
+ function renderLabel() {
564
552
  return html(_t || (_t = _`
565
- <div class="mark" style="
566
- background: linear-gradient(to ${0}, currentcolor 3px, transparent 0px)
567
- 0px ${0} / ${0} calc((100% - 3px) / ${0}) ${0}
568
- "></div>`), placeholder[0], placeholder[1], placeholder[2], numMarkers, placeholder[3]);
569
- };
570
- const SliderTemplate = context => {
553
+ <label for="control" class="label">
554
+ ${0}
555
+ </label>`), x => x.label);
556
+ }
557
+ function selectValue(context) {
558
+ const affixIconTemplate = affixIconTemplateFactory(context);
571
559
  const focusTemplate = focusTemplateFactory(context);
572
560
  return html(_t2 || (_t2 = _`
573
- <div
574
- role="slider"
575
- tabindex="${0}"
576
- aria-valuetext="${0}"
577
- aria-valuenow="${0}"
578
- aria-valuemin="${0}"
579
- aria-valuemax="${0}"
580
- aria-disabled="${0}"
581
- aria-orientation="${0}"
582
- class="${0} ${0}"
583
- >
584
- <div class="positioning-region">
585
- <div ${0} class="track">
586
- <div class="track-start" style="${0}"></div>
587
- ${0}
588
- </div>
589
- <div ${0} class="thumb-container" style="${0}">
561
+ <div
562
+ class="control ${0}"
563
+ ?disabled="${0}"
564
+ id="control"
565
+ ${0}
566
+ >
567
+ <div class="selected-value">
568
+ ${0}
569
+ <span class="text">${0}</span>
570
+ <slot name="meta" ${0}></slot>
571
+ </div>
572
+ ${0}
573
+ ${0}
574
+ </div>
575
+ `), getStateClasses, x => x.disabled, ref('_anchor'), x => affixIconTemplate(x.icon), x => x.displayValue, slotted('metaSlottedContent'), () => affixIconTemplate('chevron-down-line'), () => focusTemplate);
576
+ }
577
+ function renderControl(context) {
578
+ const focusTemplate = focusTemplateFactory(context);
579
+ const popupTag = context.tagFor(Popup);
580
+ return html(_t3 || (_t3 = _`
581
+ ${0}
582
+ <div class="control-wrapper">
590
583
  ${0}
584
+ <${0}
585
+ ?open="${0}"
586
+ anchor="control"
587
+ placement="bottom-start"
588
+ strategy="absolute"
589
+ ${0}
590
+ class="popup"
591
+ >
592
+ <div
593
+ id="${0}"
594
+ role="listbox"
595
+ ?disabled="${0}"
596
+ ${0}
597
+ class="list-box"
598
+ >
599
+ ${0}
600
+ <slot
601
+ ${0}
602
+ ></slot>
603
+ </div>
604
+ </${0}>
591
605
  </div>
592
- </div>
593
- </div>`), x => x.disabled ? null : 0, x => x.valueTextFormatter(x.value), x => x.value, x => x.min, x => x.max, x => x.disabled ? true : void 0, x => x.orientation, getClasses, x => x.orientation, ref('track'), x => x.position, x => x.markers ? getMarkersTemplate(x.orientation === Orientation$1.horizontal, Math.floor((x.max - x.min) / x.step)) : void 0, ref('thumb'), x => x.position, () => focusTemplate);
606
+ ${0}
607
+ ${0}
608
+ ${0}
609
+ `), when(x => x.label, renderLabel()), when(x => !x.multiple, selectValue(context)), popupTag, x => x.collapsible ? x.open : true, ref('_popup'), x => x.listboxId, x => x.disabled, ref('listbox'), when(x => x.multiple, focusTemplate), slotted({
610
+ filter: Listbox$1.slottedOptionFilter,
611
+ flatten: true,
612
+ property: 'slottedOptions'
613
+ }), popupTag, when(x => {
614
+ var _a;
615
+ return (_a = x.helperText) === null || _a === void 0 ? void 0 : _a.length;
616
+ }, getFeedbackTemplate('helper', context)), when(x => !x.successText && x.errorValidationMessage, getFeedbackTemplate('error', context)), when(x => x.successText, getFeedbackTemplate('success', context)));
617
+ }
618
+ const SelectTemplate = context => {
619
+ return html(_t4 || (_t4 = _`
620
+ <template class="base"
621
+ aria-label="${0}"
622
+ aria-activedescendant="${0}"
623
+ aria-controls="${0}"
624
+ aria-disabled="${0}"
625
+ aria-expanded="${0}"
626
+ aria-haspopup="${0}"
627
+ aria-multiselectable="${0}"
628
+ ?open="${0}"
629
+ role="combobox"
630
+ tabindex="${0}"
631
+ @click="${0}"
632
+ @focusin="${0}"
633
+ @focusout="${0}"
634
+ @keydown="${0}"
635
+ @mousedown="${0}"
636
+ >
637
+ ${0}
638
+ </template>
639
+ `), x => x.ariaLabel ? x.ariaLabel : x.label, x => x.ariaActiveDescendant, x => x.ariaControls, x => x.ariaDisabled, x => x.ariaExpanded, x => x.collapsible ? 'listbox' : null, x => x.ariaMultiSelectable, x => x.open, x => !x.disabled ? '0' : null, (x, c) => x.clickHandler(c.event), (x, c) => x.focusinHandler(c.event), (x, c) => x.focusoutHandler(c.event), (x, c) => x.keydownHandler(c.event), (x, c) => x.mousedownHandler(c.event), renderControl(context));
594
640
  };
595
641
 
596
- const sliderDefinition = Slider.compose({
597
- baseName: 'slider',
598
- template: SliderTemplate,
642
+ const selectDefinition = Select.compose({
643
+ baseName: 'select',
644
+ template: SelectTemplate,
599
645
  styles: css_248z
600
646
  });
601
- const sliderRegistries = [sliderDefinition(), ...focusRegistries];
602
- const registerSlider = registerFactory(sliderRegistries);
647
+ const selectRegistries = [selectDefinition(), ...focusRegistries, ...popupRegistries, ...iconRegistries, ...listboxOptionRegistries];
648
+ const registerSelect = registerFactory(selectRegistries);
603
649
 
604
- export { sliderRegistries as a, registerSlider as r, sliderDefinition as s };
650
+ export { selectRegistries as a, registerSelect as r, selectDefinition as s };