@govtechsg/sgds-web-component 3.28.1-rc.0 → 3.29.1-rc.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 (195) hide show
  1. package/base/button.js +1 -1
  2. package/base/button.js.map +1 -1
  3. package/base/dropdown-list-element.d.ts +3 -3
  4. package/base/dropdown-list-element.js.map +1 -1
  5. package/components/Alert/alert.js +1 -1
  6. package/components/Alert/alert.js.map +1 -1
  7. package/components/Alert/index.umd.min.js +3 -3
  8. package/components/Alert/index.umd.min.js.map +1 -1
  9. package/components/Alert/sgds-alert.js +1 -1
  10. package/components/Alert/sgds-alert.js.map +1 -1
  11. package/components/Appnav/index.umd.min.js +3 -3
  12. package/components/Appnav/index.umd.min.js.map +1 -1
  13. package/components/Appnav/sgds-appnav.js +1 -1
  14. package/components/Appnav/sgds-appnav.js.map +1 -1
  15. package/components/Badge/index.umd.min.js +1 -1
  16. package/components/Badge/index.umd.min.js.map +1 -1
  17. package/components/Breadcrumb/index.umd.min.js +3 -3
  18. package/components/Breadcrumb/index.umd.min.js.map +1 -1
  19. package/components/Breadcrumb/sgds-breadcrumb.js +2 -2
  20. package/components/Breadcrumb/sgds-breadcrumb.js.map +1 -1
  21. package/components/Button/index.umd.min.js +2 -2
  22. package/components/Button/index.umd.min.js.map +1 -1
  23. package/components/Button/sgds-button.js +1 -1
  24. package/components/Button/sgds-button.js.map +1 -1
  25. package/components/Checkbox/index.umd.min.js +3 -2
  26. package/components/Checkbox/index.umd.min.js.map +1 -1
  27. package/components/Checkbox/sgds-checkbox.d.ts +2 -0
  28. package/components/Checkbox/sgds-checkbox.js +3 -0
  29. package/components/Checkbox/sgds-checkbox.js.map +1 -1
  30. package/components/CloseButton/close-button.js +1 -1
  31. package/components/CloseButton/close-button.js.map +1 -1
  32. package/components/CloseButton/index.umd.min.js +1 -1
  33. package/components/CloseButton/index.umd.min.js.map +1 -1
  34. package/components/ComboBox/combo-box.js +1 -1
  35. package/components/ComboBox/combo-box.js.map +1 -1
  36. package/components/ComboBox/index.umd.min.js +30 -20
  37. package/components/ComboBox/index.umd.min.js.map +1 -1
  38. package/components/ComboBox/sgds-combo-box.d.ts +23 -2
  39. package/components/ComboBox/sgds-combo-box.js +95 -4
  40. package/components/ComboBox/sgds-combo-box.js.map +1 -1
  41. package/components/ComboBox/types.d.ts +3 -0
  42. package/components/DataTable/data-table.js +1 -1
  43. package/components/DataTable/data-table.js.map +1 -1
  44. package/components/DataTable/index.umd.min.js +20 -11
  45. package/components/DataTable/index.umd.min.js.map +1 -1
  46. package/components/DataTable/sgds-data-table-row.js +12 -4
  47. package/components/DataTable/sgds-data-table-row.js.map +1 -1
  48. package/components/DataTable/sgds-data-table.js +1 -2
  49. package/components/DataTable/sgds-data-table.js.map +1 -1
  50. package/components/Datepicker/index.umd.min.js +3 -2
  51. package/components/Datepicker/index.umd.min.js.map +1 -1
  52. package/components/Drawer/index.umd.min.js +1 -1
  53. package/components/Drawer/index.umd.min.js.map +1 -1
  54. package/components/Dropdown/index.umd.min.js +1 -1
  55. package/components/Dropdown/index.umd.min.js.map +1 -1
  56. package/components/Dropdown/sgds-dropdown.js +1 -1
  57. package/components/Dropdown/sgds-dropdown.js.map +1 -1
  58. package/components/FileUpload/index.umd.min.js +3 -3
  59. package/components/FileUpload/index.umd.min.js.map +1 -1
  60. package/components/IconButton/index.umd.min.js +1 -1
  61. package/components/IconButton/index.umd.min.js.map +1 -1
  62. package/components/Input/index.umd.min.js +1 -0
  63. package/components/Input/index.umd.min.js.map +1 -1
  64. package/components/Input/sgds-input.js +1 -0
  65. package/components/Input/sgds-input.js.map +1 -1
  66. package/components/Mainnav/index.umd.min.js +3 -3
  67. package/components/Mainnav/index.umd.min.js.map +1 -1
  68. package/components/Mainnav/sgds-mainnav.js +1 -1
  69. package/components/Mainnav/sgds-mainnav.js.map +1 -1
  70. package/components/Modal/index.umd.min.js +3 -3
  71. package/components/Modal/index.umd.min.js.map +1 -1
  72. package/components/Modal/modal.js +1 -1
  73. package/components/Modal/modal.js.map +1 -1
  74. package/components/Modal/sgds-modal.js +1 -1
  75. package/components/Modal/sgds-modal.js.map +1 -1
  76. package/components/OverflowMenu/index.umd.min.js +1 -1
  77. package/components/OverflowMenu/index.umd.min.js.map +1 -1
  78. package/components/Pagination/index.umd.min.js +2 -2
  79. package/components/Pagination/index.umd.min.js.map +1 -1
  80. package/components/QuantityToggle/index.umd.min.js +2 -1
  81. package/components/QuantityToggle/index.umd.min.js.map +1 -1
  82. package/components/Select/index.umd.min.js +1 -1
  83. package/components/Select/index.umd.min.js.map +1 -1
  84. package/components/Select/sgds-select.js +1 -1
  85. package/components/Select/sgds-select.js.map +1 -1
  86. package/components/Sidebar/index.umd.min.js +1 -1
  87. package/components/Sidebar/index.umd.min.js.map +1 -1
  88. package/components/Sidenav/index.umd.min.js +1 -1
  89. package/components/Sidenav/index.umd.min.js.map +1 -1
  90. package/components/Sidenav/sgds-sidenav.js +1 -1
  91. package/components/Sidenav/sgds-sidenav.js.map +1 -1
  92. package/components/SystemBanner/index.umd.min.js +4 -2
  93. package/components/SystemBanner/index.umd.min.js.map +1 -1
  94. package/components/SystemBanner/sgds-system-banner.js +2 -0
  95. package/components/SystemBanner/sgds-system-banner.js.map +1 -1
  96. package/components/Toast/index.umd.min.js +1 -1
  97. package/components/Toast/index.umd.min.js.map +1 -1
  98. package/components/index.umd.min.js +78 -57
  99. package/components/index.umd.min.js.map +1 -1
  100. package/custom-elements.json +174 -34
  101. package/index.umd.min.js +731 -710
  102. package/index.umd.min.js.map +1 -1
  103. package/package.json +1 -1
  104. package/react/base/button.cjs.js +1 -1
  105. package/react/base/button.cjs.js.map +1 -1
  106. package/react/base/button.js +1 -1
  107. package/react/base/button.js.map +1 -1
  108. package/react/base/dropdown-list-element.cjs.js.map +1 -1
  109. package/react/base/dropdown-list-element.js.map +1 -1
  110. package/react/combo-box/index.cjs.js +1 -0
  111. package/react/combo-box/index.cjs.js.map +1 -1
  112. package/react/combo-box/index.js +1 -0
  113. package/react/combo-box/index.js.map +1 -1
  114. package/react/components/Alert/alert.cjs.js +1 -1
  115. package/react/components/Alert/alert.cjs.js.map +1 -1
  116. package/react/components/Alert/alert.js +1 -1
  117. package/react/components/Alert/alert.js.map +1 -1
  118. package/react/components/Alert/sgds-alert.cjs.js +1 -1
  119. package/react/components/Alert/sgds-alert.cjs.js.map +1 -1
  120. package/react/components/Alert/sgds-alert.js +1 -1
  121. package/react/components/Alert/sgds-alert.js.map +1 -1
  122. package/react/components/Appnav/sgds-appnav.cjs.js +1 -1
  123. package/react/components/Appnav/sgds-appnav.cjs.js.map +1 -1
  124. package/react/components/Appnav/sgds-appnav.js +1 -1
  125. package/react/components/Appnav/sgds-appnav.js.map +1 -1
  126. package/react/components/Breadcrumb/sgds-breadcrumb.cjs.js +2 -2
  127. package/react/components/Breadcrumb/sgds-breadcrumb.cjs.js.map +1 -1
  128. package/react/components/Breadcrumb/sgds-breadcrumb.js +2 -2
  129. package/react/components/Breadcrumb/sgds-breadcrumb.js.map +1 -1
  130. package/react/components/Button/sgds-button.cjs.js +1 -1
  131. package/react/components/Button/sgds-button.cjs.js.map +1 -1
  132. package/react/components/Button/sgds-button.js +1 -1
  133. package/react/components/Button/sgds-button.js.map +1 -1
  134. package/react/components/Checkbox/sgds-checkbox.cjs.js +3 -0
  135. package/react/components/Checkbox/sgds-checkbox.cjs.js.map +1 -1
  136. package/react/components/Checkbox/sgds-checkbox.js +3 -0
  137. package/react/components/Checkbox/sgds-checkbox.js.map +1 -1
  138. package/react/components/CloseButton/close-button.cjs.js +1 -1
  139. package/react/components/CloseButton/close-button.cjs.js.map +1 -1
  140. package/react/components/CloseButton/close-button.js +1 -1
  141. package/react/components/CloseButton/close-button.js.map +1 -1
  142. package/react/components/ComboBox/combo-box.cjs.js +1 -1
  143. package/react/components/ComboBox/combo-box.cjs.js.map +1 -1
  144. package/react/components/ComboBox/combo-box.js +1 -1
  145. package/react/components/ComboBox/combo-box.js.map +1 -1
  146. package/react/components/ComboBox/sgds-combo-box.cjs.js +95 -4
  147. package/react/components/ComboBox/sgds-combo-box.cjs.js.map +1 -1
  148. package/react/components/ComboBox/sgds-combo-box.js +95 -4
  149. package/react/components/ComboBox/sgds-combo-box.js.map +1 -1
  150. package/react/components/DataTable/data-table.cjs.js +1 -1
  151. package/react/components/DataTable/data-table.cjs.js.map +1 -1
  152. package/react/components/DataTable/data-table.js +1 -1
  153. package/react/components/DataTable/data-table.js.map +1 -1
  154. package/react/components/DataTable/sgds-data-table-row.cjs.js +12 -4
  155. package/react/components/DataTable/sgds-data-table-row.cjs.js.map +1 -1
  156. package/react/components/DataTable/sgds-data-table-row.js +12 -4
  157. package/react/components/DataTable/sgds-data-table-row.js.map +1 -1
  158. package/react/components/DataTable/sgds-data-table.cjs.js +1 -2
  159. package/react/components/DataTable/sgds-data-table.cjs.js.map +1 -1
  160. package/react/components/DataTable/sgds-data-table.js +1 -2
  161. package/react/components/DataTable/sgds-data-table.js.map +1 -1
  162. package/react/components/Dropdown/sgds-dropdown.cjs.js +1 -1
  163. package/react/components/Dropdown/sgds-dropdown.cjs.js.map +1 -1
  164. package/react/components/Dropdown/sgds-dropdown.js +1 -1
  165. package/react/components/Dropdown/sgds-dropdown.js.map +1 -1
  166. package/react/components/Input/sgds-input.cjs.js +1 -0
  167. package/react/components/Input/sgds-input.cjs.js.map +1 -1
  168. package/react/components/Input/sgds-input.js +1 -0
  169. package/react/components/Input/sgds-input.js.map +1 -1
  170. package/react/components/Mainnav/sgds-mainnav.cjs.js +1 -1
  171. package/react/components/Mainnav/sgds-mainnav.cjs.js.map +1 -1
  172. package/react/components/Mainnav/sgds-mainnav.js +1 -1
  173. package/react/components/Mainnav/sgds-mainnav.js.map +1 -1
  174. package/react/components/Modal/modal.cjs.js +1 -1
  175. package/react/components/Modal/modal.cjs.js.map +1 -1
  176. package/react/components/Modal/modal.js +1 -1
  177. package/react/components/Modal/modal.js.map +1 -1
  178. package/react/components/Modal/sgds-modal.cjs.js +1 -1
  179. package/react/components/Modal/sgds-modal.cjs.js.map +1 -1
  180. package/react/components/Modal/sgds-modal.js +1 -1
  181. package/react/components/Modal/sgds-modal.js.map +1 -1
  182. package/react/components/Select/sgds-select.cjs.js +1 -1
  183. package/react/components/Select/sgds-select.cjs.js.map +1 -1
  184. package/react/components/Select/sgds-select.js +1 -1
  185. package/react/components/Select/sgds-select.js.map +1 -1
  186. package/react/components/Sidenav/sgds-sidenav.cjs.js +1 -1
  187. package/react/components/Sidenav/sgds-sidenav.cjs.js.map +1 -1
  188. package/react/components/Sidenav/sgds-sidenav.js +1 -1
  189. package/react/components/Sidenav/sgds-sidenav.js.map +1 -1
  190. package/react/components/SystemBanner/sgds-system-banner.cjs.js +2 -0
  191. package/react/components/SystemBanner/sgds-system-banner.cjs.js.map +1 -1
  192. package/react/components/SystemBanner/sgds-system-banner.js +2 -0
  193. package/react/components/SystemBanner/sgds-system-banner.js.map +1 -1
  194. package/themes/night.css +8 -8
  195. package/types/react.d.ts +9 -0
@@ -4,17 +4,18 @@ import { SgdsBadge } from "../Badge/sgds-badge";
4
4
  import SgdsIcon from "../Icon/sgds-icon";
5
5
  import { SgdsComboBoxOption } from "./sgds-combo-box-option";
6
6
  import SgdsSpinner from "../Spinner/sgds-spinner";
7
- import { ISgdsComboBoxInputEventDetail } from "./types";
7
+ import { ISgdsComboBoxInputEventDetail, ISgdsComboBoxCreateOptionEventDetail } from "./types";
8
8
  /**
9
9
  * Each item in the ComboBox has a label to display
10
10
  * and a value (the actual data / ID).
11
11
  */
12
12
  type SgdsComboBoxOptionData = SgdsOptionData;
13
- export type { ISgdsComboBoxInputEventDetail };
13
+ export type { ISgdsComboBoxCreateOptionEventDetail, ISgdsComboBoxInputEventDetail };
14
14
  /**
15
15
  * @summary ComboBox component is used for users to make one or more selections from a list through user input, keyboard or mouse actions
16
16
  *
17
17
  * @slot default - default slot to pass in sgds-combo-box-option
18
+ * @slot create - Custom content for the "Create" option shown when `creatable` is true and no match is found. Use `sgds-input` event to dynamically update the slotted content with the current input value.
18
19
  *
19
20
  * @event sgds-select - Emitted when the combo box's selected value changes.
20
21
  * @event sgds-change - Emitted when the combo box's value changes.
@@ -25,6 +26,8 @@ export type { ISgdsComboBoxInputEventDetail };
25
26
  * @event sgds-invalid - Emitted when the combo box's invalid state is set to true.
26
27
  * @event sgds-valid - Emitted when the combo box's invalid state is set to false.
27
28
  * @event sgds-scroll-end - Emitted once when the menu is scrolled to within `scrollBottomOffset` pixels of the bottom. Resets when the user scrolls back up.
29
+ * @event sgds-create-option - Emitted when the user selects the "Create xxx" option. `event.detail = { value }`
30
+ * @eventDetail {ISgdsComboBoxCreateOptionEventDetail} sgds-create-option
28
31
  */
29
32
  export declare class SgdsComboBox extends SelectElement {
30
33
  static styles: import("lit").CSSResult[];
@@ -48,6 +51,8 @@ export declare class SgdsComboBox extends SelectElement {
48
51
  async: boolean;
49
52
  /** When filtering remotely and there are no results, set this to true to enable no options feedback on the menu. Applicable for async combo box only. */
50
53
  emptyMenuAsync: boolean;
54
+ /** When true, shows a "Create xxx" option when the typed value does not match any existing option. Selecting it emits the `sgds-create-option` event. */
55
+ creatable: boolean;
51
56
  /** Number of pixels from the bottom of the menu at which the sgds-scroll-end event fires. */
52
57
  scrollBottomOffset: number;
53
58
  /** The function used to filter the menu list, given the user's input value. */
@@ -100,6 +105,22 @@ export declare class SgdsComboBox extends SelectElement {
100
105
  * For a list created using repeat, the repeat directive reorders the existing DOM nodes, so the nodes representing the first list item move to the last position.
101
106
  */
102
107
  protected _renderInput(showClearButton: boolean): TemplateResult;
108
+ /** Slotted elements from the `create-option` named slot. */
109
+ private _createOptionSlotContent;
110
+ /** The typed value captured when the create option was last synced. */
111
+ private _createOptionValue;
112
+ /** Whether the shadow-DOM create-option container is visible. */
113
+ private _showCreateOption;
114
+ /** Updates visibility of the create-option container based on creatable + filter state. */
115
+ private _syncCreateOption;
116
+ /** Handles slotchange for the create-option named slot. */
117
+ private _handleCreateOptionSlotChange;
118
+ /** Click handler for the create-option container. Lets interactive slotted elements (links, buttons) pass through. */
119
+ private _handleCreateOptionClick;
120
+ /** Keydown handler for the create-option container. */
121
+ private _handleCreateOptionKeydown;
122
+ /** Override base keyboard handler to include create-option in ArrowDown/Tab navigation. */
123
+ protected _handleKeyboardMenuItemsEvent(e: KeyboardEvent): void;
103
124
  protected _renderFeedbackMenu(): typeof nothing | TemplateResult<1>;
104
125
  render(): TemplateResult<1>;
105
126
  }
@@ -19,6 +19,7 @@ import { repeat } from "lit/directives/repeat.js";
19
19
  * @summary ComboBox component is used for users to make one or more selections from a list through user input, keyboard or mouse actions
20
20
  *
21
21
  * @slot default - default slot to pass in sgds-combo-box-option
22
+ * @slot create - Custom content for the "Create" option shown when `creatable` is true and no match is found. Use `sgds-input` event to dynamically update the slotted content with the current input value.
22
23
  *
23
24
  * @event sgds-select - Emitted when the combo box's selected value changes.
24
25
  * @event sgds-change - Emitted when the combo box's value changes.
@@ -29,6 +30,8 @@ import { repeat } from "lit/directives/repeat.js";
29
30
  * @event sgds-invalid - Emitted when the combo box's invalid state is set to true.
30
31
  * @event sgds-valid - Emitted when the combo box's invalid state is set to false.
31
32
  * @event sgds-scroll-end - Emitted once when the menu is scrolled to within `scrollBottomOffset` pixels of the bottom. Resets when the user scrolls back up.
33
+ * @event sgds-create-option - Emitted when the user selects the "Create xxx" option. `event.detail = { value }`
34
+ * @eventDetail {ISgdsComboBoxCreateOptionEventDetail} sgds-create-option
32
35
  */
33
36
  var SgdsComboBox = class SgdsComboBox extends SelectElement {
34
37
  constructor(..._args) {
@@ -39,6 +42,7 @@ var SgdsComboBox = class SgdsComboBox extends SelectElement {
39
42
  this.noValidate = false;
40
43
  this.async = false;
41
44
  this.emptyMenuAsync = false;
45
+ this.creatable = false;
42
46
  this.scrollBottomOffset = 0;
43
47
  this.filterFunction = (inputValue, item) => {
44
48
  return item.label.toLowerCase().startsWith(inputValue.toLowerCase());
@@ -52,6 +56,9 @@ var SgdsComboBox = class SgdsComboBox extends SelectElement {
52
56
  size="md"
53
57
  ></sgds-icon>`;
54
58
  this.prefixIconTemplate = html`${nothing}`;
59
+ this._createOptionSlotContent = [];
60
+ this._createOptionValue = "";
61
+ this._showCreateOption = false;
55
62
  }
56
63
  static {
57
64
  this.styles = [
@@ -84,7 +91,9 @@ var SgdsComboBox = class SgdsComboBox extends SelectElement {
84
91
  });
85
92
  this.addEventListener("sgds-hide", async (e) => {
86
93
  if (!e.detail.isOutside) (await this._input).focus();
87
- this.options.forEach((o) => o.removeAttribute("hidden"));
94
+ this.options.forEach((o) => {
95
+ o.removeAttribute("hidden");
96
+ });
88
97
  this.emptyMenuAfterFiltering = false;
89
98
  });
90
99
  }
@@ -124,7 +133,8 @@ var SgdsComboBox = class SgdsComboBox extends SelectElement {
124
133
  });
125
134
  /** this will trigger _updateValueAndDisplayValue */
126
135
  await this.updateComplete;
127
- this.optionList = await this._getMenuListFromOptions(assignedElements);
136
+ const realOptions = assignedElements;
137
+ this.optionList = await this._getMenuListFromOptions(realOptions);
128
138
  this._setupValidation(this.optionList);
129
139
  }
130
140
  async _setupValidation(list) {
@@ -139,7 +149,9 @@ var SgdsComboBox = class SgdsComboBox extends SelectElement {
139
149
  this._mixinValidate(this.input);
140
150
  }
141
151
  async _handleValueChange() {
142
- this.options.forEach((o) => o.removeAttribute("hidden"));
152
+ this.options.forEach((o) => {
153
+ o.removeAttribute("hidden");
154
+ });
143
155
  const sgdsInput = await this._input;
144
156
  this._mixinSetFormValue();
145
157
  if (this.multiSelect) this._mixinValidate(this.input);
@@ -201,6 +213,7 @@ var SgdsComboBox = class SgdsComboBox extends SelectElement {
201
213
  if (!filteredValues.includes(o.value)) o.hidden = true;
202
214
  else o.hidden = false;
203
215
  });
216
+ this._syncCreateOption();
204
217
  }
205
218
  /**
206
219
  * Called whenever an <sgds-combo-box-option> dispatches sgds-select"
@@ -218,6 +231,7 @@ var SgdsComboBox = class SgdsComboBox extends SelectElement {
218
231
  if (!this.selectedItems.some((i) => i.value === foundItem.value)) this.selectedItems = [...this.selectedItems, foundItem];
219
232
  this.value = this.selectedItems.map((i) => i.value).join(";");
220
233
  itemEl.active = true;
234
+ this.displayValue = "";
221
235
  } else if (this.selectedItems.length === 0 || this.selectedItems[0].value !== foundItem.value) {
222
236
  this.options.forEach((o) => o.active = false);
223
237
  itemEl.active = true;
@@ -268,6 +282,8 @@ var SgdsComboBox = class SgdsComboBox extends SelectElement {
268
282
  async _handleInputBlur(e) {
269
283
  e.preventDefault();
270
284
  this.emit("sgds-blur");
285
+ const relatedTarget = e.relatedTarget;
286
+ if ((this.creatable || this.multiSelect) && relatedTarget && (this.contains(relatedTarget) || this.shadowRoot?.contains(relatedTarget))) return;
271
287
  if (this.multiSelect) {
272
288
  if (this.selectedItems.filter(({ label }) => this.displayValue === label).length <= 0) this.displayValue = "";
273
289
  } else if (this.selectedItems.length > 0) this.displayValue = this.selectedItems[0].label;
@@ -392,10 +408,68 @@ var SgdsComboBox = class SgdsComboBox extends SelectElement {
392
408
  </div>
393
409
  `;
394
410
  }
411
+ /** Updates visibility of the create-option container based on creatable + filter state. */
412
+ _syncCreateOption() {
413
+ this._showCreateOption = this.creatable && this.emptyMenuAfterFiltering && this.displayValue !== "";
414
+ if (this._showCreateOption) this._createOptionValue = this.displayValue;
415
+ }
416
+ /** Handles slotchange for the create-option named slot. */
417
+ _handleCreateOptionSlotChange(e) {
418
+ this._createOptionSlotContent = e.target.assignedElements({ flatten: true });
419
+ }
420
+ /** Click handler for the create-option container. Lets interactive slotted elements (links, buttons) pass through. */
421
+ _handleCreateOptionClick(evt) {
422
+ if (evt.composedPath()[0].closest?.("a, button")) return;
423
+ this.emit("sgds-create-option", { detail: { value: this._createOptionValue } });
424
+ this.emptyMenuAfterFiltering = false;
425
+ this._syncCreateOption();
426
+ this.hideMenu();
427
+ }
428
+ /** Keydown handler for the create-option container. */
429
+ _handleCreateOptionKeydown(evt) {
430
+ if (evt.key === "Enter") {
431
+ this._handleCreateOptionClick(evt);
432
+ return;
433
+ }
434
+ if (evt.key === "ArrowUp") {
435
+ evt.preventDefault();
436
+ const items = this._getActiveMenuItems();
437
+ if (items.length > 0) this._setMenuItem(items.length - 1);
438
+ return;
439
+ }
440
+ if (evt.key === "ArrowDown") {
441
+ evt.preventDefault();
442
+ if (this._getActiveMenuItems().length > 0) this._setMenuItem(0);
443
+ }
444
+ }
445
+ /** Override base keyboard handler to include create-option in ArrowDown/Tab navigation. */
446
+ _handleKeyboardMenuItemsEvent(e) {
447
+ const createDiv = this.shadowRoot?.querySelector(".create-option");
448
+ if (createDiv?.matches(":focus") && e.key === "Tab") return;
449
+ if (this._showCreateOption && (e.key === "ArrowDown" || e.key === "Tab" && !e.shiftKey)) {
450
+ const items = this._getActiveMenuItems();
451
+ if (items.length > 0) {
452
+ if (items[items.length - 1].shadowRoot?.querySelector(".dropdown-item")?.matches(":focus")) {
453
+ e.preventDefault();
454
+ createDiv?.focus();
455
+ return;
456
+ }
457
+ }
458
+ if (items.length === 0) {
459
+ e.preventDefault();
460
+ createDiv?.focus();
461
+ return;
462
+ }
463
+ }
464
+ super._handleKeyboardMenuItemsEvent(e);
465
+ }
395
466
  _renderFeedbackMenu() {
396
467
  if (this.loading) return this._renderLoadingMenu();
397
468
  if (this.async) return this.emptyMenuAsync || this.optionList.length === 0 ? this._renderEmptyMenu() : nothing;
398
- else return this.optionList.length === 0 || this.emptyMenuAfterFiltering && this.optionList.length > 0 ? this._renderEmptyMenu() : nothing;
469
+ else {
470
+ if (this.creatable && this.emptyMenuAfterFiltering && this.optionList.length > 0) return nothing;
471
+ return this.optionList.length === 0 || this.emptyMenuAfterFiltering && this.optionList.length > 0 ? this._renderEmptyMenu() : nothing;
472
+ }
399
473
  }
400
474
  render() {
401
475
  const showClearButton = (this.isFocused || this.menuIsOpen) && this.value !== "" && this.clearable && !this.readonly;
@@ -427,6 +501,18 @@ var SgdsComboBox = class SgdsComboBox extends SelectElement {
427
501
  class=${classMap({ "d-none": this.loading || this.emptyMenuAsync || this.optionList.length === 0 })}
428
502
  @slotchange=${this._handleDefaultSlotChange}
429
503
  ></slot>
504
+ ${this._showCreateOption ? html`<div
505
+ class=${classMap({
506
+ "create-option": true,
507
+ slotted: this._createOptionSlotContent.length > 0
508
+ })}
509
+ tabindex="0"
510
+ role="option"
511
+ @click=${this._handleCreateOptionClick}
512
+ @keydown=${this._handleCreateOptionKeydown}
513
+ >
514
+ ${this._createOptionSlotContent.length > 0 ? html`<slot name="create" @slotchange=${this._handleCreateOptionSlotChange}></slot>` : `Create "${this.displayValue}"`}
515
+ </div>` : html`<slot name="create" class="d-none" @slotchange=${this._handleCreateOptionSlotChange}></slot>`}
430
516
  ${this._renderFeedbackMenu()}
431
517
  </div>
432
518
  </div>
@@ -468,6 +554,10 @@ __decorate([property({
468
554
  type: Boolean,
469
555
  reflect: true
470
556
  })], SgdsComboBox.prototype, "emptyMenuAsync", void 0);
557
+ __decorate([property({
558
+ type: Boolean,
559
+ reflect: true
560
+ })], SgdsComboBox.prototype, "creatable", void 0);
471
561
  __decorate([property({
472
562
  type: Number,
473
563
  reflect: true
@@ -485,6 +575,7 @@ __decorate([state()], SgdsComboBox.prototype, "isScrollEnd", void 0);
485
575
  __decorate([watch("value", { waitUntilFirstUpdate: true })], SgdsComboBox.prototype, "_handleValueChange", null);
486
576
  __decorate([watch("optionList", { waitUntilFirstUpdate: true })], SgdsComboBox.prototype, "_handleOptionListChange", null);
487
577
  __decorate([watch("menuList", { waitUntilFirstUpdate: true })], SgdsComboBox.prototype, "_handleMenuListChange", null);
578
+ __decorate([state()], SgdsComboBox.prototype, "_showCreateOption", void 0);
488
579
  //#endregion
489
580
  export { SgdsComboBox, SgdsComboBox as default };
490
581
 
@@ -1 +1 @@
1
- {"version":3,"file":"sgds-combo-box.js","names":["formTextControlStyle","comboBoxStyle"],"sources":["../../../src/components/ComboBox/sgds-combo-box.ts"],"sourcesContent":["import { live } from \"lit/directives/live.js\";\nimport { html, nothing, PropertyValueMap, TemplateResult } from \"lit\";\nimport { property, queryAssignedElements, queryAsync, state } from \"lit/decorators.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport { ifDefined } from \"lit/directives/if-defined.js\";\n\nimport { ref } from \"lit/directives/ref.js\";\nimport { SelectElement, SgdsOptionData } from \"../../base/select-element\";\nimport { watch } from \"../../utils/watch\";\nimport { SgdsBadge } from \"../Badge/sgds-badge\";\nimport SgdsIcon from \"../Icon/sgds-icon\";\nimport comboBoxStyle from \"./combo-box.css\";\nimport formTextControlStyle from \"../../styles/form-text-control.css\";\nimport { SgdsComboBoxOption } from \"./sgds-combo-box-option\";\n\nimport { repeat } from \"lit/directives/repeat.js\";\nimport SgdsSpinner from \"../Spinner/sgds-spinner\";\nimport { ISgdsComboBoxInputEventDetail } from \"./types\";\n\n/**\n * Each item in the ComboBox has a label to display\n * and a value (the actual data / ID).\n */\ntype SgdsComboBoxOptionData = SgdsOptionData;\n\nexport type { ISgdsComboBoxInputEventDetail };\n\n/**\n * @summary ComboBox component is used for users to make one or more selections from a list through user input, keyboard or mouse actions\n *\n * @slot default - default slot to pass in sgds-combo-box-option\n *\n * @event sgds-select - Emitted when the combo box's selected value changes.\n * @event sgds-change - Emitted when the combo box's value changes.\n * @event sgds-input - Emitted when user input is received and its value changes. `event.detail = { displayValue }`\n * @eventDetail {ISgdsComboBoxInputEventDetail} sgds-input\n * @event sgds-focus - Emitted when user input is focused.\n * @event sgds-blur - Emitted when user input is blurred.\n * @event sgds-invalid - Emitted when the combo box's invalid state is set to true.\n * @event sgds-valid - Emitted when the combo box's invalid state is set to false.\n * @event sgds-scroll-end - Emitted once when the menu is scrolled to within `scrollBottomOffset` pixels of the bottom. Resets when the user scrolls back up.\n */\nexport class SgdsComboBox extends SelectElement {\n static styles = [...SelectElement.styles, formTextControlStyle, comboBoxStyle];\n static childName = \"sgds-combo-box-option\";\n /** @internal */\n static dependencies = {\n [SgdsComboBox.childName]: SgdsComboBoxOption,\n \"sgds-icon\": SgdsIcon,\n \"sgds-badge\": SgdsBadge,\n \"sgds-spinner\": SgdsSpinner\n };\n\n /** If true, renders multiple checkbox selection items. If false, single-select. */\n @property({ type: Boolean, reflect: true }) multiSelect = false;\n\n /** If true, renders badge that fills width of combobox */\n @property({ type: Boolean, reflect: true }) badgeFullWidth = false;\n\n /** If true, a clear button will be enabled on focus */\n @property({ type: Boolean, reflect: true }) clearable = false;\n\n /** Disables native and sgds validation for the combo box. */\n @property({ type: Boolean, reflect: true }) noValidate = false;\n\n /** Enables the asynchronous behaviour of a combo box. When true, filterFunction is ignored and filtering is done remotely. */\n @property({ type: Boolean, reflect: true }) async = false;\n\n /** When filtering remotely and there are no results, set this to true to enable no options feedback on the menu. Applicable for async combo box only. */\n @property({ type: Boolean, reflect: true }) emptyMenuAsync = false;\n\n /** Number of pixels from the bottom of the menu at which the sgds-scroll-end event fires. */\n @property({ type: Number, reflect: true }) scrollBottomOffset = 0;\n\n /** The function used to filter the menu list, given the user's input value. */\n @property()\n filterFunction: (inputValue: string, item: SgdsComboBoxOptionData) => boolean = (inputValue, item) => {\n return item.label.toLowerCase().startsWith(inputValue.toLowerCase());\n };\n\n @queryAsync(\"input#multi-select-input-tracker\") private _multiSelectInput: Promise<HTMLInputElement>;\n\n @queryAssignedElements({ flatten: true, selector: \"sgds-combo-box-option\" })\n protected options: SgdsComboBoxOption[];\n\n @state() private optionList: SgdsComboBoxOptionData[] = [];\n @state() private emptyMenuAfterFiltering = false;\n\n // Used to show and hide the clear button\n @state() protected isFocused = false;\n\n // Used to determine if the scroll reached the end with offset\n @state() protected isScrollEnd = false;\n\n connectedCallback(): void {\n super.connectedCallback();\n\n this.addEventListener(\"focus\", async () => {\n this.isFocused = true;\n });\n\n this.addEventListener(\"blur\", async () => {\n this.isFocused = false;\n });\n\n this.addEventListener(\"keydown\", (e: KeyboardEvent) => {\n if (\n e.key === \"Enter\" &&\n (e.target as HTMLElement).shadowRoot?.querySelector(\".form-clearable\")?.matches(\":focus\")\n ) {\n this._handleClear();\n }\n });\n\n this.addEventListener(\"sgds-hide\", async (e: CustomEvent) => {\n if (!e.detail.isOutside) {\n const sgdsInput = await this._input;\n sgdsInput.focus();\n }\n\n this.options.forEach(o => o.removeAttribute(\"hidden\"));\n // reset emptyMenu state\n this.emptyMenuAfterFiltering = false;\n });\n }\n\n async firstUpdated(changedProperties: PropertyValueMap<this>) {\n super.firstUpdated(changedProperties);\n if (this.async) this.filterFunction = () => true;\n this.menuList.forEach(o => {\n const comboBoxOption = document.createElement(\"sgds-combo-box-option\") as SgdsComboBoxOption;\n comboBoxOption.innerText = o.label;\n comboBoxOption.value = o.value;\n comboBoxOption.checkbox = this.multiSelect;\n comboBoxOption.active = this.value.includes(o.value);\n this.appendChild(comboBoxOption);\n });\n this._setupValidation(this.menuList);\n if (this.menuIsOpen) {\n await this.updateFloatingPosition();\n }\n }\n\n protected async _handleDefaultSlotChange(e: Event) {\n const assignedElements = (e.target as HTMLSlotElement).assignedElements({\n flatten: true\n }) as ComboBoxOptionWithFlag[];\n\n assignedElements.forEach(option => {\n // Handling of click events\n if (option.hasAttribute(\"disabled\")) return false;\n if (option.clickEventAdded) return false;\n option.addEventListener(\"click\", (evt: PointerEvent) => {\n evt.preventDefault();\n const optionTarget = evt.target as SgdsComboBoxOption;\n\n if (this.multiSelect) {\n optionTarget.active ? this._handleItemUnselect(evt) : this._handleItemSelected(evt);\n } else {\n this._handleItemSelected(evt);\n }\n\n return false;\n });\n option.clickEventAdded = true;\n option.addEventListener(\"keydown\", (evt: KeyboardEvent) => {\n if (evt.key === \"Enter\") {\n this.close = \"outside\";\n const optionTarget = evt.target as SgdsComboBoxOption;\n optionTarget.click();\n }\n });\n });\n\n /** this will trigger _updateValueAndDisplayValue */\n await this.updateComplete;\n this.optionList = await this._getMenuListFromOptions(assignedElements);\n this._setupValidation(this.optionList);\n }\n\n private async _setupValidation(list: SgdsComboBoxOptionData[]) {\n if (this.value && list.length > 0) {\n const valueArray = this.value.split(\";\");\n const initialSelectedItem = list.filter(({ value }) => valueArray.includes(value));\n this.selectedItems = [...initialSelectedItem, ...this.selectedItems];\n\n if (!this.multiSelect) {\n this.displayValue = initialSelectedItem[0]?.label;\n }\n }\n /** We want to run validation regardless of value or list present */\n this.multiSelect ? (this.input = await this._multiSelectInput) : (this.input = await this._input);\n this._mixinValidate(this.input);\n }\n\n @watch(\"value\", { waitUntilFirstUpdate: true })\n async _handleValueChange() {\n this.options.forEach(o => o.removeAttribute(\"hidden\"));\n\n const sgdsInput = await this._input;\n this._mixinSetFormValue();\n\n if (this.multiSelect) {\n this._mixinValidate(this.input);\n } else {\n this._mixinValidate(sgdsInput);\n }\n\n // When value is updated by user and it doesn't map to selectedItems, we should re-map selectedItems\n const selectedItemVal = this.selectedItems.map(val => val.value).join(\";\");\n if (selectedItemVal !== this.value) {\n this._updateValueAndDisplayValue(this.optionList);\n }\n\n if (!this._isTouched && this.value === \"\") return;\n if (this._mixinShouldSkipSgdsValidation()) return;\n this.invalid = !this._mixinReportValidity();\n }\n\n /** Emits sgds-change and sgds-select events. Call after setting this.value from user interaction. */\n private _emitChangeEvents() {\n this._mixinSetFormValue();\n this.emit(\"sgds-change\");\n if (this.value) {\n this.emit(\"sgds-select\");\n }\n }\n\n @watch(\"optionList\", { waitUntilFirstUpdate: true })\n _handleOptionListChange() {\n this._updateValueAndDisplayValue(this.optionList);\n }\n\n @watch(\"menuList\", { waitUntilFirstUpdate: true })\n _handleMenuListChange() {\n const newMenu = this.menuList.map(o => {\n const comboBoxOption = document.createElement(\"sgds-combo-box-option\") as SgdsComboBoxOption;\n comboBoxOption.innerText = o.label;\n comboBoxOption.value = o.value;\n comboBoxOption.checkbox = this.multiSelect;\n comboBoxOption.active = this.value.includes(o.value);\n return comboBoxOption;\n });\n\n this.replaceChildren(...newMenu);\n }\n\n private _updateValueAndDisplayValue(list: SgdsComboBoxOptionData[]) {\n const valueArray = this.value.split(\";\");\n const initialSelectedItem = list.filter(({ value }) => valueArray.includes(value));\n this.selectedItems = [...initialSelectedItem];\n // When the new filtered items don't match value we update it\n const updatedValue = initialSelectedItem.map(item => item.value).join(\";\");\n if (updatedValue !== this.value) {\n this.value = updatedValue;\n }\n // Disabling this condition for async combobox so that the display value in the input will not clear when menu options changes\n if (!this.multiSelect && !this.async) {\n this.displayValue = initialSelectedItem[0]?.label || \"\";\n }\n\n this.options.forEach(o => (o.active = valueArray.includes(o.value)));\n }\n\n // Called each time the user types in the <sgds-input>, we set .value and show the menu\n protected async _handleInputChange(e: CustomEvent) {\n const input = e.target as HTMLInputElement;\n this.displayValue = input.value;\n this.emit<ISgdsComboBoxInputEventDetail>(\"sgds-input\", { detail: { displayValue: this.displayValue } });\n this.invalid = false;\n this.showMenu();\n // reset menu list when displayValue is cleared\n if (this.displayValue === \"\" && !this.multiSelect) {\n this.selectedItems = [];\n this.value = this.selectedItems.join(\";\");\n this.options.forEach(o => (o.active = false));\n this._emitChangeEvents();\n }\n // There is a race condition in certain situations where this.optionList is not fully updated during slotchange\n // Hence instead of using this.optionList, we have to perform a query on the <sgds-combo-box-option> elements\n const optionList = this.options.map(o => ({ value: o.value, label: o.textContent.trim() }));\n this.filteredList = optionList.filter(item => this.filterFunction(this.displayValue, item));\n\n // Filtering for slots\n this.emptyMenuAfterFiltering = this.filteredList.length === 0;\n const filteredValues = this.filteredList.map(l => l.value);\n\n this.options.forEach(o => {\n if (!filteredValues.includes(o.value)) {\n o.hidden = true;\n } else {\n o.hidden = false;\n }\n });\n }\n\n /**\n * Called whenever an <sgds-combo-box-option> dispatches sgds-select\"\n */\n protected async _handleItemSelected(e: Event) {\n const itemEl = e.target as SgdsComboBoxOption;\n if (itemEl.disabled) return;\n\n const itemLabel = itemEl.textContent?.trim() ?? \"\";\n const itemValueAttr = itemEl.getAttribute(\"value\") ?? itemLabel;\n const foundItem = this.filteredList.find(i => i.value.toString() === itemValueAttr) || {\n label: itemLabel,\n value: itemValueAttr\n };\n\n if (this.multiSelect) {\n if (!this.selectedItems.some(i => i.value === foundItem.value)) {\n this.selectedItems = [...this.selectedItems, foundItem];\n }\n\n this.value = this.selectedItems.map(i => i.value).join(\";\");\n itemEl.active = true;\n } else {\n // Single-select\n // Only update active states if a new item is selected\n if (this.selectedItems.length === 0 || this.selectedItems[0].value !== foundItem.value) {\n // Remove active from all options\n this.options.forEach(o => (o.active = false));\n itemEl.active = true;\n\n this.selectedItems = [foundItem];\n this.value = foundItem.value.toString();\n this.displayValue = foundItem.label;\n this.hideMenu();\n }\n }\n this._emitChangeEvents();\n }\n\n private _handleItemUnselect(e: Event) {\n const itemEl = e.target as SgdsComboBoxOption;\n if (itemEl.disabled) return;\n\n itemEl.removeAttribute(\"active\");\n const itemLabel = itemEl.textContent?.trim() ?? \"\";\n const itemValueAttr = itemEl.getAttribute(\"value\") ?? itemLabel;\n const foundItem = this.filteredList.find(i => i.value.toString() === itemValueAttr) || {\n label: itemLabel,\n value: itemValueAttr\n };\n\n this.selectedItems = this.selectedItems.filter(i => i.value !== foundItem.value);\n this.value = this.selectedItems.map(i => i.value).join(\";\");\n this._emitChangeEvents();\n }\n\n private async _handleBadgeDismissed(e: CustomEvent, item: SgdsComboBoxOptionData) {\n e.preventDefault();\n const removedValue = item.value;\n this.options?.forEach(o => (o.value === removedValue ? (o.active = false) : null));\n this.selectedItems = this.selectedItems.filter(i => i.value !== item.value);\n this.value = this.selectedItems.map(i => i.value).join(\";\");\n this._emitChangeEvents();\n }\n\n private async _handleMultiSelectKeyDown(e: KeyboardEvent) {\n // Only do this in multi-select mode\n if (!this.multiSelect) {\n return;\n }\n\n if (e.key === \"Backspace\" && this.multiSelect) {\n if (this.displayValue.trim() === \"\" && this.selectedItems.length > 0) {\n const removedValue = this.selectedItems[this.selectedItems.length - 1].value;\n this.options?.forEach(o => (o.value === removedValue ? (o.active = false) : null));\n this.selectedItems = this.selectedItems.slice(0, -1);\n this.value = this.selectedItems.map(i => i.value).join(\";\");\n this._emitChangeEvents();\n }\n }\n }\n\n protected _handleFocus() {\n this.emit(\"sgds-focus\");\n }\n\n protected async _handleInputBlur(e: Event) {\n e.preventDefault();\n\n this.emit(\"sgds-blur\");\n\n if (this.multiSelect) {\n const displayValueMatchedSelectedItems = this.selectedItems.filter(({ label }) => this.displayValue === label);\n if (displayValueMatchedSelectedItems.length <= 0) {\n this.displayValue = \"\";\n }\n } else {\n // Single select\n if (this.selectedItems.length > 0) {\n this.displayValue = this.selectedItems[0].label;\n } else {\n this.displayValue = \"\";\n }\n }\n }\n\n // For clearing the value\n protected async _handleClear() {\n this.value = this.displayValue = \"\";\n this.options?.forEach(o => (o.active = false));\n this._emitChangeEvents();\n\n const sgdsInput = await this._input;\n sgdsInput.focus();\n this.showMenu();\n }\n\n /** For form reset */\n protected async _mixinResetFormControl() {\n this.value = this.defaultValue;\n if (!this.multiSelect) {\n //reset menu\n this.options.forEach(o => {\n o.active = o.value === this.value;\n });\n const initialOption = this.options.filter(o => o.value === this.value);\n if (initialOption.length <= 0) {\n this.displayValue = \"\";\n } else {\n this.displayValue = initialOption[0].textContent.trim();\n }\n this._mixinResetValidity(await this._input);\n } else {\n const valueArray = this.value.split(\";\");\n // reset menu\n this.options.forEach(o => {\n o.active = valueArray.includes(o.value);\n });\n const initialOption = this.options.filter(o => valueArray.includes(o.value));\n this.selectedItems = initialOption.map(o => ({ value: o.value, label: o.textContent.trim() }));\n this._mixinResetValidity(await this._multiSelectInput);\n }\n }\n\n /**\n * Handles scroll events on the menu. Emits `sgds-scroll-end` once when the\n * scroll position reaches within `scrollBottomOffset` pixels of the bottom.\n * The event is suppressed until the user scrolls back up, preventing repeated\n * emissions while the menu stays at the bottom.\n */\n private async _handleScroll(e: MouseEvent) {\n const ele = e.target as HTMLElement;\n if (ele) {\n const endOfScroll = ele.scrollHeight - ele.clientHeight;\n const offset = Math.max(0, this.scrollBottomOffset);\n\n if (ele.scrollTop >= endOfScroll - offset) {\n if (!this.isScrollEnd) {\n this.emit(\"sgds-scroll-end\");\n }\n this.isScrollEnd = true;\n } else {\n this.isScrollEnd = false;\n }\n }\n }\n\n /** Template for the suffix icon */\n protected suffixIconTemplate: TemplateResult = html`<sgds-icon\n name=${this.menuIsOpen ? \"chevron-up\" : \"chevron-down\"}\n size=\"md\"\n ></sgds-icon>`;\n\n protected prefixIconTemplate: TemplateResult = html`${nothing}`;\n /**\n * Used `repeat` helper from Lit to render instead of .map:\n * The reassigning of value is affecting the truncation on badge as it is not triggering the slot change event.\n *\n * To compare this to lit-html's default handling for lists, consider reversing a large list of names:\n * For a list created using Array.map, lit-html maintains the DOM nodes for the list items, but reassigns the values\n * For a list created using repeat, the repeat directive reorders the existing DOM nodes, so the nodes representing the first list item move to the last position.\n */\n protected _renderInput(showClearButton: boolean): TemplateResult {\n const wantFeedbackStyle = this.hasFeedback;\n const showButton = showClearButton;\n\n return html`\n <div\n ${ref(this.myDropdown)}\n class=\"form-control-group ${classMap({\n disabled: this.disabled,\n readonly: this.readonly,\n \"is-invalid\": this.invalid && wantFeedbackStyle\n })}\"\n @click=${this._handleClick}\n >\n ${this.prefixIconTemplate}\n <div class=\"combobox-input-container\">\n ${this.multiSelect\n ? html`\n ${repeat(\n this.selectedItems,\n item => item.value,\n item =>\n html`<sgds-badge\n outlined\n variant=\"neutral\"\n show\n ?dismissible=${!(this.readonly || this.disabled)}\n ?fullwidth=${this.badgeFullWidth}\n @sgds-hide=${e => this._handleBadgeDismissed(e, item)}\n >${item.label}</sgds-badge\n >`\n )}\n `\n : nothing}\n <input\n class=\"form-control\"\n type=\"text\"\n id=${this._controlId}\n name=${ifDefined(this.name)}\n placeholder=${ifDefined(this.placeholder)}\n aria-invalid=${this.invalid ? \"true\" : \"false\"}\n ?autofocus=${this.autofocus}\n ?disabled=${this.disabled}\n ?readonly=${this.readonly}\n ?required=${this.required}\n .value=${this.displayValue ? this.displayValue.trim() : \"\"}\n @input=${this._handleInputChange}\n @blur=${this._handleInputBlur}\n @focus=${this._handleFocus}\n aria-describedby=${ifDefined(this.invalid && this.hasFeedback ? `${this._controlId}-invalid` : undefined)}\n aria-labelledby=\"${this._labelId} ${this._controlId}Help ${this.invalid && this.hasFeedback\n ? `${this._controlId}-invalid`\n : \"\"}\"\n .autocomplete=${this.autocomplete}\n />\n </div>\n\n ${showButton\n ? html`\n <sgds-icon\n id=${`${this._controlId}-combobox-clear-button`}\n tabindex=\"0\"\n class=\"form-clearable\"\n name=\"xcircle-fill\"\n size=\"md\"\n @click=${this._handleClear}\n aria-label=\"Clear selections\"\n role=\"button\"\n ></sgds-icon>\n `\n : nothing}\n ${this.suffixIconTemplate}\n </div>\n `;\n }\n\n protected _renderFeedbackMenu() {\n if (this.loading) {\n return this._renderLoadingMenu();\n }\n // When async, the filtering is done by remote server, so we do not check for emptyMenu of combobox filterFunction\n if (this.async) {\n return this.emptyMenuAsync || this.optionList.length === 0 ? this._renderEmptyMenu() : nothing;\n } else {\n return this.optionList.length === 0 || // no options at all\n (this.emptyMenuAfterFiltering && this.optionList.length > 0) // check if filtering results in empty menu\n ? this._renderEmptyMenu()\n : nothing;\n }\n }\n\n render() {\n const showClearButton =\n (this.isFocused || this.menuIsOpen) && this.value !== \"\" && this.clearable && !this.readonly;\n return html`\n <div\n class=${classMap({\n \"form-control-container\": true,\n \"m-width-256\": true,\n disabled: this.disabled,\n combobox: true\n })}\n @keydown=${this._handleMultiSelectKeyDown}\n >\n ${this._renderLabel()}\n <!-- The input -->\n ${this._renderInput(showClearButton)} ${this._renderFeedback()}\n\n <div\n id=${this.dropdownMenuId}\n class=\"dropdown-menu\"\n tabindex=\"-1\"\n role=\"menu\"\n aria-label=${this.label || \"Options\"}\n ${ref(this.menuRef)}\n @scroll=${this._handleScroll}\n >\n <slot\n id=\"default\"\n class=${classMap({ \"d-none\": this.loading || this.emptyMenuAsync || this.optionList.length === 0 })}\n @slotchange=${this._handleDefaultSlotChange}\n ></slot>\n ${this._renderFeedbackMenu()}\n </div>\n </div>\n\n <!-- Required an input element for constraint validation -->\n ${this.multiSelect\n ? html`<input\n .value=${live(this.value)}\n id=\"multi-select-input-tracker\"\n class=\"visually-hidden\"\n ?required=${this.required}\n tabindex=\"-1\"\n aria-hidden=\"true\"\n .autocomplete=${this.autocomplete}\n />`\n : nothing}\n `;\n }\n}\n\ninterface ComboBoxOptionWithFlag extends SgdsComboBoxOption {\n clickEventAdded?: boolean;\n}\n\nexport default SgdsComboBox;\n\n//TODO:\n// Replace this.optionList ?\n// During slotchange event _handleDefaultSlotChange, we try to populate this.optionList to obtain value attribute and textContent as label from <sgds-combo-box-option>\n// However, it has race conditions in certain situation like nextjs, where the last option's label (essentially the slot of <sgds-combo-box-option>) may not be available immediately.\n// To circumvent this, I avoid relying on this.optionList to perform filterFunction onInput handler and query this.options directly at the point of user typing.\n// To prevent confusion, this.optionList should ideally be removed in future iterations\n"],"mappings":"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"}
1
+ {"version":3,"file":"sgds-combo-box.js","names":["formTextControlStyle","comboBoxStyle"],"sources":["../../../src/components/ComboBox/sgds-combo-box.ts"],"sourcesContent":["import { live } from \"lit/directives/live.js\";\nimport { html, nothing, PropertyValueMap, TemplateResult } from \"lit\";\nimport { property, queryAssignedElements, queryAsync, state } from \"lit/decorators.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport { ifDefined } from \"lit/directives/if-defined.js\";\n\nimport { ref } from \"lit/directives/ref.js\";\nimport { SelectElement, SgdsOptionData } from \"../../base/select-element\";\nimport { watch } from \"../../utils/watch\";\nimport { SgdsBadge } from \"../Badge/sgds-badge\";\nimport SgdsIcon from \"../Icon/sgds-icon\";\nimport comboBoxStyle from \"./combo-box.css\";\nimport formTextControlStyle from \"../../styles/form-text-control.css\";\nimport { SgdsComboBoxOption } from \"./sgds-combo-box-option\";\n\nimport { repeat } from \"lit/directives/repeat.js\";\nimport SgdsSpinner from \"../Spinner/sgds-spinner\";\nimport { ISgdsComboBoxInputEventDetail, ISgdsComboBoxCreateOptionEventDetail } from \"./types\";\n\n/**\n * Each item in the ComboBox has a label to display\n * and a value (the actual data / ID).\n */\ntype SgdsComboBoxOptionData = SgdsOptionData;\n\nexport type { ISgdsComboBoxCreateOptionEventDetail, ISgdsComboBoxInputEventDetail };\n\n/**\n * @summary ComboBox component is used for users to make one or more selections from a list through user input, keyboard or mouse actions\n *\n * @slot default - default slot to pass in sgds-combo-box-option\n * @slot create - Custom content for the \"Create\" option shown when `creatable` is true and no match is found. Use `sgds-input` event to dynamically update the slotted content with the current input value.\n *\n * @event sgds-select - Emitted when the combo box's selected value changes.\n * @event sgds-change - Emitted when the combo box's value changes.\n * @event sgds-input - Emitted when user input is received and its value changes. `event.detail = { displayValue }`\n * @eventDetail {ISgdsComboBoxInputEventDetail} sgds-input\n * @event sgds-focus - Emitted when user input is focused.\n * @event sgds-blur - Emitted when user input is blurred.\n * @event sgds-invalid - Emitted when the combo box's invalid state is set to true.\n * @event sgds-valid - Emitted when the combo box's invalid state is set to false.\n * @event sgds-scroll-end - Emitted once when the menu is scrolled to within `scrollBottomOffset` pixels of the bottom. Resets when the user scrolls back up.\n * @event sgds-create-option - Emitted when the user selects the \"Create xxx\" option. `event.detail = { value }`\n * @eventDetail {ISgdsComboBoxCreateOptionEventDetail} sgds-create-option\n */\nexport class SgdsComboBox extends SelectElement {\n static styles = [...SelectElement.styles, formTextControlStyle, comboBoxStyle];\n static childName = \"sgds-combo-box-option\";\n /** @internal */\n static dependencies = {\n [SgdsComboBox.childName]: SgdsComboBoxOption,\n \"sgds-icon\": SgdsIcon,\n \"sgds-badge\": SgdsBadge,\n \"sgds-spinner\": SgdsSpinner\n };\n\n /** If true, renders multiple checkbox selection items. If false, single-select. */\n @property({ type: Boolean, reflect: true }) multiSelect = false;\n\n /** If true, renders badge that fills width of combobox */\n @property({ type: Boolean, reflect: true }) badgeFullWidth = false;\n\n /** If true, a clear button will be enabled on focus */\n @property({ type: Boolean, reflect: true }) clearable = false;\n\n /** Disables native and sgds validation for the combo box. */\n @property({ type: Boolean, reflect: true }) noValidate = false;\n\n /** Enables the asynchronous behaviour of a combo box. When true, filterFunction is ignored and filtering is done remotely. */\n @property({ type: Boolean, reflect: true }) async = false;\n\n /** When filtering remotely and there are no results, set this to true to enable no options feedback on the menu. Applicable for async combo box only. */\n @property({ type: Boolean, reflect: true }) emptyMenuAsync = false;\n\n /** When true, shows a \"Create xxx\" option when the typed value does not match any existing option. Selecting it emits the `sgds-create-option` event. */\n @property({ type: Boolean, reflect: true }) creatable = false;\n\n /** Number of pixels from the bottom of the menu at which the sgds-scroll-end event fires. */\n @property({ type: Number, reflect: true }) scrollBottomOffset = 0;\n\n /** The function used to filter the menu list, given the user's input value. */\n @property()\n filterFunction: (inputValue: string, item: SgdsComboBoxOptionData) => boolean = (inputValue, item) => {\n return item.label.toLowerCase().startsWith(inputValue.toLowerCase());\n };\n\n @queryAsync(\"input#multi-select-input-tracker\") private _multiSelectInput: Promise<HTMLInputElement>;\n\n @queryAssignedElements({ flatten: true, selector: \"sgds-combo-box-option\" })\n protected options: SgdsComboBoxOption[];\n\n @state() private optionList: SgdsComboBoxOptionData[] = [];\n @state() private emptyMenuAfterFiltering = false;\n\n // Used to show and hide the clear button\n @state() protected isFocused = false;\n\n // Used to determine if the scroll reached the end with offset\n @state() protected isScrollEnd = false;\n\n connectedCallback(): void {\n super.connectedCallback();\n\n this.addEventListener(\"focus\", async () => {\n this.isFocused = true;\n });\n\n this.addEventListener(\"blur\", async () => {\n this.isFocused = false;\n });\n\n this.addEventListener(\"keydown\", (e: KeyboardEvent) => {\n if (\n e.key === \"Enter\" &&\n (e.target as HTMLElement).shadowRoot?.querySelector(\".form-clearable\")?.matches(\":focus\")\n ) {\n this._handleClear();\n }\n });\n\n this.addEventListener(\"sgds-hide\", async (e: CustomEvent) => {\n if (!e.detail.isOutside) {\n const sgdsInput = await this._input;\n sgdsInput.focus();\n }\n\n this.options.forEach(o => {\n o.removeAttribute(\"hidden\");\n });\n // reset emptyMenu state\n this.emptyMenuAfterFiltering = false;\n });\n }\n\n async firstUpdated(changedProperties: PropertyValueMap<this>) {\n super.firstUpdated(changedProperties);\n if (this.async) this.filterFunction = () => true;\n this.menuList.forEach(o => {\n const comboBoxOption = document.createElement(\"sgds-combo-box-option\") as SgdsComboBoxOption;\n comboBoxOption.innerText = o.label;\n comboBoxOption.value = o.value;\n comboBoxOption.checkbox = this.multiSelect;\n comboBoxOption.active = this.value.includes(o.value);\n this.appendChild(comboBoxOption);\n });\n this._setupValidation(this.menuList);\n if (this.menuIsOpen) {\n await this.updateFloatingPosition();\n }\n }\n\n protected async _handleDefaultSlotChange(e: Event) {\n const assignedElements = (e.target as HTMLSlotElement).assignedElements({\n flatten: true\n }) as ComboBoxOptionWithFlag[];\n\n assignedElements.forEach(option => {\n // Handling of click events\n if (option.hasAttribute(\"disabled\")) return false;\n if (option.clickEventAdded) return false;\n\n option.addEventListener(\"click\", (evt: PointerEvent) => {\n evt.preventDefault();\n const optionTarget = evt.target as SgdsComboBoxOption;\n\n if (this.multiSelect) {\n optionTarget.active ? this._handleItemUnselect(evt) : this._handleItemSelected(evt);\n } else {\n this._handleItemSelected(evt);\n }\n\n return false;\n });\n option.clickEventAdded = true;\n option.addEventListener(\"keydown\", (evt: KeyboardEvent) => {\n if (evt.key === \"Enter\") {\n this.close = \"outside\";\n const optionTarget = evt.target as SgdsComboBoxOption;\n optionTarget.click();\n }\n });\n });\n\n /** this will trigger _updateValueAndDisplayValue */\n await this.updateComplete;\n const realOptions = assignedElements;\n this.optionList = await this._getMenuListFromOptions(realOptions);\n this._setupValidation(this.optionList);\n }\n\n private async _setupValidation(list: SgdsComboBoxOptionData[]) {\n if (this.value && list.length > 0) {\n const valueArray = this.value.split(\";\");\n const initialSelectedItem = list.filter(({ value }) => valueArray.includes(value));\n this.selectedItems = [...initialSelectedItem, ...this.selectedItems];\n\n if (!this.multiSelect) {\n this.displayValue = initialSelectedItem[0]?.label;\n }\n }\n /** We want to run validation regardless of value or list present */\n this.multiSelect ? (this.input = await this._multiSelectInput) : (this.input = await this._input);\n this._mixinValidate(this.input);\n }\n\n @watch(\"value\", { waitUntilFirstUpdate: true })\n async _handleValueChange() {\n this.options.forEach(o => {\n o.removeAttribute(\"hidden\");\n });\n\n const sgdsInput = await this._input;\n this._mixinSetFormValue();\n\n if (this.multiSelect) {\n this._mixinValidate(this.input);\n } else {\n this._mixinValidate(sgdsInput);\n }\n\n // When value is updated by user and it doesn't map to selectedItems, we should re-map selectedItems\n const selectedItemVal = this.selectedItems.map(val => val.value).join(\";\");\n if (selectedItemVal !== this.value) {\n this._updateValueAndDisplayValue(this.optionList);\n }\n\n if (!this._isTouched && this.value === \"\") return;\n if (this._mixinShouldSkipSgdsValidation()) return;\n this.invalid = !this._mixinReportValidity();\n }\n\n /** Emits sgds-change and sgds-select events. Call after setting this.value from user interaction. */\n private _emitChangeEvents() {\n this._mixinSetFormValue();\n this.emit(\"sgds-change\");\n if (this.value) {\n this.emit(\"sgds-select\");\n }\n }\n\n @watch(\"optionList\", { waitUntilFirstUpdate: true })\n _handleOptionListChange() {\n this._updateValueAndDisplayValue(this.optionList);\n }\n\n @watch(\"menuList\", { waitUntilFirstUpdate: true })\n _handleMenuListChange() {\n const newMenu = this.menuList.map(o => {\n const comboBoxOption = document.createElement(\"sgds-combo-box-option\") as SgdsComboBoxOption;\n comboBoxOption.innerText = o.label;\n comboBoxOption.value = o.value;\n comboBoxOption.checkbox = this.multiSelect;\n comboBoxOption.active = this.value.includes(o.value);\n return comboBoxOption;\n });\n\n this.replaceChildren(...newMenu);\n }\n\n private _updateValueAndDisplayValue(list: SgdsComboBoxOptionData[]) {\n const valueArray = this.value.split(\";\");\n const initialSelectedItem = list.filter(({ value }) => valueArray.includes(value));\n this.selectedItems = [...initialSelectedItem];\n // When the new filtered items don't match value we update it\n const updatedValue = initialSelectedItem.map(item => item.value).join(\";\");\n if (updatedValue !== this.value) {\n this.value = updatedValue;\n }\n // Disabling this condition for async combobox so that the display value in the input will not clear when menu options changes\n if (!this.multiSelect && !this.async) {\n this.displayValue = initialSelectedItem[0]?.label || \"\";\n }\n\n this.options.forEach(o => (o.active = valueArray.includes(o.value)));\n }\n\n // Called each time the user types in the <sgds-input>, we set .value and show the menu\n protected async _handleInputChange(e: CustomEvent) {\n const input = e.target as HTMLInputElement;\n this.displayValue = input.value;\n this.emit<ISgdsComboBoxInputEventDetail>(\"sgds-input\", { detail: { displayValue: this.displayValue } });\n this.invalid = false;\n this.showMenu();\n // reset menu list when displayValue is cleared\n if (this.displayValue === \"\" && !this.multiSelect) {\n this.selectedItems = [];\n this.value = this.selectedItems.join(\";\");\n this.options.forEach(o => (o.active = false));\n this._emitChangeEvents();\n }\n // There is a race condition in certain situations where this.optionList is not fully updated during slotchange\n // Hence instead of using this.optionList, we have to perform a query on the <sgds-combo-box-option> elements\n const realOptions = this.options;\n const optionList = realOptions.map(o => ({ value: o.value, label: o.textContent.trim() }));\n this.filteredList = optionList.filter(item => this.filterFunction(this.displayValue, item));\n\n // Filtering for slots\n this.emptyMenuAfterFiltering = this.filteredList.length === 0;\n const filteredValues = this.filteredList.map(l => l.value);\n\n this.options.forEach(o => {\n if (!filteredValues.includes(o.value)) {\n o.hidden = true;\n } else {\n o.hidden = false;\n }\n });\n this._syncCreateOption();\n }\n\n /**\n * Called whenever an <sgds-combo-box-option> dispatches sgds-select\"\n */\n protected async _handleItemSelected(e: Event) {\n const itemEl = e.target as SgdsComboBoxOption;\n if (itemEl.disabled) return;\n\n const itemLabel = itemEl.textContent?.trim() ?? \"\";\n const itemValueAttr = itemEl.getAttribute(\"value\") ?? itemLabel;\n const foundItem = this.filteredList.find(i => i.value.toString() === itemValueAttr) || {\n label: itemLabel,\n value: itemValueAttr\n };\n\n if (this.multiSelect) {\n if (!this.selectedItems.some(i => i.value === foundItem.value)) {\n this.selectedItems = [...this.selectedItems, foundItem];\n }\n\n this.value = this.selectedItems.map(i => i.value).join(\";\");\n itemEl.active = true;\n this.displayValue = \"\";\n } else {\n // Single-select\n // Only update active states if a new item is selected\n if (this.selectedItems.length === 0 || this.selectedItems[0].value !== foundItem.value) {\n // Remove active from all options\n this.options.forEach(o => (o.active = false));\n itemEl.active = true;\n\n this.selectedItems = [foundItem];\n this.value = foundItem.value.toString();\n this.displayValue = foundItem.label;\n this.hideMenu();\n }\n }\n this._emitChangeEvents();\n }\n\n private _handleItemUnselect(e: Event) {\n const itemEl = e.target as SgdsComboBoxOption;\n if (itemEl.disabled) return;\n\n itemEl.removeAttribute(\"active\");\n const itemLabel = itemEl.textContent?.trim() ?? \"\";\n const itemValueAttr = itemEl.getAttribute(\"value\") ?? itemLabel;\n const foundItem = this.filteredList.find(i => i.value.toString() === itemValueAttr) || {\n label: itemLabel,\n value: itemValueAttr\n };\n\n this.selectedItems = this.selectedItems.filter(i => i.value !== foundItem.value);\n this.value = this.selectedItems.map(i => i.value).join(\";\");\n this._emitChangeEvents();\n }\n\n private async _handleBadgeDismissed(e: CustomEvent, item: SgdsComboBoxOptionData) {\n e.preventDefault();\n const removedValue = item.value;\n this.options?.forEach(o => (o.value === removedValue ? (o.active = false) : null));\n this.selectedItems = this.selectedItems.filter(i => i.value !== item.value);\n this.value = this.selectedItems.map(i => i.value).join(\";\");\n this._emitChangeEvents();\n }\n\n private async _handleMultiSelectKeyDown(e: KeyboardEvent) {\n // Only do this in multi-select mode\n if (!this.multiSelect) {\n return;\n }\n\n if (e.key === \"Backspace\" && this.multiSelect) {\n if (this.displayValue.trim() === \"\" && this.selectedItems.length > 0) {\n const removedValue = this.selectedItems[this.selectedItems.length - 1].value;\n this.options?.forEach(o => (o.value === removedValue ? (o.active = false) : null));\n this.selectedItems = this.selectedItems.slice(0, -1);\n this.value = this.selectedItems.map(i => i.value).join(\";\");\n this._emitChangeEvents();\n }\n }\n }\n\n protected _handleFocus() {\n this.emit(\"sgds-focus\");\n }\n\n protected async _handleInputBlur(e: Event) {\n e.preventDefault();\n\n this.emit(\"sgds-blur\");\n\n // When focus is moving to an element inside this component (e.g. keyboard nav to an option),\n // preserve the typed input. If focus moves outside, clear as usual.\n const relatedTarget = (e as FocusEvent).relatedTarget as Node | null;\n if (\n (this.creatable || this.multiSelect) &&\n relatedTarget &&\n (this.contains(relatedTarget) || this.shadowRoot?.contains(relatedTarget))\n )\n return;\n\n if (this.multiSelect) {\n const displayValueMatchedSelectedItems = this.selectedItems.filter(({ label }) => this.displayValue === label);\n if (displayValueMatchedSelectedItems.length <= 0) {\n this.displayValue = \"\";\n }\n } else {\n // Single select\n if (this.selectedItems.length > 0) {\n this.displayValue = this.selectedItems[0].label;\n } else {\n this.displayValue = \"\";\n }\n }\n }\n\n // For clearing the value\n protected async _handleClear() {\n this.value = this.displayValue = \"\";\n this.options?.forEach(o => (o.active = false));\n this._emitChangeEvents();\n\n const sgdsInput = await this._input;\n sgdsInput.focus();\n this.showMenu();\n }\n\n /** For form reset */\n protected async _mixinResetFormControl() {\n this.value = this.defaultValue;\n if (!this.multiSelect) {\n //reset menu\n this.options.forEach(o => {\n o.active = o.value === this.value;\n });\n const initialOption = this.options.filter(o => o.value === this.value);\n if (initialOption.length <= 0) {\n this.displayValue = \"\";\n } else {\n this.displayValue = initialOption[0].textContent.trim();\n }\n this._mixinResetValidity(await this._input);\n } else {\n const valueArray = this.value.split(\";\");\n // reset menu\n this.options.forEach(o => {\n o.active = valueArray.includes(o.value);\n });\n const initialOption = this.options.filter(o => valueArray.includes(o.value));\n this.selectedItems = initialOption.map(o => ({ value: o.value, label: o.textContent.trim() }));\n this._mixinResetValidity(await this._multiSelectInput);\n }\n }\n\n /**\n * Handles scroll events on the menu. Emits `sgds-scroll-end` once when the\n * scroll position reaches within `scrollBottomOffset` pixels of the bottom.\n * The event is suppressed until the user scrolls back up, preventing repeated\n * emissions while the menu stays at the bottom.\n */\n private async _handleScroll(e: MouseEvent) {\n const ele = e.target as HTMLElement;\n if (ele) {\n const endOfScroll = ele.scrollHeight - ele.clientHeight;\n const offset = Math.max(0, this.scrollBottomOffset);\n\n if (ele.scrollTop >= endOfScroll - offset) {\n if (!this.isScrollEnd) {\n this.emit(\"sgds-scroll-end\");\n }\n this.isScrollEnd = true;\n } else {\n this.isScrollEnd = false;\n }\n }\n }\n\n /** Template for the suffix icon */\n protected suffixIconTemplate: TemplateResult = html`<sgds-icon\n name=${this.menuIsOpen ? \"chevron-up\" : \"chevron-down\"}\n size=\"md\"\n ></sgds-icon>`;\n\n protected prefixIconTemplate: TemplateResult = html`${nothing}`;\n /**\n * Used `repeat` helper from Lit to render instead of .map:\n * The reassigning of value is affecting the truncation on badge as it is not triggering the slot change event.\n *\n * To compare this to lit-html's default handling for lists, consider reversing a large list of names:\n * For a list created using Array.map, lit-html maintains the DOM nodes for the list items, but reassigns the values\n * For a list created using repeat, the repeat directive reorders the existing DOM nodes, so the nodes representing the first list item move to the last position.\n */\n protected _renderInput(showClearButton: boolean): TemplateResult {\n const wantFeedbackStyle = this.hasFeedback;\n const showButton = showClearButton;\n\n return html`\n <div\n ${ref(this.myDropdown)}\n class=\"form-control-group ${classMap({\n disabled: this.disabled,\n readonly: this.readonly,\n \"is-invalid\": this.invalid && wantFeedbackStyle\n })}\"\n @click=${this._handleClick}\n >\n ${this.prefixIconTemplate}\n <div class=\"combobox-input-container\">\n ${this.multiSelect\n ? html`\n ${repeat(\n this.selectedItems,\n item => item.value,\n item =>\n html`<sgds-badge\n outlined\n variant=\"neutral\"\n show\n ?dismissible=${!(this.readonly || this.disabled)}\n ?fullwidth=${this.badgeFullWidth}\n @sgds-hide=${e => this._handleBadgeDismissed(e, item)}\n >${item.label}</sgds-badge\n >`\n )}\n `\n : nothing}\n <input\n class=\"form-control\"\n type=\"text\"\n id=${this._controlId}\n name=${ifDefined(this.name)}\n placeholder=${ifDefined(this.placeholder)}\n aria-invalid=${this.invalid ? \"true\" : \"false\"}\n ?autofocus=${this.autofocus}\n ?disabled=${this.disabled}\n ?readonly=${this.readonly}\n ?required=${this.required}\n .value=${this.displayValue ? this.displayValue.trim() : \"\"}\n @input=${this._handleInputChange}\n @blur=${this._handleInputBlur}\n @focus=${this._handleFocus}\n aria-describedby=${ifDefined(this.invalid && this.hasFeedback ? `${this._controlId}-invalid` : undefined)}\n aria-labelledby=\"${this._labelId} ${this._controlId}Help ${this.invalid && this.hasFeedback\n ? `${this._controlId}-invalid`\n : \"\"}\"\n .autocomplete=${this.autocomplete}\n />\n </div>\n\n ${showButton\n ? html`\n <sgds-icon\n id=${`${this._controlId}-combobox-clear-button`}\n tabindex=\"0\"\n class=\"form-clearable\"\n name=\"xcircle-fill\"\n size=\"md\"\n @click=${this._handleClear}\n aria-label=\"Clear selections\"\n role=\"button\"\n ></sgds-icon>\n `\n : nothing}\n ${this.suffixIconTemplate}\n </div>\n `;\n }\n\n /** Slotted elements from the `create-option` named slot. */\n private _createOptionSlotContent: Element[] = [];\n\n /** The typed value captured when the create option was last synced. */\n private _createOptionValue = \"\";\n\n /** Whether the shadow-DOM create-option container is visible. */\n @state() private _showCreateOption = false;\n\n /** Updates visibility of the create-option container based on creatable + filter state. */\n private _syncCreateOption() {\n this._showCreateOption = this.creatable && this.emptyMenuAfterFiltering && this.displayValue !== \"\";\n if (this._showCreateOption) {\n this._createOptionValue = this.displayValue;\n }\n }\n\n /** Handles slotchange for the create-option named slot. */\n private _handleCreateOptionSlotChange(e: Event) {\n this._createOptionSlotContent = (e.target as HTMLSlotElement).assignedElements({ flatten: true });\n }\n\n /** Click handler for the create-option container. Lets interactive slotted elements (links, buttons) pass through. */\n private _handleCreateOptionClick(evt: Event) {\n const target = evt.composedPath()[0] as HTMLElement;\n if (target.closest?.(\"a, button\")) return;\n\n this.emit<ISgdsComboBoxCreateOptionEventDetail>(\"sgds-create-option\", {\n detail: { value: this._createOptionValue }\n });\n this.emptyMenuAfterFiltering = false;\n this._syncCreateOption();\n this.hideMenu();\n }\n\n /** Keydown handler for the create-option container. */\n private _handleCreateOptionKeydown(evt: KeyboardEvent) {\n if (evt.key === \"Enter\") {\n this._handleCreateOptionClick(evt);\n return;\n }\n // ArrowUp from create option → focus last menu item\n if (evt.key === \"ArrowUp\") {\n evt.preventDefault();\n const items = this._getActiveMenuItems();\n if (items.length > 0) {\n this._setMenuItem(items.length - 1);\n }\n return;\n }\n // ArrowDown from create option → wrap to first menu item\n if (evt.key === \"ArrowDown\") {\n evt.preventDefault();\n const items = this._getActiveMenuItems();\n if (items.length > 0) {\n this._setMenuItem(0);\n }\n }\n }\n\n /** Override base keyboard handler to include create-option in ArrowDown/Tab navigation. */\n protected override _handleKeyboardMenuItemsEvent(e: KeyboardEvent) {\n // When create-option div is focused, let Tab pass through naturally so it can reach\n // interactive elements inside slotted content (e.g. links)\n const createDiv = this.shadowRoot?.querySelector(\".create-option\") as HTMLElement;\n if (createDiv?.matches(\":focus\") && e.key === \"Tab\") {\n return;\n }\n\n if (this._showCreateOption && (e.key === \"ArrowDown\" || (e.key === \"Tab\" && !e.shiftKey))) {\n const items = this._getActiveMenuItems();\n if (items.length > 0) {\n const lastItem = items[items.length - 1];\n const lastItemFocused = lastItem.shadowRoot?.querySelector(\".dropdown-item\")?.matches(\":focus\");\n if (lastItemFocused) {\n e.preventDefault();\n createDiv?.focus();\n return;\n }\n }\n // When no items exist but create option is visible (empty filter), focus it\n if (items.length === 0) {\n e.preventDefault();\n createDiv?.focus();\n return;\n }\n }\n super._handleKeyboardMenuItemsEvent(e);\n }\n\n protected _renderFeedbackMenu() {\n if (this.loading) {\n return this._renderLoadingMenu();\n }\n // When async, the filtering is done by remote server, so we do not check for emptyMenu of combobox filterFunction\n if (this.async) {\n return this.emptyMenuAsync || this.optionList.length === 0 ? this._renderEmptyMenu() : nothing;\n } else {\n // When creatable, the create option is a slotted element — skip \"No options\"\n if (this.creatable && this.emptyMenuAfterFiltering && this.optionList.length > 0) {\n return nothing;\n }\n return this.optionList.length === 0 || (this.emptyMenuAfterFiltering && this.optionList.length > 0)\n ? this._renderEmptyMenu()\n : nothing;\n }\n }\n\n render() {\n const showClearButton =\n (this.isFocused || this.menuIsOpen) && this.value !== \"\" && this.clearable && !this.readonly;\n return html`\n <div\n class=${classMap({\n \"form-control-container\": true,\n \"m-width-256\": true,\n disabled: this.disabled,\n combobox: true\n })}\n @keydown=${this._handleMultiSelectKeyDown}\n >\n ${this._renderLabel()}\n <!-- The input -->\n ${this._renderInput(showClearButton)} ${this._renderFeedback()}\n\n <div\n id=${this.dropdownMenuId}\n class=\"dropdown-menu\"\n tabindex=\"-1\"\n role=\"menu\"\n aria-label=${this.label || \"Options\"}\n ${ref(this.menuRef)}\n @scroll=${this._handleScroll}\n >\n <slot\n id=\"default\"\n class=${classMap({ \"d-none\": this.loading || this.emptyMenuAsync || this.optionList.length === 0 })}\n @slotchange=${this._handleDefaultSlotChange}\n ></slot>\n ${this._showCreateOption\n ? html`<div\n class=${classMap({ \"create-option\": true, slotted: this._createOptionSlotContent.length > 0 })}\n tabindex=\"0\"\n role=\"option\"\n @click=${this._handleCreateOptionClick}\n @keydown=${this._handleCreateOptionKeydown}\n >\n ${this._createOptionSlotContent.length > 0\n ? html`<slot name=\"create\" @slotchange=${this._handleCreateOptionSlotChange}></slot>`\n : `Create \"${this.displayValue}\"`}\n </div>`\n : html`<slot name=\"create\" class=\"d-none\" @slotchange=${this._handleCreateOptionSlotChange}></slot>`}\n ${this._renderFeedbackMenu()}\n </div>\n </div>\n\n <!-- Required an input element for constraint validation -->\n ${this.multiSelect\n ? html`<input\n .value=${live(this.value)}\n id=\"multi-select-input-tracker\"\n class=\"visually-hidden\"\n ?required=${this.required}\n tabindex=\"-1\"\n aria-hidden=\"true\"\n .autocomplete=${this.autocomplete}\n />`\n : nothing}\n `;\n }\n}\n\ninterface ComboBoxOptionWithFlag extends SgdsComboBoxOption {\n clickEventAdded?: boolean;\n}\n\nexport default SgdsComboBox;\n\n//TODO:\n// Replace this.optionList ?\n// During slotchange event _handleDefaultSlotChange, we try to populate this.optionList to obtain value attribute and textContent as label from <sgds-combo-box-option>\n// However, it has race conditions in certain situation like nextjs, where the last option's label (essentially the slot of <sgds-combo-box-option>) may not be available immediately.\n// To circumvent this, I avoid relying on this.optionList to perform filterFunction onInput handler and query this.options directly at the point of user typing.\n// To prevent confusion, this.optionList should ideally be removed in future iterations\n"],"mappings":"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"}
@@ -1,3 +1,6 @@
1
+ export interface ISgdsComboBoxCreateOptionEventDetail {
2
+ value: string;
3
+ }
1
4
  export interface ISgdsComboBoxInputEventDetail {
2
5
  displayValue: string;
3
6
  }
@@ -1,6 +1,6 @@
1
1
  import { css } from "lit";
2
2
  //#region src/components/DataTable/data-table.css
3
- var css_248z = css`:host{display:contents}:host([layout=fixed]) .table{table-layout:fixed}.table{border-collapse:collapse;display:table;table-layout:auto;width:100%}.table-container{overflow-x:auto}.data-table{border:var(--sgds-border-width-1) solid;border-color:var(--sgds-border-color-muted);border-radius:var(--sgds-border-radius-none);display:flex;flex-direction:column;min-height:var(--sgds-dimension-56)}.footer{align-items:center;display:flex;justify-content:space-between;padding:var(--sgds-padding-sm) var(--sgds-padding-lg)}.skeleton-row{display:table-row}.skeleton-cell{border-bottom:var(--sgds-border-width-1) solid var(--sgds-border-color-muted);display:table-cell;height:var(--sgds-dimension-56);padding:var(--sgds-padding-sm) var(--sgds-padding-md);vertical-align:middle}.skeleton-cell.control-cell{width:var(--sgds-dimension-56)}.no-data{align-items:center;color:var(--sgds-text-color-subtle);display:flex;justify-content:center;min-height:var(--sgds-dimension-128);padding:var(--sgds-padding-sm) var(--sgds-padding-md)}.active:not(.sort-icon),tr:hover:not([data-header-row]){background-color:var(--sgds-bg-translucent-subtle);transition:background-color .15s ease}td,th{border-bottom:var(--sgds-border-width-1) solid var(--sgds-border-color-muted);vertical-align:middle}th[data-sorting]{cursor:pointer}th[data-sorting]:focus-visible{outline:var(--sgds-outline-focus);outline-offset:var(--sgds-outline-offset-focus)}.data-table-cell,.data-table-head,.footer,.no-data{align-items:center;display:flex;font-family:var(--sgds-font-family-brand);font-size:var(--sgds-font-size-label-sm);font-style:normal;letter-spacing:var(--sgds-letter-spacing-normal);line-height:var(--sgds-line-height-2-xs);min-height:var(--sgds-dimension-56);padding:var(--sgds-padding-sm) var(--sgds-padding-md)}.data-table-head{color:var(--sgds-color-default);font-weight:var(--sgds-font-weight-semibold);gap:var(--sgds-gap-2-xs)}.data-table-head ::slotted(sgds-data-table-head){font-size:var(--sgds-font-size-label-sm);font-weight:var(--sgds-font-weight-semibold);line-height:var(--sgds-line-height-2-xs)}.data-table-cell{font-weight:var(--sgds-font-weight-regular)}.data-table-cell ::slotted(sgds-data-table-cell){font-size:var(--sgds-font-size-label-sm);font-weight:var(--sgds-font-weight-regular);line-height:var(--sgds-line-height-2-xs)}.sort,.sort-button{align-items:center;display:inline-flex}.sort-button{background-color:var(--sgds-bg-transparent);border:var(--sgds-border-width-1) solid var(--sgds-border-color-transparent);border-radius:var(--sgds-form-border-radius-sm);color:var(--sgds-color-subtle);cursor:pointer;height:var(--sgds-dimension-20);justify-content:center;padding:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:var(--sgds-dimension-20)}.sort-button:hover{background-color:var(--sgds-bg-translucent-subtle);color:var(--sgds-color-default)}.sort-button:focus,.sort-button:focus-visible{background-color:var(--sgds-bg-translucent-subtle);border-color:transparent;outline:var(--sgds-outline-focus);outline-offset:var(--sgds-outline-offset-focus)}.sort-button:disabled{background-color:var(--sgds-bg-transparent);color:var(--sgds-color-muted);cursor:not-allowed}.sort-button.active{background-color:var(--sgds-primary-surface-translucent);color:var(--sgds-primary-color-default)}.sort-icon{display:inline-flex}.data-table-cell.align-right,.data-table-head.align-right{justify-content:flex-end;text-align:right}.control-cell{width:var(--sgds-dimension-56)}:host(.checkbox-cell) .data-table-cell,:host(.checkbox-cell) .data-table-head{padding:var(--sgds-padding-sm) var(--sgds-padding-md)}:host(.expand-cell) .data-table-cell{cursor:pointer;padding:var(--sgds-padding-md)}.expandable-td{border:0;padding:0}.expandable-content{background-color:var(--sgds-surface-raised);border-bottom:var(--sgds-border-width-1) solid var(--sgds-border-color-muted);padding:var(--sgds-padding-2-xl);padding-left:var(--sgds-padding-4-xl)}.hidden{display:none}`;
3
+ var css_248z = css`:host{display:contents}:host([layout=fixed]) .table{table-layout:fixed}.table{border-collapse:collapse;display:table;table-layout:auto;width:100%}.table-container{overflow-x:auto}.data-table{border:var(--sgds-border-width-1) solid;border-color:var(--sgds-border-color-muted);border-radius:var(--sgds-border-radius-none);display:flex;flex-direction:column;min-height:var(--sgds-dimension-56)}.footer{align-items:center;display:flex;justify-content:space-between;padding:var(--sgds-padding-sm) var(--sgds-padding-lg)}.skeleton-row{display:table-row}.skeleton-cell{border-bottom:var(--sgds-border-width-1) solid var(--sgds-border-color-muted);display:table-cell;height:var(--sgds-dimension-56);padding:var(--sgds-padding-sm) var(--sgds-padding-md);vertical-align:middle}.skeleton-cell.control-cell{width:var(--sgds-dimension-56)}.no-data{align-items:center;color:var(--sgds-text-color-subtle);display:flex;justify-content:center;min-height:var(--sgds-dimension-128);padding:var(--sgds-padding-sm) var(--sgds-padding-md)}.active:not(.sort-icon),tr:hover:not([data-header-row]){background-color:var(--sgds-bg-translucent-subtle);transition:background-color .15s ease}td,th{border-bottom:var(--sgds-border-width-1) solid var(--sgds-border-color-muted);vertical-align:middle}th[data-sorting]{cursor:pointer}th[data-sorting]:focus-visible{outline:var(--sgds-outline-focus);outline-offset:var(--sgds-outline-offset-focus)}.data-table-cell,.data-table-head,.footer,.no-data{align-items:center;display:flex;font-family:var(--sgds-font-family-brand);font-size:var(--sgds-font-size-label-sm);font-style:normal;letter-spacing:var(--sgds-letter-spacing-normal);line-height:var(--sgds-line-height-2-xs);min-height:var(--sgds-dimension-56);padding:var(--sgds-padding-sm) var(--sgds-padding-md)}.data-table-head{color:var(--sgds-color-default);font-weight:var(--sgds-font-weight-semibold);gap:var(--sgds-gap-2-xs)}.data-table-head ::slotted(sgds-data-table-head){font-size:var(--sgds-font-size-label-sm);font-weight:var(--sgds-font-weight-semibold);line-height:var(--sgds-line-height-2-xs)}.data-table-cell{font-weight:var(--sgds-font-weight-regular)}.data-table-cell ::slotted(sgds-data-table-cell){font-size:var(--sgds-font-size-label-sm);font-weight:var(--sgds-font-weight-regular);line-height:var(--sgds-line-height-2-xs)}.sort,.sort-button{align-items:center;display:inline-flex}.sort-button{background-color:var(--sgds-bg-transparent);border:var(--sgds-border-width-1) solid var(--sgds-border-color-transparent);border-radius:var(--sgds-form-border-radius-sm);color:var(--sgds-color-subtle);cursor:pointer;height:var(--sgds-dimension-20);justify-content:center;padding:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:var(--sgds-dimension-20)}.sort-button:hover{background-color:var(--sgds-bg-translucent-subtle);color:var(--sgds-color-default)}.sort-button:focus,.sort-button:focus-visible{background-color:var(--sgds-bg-translucent-subtle);border-color:transparent;outline:var(--sgds-outline-focus);outline-offset:var(--sgds-outline-offset-focus)}.sort-button:disabled{background-color:var(--sgds-bg-transparent);color:var(--sgds-color-muted);cursor:not-allowed}.sort-button.active{background-color:var(--sgds-primary-surface-translucent);color:var(--sgds-primary-color-default)}.sort-icon{display:inline-flex}.data-table-cell.align-right,.data-table-head.align-right{justify-content:flex-end;text-align:right}.control-cell{width:var(--sgds-dimension-56)}:host(.checkbox-cell) .data-table-cell,:host(.checkbox-cell) .data-table-head{padding:var(--sgds-padding-sm) var(--sgds-padding-md)}:host(.expand-cell) .data-table-cell{cursor:pointer;padding:var(--sgds-padding-md)}.expandable-td{border:0;padding:0}.expandable-content{background-color:var(--sgds-surface-raised);border-bottom:var(--sgds-border-width-1) solid var(--sgds-border-color-muted);padding:var(--sgds-padding-2-xl);padding-left:var(--sgds-padding-4-xl)}.hidden{display:none}.visually-hidden{clip:rect(0,0,0,0);border:0;height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;white-space:nowrap;width:1px}`;
4
4
  //#endregion
5
5
  export { css_248z as default };
6
6
 
@@ -1 +1 @@
1
- {"version":3,"file":"data-table.js","names":[],"sources":["../../../src/components/DataTable/data-table.css"],"sourcesContent":["/* shared default — overridden per component below */\n:host {\n display: contents;\n}\n\n/* ── sgds-data-table ──────────────────────────────────────────── */\n:host([layout=\"fixed\"]) .table {\n table-layout: fixed;\n}\n\n.table {\n display: table;\n width: 100%;\n table-layout: auto;\n border-collapse: collapse;\n}\n\n.table-container {\n overflow-x: auto;\n}\n\n.data-table {\n display: flex;\n flex-direction: column;\n min-height: var(--sgds-dimension-56);\n border: var(--sgds-border-width-1) solid;\n border-color: var(--sgds-border-color-muted);\n border-radius: var(--sgds-border-radius-none);\n}\n\n.footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: var(--sgds-padding-sm) var(--sgds-padding-lg);\n}\n\n.skeleton-row {\n display: table-row;\n}\n\n.skeleton-cell {\n display: table-cell;\n vertical-align: middle;\n height: var(--sgds-dimension-56);\n padding: var(--sgds-padding-sm) var(--sgds-padding-md);\n border-bottom: var(--sgds-border-width-1) solid var(--sgds-border-color-muted);\n}\n\n.skeleton-cell.control-cell {\n width: var(--sgds-dimension-56);\n}\n\n.no-data {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: var(--sgds-dimension-128);\n padding: var(--sgds-padding-sm) var(--sgds-padding-md);\n color: var(--sgds-text-color-subtle);\n}\n\n/* hover / expanded states — set CSS custom property on the row host,\n cells inherit it across the shadow boundary */\ntr:hover:not([data-header-row]),\n.active:not(.sort-icon) {\n background-color: var(--sgds-bg-translucent-subtle);\n transition: background-color 0.15s ease;\n}\n\n/* ── sgds-data-table-cell / sgds-data-table-head ─────────────── */\ntd,\nth {\n vertical-align: middle;\n border-bottom: var(--sgds-border-width-1) solid var(--sgds-border-color-muted);\n}\n\nth[data-sorting] {\n cursor: pointer;\n}\n\nth[data-sorting]:focus-visible {\n outline: var(--sgds-outline-focus);\n outline-offset: var(--sgds-outline-offset-focus);\n}\n\n.data-table-cell,\n.data-table-head,\n.footer,\n.no-data {\n display: flex;\n align-items: center;\n min-height: var(--sgds-dimension-56);\n padding: var(--sgds-padding-sm) var(--sgds-padding-md);\n font-family: var(--sgds-font-family-brand);\n font-size: var(--sgds-font-size-label-sm);\n font-style: normal;\n line-height: var(--sgds-line-height-2-xs);\n letter-spacing: var(--sgds-letter-spacing-normal);\n}\n\n.data-table-head {\n color: var(--sgds-color-default);\n font-weight: var(--sgds-font-weight-semibold);\n gap: var(--sgds-gap-2-xs);\n}\n\n.data-table-head ::slotted(sgds-data-table-head) {\n font-size: var(--sgds-font-size-label-sm);\n font-weight: var(--sgds-font-weight-semibold);\n line-height: var(--sgds-line-height-2-xs);\n}\n\n.data-table-cell {\n font-weight: var(--sgds-font-weight-regular);\n}\n\n.data-table-cell ::slotted(sgds-data-table-cell) {\n font-size: var(--sgds-font-size-label-sm);\n font-weight: var(--sgds-font-weight-regular);\n line-height: var(--sgds-line-height-2-xs);\n}\n\n.sort {\n display: inline-flex;\n align-items: center;\n}\n\n.sort-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--sgds-dimension-20);\n height: var(--sgds-dimension-20);\n padding: 0;\n border: var(--sgds-border-width-1) solid var(--sgds-border-color-transparent);\n border-radius: var(--sgds-form-border-radius-sm);\n background-color: var(--sgds-bg-transparent);\n color: var(--sgds-color-subtle);\n cursor: pointer;\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out,\n box-shadow 0.15s ease-in-out;\n}\n\n.sort-button:hover {\n background-color: var(--sgds-bg-translucent-subtle);\n color: var(--sgds-color-default);\n}\n\n.sort-button:focus,\n.sort-button:focus-visible {\n background-color: var(--sgds-bg-translucent-subtle);\n border-color: transparent;\n outline: var(--sgds-outline-focus);\n outline-offset: var(--sgds-outline-offset-focus);\n}\n\n.sort-button:disabled {\n background-color: var(--sgds-bg-transparent);\n color: var(--sgds-color-muted);\n cursor: not-allowed;\n}\n\n.sort-button.active {\n background-color: var(--sgds-primary-surface-translucent);\n color: var(--sgds-primary-color-default);\n}\n\n.sort-icon {\n display: inline-flex;\n}\n\n.data-table-head.align-right {\n justify-content: flex-end;\n text-align: right;\n}\n\n.data-table-cell.align-right {\n justify-content: flex-end;\n text-align: right;\n}\n\n/* control cell variants — applied as classes on the host */\n.control-cell {\n width: var(--sgds-dimension-56);\n}\n\n:host(.checkbox-cell) .data-table-cell,\n:host(.checkbox-cell) .data-table-head {\n padding: var(--sgds-padding-sm) var(--sgds-padding-md);\n}\n\n:host(.expand-cell) .data-table-cell {\n padding: var(--sgds-padding-md);\n cursor: pointer;\n}\n\n/* ── expandable content row ───────────────────────────────────── */\n.expandable-td {\n padding: 0;\n border: 0;\n}\n\n.expandable-content {\n background-color: var(--sgds-surface-raised);\n padding: var(--sgds-padding-2-xl);\n padding-left: var(--sgds-padding-4-xl);\n border-bottom: var(--sgds-border-width-1) solid var(--sgds-border-color-muted);\n}\n\n.hidden {\n display: none;\n}\n"],"mappings":""}
1
+ {"version":3,"file":"data-table.js","names":[],"sources":["../../../src/components/DataTable/data-table.css"],"sourcesContent":["/* shared default — overridden per component below */\n:host {\n display: contents;\n}\n\n/* ── sgds-data-table ──────────────────────────────────────────── */\n:host([layout=\"fixed\"]) .table {\n table-layout: fixed;\n}\n\n.table {\n display: table;\n width: 100%;\n table-layout: auto;\n border-collapse: collapse;\n}\n\n.table-container {\n overflow-x: auto;\n}\n\n.data-table {\n display: flex;\n flex-direction: column;\n min-height: var(--sgds-dimension-56);\n border: var(--sgds-border-width-1) solid;\n border-color: var(--sgds-border-color-muted);\n border-radius: var(--sgds-border-radius-none);\n}\n\n.footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: var(--sgds-padding-sm) var(--sgds-padding-lg);\n}\n\n.skeleton-row {\n display: table-row;\n}\n\n.skeleton-cell {\n display: table-cell;\n vertical-align: middle;\n height: var(--sgds-dimension-56);\n padding: var(--sgds-padding-sm) var(--sgds-padding-md);\n border-bottom: var(--sgds-border-width-1) solid var(--sgds-border-color-muted);\n}\n\n.skeleton-cell.control-cell {\n width: var(--sgds-dimension-56);\n}\n\n.no-data {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: var(--sgds-dimension-128);\n padding: var(--sgds-padding-sm) var(--sgds-padding-md);\n color: var(--sgds-text-color-subtle);\n}\n\n/* hover / expanded states — set CSS custom property on the row host,\n cells inherit it across the shadow boundary */\ntr:hover:not([data-header-row]),\n.active:not(.sort-icon) {\n background-color: var(--sgds-bg-translucent-subtle);\n transition: background-color 0.15s ease;\n}\n\n/* ── sgds-data-table-cell / sgds-data-table-head ─────────────── */\ntd,\nth {\n vertical-align: middle;\n border-bottom: var(--sgds-border-width-1) solid var(--sgds-border-color-muted);\n}\n\nth[data-sorting] {\n cursor: pointer;\n}\n\nth[data-sorting]:focus-visible {\n outline: var(--sgds-outline-focus);\n outline-offset: var(--sgds-outline-offset-focus);\n}\n\n.data-table-cell,\n.data-table-head,\n.footer,\n.no-data {\n display: flex;\n align-items: center;\n min-height: var(--sgds-dimension-56);\n padding: var(--sgds-padding-sm) var(--sgds-padding-md);\n font-family: var(--sgds-font-family-brand);\n font-size: var(--sgds-font-size-label-sm);\n font-style: normal;\n line-height: var(--sgds-line-height-2-xs);\n letter-spacing: var(--sgds-letter-spacing-normal);\n}\n\n.data-table-head {\n color: var(--sgds-color-default);\n font-weight: var(--sgds-font-weight-semibold);\n gap: var(--sgds-gap-2-xs);\n}\n\n.data-table-head ::slotted(sgds-data-table-head) {\n font-size: var(--sgds-font-size-label-sm);\n font-weight: var(--sgds-font-weight-semibold);\n line-height: var(--sgds-line-height-2-xs);\n}\n\n.data-table-cell {\n font-weight: var(--sgds-font-weight-regular);\n}\n\n.data-table-cell ::slotted(sgds-data-table-cell) {\n font-size: var(--sgds-font-size-label-sm);\n font-weight: var(--sgds-font-weight-regular);\n line-height: var(--sgds-line-height-2-xs);\n}\n\n.sort {\n display: inline-flex;\n align-items: center;\n}\n\n.sort-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--sgds-dimension-20);\n height: var(--sgds-dimension-20);\n padding: 0;\n border: var(--sgds-border-width-1) solid var(--sgds-border-color-transparent);\n border-radius: var(--sgds-form-border-radius-sm);\n background-color: var(--sgds-bg-transparent);\n color: var(--sgds-color-subtle);\n cursor: pointer;\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out,\n box-shadow 0.15s ease-in-out;\n}\n\n.sort-button:hover {\n background-color: var(--sgds-bg-translucent-subtle);\n color: var(--sgds-color-default);\n}\n\n.sort-button:focus,\n.sort-button:focus-visible {\n background-color: var(--sgds-bg-translucent-subtle);\n border-color: transparent;\n outline: var(--sgds-outline-focus);\n outline-offset: var(--sgds-outline-offset-focus);\n}\n\n.sort-button:disabled {\n background-color: var(--sgds-bg-transparent);\n color: var(--sgds-color-muted);\n cursor: not-allowed;\n}\n\n.sort-button.active {\n background-color: var(--sgds-primary-surface-translucent);\n color: var(--sgds-primary-color-default);\n}\n\n.sort-icon {\n display: inline-flex;\n}\n\n.data-table-head.align-right {\n justify-content: flex-end;\n text-align: right;\n}\n\n.data-table-cell.align-right {\n justify-content: flex-end;\n text-align: right;\n}\n\n/* control cell variants — applied as classes on the host */\n.control-cell {\n width: var(--sgds-dimension-56);\n}\n\n:host(.checkbox-cell) .data-table-cell,\n:host(.checkbox-cell) .data-table-head {\n padding: var(--sgds-padding-sm) var(--sgds-padding-md);\n}\n\n:host(.expand-cell) .data-table-cell {\n padding: var(--sgds-padding-md);\n cursor: pointer;\n}\n\n/* ── expandable content row ───────────────────────────────────── */\n.expandable-td {\n padding: 0;\n border: 0;\n}\n\n.expandable-content {\n background-color: var(--sgds-surface-raised);\n padding: var(--sgds-padding-2-xl);\n padding-left: var(--sgds-padding-4-xl);\n border-bottom: var(--sgds-border-width-1) solid var(--sgds-border-color-muted);\n}\n\n.hidden {\n display: none;\n}\n\n.visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n"],"mappings":""}