@tylertech/forge 3.9.0 → 3.9.2

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 (82) hide show
  1. package/custom-elements.json +22 -20
  2. package/dist/badge/forge-badge.css +1 -1
  3. package/dist/forge.css +0 -1
  4. package/dist/lib.js +7 -7
  5. package/dist/lib.js.map +3 -3
  6. package/dist/table/forge-table.css +0 -1
  7. package/esm/autocomplete/autocomplete-core.js +9 -12
  8. package/esm/autocomplete/autocomplete-utils.js +3 -2
  9. package/esm/badge/badge.js +1 -1
  10. package/esm/button/base/base-button-adapter.js +6 -5
  11. package/esm/button/base/base-button-constants.d.ts +2 -2
  12. package/esm/button-area/button-area-adapter.d.ts +0 -2
  13. package/esm/button-area/button-area-adapter.js +5 -3
  14. package/esm/button-area/button-area-core.js +0 -1
  15. package/esm/button-area/button-area.js +1 -1
  16. package/esm/button-toggle/button-toggle-group/button-toggle-group-core.js +0 -1
  17. package/esm/calendar/calendar-core.js +6 -4
  18. package/esm/calendar/calendar-dropdown/calendar-dropdown.js +1 -1
  19. package/esm/calendar/calendar-utils.js +1 -3
  20. package/esm/calendar/calendar.js +1 -1
  21. package/esm/color-picker/color-picker-core.js +6 -5
  22. package/esm/color-picker/color-picker-gradient-slider.d.ts +1 -1
  23. package/esm/color-picker/color-picker-gradient-slider.js +19 -30
  24. package/esm/core/configuration/global-configuration.js +0 -1
  25. package/esm/core/mixins/form/with-form-associated.js +6 -2
  26. package/esm/core/utils/a11y-utils.d.ts +2 -2
  27. package/esm/core/utils/date-utils.js +1 -1
  28. package/esm/core/utils/dismissible-stack.js +0 -1
  29. package/esm/core/utils/feature-detection.js +2 -2
  30. package/esm/date-picker/base/base-date-picker-adapter.d.ts +2 -1
  31. package/esm/date-picker/base/base-date-picker-adapter.js +4 -0
  32. package/esm/date-picker/base/base-date-picker-core.js +2 -4
  33. package/esm/date-picker/base/base-date-picker-utils.d.ts +2 -1
  34. package/esm/date-picker/date-picker-adapter.js +1 -1
  35. package/esm/date-picker/date-picker-core.js +2 -1
  36. package/esm/date-range-picker/date-range-picker-adapter.d.ts +2 -1
  37. package/esm/date-range-picker/date-range-picker-adapter.js +1 -1
  38. package/esm/date-range-picker/date-range-picker-core.js +4 -5
  39. package/esm/deprecated/icon-button/deprecated-icon-button-component-delegate.js +2 -1
  40. package/esm/dialog/dialog.js +1 -1
  41. package/esm/expansion-panel/expansion-panel-core.d.ts +4 -0
  42. package/esm/expansion-panel/expansion-panel-core.js +19 -11
  43. package/esm/field/field-core.js +2 -1
  44. package/esm/field/field.js +1 -1
  45. package/esm/file-picker/file-picker-core.js +1 -3
  46. package/esm/floating-action-button/floating-action-button-component-delegate.js +2 -1
  47. package/esm/icon/icon-core.js +1 -1
  48. package/esm/icon/icon-registry.js +1 -1
  49. package/esm/icon-button/icon-button-component-delegate.js +2 -1
  50. package/esm/label/label-aware.js +1 -3
  51. package/esm/list-dropdown/list-dropdown-core.js +4 -2
  52. package/esm/list-dropdown/list-dropdown-utils.js +6 -3
  53. package/esm/menu/menu-core.js +5 -6
  54. package/esm/menu/menu.js +2 -2
  55. package/esm/overlay/overlay-constants.d.ts +1 -1
  56. package/esm/overlay/overlay-constants.js +1 -1
  57. package/esm/overlay/overlay.d.ts +2 -2
  58. package/esm/overlay/overlay.js +2 -2
  59. package/esm/select/core/base-select-adapter.js +0 -1
  60. package/esm/select/core/base-select-core.js +70 -74
  61. package/esm/select/core/select-utils.d.ts +1 -1
  62. package/esm/select/core/select-utils.js +2 -2
  63. package/esm/select/select-dropdown/select-dropdown-adapter.js +1 -3
  64. package/esm/split-view/split-view-panel/split-view-panel.js +1 -1
  65. package/esm/table/table-utils.js +10 -12
  66. package/esm/tabs/tab-bar/tab-bar-core.js +2 -1
  67. package/esm/text-field/text-field-adapter.js +1 -3
  68. package/esm/time-picker/time-picker-core.js +5 -5
  69. package/esm/toast/toast-adapter.js +1 -1
  70. package/esm/toast/toast-core.js +1 -1
  71. package/esm/toast/toast.js +2 -1
  72. package/esm/tooltip/tooltip-adapter.d.ts +7 -0
  73. package/esm/tooltip/tooltip-adapter.js +10 -0
  74. package/esm/tooltip/tooltip-constants.d.ts +1 -0
  75. package/esm/tooltip/tooltip-constants.js +2 -1
  76. package/esm/tooltip/tooltip-core.js +3 -0
  77. package/esm/tooltip/tooltip.js +1 -1
  78. package/esm/view-switcher/view-switcher-core.js +2 -1
  79. package/package.json +1 -1
  80. package/sass/core/styles/tokens/badge/_tokens.scss +1 -1
  81. package/sass/table/forge-table.scss +0 -1
  82. package/sass/utils/_mixins.scss +7 -8
@@ -157,7 +157,7 @@ export class ListDropdownCore {
157
157
  handleKey(key) {
158
158
  switch (key) {
159
159
  case 'Enter':
160
- case 'NumpadEnter':
160
+ case 'NumpadEnter': {
161
161
  const activeOptionIndex = this.getActiveOptionIndex();
162
162
  const activeOption = this._nonDividerOptions[activeOptionIndex];
163
163
  if (this._canSelectOption(activeOption)) {
@@ -167,10 +167,11 @@ export class ListDropdownCore {
167
167
  }
168
168
  }
169
169
  break;
170
+ }
170
171
  case 'Up':
171
172
  case 'ArrowUp':
172
173
  case 'Down':
173
- case 'ArrowDown':
174
+ case 'ArrowDown': {
174
175
  const options = this._nonDividerOptions;
175
176
  if (options.length && options.every(o => !this._canSelectOption(o))) {
176
177
  return;
@@ -178,6 +179,7 @@ export class ListDropdownCore {
178
179
  const index = this._getNextActiveOptionIndex(key);
179
180
  this.activateOption(index);
180
181
  break;
182
+ }
181
183
  case 'Home':
182
184
  this.activateFirstOption();
183
185
  break;
@@ -285,7 +285,7 @@ export function createListItems(config, listElement, options, startIndex = 0, re
285
285
  if (!option.disabled && typeof config.cascadingElementFactory === 'function' && Array.isArray(option.options) && option.options.length) {
286
286
  // Create the trailing indicator icon to show that a child menu exists for this option.
287
287
  const optionIconElement = document.createElement('forge-icon');
288
- optionIconElement.name = 'arrow_right';
288
+ optionIconElement.name = 'arrow_right_alt';
289
289
  optionIconElement.slot = 'trailing';
290
290
  listItemElement.appendChild(optionIconElement);
291
291
  const nonDividerOptions = flatOptions.filter(o => !o.divider);
@@ -387,8 +387,11 @@ function getOptionsByGroup(options) {
387
387
  * @param type The type of option to detect.
388
388
  */
389
389
  export function isListDropdownOptionType(options, type) {
390
- const isOptionGroups = options.some((o) => isDefined(o) && isObject(o) && o.hasOwnProperty('options') && (o.hasOwnProperty('text') || o.hasOwnProperty('builder')));
391
- const isOptionTypes = options.some((o) => isDefined(o) && isObject(o) && o.hasOwnProperty('label') && o.hasOwnProperty('value'));
390
+ const isOptionGroups = options.some((o) => isDefined(o) &&
391
+ isObject(o) &&
392
+ Object.prototype.hasOwnProperty.call(o, 'options') &&
393
+ (Object.prototype.hasOwnProperty.call(o, 'text') || Object.prototype.hasOwnProperty.call(o, 'builder')));
394
+ const isOptionTypes = options.some((o) => isDefined(o) && isObject(o) && Object.prototype.hasOwnProperty.call(o, 'label') && Object.prototype.hasOwnProperty.call(o, 'value'));
392
395
  return (isOptionGroups && type === ListDropdownOptionType.Group) || (isOptionTypes && type === ListDropdownOptionType.Option);
393
396
  }
394
397
  export function getFlattenedOptions(options) {
@@ -88,9 +88,7 @@ export class MenuCore extends CascadingListDropdownAwareCore {
88
88
  }
89
89
  _flattenOptions(options) {
90
90
  if (isListDropdownOptionType(options, ListDropdownOptionType.Group)) {
91
- return options.reduce((previousValue, currentValue) => {
92
- return currentValue.options ? previousValue.concat(currentValue.options) : previousValue;
93
- }, []);
91
+ return options.reduce((previousValue, currentValue) => (currentValue.options ? previousValue.concat(currentValue.options) : previousValue), []);
94
92
  }
95
93
  return options;
96
94
  }
@@ -147,7 +145,7 @@ export class MenuCore extends CascadingListDropdownAwareCore {
147
145
  this._adapter.propagateKey(evt.code);
148
146
  }
149
147
  break;
150
- case 'Enter':
148
+ case 'Enter': {
151
149
  evt.preventDefault();
152
150
  if (!this._open) {
153
151
  evt.preventDefault();
@@ -163,6 +161,7 @@ export class MenuCore extends CascadingListDropdownAwareCore {
163
161
  this._adapter.toggleChildMenu(activeIndex);
164
162
  }
165
163
  break;
164
+ }
166
165
  case 'ArrowUp':
167
166
  case 'ArrowDown':
168
167
  if (this._open) {
@@ -184,7 +183,7 @@ export class MenuCore extends CascadingListDropdownAwareCore {
184
183
  this._closeDropdown();
185
184
  }
186
185
  break;
187
- case 'ArrowRight':
186
+ case 'ArrowRight': {
188
187
  if (this._open) {
189
188
  evt.stopImmediatePropagation();
190
189
  }
@@ -198,6 +197,7 @@ export class MenuCore extends CascadingListDropdownAwareCore {
198
197
  return;
199
198
  }
200
199
  break;
200
+ }
201
201
  }
202
202
  }
203
203
  async _openMenu({ fromKeyboard } = {}) {
@@ -220,7 +220,6 @@ export class MenuCore extends CascadingListDropdownAwareCore {
220
220
  const selectedValues = this._persistSelection ? this._getSelectedValues() : [];
221
221
  const config = {
222
222
  id: this._identifier,
223
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
224
223
  referenceElement: this._adapter.targetElement,
225
224
  type: ListDropdownType.Menu,
226
225
  options: this._options,
package/esm/menu/menu.js CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import { __decorate } from "tslib";
7
7
  import { attachShadowTemplate, coerceBoolean, customElement, ensureChild, coreProperty, isDefined } from '@tylertech/forge-core';
8
- import { tylIconArrowRight } from '@tylertech/tyler-icons';
8
+ import { tylIconArrowRightAlt } from '@tylertech/tyler-icons';
9
9
  import { IconRegistry } from '../icon';
10
10
  import { ListComponent } from '../list';
11
11
  import { ListDropdownAware } from '../list-dropdown/list-dropdown-aware';
@@ -43,7 +43,7 @@ let MenuComponent = class MenuComponent extends ListDropdownAware {
43
43
  }
44
44
  constructor() {
45
45
  super();
46
- IconRegistry.define(tylIconArrowRight);
46
+ IconRegistry.define(tylIconArrowRightAlt);
47
47
  this._core = new MenuCore(new MenuAdapter(this));
48
48
  attachShadowTemplate(this, template, styles);
49
49
  }
@@ -48,7 +48,7 @@ export declare const OVERLAY_CONSTANTS: {
48
48
  readonly DESCENDANT_TEST: "forge-overlay-descendant-test";
49
49
  };
50
50
  defaults: {
51
- readonly HIDE: "anchor-hidden";
51
+ readonly HIDE: "never";
52
52
  readonly FLIP: "auto";
53
53
  readonly SHIFT: "auto";
54
54
  };
@@ -37,7 +37,7 @@ const events = {
37
37
  DESCENDANT_TEST: `${elementName}-descendant-test`
38
38
  };
39
39
  const defaults = {
40
- HIDE: 'anchor-hidden',
40
+ HIDE: 'never',
41
41
  FLIP: 'auto',
42
42
  SHIFT: 'auto'
43
43
  };
@@ -40,7 +40,7 @@ declare global {
40
40
  * @property {OverlayPositionStrategy} [positionStrategy="fixed"] - The positioning strategy to use for the overlay. Valid values are `'fixed'` and `'absolute'`.
41
41
  * @property {IOverlayPosition} offset - The offset to apply to the overlay position relative to the anchor element.
42
42
  * @property {OverlayShiftState} [shift="auto"] - Whether or not the anchor element should shift along the side of the overlay when scrolling.
43
- * @property {OverlayHideState} [hide="anchor-hidden"] - Whether or not the overlay should hide itself when the anchor element is out of view.
43
+ * @property {OverlayHideState} [hide="never"] - Whether or not the overlay should hide itself when the anchor element is out of view.
44
44
  * @property {boolean} persistent - Whether or not the overlay handles light dismiss itself or not.
45
45
  * @property {OverlayFlipState} [flip="auto"] - Whether or not the overlay should flip to the opposite placement when not enough room.
46
46
  * @property {string} boundary - The id of the element to use as the boundary for the overlay.
@@ -62,7 +62,7 @@ declare global {
62
62
  * @attribute {string} [inline=false] - Whether or not the overlay should be rendered inline (not in the :top-layer).
63
63
  * @attribute {string} [placement="bottom"] - The placement of the overlay relative to the anchor element.
64
64
  * @attribute {string} [position-strategy="fixed"] - The positioning strategy to use for the overlay. Valid values are `'fixed'` and `'absolute'`.
65
- * @attribute {string} [hide="anchor-hidden"] - Whether or not the overlay should hide itself when the anchor element is out of view.
65
+ * @attribute {string} [hide="never"] - Whether or not the overlay should hide itself when the anchor element is out of view.
66
66
  * @attribute {string} persistent - Whether or not the overlay handles light dismiss itself or not.
67
67
  * @attribute {OverlayShiftState} [shift="auto"] - Whether or not the anchor element should shift along the side of the overlay when scrolling.
68
68
  * @attribute {OverlayFlipState} [flip="auto"] - Tells the overlay not to flip to the opposite placement when not enough room.
@@ -34,7 +34,7 @@ const styles = ':host{display:contents}:host([hidden]){display:none}.forge-overl
34
34
  * @property {OverlayPositionStrategy} [positionStrategy="fixed"] - The positioning strategy to use for the overlay. Valid values are `'fixed'` and `'absolute'`.
35
35
  * @property {IOverlayPosition} offset - The offset to apply to the overlay position relative to the anchor element.
36
36
  * @property {OverlayShiftState} [shift="auto"] - Whether or not the anchor element should shift along the side of the overlay when scrolling.
37
- * @property {OverlayHideState} [hide="anchor-hidden"] - Whether or not the overlay should hide itself when the anchor element is out of view.
37
+ * @property {OverlayHideState} [hide="never"] - Whether or not the overlay should hide itself when the anchor element is out of view.
38
38
  * @property {boolean} persistent - Whether or not the overlay handles light dismiss itself or not.
39
39
  * @property {OverlayFlipState} [flip="auto"] - Whether or not the overlay should flip to the opposite placement when not enough room.
40
40
  * @property {string} boundary - The id of the element to use as the boundary for the overlay.
@@ -56,7 +56,7 @@ const styles = ':host{display:contents}:host([hidden]){display:none}.forge-overl
56
56
  * @attribute {string} [inline=false] - Whether or not the overlay should be rendered inline (not in the :top-layer).
57
57
  * @attribute {string} [placement="bottom"] - The placement of the overlay relative to the anchor element.
58
58
  * @attribute {string} [position-strategy="fixed"] - The positioning strategy to use for the overlay. Valid values are `'fixed'` and `'absolute'`.
59
- * @attribute {string} [hide="anchor-hidden"] - Whether or not the overlay should hide itself when the anchor element is out of view.
59
+ * @attribute {string} [hide="never"] - Whether or not the overlay should hide itself when the anchor element is out of view.
60
60
  * @attribute {string} persistent - Whether or not the overlay handles light dismiss itself or not.
61
61
  * @attribute {OverlayShiftState} [shift="auto"] - Whether or not the anchor element should shift along the side of the overlay when scrolling.
62
62
  * @attribute {OverlayFlipState} [flip="auto"] - Tells the overlay not to flip to the opposite placement when not enough room.
@@ -45,7 +45,6 @@ export class BaseSelectAdapter extends BaseAdapter {
45
45
  optionClass = optionClass.split(' ');
46
46
  }
47
47
  return {
48
- // eslint-disable-next-line @typescript-eslint/no-extra-parens
49
48
  label: o.hasAttribute(OPTION_CONSTANTS.attributes.LABEL)
50
49
  ? o.getAttribute(OPTION_CONSTANTS.attributes.LABEL)
51
50
  : isDefined(o.label)
@@ -73,7 +73,7 @@ export class BaseSelectCore extends ListDropdownAwareCore {
73
73
  }
74
74
  get _flatOptions() {
75
75
  if (isSelectOptionType(this._options, SelectOptionType.Group)) {
76
- return [].concat.apply([], this._options.map(g => g.options));
76
+ return this._options.flatMap(g => g.options);
77
77
  }
78
78
  return this._options;
79
79
  }
@@ -162,84 +162,82 @@ export class BaseSelectCore extends ListDropdownAwareCore {
162
162
  * @param {number} optionIndex The index of the selected option.
163
163
  */
164
164
  async _onSelect(option, optionIndex, closeDropdown = true) {
165
- return new Promise(async (resolve) => {
166
- if (this._valueChanging) {
167
- return Promise.resolve(false);
168
- }
169
- const value = option ? option.value : '';
170
- const label = option ? option.label : '';
171
- // Store the current selections in case we need to rollback (if the event was cancelled)
172
- const prevValues = [...this._value];
173
- const prevSelectedValues = [...this._selectedValues];
174
- const prevSelectedLabels = [...this._selectedLabels];
175
- const prevSelectedIndexes = [...this._selectedIndexes];
176
- if (this._multiple) {
177
- if (this._selectedValues.includes(value)) {
178
- const index = this._selectedValues.indexOf(value);
179
- this._selectedValues.splice(index, 1);
180
- this._selectedLabels.splice(index, 1);
181
- this._selectedIndexes.splice(index, 1);
182
- }
183
- else {
184
- this._selectedValues.push(value);
185
- this._selectedLabels.push(label);
186
- this._selectedIndexes.push(optionIndex);
187
- }
165
+ if (this._valueChanging) {
166
+ return false;
167
+ }
168
+ const value = option ? option.value : '';
169
+ const label = option ? option.label : '';
170
+ // Store the current selections in case we need to rollback (if the event was cancelled)
171
+ const prevValues = [...this._value];
172
+ const prevSelectedValues = [...this._selectedValues];
173
+ const prevSelectedLabels = [...this._selectedLabels];
174
+ const prevSelectedIndexes = [...this._selectedIndexes];
175
+ if (this._multiple) {
176
+ if (this._selectedValues.includes(value)) {
177
+ const index = this._selectedValues.indexOf(value);
178
+ this._selectedValues.splice(index, 1);
179
+ this._selectedLabels.splice(index, 1);
180
+ this._selectedIndexes.splice(index, 1);
188
181
  }
189
182
  else {
190
- if (isDefined(value)) {
191
- this._selectedValues[0] = value;
192
- this._selectedLabels[0] = label;
193
- this._selectedIndexes[0] = optionIndex;
194
- }
195
- else {
196
- this._selectedValues = [];
197
- this._selectedLabels = [];
198
- this._selectedIndexes = [];
199
- }
183
+ this._selectedValues.push(value);
184
+ this._selectedLabels.push(label);
185
+ this._selectedIndexes.push(optionIndex);
200
186
  }
201
- this._value = [...this._selectedValues];
202
- const rollbackValue = () => {
203
- this._selectedValues = [...prevSelectedValues];
204
- this._selectedLabels = [...prevSelectedLabels];
205
- this._selectedIndexes = [...prevSelectedIndexes];
206
- this._value = [...prevValues];
207
- };
208
- const applyValue = () => {
209
- // If we're in multiselect mode, we need to toggle the selected option
210
- if (this._multiple) {
211
- const isSelected = this._selectedIndexes.includes(optionIndex);
212
- this._adapter.toggleOptionMultiple(optionIndex, isSelected);
213
- }
214
- this._applySelection();
215
- };
216
- const data = this.multiple ? [...this._selectedValues] : this._selectedValues[0];
217
- // We close the dropdown immediately if in single selection mode
218
- if (this._open && closeDropdown && !this._multiple) {
219
- this._closeDropdown();
187
+ }
188
+ else {
189
+ if (isDefined(value)) {
190
+ this._selectedValues[0] = value;
191
+ this._selectedLabels[0] = label;
192
+ this._selectedIndexes[0] = optionIndex;
220
193
  }
221
- // First we check to see if there is an before change callback and execute that
222
- if (typeof this._beforeValueChange === 'function') {
223
- this._valueChanging = Promise.resolve(this._beforeValueChange.call(null, data));
224
- const shouldContinue = await this._valueChanging;
225
- this._valueChanging = undefined;
226
- if (!shouldContinue) {
227
- rollbackValue();
228
- this._tryUpdateDropdownPosition();
229
- return resolve(false);
230
- }
194
+ else {
195
+ this._selectedValues = [];
196
+ this._selectedLabels = [];
197
+ this._selectedIndexes = [];
231
198
  }
232
- // Now we can emit the change event AFTER the before change callback has been executed and returned true
233
- const cancelled = !this._adapter.emitHostEvent(BASE_SELECT_CONSTANTS.events.CHANGE, data, true, true);
234
- if (!cancelled) {
235
- applyValue();
199
+ }
200
+ this._value = [...this._selectedValues];
201
+ const rollbackValue = () => {
202
+ this._selectedValues = [...prevSelectedValues];
203
+ this._selectedLabels = [...prevSelectedLabels];
204
+ this._selectedIndexes = [...prevSelectedIndexes];
205
+ this._value = [...prevValues];
206
+ };
207
+ const applyValue = () => {
208
+ // If we're in multiselect mode, we need to toggle the selected option
209
+ if (this._multiple) {
210
+ const isSelected = this._selectedIndexes.includes(optionIndex);
211
+ this._adapter.toggleOptionMultiple(optionIndex, isSelected);
236
212
  }
237
- else {
213
+ this._applySelection();
214
+ };
215
+ const data = this.multiple ? [...this._selectedValues] : this._selectedValues[0];
216
+ // We close the dropdown immediately if in single selection mode
217
+ if (this._open && closeDropdown && !this._multiple) {
218
+ this._closeDropdown();
219
+ }
220
+ // First we check to see if there is an before change callback and execute that
221
+ if (typeof this._beforeValueChange === 'function') {
222
+ this._valueChanging = Promise.resolve(this._beforeValueChange.call(null, data));
223
+ const shouldContinue = await this._valueChanging;
224
+ this._valueChanging = undefined;
225
+ if (!shouldContinue) {
238
226
  rollbackValue();
227
+ this._tryUpdateDropdownPosition();
228
+ return false;
239
229
  }
240
- this._tryUpdateDropdownPosition();
241
- resolve(!cancelled);
242
- });
230
+ }
231
+ // Now we can emit the change event AFTER the before change callback has been executed and returned true
232
+ const cancelled = !this._adapter.emitHostEvent(BASE_SELECT_CONSTANTS.events.CHANGE, data, true, true);
233
+ if (!cancelled) {
234
+ applyValue();
235
+ }
236
+ else {
237
+ rollbackValue();
238
+ }
239
+ this._tryUpdateDropdownPosition();
240
+ return !cancelled;
243
241
  }
244
242
  _selectActiveOption() {
245
243
  const activeOptionIndex = this._adapter.getActiveOptionIndex();
@@ -450,9 +448,7 @@ export class BaseSelectCore extends ListDropdownAwareCore {
450
448
  }, 300);
451
449
  this._options = this._adapter.getOptions();
452
450
  // TODO: Enhance this to cycle through closest matches (see the native select)
453
- const matchedOption = this._flatOptions.find(({ disabled, label }) => {
454
- return !disabled && label.trim().toLowerCase().startsWith(this._filterString.trim().toLowerCase());
455
- });
451
+ const matchedOption = this._flatOptions.find(({ disabled, label }) => !disabled && label.trim().toLowerCase().startsWith(this._filterString.trim().toLowerCase()));
456
452
  if (matchedOption) {
457
453
  const optionIndex = this._flatOptions.indexOf(matchedOption);
458
454
  if (this._open) {
@@ -13,6 +13,6 @@ export declare enum SelectOptionType {
13
13
  * @param options The options either grouped or individual.
14
14
  * @param type The type of option to detect.
15
15
  */
16
- export declare function isSelectOptionType(options: ISelectOption[] | ISelectOptionGroup[], type: SelectOptionType): boolean;
16
+ export declare function isSelectOptionType(options: ISelectOption[] | ISelectOptionGroup[], type: SelectOptionType): options is ISelectOptionGroup[];
17
17
  export declare function isOptionGroupObject(o: ISelectOption | ISelectOptionGroup): o is ISelectOptionGroup;
18
18
  export declare function isOptionObject(o: ISelectOption | ISelectOptionGroup): o is ISelectOption;
@@ -20,8 +20,8 @@ export function isSelectOptionType(options, type) {
20
20
  return (isOptionGroups && type === SelectOptionType.Group) || (isOptionTypes && type === SelectOptionType.Option);
21
21
  }
22
22
  export function isOptionGroupObject(o) {
23
- return isDefined(o) && isObject(o) && o.hasOwnProperty('options');
23
+ return isDefined(o) && isObject(o) && Object.prototype.hasOwnProperty.call(o, 'options');
24
24
  }
25
25
  export function isOptionObject(o) {
26
- return isDefined(o) && isObject(o) && o.hasOwnProperty('label') && o.hasOwnProperty('value');
26
+ return isDefined(o) && isObject(o) && Object.prototype.hasOwnProperty.call(o, 'label') && Object.prototype.hasOwnProperty.call(o, 'value');
27
27
  }
@@ -75,9 +75,7 @@ export class SelectDropdownAdapter extends BaseSelectAdapter {
75
75
  return () => { };
76
76
  }
77
77
  const observer = new MutationObserver(mutations => {
78
- const isTargetRemoved = mutations.some(mutation => {
79
- return Array.from(mutation.removedNodes).some(node => node === this._targetElement);
80
- });
78
+ const isTargetRemoved = mutations.some(mutation => Array.from(mutation.removedNodes).some(node => node === this._targetElement));
81
79
  if (isTargetRemoved) {
82
80
  observer.disconnect();
83
81
  cb();
@@ -14,7 +14,7 @@ import { IconComponent, IconRegistry } from '../../icon';
14
14
  import { StateLayerComponent } from '../../state-layer';
15
15
  import { FocusIndicatorComponent } from '../../focus-indicator';
16
16
  const template = '<template><div class=\"forge-split-view-panel\" id=\"root\" part=\"root\"><div class=\"forge-split-view-panel__handle\" id=\"handle\" part=\"handle\" role=\"separator\" aria-controls=\"content\" aria-grabbed=\"false\" tabindex=\"0\"><forge-icon class=\"forge-split-view-panel__icon\" id=\"icon\" part=\"icon\"></forge-icon><forge-state-layer target=\"handle\" id=\"state-layer\" exportparts=\"surface:state-layer\"></forge-state-layer><forge-focus-indicator inward target=\"handle\" part=\"focus-indicator\"></forge-focus-indicator></div><div class=\"forge-split-view-panel__content\" id=\"content\" part=\"content\" role=\"group\"><slot></slot></div></div></template>';
17
- const styles = '.forge-split-view-panel{display:flex;width:100%;height:100%;overflow:hidden}.forge-split-view-panel__handle{color:var(--forge-theme-text-medium,rgba(0,0,0,.6));background-color:var(--forge-theme-outline,#e0e0e0);position:relative;display:flex;flex-shrink:0;justify-content:center;align-items:center;outline:0}.forge-split-view-panel__content{flex:1;overflow:hidden}.forge-split-view-panel--closed{display:none}.forge-split-view-panel--disabled #handle{pointer-events:none}.forge-split-view-panel--disabled .forge-split-view-panel__icon{display:none}.forge-split-view-panel[orientation=horizontal]{min-width:var(--forge-split-view-handle-width,8px);width:calc(var(--forge-split-view-panel-size,unset) + var(--forge-split-view-handle-width,8px));flex-direction:row}.forge-split-view-panel[orientation=horizontal] .forge-split-view-panel__handle{width:var(--forge-split-view-handle-width,8px);cursor:var(--forge-split-view-panel-cursor)}.forge-split-view-panel[orientation=horizontal].forge-split-view-panel--closing[resizable=end]{position:absolute;top:0;left:0;animation-name:ukmfbnr;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1))}@keyframes ukmfbnr{from{transform:none}to{transform:translateX(-100%)}}.forge-split-view-panel[orientation=horizontal].forge-split-view-panel--closing[resizable=start]{position:absolute;top:0;right:0;animation-name:ukmfbop;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1))}@keyframes ukmfbop{from{transform:none}to{transform:translateX(100%)}}.forge-split-view-panel[orientation=horizontal].forge-split-view-panel--opening[resizable=end]{position:absolute;top:0;left:0;animation-name:ukmfbow;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1));animation-direction:reverse}@keyframes ukmfbow{from{transform:none}to{transform:translateX(-100%)}}.forge-split-view-panel[orientation=horizontal].forge-split-view-panel--opening[resizable=start]{position:absolute;top:0;right:0;animation-name:ukmfbp9;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1));animation-direction:reverse}@keyframes ukmfbp9{from{transform:none}to{transform:translateX(100%)}}.forge-split-view-panel[orientation=vertical]{min-height:var(--forge-split-view-handle-width,8px);height:calc(var(--forge-split-view-panel-size,unset) + var(--forge-split-view-handle-width,8px));flex-direction:column}.forge-split-view-panel[orientation=vertical] .forge-split-view-panel__handle{height:var(--forge-split-view-handle-width,8px);cursor:var(--forge-split-view-panel-cursor)}.forge-split-view-panel[orientation=vertical].forge-split-view-panel--closing[resizable=end]{position:absolute;top:0;left:0;animation-name:ukmfbpk;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1))}@keyframes ukmfbpk{from{transform:none}to{transform:translateY(-100%)}}.forge-split-view-panel[orientation=vertical].forge-split-view-panel--closing[resizable=start]{position:absolute;bottom:0;left:0;animation-name:ukmfbqd;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1))}@keyframes ukmfbqd{from{transform:none}to{transform:translateY(100%)}}.forge-split-view-panel[orientation=vertical].forge-split-view-panel--opening[resizable=end]{position:absolute;top:0;left:0;animation-name:ukmfbqg;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1));animation-direction:reverse}@keyframes ukmfbqg{from{transform:none}to{transform:translateY(-100%)}}.forge-split-view-panel[orientation=vertical].forge-split-view-panel--opening[resizable=start]{position:absolute;bottom:0;left:0;animation-name:ukmfbqp;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1));animation-direction:reverse}@keyframes ukmfbqp{from{transform:none}to{transform:translateY(100%)}}:host{z-index:var(--forge-split-view-animating-layer)!important;display:block;position:relative;height:100%;width:100%;flex:0}:host([hidden]){display:none}:host(:not([resizable=start],[resizable=end])){flex:1}:host(:not([resizable=start],[resizable=end])) .forge-split-view-panel{width:100%;height:100%;min-width:0;min-height:0}:host(:not([resizable=start],[resizable=end])) .forge-split-view-panel__handle{display:none}forge-focus-indicator{--forge-focus-indicator-active-width:2px}';
17
+ const styles = '.forge-split-view-panel{display:flex;width:100%;height:100%;overflow:hidden}.forge-split-view-panel__handle{color:var(--forge-theme-text-medium,rgba(0,0,0,.6));background-color:var(--forge-theme-outline,#e0e0e0);position:relative;display:flex;flex-shrink:0;justify-content:center;align-items:center;outline:0}.forge-split-view-panel__content{flex:1;overflow:hidden}.forge-split-view-panel--closed{display:none}.forge-split-view-panel--disabled #handle{pointer-events:none}.forge-split-view-panel--disabled .forge-split-view-panel__icon{display:none}.forge-split-view-panel[orientation=horizontal]{min-width:var(--forge-split-view-handle-width,8px);width:calc(var(--forge-split-view-panel-size,unset) + var(--forge-split-view-handle-width,8px));flex-direction:row}.forge-split-view-panel[orientation=horizontal] .forge-split-view-panel__handle{width:var(--forge-split-view-handle-width,8px);cursor:var(--forge-split-view-panel-cursor)}.forge-split-view-panel[orientation=horizontal].forge-split-view-panel--closing[resizable=end]{position:absolute;top:0;left:0;animation-name:udxwkwm;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1))}@keyframes udxwkwm{from{transform:none}to{transform:translateX(-100%)}}.forge-split-view-panel[orientation=horizontal].forge-split-view-panel--closing[resizable=start]{position:absolute;top:0;right:0;animation-name:udxwkxa;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1))}@keyframes udxwkxa{from{transform:none}to{transform:translateX(100%)}}.forge-split-view-panel[orientation=horizontal].forge-split-view-panel--opening[resizable=end]{position:absolute;top:0;left:0;animation-name:udxwky1;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1));animation-direction:reverse}@keyframes udxwky1{from{transform:none}to{transform:translateX(-100%)}}.forge-split-view-panel[orientation=horizontal].forge-split-view-panel--opening[resizable=start]{position:absolute;top:0;right:0;animation-name:udxwkyf;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1));animation-direction:reverse}@keyframes udxwkyf{from{transform:none}to{transform:translateX(100%)}}.forge-split-view-panel[orientation=vertical]{min-height:var(--forge-split-view-handle-width,8px);height:calc(var(--forge-split-view-panel-size,unset) + var(--forge-split-view-handle-width,8px));flex-direction:column}.forge-split-view-panel[orientation=vertical] .forge-split-view-panel__handle{height:var(--forge-split-view-handle-width,8px);cursor:var(--forge-split-view-panel-cursor)}.forge-split-view-panel[orientation=vertical].forge-split-view-panel--closing[resizable=end]{position:absolute;top:0;left:0;animation-name:udxwkyt;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1))}@keyframes udxwkyt{from{transform:none}to{transform:translateY(-100%)}}.forge-split-view-panel[orientation=vertical].forge-split-view-panel--closing[resizable=start]{position:absolute;bottom:0;left:0;animation-name:udxwkz2;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1))}@keyframes udxwkz2{from{transform:none}to{transform:translateY(100%)}}.forge-split-view-panel[orientation=vertical].forge-split-view-panel--opening[resizable=end]{position:absolute;top:0;left:0;animation-name:udxwkz5;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1));animation-direction:reverse}@keyframes udxwkz5{from{transform:none}to{transform:translateY(-100%)}}.forge-split-view-panel[orientation=vertical].forge-split-view-panel--opening[resizable=start]{position:absolute;bottom:0;left:0;animation-name:udxwkzb;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1));animation-direction:reverse}@keyframes udxwkzb{from{transform:none}to{transform:translateY(100%)}}:host{z-index:var(--forge-split-view-animating-layer)!important;display:block;position:relative;height:100%;width:100%;flex:0}:host([hidden]){display:none}:host(:not([resizable=start],[resizable=end])){flex:1}:host(:not([resizable=start],[resizable=end])) .forge-split-view-panel{width:100%;height:100%;min-width:0;min-height:0}:host(:not([resizable=start],[resizable=end])) .forge-split-view-panel__handle{display:none}forge-focus-indicator{--forge-focus-indicator-active-width:2px}';
18
18
  /**
19
19
  * @tag forge-split-view-panel
20
20
  *
@@ -424,18 +424,16 @@ export class TableUtils {
424
424
  * @param {IColumnData[]} data The row data.
425
425
  */
426
426
  static _createColumnDataMap(columnConfigurations, data) {
427
- return columnConfigurations.map(columnConfig => {
428
- return {
429
- config: columnConfig,
430
- data: data.map(item => {
431
- if (columnConfig.property) {
432
- const value = getPropertyValue(item.data, columnConfig.property);
433
- return isDefined(value) ? value : null;
434
- }
435
- return null;
436
- })
437
- };
438
- });
427
+ return columnConfigurations.map(columnConfig => ({
428
+ config: columnConfig,
429
+ data: data.map(item => {
430
+ if (columnConfig.property) {
431
+ const value = getPropertyValue(item.data, columnConfig.property);
432
+ return isDefined(value) ? value : null;
433
+ }
434
+ return null;
435
+ })
436
+ }));
439
437
  }
440
438
  /**
441
439
  * Returns the row data in a column ordered fashion.
@@ -142,8 +142,9 @@ export class TabBarCore {
142
142
  _syncTabState() {
143
143
  this._tabs.forEach((tab, index) => {
144
144
  tab.selected = index === this._activeTab;
145
- if (this._disabled)
145
+ if (this._disabled) {
146
146
  tab.disabled = this._disabled;
147
+ }
147
148
  tab.vertical = this._vertical;
148
149
  tab.stacked = this._stacked;
149
150
  tab.secondary = this._secondary;
@@ -92,9 +92,7 @@ export class TextFieldAdapter extends BaseFieldAdapter {
92
92
  // Destroy the previous value change listeners
93
93
  this._destroyValueChangerListeners.forEach(callback => callback());
94
94
  // Add a new value change listener to each input
95
- this._destroyValueChangerListeners = this._inputElements.map(el => {
96
- return listenOwnProperty(context, el, 'value', listener);
97
- });
95
+ this._destroyValueChangerListeners = this._inputElements.map(el => listenOwnProperty(context, el, 'value', listener));
98
96
  }
99
97
  removeValueChangeListener() {
100
98
  this._destroyValueChangerListeners.forEach(callback => callback());
@@ -95,13 +95,14 @@ export class TimePickerCore {
95
95
  if (evt.shiftKey) {
96
96
  switch (evt.code) {
97
97
  case 'Backspace':
98
- case 'Delete':
98
+ case 'Delete': {
99
99
  evt.preventDefault();
100
100
  const result = this._trySetValue(null);
101
101
  if (result) {
102
102
  this._formatInputValue();
103
103
  }
104
104
  return;
105
+ }
105
106
  }
106
107
  }
107
108
  switch (evt.code) {
@@ -170,7 +171,7 @@ export class TimePickerCore {
170
171
  this._adapter.propagateKey(evt.code);
171
172
  }
172
173
  break;
173
- case 'KeyN':
174
+ case 'KeyN': {
174
175
  evt.preventDefault();
175
176
  const nowMillis = getCurrentTimeOfDayMillis(this._allowSeconds);
176
177
  if (this._value !== nowMillis) {
@@ -182,6 +183,7 @@ export class TimePickerCore {
182
183
  }
183
184
  }
184
185
  break;
186
+ }
185
187
  }
186
188
  }
187
189
  _trySetActiveOption() {
@@ -523,9 +525,7 @@ export class TimePickerCore {
523
525
  return this._findClosestOptionIndex(currentTimeMillis, options);
524
526
  }
525
527
  _findClosestOptionIndex(value, options) {
526
- const closestItem = options.reduce((prev, curr) => {
527
- return Math.abs((curr.value.time || 0) - value) < Math.abs((prev.value.time || 0) - value) ? curr : prev;
528
- });
528
+ const closestItem = options.reduce((prev, curr) => (Math.abs((curr.value.time || 0) - value) < Math.abs((prev.value.time || 0) - value) ? curr : prev));
529
529
  return options.indexOf(closestItem);
530
530
  }
531
531
  _formatInputValue(emitEvents = true) {
@@ -39,7 +39,7 @@ export class ToastAdapter extends BaseAdapter {
39
39
  }
40
40
  setActionText(text) {
41
41
  this._actionButtonElement.textContent = text;
42
- if (!!text) {
42
+ if (text) {
43
43
  this._actionButtonElement.removeAttribute('hidden');
44
44
  }
45
45
  else {
@@ -103,7 +103,7 @@ export class ToastCore {
103
103
  if (this._actionText !== value) {
104
104
  this._actionText = value;
105
105
  this._adapter.setActionText(this._actionText);
106
- if (!!this._actionText) {
106
+ if (this._actionText) {
107
107
  this._adapter.addActionListener(this._actionListener);
108
108
  }
109
109
  else {
@@ -103,10 +103,11 @@ let ToastComponent = class ToastComponent extends WithElementInternals(WithDefau
103
103
  case TOAST_CONSTANTS.attributes.OPEN:
104
104
  this.open = coerceBoolean(newValue);
105
105
  break;
106
- case TOAST_CONSTANTS.attributes.DURATION:
106
+ case TOAST_CONSTANTS.attributes.DURATION: {
107
107
  const value = Number(newValue);
108
108
  this.duration = value && value > 0 ? value : TOAST_CONSTANTS.defaults.DURATION;
109
109
  break;
110
+ }
110
111
  case TOAST_CONSTANTS.attributes.PLACEMENT:
111
112
  this.placement = newValue || TOAST_CONSTANTS.defaults.PLACEMENT;
112
113
  break;
@@ -8,6 +8,7 @@ import { ITooltipComponent } from './tooltip';
8
8
  export interface ITooltipAdapter extends IBaseAdapter<ITooltipComponent> {
9
9
  readonly hostElement: ITooltipComponent;
10
10
  readonly anchorElement: HTMLElement | null;
11
+ readonly hasContent: boolean;
11
12
  syncAria(): void;
12
13
  detachAria(): void;
13
14
  setAnchorElement(element: HTMLElement | null): void;
@@ -22,10 +23,16 @@ export interface ITooltipAdapter extends IBaseAdapter<ITooltipComponent> {
22
23
  export declare class TooltipAdapter extends BaseAdapter<ITooltipComponent> implements ITooltipAdapter {
23
24
  private _contentElement;
24
25
  private _arrowElement;
26
+ private _defaultSlotElement;
25
27
  private _anchorElement;
26
28
  private _overlayElement;
27
29
  constructor(component: ITooltipComponent);
28
30
  get anchorElement(): HTMLElement | null;
31
+ /**
32
+ * Tooltips are considered to have content if the default slot has assigned nodes that
33
+ * are either elements, or text nodes with non-whitespace content.
34
+ */
35
+ get hasContent(): boolean;
29
36
  syncAria(): void;
30
37
  detachAria(): void;
31
38
  setAnchorElement(element: HTMLElement | null): void;
@@ -16,10 +16,20 @@ export class TooltipAdapter extends BaseAdapter {
16
16
  this._overlayElement = null;
17
17
  this._contentElement = getShadowElement(this._component, TOOLTIP_CONSTANTS.selectors.CONTENT);
18
18
  this._arrowElement = getShadowElement(this._component, TOOLTIP_CONSTANTS.selectors.ARROW);
19
+ this._defaultSlotElement = getShadowElement(this._component, TOOLTIP_CONSTANTS.selectors.DEFAULT_SLOT);
19
20
  }
20
21
  get anchorElement() {
21
22
  return this._anchorElement;
22
23
  }
24
+ /**
25
+ * Tooltips are considered to have content if the default slot has assigned nodes that
26
+ * are either elements, or text nodes with non-whitespace content.
27
+ */
28
+ get hasContent() {
29
+ return this._defaultSlotElement
30
+ .assignedNodes({ flatten: true })
31
+ .some(node => node.nodeType === Node.ELEMENT_NODE || (node.nodeType === Node.TEXT_NODE && node.textContent?.trim()));
32
+ }
23
33
  syncAria() {
24
34
  const role = this._component.type === 'description' ? 'tooltip' : null;
25
35
  this._component[setDefaultAria]({ role });
@@ -51,6 +51,7 @@ export declare const TOOLTIP_CONSTANTS: {
51
51
  selectors: {
52
52
  readonly CONTENT: ".forge-tooltip";
53
53
  readonly ARROW: ".arrow";
54
+ readonly DEFAULT_SLOT: "slot:not([name])";
54
55
  };
55
56
  };
56
57
  export type TooltipType = 'presentation' | 'label' | 'description';
@@ -36,7 +36,8 @@ const defaults = {
36
36
  };
37
37
  const selectors = {
38
38
  CONTENT: '.forge-tooltip',
39
- ARROW: '.arrow'
39
+ ARROW: '.arrow',
40
+ DEFAULT_SLOT: 'slot:not([name])'
40
41
  };
41
42
  export const TOOLTIP_CONSTANTS = {
42
43
  elementName,