@vonage/vivid 3.40.0 → 3.42.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 (161) hide show
  1. package/accordion/index.js +2 -2
  2. package/accordion-item/index.js +2 -2
  3. package/alert/index.js +6 -5
  4. package/audio-player/index.js +33 -0
  5. package/avatar/index.js +2 -2
  6. package/badge/index.js +2 -2
  7. package/banner/index.js +8 -5
  8. package/breadcrumb/index.js +1 -1
  9. package/breadcrumb-item/index.js +3 -3
  10. package/button/index.js +4 -4
  11. package/calendar/index.js +1 -1
  12. package/calendar-event/index.js +1 -1
  13. package/card/index.js +4 -3
  14. package/checkbox/index.js +3 -3
  15. package/combobox/index.js +8 -8
  16. package/custom-elements.json +438 -41
  17. package/data-grid/index.js +2 -2
  18. package/date-picker/index.js +9 -9
  19. package/date-range-picker/index.js +8 -8
  20. package/dialog/index.js +6 -6
  21. package/divider/index.js +1 -1
  22. package/elevation/index.js +1 -1
  23. package/empty-state/index.js +2 -2
  24. package/fab/index.js +3 -3
  25. package/file-picker/index.js +5 -5
  26. package/focus/index.js +1 -1
  27. package/header/index.js +2 -2
  28. package/icon/index.js +1 -1
  29. package/index.js +57 -56
  30. package/layout/index.js +1 -1
  31. package/lib/alert/alert.d.ts +3 -1
  32. package/lib/alert/locale.d.ts +3 -0
  33. package/lib/audio-player/audio-player.d.ts +17 -0
  34. package/lib/audio-player/audio-player.template.d.ts +4 -0
  35. package/lib/audio-player/definition.d.ts +4 -0
  36. package/lib/audio-player/locale.d.ts +5 -0
  37. package/lib/banner/banner.d.ts +3 -1
  38. package/lib/banner/locale.d.ts +3 -0
  39. package/lib/card/card.d.ts +3 -0
  40. package/lib/card/card.template.d.ts +1 -1
  41. package/lib/card/definition.d.ts +1 -0
  42. package/lib/checkbox/checkbox.d.ts +1 -0
  43. package/lib/components.d.ts +1 -0
  44. package/lib/enums.d.ts +2 -1
  45. package/lib/selectable-box/selectable-box.d.ts +2 -2
  46. package/lib/split-button/locale.d.ts +3 -0
  47. package/lib/split-button/split-button.d.ts +4 -2
  48. package/listbox/index.js +4 -4
  49. package/locales/en-GB.js +14 -0
  50. package/locales/en-US.js +14 -0
  51. package/locales/ja-JP.js +14 -0
  52. package/locales/zh-CN.js +14 -0
  53. package/menu/index.js +8 -8
  54. package/menu-item/index.js +3 -3
  55. package/nav/index.js +1 -1
  56. package/nav-disclosure/index.js +3 -3
  57. package/nav-item/index.js +3 -3
  58. package/note/index.js +2 -2
  59. package/number-field/index.js +6 -6
  60. package/option/index.js +3 -3
  61. package/package.json +1 -1
  62. package/pagination/index.js +5 -5
  63. package/popup/index.js +6 -6
  64. package/progress/index.js +1 -1
  65. package/progress-ring/index.js +1 -1
  66. package/radio/index.js +2 -2
  67. package/radio-group/index.js +2 -2
  68. package/select/index.js +8 -8
  69. package/selectable-box/index.js +5 -5
  70. package/shared/definition.js +3 -3
  71. package/shared/definition10.js +90 -159
  72. package/shared/definition11.js +151 -29
  73. package/shared/definition12.js +37 -766
  74. package/shared/definition13.js +747 -106
  75. package/shared/definition14.js +121 -198
  76. package/shared/definition15.js +167 -664
  77. package/shared/definition16.js +576 -1137
  78. package/shared/definition17.js +1278 -143
  79. package/shared/definition18.js +68 -306
  80. package/shared/definition19.js +359 -217
  81. package/shared/definition2.js +1 -1
  82. package/shared/definition20.js +259 -67
  83. package/shared/definition21.js +66 -58
  84. package/shared/definition22.js +43 -84
  85. package/shared/definition23.js +76 -2353
  86. package/shared/definition24.js +2362 -45
  87. package/shared/definition25.js +63 -27
  88. package/shared/definition26.js +24 -51
  89. package/shared/definition27.js +36 -822
  90. package/shared/definition28.js +837 -49
  91. package/shared/definition29.js +52 -89
  92. package/shared/definition3.js +1 -1
  93. package/shared/definition30.js +88 -24
  94. package/shared/definition31.js +25 -12
  95. package/shared/definition32.js +12 -52
  96. package/shared/definition33.js +28 -502
  97. package/shared/definition34.js +442 -197
  98. package/shared/definition35.js +260 -186
  99. package/shared/definition36.js +186 -75
  100. package/shared/definition37.js +70 -54
  101. package/shared/definition38.js +65 -421
  102. package/shared/definition39.js +437 -38
  103. package/shared/definition4.js +43 -16
  104. package/shared/definition40.js +32 -680
  105. package/shared/definition41.js +654 -105
  106. package/shared/definition42.js +117 -78
  107. package/shared/definition43.js +74 -567
  108. package/shared/definition44.js +567 -98
  109. package/shared/definition45.js +110 -135
  110. package/shared/definition46.js +153 -17
  111. package/shared/definition47.js +16 -79
  112. package/shared/definition48.js +53 -475
  113. package/shared/definition49.js +502 -25
  114. package/shared/definition5.js +160 -44
  115. package/shared/definition50.js +22 -121
  116. package/shared/definition51.js +113 -271
  117. package/shared/definition52.js +249 -243
  118. package/shared/definition53.js +270 -109
  119. package/shared/definition54.js +84 -74
  120. package/shared/definition55.js +114 -69
  121. package/shared/definition56.js +81 -292
  122. package/shared/definition57.js +302 -13
  123. package/shared/definition58.js +11 -41
  124. package/shared/definition59.js +20 -154
  125. package/shared/definition6.js +43 -33
  126. package/shared/definition60.js +181 -0
  127. package/shared/definition7.js +39 -106
  128. package/shared/definition8.js +122 -38
  129. package/shared/definition9.js +56 -89
  130. package/shared/enums.js +1 -0
  131. package/shared/icon.js +2 -2
  132. package/shared/index.js +1 -1
  133. package/shared/index2.js +1 -1
  134. package/shared/listbox.js +1 -1
  135. package/shared/localization/Locale.d.ts +8 -0
  136. package/shared/patterns/form-elements/form-elements.d.ts +6 -6
  137. package/shared/presentationDate.js +10 -8
  138. package/shared/text-field.js +1 -1
  139. package/side-drawer/index.js +1 -1
  140. package/slider/index.js +3 -3
  141. package/split-button/index.js +6 -3
  142. package/style.css +329 -242
  143. package/styles/core/all.css +31 -25
  144. package/styles/core/theme.css +1 -1
  145. package/styles/core/typography.css +31 -25
  146. package/styles/tokens/theme-dark.css +4 -4
  147. package/styles/tokens/theme-light.css +4 -4
  148. package/styles/tokens/vivid-2-compat.css +1 -1
  149. package/switch/index.js +3 -3
  150. package/tab/index.js +3 -3
  151. package/tab-panel/index.js +1 -1
  152. package/tabs/index.js +5 -5
  153. package/tag/index.js +3 -3
  154. package/tag-group/index.js +1 -1
  155. package/text-area/index.js +3 -3
  156. package/text-field/index.js +3 -3
  157. package/toggletip/index.js +7 -7
  158. package/tooltip/index.js +7 -7
  159. package/tree-item/index.js +3 -3
  160. package/tree-view/index.js +1 -1
  161. package/vivid.api.json +270 -1
@@ -1,1138 +1,627 @@
1
- import { a as iconRegistries } from './definition25.js';
2
- import { F as FoundationElement, _ as __decorate, a as attr, o as observable, D as DOM, h as html, r as registerFactory } from './index.js';
3
- import { d as keyEnd, g as keyHome, h as keyArrowRight, i as keyArrowLeft, j as keyPageDown, l as keyPageUp, f as keyArrowDown, e as keyArrowUp, b as keyEscape, m as keyFunction2, k as keyEnter } from './key-codes.js';
4
- import { R as RepeatDirective } from './repeat.js';
5
- import { e as elements, s as slotted } from './slotted.js';
6
- import { c as children } from './children.js';
7
- import { I as Icon } from './icon.js';
1
+ import { D as DOM, O as Observable, _ as __decorate, a as attr, o as observable, h as html, r as registerFactory } from './index.js';
2
+ import { a as iconRegistries } from './definition26.js';
3
+ import { P as Popup, p as popupRegistries } from './definition60.js';
4
+ import { f as focusRegistries } from './definition58.js';
5
+ import { a as listboxOptionRegistries } from './definition35.js';
6
+ import { s as styles$1 } from './text-field.js';
7
+ import { A as AffixIcon, a as affixIconTemplateFactory } from './affix.js';
8
+ import { f as formElements } from './index2.js';
9
+ import { b as Listbox, D as DelegatesARIAListbox, a as Listbox$1 } from './listbox.js';
10
+ import { S as StartEnd } from './start-end.js';
11
+ import { S as SelectPosition } from './select.options.js';
12
+ import { a as applyMixins } from './apply-mixins.js';
13
+ import { F as FormAssociated } from './form-associated.js';
14
+ import { l as limit } from './numbers.js';
15
+ import { u as uniqueId } from './strings.js';
8
16
  import { f as focusTemplateFactory } from './focus2.js';
9
- import { b as keyEnter$1, c as keySpace } from './key-codes2.js';
17
+ import { r as ref } from './ref.js';
18
+ import { s as slotted } from './slotted.js';
10
19
  import { w as when } from './when.js';
20
+ import { c as classNames } from './class-names.js';
11
21
 
22
+ class _Combobox extends Listbox {
23
+ }
12
24
  /**
13
- * This set of exported strings reference https://developer.mozilla.org/en-US/docs/Web/Events
14
- * and should include all non-deprecated and non-experimental Standard events
25
+ * A form-associated base class for the {@link (Combobox:class)} component.
26
+ *
27
+ * @internal
15
28
  */
16
- const eventFocus = "focus";
17
- const eventFocusIn = "focusin";
18
- const eventFocusOut = "focusout";
19
- const eventKeyDown = "keydown";
29
+ class FormAssociatedCombobox extends FormAssociated(_Combobox) {
30
+ constructor() {
31
+ super(...arguments);
32
+ this.proxy = document.createElement("input");
33
+ }
34
+ }
20
35
 
21
36
  /**
22
- * Enumerates the data grid auto generated header options
23
- * default option generates a non-sticky header row
24
- *
37
+ * Autocomplete values for combobox.
25
38
  * @public
26
39
  */
27
- const GenerateHeaderOptions$1 = {
40
+ const ComboboxAutocomplete = {
41
+ inline: "inline",
42
+ list: "list",
43
+ both: "both",
28
44
  none: "none",
29
- default: "default",
30
- sticky: "sticky",
31
- };
32
- /**
33
- * Enumerates possible data grid cell types.
34
- *
35
- * @public
36
- */
37
- const DataGridCellTypes = {
38
- default: "default",
39
- columnHeader: "columnheader",
40
- rowHeader: "rowheader",
41
- };
42
- /**
43
- * Enumerates possible data grid row types
44
- *
45
- * @public
46
- */
47
- const DataGridRowTypes$1 = {
48
- default: "default",
49
- header: "header",
50
- stickyHeader: "sticky-header",
51
45
  };
52
46
 
53
47
  /**
54
- * A Data Grid Row Custom HTML Element.
48
+ * A Combobox Custom HTML Element.
49
+ * Implements the {@link https://w3c.github.io/aria-practices/#combobox | ARIA combobox }.
50
+ *
51
+ * @slot start - Content which can be provided before the input
52
+ * @slot end - Content which can be provided after the input
53
+ * @slot control - Used to replace the input element representing the combobox
54
+ * @slot indicator - The visual indicator representing the expanded state
55
+ * @slot - The default slot for the options
56
+ * @csspart control - The wrapper element containing the input area, including start and end
57
+ * @csspart selected-value - The input element representing the selected value
58
+ * @csspart indicator - The element wrapping the indicator slot
59
+ * @csspart listbox - The wrapper for the listbox slotted options
60
+ * @fires change - Fires a custom 'change' event when the value updates
55
61
  *
56
- * @fires row-focused - Fires a custom 'row-focused' event when focus is on an element (usually a cell or its contents) in the row
57
- * @slot - The default slot for custom cell elements
58
62
  * @public
59
63
  */
60
- let DataGridRow$1 = class DataGridRow extends FoundationElement {
64
+ let Combobox$1 = class Combobox extends FormAssociatedCombobox {
61
65
  constructor() {
62
66
  super(...arguments);
63
67
  /**
64
- * The type of row
68
+ * The internal value property.
65
69
  *
66
- * @public
67
- * @remarks
68
- * HTML Attribute: row-type
70
+ * @internal
69
71
  */
70
- this.rowType = DataGridRowTypes$1.default;
72
+ this._value = "";
71
73
  /**
72
- * The base data for this row
74
+ * The collection of currently filtered options.
73
75
  *
74
76
  * @public
75
77
  */
76
- this.rowData = null;
78
+ this.filteredOptions = [];
77
79
  /**
78
- * The column definitions of the row
80
+ * The current filter value.
79
81
  *
80
- * @public
82
+ * @internal
81
83
  */
82
- this.columnDefinitions = null;
84
+ this.filter = "";
83
85
  /**
84
- * Whether focus is on/in a cell within this row.
86
+ * The initial state of the position attribute.
85
87
  *
86
88
  * @internal
87
89
  */
88
- this.isActiveRow = false;
89
- this.cellsRepeatBehavior = null;
90
- this.cellsPlaceholder = null;
90
+ this.forcedPosition = false;
91
91
  /**
92
+ * The unique id for the internal listbox element.
93
+ *
92
94
  * @internal
93
95
  */
94
- this.focusColumnIndex = 0;
95
- this.refocusOnLoad = false;
96
- this.updateRowStyle = () => {
97
- this.style.gridTemplateColumns = this.gridTemplateColumns;
98
- };
96
+ this.listboxId = uniqueId("listbox-");
97
+ /**
98
+ * The max height for the listbox when opened.
99
+ *
100
+ * @internal
101
+ */
102
+ this.maxHeight = 0;
103
+ /**
104
+ * The open attribute.
105
+ *
106
+ * @public
107
+ * @remarks
108
+ * HTML Attribute: open
109
+ */
110
+ this.open = false;
99
111
  }
100
- gridTemplateColumnsChanged() {
101
- if (this.$fastController.isConnected) {
102
- this.updateRowStyle();
103
- }
112
+ /**
113
+ * Reset the element to its first selectable option when its parent form is reset.
114
+ *
115
+ * @internal
116
+ */
117
+ formResetCallback() {
118
+ super.formResetCallback();
119
+ this.setDefaultSelectedOption();
120
+ this.updateValue();
104
121
  }
105
- rowTypeChanged() {
106
- if (this.$fastController.isConnected) {
107
- this.updateItemTemplate();
108
- }
122
+ /** {@inheritDoc (FormAssociated:interface).validate} */
123
+ validate() {
124
+ super.validate(this.control);
109
125
  }
110
- rowDataChanged() {
111
- if (this.rowData !== null && this.isActiveRow) {
112
- this.refocusOnLoad = true;
113
- return;
114
- }
126
+ get isAutocompleteInline() {
127
+ return (this.autocomplete === ComboboxAutocomplete.inline || this.isAutocompleteBoth);
115
128
  }
116
- cellItemTemplateChanged() {
117
- this.updateItemTemplate();
129
+ get isAutocompleteList() {
130
+ return this.autocomplete === ComboboxAutocomplete.list || this.isAutocompleteBoth;
118
131
  }
119
- headerCellItemTemplateChanged() {
120
- this.updateItemTemplate();
132
+ get isAutocompleteBoth() {
133
+ return this.autocomplete === ComboboxAutocomplete.both;
121
134
  }
122
135
  /**
136
+ * Sets focus and synchronize ARIA attributes when the open property changes.
137
+ *
138
+ * @param prev - the previous open value
139
+ * @param next - the current open value
140
+ *
123
141
  * @internal
124
142
  */
125
- connectedCallback() {
126
- super.connectedCallback();
127
- // note that row elements can be reused with a different data object
128
- // as the parent grid's repeat behavior reacts to changes in the data set.
129
- if (this.cellsRepeatBehavior === null) {
130
- this.cellsPlaceholder = document.createComment("");
131
- this.appendChild(this.cellsPlaceholder);
132
- this.updateItemTemplate();
133
- this.cellsRepeatBehavior = new RepeatDirective(x => x.columnDefinitions, x => x.activeCellItemTemplate, { positioning: true }).createBehavior(this.cellsPlaceholder);
134
- /* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */
135
- this.$fastController.addBehaviors([this.cellsRepeatBehavior]);
136
- }
137
- this.addEventListener("cell-focused", this.handleCellFocus);
138
- this.addEventListener(eventFocusOut, this.handleFocusout);
139
- this.addEventListener(eventKeyDown, this.handleKeydown);
140
- this.updateRowStyle();
141
- if (this.refocusOnLoad) {
142
- // if focus was on the row when data changed try to refocus on same cell
143
- this.refocusOnLoad = false;
144
- if (this.cellElements.length > this.focusColumnIndex) {
145
- this.cellElements[this.focusColumnIndex].focus();
146
- }
143
+ openChanged() {
144
+ if (this.open) {
145
+ this.ariaControls = this.listboxId;
146
+ this.ariaExpanded = "true";
147
+ this.setPositioning();
148
+ this.focusAndScrollOptionIntoView();
149
+ // focus is directed to the element when `open` is changed programmatically
150
+ DOM.queueUpdate(() => this.focus());
151
+ return;
147
152
  }
153
+ this.ariaControls = "";
154
+ this.ariaExpanded = "false";
148
155
  }
149
156
  /**
150
- * @internal
157
+ * The list of options.
158
+ *
159
+ * @public
160
+ * @remarks
161
+ * Overrides `Listbox.options`.
151
162
  */
152
- disconnectedCallback() {
153
- super.disconnectedCallback();
154
- this.removeEventListener("cell-focused", this.handleCellFocus);
155
- this.removeEventListener(eventFocusOut, this.handleFocusout);
156
- this.removeEventListener(eventKeyDown, this.handleKeydown);
157
- }
158
- handleFocusout(e) {
159
- if (!this.contains(e.target)) {
160
- this.isActiveRow = false;
161
- this.focusColumnIndex = 0;
162
- }
163
- }
164
- handleCellFocus(e) {
165
- this.isActiveRow = true;
166
- this.focusColumnIndex = this.cellElements.indexOf(e.target);
167
- this.$emit("row-focused", this);
163
+ get options() {
164
+ Observable.track(this, "options");
165
+ return this.filteredOptions.length ? this.filteredOptions : this._options;
168
166
  }
169
- handleKeydown(e) {
170
- if (e.defaultPrevented) {
171
- return;
172
- }
173
- let newFocusColumnIndex = 0;
174
- switch (e.key) {
175
- case keyArrowLeft:
176
- // focus left one cell
177
- newFocusColumnIndex = Math.max(0, this.focusColumnIndex - 1);
178
- this.cellElements[newFocusColumnIndex].focus();
179
- e.preventDefault();
180
- break;
181
- case keyArrowRight:
182
- // focus right one cell
183
- newFocusColumnIndex = Math.min(this.cellElements.length - 1, this.focusColumnIndex + 1);
184
- this.cellElements[newFocusColumnIndex].focus();
185
- e.preventDefault();
186
- break;
187
- case keyHome:
188
- if (!e.ctrlKey) {
189
- this.cellElements[0].focus();
190
- e.preventDefault();
191
- }
192
- break;
193
- case keyEnd:
194
- if (!e.ctrlKey) {
195
- // focus last cell of the row
196
- this.cellElements[this.cellElements.length - 1].focus();
197
- e.preventDefault();
198
- }
199
- break;
200
- }
201
- }
202
- updateItemTemplate() {
203
- this.activeCellItemTemplate =
204
- this.rowType === DataGridRowTypes$1.default &&
205
- this.cellItemTemplate !== undefined
206
- ? this.cellItemTemplate
207
- : this.rowType === DataGridRowTypes$1.default &&
208
- this.cellItemTemplate === undefined
209
- ? this.defaultCellItemTemplate
210
- : this.headerCellItemTemplate !== undefined
211
- ? this.headerCellItemTemplate
212
- : this.defaultHeaderCellItemTemplate;
213
- }
214
- };
215
- __decorate([
216
- attr({ attribute: "grid-template-columns" })
217
- ], DataGridRow$1.prototype, "gridTemplateColumns", void 0);
218
- __decorate([
219
- attr({ attribute: "row-type" })
220
- ], DataGridRow$1.prototype, "rowType", void 0);
221
- __decorate([
222
- observable
223
- ], DataGridRow$1.prototype, "rowData", void 0);
224
- __decorate([
225
- observable
226
- ], DataGridRow$1.prototype, "columnDefinitions", void 0);
227
- __decorate([
228
- observable
229
- ], DataGridRow$1.prototype, "cellItemTemplate", void 0);
230
- __decorate([
231
- observable
232
- ], DataGridRow$1.prototype, "headerCellItemTemplate", void 0);
233
- __decorate([
234
- observable
235
- ], DataGridRow$1.prototype, "rowIndex", void 0);
236
- __decorate([
237
- observable
238
- ], DataGridRow$1.prototype, "isActiveRow", void 0);
239
- __decorate([
240
- observable
241
- ], DataGridRow$1.prototype, "activeCellItemTemplate", void 0);
242
- __decorate([
243
- observable
244
- ], DataGridRow$1.prototype, "defaultCellItemTemplate", void 0);
245
- __decorate([
246
- observable
247
- ], DataGridRow$1.prototype, "defaultHeaderCellItemTemplate", void 0);
248
- __decorate([
249
- observable
250
- ], DataGridRow$1.prototype, "cellElements", void 0);
251
-
252
- /**
253
- * A Data Grid Custom HTML Element.
254
- *
255
- * @slot - The default slot for custom row elements
256
- * @public
257
- */
258
- let DataGrid$1 = class DataGrid extends FoundationElement {
259
- constructor() {
260
- super();
261
- /**
262
- * When true the component will not add itself to the tab queue.
263
- * Default is false.
264
- *
265
- * @public
266
- * @remarks
267
- * HTML Attribute: no-tabbing
268
- */
269
- this.noTabbing = false;
270
- /**
271
- * Whether the grid should automatically generate a header row and its type
272
- *
273
- * @public
274
- * @remarks
275
- * HTML Attribute: generate-header
276
- */
277
- this.generateHeader = GenerateHeaderOptions$1.default;
278
- /**
279
- * The data being displayed in the grid
280
- *
281
- * @public
282
- */
283
- this.rowsData = [];
284
- /**
285
- * The column definitions of the grid
286
- *
287
- * @public
288
- */
289
- this.columnDefinitions = null;
290
- /**
291
- * The index of the row that will receive focus the next time the
292
- * grid is focused. This value changes as focus moves to different
293
- * rows within the grid. Changing this value when focus is already
294
- * within the grid moves focus to the specified row.
295
- *
296
- * @public
297
- */
298
- this.focusRowIndex = 0;
299
- /**
300
- * The index of the column that will receive focus the next time the
301
- * grid is focused. This value changes as focus moves to different rows
302
- * within the grid. Changing this value when focus is already within
303
- * the grid moves focus to the specified column.
304
- *
305
- * @public
306
- */
307
- this.focusColumnIndex = 0;
308
- this.rowsPlaceholder = null;
309
- this.generatedHeader = null;
310
- this.isUpdatingFocus = false;
311
- this.pendingFocusUpdate = false;
312
- this.rowindexUpdateQueued = false;
313
- this.columnDefinitionsStale = true;
314
- this.generatedGridTemplateColumns = "";
315
- this.focusOnCell = (rowIndex, columnIndex, scrollIntoView) => {
316
- if (this.rowElements.length === 0) {
317
- this.focusRowIndex = 0;
318
- this.focusColumnIndex = 0;
319
- return;
320
- }
321
- const focusRowIndex = Math.max(0, Math.min(this.rowElements.length - 1, rowIndex));
322
- const focusRow = this.rowElements[focusRowIndex];
323
- const cells = focusRow.querySelectorAll('[role="cell"], [role="gridcell"], [role="columnheader"], [role="rowheader"]');
324
- const focusColumnIndex = Math.max(0, Math.min(cells.length - 1, columnIndex));
325
- const focusTarget = cells[focusColumnIndex];
326
- if (scrollIntoView &&
327
- this.scrollHeight !== this.clientHeight &&
328
- ((focusRowIndex < this.focusRowIndex && this.scrollTop > 0) ||
329
- (focusRowIndex > this.focusRowIndex &&
330
- this.scrollTop < this.scrollHeight - this.clientHeight))) {
331
- focusTarget.scrollIntoView({ block: "center", inline: "center" });
332
- }
333
- focusTarget.focus();
334
- };
335
- this.onChildListChange = (mutations,
336
- /* eslint-disable-next-line @typescript-eslint/no-unused-vars */
337
- observer) => {
338
- if (mutations && mutations.length) {
339
- mutations.forEach((mutation) => {
340
- mutation.addedNodes.forEach((newNode) => {
341
- if (newNode.nodeType === 1 &&
342
- newNode.getAttribute("role") === "row") {
343
- newNode.columnDefinitions = this.columnDefinitions;
344
- }
345
- });
346
- });
347
- this.queueRowIndexUpdate();
348
- }
349
- };
350
- this.queueRowIndexUpdate = () => {
351
- if (!this.rowindexUpdateQueued) {
352
- this.rowindexUpdateQueued = true;
353
- DOM.queueUpdate(this.updateRowIndexes);
354
- }
355
- };
356
- this.updateRowIndexes = () => {
357
- let newGridTemplateColumns = this.gridTemplateColumns;
358
- if (newGridTemplateColumns === undefined) {
359
- // try to generate columns based on manual rows
360
- if (this.generatedGridTemplateColumns === "" && this.rowElements.length > 0) {
361
- const firstRow = this.rowElements[0];
362
- this.generatedGridTemplateColumns = new Array(firstRow.cellElements.length)
363
- .fill("1fr")
364
- .join(" ");
365
- }
366
- newGridTemplateColumns = this.generatedGridTemplateColumns;
367
- }
368
- this.rowElements.forEach((element, index) => {
369
- const thisRow = element;
370
- thisRow.rowIndex = index;
371
- thisRow.gridTemplateColumns = newGridTemplateColumns;
372
- if (this.columnDefinitionsStale) {
373
- thisRow.columnDefinitions = this.columnDefinitions;
374
- }
375
- });
376
- this.rowindexUpdateQueued = false;
377
- this.columnDefinitionsStale = false;
378
- };
167
+ set options(value) {
168
+ this._options = value;
169
+ Observable.notify(this, "options");
379
170
  }
380
171
  /**
381
- * generates a gridTemplateColumns based on columndata array
172
+ * Updates the placeholder on the proxy element.
173
+ * @internal
382
174
  */
383
- static generateTemplateColumns(columnDefinitions) {
384
- let templateColumns = "";
385
- columnDefinitions.forEach((column) => {
386
- templateColumns = `${templateColumns}${templateColumns === "" ? "" : " "}${"1fr"}`;
387
- });
388
- return templateColumns;
389
- }
390
- noTabbingChanged() {
391
- if (this.$fastController.isConnected) {
392
- if (this.noTabbing) {
393
- this.setAttribute("tabIndex", "-1");
394
- }
395
- else {
396
- this.setAttribute("tabIndex", this.contains(document.activeElement) ||
397
- this === document.activeElement
398
- ? "-1"
399
- : "0");
400
- }
401
- }
402
- }
403
- generateHeaderChanged() {
404
- if (this.$fastController.isConnected) {
405
- this.toggleGeneratedHeader();
175
+ placeholderChanged() {
176
+ if (this.proxy instanceof HTMLInputElement) {
177
+ this.proxy.placeholder = this.placeholder;
406
178
  }
407
179
  }
408
- gridTemplateColumnsChanged() {
409
- if (this.$fastController.isConnected) {
410
- this.updateRowIndexes();
411
- }
180
+ positionChanged(prev, next) {
181
+ this.positionAttribute = next;
182
+ this.setPositioning();
412
183
  }
413
- rowsDataChanged() {
414
- if (this.columnDefinitions === null && this.rowsData.length > 0) {
415
- this.columnDefinitions = DataGrid.generateColumns(this.rowsData[0]);
416
- }
417
- if (this.$fastController.isConnected) {
418
- this.toggleGeneratedHeader();
184
+ /**
185
+ * The value property.
186
+ *
187
+ * @public
188
+ */
189
+ get value() {
190
+ Observable.track(this, "value");
191
+ return this._value;
192
+ }
193
+ set value(next) {
194
+ var _a, _b, _c;
195
+ const prev = `${this._value}`;
196
+ if (this.$fastController.isConnected && this.options) {
197
+ const selectedIndex = this.options.findIndex(el => el.text.toLowerCase() === next.toLowerCase());
198
+ const prevSelectedValue = (_a = this.options[this.selectedIndex]) === null || _a === void 0 ? void 0 : _a.text;
199
+ const nextSelectedValue = (_b = this.options[selectedIndex]) === null || _b === void 0 ? void 0 : _b.text;
200
+ this.selectedIndex =
201
+ prevSelectedValue !== nextSelectedValue
202
+ ? selectedIndex
203
+ : this.selectedIndex;
204
+ next = ((_c = this.firstSelectedOption) === null || _c === void 0 ? void 0 : _c.text) || next;
205
+ }
206
+ if (prev !== next) {
207
+ this._value = next;
208
+ super.valueChanged(prev, next);
209
+ Observable.notify(this, "value");
419
210
  }
420
211
  }
421
- columnDefinitionsChanged() {
422
- if (this.columnDefinitions === null) {
423
- this.generatedGridTemplateColumns = "";
212
+ /**
213
+ * Handle opening and closing the listbox when the combobox is clicked.
214
+ *
215
+ * @param e - the mouse event
216
+ * @internal
217
+ */
218
+ clickHandler(e) {
219
+ if (this.disabled) {
424
220
  return;
425
221
  }
426
- this.generatedGridTemplateColumns = DataGrid.generateTemplateColumns(this.columnDefinitions);
427
- if (this.$fastController.isConnected) {
428
- this.columnDefinitionsStale = true;
429
- this.queueRowIndexUpdate();
430
- }
431
- }
432
- headerCellItemTemplateChanged() {
433
- if (this.$fastController.isConnected) {
434
- if (this.generatedHeader !== null) {
435
- this.generatedHeader.headerCellItemTemplate = this.headerCellItemTemplate;
222
+ if (this.open) {
223
+ const captured = e.target.closest(`option,[role=option]`);
224
+ if (!captured || captured.disabled) {
225
+ return;
436
226
  }
227
+ this.selectedOptions = [captured];
228
+ this.control.value = captured.text;
229
+ this.clearSelectionRange();
230
+ this.updateValue(true);
437
231
  }
438
- }
439
- focusRowIndexChanged() {
440
- if (this.$fastController.isConnected) {
441
- this.queueFocusUpdate();
232
+ this.open = !this.open;
233
+ if (this.open) {
234
+ this.control.focus();
442
235
  }
236
+ return true;
443
237
  }
444
- focusColumnIndexChanged() {
445
- if (this.$fastController.isConnected) {
446
- this.queueFocusUpdate();
238
+ connectedCallback() {
239
+ super.connectedCallback();
240
+ this.forcedPosition = !!this.positionAttribute;
241
+ if (this.value) {
242
+ this.initialValue = this.value;
447
243
  }
448
244
  }
449
245
  /**
246
+ * Synchronize the `aria-disabled` property when the `disabled` property changes.
247
+ *
248
+ * @param prev - The previous disabled value
249
+ * @param next - The next disabled value
250
+ *
450
251
  * @internal
451
252
  */
452
- connectedCallback() {
453
- super.connectedCallback();
454
- if (this.rowItemTemplate === undefined) {
455
- this.rowItemTemplate = this.defaultRowItemTemplate;
253
+ disabledChanged(prev, next) {
254
+ if (super.disabledChanged) {
255
+ super.disabledChanged(prev, next);
456
256
  }
457
- this.rowsPlaceholder = document.createComment("");
458
- this.appendChild(this.rowsPlaceholder);
459
- this.toggleGeneratedHeader();
460
- this.rowsRepeatBehavior = new RepeatDirective(x => x.rowsData, x => x.rowItemTemplate, { positioning: true }).createBehavior(this.rowsPlaceholder);
461
- /* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */
462
- this.$fastController.addBehaviors([this.rowsRepeatBehavior]);
463
- this.addEventListener("row-focused", this.handleRowFocus);
464
- this.addEventListener(eventFocus, this.handleFocus);
465
- this.addEventListener(eventKeyDown, this.handleKeydown);
466
- this.addEventListener(eventFocusOut, this.handleFocusOut);
467
- this.observer = new MutationObserver(this.onChildListChange);
468
- // only observe if nodes are added or removed
469
- this.observer.observe(this, { childList: true });
470
- if (this.noTabbing) {
471
- this.setAttribute("tabindex", "-1");
472
- }
473
- DOM.queueUpdate(this.queueRowIndexUpdate);
257
+ this.ariaDisabled = this.disabled ? "true" : "false";
474
258
  }
475
259
  /**
476
- * @internal
260
+ * Filter available options by text value.
261
+ *
262
+ * @public
477
263
  */
478
- disconnectedCallback() {
479
- super.disconnectedCallback();
480
- this.removeEventListener("row-focused", this.handleRowFocus);
481
- this.removeEventListener(eventFocus, this.handleFocus);
482
- this.removeEventListener(eventKeyDown, this.handleKeydown);
483
- this.removeEventListener(eventFocusOut, this.handleFocusOut);
484
- // disconnect observer
485
- this.observer.disconnect();
486
- this.rowsPlaceholder = null;
487
- this.generatedHeader = null;
264
+ filterOptions() {
265
+ if (!this.autocomplete || this.autocomplete === ComboboxAutocomplete.none) {
266
+ this.filter = "";
267
+ }
268
+ const filter = this.filter.toLowerCase();
269
+ this.filteredOptions = this._options.filter(o => o.text.toLowerCase().startsWith(this.filter.toLowerCase()));
270
+ if (this.isAutocompleteList) {
271
+ if (!this.filteredOptions.length && !filter) {
272
+ this.filteredOptions = this._options;
273
+ }
274
+ this._options.forEach(o => {
275
+ o.hidden = !this.filteredOptions.includes(o);
276
+ });
277
+ }
488
278
  }
489
279
  /**
280
+ * Focus the control and scroll the first selected option into view.
281
+ *
490
282
  * @internal
283
+ * @remarks
284
+ * Overrides: `Listbox.focusAndScrollOptionIntoView`
491
285
  */
492
- handleRowFocus(e) {
493
- this.isUpdatingFocus = true;
494
- const focusRow = e.target;
495
- this.focusRowIndex = this.rowElements.indexOf(focusRow);
496
- this.focusColumnIndex = focusRow.focusColumnIndex;
497
- this.setAttribute("tabIndex", "-1");
498
- this.isUpdatingFocus = false;
286
+ focusAndScrollOptionIntoView() {
287
+ if (this.contains(document.activeElement)) {
288
+ this.control.focus();
289
+ if (this.firstSelectedOption) {
290
+ requestAnimationFrame(() => {
291
+ var _a;
292
+ (_a = this.firstSelectedOption) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ block: "nearest" });
293
+ });
294
+ }
295
+ }
499
296
  }
500
297
  /**
298
+ * Handle focus state when the element or its children lose focus.
299
+ *
300
+ * @param e - The focus event
501
301
  * @internal
502
302
  */
503
- handleFocus(e) {
504
- this.focusOnCell(this.focusRowIndex, this.focusColumnIndex, true);
303
+ focusoutHandler(e) {
304
+ this.syncValue();
305
+ if (!this.open) {
306
+ return true;
307
+ }
308
+ const focusTarget = e.relatedTarget;
309
+ if (this.isSameNode(focusTarget)) {
310
+ this.focus();
311
+ return;
312
+ }
313
+ if (!this.options || !this.options.includes(focusTarget)) {
314
+ this.open = false;
315
+ }
505
316
  }
506
317
  /**
318
+ * Handle content changes on the control input.
319
+ *
320
+ * @param e - the input event
507
321
  * @internal
508
322
  */
509
- handleFocusOut(e) {
510
- if (e.relatedTarget === null || !this.contains(e.relatedTarget)) {
511
- this.setAttribute("tabIndex", this.noTabbing ? "-1" : "0");
323
+ inputHandler(e) {
324
+ this.filter = this.control.value;
325
+ this.filterOptions();
326
+ if (!this.isAutocompleteInline) {
327
+ this.selectedIndex = this.options
328
+ .map(option => option.text)
329
+ .indexOf(this.control.value);
330
+ }
331
+ if (e.inputType.includes("deleteContent") || !this.filter.length) {
332
+ return true;
333
+ }
334
+ if (this.isAutocompleteList && !this.open) {
335
+ this.open = true;
336
+ }
337
+ if (this.isAutocompleteInline) {
338
+ if (this.filteredOptions.length) {
339
+ this.selectedOptions = [this.filteredOptions[0]];
340
+ this.selectedIndex = this.options.indexOf(this.firstSelectedOption);
341
+ this.setInlineSelection();
342
+ }
343
+ else {
344
+ this.selectedIndex = -1;
345
+ }
512
346
  }
347
+ return;
513
348
  }
514
349
  /**
350
+ * Handle keydown actions for listbox navigation.
351
+ *
352
+ * @param e - the keyboard event
515
353
  * @internal
516
354
  */
517
- handleKeydown(e) {
518
- if (e.defaultPrevented) {
519
- return;
520
- }
521
- let newFocusRowIndex;
522
- const maxIndex = this.rowElements.length - 1;
523
- const currentGridBottom = this.offsetHeight + this.scrollTop;
524
- const lastRow = this.rowElements[maxIndex];
525
- switch (e.key) {
526
- case keyArrowUp:
527
- e.preventDefault();
528
- // focus up one row
529
- this.focusOnCell(this.focusRowIndex - 1, this.focusColumnIndex, true);
530
- break;
531
- case keyArrowDown:
532
- e.preventDefault();
533
- // focus down one row
534
- this.focusOnCell(this.focusRowIndex + 1, this.focusColumnIndex, true);
535
- break;
536
- case keyPageUp:
537
- e.preventDefault();
538
- if (this.rowElements.length === 0) {
539
- this.focusOnCell(0, 0, false);
540
- break;
355
+ keydownHandler(e) {
356
+ const key = e.key;
357
+ if (e.ctrlKey || e.shiftKey) {
358
+ return true;
359
+ }
360
+ switch (key) {
361
+ case "Enter": {
362
+ this.syncValue();
363
+ if (this.isAutocompleteInline) {
364
+ this.filter = this.value;
541
365
  }
542
- if (this.focusRowIndex === 0) {
543
- this.focusOnCell(0, this.focusColumnIndex, false);
544
- return;
366
+ this.open = false;
367
+ this.clearSelectionRange();
368
+ break;
369
+ }
370
+ case "Escape": {
371
+ if (!this.isAutocompleteInline) {
372
+ this.selectedIndex = -1;
545
373
  }
546
- newFocusRowIndex = this.focusRowIndex - 1;
547
- for (newFocusRowIndex; newFocusRowIndex >= 0; newFocusRowIndex--) {
548
- const thisRow = this.rowElements[newFocusRowIndex];
549
- if (thisRow.offsetTop < this.scrollTop) {
550
- this.scrollTop =
551
- thisRow.offsetTop + thisRow.clientHeight - this.clientHeight;
552
- break;
553
- }
374
+ if (this.open) {
375
+ this.open = false;
376
+ break;
554
377
  }
555
- this.focusOnCell(newFocusRowIndex, this.focusColumnIndex, false);
378
+ this.value = "";
379
+ this.control.value = "";
380
+ this.filter = "";
381
+ this.filterOptions();
556
382
  break;
557
- case keyPageDown:
383
+ }
384
+ case "Tab": {
385
+ this.setInputToSelection();
386
+ if (!this.open) {
387
+ return true;
388
+ }
558
389
  e.preventDefault();
559
- if (this.rowElements.length === 0) {
560
- this.focusOnCell(0, 0, false);
390
+ this.open = false;
391
+ break;
392
+ }
393
+ case "ArrowUp":
394
+ case "ArrowDown": {
395
+ this.filterOptions();
396
+ if (!this.open) {
397
+ this.open = true;
561
398
  break;
562
399
  }
563
- // focus down one "page"
564
- if (this.focusRowIndex >= maxIndex ||
565
- lastRow.offsetTop + lastRow.offsetHeight <= currentGridBottom) {
566
- this.focusOnCell(maxIndex, this.focusColumnIndex, false);
567
- return;
400
+ if (this.filteredOptions.length > 0) {
401
+ super.keydownHandler(e);
568
402
  }
569
- newFocusRowIndex = this.focusRowIndex + 1;
570
- for (newFocusRowIndex; newFocusRowIndex <= maxIndex; newFocusRowIndex++) {
571
- const thisRow = this.rowElements[newFocusRowIndex];
572
- if (thisRow.offsetTop + thisRow.offsetHeight > currentGridBottom) {
573
- let stickyHeaderOffset = 0;
574
- if (this.generateHeader === GenerateHeaderOptions$1.sticky &&
575
- this.generatedHeader !== null) {
576
- stickyHeaderOffset = this.generatedHeader.clientHeight;
577
- }
578
- this.scrollTop = thisRow.offsetTop - stickyHeaderOffset;
579
- break;
580
- }
581
- }
582
- this.focusOnCell(newFocusRowIndex, this.focusColumnIndex, false);
583
- break;
584
- case keyHome:
585
- if (e.ctrlKey) {
586
- e.preventDefault();
587
- // focus first cell of first row
588
- this.focusOnCell(0, 0, true);
589
- }
590
- break;
591
- case keyEnd:
592
- if (e.ctrlKey && this.columnDefinitions !== null) {
593
- e.preventDefault();
594
- // focus last cell of last row
595
- this.focusOnCell(this.rowElements.length - 1, this.columnDefinitions.length - 1, true);
403
+ if (this.isAutocompleteInline) {
404
+ this.setInlineSelection();
596
405
  }
597
406
  break;
407
+ }
408
+ default: {
409
+ return true;
410
+ }
598
411
  }
599
412
  }
600
- queueFocusUpdate() {
601
- if (this.isUpdatingFocus &&
602
- (this.contains(document.activeElement) || this === document.activeElement)) {
603
- return;
604
- }
605
- if (this.pendingFocusUpdate === false) {
606
- this.pendingFocusUpdate = true;
607
- DOM.queueUpdate(() => this.updateFocus());
413
+ /**
414
+ * Handle keyup actions for value input and text field manipulations.
415
+ *
416
+ * @param e - the keyboard event
417
+ * @internal
418
+ */
419
+ keyupHandler(e) {
420
+ const key = e.key;
421
+ switch (key) {
422
+ case "ArrowLeft":
423
+ case "ArrowRight":
424
+ case "Backspace":
425
+ case "Delete":
426
+ case "Home":
427
+ case "End": {
428
+ this.filter = this.control.value;
429
+ this.selectedIndex = -1;
430
+ this.filterOptions();
431
+ break;
432
+ }
608
433
  }
609
434
  }
610
- updateFocus() {
611
- this.pendingFocusUpdate = false;
612
- this.focusOnCell(this.focusRowIndex, this.focusColumnIndex, true);
613
- }
614
- toggleGeneratedHeader() {
615
- if (this.generatedHeader !== null) {
616
- this.removeChild(this.generatedHeader);
617
- this.generatedHeader = null;
618
- }
619
- if (this.generateHeader !== GenerateHeaderOptions$1.none &&
620
- this.rowsData.length > 0) {
621
- const generatedHeaderElement = document.createElement(this.rowElementTag);
622
- this.generatedHeader = generatedHeaderElement;
623
- this.generatedHeader.columnDefinitions = this.columnDefinitions;
624
- this.generatedHeader.gridTemplateColumns = this.gridTemplateColumns;
625
- this.generatedHeader.rowType =
626
- this.generateHeader === GenerateHeaderOptions$1.sticky
627
- ? DataGridRowTypes$1.stickyHeader
628
- : DataGridRowTypes$1.header;
629
- if (this.firstChild !== null || this.rowsPlaceholder !== null) {
630
- this.insertBefore(generatedHeaderElement, this.firstChild !== null ? this.firstChild : this.rowsPlaceholder);
435
+ /**
436
+ * Ensure that the selectedIndex is within the current allowable filtered range.
437
+ *
438
+ * @param prev - the previous selected index value
439
+ * @param next - the current selected index value
440
+ *
441
+ * @internal
442
+ */
443
+ selectedIndexChanged(prev, next) {
444
+ if (this.$fastController.isConnected) {
445
+ next = limit(-1, this.options.length - 1, next);
446
+ // we only want to call the super method when the selectedIndex is in range
447
+ if (next !== this.selectedIndex) {
448
+ this.selectedIndex = next;
449
+ return;
631
450
  }
632
- return;
451
+ super.selectedIndexChanged(prev, next);
633
452
  }
634
453
  }
635
- };
636
- /**
637
- * generates a basic column definition by examining sample row data
638
- */
639
- DataGrid$1.generateColumns = (row) => {
640
- return Object.getOwnPropertyNames(row).map((property, index) => {
641
- return {
642
- columnDataKey: property,
643
- gridColumn: `${index}`,
644
- };
645
- });
646
- };
647
- __decorate([
648
- attr({ attribute: "no-tabbing", mode: "boolean" })
649
- ], DataGrid$1.prototype, "noTabbing", void 0);
650
- __decorate([
651
- attr({ attribute: "generate-header" })
652
- ], DataGrid$1.prototype, "generateHeader", void 0);
653
- __decorate([
654
- attr({ attribute: "grid-template-columns" })
655
- ], DataGrid$1.prototype, "gridTemplateColumns", void 0);
656
- __decorate([
657
- observable
658
- ], DataGrid$1.prototype, "rowsData", void 0);
659
- __decorate([
660
- observable
661
- ], DataGrid$1.prototype, "columnDefinitions", void 0);
662
- __decorate([
663
- observable
664
- ], DataGrid$1.prototype, "rowItemTemplate", void 0);
665
- __decorate([
666
- observable
667
- ], DataGrid$1.prototype, "cellItemTemplate", void 0);
668
- __decorate([
669
- observable
670
- ], DataGrid$1.prototype, "headerCellItemTemplate", void 0);
671
- __decorate([
672
- observable
673
- ], DataGrid$1.prototype, "focusRowIndex", void 0);
674
- __decorate([
675
- observable
676
- ], DataGrid$1.prototype, "focusColumnIndex", void 0);
677
- __decorate([
678
- observable
679
- ], DataGrid$1.prototype, "defaultRowItemTemplate", void 0);
680
- __decorate([
681
- observable
682
- ], DataGrid$1.prototype, "rowElementTag", void 0);
683
- __decorate([
684
- observable
685
- ], DataGrid$1.prototype, "rowElements", void 0);
686
-
687
- const defaultCellContentsTemplate = html `
688
- <template>
689
- ${x => x.rowData === null ||
690
- x.columnDefinition === null ||
691
- x.columnDefinition.columnDataKey === null
692
- ? null
693
- : x.rowData[x.columnDefinition.columnDataKey]}
694
- </template>
695
- `;
696
- const defaultHeaderCellContentsTemplate = html `
697
- <template>
698
- ${x => x.columnDefinition === null
699
- ? null
700
- : x.columnDefinition.title === undefined
701
- ? x.columnDefinition.columnDataKey
702
- : x.columnDefinition.title}
703
- </template>
704
- `;
705
- /**
706
- * A Data Grid Cell Custom HTML Element.
707
- *
708
- * @fires cell-focused - Fires a custom 'cell-focused' event when focus is on the cell or its contents
709
- * @slot - The default slot for cell contents. The "cell contents template" renders here.
710
- * @public
711
- */
712
- let DataGridCell$1 = class DataGridCell extends FoundationElement {
713
- constructor() {
714
- super(...arguments);
715
- /**
716
- * The type of cell
717
- *
718
- * @public
719
- * @remarks
720
- * HTML Attribute: cell-type
721
- */
722
- this.cellType = DataGridCellTypes.default;
723
- /**
724
- * The base data for the parent row
725
- *
726
- * @public
727
- */
728
- this.rowData = null;
729
- /**
730
- * The base data for the column
731
- *
732
- * @public
733
- */
734
- this.columnDefinition = null;
735
- this.isActiveCell = false;
736
- this.customCellView = null;
737
- this.updateCellStyle = () => {
738
- this.style.gridColumn = this.gridColumn;
739
- };
740
- }
741
- cellTypeChanged() {
742
- if (this.$fastController.isConnected) {
743
- this.updateCellView();
454
+ /**
455
+ * Move focus to the previous selectable option.
456
+ *
457
+ * @internal
458
+ * @remarks
459
+ * Overrides `Listbox.selectPreviousOption`
460
+ */
461
+ selectPreviousOption() {
462
+ if (!this.disabled && this.selectedIndex >= 0) {
463
+ this.selectedIndex = this.selectedIndex - 1;
744
464
  }
745
465
  }
746
- gridColumnChanged() {
747
- if (this.$fastController.isConnected) {
748
- this.updateCellStyle();
466
+ /**
467
+ * Set the default selected options at initialization or reset.
468
+ *
469
+ * @internal
470
+ * @remarks
471
+ * Overrides `Listbox.setDefaultSelectedOption`
472
+ */
473
+ setDefaultSelectedOption() {
474
+ if (this.$fastController.isConnected && this.options) {
475
+ const selectedIndex = this.options.findIndex(el => el.getAttribute("selected") !== null || el.selected);
476
+ this.selectedIndex = selectedIndex;
477
+ if (!this.dirtyValue && this.firstSelectedOption) {
478
+ this.value = this.firstSelectedOption.text;
479
+ }
480
+ this.setSelectedOptions();
749
481
  }
750
482
  }
751
- columnDefinitionChanged(oldValue, newValue) {
752
- if (this.$fastController.isConnected) {
753
- this.updateCellView();
483
+ /**
484
+ * Focus and set the content of the control based on the first selected option.
485
+ *
486
+ * @internal
487
+ */
488
+ setInputToSelection() {
489
+ if (this.firstSelectedOption) {
490
+ this.control.value = this.firstSelectedOption.text;
491
+ this.control.focus();
754
492
  }
755
493
  }
756
494
  /**
495
+ * Focus, set and select the content of the control based on the first selected option.
496
+ *
757
497
  * @internal
758
498
  */
759
- connectedCallback() {
760
- var _a;
761
- super.connectedCallback();
762
- this.addEventListener(eventFocusIn, this.handleFocusin);
763
- this.addEventListener(eventFocusOut, this.handleFocusout);
764
- this.addEventListener(eventKeyDown, this.handleKeydown);
765
- this.style.gridColumn = `${((_a = this.columnDefinition) === null || _a === void 0 ? void 0 : _a.gridColumn) === undefined
766
- ? 0
767
- : this.columnDefinition.gridColumn}`;
768
- this.updateCellView();
769
- this.updateCellStyle();
499
+ setInlineSelection() {
500
+ if (this.firstSelectedOption) {
501
+ this.setInputToSelection();
502
+ this.control.setSelectionRange(this.filter.length, this.control.value.length, "backward");
503
+ }
770
504
  }
771
505
  /**
506
+ * Determines if a value update should involve emitting a change event, then updates the value.
507
+ *
772
508
  * @internal
773
509
  */
774
- disconnectedCallback() {
775
- super.disconnectedCallback();
776
- this.removeEventListener(eventFocusIn, this.handleFocusin);
777
- this.removeEventListener(eventFocusOut, this.handleFocusout);
778
- this.removeEventListener(eventKeyDown, this.handleKeydown);
779
- this.disconnectCellView();
510
+ syncValue() {
511
+ var _a;
512
+ const newValue = this.selectedIndex > -1 ? (_a = this.firstSelectedOption) === null || _a === void 0 ? void 0 : _a.text : this.control.value;
513
+ this.updateValue(this.value !== newValue);
780
514
  }
781
- handleFocusin(e) {
782
- if (this.isActiveCell) {
783
- return;
784
- }
785
- this.isActiveCell = true;
786
- switch (this.cellType) {
787
- case DataGridCellTypes.columnHeader:
788
- if (this.columnDefinition !== null &&
789
- this.columnDefinition.headerCellInternalFocusQueue !== true &&
790
- typeof this.columnDefinition.headerCellFocusTargetCallback ===
791
- "function") {
792
- // move focus to the focus target
793
- const focusTarget = this.columnDefinition.headerCellFocusTargetCallback(this);
794
- if (focusTarget !== null) {
795
- focusTarget.focus();
796
- }
797
- }
798
- break;
799
- default:
800
- if (this.columnDefinition !== null &&
801
- this.columnDefinition.cellInternalFocusQueue !== true &&
802
- typeof this.columnDefinition.cellFocusTargetCallback === "function") {
803
- // move focus to the focus target
804
- const focusTarget = this.columnDefinition.cellFocusTargetCallback(this);
805
- if (focusTarget !== null) {
806
- focusTarget.focus();
807
- }
808
- }
809
- break;
810
- }
811
- this.$emit("cell-focused", this);
515
+ /**
516
+ * Calculate and apply listbox positioning based on available viewport space.
517
+ *
518
+ * @param force - direction to force the listbox to display
519
+ * @public
520
+ */
521
+ setPositioning() {
522
+ const currentBox = this.getBoundingClientRect();
523
+ const viewportHeight = window.innerHeight;
524
+ const availableBottom = viewportHeight - currentBox.bottom;
525
+ this.position = this.forcedPosition
526
+ ? this.positionAttribute
527
+ : currentBox.top > availableBottom
528
+ ? SelectPosition.above
529
+ : SelectPosition.below;
530
+ this.positionAttribute = this.forcedPosition
531
+ ? this.positionAttribute
532
+ : this.position;
533
+ this.maxHeight =
534
+ this.position === SelectPosition.above ? ~~currentBox.top : ~~availableBottom;
812
535
  }
813
- handleFocusout(e) {
814
- if (this !== document.activeElement && !this.contains(document.activeElement)) {
815
- this.isActiveCell = false;
536
+ /**
537
+ * Ensure that the entire list of options is used when setting the selected property.
538
+ *
539
+ * @param prev - the previous list of selected options
540
+ * @param next - the current list of selected options
541
+ *
542
+ * @internal
543
+ * @remarks
544
+ * Overrides: `Listbox.selectedOptionsChanged`
545
+ */
546
+ selectedOptionsChanged(prev, next) {
547
+ if (this.$fastController.isConnected) {
548
+ this._options.forEach(o => {
549
+ o.selected = next.includes(o);
550
+ });
816
551
  }
817
552
  }
818
- handleKeydown(e) {
819
- if (e.defaultPrevented ||
820
- this.columnDefinition === null ||
821
- (this.cellType === DataGridCellTypes.default &&
822
- this.columnDefinition.cellInternalFocusQueue !== true) ||
823
- (this.cellType === DataGridCellTypes.columnHeader &&
824
- this.columnDefinition.headerCellInternalFocusQueue !== true)) {
825
- return;
826
- }
827
- switch (e.key) {
828
- case keyEnter:
829
- case keyFunction2:
830
- if (this.contains(document.activeElement) &&
831
- document.activeElement !== this) {
832
- return;
833
- }
834
- switch (this.cellType) {
835
- case DataGridCellTypes.columnHeader:
836
- if (this.columnDefinition.headerCellFocusTargetCallback !==
837
- undefined) {
838
- const focusTarget = this.columnDefinition.headerCellFocusTargetCallback(this);
839
- if (focusTarget !== null) {
840
- focusTarget.focus();
841
- }
842
- e.preventDefault();
843
- }
844
- break;
845
- default:
846
- if (this.columnDefinition.cellFocusTargetCallback !== undefined) {
847
- const focusTarget = this.columnDefinition.cellFocusTargetCallback(this);
848
- if (focusTarget !== null) {
849
- focusTarget.focus();
850
- }
851
- e.preventDefault();
852
- }
853
- break;
854
- }
855
- break;
856
- case keyEscape:
857
- if (this.contains(document.activeElement) &&
858
- document.activeElement !== this) {
859
- this.focus();
860
- e.preventDefault();
861
- }
862
- break;
863
- }
553
+ /**
554
+ * Synchronize the form-associated proxy and update the value property of the element.
555
+ *
556
+ * @param prev - the previous collection of slotted option elements
557
+ * @param next - the next collection of slotted option elements
558
+ *
559
+ * @internal
560
+ */
561
+ slottedOptionsChanged(prev, next) {
562
+ super.slottedOptionsChanged(prev, next);
563
+ this.updateValue();
864
564
  }
865
- updateCellView() {
866
- this.disconnectCellView();
867
- if (this.columnDefinition === null) {
868
- return;
565
+ /**
566
+ * Sets the value and to match the first selected option.
567
+ *
568
+ * @param shouldEmit - if true, the change event will be emitted
569
+ *
570
+ * @internal
571
+ */
572
+ updateValue(shouldEmit) {
573
+ var _a;
574
+ if (this.$fastController.isConnected) {
575
+ this.value = ((_a = this.firstSelectedOption) === null || _a === void 0 ? void 0 : _a.text) || this.control.value;
576
+ this.control.value = this.value;
869
577
  }
870
- switch (this.cellType) {
871
- case DataGridCellTypes.columnHeader:
872
- if (this.columnDefinition.headerCellTemplate !== undefined) {
873
- this.customCellView = this.columnDefinition.headerCellTemplate.render(this, this);
874
- }
875
- else {
876
- this.customCellView = defaultHeaderCellContentsTemplate.render(this, this);
877
- }
878
- break;
879
- case undefined:
880
- case DataGridCellTypes.rowHeader:
881
- case DataGridCellTypes.default:
882
- if (this.columnDefinition.cellTemplate !== undefined) {
883
- this.customCellView = this.columnDefinition.cellTemplate.render(this, this);
884
- }
885
- else {
886
- this.customCellView = defaultCellContentsTemplate.render(this, this);
887
- }
888
- break;
578
+ if (shouldEmit) {
579
+ this.$emit("change");
889
580
  }
890
581
  }
891
- disconnectCellView() {
892
- if (this.customCellView !== null) {
893
- this.customCellView.dispose();
894
- this.customCellView = null;
895
- }
582
+ /**
583
+ * @internal
584
+ */
585
+ clearSelectionRange() {
586
+ const controlValueLength = this.control.value.length;
587
+ this.control.setSelectionRange(controlValueLength, controlValueLength);
896
588
  }
897
589
  };
898
590
  __decorate([
899
- attr({ attribute: "cell-type" })
900
- ], DataGridCell$1.prototype, "cellType", void 0);
901
- __decorate([
902
- attr({ attribute: "grid-column" })
903
- ], DataGridCell$1.prototype, "gridColumn", void 0);
591
+ attr({ attribute: "autocomplete", mode: "fromView" })
592
+ ], Combobox$1.prototype, "autocomplete", void 0);
904
593
  __decorate([
905
594
  observable
906
- ], DataGridCell$1.prototype, "rowData", void 0);
595
+ ], Combobox$1.prototype, "maxHeight", void 0);
596
+ __decorate([
597
+ attr({ attribute: "open", mode: "boolean" })
598
+ ], Combobox$1.prototype, "open", void 0);
599
+ __decorate([
600
+ attr
601
+ ], Combobox$1.prototype, "placeholder", void 0);
602
+ __decorate([
603
+ attr({ attribute: "position" })
604
+ ], Combobox$1.prototype, "positionAttribute", void 0);
907
605
  __decorate([
908
606
  observable
909
- ], DataGridCell$1.prototype, "columnDefinition", void 0);
910
-
911
- const dataGridStyles = ":host {\n display: block;\n}\n\n:host([generate-header=sticky]) {\n max-block-size: 400px;\n}\n\n.base {\n position: relative;\n overflow: auto;\n block-size: inherit;\n inline-size: 100%;\n max-block-size: inherit;\n}\n.base::-webkit-scrollbar {\n display: none;\n}";
912
-
913
- const dataGridRowStyles = "/**\n * Do not edit directly\n * Generated on Wed, 01 Nov 2023 12:16:28 GMT\n */\n.base {\n display: grid;\n width: 100%;\n box-sizing: border-box;\n color: var(--vvd-color-canvas-text);\n}\n.base.connotation-cta {\n /* @cssprop [--vvd-data-grid-row-cta-primary=var(--vvd-color-cta-500)] */\n --_connotation-color-primary: var(--vvd-data-grid-row-cta-primary, var(--vvd-color-cta-500));\n /* @cssprop [--vvd-data-grid-row-cta-primary-text=var(--vvd-color-canvas)] */\n --_connotation-color-primary-text: var(--vvd-data-grid-row-cta-primary-text, var(--vvd-color-canvas));\n /* @cssprop [--vvd-data-grid-row-cta-primary-increment=var(--vvd-color-cta-600)] */\n --_connotation-color-primary-increment: var(--vvd-data-grid-row-cta-primary-increment, var(--vvd-color-cta-600));\n /* @cssprop [--vvd-data-grid-row-cta-faint=var(--vvd-color-cta-50)] */\n --_connotation-color-faint: var(--vvd-data-grid-row-cta-faint, var(--vvd-color-cta-50));\n /* @cssprop [--vvd-data-grid-row-cta-pale=var(--vvd-color-cta-300)] */\n --_connotation-color-pale: var(--vvd-data-grid-row-cta-pale, var(--vvd-color-cta-300));\n /* @cssprop [--vvd-data-grid-row-cta-dim=var(--vvd-color-cta-200)] */\n --_connotation-color-dim: var(--vvd-data-grid-row-cta-dim, var(--vvd-color-cta-200));\n}\n.base:not(.connotation-cta) {\n /* @cssprop [--vvd-data-grid-row-accent-primary=var(--vvd-color-canvas-text)] */\n --_connotation-color-primary: var(--vvd-data-grid-row-accent-primary, var(--vvd-color-canvas-text));\n /* @cssprop [--vvd-data-grid-row-accent-primary-text=var(--vvd-color-canvas)] */\n --_connotation-color-primary-text: var(--vvd-data-grid-row-accent-primary-text, var(--vvd-color-canvas));\n /* @cssprop [--vvd-data-grid-row-accent-primary-increment=var(--vvd-color-neutral-800)] */\n --_connotation-color-primary-increment: var(--vvd-data-grid-row-accent-primary-increment, var(--vvd-color-neutral-800));\n /* @cssprop [--vvd-data-grid-row-accent-faint=var(--vvd-color-neutral-50)] */\n --_connotation-color-faint: var(--vvd-data-grid-row-accent-faint, var(--vvd-color-neutral-50));\n /* @cssprop [--vvd-data-grid-row-accent-pale=var(--vvd-color-neutral-300)] */\n --_connotation-color-pale: var(--vvd-data-grid-row-accent-pale, var(--vvd-color-neutral-300));\n /* @cssprop [--vvd-data-grid-row-accent-dim=var(--vvd-color-neutral-200)] */\n --_connotation-color-dim: var(--vvd-data-grid-row-accent-dim, var(--vvd-color-neutral-200));\n}\n.base {\n --_appearance-color-text: var(--_connotation-color-primary);\n --_appearance-color-fill: transparent;\n --_appearance-color-outline: transparent;\n}\n.base:where(:hover, .hover):where(:not(:disabled, .disabled, .readonly)) {\n --_appearance-color-text: var(--_connotation-color-primary);\n --_appearance-color-fill: var(--_connotation-color-faint);\n --_appearance-color-outline: transparent;\n}\n.base:where(.selected, [aria-current]):where(:not(:disabled, .disabled, :hover, .hover)) {\n --_appearance-color-text: var(--_connotation-color-primary);\n --_appearance-color-fill: var(--_connotation-color-dim);\n --_appearance-color-outline: transparent;\n}\n.base:where(.selected, [aria-current]):where(:hover, .hover) {\n --_appearance-color-text: var(--_connotation-color-primary);\n --_appearance-color-fill: var(--_connotation-color-pale);\n --_appearance-color-outline: transparent;\n}\n:host([row-type=sticky-header]) .base {\n position: sticky;\n z-index: 9;\n top: 0;\n background: var(--data-grid-row-background, var(--vvd-color-canvas));\n}\n:host([row-type=hidden-header]) .base {\n display: none;\n}\n:host(:is([aria-selected]):not([row-type*=header])) .base {\n background-color: var(--_appearance-color-fill);\n}";
914
-
915
- const dataGridCellStyles = "/**\n * Do not edit directly\n * Generated on Wed, 01 Nov 2023 12:16:28 GMT\n */\n:host {\n min-inline-size: 80px;\n}\n\n:host(:focus-visible) {\n outline: none;\n}\n\n.base {\n position: relative;\n display: flex;\n box-sizing: border-box;\n align-items: center;\n padding: 8px 12px;\n border-bottom: 1px solid var(--vvd-color-neutral-300);\n block-size: calc(1px * (40 + 4 * clamp(-1, var(--vvd-size-density, 0), 2) + 8));\n color: var(--_appearance-color-text);\n font: var(--vvd-typography-base);\n}\n.base.connotation-cta {\n /* @cssprop [--vvd-data-grid-cell-cta-primary=var(--vvd-color-cta-500)] */\n --_connotation-color-primary: var(--vvd-data-grid-cell-cta-primary, var(--vvd-color-cta-500));\n /* @cssprop [--vvd-data-grid-cell-cta-primary-text=var(--vvd-color-canvas)] */\n --_connotation-color-primary-text: var(--vvd-data-grid-cell-cta-primary-text, var(--vvd-color-canvas));\n /* @cssprop [--vvd-data-grid-cell-cta-primary-increment=var(--vvd-color-cta-600)] */\n --_connotation-color-primary-increment: var(--vvd-data-grid-cell-cta-primary-increment, var(--vvd-color-cta-600));\n /* @cssprop [--vvd-data-grid-cell-cta-faint=var(--vvd-color-cta-50)] */\n --_connotation-color-faint: var(--vvd-data-grid-cell-cta-faint, var(--vvd-color-cta-50));\n /* @cssprop [--vvd-data-grid-cell-cta-pale=var(--vvd-color-cta-300)] */\n --_connotation-color-pale: var(--vvd-data-grid-cell-cta-pale, var(--vvd-color-cta-300));\n /* @cssprop [--vvd-data-grid-cell-cta-dim=var(--vvd-color-cta-200)] */\n --_connotation-color-dim: var(--vvd-data-grid-cell-cta-dim, var(--vvd-color-cta-200));\n}\n.base:not(.connotation-cta) {\n /* @cssprop [--vvd-data-grid-cell-accent-primary=var(--vvd-color-canvas-text)] */\n --_connotation-color-primary: var(--vvd-data-grid-cell-accent-primary, var(--vvd-color-canvas-text));\n /* @cssprop [--vvd-data-grid-cell-accent-primary-text=var(--vvd-color-canvas)] */\n --_connotation-color-primary-text: var(--vvd-data-grid-cell-accent-primary-text, var(--vvd-color-canvas));\n /* @cssprop [--vvd-data-grid-cell-accent-primary-increment=var(--vvd-color-neutral-800)] */\n --_connotation-color-primary-increment: var(--vvd-data-grid-cell-accent-primary-increment, var(--vvd-color-neutral-800));\n /* @cssprop [--vvd-data-grid-cell-accent-faint=var(--vvd-color-neutral-50)] */\n --_connotation-color-faint: var(--vvd-data-grid-cell-accent-faint, var(--vvd-color-neutral-50));\n /* @cssprop [--vvd-data-grid-cell-accent-pale=var(--vvd-color-neutral-300)] */\n --_connotation-color-pale: var(--vvd-data-grid-cell-accent-pale, var(--vvd-color-neutral-300));\n /* @cssprop [--vvd-data-grid-cell-accent-dim=var(--vvd-color-neutral-200)] */\n --_connotation-color-dim: var(--vvd-data-grid-cell-accent-dim, var(--vvd-color-neutral-200));\n}\n.base {\n --_appearance-color-text: var(--_connotation-color-primary);\n --_appearance-color-fill: transparent;\n --_appearance-color-outline: transparent;\n}\n.base:where(:hover, .hover):where(:not(:disabled, .disabled, .readonly)) {\n --_appearance-color-text: var(--_connotation-color-primary);\n --_appearance-color-fill: var(--_connotation-color-faint);\n --_appearance-color-outline: transparent;\n}\n.base:where(.selected, [aria-current]):where(:not(:disabled, .disabled, :hover, .hover)) {\n --_appearance-color-text: var(--_connotation-color-primary);\n --_appearance-color-fill: var(--_connotation-color-dim);\n --_appearance-color-outline: transparent;\n}\n.base:where(.selected, [aria-current]):where(:hover, .hover) {\n --_appearance-color-text: var(--_connotation-color-primary);\n --_appearance-color-fill: var(--_connotation-color-pale);\n --_appearance-color-outline: transparent;\n}\n:host([cell-type=columnheader]) .base {\n border-color: var(--vvd-color-canvas-text);\n font: var(--vvd-typography-base-bold);\n}\n:host(:is([aria-selected]):not([cell-type=columnheader])) .base {\n background-color: var(--_appearance-color-fill);\n}\n\n.focus-indicator {\n --focus-stroke-gap-color: transparent;\n pointer-events: none;\n}\n:host(:not(:focus)) .base > .focus-indicator {\n display: none;\n}\n\nslot {\n display: block;\n overflow: hidden;\n inline-size: 100%;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.header-icon {\n margin-inline-start: auto;\n}";
916
-
917
- var __defProp$2 = Object.defineProperty;
918
- var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
919
- var __decorateClass$2 = (decorators, target, key, kind) => {
920
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$2(target, key) : target;
921
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
922
- if (decorator = decorators[i])
923
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
924
- if (kind && result)
925
- __defProp$2(target, key, result);
926
- return result;
927
- };
928
- const DataGridSelectionMode = {
929
- none: "none",
930
- singleRow: "single-row",
931
- multiRow: "multi-row",
932
- singleCell: "single-cell",
933
- multiCell: "multi-cell"
934
- };
935
- class DataGrid extends DataGrid$1 {
936
- constructor() {
937
- super();
938
- this.#handleKeypress = (e) => {
939
- if (e.key === "Enter" || e.key === " ") {
940
- this.#handleClick(e);
941
- }
942
- };
943
- this.#handleClick = ({ target, ctrlKey, shiftKey, metaKey }) => {
944
- if (target.getAttribute("role") !== "gridcell")
945
- return;
946
- if (this.selectionMode === DataGridSelectionMode.singleCell || this.selectionMode === DataGridSelectionMode.multiCell) {
947
- this.#handleCellSelection({ target, ctrlKey, shiftKey, metaKey });
948
- return;
949
- }
950
- if (this.selectionMode === DataGridSelectionMode.singleRow || this.selectionMode === DataGridSelectionMode.multiRow) {
951
- this.#handleRowSelection({ target, ctrlKey, shiftKey, metaKey });
952
- }
953
- };
954
- this.#handleCellSelection = ({ target, ctrlKey, shiftKey, metaKey }) => {
955
- const cell = target;
956
- if (this.selectionMode === DataGridSelectionMode.multiCell && (ctrlKey || shiftKey || metaKey)) {
957
- this.#setSelectedState(cell, !this.#selectedCells.includes(cell));
958
- } else {
959
- const cacheTargetSelection = cell.getAttribute("aria-selected") === "true";
960
- this.#resetSelection();
961
- this.#setSelectedState(cell, !cacheTargetSelection);
962
- }
963
- };
964
- this.#handleRowSelection = ({ target, ctrlKey, shiftKey, metaKey }) => {
965
- const row = target.parentNode;
966
- if (this.selectionMode === DataGridSelectionMode.multiRow && (ctrlKey || shiftKey || metaKey)) {
967
- this.#setSelectedState(row, !this.#selectedRows.includes(row));
968
- } else {
969
- const cacheTargetSelection = row.getAttribute("aria-selected") === "true";
970
- this.#resetSelection();
971
- this.#setSelectedState(row, !cacheTargetSelection);
972
- }
973
- };
974
- this.#setSelectedState = (cell, selectedState) => {
975
- cell.setAttribute("aria-selected", selectedState.toString());
976
- };
977
- this.#resetSelection = () => {
978
- if (this.selectionMode === DataGridSelectionMode.singleCell || this.selectionMode === DataGridSelectionMode.multiCell) {
979
- Array.from(this.querySelectorAll('[role="gridcell"]')).forEach((cell) => this.#setSelectedState(cell, false));
980
- Array.from(this.querySelectorAll('[role="row"]')).forEach((row) => row.removeAttribute("aria-selected"));
981
- }
982
- if (this.selectionMode === DataGridSelectionMode.none) {
983
- Array.from(this.querySelectorAll('[role="gridcell"]')).forEach((cell) => cell.removeAttribute("aria-selected"));
984
- Array.from(this.querySelectorAll('[role="row"]')).forEach((row) => row.removeAttribute("aria-selected"));
985
- }
986
- if (this.selectionMode === DataGridSelectionMode.singleRow || this.selectionMode === DataGridSelectionMode.multiRow) {
987
- Array.from(this.querySelectorAll('[role="gridcell"]')).forEach((cell) => cell.removeAttribute("aria-selected"));
988
- Array.from(this.querySelectorAll('[role="row"]')).forEach((row) => row.setAttribute("aria-selected", "false"));
989
- }
990
- };
991
- this.#initSelections = () => {
992
- if (this.selectionMode === DataGridSelectionMode.singleCell || this.selectionMode === DataGridSelectionMode.multiCell) {
993
- Array.from(this.querySelectorAll('[role="gridcell"]')).forEach((cell) => !cell.hasAttribute("aria-selected") && this.#setSelectedState(cell, false));
994
- Array.from(this.querySelectorAll('[role="row"]')).forEach((row) => row.removeAttribute("aria-selected"));
995
- }
996
- if (this.selectionMode === DataGridSelectionMode.none) {
997
- Array.from(this.querySelectorAll('[role="gridcell"]')).forEach((cell) => cell.removeAttribute("aria-selected"));
998
- Array.from(this.querySelectorAll('[role="row"]')).forEach((row) => row.removeAttribute("aria-selected"));
999
- }
1000
- if (this.selectionMode === DataGridSelectionMode.singleRow || this.selectionMode === DataGridSelectionMode.multiRow) {
1001
- Array.from(this.querySelectorAll('[role="gridcell"]')).forEach((cell) => cell.removeAttribute("aria-selected"));
1002
- Array.from(this.querySelectorAll('[role="row"]')).forEach((row) => !row.hasAttribute("aria-selected") && row.setAttribute("aria-selected", "false"));
1003
- }
1004
- };
1005
- this.addEventListener("click", this.#handleClick);
1006
- this.addEventListener("keydown", this.#handleKeypress);
1007
- }
1008
- get #selectedRows() {
1009
- return this.rowElements.filter((row) => row.getAttribute("aria-selected") === "true");
1010
- }
1011
- get #selectedCells() {
1012
- return this.rowElements.reduce((acc, row) => {
1013
- const rowChildren = Array.from(row.children);
1014
- const selectedCells = rowChildren.filter((cell) => cell.getAttribute("aria-selected") === "true");
1015
- return acc.concat(selectedCells);
1016
- }, []);
1017
- }
1018
- selectionModeChanged(oldValue) {
1019
- if (oldValue === void 0) {
1020
- DOM.queueUpdate(this.#initSelections);
1021
- return;
1022
- }
1023
- this.#resetSelection();
1024
- }
1025
- #handleKeypress;
1026
- #handleClick;
1027
- #handleCellSelection;
1028
- #handleRowSelection;
1029
- #setSelectedState;
1030
- #resetSelection;
1031
- #initSelections;
1032
- static generateColumns(rowData) {
1033
- return Object.keys(rowData).map((property, index) => {
1034
- return {
1035
- columnDataKey: property,
1036
- gridColumn: `${index}`
1037
- };
1038
- });
1039
- }
1040
- }
1041
- __decorateClass$2([
1042
- attr({ attribute: "selection-mode" })
1043
- ], DataGrid.prototype, "selectionMode", 2);
1044
-
1045
- var __defProp$1 = Object.defineProperty;
1046
- var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
1047
- var __decorateClass$1 = (decorators, target, key, kind) => {
1048
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
1049
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
1050
- if (decorator = decorators[i])
1051
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
1052
- if (kind && result)
1053
- __defProp$1(target, key, result);
1054
- return result;
1055
- };
1056
- class DataGridRow extends DataGridRow$1 {
1057
- constructor() {
1058
- super(...arguments);
1059
- this.ariaSelected = null;
1060
- }
607
+ ], Combobox$1.prototype, "position", void 0);
608
+ /**
609
+ * Includes ARIA states and properties relating to the ARIA combobox role.
610
+ *
611
+ * @public
612
+ */
613
+ class DelegatesARIACombobox {
1061
614
  }
1062
- __decorateClass$1([
1063
- attr({ attribute: "aria-selected" })
1064
- ], DataGridRow.prototype, "ariaSelected", 2);
1065
-
1066
- const DataGridCellSortStates = {
1067
- none: "none",
1068
- ascending: "ascending",
1069
- descending: "descending",
1070
- other: "other"
1071
- };
1072
- const GenerateHeaderOptions = {
1073
- none: "none",
1074
- default: "default",
1075
- sticky: "sticky"
1076
- };
1077
- const DataGridRowTypes = {
1078
- default: "default",
1079
- header: "header",
1080
- stickyHeader: "sticky-header"
1081
- };
1082
- const DataGridCellRole = {
1083
- columnheader: "columnheader",
1084
- rowheader: "rowheader",
1085
- default: "gridcell"
1086
- };
615
+ __decorate([
616
+ observable
617
+ ], DelegatesARIACombobox.prototype, "ariaAutoComplete", void 0);
618
+ __decorate([
619
+ observable
620
+ ], DelegatesARIACombobox.prototype, "ariaControls", void 0);
621
+ applyMixins(DelegatesARIACombobox, DelegatesARIAListbox);
622
+ applyMixins(Combobox$1, StartEnd, DelegatesARIACombobox);
1087
623
 
1088
- function createRowItemTemplate(context) {
1089
- const rowTag = context.tagFor(DataGridRow);
1090
- return html`
1091
- <${rowTag}
1092
- :rowData="${(x) => x}"
1093
- :cellItemTemplate="${(_, c) => c.parent.cellItemTemplate}"
1094
- :headerCellItemTemplate="${(_, c) => c.parent.headerCellItemTemplate}"
1095
- ></${rowTag}>
1096
- `;
1097
- }
1098
- function getMultiSelectAriaState(x) {
1099
- return x.selectionMode === void 0 || x.selectionMode === DataGridSelectionMode.none ? null : x.selectionMode.includes("multi") ? "true" : "false";
1100
- }
1101
- function setHeaderRow(x) {
1102
- if (x.columnDefinitions === null) {
1103
- const headerRow = x.querySelector('[cell-type="columnheader"]')?.parentElement;
1104
- if (headerRow) {
1105
- const rowType = x.generateHeader === GenerateHeaderOptions.sticky ? DataGridRowTypes.stickyHeader : x.generateHeader === GenerateHeaderOptions.default ? DataGridRowTypes.header : "hidden-header";
1106
- headerRow.setAttribute("row-type", rowType);
1107
- }
1108
- }
1109
- }
1110
- function handleColumnSort(_, { event }) {
1111
- event.stopPropagation();
1112
- }
1113
- const DataGridTemplate = (context) => {
1114
- const rowItemTemplate = createRowItemTemplate(context);
1115
- const rowTag = context.tagFor(DataGridRow);
1116
- return html`
1117
- <template
1118
- aria-multiselectable="${getMultiSelectAriaState}"
1119
- role="grid"
1120
- tabindex="0"
1121
- @sort="${handleColumnSort}"
1122
- :rowElementTag="${() => rowTag}"
1123
- :defaultRowItemTemplate="${rowItemTemplate}"
1124
- ${children({
1125
- property: "rowElements",
1126
- filter: elements("[role=row]")
1127
- })}
1128
- >
1129
- <div class="base">
1130
- ${setHeaderRow}
1131
- <slot></slot>
1132
- </div>
1133
- </template>
1134
- `;
1135
- };
624
+ const styles = "/**\n * Do not edit directly\n * Generated on Thu, 30 Nov 2023 11:42:28 GMT\n */\n:host {\n position: relative;\n}\n\n.control {\n display: flex;\n padding-inline-end: 44px !important;\n}\n\n.icon {\n inset-inline-end: 16px;\n inset-inline-start: unset;\n}\n:not(.disabled) .icon {\n cursor: pointer;\n}\n.disabled .icon {\n cursor: not-allowed;\n}\n\n.listbox {\n padding: 4px;\n background-color: var(--_appearance-color-fill);\n border-radius: 6px;\n box-shadow: inset 0 0 0 1px var(--_appearance-color-outline);\n contain: paint;\n}\n.listbox {\n /* @cssprop [--vvd-combobox-accent-backdrop=var(--vvd-color-canvas)] */\n --_connotation-color-backdrop: var(--vvd-combobox-accent-backdrop, var(--vvd-color-canvas));\n /* @cssprop [--vvd-combobox-accent-intermediate=var(--vvd-color-neutral-500)] */\n --_connotation-color-intermediate: var(--vvd-combobox-accent-intermediate, var(--vvd-color-neutral-500));\n /* @cssprop [--vvd-combobox-accent-primary=var(--vvd-color-canvas-text)] */\n --_connotation-color-primary: var(--vvd-combobox-accent-primary, var(--vvd-color-canvas-text));\n /* @cssprop [--vvd-combobox-accent-soft=var(--vvd-color-neutral-100)] */\n --_connotation-color-soft: var(--vvd-combobox-accent-soft, var(--vvd-color-neutral-100));\n}\n.listbox {\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.listbox.appearance-ghost {\n --_appearance-color-text: var(--_connotation-color-primary);\n --_appearance-color-fill: transparent;\n --_appearance-color-outline: transparent;\n}\n.listbox:where(:disabled, .disabled) {\n --_appearance-color-text: var(--vvd-color-neutral-300);\n --_appearance-color-fill: var(--vvd-color-neutral-100);\n --_appearance-color-outline: var(--vvd-color-neutral-300);\n}\n.listbox:where(:disabled, .disabled).appearance-ghost {\n --_appearance-color-text: var(--vvd-color-neutral-300);\n --_appearance-color-fill: transparent;\n --_appearance-color-outline: transparent;\n}\n\n::part(popup-base) {\n inline-size: 100%;\n}";
1136
625
 
1137
626
  var __defProp = Object.defineProperty;
1138
627
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -1145,159 +634,109 @@ var __decorateClass = (decorators, target, key, kind) => {
1145
634
  __defProp(target, key, result);
1146
635
  return result;
1147
636
  };
1148
- class DataGridCell extends DataGridCell$1 {
1149
- constructor() {
1150
- super();
1151
- this.ariaSelected = null;
1152
- this.ariaSort = null;
1153
- this.updateCellStyle = () => {
1154
- if (this.gridColumn && !this.gridColumn.includes("undefined")) {
1155
- this.style.gridColumn = this.gridColumn;
1156
- } else {
1157
- this.style.removeProperty("grid-column");
1158
- }
1159
- };
1160
- }
1161
- ariaSelectedChanged(_, selectedState) {
1162
- this.shadowRoot.querySelector(".base")?.classList.toggle("selected", selectedState === "true");
1163
- }
637
+ let Combobox = class extends Combobox$1 {
1164
638
  connectedCallback() {
1165
639
  super.connectedCallback();
1166
- this.ariaSelectedChanged(null, this.ariaSelected);
640
+ this._popup.anchor = this._anchor;
1167
641
  }
1168
- handleFocusin(e) {
1169
- super.handleFocusin(e);
1170
- this.shadowRoot.querySelector(".base").classList.add("active");
1171
- }
1172
- handleFocusout(e) {
1173
- super.handleFocusout(e);
1174
- this.shadowRoot.querySelector(".base").classList.remove("active");
1175
- }
1176
- }
1177
- __decorateClass([
1178
- attr({ attribute: "aria-selected", mode: "fromView" })
1179
- ], DataGridCell.prototype, "ariaSelected", 2);
642
+ };
1180
643
  __decorateClass([
1181
- attr({ attribute: "aria-sort" })
1182
- ], DataGridCell.prototype, "ariaSort", 2);
644
+ attr
645
+ ], Combobox.prototype, "placement", 2);
646
+ Combobox = __decorateClass([
647
+ formElements
648
+ ], Combobox);
649
+ applyMixins(Combobox, AffixIcon);
1183
650
 
1184
- function createCellItemTemplate(context) {
1185
- const cellTag = context.tagFor(DataGridCell);
651
+ function renderLabel() {
1186
652
  return html`
1187
- <${cellTag}
1188
- cell-type="${(x) => x.isRowHeader ? "rowheader" : void 0}"
1189
- grid-column="${(_, c) => c.index + 1}"
1190
- :rowData="${(_, c) => c.parent.rowData}"
1191
- :columnDefinition="${(x) => x}"
1192
- selected="${(_, c) => c.parent.ariaSelected === "true" ? true : null}"
1193
- ></${cellTag}>
1194
- `;
653
+ <label for="control" class="label">
654
+ ${(x) => x.label}
655
+ </label>`;
1195
656
  }
1196
- function createHeaderCellItemTemplate(context) {
1197
- const cellTag = context.tagFor(DataGridCell);
657
+ const getStateClasses = ({
658
+ disabled,
659
+ placeholder,
660
+ label
661
+ }) => classNames(
662
+ "base",
663
+ ["disabled", disabled],
664
+ ["placeholder", Boolean(placeholder)],
665
+ ["no-label", !label]
666
+ );
667
+ function renderInput(context) {
668
+ const affixIconTemplate = affixIconTemplateFactory(context);
669
+ const focusTemplate = focusTemplateFactory(context);
1198
670
  return html`
1199
- <${cellTag}
1200
- cell-type="columnheader"
1201
- grid-column="${(_, c) => c.index + 1}"
1202
- :columnDefinition="${(x) => x}"
1203
- ></${cellTag}>
1204
- `;
671
+ <div class="${getStateClasses}" ${ref("_anchor")}>
672
+ ${when((x) => x.label, renderLabel())}
673
+ <div class="fieldset">
674
+ <input
675
+ id="control"
676
+ class="control"
677
+ aria-activedescendant="${(x) => x.open ? x.ariaActiveDescendant : null}"
678
+ aria-autocomplete="${(x) => x.ariaAutoComplete}"
679
+ aria-controls="${(x) => x.ariaControls}"
680
+ aria-disabled="${(x) => x.ariaDisabled}"
681
+ aria-expanded="${(x) => x.ariaExpanded}"
682
+ aria-haspopup="listbox"
683
+ placeholder="${(x) => x.placeholder}"
684
+ role="combobox"
685
+ type="text"
686
+ ?disabled="${(x) => x.disabled}"
687
+ :value="${(x) => x.value}"
688
+ @input="${(x, c) => x.inputHandler(c.event)}"
689
+ @keyup="${(x, c) => x.keyupHandler(c.event)}"
690
+ ${ref("control")}
691
+ />
692
+ ${() => affixIconTemplate("chevron-down-line")}
693
+ ${() => focusTemplate}
694
+ </div>
695
+ </div>`;
1205
696
  }
1206
- const DataGridRowTemplate = (context) => {
1207
- const cellItemTemplate = createCellItemTemplate(context);
1208
- const headerCellItemTemplate = createHeaderCellItemTemplate(context);
697
+ const comboboxTemplate = (context) => {
698
+ const popupTag = context.tagFor(Popup);
1209
699
  return html`
1210
700
  <template
1211
- role="row"
1212
- class="${(x) => x.rowType !== "default" ? x.rowType : ""}"
1213
- :defaultCellItemTemplate="${cellItemTemplate}"
1214
- :defaultHeaderCellItemTemplate="${headerCellItemTemplate}"
1215
- ${children({
1216
- property: "cellElements",
1217
- filter: elements('[role="cell"],[role="gridcell"],[role="columnheader"],[role="rowheader"]')
1218
- })}
701
+ aria-disabled="${(x) => x.ariaDisabled}"
702
+ autocomplete="${(x) => x.autocomplete}"
703
+ tabindex="${(x) => !x.disabled ? "0" : null}"
704
+ @click="${(x, c) => x.clickHandler(c.event)}"
705
+ @focusout="${(x, c) => x.focusoutHandler(c.event)}"
706
+ @keydown="${(x, c) => x.keydownHandler(c.event)}"
1219
707
  >
1220
- <div class="base ${(x) => x.ariaSelected === "true" ? "selected" : ""}"
1221
- style="grid-template-columns: ${(x) => x.gridTemplateColumns};"
1222
- >
1223
- <slot ${slotted("slottedCellElements")}></slot>
1224
- </div>
708
+ ${() => renderInput(context)}
709
+ <${popupTag} class="popup"
710
+ ?open="${(x) => x.open}"
711
+ placement="${(x) => x.placement}"
712
+ strategy="absolute"
713
+ ${ref("_popup")}>
714
+ <div id="${(x) => x.listboxId}"
715
+ class="listbox"
716
+ role="listbox"
717
+ ?disabled="${(x) => x.disabled}"
718
+ ${ref("listbox")}>
719
+ <slot ${slotted({
720
+ filter: Listbox$1.slottedOptionFilter,
721
+ flatten: true,
722
+ property: "slottedOptions"
723
+ })}>
724
+ </slot>
725
+ </div>
726
+ </${popupTag}>
1225
727
  </template>
1226
- `;
728
+ `;
1227
729
  };
1228
730
 
1229
- function shouldShowSortIcons(x) {
1230
- if (x.columnDefinition) {
1231
- x.ariaSort = !x.columnDefinition.sortable ? null : x.columnDefinition.sortDirection ? x.columnDefinition.sortDirection : DataGridCellSortStates.none;
731
+ const combobox = Combobox.compose({
732
+ baseName: "combobox",
733
+ template: comboboxTemplate,
734
+ styles: [styles$1, styles],
735
+ shadowOptions: {
736
+ delegatesFocus: true
1232
737
  }
1233
- return x.cellType === "columnheader" && x.ariaSort !== null && x.ariaSort !== DataGridCellSortStates.other;
1234
- }
1235
- function getSortIcon(x) {
1236
- return x.ariaSort === DataGridCellSortStates.ascending ? "sort-asc-solid" : x.ariaSort === DataGridCellSortStates.descending ? "sort-desc-solid" : "sort-solid";
1237
- }
1238
- function renderSortIcons(c) {
1239
- const iconTag = c.tagFor(Icon);
1240
- return html`
1241
- ${when(shouldShowSortIcons, html`
1242
- <${iconTag} class="header-icon" name="${getSortIcon}"></${iconTag}>
1243
- `)}
1244
- `;
1245
- }
1246
- function isSortable(x) {
1247
- return x.cellType === "columnheader" && x.ariaSort !== null;
1248
- }
1249
- function emitSortEvent(x) {
1250
- x.$emit(
1251
- "sort",
1252
- { columnDataKey: x.columnDefinition && x.columnDefinition.columnDataKey ? x.columnDefinition.columnDataKey : x.textContent.trim(), sortDirection: x.ariaSort }
1253
- );
1254
- }
1255
- function handleClick(x) {
1256
- if (isSortable(x)) {
1257
- emitSortEvent(x);
1258
- }
1259
- }
1260
- function handleKeyDown(x, e) {
1261
- if (isSortable(x) && (e.key === keyEnter$1 || e.key === keySpace)) {
1262
- emitSortEvent(x);
1263
- }
1264
- return true;
1265
- }
1266
- function DataGridCellTemplate(context) {
1267
- const focusTemplate = focusTemplateFactory(context);
1268
- return html`
1269
- <template
1270
- tabindex="-1"
1271
- role="${(x) => DataGridCellRole[x.cellType] ?? DataGridCellRole.default}"
1272
- @click="${handleClick}"
1273
- @keydown="${(x, c) => handleKeyDown(x, c.event)}"
1274
- >
1275
- <div class="base">
1276
- <slot></slot>
1277
- ${() => focusTemplate}
1278
- ${(_) => renderSortIcons(context)}
1279
- </div>
1280
-
1281
- </template>
1282
- `;
1283
- }
1284
-
1285
- const dataGrid = DataGrid.compose({
1286
- baseName: "data-grid",
1287
- template: DataGridTemplate,
1288
- styles: dataGridStyles
1289
- })();
1290
- const dataGridRow = DataGridRow.compose({
1291
- baseName: "data-grid-row",
1292
- template: DataGridRowTemplate,
1293
- styles: dataGridRowStyles
1294
- })();
1295
- const dataGridCell = DataGridCell.compose({
1296
- baseName: "data-grid-cell",
1297
- template: DataGridCellTemplate,
1298
- styles: dataGridCellStyles
1299
738
  })();
1300
- const dataGridElements = [dataGridCell, dataGridRow, dataGrid, ...iconRegistries];
1301
- const registerDataGrid = registerFactory(dataGridElements);
739
+ const comboboxRegistries = [combobox, ...iconRegistries, ...popupRegistries, ...focusRegistries, ...listboxOptionRegistries];
740
+ const registerCombobox = registerFactory(comboboxRegistries);
1302
741
 
1303
- export { dataGridRow as a, dataGridCell as b, dataGridElements as c, dataGrid as d, registerDataGrid as r };
742
+ export { comboboxRegistries as a, combobox as c, registerCombobox as r };