@tylertech/forge 3.12.0 → 3.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +1792 -231
- package/dist/lib.js +12 -12
- package/dist/lib.js.map +4 -4
- package/dist/vscode.css-custom-data.json +2 -1
- package/dist/vscode.html-custom-data.json +85 -1
- package/esm/autocomplete/autocomplete-constants.d.ts +1 -0
- package/esm/autocomplete/autocomplete-constants.js +1 -0
- package/esm/autocomplete/autocomplete-core.d.ts +6 -0
- package/esm/autocomplete/autocomplete-core.js +49 -12
- package/esm/autocomplete/autocomplete.d.ts +7 -0
- package/esm/autocomplete/autocomplete.js +7 -0
- package/esm/calendar/calendar-core.d.ts +2 -0
- package/esm/calendar/calendar-core.js +20 -14
- package/esm/core/testing/test-harness.d.ts +11 -0
- package/esm/core/testing/test-harness.js +14 -0
- package/esm/core/testing/utils.d.ts +7 -0
- package/esm/core/testing/utils.js +14 -0
- package/esm/core/utils/index.d.ts +1 -0
- package/esm/core/utils/index.js +1 -0
- package/esm/core/utils/key-action.d.ts +102 -0
- package/esm/core/utils/key-action.js +109 -0
- package/esm/expansion-panel/expansion-panel-adapter.d.ts +9 -0
- package/esm/expansion-panel/expansion-panel-adapter.js +31 -3
- package/esm/expansion-panel/expansion-panel-constants.d.ts +2 -0
- package/esm/expansion-panel/expansion-panel-constants.js +2 -1
- package/esm/expansion-panel/expansion-panel-core.d.ts +7 -0
- package/esm/expansion-panel/expansion-panel-core.js +30 -0
- package/esm/expansion-panel/expansion-panel.d.ts +11 -3
- package/esm/expansion-panel/expansion-panel.js +16 -3
- package/esm/list-dropdown/list-dropdown-core.js +1 -1
- package/esm/list-dropdown/list-dropdown-utils.js +1 -1
- package/esm/list-dropdown/list-dropdown.js +1 -1
- package/esm/paginator/paginator-adapter.d.ts +1 -0
- package/esm/paginator/paginator-adapter.js +15 -4
- package/esm/split-view/split-view-panel/split-view-panel.js +1 -1
- package/esm/tree/index.d.ts +7 -0
- package/esm/tree/index.js +7 -0
- package/esm/tree/tree/index.d.ts +7 -0
- package/esm/tree/tree/index.js +11 -0
- package/esm/tree/tree/tree-selection-controller.d.ts +104 -0
- package/esm/tree/tree/tree-selection-controller.js +375 -0
- package/esm/tree/tree/tree.d.ts +141 -0
- package/esm/tree/tree/tree.js +488 -0
- package/esm/tree/tree-item/index.d.ts +7 -0
- package/esm/tree/tree-item/index.js +11 -0
- package/esm/tree/tree-item/tree-item.d.ts +112 -0
- package/esm/tree/tree-item/tree-item.js +378 -0
- package/esm/tree/tree-utils.d.ts +154 -0
- package/esm/tree/tree-utils.js +315 -0
- package/package.json +2 -1
- package/sass/core/styles/tokens/tree/tree/_tokens.scss +24 -0
- package/sass/core/styles/tokens/tree/tree-item/_tokens.scss +39 -0
- package/sass/tree/tree/_core.scss +31 -0
- package/sass/tree/tree/_token-utils.scss +30 -0
- package/sass/tree/tree/index.scss +6 -0
- package/sass/tree/tree/tree.scss +44 -0
- package/sass/tree/tree-item/_core.scss +121 -0
- package/sass/tree/tree-item/_token-utils.scss +30 -0
- package/sass/tree/tree-item/index.scss +6 -0
- package/sass/tree/tree-item/tree-item.scss +199 -0
|
@@ -43,6 +43,11 @@
|
|
|
43
43
|
"description": "Gets/sets whether the first option in the dropdown will be focused automatically when opened or not.",
|
|
44
44
|
"values": []
|
|
45
45
|
},
|
|
46
|
+
{
|
|
47
|
+
"name": "select-first-option-on-blur",
|
|
48
|
+
"description": "Determines whether the first available option should be selected automatically when blurring mid-filter.",
|
|
49
|
+
"values": []
|
|
50
|
+
},
|
|
46
51
|
{
|
|
47
52
|
"name": "allow-unmatched",
|
|
48
53
|
"description": "Controls whether unmatched text entered by the user will stay visible an option in the dropdown is not found.",
|
|
@@ -900,7 +905,12 @@
|
|
|
900
905
|
},
|
|
901
906
|
{
|
|
902
907
|
"name": "trigger",
|
|
903
|
-
"description": "The id of the button that the expansion panel
|
|
908
|
+
"description": "The id of the button that the expansion panel should be toggled by.",
|
|
909
|
+
"values": []
|
|
910
|
+
},
|
|
911
|
+
{
|
|
912
|
+
"name": "open-icon",
|
|
913
|
+
"description": "The id of the `<forge-open-icon>` that the expansion panel should toggle.",
|
|
904
914
|
"values": []
|
|
905
915
|
}
|
|
906
916
|
],
|
|
@@ -3929,6 +3939,80 @@
|
|
|
3929
3939
|
],
|
|
3930
3940
|
"references": []
|
|
3931
3941
|
},
|
|
3942
|
+
{
|
|
3943
|
+
"name": "forge-tree",
|
|
3944
|
+
"description": "Trees are interactive lists that allow users to navigate through hierarchical data.\n---\n\n\n### **Events:**\n - **forge-tree-select-all** - Dispatched when the user selects all items.\n\n### **Slots:**\n - _default_ - The default slot for tree items.\n- **expand-icon** - A custom expand icon to show when an item is closed.\n- **collapse-icon** - A custom collapse icon to show when an item is open.\n\n### **CSS Parts:**\n - **root** - The root tree element.",
|
|
3945
|
+
"attributes": [
|
|
3946
|
+
{
|
|
3947
|
+
"name": "accordion",
|
|
3948
|
+
"description": "Whether opening an item closes all other items.",
|
|
3949
|
+
"values": []
|
|
3950
|
+
},
|
|
3951
|
+
{
|
|
3952
|
+
"name": "indentLines",
|
|
3953
|
+
"description": "Toggles the rendering of indent lines showing hierarchy.",
|
|
3954
|
+
"values": []
|
|
3955
|
+
},
|
|
3956
|
+
{
|
|
3957
|
+
"name": "mode",
|
|
3958
|
+
"description": "How selecting tree items is handled.",
|
|
3959
|
+
"values": [{ "name": "TreeMode" }]
|
|
3960
|
+
},
|
|
3961
|
+
{
|
|
3962
|
+
"name": "selectionFollowsFocus",
|
|
3963
|
+
"description": "Whether focusing an item also selects it. This takes no effect when in multiple mode.",
|
|
3964
|
+
"values": []
|
|
3965
|
+
},
|
|
3966
|
+
{
|
|
3967
|
+
"name": "disabled",
|
|
3968
|
+
"description": "Whether selecting items is disabled.",
|
|
3969
|
+
"values": []
|
|
3970
|
+
},
|
|
3971
|
+
{
|
|
3972
|
+
"name": "value",
|
|
3973
|
+
"description": "The value of all selected items.",
|
|
3974
|
+
"values": [{ "name": "unknown[]" }]
|
|
3975
|
+
}
|
|
3976
|
+
],
|
|
3977
|
+
"references": []
|
|
3978
|
+
},
|
|
3979
|
+
{
|
|
3980
|
+
"name": "forge-tree-item",
|
|
3981
|
+
"description": "\n---\n\n\n### **Events:**\n - **forge-tree-item-update**\n- **forge-tree-item-select** - Dispatched when the user selects a tree item.\n- **forge-tree-item-open** - Dispatched when the user opens a tree item.\n- **forge-tree-item-close** - Dispatched when the user closes a tree item.",
|
|
3982
|
+
"attributes": [
|
|
3983
|
+
{
|
|
3984
|
+
"name": "value",
|
|
3985
|
+
"description": "The value of the tree item.",
|
|
3986
|
+
"values": []
|
|
3987
|
+
},
|
|
3988
|
+
{
|
|
3989
|
+
"name": "selected",
|
|
3990
|
+
"description": "Whether the tree item is selected.",
|
|
3991
|
+
"values": []
|
|
3992
|
+
},
|
|
3993
|
+
{
|
|
3994
|
+
"name": "open",
|
|
3995
|
+
"description": "Whether the tree item is expanded.",
|
|
3996
|
+
"values": []
|
|
3997
|
+
},
|
|
3998
|
+
{
|
|
3999
|
+
"name": "lazy",
|
|
4000
|
+
"description": "Whether the tree item supports lazy loading.",
|
|
4001
|
+
"values": []
|
|
4002
|
+
},
|
|
4003
|
+
{
|
|
4004
|
+
"name": "disabled",
|
|
4005
|
+
"description": "Whether the tree item is disabled.",
|
|
4006
|
+
"values": []
|
|
4007
|
+
},
|
|
4008
|
+
{
|
|
4009
|
+
"name": "openDisabled",
|
|
4010
|
+
"description": "Whether opening the tree item is disabled.",
|
|
4011
|
+
"values": []
|
|
4012
|
+
}
|
|
4013
|
+
],
|
|
4014
|
+
"references": []
|
|
4015
|
+
},
|
|
3932
4016
|
{
|
|
3933
4017
|
"name": "forge-view",
|
|
3934
4018
|
"description": "Represents a single view content area within a view-switcher for organizing and displaying content sections.\n---\n",
|
|
@@ -11,6 +11,7 @@ const attributes = {
|
|
|
11
11
|
DEBOUNCE: 'debounce',
|
|
12
12
|
FILTER_ON_FOCUS: 'filter-on-focus',
|
|
13
13
|
FILTER_FOCUS_FIRST: 'filter-focus-first',
|
|
14
|
+
SELECT_FIRST_OPTION_ON_BLUR: 'select-first-option-on-blur',
|
|
14
15
|
ALLOW_UNMATCHED: 'allow-unmatched',
|
|
15
16
|
POPUP_TARGET: 'popup-target',
|
|
16
17
|
POPUP_CLASSES: 'popup-classes',
|
|
@@ -14,6 +14,7 @@ export interface IAutocompleteCore extends IListDropdownAwareCore {
|
|
|
14
14
|
debounce: number;
|
|
15
15
|
filterOnFocus: boolean;
|
|
16
16
|
filterFocusFirst: boolean;
|
|
17
|
+
selectFirstOptionOnBlur: boolean;
|
|
17
18
|
allowUnmatched: boolean;
|
|
18
19
|
popupTarget: string;
|
|
19
20
|
filterText: string;
|
|
@@ -38,6 +39,7 @@ export declare class AutocompleteCore extends ListDropdownAwareCore implements I
|
|
|
38
39
|
private _popupTarget;
|
|
39
40
|
private _filterOnFocus;
|
|
40
41
|
private _filterFocusFirst;
|
|
42
|
+
private _selectFirstOptionOnBlur;
|
|
41
43
|
private _optionBuilder?;
|
|
42
44
|
private _filter?;
|
|
43
45
|
private _selectedTextBuilder;
|
|
@@ -46,6 +48,7 @@ export declare class AutocompleteCore extends ListDropdownAwareCore implements I
|
|
|
46
48
|
private _selectedOptions;
|
|
47
49
|
private _values;
|
|
48
50
|
private _pendingFilterPromises;
|
|
51
|
+
private _selectOnBlurPending;
|
|
49
52
|
private _identifier;
|
|
50
53
|
private _matchKey?;
|
|
51
54
|
private _filterFn;
|
|
@@ -81,6 +84,7 @@ export declare class AutocompleteCore extends ListDropdownAwareCore implements I
|
|
|
81
84
|
private _onFocus;
|
|
82
85
|
private _onBlur;
|
|
83
86
|
private _applyBlur;
|
|
87
|
+
private _shouldSelectFirstOptionOnBlur;
|
|
84
88
|
private _onInput;
|
|
85
89
|
private _debounceFilter;
|
|
86
90
|
private _onKeydown;
|
|
@@ -131,6 +135,8 @@ export declare class AutocompleteCore extends ListDropdownAwareCore implements I
|
|
|
131
135
|
/** Gets/sets whether the first option in the dropdown will be focused automatically when opened or not. */
|
|
132
136
|
get filterFocusFirst(): boolean;
|
|
133
137
|
set filterFocusFirst(value: boolean);
|
|
138
|
+
get selectFirstOptionOnBlur(): boolean;
|
|
139
|
+
set selectFirstOptionOnBlur(value: boolean);
|
|
134
140
|
/** Controls whether unmatched text entered by the user will stay visible an option in the dropdown is not found. */
|
|
135
141
|
get allowUnmatched(): boolean;
|
|
136
142
|
set allowUnmatched(value: boolean);
|
|
@@ -21,11 +21,13 @@ export class AutocompleteCore extends ListDropdownAwareCore {
|
|
|
21
21
|
this._allowUnmatched = false;
|
|
22
22
|
this._filterOnFocus = true;
|
|
23
23
|
this._filterFocusFirst = true;
|
|
24
|
+
this._selectFirstOptionOnBlur = false;
|
|
24
25
|
this._options = [];
|
|
25
26
|
this._filterText = '';
|
|
26
27
|
this._selectedOptions = [];
|
|
27
28
|
this._values = [];
|
|
28
29
|
this._pendingFilterPromises = [];
|
|
30
|
+
this._selectOnBlurPending = false;
|
|
29
31
|
this._matchKey = null;
|
|
30
32
|
this._clickListener = evt => this._onClick(evt);
|
|
31
33
|
this._focusListener = () => this._onFocus();
|
|
@@ -147,6 +149,7 @@ export class AutocompleteCore extends ListDropdownAwareCore {
|
|
|
147
149
|
this._adapter.emitHostEvent(AUTOCOMPLETE_CONSTANTS.events.SCROLLED_BOTTOM);
|
|
148
150
|
}
|
|
149
151
|
_onFocus() {
|
|
152
|
+
this._selectOnBlurPending = false;
|
|
150
153
|
if (!this._isDropdownOpen && this._adapter.getInputValue() && !Platform.isMobile) {
|
|
151
154
|
this._adapter.selectInputValue();
|
|
152
155
|
}
|
|
@@ -159,11 +162,11 @@ export class AutocompleteCore extends ListDropdownAwareCore {
|
|
|
159
162
|
this._applyBlur();
|
|
160
163
|
}
|
|
161
164
|
_applyBlur() {
|
|
165
|
+
this._selectOnBlurPending = this._shouldSelectFirstOptionOnBlur();
|
|
162
166
|
if (this._isDropdownOpen) {
|
|
163
167
|
this._closeDropdown();
|
|
164
168
|
}
|
|
165
|
-
|
|
166
|
-
if (this._mode === AutocompleteMode.Stateless) {
|
|
169
|
+
if (this._selectOnBlurPending || this._mode === AutocompleteMode.Stateless) {
|
|
167
170
|
return;
|
|
168
171
|
}
|
|
169
172
|
if (!this._selectedOptions.length) {
|
|
@@ -176,6 +179,9 @@ export class AutocompleteCore extends ListDropdownAwareCore {
|
|
|
176
179
|
this._adapter.setSelectedText(this._getSelectedText());
|
|
177
180
|
}
|
|
178
181
|
}
|
|
182
|
+
_shouldSelectFirstOptionOnBlur() {
|
|
183
|
+
return this._selectFirstOptionOnBlur && !this._multiple && this._mode !== AutocompleteMode.Stateless && !!this._filter && !!this._filterText;
|
|
184
|
+
}
|
|
179
185
|
_onInput(evt) {
|
|
180
186
|
if (this._selectedOptions.length && !this._multiple && (!this._adapter.getInputValue() || this._allowUnmatched) && !this._adapter.isWrappingChipField()) {
|
|
181
187
|
this._selectedOptions = [];
|
|
@@ -203,10 +209,14 @@ export class AutocompleteCore extends ListDropdownAwareCore {
|
|
|
203
209
|
// If the dropdown is open, show the spinner and execute the filter. If not open, then we need to
|
|
204
210
|
// show the dropdown (which will handle showing the spinner and executing the filter for us) so
|
|
205
211
|
// we use the promise from that method instead.
|
|
206
|
-
|
|
212
|
+
const keepDropdownClosed = this._selectOnBlurPending && !this._adapter.hasFocus();
|
|
213
|
+
if (this._isDropdownOpen && keepDropdownClosed) {
|
|
214
|
+
this._closeDropdown();
|
|
215
|
+
}
|
|
216
|
+
else if (this._isDropdownOpen) {
|
|
207
217
|
this._adapter.setBusyVisibility(true);
|
|
208
218
|
}
|
|
209
|
-
else {
|
|
219
|
+
else if (!keepDropdownClosed) {
|
|
210
220
|
this._showDropdown({ filter: false });
|
|
211
221
|
}
|
|
212
222
|
try {
|
|
@@ -215,6 +225,7 @@ export class AutocompleteCore extends ListDropdownAwareCore {
|
|
|
215
225
|
catch {
|
|
216
226
|
// When an exception occurs, we just flush the pending promises and clean up
|
|
217
227
|
this._pendingFilterPromises = [];
|
|
228
|
+
this._selectOnBlurPending = false;
|
|
218
229
|
if (this._isDropdownOpen) {
|
|
219
230
|
this._closeDropdown();
|
|
220
231
|
}
|
|
@@ -307,21 +318,38 @@ export class AutocompleteCore extends ListDropdownAwareCore {
|
|
|
307
318
|
.catch(e => reject(`An unexpected error occurred while filtering: ${e}`)));
|
|
308
319
|
}
|
|
309
320
|
_onFilterComplete() {
|
|
310
|
-
|
|
321
|
+
const shouldSelectOnBlur = this._selectFirstOptionOnBlur && this._selectOnBlurPending;
|
|
322
|
+
if (!this._options.length) {
|
|
323
|
+
this._selectOnBlurPending = false;
|
|
311
324
|
if (this._isDropdownOpen) {
|
|
312
325
|
this._closeDropdown();
|
|
313
326
|
}
|
|
327
|
+
if (shouldSelectOnBlur && !this._allowUnmatched) {
|
|
328
|
+
this._filterText = '';
|
|
329
|
+
this._adapter.setSelectedText('');
|
|
330
|
+
this._clearValue();
|
|
331
|
+
}
|
|
314
332
|
return;
|
|
315
333
|
}
|
|
316
|
-
if (
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
if (
|
|
320
|
-
this.
|
|
334
|
+
if (shouldSelectOnBlur) {
|
|
335
|
+
this._selectOnBlurPending = false;
|
|
336
|
+
const firstOption = this._flatOptions[0];
|
|
337
|
+
if (firstOption) {
|
|
338
|
+
this._onSelect(firstOption.value, false);
|
|
321
339
|
}
|
|
340
|
+
return;
|
|
322
341
|
}
|
|
323
|
-
|
|
324
|
-
this.
|
|
342
|
+
if (!this._adapter.hasFocus()) {
|
|
343
|
+
this._selectOnBlurPending = false;
|
|
344
|
+
if (this._isDropdownOpen) {
|
|
345
|
+
this._closeDropdown();
|
|
346
|
+
}
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
const sendFilterText = this._allowUnmatched && !this._selectedOptions.length;
|
|
350
|
+
this._dropdownReady({ userTriggered: sendFilterText });
|
|
351
|
+
if (this._filterFocusFirst && this._filterText) {
|
|
352
|
+
this._adapter.activateFirstOption();
|
|
325
353
|
}
|
|
326
354
|
}
|
|
327
355
|
_clearValue() {
|
|
@@ -758,6 +786,15 @@ export class AutocompleteCore extends ListDropdownAwareCore {
|
|
|
758
786
|
this._adapter.toggleHostAttribute(AUTOCOMPLETE_CONSTANTS.attributes.FILTER_FOCUS_FIRST, this._filterFocusFirst);
|
|
759
787
|
}
|
|
760
788
|
}
|
|
789
|
+
get selectFirstOptionOnBlur() {
|
|
790
|
+
return this._selectFirstOptionOnBlur;
|
|
791
|
+
}
|
|
792
|
+
set selectFirstOptionOnBlur(value) {
|
|
793
|
+
if (this._selectFirstOptionOnBlur !== value) {
|
|
794
|
+
this._selectFirstOptionOnBlur = value;
|
|
795
|
+
this._adapter.toggleHostAttribute(AUTOCOMPLETE_CONSTANTS.attributes.SELECT_FIRST_OPTION_ON_BLUR, this._selectFirstOptionOnBlur);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
761
798
|
/** Controls whether unmatched text entered by the user will stay visible an option in the dropdown is not found. */
|
|
762
799
|
get allowUnmatched() {
|
|
763
800
|
return this._allowUnmatched;
|
|
@@ -12,6 +12,7 @@ export interface IAutocompleteComponent extends IListDropdownAware {
|
|
|
12
12
|
debounce: number;
|
|
13
13
|
filterOnFocus: boolean;
|
|
14
14
|
filterFocusFirst: boolean;
|
|
15
|
+
selectFirstOptionOnBlur: boolean;
|
|
15
16
|
allowUnmatched: boolean;
|
|
16
17
|
matchKey: string | null | undefined;
|
|
17
18
|
popupTarget: string;
|
|
@@ -88,6 +89,12 @@ export declare class AutocompleteComponent extends ListDropdownAware implements
|
|
|
88
89
|
* @attribute filter-focus-first
|
|
89
90
|
*/
|
|
90
91
|
filterFocusFirst: boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Determines whether the first available option should be selected automatically when blurring mid-filter.
|
|
94
|
+
* @default false
|
|
95
|
+
* @attribute select-first-option-on-blur
|
|
96
|
+
*/
|
|
97
|
+
selectFirstOptionOnBlur: boolean;
|
|
91
98
|
/**
|
|
92
99
|
* Controls whether unmatched text entered by the user will stay visible an option in the dropdown is not found.
|
|
93
100
|
* @default false
|
|
@@ -37,6 +37,7 @@ let AutocompleteComponent = class AutocompleteComponent extends ListDropdownAwar
|
|
|
37
37
|
AUTOCOMPLETE_CONSTANTS.attributes.DEBOUNCE,
|
|
38
38
|
AUTOCOMPLETE_CONSTANTS.attributes.FILTER_ON_FOCUS,
|
|
39
39
|
AUTOCOMPLETE_CONSTANTS.attributes.FILTER_FOCUS_FIRST,
|
|
40
|
+
AUTOCOMPLETE_CONSTANTS.attributes.SELECT_FIRST_OPTION_ON_BLUR,
|
|
40
41
|
AUTOCOMPLETE_CONSTANTS.attributes.ALLOW_UNMATCHED,
|
|
41
42
|
AUTOCOMPLETE_CONSTANTS.attributes.POPUP_TARGET,
|
|
42
43
|
AUTOCOMPLETE_CONSTANTS.attributes.OPEN,
|
|
@@ -79,6 +80,9 @@ let AutocompleteComponent = class AutocompleteComponent extends ListDropdownAwar
|
|
|
79
80
|
case AUTOCOMPLETE_CONSTANTS.attributes.FILTER_FOCUS_FIRST:
|
|
80
81
|
this.filterFocusFirst = coerceBoolean(newValue);
|
|
81
82
|
break;
|
|
83
|
+
case AUTOCOMPLETE_CONSTANTS.attributes.SELECT_FIRST_OPTION_ON_BLUR:
|
|
84
|
+
this.selectFirstOptionOnBlur = coerceBoolean(newValue);
|
|
85
|
+
break;
|
|
82
86
|
case AUTOCOMPLETE_CONSTANTS.attributes.ALLOW_UNMATCHED:
|
|
83
87
|
this.allowUnmatched = coerceBoolean(newValue);
|
|
84
88
|
break;
|
|
@@ -133,6 +137,9 @@ __decorate([
|
|
|
133
137
|
__decorate([
|
|
134
138
|
coreProperty()
|
|
135
139
|
], AutocompleteComponent.prototype, "filterFocusFirst", void 0);
|
|
140
|
+
__decorate([
|
|
141
|
+
coreProperty()
|
|
142
|
+
], AutocompleteComponent.prototype, "selectFirstOptionOnBlur", void 0);
|
|
136
143
|
__decorate([
|
|
137
144
|
coreProperty()
|
|
138
145
|
], AutocompleteComponent.prototype, "allowUnmatched", void 0);
|
|
@@ -376,11 +376,13 @@ export declare class CalendarCore implements ICalendarCore {
|
|
|
376
376
|
/**
|
|
377
377
|
* Sets the month text and attribute in the adapter.
|
|
378
378
|
* @param userSelected Whether the month was explicitly selected by the user (optional)
|
|
379
|
+
* @param suppressEvent Whether to suppress emitting the month change event (optional)
|
|
379
380
|
* */
|
|
380
381
|
private _setMonth;
|
|
381
382
|
/**
|
|
382
383
|
* Sets the year text and attribute in the adapter.
|
|
383
384
|
* @param userSelected Whether the year was explicity selected by the user (optional)
|
|
385
|
+
* @param suppressEvent Whether to suppress emitting the month change event (optional)
|
|
384
386
|
* */
|
|
385
387
|
private _setYear;
|
|
386
388
|
/**
|
|
@@ -1183,7 +1183,7 @@ export class CalendarCore {
|
|
|
1183
1183
|
else {
|
|
1184
1184
|
this._month = 0;
|
|
1185
1185
|
this._year += 1;
|
|
1186
|
-
this._setYear();
|
|
1186
|
+
this._setYear(undefined, true);
|
|
1187
1187
|
}
|
|
1188
1188
|
this._setMonth();
|
|
1189
1189
|
this._resetDateGrid();
|
|
@@ -1198,7 +1198,7 @@ export class CalendarCore {
|
|
|
1198
1198
|
else {
|
|
1199
1199
|
this._month = 11;
|
|
1200
1200
|
this._year -= 1;
|
|
1201
|
-
this._setYear();
|
|
1201
|
+
this._setYear(undefined, true);
|
|
1202
1202
|
}
|
|
1203
1203
|
this._setMonth();
|
|
1204
1204
|
this._resetDateGrid();
|
|
@@ -1315,33 +1315,39 @@ export class CalendarCore {
|
|
|
1315
1315
|
/**
|
|
1316
1316
|
* Sets the month text and attribute in the adapter.
|
|
1317
1317
|
* @param userSelected Whether the month was explicitly selected by the user (optional)
|
|
1318
|
+
* @param suppressEvent Whether to suppress emitting the month change event (optional)
|
|
1318
1319
|
* */
|
|
1319
|
-
_setMonth(userSelected) {
|
|
1320
|
+
_setMonth(userSelected, suppressEvent) {
|
|
1320
1321
|
this._adapter.setMonth(this._month, this._locale);
|
|
1321
1322
|
this._adapter.setHostAttribute(CALENDAR_CONSTANTS.attributes.MONTH, this._month.toString());
|
|
1322
1323
|
if (this._isInitialized) {
|
|
1323
1324
|
this._setNavigationButtonStates();
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1325
|
+
if (!suppressEvent) {
|
|
1326
|
+
this._adapter.emitHostEvent(CALENDAR_CONSTANTS.events.MONTH_CHANGE, {
|
|
1327
|
+
month: this._month,
|
|
1328
|
+
userSelected: userSelected ?? false,
|
|
1329
|
+
year: this._year
|
|
1330
|
+
});
|
|
1331
|
+
}
|
|
1329
1332
|
}
|
|
1330
1333
|
}
|
|
1331
1334
|
/**
|
|
1332
1335
|
* Sets the year text and attribute in the adapter.
|
|
1333
1336
|
* @param userSelected Whether the year was explicity selected by the user (optional)
|
|
1337
|
+
* @param suppressEvent Whether to suppress emitting the month change event (optional)
|
|
1334
1338
|
* */
|
|
1335
|
-
_setYear(userSelected) {
|
|
1339
|
+
_setYear(userSelected, suppressEvent) {
|
|
1336
1340
|
this._adapter.setYear(this._year, this._locale);
|
|
1337
1341
|
this._adapter.setHostAttribute(CALENDAR_CONSTANTS.attributes.YEAR, this._year.toString());
|
|
1338
1342
|
if (this._isInitialized) {
|
|
1339
1343
|
this._setNavigationButtonStates();
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1344
|
+
if (!suppressEvent) {
|
|
1345
|
+
this._adapter.emitHostEvent(CALENDAR_CONSTANTS.events.MONTH_CHANGE, {
|
|
1346
|
+
month: this._month,
|
|
1347
|
+
userSelected: userSelected ?? false,
|
|
1348
|
+
year: this._year
|
|
1349
|
+
});
|
|
1350
|
+
}
|
|
1345
1351
|
}
|
|
1346
1352
|
}
|
|
1347
1353
|
/**
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Tyler Technologies, Inc.
|
|
4
|
+
* License: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
export function tryCleanupPopovers() {
|
|
7
|
+
const popovers = Array.from(document.querySelectorAll('forge-popover'));
|
|
8
|
+
popovers.forEach(p => p.remove());
|
|
9
|
+
}
|
|
10
|
+
export function isVisibleInScrollContainer(scrollContainer, element) {
|
|
11
|
+
const elemTop = element.offsetTop - scrollContainer.offsetTop;
|
|
12
|
+
const elemBottom = elemTop + element.offsetHeight;
|
|
13
|
+
return elemTop >= scrollContainer.scrollTop && elemBottom <= scrollContainer.scrollTop + scrollContainer.offsetHeight;
|
|
14
|
+
}
|
|
@@ -9,6 +9,7 @@ export * from './dismissible-stack';
|
|
|
9
9
|
export * from './event-utils';
|
|
10
10
|
export * from './feature-detection';
|
|
11
11
|
export * from './form-utils';
|
|
12
|
+
export * from './key-action';
|
|
12
13
|
export * from './reflect-utils';
|
|
13
14
|
export * from './svg-utils';
|
|
14
15
|
export * from './time-utils';
|
package/esm/core/utils/index.js
CHANGED
|
@@ -9,6 +9,7 @@ export * from './dismissible-stack';
|
|
|
9
9
|
export * from './event-utils';
|
|
10
10
|
export * from './feature-detection';
|
|
11
11
|
export * from './form-utils';
|
|
12
|
+
export * from './key-action';
|
|
12
13
|
export * from './reflect-utils';
|
|
13
14
|
export * from './svg-utils';
|
|
14
15
|
export * from './time-utils';
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Tyler Technologies, Inc.
|
|
4
|
+
* License: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { ReactiveController, ReactiveControllerHost } from 'lit';
|
|
7
|
+
export type ModifierKey = 'alt' | 'ctrl' | 'meta' | 'shift';
|
|
8
|
+
export type SearchFn = (searchString: string, evt: KeyboardEvent) => void;
|
|
9
|
+
/**
|
|
10
|
+
* Defines a key combination.
|
|
11
|
+
*/
|
|
12
|
+
export interface KeyCombination {
|
|
13
|
+
/**
|
|
14
|
+
* The key.
|
|
15
|
+
*/
|
|
16
|
+
key: string;
|
|
17
|
+
/**
|
|
18
|
+
* One or more modifier keys that must be pressed in conjunction with the key.
|
|
19
|
+
*/
|
|
20
|
+
modifier?: ModifierKey | ModifierKey[];
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Configuration interface for a key action.
|
|
24
|
+
*/
|
|
25
|
+
export interface IKeyAction {
|
|
26
|
+
/**
|
|
27
|
+
* One or more keys or key combinations that trigger the handler.
|
|
28
|
+
*/
|
|
29
|
+
key: string | string[] | KeyCombination | KeyCombination[];
|
|
30
|
+
/**
|
|
31
|
+
* The function to be called when the specified key(s) are pressed.
|
|
32
|
+
* @param event - The keyboard event that triggered the handler.
|
|
33
|
+
* @returns A boolean or void. Returning `true` allows fallthrough to the next key handler.
|
|
34
|
+
*/
|
|
35
|
+
handler(event: KeyboardEvent): boolean | void;
|
|
36
|
+
/**
|
|
37
|
+
* Indicates whether the handler should be called repeatedly while the key is held down.
|
|
38
|
+
*/
|
|
39
|
+
allowRepeat?: boolean;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Configuration interface for the key action controller.
|
|
43
|
+
*/
|
|
44
|
+
export interface IKeyActionControllerConfig {
|
|
45
|
+
/**
|
|
46
|
+
* An optional array of key interaction configurations.
|
|
47
|
+
*/
|
|
48
|
+
actions?: IKeyAction[];
|
|
49
|
+
/**
|
|
50
|
+
* An optional search handling function. If not provided, searching is disabled.
|
|
51
|
+
*/
|
|
52
|
+
searchHandler?: SearchFn;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* A Lit controller for attaching key down actions to a component host.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* class ExampleComponent extends LitElement {
|
|
59
|
+
* private _keyActionController = new KeyActionController(this, {
|
|
60
|
+
* actions: [
|
|
61
|
+
* {
|
|
62
|
+
* key: ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'],
|
|
63
|
+
* handler: this._handleArrowKey.bind(this),
|
|
64
|
+
* allowRepeat: true
|
|
65
|
+
* },
|
|
66
|
+
* { key: 'Enter', handler: this._handleEnterKey.bind(this) },
|
|
67
|
+
* { key: { key: 'a', modifier: 'shift' }, handler: this._handleAKey.bind(this) }
|
|
68
|
+
* ],
|
|
69
|
+
* searchHandler: this.handleSearch.bind(this)
|
|
70
|
+
* });
|
|
71
|
+
*
|
|
72
|
+
* private _handleArrowKey(evt: KeyboardEvent): void {
|
|
73
|
+
* console.log(evt.key);
|
|
74
|
+
* }
|
|
75
|
+
*
|
|
76
|
+
* private _handleEnterKey(evt: KeyboardEvent): void {
|
|
77
|
+
* console.log(evt.key);
|
|
78
|
+
* }
|
|
79
|
+
*
|
|
80
|
+
* private _handleAKey(evt: KeyboardEvent): void {
|
|
81
|
+
* console.log(evt.key);
|
|
82
|
+
* }
|
|
83
|
+
*
|
|
84
|
+
* private _handleSearch(searchString: string): void {
|
|
85
|
+
* console.log(searchString);
|
|
86
|
+
* }
|
|
87
|
+
*/
|
|
88
|
+
export declare class KeyActionController implements ReactiveController {
|
|
89
|
+
private static _searchTimeout;
|
|
90
|
+
host: ReactiveControllerHost;
|
|
91
|
+
actions: IKeyAction[];
|
|
92
|
+
searchHandler?: SearchFn;
|
|
93
|
+
private _searchString;
|
|
94
|
+
private _searchTimeout?;
|
|
95
|
+
private _keyDownListener;
|
|
96
|
+
constructor(host: ReactiveControllerHost, config?: IKeyActionControllerConfig);
|
|
97
|
+
hostConnected(): void;
|
|
98
|
+
hostDisconnected(): void;
|
|
99
|
+
private _handleKeyDown;
|
|
100
|
+
private _handleSearch;
|
|
101
|
+
private _eventMatchesKey;
|
|
102
|
+
}
|