@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.
- package/custom-elements.json +22 -20
- package/dist/badge/forge-badge.css +1 -1
- package/dist/forge.css +0 -1
- package/dist/lib.js +7 -7
- package/dist/lib.js.map +3 -3
- package/dist/table/forge-table.css +0 -1
- package/esm/autocomplete/autocomplete-core.js +9 -12
- package/esm/autocomplete/autocomplete-utils.js +3 -2
- package/esm/badge/badge.js +1 -1
- package/esm/button/base/base-button-adapter.js +6 -5
- package/esm/button/base/base-button-constants.d.ts +2 -2
- package/esm/button-area/button-area-adapter.d.ts +0 -2
- package/esm/button-area/button-area-adapter.js +5 -3
- package/esm/button-area/button-area-core.js +0 -1
- package/esm/button-area/button-area.js +1 -1
- package/esm/button-toggle/button-toggle-group/button-toggle-group-core.js +0 -1
- package/esm/calendar/calendar-core.js +6 -4
- package/esm/calendar/calendar-dropdown/calendar-dropdown.js +1 -1
- package/esm/calendar/calendar-utils.js +1 -3
- package/esm/calendar/calendar.js +1 -1
- package/esm/color-picker/color-picker-core.js +6 -5
- package/esm/color-picker/color-picker-gradient-slider.d.ts +1 -1
- package/esm/color-picker/color-picker-gradient-slider.js +19 -30
- package/esm/core/configuration/global-configuration.js +0 -1
- package/esm/core/mixins/form/with-form-associated.js +6 -2
- package/esm/core/utils/a11y-utils.d.ts +2 -2
- package/esm/core/utils/date-utils.js +1 -1
- package/esm/core/utils/dismissible-stack.js +0 -1
- package/esm/core/utils/feature-detection.js +2 -2
- package/esm/date-picker/base/base-date-picker-adapter.d.ts +2 -1
- package/esm/date-picker/base/base-date-picker-adapter.js +4 -0
- package/esm/date-picker/base/base-date-picker-core.js +2 -4
- package/esm/date-picker/base/base-date-picker-utils.d.ts +2 -1
- package/esm/date-picker/date-picker-adapter.js +1 -1
- package/esm/date-picker/date-picker-core.js +2 -1
- package/esm/date-range-picker/date-range-picker-adapter.d.ts +2 -1
- package/esm/date-range-picker/date-range-picker-adapter.js +1 -1
- package/esm/date-range-picker/date-range-picker-core.js +4 -5
- package/esm/deprecated/icon-button/deprecated-icon-button-component-delegate.js +2 -1
- package/esm/dialog/dialog.js +1 -1
- package/esm/expansion-panel/expansion-panel-core.d.ts +4 -0
- package/esm/expansion-panel/expansion-panel-core.js +19 -11
- package/esm/field/field-core.js +2 -1
- package/esm/field/field.js +1 -1
- package/esm/file-picker/file-picker-core.js +1 -3
- package/esm/floating-action-button/floating-action-button-component-delegate.js +2 -1
- package/esm/icon/icon-core.js +1 -1
- package/esm/icon/icon-registry.js +1 -1
- package/esm/icon-button/icon-button-component-delegate.js +2 -1
- package/esm/label/label-aware.js +1 -3
- package/esm/list-dropdown/list-dropdown-core.js +4 -2
- package/esm/list-dropdown/list-dropdown-utils.js +6 -3
- package/esm/menu/menu-core.js +5 -6
- package/esm/menu/menu.js +2 -2
- package/esm/overlay/overlay-constants.d.ts +1 -1
- package/esm/overlay/overlay-constants.js +1 -1
- package/esm/overlay/overlay.d.ts +2 -2
- package/esm/overlay/overlay.js +2 -2
- package/esm/select/core/base-select-adapter.js +0 -1
- package/esm/select/core/base-select-core.js +70 -74
- package/esm/select/core/select-utils.d.ts +1 -1
- package/esm/select/core/select-utils.js +2 -2
- package/esm/select/select-dropdown/select-dropdown-adapter.js +1 -3
- package/esm/split-view/split-view-panel/split-view-panel.js +1 -1
- package/esm/table/table-utils.js +10 -12
- package/esm/tabs/tab-bar/tab-bar-core.js +2 -1
- package/esm/text-field/text-field-adapter.js +1 -3
- package/esm/time-picker/time-picker-core.js +5 -5
- package/esm/toast/toast-adapter.js +1 -1
- package/esm/toast/toast-core.js +1 -1
- package/esm/toast/toast.js +2 -1
- package/esm/tooltip/tooltip-adapter.d.ts +7 -0
- package/esm/tooltip/tooltip-adapter.js +10 -0
- package/esm/tooltip/tooltip-constants.d.ts +1 -0
- package/esm/tooltip/tooltip-constants.js +2 -1
- package/esm/tooltip/tooltip-core.js +3 -0
- package/esm/tooltip/tooltip.js +1 -1
- package/esm/view-switcher/view-switcher-core.js +2 -1
- package/package.json +1 -1
- package/sass/core/styles/tokens/badge/_tokens.scss +1 -1
- package/sass/table/forge-table.scss +0 -1
- 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 = '
|
|
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) &&
|
|
391
|
-
|
|
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) {
|
package/esm/menu/menu-core.js
CHANGED
|
@@ -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 {
|
|
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(
|
|
46
|
+
IconRegistry.define(tylIconArrowRightAlt);
|
|
47
47
|
this._core = new MenuCore(new MenuAdapter(this));
|
|
48
48
|
attachShadowTemplate(this, template, styles);
|
|
49
49
|
}
|
package/esm/overlay/overlay.d.ts
CHANGED
|
@@ -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="
|
|
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="
|
|
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.
|
package/esm/overlay/overlay.js
CHANGED
|
@@ -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="
|
|
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="
|
|
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
|
|
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
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
if (this.
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
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
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
this.
|
|
205
|
-
this.
|
|
206
|
-
this.
|
|
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
|
-
|
|
222
|
-
|
|
223
|
-
this.
|
|
224
|
-
|
|
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
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
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
|
-
|
|
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
|
-
|
|
241
|
-
|
|
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):
|
|
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) &&
|
|
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) &&
|
|
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:
|
|
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
|
*
|
package/esm/table/table-utils.js
CHANGED
|
@@ -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
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
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) {
|
package/esm/toast/toast-core.js
CHANGED
|
@@ -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 (
|
|
106
|
+
if (this._actionText) {
|
|
107
107
|
this._adapter.addActionListener(this._actionListener);
|
|
108
108
|
}
|
|
109
109
|
else {
|
package/esm/toast/toast.js
CHANGED
|
@@ -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 });
|