@lion/ui 0.18.0-menu-system.5 → 0.18.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/collapsible.js +0 -1
- package/components/button/src/LionButton.js +0 -4
- package/components/button/test-suites/LionButton.suite.js +0 -1
- package/components/calendar/src/LionCalendar.js +1 -3
- package/components/combobox/test/lion-combobox.test.js +0 -1
- package/components/form-core/src/form-group/FormGroupMixin.js +0 -7
- package/components/form-core/src/registration/FormRegistrarMixin.js +0 -11
- package/components/form-core/test/FormControlMixin.test.js +0 -1
- package/components/form-core/test/validate/Validator.test.js +0 -2
- package/components/form-core/test-suites/ValidateMixin.suite.js +0 -2
- package/components/form-core/test-suites/ValidateMixinFeedbackPart.suite.js +0 -1
- package/components/input-datepicker/src/localizeNamespaceLoader.js +0 -1
- package/components/input-datepicker/test/lion-input-datepicker.test.js +6 -5
- package/components/listbox/test-suites/ListboxMixin.suite.js +1 -7
- package/components/localize/src/date/utils/normalizeIntlDate.js +2 -3
- package/components/localize/test/date/formatDate.test.js +2 -3
- package/components/overlays/src/OverlayController.js +110 -278
- package/components/overlays/src/OverlayMixin.js +11 -58
- package/components/overlays/src/OverlaysManager.js +2 -2
- package/components/overlays/src/configurations/withDropdownConfig.js +2 -22
- package/components/overlays/src/configurations/withPopoverConfig.js +32 -0
- package/components/overlays/src/utils/adopt-styles.js +5 -4
- package/components/overlays/src/utils/get-focusable-elements.js +0 -4
- package/components/overlays/src/utils/is-equal-config.js +6 -10
- package/components/overlays/test/OverlayController.test.js +21 -128
- package/components/overlays/test/utils-tests/is-equal-config.test.js +1 -1
- package/components/overlays/test-suites/OverlayMixin.suite.js +8 -8
- package/components/overlays/types/ArrowMixinTypes.ts +1 -3
- package/components/overlays/types/OverlayConfig.ts +5 -20
- package/components/select-rich/test/lion-select-rich.test.js +0 -3
- package/components/switch/src/LionSwitchButton.js +8 -3
- package/components/switch/test/lion-switch-button.test.js +38 -0
- package/custom-elements.json +17566 -30468
- package/dist-types/components/button/src/LionButton.d.ts +0 -1
- package/dist-types/components/button/src/LionButton.d.ts.map +1 -1
- package/dist-types/components/button/test-suites/LionButton.suite.d.ts.map +1 -1
- package/dist-types/components/calendar/src/LionCalendar.d.ts.map +1 -1
- package/dist-types/components/dialog/src/LionDialog.d.ts +1 -5
- package/dist-types/components/dialog/src/LionDialog.d.ts.map +1 -1
- package/dist-types/components/form-core/src/form-group/FormGroupMixin.d.ts.map +1 -1
- package/dist-types/components/form-core/src/registration/FormRegistrarMixin.d.ts.map +1 -1
- package/dist-types/components/form-core/test-suites/ValidateMixin.suite.d.ts.map +1 -1
- package/dist-types/components/form-core/test-suites/ValidateMixinFeedbackPart.suite.d.ts.map +1 -1
- package/dist-types/components/input-datepicker/src/localizeNamespaceLoader.d.ts.map +1 -1
- package/dist-types/components/listbox/test-suites/ListboxMixin.suite.d.ts.map +1 -1
- package/dist-types/components/localize/src/date/utils/normalizeIntlDate.d.ts.map +1 -1
- package/dist-types/components/overlays/src/OverlayController.d.ts +12 -24
- package/dist-types/components/overlays/src/OverlayController.d.ts.map +1 -1
- package/dist-types/components/overlays/src/OverlayMixin.d.ts.map +1 -1
- package/dist-types/components/overlays/src/configurations/withDropdownConfig.d.ts +0 -1
- package/dist-types/components/overlays/src/configurations/withDropdownConfig.d.ts.map +1 -1
- package/dist-types/components/overlays/src/configurations/withPopoverConfig.d.ts +6 -0
- package/dist-types/components/overlays/src/configurations/withPopoverConfig.d.ts.map +1 -0
- package/dist-types/components/overlays/src/utils/get-focusable-elements.d.ts.map +1 -1
- package/dist-types/components/overlays/src/utils/is-equal-config.d.ts.map +1 -1
- package/dist-types/components/overlays/types/ArrowMixinTypes.d.ts.map +1 -1
- package/dist-types/components/overlays/types/OverlayConfig.d.ts +2 -12
- package/dist-types/components/overlays/types/OverlayConfig.d.ts.map +1 -1
- package/dist-types/components/select-rich/src/LionSelectRich.d.ts +2 -10
- package/dist-types/components/select-rich/src/LionSelectRich.d.ts.map +1 -1
- package/dist-types/components/switch/src/LionSwitchButton.d.ts +6 -0
- package/dist-types/components/switch/src/LionSwitchButton.d.ts.map +1 -1
- package/dist-types/exports/overlays.d.ts +1 -3
- package/dist-types/exports/overlays.d.ts.map +1 -1
- package/dist-types/tsconfig.tsbuildinfo +1 -1
- package/docs/components/checkbox-group/overview.md +2 -2
- package/docs/components/collapsible/overview.md +1 -1
- package/docs/components/combobox/api-table.md +8 -21
- package/docs/components/combobox/overview.md +1 -1
- package/docs/components/combobox/use-cases.md +1 -1
- package/docs/components/dialog/api-table.md +6 -31
- package/docs/components/dialog/overview.md +1 -1
- package/docs/components/fieldset/overview.md +5 -5
- package/docs/components/form/overview.md +3 -3
- package/docs/components/form/use-cases.md +2 -2
- package/docs/components/icon/use-cases.md +1 -1
- package/docs/components/input/overview.md +1 -1
- package/docs/components/input-amount/overview.md +3 -3
- package/docs/components/input-date/overview.md +3 -3
- package/docs/components/input-datepicker/api-table.md +4 -21
- package/docs/components/input-datepicker/overview.md +5 -5
- package/docs/components/input-email/overview.md +2 -2
- package/docs/components/input-file/overview.md +1 -1
- package/docs/components/input-iban/overview.md +2 -2
- package/docs/components/input-range/overview.md +2 -2
- package/docs/components/input-stepper/overview.md +1 -1
- package/docs/components/input-tel/overview.md +1 -1
- package/docs/components/input-tel/use-cases.md +6 -6
- package/docs/components/input-tel-dropdown/overview.md +1 -1
- package/docs/components/listbox/use-cases.md +1 -1
- package/docs/components/radio-group/overview.md +3 -3
- package/docs/components/select/use-cases.md +1 -1
- package/docs/components/select-rich/api-table.md +5 -21
- package/docs/components/select-rich/use-cases.md +2 -2
- package/docs/components/switch/api-table.md +2 -0
- package/docs/components/tabs/examples.md +1 -1
- package/docs/components/tooltip/api-table.md +11 -36
- package/docs/fundamentals/index.md +4 -4
- package/docs/fundamentals/node-tools/publish-docs/overview.md +3 -3
- package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +2 -2
- package/docs/fundamentals/rationales/accessibility.md +1 -1
- package/docs/fundamentals/systems/core/SlotMixin.md +1 -1
- package/docs/fundamentals/systems/core/overview.md +1 -1
- package/docs/fundamentals/systems/form/formatting-and-parsing.md +4 -4
- package/docs/fundamentals/systems/form/model-value.md +1 -1
- package/docs/fundamentals/systems/form/overview.md +28 -28
- package/docs/fundamentals/systems/form/validate.md +2 -2
- package/docs/fundamentals/systems/localize/overview.md +4 -4
- package/docs/fundamentals/systems/overlays/api-table.md +34 -36
- package/docs/fundamentals/systems/overlays/configuration.md +2 -2
- package/docs/fundamentals/systems/overlays/overview.md +5 -5
- package/docs/fundamentals/systems/overlays/use-cases.md +2 -2
- package/docs/fundamentals/tools/helpers/overview.md +1 -1
- package/docs/fundamentals/tools/singleton-manager/overview.md +4 -4
- package/docs/guides/how-to/create-a-custom-field.md +5 -5
- package/docs/guides/how-to/create-a-form.md +4 -4
- package/docs/guides/how-to/extend-a-native-input.md +2 -2
- package/docs/guides/how-to/index.md +1 -1
- package/docs/guides/index.md +8 -8
- package/docs/guides/principles/index.md +5 -5
- package/docs/guides/principles/styling.md +1 -1
- package/exports/collapsible.js +0 -1
- package/exports/overlays.js +1 -6
- package/overlays.js +1 -6
- package/package.json +1 -1
- package/components/collapsible/src/DisclosureMixin.js +0 -313
- package/components/collapsible/test-suites/DisclosureMixin.suite.js +0 -30
- package/components/collapsible/types/DisclosureMixinTypes.ts +0 -48
- package/components/menu/CHANGELOG.md +0 -37
- package/components/menu/README.md +0 -335
- package/components/menu/index.js +0 -2
- package/components/menu/lion-menu-overlay.js +0 -3
- package/components/menu/lion-menu.js +0 -3
- package/components/menu/lion-spinbutton.js +0 -3
- package/components/menu/lion-toolbar.js +0 -3
- package/components/menu/lion-tree.js +0 -3
- package/components/menu/package.json +0 -46
- package/components/menu/requirements.temp.md +0 -12
- package/components/menu/src/InteractiveListMixin.js +0 -838
- package/components/menu/src/LionMenu.js +0 -250
- package/components/menu/src/LionMenuHybrid.js +0 -46
- package/components/menu/src/LionMenuOverlay.js +0 -155
- package/components/menu/src/LionSpinbutton.js +0 -213
- package/components/menu/src/LionToolbar.js +0 -94
- package/components/menu/src/LionTree.js +0 -52
- package/components/menu/src/MoreButtonMenuMixin.js +0 -287
- package/components/menu/src/MultiLevelListMixin.js +0 -274
- package/components/menu/src/utils/isInView.js +0 -26
- package/components/menu/src/utils/listItemInteractions.js +0 -123
- package/components/menu/src/utils/uuid.js +0 -3
- package/components/menu/test/lion-menu.test.js +0 -4
- package/components/menu/test-suites/InteractiveListMixin.suite.js +0 -304
- package/components/menu/types/InteractiveListMixinTypes.d.ts +0 -82
- package/components/navigation-bar/README.md +0 -1
- package/components/navigation-bar/src/LionNavigationBar.js +0 -439
- package/components/navigation-bar/src/types.js +0 -41
- package/components/overlays/NEXT.md +0 -49
- package/dist-types/components/collapsible/src/DisclosureMixin.d.ts +0 -3
- package/dist-types/components/collapsible/src/DisclosureMixin.d.ts.map +0 -1
- package/dist-types/components/collapsible/test-suites/DisclosureMixin.suite.d.ts +0 -2
- package/dist-types/components/collapsible/test-suites/DisclosureMixin.suite.d.ts.map +0 -1
- package/dist-types/components/collapsible/types/DisclosureMixinTypes.d.ts +0 -24
- package/dist-types/components/collapsible/types/DisclosureMixinTypes.d.ts.map +0 -1
- package/dist-types/components/menu/index.d.ts +0 -3
- package/dist-types/components/menu/index.d.ts.map +0 -1
- package/dist-types/components/menu/lion-menu-overlay.d.ts +0 -2
- package/dist-types/components/menu/lion-menu-overlay.d.ts.map +0 -1
- package/dist-types/components/menu/lion-menu.d.ts +0 -2
- package/dist-types/components/menu/lion-menu.d.ts.map +0 -1
- package/dist-types/components/menu/lion-spinbutton.d.ts +0 -2
- package/dist-types/components/menu/lion-spinbutton.d.ts.map +0 -1
- package/dist-types/components/menu/lion-toolbar.d.ts +0 -2
- package/dist-types/components/menu/lion-toolbar.d.ts.map +0 -1
- package/dist-types/components/menu/lion-tree.d.ts +0 -2
- package/dist-types/components/menu/lion-tree.d.ts.map +0 -1
- package/dist-types/components/menu/src/InteractiveListMixin.d.ts +0 -617
- package/dist-types/components/menu/src/InteractiveListMixin.d.ts.map +0 -1
- package/dist-types/components/menu/src/LionMenu.d.ts +0 -565
- package/dist-types/components/menu/src/LionMenu.d.ts.map +0 -1
- package/dist-types/components/menu/src/LionMenuHybrid.d.ts +0 -19
- package/dist-types/components/menu/src/LionMenuHybrid.d.ts.map +0 -1
- package/dist-types/components/menu/src/LionMenuOverlay.d.ts +0 -1013
- package/dist-types/components/menu/src/LionMenuOverlay.d.ts.map +0 -1
- package/dist-types/components/menu/src/LionSpinbutton.d.ts +0 -58
- package/dist-types/components/menu/src/LionSpinbutton.d.ts.map +0 -1
- package/dist-types/components/menu/src/LionToolbar.d.ts +0 -8
- package/dist-types/components/menu/src/LionToolbar.d.ts.map +0 -1
- package/dist-types/components/menu/src/LionTree.d.ts +0 -447
- package/dist-types/components/menu/src/LionTree.d.ts.map +0 -1
- package/dist-types/components/menu/src/MoreButtonMenuMixin.d.ts +0 -40
- package/dist-types/components/menu/src/MoreButtonMenuMixin.d.ts.map +0 -1
- package/dist-types/components/menu/src/MultiLevelListMixin.d.ts +0 -495
- package/dist-types/components/menu/src/MultiLevelListMixin.d.ts.map +0 -1
- package/dist-types/components/menu/src/utils/isInView.d.ts +0 -9
- package/dist-types/components/menu/src/utils/isInView.d.ts.map +0 -1
- package/dist-types/components/menu/src/utils/listItemInteractions.d.ts +0 -48
- package/dist-types/components/menu/src/utils/listItemInteractions.d.ts.map +0 -1
- package/dist-types/components/menu/src/utils/uuid.d.ts +0 -2
- package/dist-types/components/menu/src/utils/uuid.d.ts.map +0 -1
- package/dist-types/components/menu/test/lion-menu.test.d.ts +0 -2
- package/dist-types/components/menu/test/lion-menu.test.d.ts.map +0 -1
- package/dist-types/components/menu/test-suites/InteractiveListMixin.suite.d.ts +0 -14
- package/dist-types/components/menu/test-suites/InteractiveListMixin.suite.d.ts.map +0 -1
- package/dist-types/components/navigation-bar/src/LionNavigationBar.d.ts +0 -238
- package/dist-types/components/navigation-bar/src/LionNavigationBar.d.ts.map +0 -1
- package/dist-types/components/navigation-bar/src/types.d.ts +0 -85
- package/dist-types/components/navigation-bar/src/types.d.ts.map +0 -1
- package/dist-types/exports/define/lion-item.d.ts +0 -2
- package/dist-types/exports/define/lion-item.d.ts.map +0 -1
- package/dist-types/exports/define/lion-menu-overlay.d.ts +0 -2
- package/dist-types/exports/define/lion-menu-overlay.d.ts.map +0 -1
- package/dist-types/exports/define/lion-menu.d.ts +0 -2
- package/dist-types/exports/define/lion-menu.d.ts.map +0 -1
- package/dist-types/exports/define/lion-navigation-bar.d.ts +0 -2
- package/dist-types/exports/define/lion-navigation-bar.d.ts.map +0 -1
- package/dist-types/exports/define/lion-toolbar.d.ts +0 -2
- package/dist-types/exports/define/lion-toolbar.d.ts.map +0 -1
- package/dist-types/exports/define/lion-tree.d.ts +0 -2
- package/dist-types/exports/define/lion-tree.d.ts.map +0 -1
- package/dist-types/exports/menu-test-suites.d.ts +0 -2
- package/dist-types/exports/menu-test-suites.d.ts.map +0 -1
- package/dist-types/exports/menu.d.ts +0 -7
- package/dist-types/exports/menu.d.ts.map +0 -1
- package/dist-types/exports/navigation-bar.d.ts +0 -2
- package/dist-types/exports/navigation-bar.d.ts.map +0 -1
- package/docs/components/menu/api-table.md +0 -455
- package/docs/components/menu/applyMenuDemoStyles.js +0 -173
- package/docs/components/menu/extensions.md +0 -262
- package/docs/components/menu/index.md +0 -13
- package/docs/components/menu/overview.md +0 -422
- package/exports/define/lion-item.js +0 -3
- package/exports/define/lion-menu-overlay.js +0 -3
- package/exports/define/lion-menu.js +0 -3
- package/exports/define/lion-navigation-bar.js +0 -3
- package/exports/define/lion-toolbar.js +0 -3
- package/exports/define/lion-tree.js +0 -3
- package/exports/menu-test-suites.js +0 -2
- package/exports/menu.js +0 -7
- package/exports/navigation-bar.js +0 -1
- package/menu-test-suites.js +0 -2
- package/menu.js +0 -7
- package/navigation-bar.js +0 -1
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
/* eslint-disable import/no-extraneous-dependencies */
|
|
2
|
-
import { LionMenu } from './LionMenu.js';
|
|
3
|
-
import { setChecked, toggleChecked } from './utils/listItemInteractions.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @typedef {import('../types/InteractiveListMixinTypes.js').InteractiveListItemRole} InteractiveListItemRole
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
export class LionToolbar extends LionMenu {
|
|
10
|
-
constructor() {
|
|
11
|
-
super();
|
|
12
|
-
|
|
13
|
-
this._listRole = 'toolbar';
|
|
14
|
-
this.bar = true;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Allows groups ([role=radiogroup|checkboxgroup]) within one level.
|
|
19
|
-
* In case we deal with [role=checkbox], we treat it as multiple choice group
|
|
20
|
-
* @override InteractiveListMixin
|
|
21
|
-
* @param {number} index
|
|
22
|
-
*/
|
|
23
|
-
setCheckedIndex(index) {
|
|
24
|
-
const item = this.listItems[index];
|
|
25
|
-
if (item) {
|
|
26
|
-
// @ts-ignore - InteractiveListItemRole type
|
|
27
|
-
const role = /** @type {InteractiveListItemRole} */ (item.getAttribute('role'));
|
|
28
|
-
let listItemsWithinGroup = this.listItems;
|
|
29
|
-
let multiple = this.multipleChoice;
|
|
30
|
-
if (role === 'radio' || role === 'checkbox') {
|
|
31
|
-
/**
|
|
32
|
-
* If index = 1 (radio 'Red'), closest group will be div[role=radiogroup]
|
|
33
|
-
* @example
|
|
34
|
-
* <lion-toolbar>
|
|
35
|
-
* <div role="radiogroup" aria-label="Text Color">
|
|
36
|
-
* <button role="radio" aria-checked="false">Blue</button>
|
|
37
|
-
* <button role="radio" aria-checked="true">Red</button>
|
|
38
|
-
* <button role="radio" aria-checked="false">Green</button>
|
|
39
|
-
* </div>
|
|
40
|
-
* <div role="separator"></div>
|
|
41
|
-
* <div role="checkboxgroup" aria-label="Text Color">
|
|
42
|
-
* <button role="checkbox" aria-checked="false">Blue</button>
|
|
43
|
-
* <button role="checkbox" aria-checked="true">Red</button>
|
|
44
|
-
* <button role="checkbox" aria-checked="false">Green</button>
|
|
45
|
-
* </div>
|
|
46
|
-
* </lion-toolbar>
|
|
47
|
-
*/
|
|
48
|
-
let closestGroup;
|
|
49
|
-
if (role === 'radio') {
|
|
50
|
-
closestGroup = item.closest('[role="radiogroup"]');
|
|
51
|
-
} else if (role === 'checkbox') {
|
|
52
|
-
closestGroup = item.closest('[role="checkboxgroup"]');
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const group = closestGroup && this.contains(closestGroup) ? closestGroup : this;
|
|
56
|
-
listItemsWithinGroup = this.listItems.filter(listItem => group.contains(listItem));
|
|
57
|
-
multiple = role === 'checkbox';
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (!multiple) {
|
|
61
|
-
// Uncheck all
|
|
62
|
-
listItemsWithinGroup.forEach(listItem => {
|
|
63
|
-
setChecked(listItem, true);
|
|
64
|
-
});
|
|
65
|
-
setChecked(this.listItems[index]);
|
|
66
|
-
} else {
|
|
67
|
-
toggleChecked(this.listItems[index]);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* @param {*} newItems
|
|
74
|
-
*/
|
|
75
|
-
_initListItems(newItems) {
|
|
76
|
-
super._initListItems(newItems);
|
|
77
|
-
|
|
78
|
-
// @ts-ignore - forEach parameter
|
|
79
|
-
newItems.forEach(item => {
|
|
80
|
-
if (
|
|
81
|
-
item.getAttribute('role') === 'button' ||
|
|
82
|
-
(item.tagName === 'BUTTON' && !item.hasAttribute('role'))
|
|
83
|
-
) {
|
|
84
|
-
const initialAriaPressed = item.getAttribute('aria-pressed');
|
|
85
|
-
item.setAttribute('aria-pressed', initialAriaPressed || 'false');
|
|
86
|
-
|
|
87
|
-
item.addEventListener('click', () => {
|
|
88
|
-
const ariaPressed = item.getAttribute('aria-pressed') === 'true';
|
|
89
|
-
item.setAttribute('aria-pressed', `${!ariaPressed}`);
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/* eslint-disable import/no-extraneous-dependencies */
|
|
2
|
-
import { LitElement } from 'lit';
|
|
3
|
-
import { MultiLevelListMixin } from './MultiLevelListMixin.js';
|
|
4
|
-
|
|
5
|
-
// @ts-ignore - class extension with mixin
|
|
6
|
-
export class LionTree extends MultiLevelListMixin(LitElement) {
|
|
7
|
-
constructor() {
|
|
8
|
-
super();
|
|
9
|
-
|
|
10
|
-
/** @configure InteractiveListMixin */
|
|
11
|
-
this._listRole = 'tree';
|
|
12
|
-
/** @configure InteractiveListMixin */
|
|
13
|
-
this._activateOnTypedChars = true;
|
|
14
|
-
/** @configure DisclosureMixin */
|
|
15
|
-
this.invokerInteraction = 'click';
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* @param {*} changedProperties
|
|
20
|
-
*/
|
|
21
|
-
updated(changedProperties) {
|
|
22
|
-
super.updated(changedProperties);
|
|
23
|
-
|
|
24
|
-
if (changedProperties.has('level')) {
|
|
25
|
-
if (this.level > 0) {
|
|
26
|
-
this._listNode.setAttribute('role', 'group');
|
|
27
|
-
}
|
|
28
|
-
this.__setAriaLevelForListItems();
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* @param {*} newItems
|
|
34
|
-
*/
|
|
35
|
-
_initListItems(newItems) {
|
|
36
|
-
// @ts-ignore - parameter types
|
|
37
|
-
super._initListItems(newItems);
|
|
38
|
-
|
|
39
|
-
this.__setAriaLevelForListItems();
|
|
40
|
-
// @ts-ignore - forEach parameters
|
|
41
|
-
newItems.forEach((item, index) => {
|
|
42
|
-
item.setAttribute('aria-posinset', `${index + 1}`);
|
|
43
|
-
item.setAttribute('aria-setsize', `${this.listItems.length}`);
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
__setAriaLevelForListItems() {
|
|
48
|
-
this.listItems.forEach(item => {
|
|
49
|
-
item.setAttribute?.('aria-level', `${this.level + 1}`);
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
}
|
|
@@ -1,287 +0,0 @@
|
|
|
1
|
-
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
2
|
-
import { css } from 'lit';
|
|
3
|
-
|
|
4
|
-
const styles = css`
|
|
5
|
-
/** More button is hidden by default */
|
|
6
|
-
[data-more-button-wrapper] {
|
|
7
|
-
display: none;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
[data-more-button-menu][data-open]:not(:has([role='listitem'] [aria-expanded='true'])) {
|
|
11
|
-
position: absolute;
|
|
12
|
-
overflow: visible;
|
|
13
|
-
height: auto;
|
|
14
|
-
width: auto;
|
|
15
|
-
top: 100%;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/** N.B. this is a simplified version of sr-only. when we move to overlayctrl, we should build this into overlayctrl */
|
|
19
|
-
[data-more-button-menu] {
|
|
20
|
-
overflow: hidden;
|
|
21
|
-
height: 1px;
|
|
22
|
-
width: 1px;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
[role='list']:has(> [data-more-button-wrapper]) > [role='listitem'] > :is(button, a) {
|
|
26
|
-
white-space: nowrap;
|
|
27
|
-
}
|
|
28
|
-
`;
|
|
29
|
-
|
|
30
|
-
// @ts-ignore - JS mixin typing
|
|
31
|
-
export const MoreButtonMenuMixin = superclass =>
|
|
32
|
-
class MoreButtonMenuMixinClass extends superclass {
|
|
33
|
-
constructor() {
|
|
34
|
-
super();
|
|
35
|
-
this.__resizeTimeout = null;
|
|
36
|
-
this.isMoreButtonShown = null;
|
|
37
|
-
this.handleResize = this.handleResize.bind(this);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
disconnectedCallback() {
|
|
41
|
-
window.removeEventListener('resize', this.handleResize);
|
|
42
|
-
if (this.__resizeTimeout) {
|
|
43
|
-
clearTimeout(this.__resizeTimeout);
|
|
44
|
-
}
|
|
45
|
-
super.disconnectedCallback?.();
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
_initMoreButtonMenu() {
|
|
49
|
-
this._createMoreButtonWrapper();
|
|
50
|
-
window.addEventListener('resize', this.handleResize);
|
|
51
|
-
this.handleResize();
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// eslint-disable-next-line class-methods-use-this
|
|
55
|
-
_getDeepActiveElement() {
|
|
56
|
-
let host = document.activeElement || document.body;
|
|
57
|
-
while (host?.shadowRoot?.activeElement) {
|
|
58
|
-
host = host.shadowRoot.activeElement;
|
|
59
|
-
}
|
|
60
|
-
return host;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
_createMoreButtonWrapper() {
|
|
64
|
-
const moreButtonWrapper = document.createElement('div');
|
|
65
|
-
const style = document.createElement('style');
|
|
66
|
-
style.textContent = styles.cssText;
|
|
67
|
-
moreButtonWrapper.appendChild(style);
|
|
68
|
-
moreButtonWrapper.setAttribute('data-more-button-wrapper', '');
|
|
69
|
-
[...this.getMoreButtonSlotProjection().childNodes].forEach(node =>
|
|
70
|
-
moreButtonWrapper.appendChild(node),
|
|
71
|
-
);
|
|
72
|
-
const moreButton = moreButtonWrapper.querySelector('button');
|
|
73
|
-
moreButton?.setAttribute('data-more-button', '');
|
|
74
|
-
moreButton?.setAttribute('tabindex', '-1');
|
|
75
|
-
moreButton?.setAttribute('aria-expanded', 'false');
|
|
76
|
-
const moreButtonMenu = document.createElement('div');
|
|
77
|
-
moreButtonMenu.setAttribute('data-more-button-menu', '');
|
|
78
|
-
moreButtonWrapper.appendChild(moreButtonMenu);
|
|
79
|
-
this._listNode.appendChild(moreButtonWrapper);
|
|
80
|
-
|
|
81
|
-
const isElementDirectFocusableItemUnderMoreButtonMenu = (/** @type {Element} */ element) =>
|
|
82
|
-
this.listItems.includes(element) && moreButtonMenu.contains(element);
|
|
83
|
-
|
|
84
|
-
moreButtonMenu.addEventListener(
|
|
85
|
-
'focusin',
|
|
86
|
-
/** @type {FocusEvent} */ event => {
|
|
87
|
-
const target = /** @type {HTMLElement} */ (event?.target);
|
|
88
|
-
if (!isElementDirectFocusableItemUnderMoreButtonMenu(target)) return;
|
|
89
|
-
|
|
90
|
-
// A user did `Shift + Tab` from L2 menu to More menu
|
|
91
|
-
if (target?.getAttribute('aria-expanded') === 'true') {
|
|
92
|
-
// close L2 menu
|
|
93
|
-
target?.click();
|
|
94
|
-
}
|
|
95
|
-
moreButton?.setAttribute('aria-expanded', 'true');
|
|
96
|
-
moreButtonMenu.setAttribute('data-open', '');
|
|
97
|
-
},
|
|
98
|
-
);
|
|
99
|
-
|
|
100
|
-
moreButtonMenu.addEventListener('focusout', () => {
|
|
101
|
-
// We need this timeout for Safari/WebKit.
|
|
102
|
-
// Unfortunately, an in progress click gets canceled when overflow:hidden is applied.
|
|
103
|
-
// Although mousedown would work instead, the consuming developer should have the freedom to apply all possible interaction pattterns.
|
|
104
|
-
// Especially, we should be compatible with 'withClickInteraction'
|
|
105
|
-
setTimeout(() => {
|
|
106
|
-
if (isElementDirectFocusableItemUnderMoreButtonMenu(this._getDeepActiveElement())) return;
|
|
107
|
-
moreButton?.setAttribute('aria-expanded', 'false');
|
|
108
|
-
|
|
109
|
-
moreButtonMenu.removeAttribute('data-open');
|
|
110
|
-
}, 100);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
this.hasMoreButtonMenuAnyFocusedFirstLevelItems = false;
|
|
114
|
-
|
|
115
|
-
moreButton?.addEventListener('mousedown', () => {
|
|
116
|
-
this.hasMoreButtonMenuAnyFocusedFirstLevelItems = false;
|
|
117
|
-
const focusableFirstLevelItems = moreButtonMenu.querySelectorAll(
|
|
118
|
-
':scope > [role="listitem"] > :is(a, button)',
|
|
119
|
-
);
|
|
120
|
-
|
|
121
|
-
// @ts-ignore Type 'NodeListOf<Element>' must have a '[Symbol.iterator]()' method that returns an iterator.
|
|
122
|
-
for (const focusableFirstLevelItem of focusableFirstLevelItems) {
|
|
123
|
-
if (this._getDeepActiveElement() === focusableFirstLevelItem) {
|
|
124
|
-
this.hasMoreButtonMenuAnyFocusedFirstLevelItems = true;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
moreButton?.addEventListener('click', () => {
|
|
130
|
-
if (this.hasMoreButtonMenuAnyFocusedFirstLevelItems) return;
|
|
131
|
-
/** @type {HTMLElement | null} */
|
|
132
|
-
const firstInteractiveItem = moreButtonMenu.querySelector(
|
|
133
|
-
':scope > [role="listitem"] > :is(a, button)',
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
firstInteractiveItem?.focus();
|
|
137
|
-
moreButtonMenu.setAttribute('data-open', '');
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
getMoreButtonSlotProjection() {
|
|
142
|
-
return this.querySelector('[slot="more-button"]');
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
getMoreButtonMenu() {
|
|
146
|
-
return this.querySelector('[data-more-button-menu]');
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
getMoreButtonMenuWrapper() {
|
|
150
|
-
return this.querySelector('[data-more-button-wrapper]');
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
displayMoreButton() {
|
|
154
|
-
this.getMoreButtonMenuWrapper().style.display = 'block';
|
|
155
|
-
this.isMoreButtonShown = true;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
hideMoreButton() {
|
|
159
|
-
this.getMoreButtonMenuWrapper().style.display = 'none';
|
|
160
|
-
this.isMoreButtonShown = false;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
doItemsFit() {
|
|
164
|
-
this.style.display = 'none';
|
|
165
|
-
const parentWidth = this.parentElement.clientWidth;
|
|
166
|
-
this.style.display = '';
|
|
167
|
-
return (
|
|
168
|
-
this._listNode.scrollWidth === this._listNode.clientWidth &&
|
|
169
|
-
this._listNode.scrollWidth <= parentWidth
|
|
170
|
-
);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
getListItems() {
|
|
174
|
-
const listNode = this._listNode;
|
|
175
|
-
return Array.from(listNode.querySelectorAll(':scope > [role="listitem"]'));
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* @param {Node} listItem
|
|
180
|
-
*/
|
|
181
|
-
getListItemWithAdjacentNodes = listItem => {
|
|
182
|
-
const markerNodeType = this.nodeType && Node.COMMENT_NODE;
|
|
183
|
-
/** @param {Node | null | undefined} node */
|
|
184
|
-
const isMarkerComment = node => node?.nodeType === markerNodeType && node?.nodeValue === '';
|
|
185
|
-
|
|
186
|
-
const previousNodes = [];
|
|
187
|
-
let { previousSibling } = listItem;
|
|
188
|
-
while (previousSibling) {
|
|
189
|
-
previousNodes.unshift(previousSibling);
|
|
190
|
-
if (isMarkerComment(previousSibling)) {
|
|
191
|
-
break;
|
|
192
|
-
}
|
|
193
|
-
({ previousSibling } = previousSibling);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
const nextNodes = [];
|
|
197
|
-
let { nextSibling } = listItem;
|
|
198
|
-
while (nextSibling) {
|
|
199
|
-
nextNodes.push(nextSibling);
|
|
200
|
-
|
|
201
|
-
if (isMarkerComment(nextSibling)) {
|
|
202
|
-
break;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
({ nextSibling } = nextSibling);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const fragment = document.createDocumentFragment();
|
|
209
|
-
const nodes = [...previousNodes, listItem, ...nextNodes];
|
|
210
|
-
nodes.forEach(node => fragment.appendChild(node));
|
|
211
|
-
return fragment;
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* @param {{ moreButtonMenuElement: HTMLButtonElement, listItem: HTMLElement }} opts
|
|
216
|
-
*/
|
|
217
|
-
moveItemToMoreButtonMenuFromMainMenu({ moreButtonMenuElement, listItem }) {
|
|
218
|
-
const fragment = this.getListItemWithAdjacentNodes(listItem);
|
|
219
|
-
moreButtonMenuElement.prepend(fragment);
|
|
220
|
-
// eslint-disable-next-line no-param-reassign
|
|
221
|
-
listItem.style.display = '';
|
|
222
|
-
this.displayMoreButton();
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
moveAllItemsToMainMenuFromMoreButtonMenu() {
|
|
226
|
-
const moreButtonMenu = this.getMoreButtonMenu();
|
|
227
|
-
const moreButtonMenuWrapper = this.getMoreButtonMenuWrapper();
|
|
228
|
-
if (moreButtonMenu.childNodes.length === 0) {
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
231
|
-
[...moreButtonMenu.childNodes].forEach(node => {
|
|
232
|
-
moreButtonMenuWrapper.before(node);
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
renderAllItemsInMainMenu() {
|
|
237
|
-
this.moveAllItemsToMainMenuFromMoreButtonMenu();
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
hideItemsOneByOneInMainMenuUntilTheyFit() {
|
|
241
|
-
let hiddenItemsCount = 0;
|
|
242
|
-
const mainMenuItems = this.getListItems();
|
|
243
|
-
for (let i = mainMenuItems.length - 1; i >= 0 && !this.doItemsFit(); i -= 1) {
|
|
244
|
-
mainMenuItems[i].style.display = 'none';
|
|
245
|
-
hiddenItemsCount += 1;
|
|
246
|
-
}
|
|
247
|
-
return hiddenItemsCount;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* @param {number} hiddenItemsCount
|
|
252
|
-
*/
|
|
253
|
-
moveHiddenItemsFromMainMenuToMoreButtonMenu(hiddenItemsCount) {
|
|
254
|
-
const moreButtonMenuElement = this.getMoreButtonMenu();
|
|
255
|
-
const listItems = this._listNode.querySelectorAll(':scope > [role="listitem"]');
|
|
256
|
-
for (let i = 0; i < hiddenItemsCount; i += 1) {
|
|
257
|
-
const listItem = listItems[listItems.length - 1 - i];
|
|
258
|
-
this.moveItemToMoreButtonMenuFromMainMenu({ moreButtonMenuElement, listItem });
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
handleResize() {
|
|
263
|
-
if (this.__resizeTimeout) {
|
|
264
|
-
return;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
this.style.visibility = 'hidden';
|
|
268
|
-
|
|
269
|
-
this.__resizeTimeout = setTimeout(() => {
|
|
270
|
-
this.__resizeTimeout = null;
|
|
271
|
-
|
|
272
|
-
this.renderAllItemsInMainMenu();
|
|
273
|
-
this.hideMoreButton();
|
|
274
|
-
|
|
275
|
-
if (this.doItemsFit()) {
|
|
276
|
-
this.style.visibility = '';
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
this.style.visibility = 'hidden';
|
|
281
|
-
this.displayMoreButton();
|
|
282
|
-
const hiddenItemsCount = this.hideItemsOneByOneInMainMenuUntilTheyFit();
|
|
283
|
-
this.moveHiddenItemsFromMainMenuToMoreButtonMenu(hiddenItemsCount);
|
|
284
|
-
this.style.visibility = '';
|
|
285
|
-
}, 50);
|
|
286
|
-
}
|
|
287
|
-
};
|
|
@@ -1,274 +0,0 @@
|
|
|
1
|
-
/* eslint-disable import/no-extraneous-dependencies */
|
|
2
|
-
import { html } from 'lit';
|
|
3
|
-
import { dedupeMixin } from '@open-wc/dedupe-mixin';
|
|
4
|
-
// import { DisclosureMixin } from '@lion/ui/collapsible.js';
|
|
5
|
-
import { InteractiveListMixin } from './InteractiveListMixin.js';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @typedef {import('./InteractiveListMixin.js').LionItem} LionItem
|
|
9
|
-
* @typedef {import('../types/InteractiveListMixinTypes.js').InteractiveListHost} InteractiveList
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* All logic that is needed for interactive lists that are allowed to have multiple nested, collapsible levels
|
|
14
|
-
* Applies to [role=menu] and [role=tree]
|
|
15
|
-
*/
|
|
16
|
-
// @ts-ignore - mixin implementation
|
|
17
|
-
const MultiLevelListMixinImplementation = superclass =>
|
|
18
|
-
// @ts-ignore - mixin class extension
|
|
19
|
-
class extends InteractiveListMixin(superclass) {
|
|
20
|
-
render() {
|
|
21
|
-
return html`
|
|
22
|
-
<slot name="invoker"></slot>
|
|
23
|
-
<slot name="list"></slot>
|
|
24
|
-
<slot id="list-items-outlet"></slot>
|
|
25
|
-
`;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
static get properties() {
|
|
29
|
-
return {
|
|
30
|
-
invokerNode: Object,
|
|
31
|
-
behaveAsAccordion: { type: Boolean, attribute: 'behave-as-accordion' },
|
|
32
|
-
level: { type: Number, reflect: true },
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* @configure DisclosureMixin
|
|
38
|
-
*/
|
|
39
|
-
get _invokerNode() {
|
|
40
|
-
// @ts-ignore - accessing static method and super property
|
|
41
|
-
return this.constructor._getFocusableInvokerEl(this.invokerNode) || super._invokerNode;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* @configure DisclosureMixin
|
|
46
|
-
* This will be compatible with DisclosureMixin and OverlayMixin. It contains the invoked
|
|
47
|
-
* InteractiveList widget (like menu|tree).
|
|
48
|
-
*/
|
|
49
|
-
get _contentNode() {
|
|
50
|
-
return this._listNode;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
constructor() {
|
|
54
|
-
super();
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* When an invokerNode is supplied (usually by a parent level menu), it will take precedence
|
|
58
|
-
* over [slot=invoker] and previousElementSibling with [data-invoker] attribute
|
|
59
|
-
* @type {HTMLElement}
|
|
60
|
-
*/
|
|
61
|
-
// @ts-ignore - can be undefined initially
|
|
62
|
-
this.invokerNode = undefined;
|
|
63
|
-
/**
|
|
64
|
-
* @configure DisclosureMixin
|
|
65
|
-
*/
|
|
66
|
-
this.handleFocus = true;
|
|
67
|
-
/**
|
|
68
|
-
* The parent list if level > 1
|
|
69
|
-
* @type {InteractiveList}
|
|
70
|
-
*/
|
|
71
|
-
// @ts-ignore - can be undefined initially
|
|
72
|
-
this.parentList = undefined;
|
|
73
|
-
/**
|
|
74
|
-
* When true, will have a maximum of one submenu open at a time
|
|
75
|
-
*/
|
|
76
|
-
this.behaveAsAccordion = false;
|
|
77
|
-
/**
|
|
78
|
-
* The level of nested menus. Will be reflected as attribute for styling purposes
|
|
79
|
-
*/
|
|
80
|
-
this.level = 1;
|
|
81
|
-
/**
|
|
82
|
-
* @configure InteractiveListMixin
|
|
83
|
-
*/
|
|
84
|
-
this.noPreselect = true;
|
|
85
|
-
/**
|
|
86
|
-
* @configure InteractiveListMixin
|
|
87
|
-
*/
|
|
88
|
-
this._activeMode = 'roving-tabindex';
|
|
89
|
-
/**
|
|
90
|
-
* @type {Map<HTMLElement|LionItem,InteractiveList>}
|
|
91
|
-
*/
|
|
92
|
-
this._subListMap = new Map();
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// /**
|
|
96
|
-
// * @param {import('lit-element').PropertyValues } changedProperties
|
|
97
|
-
// */
|
|
98
|
-
// updated(changedProperties) {
|
|
99
|
-
// super.updated(changedProperties);
|
|
100
|
-
|
|
101
|
-
// if (changedProperties.has('invokerNode')) {
|
|
102
|
-
// // TODO: update openableCtrl invokerNode once we make this a ctrl as well
|
|
103
|
-
// }
|
|
104
|
-
// }
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Gets the child InteractiveList, based on item
|
|
108
|
-
* @param {LionItem|HTMLElement} item can be sibling of or parent of InteractiveList
|
|
109
|
-
*/
|
|
110
|
-
static _getSubInteractiveList(item) {
|
|
111
|
-
/**
|
|
112
|
-
* Note that, according to W3C spec, the sub level element with [role=menu|menubar|tree]
|
|
113
|
-
* needs to be a sibling of the invoker element with
|
|
114
|
-
* [role=menuitem|menuitemchecbox|menuitemradio|treeitem] (and not the parent)
|
|
115
|
-
*
|
|
116
|
-
* In the example below <lion-menu> is considered as item
|
|
117
|
-
* @example
|
|
118
|
-
* <lion-menuitem>
|
|
119
|
-
* <button slot="invoker"></button>
|
|
120
|
-
* <lion-menu> ... </lion-menu>
|
|
121
|
-
* </lion-menuitem>
|
|
122
|
-
*/
|
|
123
|
-
// @ts-ignore - isInteractiveList property check
|
|
124
|
-
const siblingOfInvoker = item.nextElementSibling?.isInteractiveList;
|
|
125
|
-
if (siblingOfInvoker) {
|
|
126
|
-
return item.nextElementSibling;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* In the example below div[role=listitem] | [data-item] is considered as item
|
|
130
|
-
* @example
|
|
131
|
-
* <div role="listitem" data-item>
|
|
132
|
-
* <button slot="invoker"></button>
|
|
133
|
-
* <lion-menu> ... </lion-menu>
|
|
134
|
-
* </div>
|
|
135
|
-
*/
|
|
136
|
-
const childOfInvoker =
|
|
137
|
-
item.getAttribute?.('role') === 'listitem' || item.hasAttribute?.('data-item');
|
|
138
|
-
if (childOfInvoker) {
|
|
139
|
-
// @ts-ignore - isInteractiveList check
|
|
140
|
-
return Array.from(item.children).find(child => child.isInteractiveList);
|
|
141
|
-
}
|
|
142
|
-
return undefined;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* @param {*} newItems
|
|
147
|
-
*/
|
|
148
|
-
_initListItems(newItems) {
|
|
149
|
-
super._initListItems(newItems);
|
|
150
|
-
|
|
151
|
-
const ctor = this.constructor;
|
|
152
|
-
// @ts-ignore - forEach parameter types
|
|
153
|
-
newItems.forEach(item => {
|
|
154
|
-
// @ts-ignore - static method access
|
|
155
|
-
const subList = ctor._getSubInteractiveList(item);
|
|
156
|
-
if (subList) {
|
|
157
|
-
this._subListMap.set(item, subList);
|
|
158
|
-
subList.level = this.level + 1;
|
|
159
|
-
subList.parentList = this;
|
|
160
|
-
subList.invokerNode = item;
|
|
161
|
-
// @ts-ignore - invokerInteraction property
|
|
162
|
-
subList.invokerInteraction = this.invokerInteraction;
|
|
163
|
-
subList._activeMode = this._activeMode;
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* @enhance DisclosureMixin
|
|
170
|
-
* @param {Event} [ev]
|
|
171
|
-
*/
|
|
172
|
-
toggle(ev) {
|
|
173
|
-
// @ts-ignore - target property
|
|
174
|
-
if (ev && this._listNode.contains(ev.target)) {
|
|
175
|
-
// prevent nested menus (inside invokers) from triggering invoker
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
// @ts-ignore - super.toggle method
|
|
179
|
-
super.toggle();
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* @enhance InteractiveListMixin
|
|
184
|
-
* @param {*} ev
|
|
185
|
-
*/
|
|
186
|
-
_onListKeyDown(ev) {
|
|
187
|
-
const targetFromsubList = Array.from(this._subListMap).find(
|
|
188
|
-
// @ts-ignore - contains method on InteractiveListHost
|
|
189
|
-
([, s]) => s === ev.target || s.contains(ev.target),
|
|
190
|
-
);
|
|
191
|
-
|
|
192
|
-
if (targetFromsubList) {
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
super._onListKeyDown(ev);
|
|
197
|
-
|
|
198
|
-
const subListOfActiveItem = this._subListMap.get(this.activeItem);
|
|
199
|
-
const parentListOfActiveItem = this.parentList;
|
|
200
|
-
const { key } = ev;
|
|
201
|
-
|
|
202
|
-
if (key === 'Escape' && parentListOfActiveItem) {
|
|
203
|
-
// We need to stop here, or else we affect parent menu (handled by OverlayController)
|
|
204
|
-
ev.stopPropagation();
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
switch (key) {
|
|
208
|
-
case 'Enter':
|
|
209
|
-
case ' ':
|
|
210
|
-
// make it work like a button
|
|
211
|
-
this.activeItem?.click();
|
|
212
|
-
break;
|
|
213
|
-
case 'ArrowDown':
|
|
214
|
-
if (
|
|
215
|
-
this.orientation === 'horizontal' &&
|
|
216
|
-
subListOfActiveItem &&
|
|
217
|
-
this._activeMode !== 'tabbable-disclosure'
|
|
218
|
-
) {
|
|
219
|
-
this.activeItem.click();
|
|
220
|
-
}
|
|
221
|
-
break;
|
|
222
|
-
case 'ArrowRight':
|
|
223
|
-
if (this.orientation === 'vertical' && subListOfActiveItem) {
|
|
224
|
-
this.activeItem.click();
|
|
225
|
-
}
|
|
226
|
-
break;
|
|
227
|
-
case 'ArrowUp':
|
|
228
|
-
if (this.orientation === 'horizontal' && parentListOfActiveItem) {
|
|
229
|
-
// @ts-ignore - close method
|
|
230
|
-
this.close();
|
|
231
|
-
// @ts-ignore - _onOverlayShow method
|
|
232
|
-
parentListOfActiveItem._onOverlayShow();
|
|
233
|
-
}
|
|
234
|
-
break;
|
|
235
|
-
case 'ArrowLeft':
|
|
236
|
-
if (this.orientation === 'vertical' && parentListOfActiveItem) {
|
|
237
|
-
// @ts-ignore - close method
|
|
238
|
-
this.close();
|
|
239
|
-
// @ts-ignore - _onOverlayShow method
|
|
240
|
-
parentListOfActiveItem._onOverlayShow();
|
|
241
|
-
}
|
|
242
|
-
break;
|
|
243
|
-
/* no default */
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
// /**
|
|
248
|
-
// * @enhance DisclosureMixin
|
|
249
|
-
// */
|
|
250
|
-
// _setupDisclosure() {
|
|
251
|
-
// if (!this._invokerNode) return;
|
|
252
|
-
|
|
253
|
-
// super._setupDisclosure();
|
|
254
|
-
// }
|
|
255
|
-
|
|
256
|
-
// /**
|
|
257
|
-
// * @enhance DisclosureMixin
|
|
258
|
-
// */
|
|
259
|
-
// _teardownDisclosure() {
|
|
260
|
-
// if (!this._invokerNode) return;
|
|
261
|
-
|
|
262
|
-
// super._teardownDisclosure();
|
|
263
|
-
// }
|
|
264
|
-
|
|
265
|
-
// /**
|
|
266
|
-
// * @enhance DisclosureMixin
|
|
267
|
-
// */
|
|
268
|
-
// async _onOpenedChanged() {
|
|
269
|
-
// if (!this._invokerNode) return;
|
|
270
|
-
|
|
271
|
-
// await super._onOpenedChanged();
|
|
272
|
-
// }
|
|
273
|
-
};
|
|
274
|
-
export const MultiLevelListMixin = dedupeMixin(MultiLevelListMixinImplementation);
|