@ni/nimble-components 24.1.6 → 24.1.7
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/dist/all-components-bundle.js +492 -56
- package/dist/all-components-bundle.js.map +1 -1
- package/dist/all-components-bundle.min.js +7370 -7348
- package/dist/all-components-bundle.min.js.map +1 -1
- package/dist/esm/combobox/index.d.ts +172 -20
- package/dist/esm/combobox/index.js +453 -44
- package/dist/esm/combobox/index.js.map +1 -1
- package/dist/esm/combobox/models/combobox-form-associated.d.ts +16 -0
- package/dist/esm/combobox/models/combobox-form-associated.js +19 -0
- package/dist/esm/combobox/models/combobox-form-associated.js.map +1 -0
- package/dist/esm/src/combobox/index.d.ts +172 -20
- package/dist/esm/src/combobox/models/combobox-form-associated.d.ts +16 -0
- package/package.json +1 -1
|
@@ -5398,7 +5398,7 @@
|
|
|
5398
5398
|
* Ensures that a value is between a min and max value. If value is lower than min, min will be returned.
|
|
5399
5399
|
* If value is greater than max, max will be returned.
|
|
5400
5400
|
*/
|
|
5401
|
-
function limit(min, max, value) {
|
|
5401
|
+
function limit$1(min, max, value) {
|
|
5402
5402
|
return Math.min(Math.max(value, min), max);
|
|
5403
5403
|
}
|
|
5404
5404
|
/**
|
|
@@ -8380,12 +8380,12 @@
|
|
|
8380
8380
|
*
|
|
8381
8381
|
* @internal
|
|
8382
8382
|
*/
|
|
8383
|
-
class FormAssociatedCombobox extends FormAssociated(_Combobox) {
|
|
8383
|
+
let FormAssociatedCombobox$1 = class FormAssociatedCombobox extends FormAssociated(_Combobox) {
|
|
8384
8384
|
constructor() {
|
|
8385
8385
|
super(...arguments);
|
|
8386
8386
|
this.proxy = document.createElement("input");
|
|
8387
8387
|
}
|
|
8388
|
-
}
|
|
8388
|
+
};
|
|
8389
8389
|
|
|
8390
8390
|
/**
|
|
8391
8391
|
* Autocomplete values for combobox.
|
|
@@ -8415,7 +8415,7 @@
|
|
|
8415
8415
|
*
|
|
8416
8416
|
* @public
|
|
8417
8417
|
*/
|
|
8418
|
-
let Combobox$
|
|
8418
|
+
let Combobox$2 = class Combobox extends FormAssociatedCombobox$1 {
|
|
8419
8419
|
constructor() {
|
|
8420
8420
|
super(...arguments);
|
|
8421
8421
|
/**
|
|
@@ -8796,7 +8796,7 @@
|
|
|
8796
8796
|
*/
|
|
8797
8797
|
selectedIndexChanged(prev, next) {
|
|
8798
8798
|
if (this.$fastController.isConnected) {
|
|
8799
|
-
next = limit(-1, this.options.length - 1, next);
|
|
8799
|
+
next = limit$1(-1, this.options.length - 1, next);
|
|
8800
8800
|
// we only want to call the super method when the selectedIndex is in range
|
|
8801
8801
|
if (next !== this.selectedIndex) {
|
|
8802
8802
|
this.selectedIndex = next;
|
|
@@ -8943,22 +8943,22 @@
|
|
|
8943
8943
|
};
|
|
8944
8944
|
__decorate([
|
|
8945
8945
|
attr({ attribute: "autocomplete", mode: "fromView" })
|
|
8946
|
-
], Combobox$
|
|
8946
|
+
], Combobox$2.prototype, "autocomplete", void 0);
|
|
8947
8947
|
__decorate([
|
|
8948
8948
|
observable
|
|
8949
|
-
], Combobox$
|
|
8949
|
+
], Combobox$2.prototype, "maxHeight", void 0);
|
|
8950
8950
|
__decorate([
|
|
8951
8951
|
attr({ attribute: "open", mode: "boolean" })
|
|
8952
|
-
], Combobox$
|
|
8952
|
+
], Combobox$2.prototype, "open", void 0);
|
|
8953
8953
|
__decorate([
|
|
8954
8954
|
attr
|
|
8955
|
-
], Combobox$
|
|
8955
|
+
], Combobox$2.prototype, "placeholder", void 0);
|
|
8956
8956
|
__decorate([
|
|
8957
8957
|
attr({ attribute: "position" })
|
|
8958
|
-
], Combobox$
|
|
8958
|
+
], Combobox$2.prototype, "positionAttribute", void 0);
|
|
8959
8959
|
__decorate([
|
|
8960
8960
|
observable
|
|
8961
|
-
], Combobox$
|
|
8961
|
+
], Combobox$2.prototype, "position", void 0);
|
|
8962
8962
|
/**
|
|
8963
8963
|
* Includes ARIA states and properties relating to the ARIA combobox role.
|
|
8964
8964
|
*
|
|
@@ -8973,7 +8973,7 @@
|
|
|
8973
8973
|
observable
|
|
8974
8974
|
], DelegatesARIACombobox.prototype, "ariaControls", void 0);
|
|
8975
8975
|
applyMixins(DelegatesARIACombobox, DelegatesARIAListbox);
|
|
8976
|
-
applyMixins(Combobox$
|
|
8976
|
+
applyMixins(Combobox$2, StartEnd, DelegatesARIACombobox);
|
|
8977
8977
|
|
|
8978
8978
|
/**
|
|
8979
8979
|
* Retrieves the "composed parent" element of a node, ignoring DOM tree boundaries.
|
|
@@ -13545,7 +13545,7 @@
|
|
|
13545
13545
|
adjust(adjustment) {
|
|
13546
13546
|
const focusableTabs = this.tabs.filter(t => this.isFocusableElement(t));
|
|
13547
13547
|
const currentActiveTabIndex = focusableTabs.indexOf(this.activetab);
|
|
13548
|
-
const nextTabIndex = limit(0, focusableTabs.length - 1, currentActiveTabIndex + adjustment);
|
|
13548
|
+
const nextTabIndex = limit$1(0, focusableTabs.length - 1, currentActiveTabIndex + adjustment);
|
|
13549
13549
|
// the index of the next focusable tab within the context of all available tabs
|
|
13550
13550
|
const nextIndex = this.tabs.indexOf(focusableTabs[nextTabIndex]);
|
|
13551
13551
|
if (nextIndex > -1) {
|
|
@@ -13942,7 +13942,7 @@
|
|
|
13942
13942
|
}
|
|
13943
13943
|
set activeIndex(value) {
|
|
13944
13944
|
if (this.$fastController.isConnected) {
|
|
13945
|
-
this._activeIndex = limit(0, this.focusableElements.length - 1, value);
|
|
13945
|
+
this._activeIndex = limit$1(0, this.focusableElements.length - 1, value);
|
|
13946
13946
|
Observable.notify(this, "activeIndex");
|
|
13947
13947
|
}
|
|
13948
13948
|
}
|
|
@@ -16301,7 +16301,7 @@
|
|
|
16301
16301
|
|
|
16302
16302
|
/**
|
|
16303
16303
|
* Do not edit directly
|
|
16304
|
-
* Generated on Thu, 04 Apr 2024
|
|
16304
|
+
* Generated on Thu, 04 Apr 2024 17:54:36 GMT
|
|
16305
16305
|
*/
|
|
16306
16306
|
|
|
16307
16307
|
const Information100DarkUi = "#a46eff";
|
|
@@ -16717,6 +16717,19 @@
|
|
|
16717
16717
|
Direction["rtl"] = "rtl";
|
|
16718
16718
|
})(Direction || (Direction = {}));
|
|
16719
16719
|
|
|
16720
|
+
/**
|
|
16721
|
+
* This method keeps a given value within the bounds of a min and max value. If the value
|
|
16722
|
+
* is larger than the max, the minimum value will be returned. If the value is smaller than the minimum,
|
|
16723
|
+
* the maximum will be returned. Otherwise, the value is returned un-changed.
|
|
16724
|
+
*/
|
|
16725
|
+
/**
|
|
16726
|
+
* Ensures that a value is between a min and max value. If value is lower than min, min will be returned.
|
|
16727
|
+
* If value is greater than max, max will be returned.
|
|
16728
|
+
*/
|
|
16729
|
+
function limit(min, max, value) {
|
|
16730
|
+
return Math.min(Math.max(value, min), max);
|
|
16731
|
+
}
|
|
16732
|
+
|
|
16720
16733
|
let uniqueIdCounter = 0;
|
|
16721
16734
|
/**
|
|
16722
16735
|
* Generates a unique ID based on incrementing a counter.
|
|
@@ -21077,65 +21090,173 @@
|
|
|
21077
21090
|
</template>
|
|
21078
21091
|
`;
|
|
21079
21092
|
|
|
21093
|
+
// Based on: https://github.com/microsoft/fast/blob/%40microsoft/fast-foundation_v2.49.5/packages/web-components/fast-foundation/src/combobox/combobox.form-associated.ts
|
|
21094
|
+
/* eslint-disable max-classes-per-file */
|
|
21095
|
+
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
21096
|
+
let Combobox$1 = class Combobox extends ListboxElement {
|
|
21097
|
+
};
|
|
21098
|
+
/**
|
|
21099
|
+
* A form-associated base class for the Combobox component. This was copied from the
|
|
21100
|
+
* FAST FormAssociatedCombobox (which is not exported by fast-foundation)
|
|
21101
|
+
*
|
|
21102
|
+
* @internal
|
|
21103
|
+
*/
|
|
21104
|
+
class FormAssociatedCombobox extends FormAssociated(Combobox$1) {
|
|
21105
|
+
constructor() {
|
|
21106
|
+
super(...arguments);
|
|
21107
|
+
this.proxy = document.createElement('input');
|
|
21108
|
+
}
|
|
21109
|
+
}
|
|
21110
|
+
|
|
21080
21111
|
/**
|
|
21081
21112
|
* A nimble-styed HTML combobox
|
|
21082
21113
|
*/
|
|
21083
|
-
class Combobox extends
|
|
21114
|
+
class Combobox extends FormAssociatedCombobox {
|
|
21084
21115
|
constructor() {
|
|
21085
21116
|
super(...arguments);
|
|
21086
21117
|
this.appearance = DropdownAppearance.underline;
|
|
21087
21118
|
this.errorVisible = false;
|
|
21119
|
+
/**
|
|
21120
|
+
* The open attribute.
|
|
21121
|
+
*/
|
|
21122
|
+
this.open = false;
|
|
21123
|
+
/**
|
|
21124
|
+
* The collection of currently filtered options.
|
|
21125
|
+
*/
|
|
21126
|
+
this.filteredOptions = [];
|
|
21088
21127
|
/** @internal */
|
|
21089
21128
|
this.hasOverflow = false;
|
|
21129
|
+
/**
|
|
21130
|
+
* The unique id for the internal listbox element.
|
|
21131
|
+
*
|
|
21132
|
+
* @internal
|
|
21133
|
+
*/
|
|
21134
|
+
this.listboxId = uniqueId('listbox-');
|
|
21135
|
+
/**
|
|
21136
|
+
* The max height for the listbox when opened.
|
|
21137
|
+
*
|
|
21138
|
+
* @internal
|
|
21139
|
+
*/
|
|
21140
|
+
this.maxHeight = 0;
|
|
21090
21141
|
this.valueUpdatedByInput = false;
|
|
21142
|
+
this._value = '';
|
|
21143
|
+
this.filter = '';
|
|
21144
|
+
/**
|
|
21145
|
+
* The initial state of the position attribute.
|
|
21146
|
+
*/
|
|
21147
|
+
this.forcedPosition = false;
|
|
21091
21148
|
}
|
|
21092
21149
|
get value() {
|
|
21093
|
-
|
|
21150
|
+
Observable.track(this, 'value');
|
|
21151
|
+
return this._value;
|
|
21094
21152
|
}
|
|
21095
|
-
// This override is to work around an issue in FAST where an old filter value
|
|
21096
|
-
// is used after programmatically setting the value property.
|
|
21097
|
-
// See: https://github.com/microsoft/fast/issues/6749
|
|
21098
21153
|
set value(next) {
|
|
21099
|
-
|
|
21100
|
-
|
|
21154
|
+
const prev = `${this._value}`;
|
|
21155
|
+
let updatedValue = next;
|
|
21156
|
+
if (this.$fastController.isConnected && this.options) {
|
|
21157
|
+
const selectedIndex = this.options.findIndex(el => el.text.toLowerCase() === next.toLowerCase());
|
|
21158
|
+
const prevSelectedValue = this.options[this.selectedIndex]?.text;
|
|
21159
|
+
const nextSelectedValue = this.options[selectedIndex]?.text;
|
|
21160
|
+
this.selectedIndex = prevSelectedValue !== nextSelectedValue
|
|
21161
|
+
? selectedIndex
|
|
21162
|
+
: this.selectedIndex;
|
|
21163
|
+
updatedValue = this.firstSelectedOption?.text || next;
|
|
21164
|
+
}
|
|
21165
|
+
if (prev !== updatedValue) {
|
|
21166
|
+
this._value = updatedValue;
|
|
21167
|
+
super.valueChanged(prev, updatedValue);
|
|
21168
|
+
Observable.notify(this, 'value');
|
|
21169
|
+
}
|
|
21101
21170
|
// Can remove when following resolved: https://github.com/microsoft/fast/issues/6749
|
|
21102
|
-
|
|
21103
|
-
this['filter'] = next;
|
|
21171
|
+
this.filter = next;
|
|
21104
21172
|
this.filterOptions();
|
|
21105
21173
|
this.selectedIndex = this.options
|
|
21106
21174
|
.map(option => option.text)
|
|
21107
21175
|
.indexOf(this.value);
|
|
21108
21176
|
}
|
|
21109
|
-
|
|
21110
|
-
|
|
21111
|
-
|
|
21112
|
-
|
|
21113
|
-
|
|
21114
|
-
|
|
21115
|
-
|
|
21116
|
-
|
|
21177
|
+
/**
|
|
21178
|
+
* The list of options.
|
|
21179
|
+
*
|
|
21180
|
+
* Overrides `Listbox.options`.
|
|
21181
|
+
*/
|
|
21182
|
+
get options() {
|
|
21183
|
+
Observable.track(this, 'options');
|
|
21184
|
+
return this.filteredOptions?.length
|
|
21185
|
+
? this.filteredOptions
|
|
21186
|
+
: this._options;
|
|
21187
|
+
}
|
|
21188
|
+
set options(value) {
|
|
21189
|
+
this._options = value;
|
|
21190
|
+
Observable.notify(this, 'options');
|
|
21191
|
+
}
|
|
21192
|
+
get isAutocompleteInline() {
|
|
21193
|
+
return (this.autocomplete === ComboboxAutocomplete.inline
|
|
21194
|
+
|| this.isAutocompleteBoth);
|
|
21195
|
+
}
|
|
21196
|
+
get isAutocompleteList() {
|
|
21197
|
+
return (this.autocomplete === ComboboxAutocomplete.list
|
|
21198
|
+
|| this.isAutocompleteBoth);
|
|
21199
|
+
}
|
|
21200
|
+
get isAutocompleteBoth() {
|
|
21201
|
+
return this.autocomplete === ComboboxAutocomplete.both;
|
|
21117
21202
|
}
|
|
21118
|
-
// Workaround for https://github.com/microsoft/fast/issues/5773
|
|
21119
21203
|
slottedOptionsChanged(prev, next) {
|
|
21204
|
+
// Workaround for https://github.com/microsoft/fast/issues/5773
|
|
21120
21205
|
const value = this.value;
|
|
21121
21206
|
super.slottedOptionsChanged(prev, next);
|
|
21207
|
+
this.updateValue();
|
|
21122
21208
|
if (value) {
|
|
21123
21209
|
this.value = value;
|
|
21124
21210
|
}
|
|
21125
21211
|
}
|
|
21126
21212
|
connectedCallback() {
|
|
21127
21213
|
super.connectedCallback();
|
|
21128
|
-
|
|
21214
|
+
this.forcedPosition = !!this.positionAttribute;
|
|
21215
|
+
if (this.value) {
|
|
21216
|
+
this.initialValue = this.value;
|
|
21217
|
+
}
|
|
21129
21218
|
this.setPositioning();
|
|
21130
21219
|
this.updateInputAriaLabel();
|
|
21131
21220
|
}
|
|
21221
|
+
/**
|
|
21222
|
+
* @internal
|
|
21223
|
+
*/
|
|
21224
|
+
clickHandler(e) {
|
|
21225
|
+
if (this.disabled) {
|
|
21226
|
+
return false;
|
|
21227
|
+
}
|
|
21228
|
+
if (this.open) {
|
|
21229
|
+
const captured = e.target.closest('option,[role=option]');
|
|
21230
|
+
if (!captured || captured.disabled) {
|
|
21231
|
+
return false;
|
|
21232
|
+
}
|
|
21233
|
+
this.selectedOptions = [captured];
|
|
21234
|
+
this.control.value = captured.text;
|
|
21235
|
+
this.clearSelectionRange();
|
|
21236
|
+
this.updateValue(true);
|
|
21237
|
+
}
|
|
21238
|
+
this.open = !this.open;
|
|
21239
|
+
if (this.open) {
|
|
21240
|
+
this.control.focus();
|
|
21241
|
+
}
|
|
21242
|
+
return true;
|
|
21243
|
+
}
|
|
21244
|
+
/**
|
|
21245
|
+
* @internal
|
|
21246
|
+
*/
|
|
21132
21247
|
toggleButtonClickHandler(e) {
|
|
21133
21248
|
e.stopImmediatePropagation();
|
|
21134
21249
|
}
|
|
21250
|
+
/**
|
|
21251
|
+
* @internal
|
|
21252
|
+
*/
|
|
21135
21253
|
toggleButtonChangeHandler(e) {
|
|
21136
21254
|
this.open = this.dropdownButton.checked;
|
|
21137
21255
|
e.stopImmediatePropagation();
|
|
21138
21256
|
}
|
|
21257
|
+
/**
|
|
21258
|
+
* @internal
|
|
21259
|
+
*/
|
|
21139
21260
|
toggleButtonKeyDownHandler(e) {
|
|
21140
21261
|
switch (e.key) {
|
|
21141
21262
|
case keyArrowUp:
|
|
@@ -21149,20 +21270,57 @@
|
|
|
21149
21270
|
return true;
|
|
21150
21271
|
}
|
|
21151
21272
|
}
|
|
21273
|
+
/**
|
|
21274
|
+
* @internal
|
|
21275
|
+
*/
|
|
21152
21276
|
filterOptions() {
|
|
21153
|
-
|
|
21277
|
+
if (!this.autocomplete
|
|
21278
|
+
|| this.autocomplete === ComboboxAutocomplete.none) {
|
|
21279
|
+
this.filter = '';
|
|
21280
|
+
}
|
|
21281
|
+
const filter = this.filter.toLowerCase();
|
|
21282
|
+
this.filteredOptions = this._options.filter(o => o.text.toLowerCase().startsWith(filter));
|
|
21283
|
+
if (this.isAutocompleteList) {
|
|
21284
|
+
if (!this.filteredOptions.length && !filter) {
|
|
21285
|
+
this.filteredOptions = this._options;
|
|
21286
|
+
}
|
|
21287
|
+
this._options.forEach(o => {
|
|
21288
|
+
o.visuallyHidden = !this.filteredOptions.includes(o);
|
|
21289
|
+
});
|
|
21290
|
+
}
|
|
21154
21291
|
const enabledOptions = this.filteredOptions.filter(o => !o.disabled);
|
|
21155
21292
|
this.filteredOptions = enabledOptions;
|
|
21156
21293
|
}
|
|
21157
21294
|
/**
|
|
21158
|
-
*
|
|
21159
|
-
* For now, we will update the value ourselves while a user types in text. Note that there is other
|
|
21160
|
-
* implementation related to this (like the 'keydownEventHandler') needed to create the complete set
|
|
21161
|
-
* of desired behavior described in the issue noted above.
|
|
21295
|
+
* @internal
|
|
21162
21296
|
*/
|
|
21163
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
|
21164
21297
|
inputHandler(e) {
|
|
21165
|
-
|
|
21298
|
+
this.filter = this.control.value;
|
|
21299
|
+
this.filterOptions();
|
|
21300
|
+
if (!this.isAutocompleteInline) {
|
|
21301
|
+
this.selectedIndex = this.options
|
|
21302
|
+
.map(option => option.text)
|
|
21303
|
+
.indexOf(this.control.value);
|
|
21304
|
+
}
|
|
21305
|
+
if (!(e.inputType.includes('deleteContent') || !this.filter.length)) {
|
|
21306
|
+
if (this.isAutocompleteList && !this.open) {
|
|
21307
|
+
this.open = true;
|
|
21308
|
+
}
|
|
21309
|
+
if (this.isAutocompleteInline) {
|
|
21310
|
+
if (this.filteredOptions.length) {
|
|
21311
|
+
this.selectedOptions = [this.filteredOptions[0]];
|
|
21312
|
+
this.selectedIndex = this.options.indexOf(this.firstSelectedOption);
|
|
21313
|
+
this.setInlineSelection();
|
|
21314
|
+
}
|
|
21315
|
+
else {
|
|
21316
|
+
this.selectedIndex = -1;
|
|
21317
|
+
}
|
|
21318
|
+
}
|
|
21319
|
+
}
|
|
21320
|
+
// This is a workaround for the issue described here: https://github.com/microsoft/fast/issues/6267
|
|
21321
|
+
// For now, we will update the value ourselves while a user types in text. Note that there is other
|
|
21322
|
+
// implementation related to this (like the 'keydownEventHandler') needed to create the complete set
|
|
21323
|
+
// of desired behavior described in the issue noted above.
|
|
21166
21324
|
if (!this.valueUpdatedByInput) {
|
|
21167
21325
|
this.valueBeforeTextUpdate = this.value;
|
|
21168
21326
|
}
|
|
@@ -21172,47 +21330,257 @@
|
|
|
21172
21330
|
this.focusAndScrollOptionIntoView();
|
|
21173
21331
|
}
|
|
21174
21332
|
this.value = this.control.value;
|
|
21175
|
-
return
|
|
21333
|
+
return true;
|
|
21176
21334
|
}
|
|
21177
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
|
21178
21335
|
keydownHandler(e) {
|
|
21179
|
-
const returnValue = super.keydownHandler(e);
|
|
21180
21336
|
if (e.ctrlKey || e.altKey) {
|
|
21181
|
-
return
|
|
21337
|
+
return true;
|
|
21182
21338
|
}
|
|
21183
21339
|
switch (e.key) {
|
|
21184
21340
|
case keyEnter:
|
|
21341
|
+
this.syncValue();
|
|
21342
|
+
if (this.isAutocompleteInline) {
|
|
21343
|
+
this.filter = this.value;
|
|
21344
|
+
}
|
|
21345
|
+
this.open = false;
|
|
21346
|
+
this.clearSelectionRange();
|
|
21185
21347
|
this.emitChangeIfValueUpdated();
|
|
21186
21348
|
break;
|
|
21349
|
+
case keyEscape:
|
|
21350
|
+
if (!this.isAutocompleteInline) {
|
|
21351
|
+
this.selectedIndex = -1;
|
|
21352
|
+
}
|
|
21353
|
+
if (this.open) {
|
|
21354
|
+
this.open = false;
|
|
21355
|
+
break;
|
|
21356
|
+
}
|
|
21357
|
+
this.value = '';
|
|
21358
|
+
this.control.value = '';
|
|
21359
|
+
this.filter = '';
|
|
21360
|
+
this.filterOptions();
|
|
21361
|
+
break;
|
|
21362
|
+
case keyTab:
|
|
21363
|
+
this.setInputToSelection();
|
|
21364
|
+
if (!this.open) {
|
|
21365
|
+
return true;
|
|
21366
|
+
}
|
|
21367
|
+
e.preventDefault();
|
|
21368
|
+
this.open = false;
|
|
21369
|
+
break;
|
|
21187
21370
|
case keyArrowDown:
|
|
21188
21371
|
case keyArrowUp:
|
|
21372
|
+
this.filterOptions();
|
|
21373
|
+
if (!this.open) {
|
|
21374
|
+
this.open = true;
|
|
21375
|
+
break;
|
|
21376
|
+
}
|
|
21377
|
+
if (this.filteredOptions.length > 0) {
|
|
21378
|
+
super.keydownHandler(e);
|
|
21379
|
+
}
|
|
21380
|
+
if (this.isAutocompleteInline) {
|
|
21381
|
+
this.setInlineSelection();
|
|
21382
|
+
}
|
|
21189
21383
|
if (this.open && this.valueUpdatedByInput) {
|
|
21190
21384
|
this.valueUpdatedByInput = false;
|
|
21191
21385
|
}
|
|
21192
21386
|
break;
|
|
21193
21387
|
default:
|
|
21194
|
-
return
|
|
21388
|
+
return true;
|
|
21389
|
+
}
|
|
21390
|
+
return true;
|
|
21391
|
+
}
|
|
21392
|
+
/**
|
|
21393
|
+
* @internal
|
|
21394
|
+
*/
|
|
21395
|
+
keyupHandler(e) {
|
|
21396
|
+
const key = e.key;
|
|
21397
|
+
switch (key) {
|
|
21398
|
+
case 'ArrowLeft':
|
|
21399
|
+
case 'ArrowRight':
|
|
21400
|
+
case 'Backspace':
|
|
21401
|
+
case 'Delete':
|
|
21402
|
+
case 'Home':
|
|
21403
|
+
case 'End': {
|
|
21404
|
+
this.filter = this.control.value;
|
|
21405
|
+
this.selectedIndex = -1;
|
|
21406
|
+
this.filterOptions();
|
|
21407
|
+
break;
|
|
21408
|
+
}
|
|
21195
21409
|
}
|
|
21196
|
-
return
|
|
21410
|
+
return true;
|
|
21197
21411
|
}
|
|
21198
|
-
|
|
21412
|
+
/**
|
|
21413
|
+
* @internal
|
|
21414
|
+
*/
|
|
21199
21415
|
focusoutHandler(e) {
|
|
21200
|
-
|
|
21416
|
+
this.syncValue();
|
|
21417
|
+
if (this.open) {
|
|
21418
|
+
const focusTarget = e.relatedTarget;
|
|
21419
|
+
if (this.isSameNode(focusTarget)) {
|
|
21420
|
+
this.focus();
|
|
21421
|
+
}
|
|
21422
|
+
}
|
|
21201
21423
|
this.open = false;
|
|
21202
21424
|
this.emitChangeIfValueUpdated();
|
|
21203
|
-
return
|
|
21425
|
+
return true;
|
|
21426
|
+
}
|
|
21427
|
+
/**
|
|
21428
|
+
* Reset the element to its first selectable option when its parent form is reset.
|
|
21429
|
+
*
|
|
21430
|
+
* @internal
|
|
21431
|
+
*/
|
|
21432
|
+
formResetCallback() {
|
|
21433
|
+
super.formResetCallback();
|
|
21434
|
+
this.setDefaultSelectedOption();
|
|
21435
|
+
this.updateValue();
|
|
21436
|
+
}
|
|
21437
|
+
/** {@inheritDoc (FormAssociated:interface).validate} */
|
|
21438
|
+
validate() {
|
|
21439
|
+
super.validate(this.control);
|
|
21440
|
+
}
|
|
21441
|
+
/**
|
|
21442
|
+
* Set the default selected options at initialization or reset.
|
|
21443
|
+
*
|
|
21444
|
+
* @internal
|
|
21445
|
+
* @remarks
|
|
21446
|
+
* Overrides `Listbox.setDefaultSelectedOption`
|
|
21447
|
+
*/
|
|
21448
|
+
setDefaultSelectedOption() {
|
|
21449
|
+
if (this.$fastController.isConnected && this.options) {
|
|
21450
|
+
const selectedIndex = this.options.findIndex(el => el.getAttribute('selected') !== null || el.selected);
|
|
21451
|
+
this.selectedIndex = selectedIndex;
|
|
21452
|
+
if (!this.dirtyValue && this.firstSelectedOption) {
|
|
21453
|
+
this.value = this.firstSelectedOption.text;
|
|
21454
|
+
}
|
|
21455
|
+
this.setSelectedOptions();
|
|
21456
|
+
}
|
|
21457
|
+
}
|
|
21458
|
+
/**
|
|
21459
|
+
* @internal
|
|
21460
|
+
*/
|
|
21461
|
+
selectedIndexChanged(prev, next) {
|
|
21462
|
+
if (this.$fastController.isConnected) {
|
|
21463
|
+
const pinnedSelectedIndex = limit(-1, this.options.length - 1, next);
|
|
21464
|
+
// we only want to call the super method when the selectedIndex is in range
|
|
21465
|
+
if (pinnedSelectedIndex !== this.selectedIndex) {
|
|
21466
|
+
this.selectedIndex = pinnedSelectedIndex;
|
|
21467
|
+
return;
|
|
21468
|
+
}
|
|
21469
|
+
super.selectedIndexChanged(prev, pinnedSelectedIndex);
|
|
21470
|
+
}
|
|
21471
|
+
}
|
|
21472
|
+
/**
|
|
21473
|
+
* Synchronize the `aria-disabled` property when the `disabled` property changes.
|
|
21474
|
+
*
|
|
21475
|
+
* @internal
|
|
21476
|
+
*/
|
|
21477
|
+
disabledChanged(prev, next) {
|
|
21478
|
+
if (super.disabledChanged) {
|
|
21479
|
+
super.disabledChanged(prev, next);
|
|
21480
|
+
}
|
|
21481
|
+
this.ariaDisabled = this.disabled ? 'true' : 'false';
|
|
21482
|
+
}
|
|
21483
|
+
/**
|
|
21484
|
+
* Move focus to the previous selectable option.
|
|
21485
|
+
*
|
|
21486
|
+
* @internal
|
|
21487
|
+
* @remarks
|
|
21488
|
+
* Overrides `Listbox.selectPreviousOption`
|
|
21489
|
+
*/
|
|
21490
|
+
selectPreviousOption() {
|
|
21491
|
+
if (!this.disabled && this.selectedIndex >= 0) {
|
|
21492
|
+
this.selectedIndex -= 1;
|
|
21493
|
+
}
|
|
21494
|
+
}
|
|
21495
|
+
/**
|
|
21496
|
+
* @internal
|
|
21497
|
+
*/
|
|
21498
|
+
setPositioning() {
|
|
21499
|
+
// Workaround for https://github.com/microsoft/fast/issues/5123
|
|
21500
|
+
if (!this.$fastController.isConnected) {
|
|
21501
|
+
// Don't call setPositioning() until we're connected,
|
|
21502
|
+
// since this.forcedPosition isn't initialized yet.
|
|
21503
|
+
return;
|
|
21504
|
+
}
|
|
21505
|
+
const currentBox = this.getBoundingClientRect();
|
|
21506
|
+
const viewportHeight = window.innerHeight;
|
|
21507
|
+
const availableBottom = viewportHeight - currentBox.bottom;
|
|
21508
|
+
if (this.forcedPosition) {
|
|
21509
|
+
this.position = this.positionAttribute;
|
|
21510
|
+
}
|
|
21511
|
+
else if (currentBox.top > availableBottom) {
|
|
21512
|
+
this.position = SelectPosition.above;
|
|
21513
|
+
}
|
|
21514
|
+
else {
|
|
21515
|
+
this.position = SelectPosition.below;
|
|
21516
|
+
}
|
|
21517
|
+
this.positionAttribute = this.forcedPosition
|
|
21518
|
+
? this.positionAttribute
|
|
21519
|
+
: this.position;
|
|
21520
|
+
this.maxHeight = this.position === SelectPosition.above
|
|
21521
|
+
? Math.trunc(currentBox.top)
|
|
21522
|
+
: Math.trunc(availableBottom);
|
|
21204
21523
|
}
|
|
21524
|
+
/**
|
|
21525
|
+
* Focus the control and scroll the first selected option into view.
|
|
21526
|
+
*
|
|
21527
|
+
* @internal
|
|
21528
|
+
* @remarks
|
|
21529
|
+
* Overrides: `Listbox.focusAndScrollOptionIntoView`
|
|
21530
|
+
*/
|
|
21205
21531
|
focusAndScrollOptionIntoView() {
|
|
21206
21532
|
if (this.open) {
|
|
21207
|
-
|
|
21533
|
+
if (this.contains(document.activeElement)) {
|
|
21534
|
+
this.control.focus();
|
|
21535
|
+
if (this.firstSelectedOption) {
|
|
21536
|
+
requestAnimationFrame(() => {
|
|
21537
|
+
this.firstSelectedOption?.scrollIntoView({
|
|
21538
|
+
block: 'nearest'
|
|
21539
|
+
});
|
|
21540
|
+
});
|
|
21541
|
+
}
|
|
21542
|
+
}
|
|
21208
21543
|
}
|
|
21209
21544
|
}
|
|
21210
21545
|
openChanged() {
|
|
21211
|
-
|
|
21546
|
+
if (this.open) {
|
|
21547
|
+
this.ariaControls = this.listboxId;
|
|
21548
|
+
this.ariaExpanded = 'true';
|
|
21549
|
+
this.setPositioning();
|
|
21550
|
+
this.focusAndScrollOptionIntoView();
|
|
21551
|
+
// focus is directed to the element when `open` is changed programmatically
|
|
21552
|
+
DOM.queueUpdate(() => this.focus());
|
|
21553
|
+
}
|
|
21554
|
+
else {
|
|
21555
|
+
this.ariaControls = '';
|
|
21556
|
+
this.ariaExpanded = 'false';
|
|
21557
|
+
}
|
|
21212
21558
|
if (this.dropdownButton) {
|
|
21213
21559
|
this.dropdownButton.checked = this.open;
|
|
21214
21560
|
}
|
|
21215
21561
|
}
|
|
21562
|
+
placeholderChanged() {
|
|
21563
|
+
if (this.proxy instanceof HTMLInputElement) {
|
|
21564
|
+
this.proxy.placeholder = this.placeholder ?? '';
|
|
21565
|
+
}
|
|
21566
|
+
}
|
|
21567
|
+
/**
|
|
21568
|
+
* Ensure that the entire list of options is used when setting the selected property.
|
|
21569
|
+
* @internal
|
|
21570
|
+
* @remarks
|
|
21571
|
+
* Overrides: `Listbox.selectedOptionsChanged`
|
|
21572
|
+
*/
|
|
21573
|
+
selectedOptionsChanged(_, next) {
|
|
21574
|
+
if (this.$fastController.isConnected) {
|
|
21575
|
+
this._options.forEach(o => {
|
|
21576
|
+
o.selected = next.includes(o);
|
|
21577
|
+
});
|
|
21578
|
+
}
|
|
21579
|
+
}
|
|
21580
|
+
positionChanged(_, next) {
|
|
21581
|
+
this.positionAttribute = next;
|
|
21582
|
+
this.setPositioning();
|
|
21583
|
+
}
|
|
21216
21584
|
regionChanged(_prev, _next) {
|
|
21217
21585
|
if (this.region && this.controlWrapper) {
|
|
21218
21586
|
this.region.anchorElement = this.controlWrapper;
|
|
@@ -21230,6 +21598,49 @@
|
|
|
21230
21598
|
maxHeightChanged() {
|
|
21231
21599
|
this.updateListboxMaxHeightCssVariable();
|
|
21232
21600
|
}
|
|
21601
|
+
/**
|
|
21602
|
+
* Sets the value and to match the first selected option.
|
|
21603
|
+
*/
|
|
21604
|
+
updateValue(shouldEmit) {
|
|
21605
|
+
if (this.$fastController.isConnected) {
|
|
21606
|
+
this.value = this.firstSelectedOption?.text || this.control.value;
|
|
21607
|
+
this.control.value = this.value;
|
|
21608
|
+
}
|
|
21609
|
+
if (shouldEmit) {
|
|
21610
|
+
this.$emit('change');
|
|
21611
|
+
}
|
|
21612
|
+
}
|
|
21613
|
+
/**
|
|
21614
|
+
* Focus and set the content of the control based on the first selected option.
|
|
21615
|
+
*/
|
|
21616
|
+
setInputToSelection() {
|
|
21617
|
+
if (this.firstSelectedOption) {
|
|
21618
|
+
this.control.value = this.firstSelectedOption.text;
|
|
21619
|
+
this.control.focus();
|
|
21620
|
+
}
|
|
21621
|
+
}
|
|
21622
|
+
/**
|
|
21623
|
+
* Focus, set and select the content of the control based on the first selected option.
|
|
21624
|
+
*/
|
|
21625
|
+
setInlineSelection() {
|
|
21626
|
+
if (this.firstSelectedOption) {
|
|
21627
|
+
this.setInputToSelection();
|
|
21628
|
+
this.control.setSelectionRange(this.filter.length, this.control.value.length, 'backward');
|
|
21629
|
+
}
|
|
21630
|
+
}
|
|
21631
|
+
clearSelectionRange() {
|
|
21632
|
+
const controlValueLength = this.control.value.length;
|
|
21633
|
+
this.control.setSelectionRange(controlValueLength, controlValueLength);
|
|
21634
|
+
}
|
|
21635
|
+
/**
|
|
21636
|
+
* Determines if a value update should involve emitting a change event, then updates the value.
|
|
21637
|
+
*/
|
|
21638
|
+
syncValue() {
|
|
21639
|
+
const newValue = this.selectedIndex > -1
|
|
21640
|
+
? this.firstSelectedOption?.text
|
|
21641
|
+
: this.control.value;
|
|
21642
|
+
this.updateValue(this.value !== newValue);
|
|
21643
|
+
}
|
|
21233
21644
|
updateListboxMaxHeightCssVariable() {
|
|
21234
21645
|
if (this.listbox) {
|
|
21235
21646
|
this.listbox.style.setProperty('--ni-private-select-max-height', `${this.maxHeight}px`);
|
|
@@ -21266,27 +21677,51 @@
|
|
|
21266
21677
|
__decorate$1([
|
|
21267
21678
|
attr
|
|
21268
21679
|
], Combobox.prototype, "appearance", void 0);
|
|
21269
|
-
__decorate$1([
|
|
21270
|
-
observable
|
|
21271
|
-
], Combobox.prototype, "dropdownButton", void 0);
|
|
21272
21680
|
__decorate$1([
|
|
21273
21681
|
attr({ attribute: 'error-text' })
|
|
21274
21682
|
], Combobox.prototype, "errorText", void 0);
|
|
21275
21683
|
__decorate$1([
|
|
21276
21684
|
attr({ attribute: 'error-visible', mode: 'boolean' })
|
|
21277
21685
|
], Combobox.prototype, "errorVisible", void 0);
|
|
21686
|
+
__decorate$1([
|
|
21687
|
+
attr({ attribute: 'autocomplete', mode: 'fromView' })
|
|
21688
|
+
], Combobox.prototype, "autocomplete", void 0);
|
|
21689
|
+
__decorate$1([
|
|
21690
|
+
attr({ attribute: 'position' })
|
|
21691
|
+
], Combobox.prototype, "positionAttribute", void 0);
|
|
21692
|
+
__decorate$1([
|
|
21693
|
+
attr({ attribute: 'open', mode: 'boolean' })
|
|
21694
|
+
], Combobox.prototype, "open", void 0);
|
|
21695
|
+
__decorate$1([
|
|
21696
|
+
attr
|
|
21697
|
+
], Combobox.prototype, "placeholder", void 0);
|
|
21698
|
+
__decorate$1([
|
|
21699
|
+
observable
|
|
21700
|
+
], Combobox.prototype, "position", void 0);
|
|
21278
21701
|
__decorate$1([
|
|
21279
21702
|
observable
|
|
21280
21703
|
], Combobox.prototype, "region", void 0);
|
|
21281
21704
|
__decorate$1([
|
|
21282
21705
|
observable
|
|
21283
21706
|
], Combobox.prototype, "controlWrapper", void 0);
|
|
21707
|
+
__decorate$1([
|
|
21708
|
+
observable
|
|
21709
|
+
], Combobox.prototype, "control", void 0);
|
|
21710
|
+
__decorate$1([
|
|
21711
|
+
observable
|
|
21712
|
+
], Combobox.prototype, "listbox", void 0);
|
|
21713
|
+
__decorate$1([
|
|
21714
|
+
observable
|
|
21715
|
+
], Combobox.prototype, "dropdownButton", void 0);
|
|
21284
21716
|
__decorate$1([
|
|
21285
21717
|
observable
|
|
21286
21718
|
], Combobox.prototype, "hasOverflow", void 0);
|
|
21719
|
+
__decorate$1([
|
|
21720
|
+
observable
|
|
21721
|
+
], Combobox.prototype, "maxHeight", void 0);
|
|
21287
21722
|
const nimbleCombobox = Combobox.compose({
|
|
21288
21723
|
baseName: 'combobox',
|
|
21289
|
-
baseClass:
|
|
21724
|
+
baseClass: FormAssociatedCombobox,
|
|
21290
21725
|
template: template$u,
|
|
21291
21726
|
styles: styles$D,
|
|
21292
21727
|
shadowOptions: {
|
|
@@ -21324,6 +21759,7 @@
|
|
|
21324
21759
|
${errorTextTemplate}
|
|
21325
21760
|
`
|
|
21326
21761
|
});
|
|
21762
|
+
applyMixins(Combobox, StartEnd, DelegatesARIACombobox);
|
|
21327
21763
|
DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleCombobox());
|
|
21328
21764
|
|
|
21329
21765
|
/**
|