@lion/ui 0.17.0 → 0.18.0-menu-system.1
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 +1 -0
- package/components/button/src/LionButton.js +4 -0
- package/components/button/test-suites/LionButton.suite.js +1 -0
- package/components/calendar/src/LionCalendar.js +2 -0
- package/components/collapsible/src/DisclosureMixin.js +313 -0
- package/components/collapsible/types/DisclosureMixinTypes.ts +48 -0
- package/components/combobox/test/lion-combobox.test.js +1 -0
- package/components/form-core/src/form-group/FormGroupMixin.js +7 -0
- package/components/form-core/src/registration/FormRegistrarMixin.js +11 -0
- package/components/form-core/test/FormControlMixin.test.js +1 -0
- package/components/form-core/test/validate/Validator.test.js +2 -0
- package/components/form-core/test-suites/ValidateMixin.suite.js +2 -0
- package/components/form-core/test-suites/ValidateMixinFeedbackPart.suite.js +1 -0
- package/components/input-datepicker/src/localizeNamespaceLoader.js +1 -0
- package/components/input-datepicker/test/lion-input-datepicker.test.js +5 -6
- package/components/localize/test/date/formatDate.test.js +1 -0
- package/components/menu/CHANGELOG.md +37 -0
- package/components/menu/README.md +335 -0
- package/components/menu/index.js +2 -0
- package/components/menu/lion-menu-overlay.js +3 -0
- package/components/menu/lion-menu.js +3 -0
- package/components/menu/lion-spinbutton.js +3 -0
- package/components/menu/lion-toolbar.js +3 -0
- package/components/menu/lion-tree.js +3 -0
- package/components/menu/package.json +46 -0
- package/components/menu/requirements.temp.md +12 -0
- package/components/menu/src/InteractiveListMixin.js +805 -0
- package/components/menu/src/LionMenu.js +250 -0
- package/components/menu/src/LionMenuHybrid.js +46 -0
- package/components/menu/src/LionMenuOverlay.js +155 -0
- package/components/menu/src/LionSpinbutton.js +213 -0
- package/components/menu/src/LionToolbar.js +94 -0
- package/components/menu/src/LionTree.js +52 -0
- package/components/menu/src/MoreButtonMenuMixin.js +297 -0
- package/components/menu/src/MultiLevelListMixin.js +274 -0
- package/components/menu/src/utils/isInView.js +26 -0
- package/components/menu/src/utils/listItemInteractions.js +104 -0
- package/components/menu/src/utils/uuid.js +3 -0
- package/components/menu/test/lion-menu.test.js +3 -0
- package/components/menu/test-suites/InteractiveListMixin.suite.js +142 -0
- package/components/menu/types/InteractiveListMixinTypes.d.ts +82 -0
- package/components/navigation-bar/README.md +1 -0
- package/components/navigation-bar/src/LionNavigationBar.js +439 -0
- package/components/navigation-bar/src/types.js +41 -0
- package/components/overlays/NEXT.md +49 -0
- package/components/overlays/src/OverlayController.js +244 -111
- package/components/overlays/src/OverlayMixin.js +58 -11
- package/components/overlays/src/OverlaysManager.js +2 -2
- package/components/overlays/src/utils/adopt-styles.js +3 -2
- package/components/overlays/src/utils/get-focusable-elements.js +4 -0
- package/components/overlays/src/utils/is-equal-config.js +10 -6
- package/components/overlays/test/OverlayController.test.js +5 -3
- 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/OverlayConfig.ts +16 -5
- package/components/select-rich/test/lion-select-rich.test.js +3 -0
- package/custom-elements.json +32144 -19531
- package/dist-types/components/button/src/LionButton.d.ts +1 -0
- 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/collapsible/src/DisclosureMixin.d.ts +3 -0
- package/dist-types/components/collapsible/src/DisclosureMixin.d.ts.map +1 -0
- package/dist-types/components/collapsible/types/DisclosureMixinTypes.d.ts +24 -0
- package/dist-types/components/collapsible/types/DisclosureMixinTypes.d.ts.map +1 -0
- package/dist-types/components/dialog/src/LionDialog.d.ts +3 -1
- 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/menu/index.d.ts +3 -0
- package/dist-types/components/menu/index.d.ts.map +1 -0
- package/dist-types/components/menu/lion-menu-overlay.d.ts +2 -0
- package/dist-types/components/menu/lion-menu-overlay.d.ts.map +1 -0
- package/dist-types/components/menu/lion-menu.d.ts +2 -0
- package/dist-types/components/menu/lion-menu.d.ts.map +1 -0
- package/dist-types/components/menu/lion-spinbutton.d.ts +2 -0
- package/dist-types/components/menu/lion-spinbutton.d.ts.map +1 -0
- package/dist-types/components/menu/lion-toolbar.d.ts +2 -0
- package/dist-types/components/menu/lion-toolbar.d.ts.map +1 -0
- package/dist-types/components/menu/lion-tree.d.ts +2 -0
- package/dist-types/components/menu/lion-tree.d.ts.map +1 -0
- package/dist-types/components/menu/src/InteractiveListMixin.d.ts +611 -0
- package/dist-types/components/menu/src/InteractiveListMixin.d.ts.map +1 -0
- package/dist-types/components/menu/src/LionMenu.d.ts +563 -0
- package/dist-types/components/menu/src/LionMenu.d.ts.map +1 -0
- package/dist-types/components/menu/src/LionMenuHybrid.d.ts +19 -0
- package/dist-types/components/menu/src/LionMenuHybrid.d.ts.map +1 -0
- package/dist-types/components/menu/src/LionMenuOverlay.d.ts +1007 -0
- package/dist-types/components/menu/src/LionMenuOverlay.d.ts.map +1 -0
- package/dist-types/components/menu/src/LionSpinbutton.d.ts +58 -0
- package/dist-types/components/menu/src/LionSpinbutton.d.ts.map +1 -0
- package/dist-types/components/menu/src/LionToolbar.d.ts +8 -0
- package/dist-types/components/menu/src/LionToolbar.d.ts.map +1 -0
- package/dist-types/components/menu/src/LionTree.d.ts +445 -0
- package/dist-types/components/menu/src/LionTree.d.ts.map +1 -0
- package/dist-types/components/menu/src/MoreButtonMenuMixin.d.ts +31 -0
- package/dist-types/components/menu/src/MoreButtonMenuMixin.d.ts.map +1 -0
- package/dist-types/components/menu/src/MultiLevelListMixin.d.ts +493 -0
- package/dist-types/components/menu/src/MultiLevelListMixin.d.ts.map +1 -0
- package/dist-types/components/menu/src/utils/isInView.d.ts +9 -0
- package/dist-types/components/menu/src/utils/isInView.d.ts.map +1 -0
- package/dist-types/components/menu/src/utils/listItemInteractions.d.ts +42 -0
- package/dist-types/components/menu/src/utils/listItemInteractions.d.ts.map +1 -0
- package/dist-types/components/menu/src/utils/uuid.d.ts +2 -0
- package/dist-types/components/menu/src/utils/uuid.d.ts.map +1 -0
- package/dist-types/components/menu/test/lion-menu.test.d.ts +2 -0
- package/dist-types/components/menu/test/lion-menu.test.d.ts.map +1 -0
- package/dist-types/components/menu/test-suites/InteractiveListMixin.suite.d.ts +13 -0
- package/dist-types/components/menu/test-suites/InteractiveListMixin.suite.d.ts.map +1 -0
- package/dist-types/components/navigation-bar/src/LionNavigationBar.d.ts +238 -0
- package/dist-types/components/navigation-bar/src/LionNavigationBar.d.ts.map +1 -0
- package/dist-types/components/navigation-bar/src/types.d.ts +85 -0
- package/dist-types/components/navigation-bar/src/types.d.ts.map +1 -0
- package/dist-types/components/overlays/src/OverlayController.d.ts +9 -13
- 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/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/OverlayConfig.d.ts +10 -2
- package/dist-types/components/overlays/types/OverlayConfig.d.ts.map +1 -1
- package/dist-types/components/select-rich/src/LionSelectRich.d.ts +8 -2
- package/dist-types/components/select-rich/src/LionSelectRich.d.ts.map +1 -1
- package/dist-types/exports/define/lion-item.d.ts +2 -0
- package/dist-types/exports/define/lion-item.d.ts.map +1 -0
- package/dist-types/exports/define/lion-menu-overlay.d.ts +2 -0
- package/dist-types/exports/define/lion-menu-overlay.d.ts.map +1 -0
- package/dist-types/exports/define/lion-menu.d.ts +2 -0
- package/dist-types/exports/define/lion-menu.d.ts.map +1 -0
- package/dist-types/exports/define/lion-navigation-bar.d.ts +2 -0
- package/dist-types/exports/define/lion-navigation-bar.d.ts.map +1 -0
- package/dist-types/exports/define/lion-toolbar.d.ts +2 -0
- package/dist-types/exports/define/lion-toolbar.d.ts.map +1 -0
- package/dist-types/exports/define/lion-tree.d.ts +2 -0
- package/dist-types/exports/define/lion-tree.d.ts.map +1 -0
- package/dist-types/exports/menu.d.ts +7 -0
- package/dist-types/exports/menu.d.ts.map +1 -0
- package/dist-types/exports/navigation-bar.d.ts +2 -0
- package/dist-types/exports/navigation-bar.d.ts.map +1 -0
- package/dist-types/exports/overlays.d.ts +3 -0
- 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 +21 -8
- package/docs/components/combobox/overview.md +1 -1
- package/docs/components/combobox/use-cases.md +1 -1
- package/docs/components/dialog/api-table.md +31 -6
- 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 +21 -4
- 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/menu/api-table.md +450 -0
- package/docs/components/menu/applyMenuDemoStyles.js +173 -0
- package/docs/components/menu/extensions.md +235 -0
- package/docs/components/menu/index.md +13 -0
- package/docs/components/menu/overview.md +422 -0
- 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 +21 -5
- package/docs/components/select-rich/use-cases.md +2 -2
- package/docs/components/tabs/examples.md +1 -1
- package/docs/components/tooltip/api-table.md +36 -11
- 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 -34
- 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 +1 -0
- package/exports/define/lion-item.js +3 -0
- package/exports/define/lion-menu-overlay.js +3 -0
- package/exports/define/lion-menu.js +3 -0
- package/exports/define/lion-navigation-bar.js +3 -0
- package/exports/define/lion-toolbar.js +3 -0
- package/exports/define/lion-tree.js +3 -0
- package/exports/menu.js +7 -0
- package/exports/navigation-bar.js +1 -0
- package/exports/overlays.js +6 -0
- package/menu.js +7 -0
- package/navigation-bar.js +1 -0
- package/overlays.js +6 -0
- package/package.json +1 -1
|
@@ -33,10 +33,7 @@ export const OverlayMixinImplementation = superclass => {
|
|
|
33
33
|
class OverlayMixin extends superclass {
|
|
34
34
|
static get properties() {
|
|
35
35
|
return {
|
|
36
|
-
opened: {
|
|
37
|
-
type: Boolean,
|
|
38
|
-
reflect: true,
|
|
39
|
-
},
|
|
36
|
+
opened: { type: Boolean, reflect: true },
|
|
40
37
|
};
|
|
41
38
|
}
|
|
42
39
|
|
|
@@ -62,6 +59,17 @@ export const OverlayMixinImplementation = superclass => {
|
|
|
62
59
|
this.open = this.open.bind(this);
|
|
63
60
|
/** @type {EventListener} */
|
|
64
61
|
this.close = this.close.bind(this);
|
|
62
|
+
|
|
63
|
+
// // By default, we go for disclosure behavior
|
|
64
|
+
// // TODO: in the future, bring disclosure behavior to a controller (and therefore directive).
|
|
65
|
+
// // Take inspiration from VisibilityToggleCtrl of portal elements
|
|
66
|
+
// /**
|
|
67
|
+
// * Terminology aligned with https://open-ui.org/components/openable.explainer/
|
|
68
|
+
// * @type {'disclosure'|'overlay'}
|
|
69
|
+
// */
|
|
70
|
+
// this.openableMode = 'disclosure';
|
|
71
|
+
|
|
72
|
+
// allow hybrid disclosure/overlay components
|
|
65
73
|
}
|
|
66
74
|
|
|
67
75
|
get config() {
|
|
@@ -70,6 +78,7 @@ export const OverlayMixinImplementation = superclass => {
|
|
|
70
78
|
|
|
71
79
|
/** @param {OverlayConfig} value */
|
|
72
80
|
set config(value) {
|
|
81
|
+
// TODO: built-in in overlayCtrl now... delete here
|
|
73
82
|
const shouldUpdate = !isEqualConfig(this.config, value);
|
|
74
83
|
|
|
75
84
|
if (this._overlayCtrl && shouldUpdate) {
|
|
@@ -161,6 +170,8 @@ export const OverlayMixinImplementation = superclass => {
|
|
|
161
170
|
*/
|
|
162
171
|
// eslint-disable-next-line class-methods-use-this
|
|
163
172
|
_setupOpenCloseListeners() {
|
|
173
|
+
// Keeps the close-overlay event private for the controller.
|
|
174
|
+
// (we already have )
|
|
164
175
|
/**
|
|
165
176
|
* @param {{ stopPropagation: () => void; }} ev
|
|
166
177
|
*/
|
|
@@ -218,11 +229,11 @@ export const OverlayMixinImplementation = superclass => {
|
|
|
218
229
|
// @ts-expect-error
|
|
219
230
|
static enabledWarnings = super.enabledWarnings?.filter(w => w !== 'change-in-update') || [];
|
|
220
231
|
|
|
221
|
-
get _overlayInvokerNode() {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
}
|
|
232
|
+
// get _overlayInvokerNode() {
|
|
233
|
+
// return /** @type {HTMLElement | undefined} */ (
|
|
234
|
+
// Array.from(this.children).find(child => child.slot === 'invoker')
|
|
235
|
+
// );
|
|
236
|
+
// }
|
|
226
237
|
|
|
227
238
|
/**
|
|
228
239
|
* @overridable
|
|
@@ -256,13 +267,46 @@ export const OverlayMixinImplementation = superclass => {
|
|
|
256
267
|
);
|
|
257
268
|
}
|
|
258
269
|
|
|
270
|
+
/**
|
|
271
|
+
* @param {Element} focusableElOrWrapper
|
|
272
|
+
* @returns {Element|null}
|
|
273
|
+
*/
|
|
274
|
+
static _getFocusableInvokerEl(focusableElOrWrapper) {
|
|
275
|
+
// return focusableElOrWrapper;
|
|
276
|
+
return (
|
|
277
|
+
focusableElOrWrapper &&
|
|
278
|
+
(focusableElOrWrapper.hasAttribute('tabindex') || focusableElOrWrapper.tagName === 'BUTTON'
|
|
279
|
+
? focusableElOrWrapper
|
|
280
|
+
: focusableElOrWrapper.querySelector('[role=button], button'))
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
get _overlayInvokerNode() {
|
|
285
|
+
const ctor = /** @type {typeof OverlayMixin} */ (this.constructor);
|
|
286
|
+
if (!this.__invokerNode) {
|
|
287
|
+
const slottedNode = Array.from(this.children).find(child => child.slot === 'invoker');
|
|
288
|
+
if (slottedNode) {
|
|
289
|
+
this.__invokerNode = ctor._getFocusableInvokerEl(slottedNode);
|
|
290
|
+
} else {
|
|
291
|
+
// Look for preceeding sibling with [data-invoker] attribute, and try to find a focusable element in it (either itself or a child)
|
|
292
|
+
this.__invokerNode =
|
|
293
|
+
this.previousElementSibling?.hasAttribute('data-invoker') &&
|
|
294
|
+
ctor._getFocusableInvokerEl(this.previousElementSibling);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return this.__invokerNode;
|
|
298
|
+
}
|
|
299
|
+
|
|
259
300
|
/** @protected */
|
|
260
301
|
_setupOverlayCtrl() {
|
|
261
302
|
if (this.#hasSetup) return;
|
|
303
|
+
|
|
304
|
+
const invokerNode = this._overlayInvokerNode;
|
|
305
|
+
|
|
262
306
|
const config = {
|
|
263
307
|
contentNode: this._overlayContentNode,
|
|
264
308
|
contentWrapperNode: this._overlayContentWrapperNode,
|
|
265
|
-
invokerNode:
|
|
309
|
+
invokerNode: invokerNode && invokerNode instanceof HTMLElement ? invokerNode : undefined,
|
|
266
310
|
referenceNode: this._overlayReferenceNode,
|
|
267
311
|
backdropNode: this._overlayBackdropNode,
|
|
268
312
|
};
|
|
@@ -282,6 +326,8 @@ export const OverlayMixinImplementation = superclass => {
|
|
|
282
326
|
|
|
283
327
|
/** @protected */
|
|
284
328
|
_teardownOverlayCtrl() {
|
|
329
|
+
// Make sure that dynamic behavior (e.g. responsive) is possible by allowing multiple setups and teardowns of the overlay controller.
|
|
330
|
+
this.#hasSetup = false;
|
|
285
331
|
if (!this._overlayCtrl) return;
|
|
286
332
|
|
|
287
333
|
this._teardownOpenCloseListeners();
|
|
@@ -434,6 +480,7 @@ export const OverlayMixinImplementation = superclass => {
|
|
|
434
480
|
for (const postProcessor of overlayMixinPostProcessors) {
|
|
435
481
|
postProcessor(OverlayMixin);
|
|
436
482
|
}
|
|
437
|
-
|
|
483
|
+
// @ts-ignore https://github.com/microsoft/TypeScript/issues/36821#issuecomment-588375051
|
|
484
|
+
return OverlayMixin;
|
|
438
485
|
};
|
|
439
486
|
export const OverlayMixin = dedupeMixin(OverlayMixinImplementation);
|
|
@@ -209,9 +209,9 @@ export class OverlaysManager {
|
|
|
209
209
|
const newMarginBottom = this.__bodySizeVars.marginBottom + scrollbarHeight;
|
|
210
210
|
// @ts-expect-error [external]: CSS not yet typed
|
|
211
211
|
if (window.CSS?.number && document.body.attributeStyleMap?.set) {
|
|
212
|
-
// @ts-ignore
|
|
212
|
+
// @ts-ignore - CSS Typed OM not fully typed
|
|
213
213
|
document.body.attributeStyleMap.set('margin-right', CSS.px(newMarginRight));
|
|
214
|
-
// @ts-ignore
|
|
214
|
+
// @ts-ignore - CSS Typed OM not fully typed
|
|
215
215
|
document.body.attributeStyleMap.set('margin-bottom', CSS.px(newMarginBottom));
|
|
216
216
|
} else {
|
|
217
217
|
document.body.style.marginRight = `${newMarginRight}px`;
|
|
@@ -56,7 +56,8 @@ function adoptStyleWhenAdoptedStylesheetsNotSupported(
|
|
|
56
56
|
const styleEl = document.createElement('style');
|
|
57
57
|
// keep notation, so it's not renamed in minification/build
|
|
58
58
|
// eslint-disable-next-line dot-notation
|
|
59
|
-
|
|
59
|
+
// @ts-ignore - litNonce is a custom property
|
|
60
|
+
const nonce = window.litNonce;
|
|
60
61
|
if (nonce !== undefined) {
|
|
61
62
|
styleEl.setAttribute('nonce', nonce);
|
|
62
63
|
}
|
|
@@ -124,7 +125,7 @@ export function adoptStyle(renderRoot, style, { teardown = false } = {}) {
|
|
|
124
125
|
if (!teardown) {
|
|
125
126
|
// @ts-ignore
|
|
126
127
|
// eslint-disable-next-line no-param-reassign
|
|
127
|
-
renderRoot.adoptedStyleSheets = [...renderRoot.adoptedStyleSheets, sheet];
|
|
128
|
+
renderRoot.adoptedStyleSheets = [...(renderRoot.adoptedStyleSheets || []), sheet];
|
|
128
129
|
} else if (renderRoot.adoptedStyleSheets.includes(sheet)) {
|
|
129
130
|
renderRoot.adoptedStyleSheets.splice(renderRoot.adoptedStyleSheets.indexOf(sheet), 1);
|
|
130
131
|
}
|
|
@@ -8,6 +8,7 @@ import { isVisible } from './is-visible.js';
|
|
|
8
8
|
import { sortByTabIndex } from './sort-by-tabindex.js';
|
|
9
9
|
|
|
10
10
|
// IE11 supports matches as 'msMatchesSelector'
|
|
11
|
+
/** @type {'matches' | 'msMatchesSelector'} */
|
|
11
12
|
const matchesFunc = 'matches' in Element.prototype ? 'matches' : 'msMatchesSelector';
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -16,11 +17,14 @@ const matchesFunc = 'matches' in Element.prototype ? 'matches' : 'msMatchesSelec
|
|
|
16
17
|
*/
|
|
17
18
|
function isFocusable(element) {
|
|
18
19
|
// Elements that cannot be focused if they have [disabled] attribute.
|
|
20
|
+
// @ts-ignore - msMatchesSelector is legacy
|
|
19
21
|
if (element[matchesFunc]('input, select, textarea, button, object')) {
|
|
22
|
+
// @ts-ignore
|
|
20
23
|
return element[matchesFunc](':not([disabled])');
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
// Elements that can be focused even if they have [disabled] attribute.
|
|
27
|
+
// @ts-ignore
|
|
24
28
|
return element[matchesFunc]('a[href], area[href], iframe, [tabindex], [contentEditable]');
|
|
25
29
|
}
|
|
26
30
|
|
|
@@ -12,13 +12,17 @@
|
|
|
12
12
|
*/
|
|
13
13
|
export function isEqualConfig(a, b) {
|
|
14
14
|
if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) {
|
|
15
|
+
if (typeof a === 'function' && typeof b === 'function') {
|
|
16
|
+
return /** @type {Function} */ (a).toString() === /** @type {Function} */ (b).toString();
|
|
17
|
+
}
|
|
15
18
|
return a === b;
|
|
16
19
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
if (aProps.length !== bProps.length) {
|
|
20
|
-
return false;
|
|
20
|
+
if (a instanceof Node && b instanceof Node) {
|
|
21
|
+
return a === b;
|
|
21
22
|
}
|
|
22
|
-
|
|
23
|
-
return
|
|
23
|
+
|
|
24
|
+
return Array.from(new Set([...Object.keys(a), ...Object.keys(b)])).every(prop =>
|
|
25
|
+
// @ts-ignore - dynamic property access
|
|
26
|
+
isEqualConfig(a[prop], b[prop], prop),
|
|
27
|
+
);
|
|
24
28
|
}
|
|
@@ -283,8 +283,9 @@ describe('OverlayController', () => {
|
|
|
283
283
|
contentNode,
|
|
284
284
|
});
|
|
285
285
|
};
|
|
286
|
+
|
|
286
287
|
expect(createOverlayController).to.throw(
|
|
287
|
-
'[OverlayController] Could not find a render target,
|
|
288
|
+
'[OverlayController] Could not find a render target, makes sure contentNode has a parent element (or contentWrapperNode is connected)',
|
|
288
289
|
);
|
|
289
290
|
});
|
|
290
291
|
|
|
@@ -403,7 +404,7 @@ describe('OverlayController', () => {
|
|
|
403
404
|
{ ignoreAttributes: ['closedby'] },
|
|
404
405
|
);
|
|
405
406
|
|
|
406
|
-
expect(el).lightDom.to.equal(`<div slot="content">projected</div>`);
|
|
407
|
+
expect(el).lightDom.to.equal(`<div data-content="" slot="content">projected</div>`);
|
|
407
408
|
});
|
|
408
409
|
});
|
|
409
410
|
|
|
@@ -425,7 +426,7 @@ describe('OverlayController', () => {
|
|
|
425
426
|
`
|
|
426
427
|
<dialog data-overlay-outer-wrapper="" open="" role="none" style="${wrappingDialogNodeStyle}">
|
|
427
428
|
<div data-id="content-wrapper">
|
|
428
|
-
<div id="content">non projected</div>
|
|
429
|
+
<div data-content="" id="content">non projected</div>
|
|
429
430
|
</div>
|
|
430
431
|
</dialog>
|
|
431
432
|
`,
|
|
@@ -2292,6 +2293,7 @@ describe('OverlayController', () => {
|
|
|
2292
2293
|
});
|
|
2293
2294
|
|
|
2294
2295
|
it('should run with scroll prevention', async () => {
|
|
2296
|
+
await overlayControllerPreventsScroll.hide();
|
|
2295
2297
|
await overlayControllerPreventsScroll.show();
|
|
2296
2298
|
|
|
2297
2299
|
expect(
|
|
@@ -48,7 +48,7 @@ describe('isEqualConfig()', () => {
|
|
|
48
48
|
expect(isEqualConfig({ ...config, isBlocking: true }, config)).eql(false);
|
|
49
49
|
});
|
|
50
50
|
|
|
51
|
-
it('regards missing props different from ones with undefined value', () => {
|
|
51
|
+
it.skip('regards missing props different from ones with undefined value', () => {
|
|
52
52
|
const config = TestConfig();
|
|
53
53
|
expect(isEqualConfig(config, { ...config, referenceNode: undefined })).eql(false);
|
|
54
54
|
});
|
|
@@ -537,13 +537,13 @@ export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) {
|
|
|
537
537
|
it('works with cache directive when reconnected', async () => {
|
|
538
538
|
class CachingContext extends LitElement {
|
|
539
539
|
static properties = {
|
|
540
|
-
|
|
540
|
+
showOverlay: { type: Boolean },
|
|
541
541
|
};
|
|
542
542
|
|
|
543
543
|
constructor() {
|
|
544
544
|
super();
|
|
545
545
|
|
|
546
|
-
this.
|
|
546
|
+
this.showOverlay = true;
|
|
547
547
|
}
|
|
548
548
|
|
|
549
549
|
get overlayEl() {
|
|
@@ -552,12 +552,12 @@ export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) {
|
|
|
552
552
|
|
|
553
553
|
render() {
|
|
554
554
|
return html`${cache(
|
|
555
|
-
this.
|
|
556
|
-
? html
|
|
557
|
-
: html`<${tag} id="myOverlay">
|
|
555
|
+
this.showOverlay
|
|
556
|
+
? html`<${tag} id="myOverlay">
|
|
558
557
|
<div slot="content">content b</div>
|
|
559
558
|
<button slot="invoker">invoker button b</button>
|
|
560
|
-
</${tag}
|
|
559
|
+
</${tag}>`
|
|
560
|
+
: html`something else`,
|
|
561
561
|
)}`;
|
|
562
562
|
}
|
|
563
563
|
}
|
|
@@ -578,7 +578,7 @@ export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) {
|
|
|
578
578
|
// @ts-expect-error [allow-protected] in tests
|
|
579
579
|
const setupSpy = sinon.spy(el.overlayEl, '_setupOverlayCtrl');
|
|
580
580
|
|
|
581
|
-
el.
|
|
581
|
+
el.showOverlay = false;
|
|
582
582
|
// render the new content
|
|
583
583
|
await el.updateComplete;
|
|
584
584
|
// wait for the teardown to complete
|
|
@@ -588,7 +588,7 @@ export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) {
|
|
|
588
588
|
expect(teardownSpy.callCount).to.equal(1);
|
|
589
589
|
expect(setupSpy.callCount).to.equal(0);
|
|
590
590
|
|
|
591
|
-
el.
|
|
591
|
+
el.showOverlay = true;
|
|
592
592
|
await el.updateComplete;
|
|
593
593
|
expect(setupSpy.callCount).to.equal(1);
|
|
594
594
|
|
|
@@ -21,7 +21,6 @@ export type OverlayPhase =
|
|
|
21
21
|
| 'add'
|
|
22
22
|
| 'remove';
|
|
23
23
|
|
|
24
|
-
|
|
25
24
|
export interface ViewportConfig {
|
|
26
25
|
placement: ViewportPlacement;
|
|
27
26
|
}
|
|
@@ -97,14 +96,26 @@ export interface OverlayConfig {
|
|
|
97
96
|
/** By default, the tooltip content is a 'description' for the invoker (uses aria-describedby) Setting this property to 'label' makes the content function as a label (via aria-labelledby) */
|
|
98
97
|
invokerRelation?: 'label' | 'description';
|
|
99
98
|
|
|
100
|
-
/** render a div instead of dialog */
|
|
101
|
-
_noDialogEl?: Boolean;
|
|
102
|
-
|
|
103
99
|
/**
|
|
104
100
|
* Determines the conditions hiding/showing should be based on. It gets the OverlayController as input and returns an object with
|
|
105
101
|
* functions with Overlay phases as keys
|
|
106
102
|
*/
|
|
107
103
|
visibilityTriggerFunction?: Function;
|
|
108
|
-
}
|
|
109
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Whether the overlay content should receive focus when shown.
|
|
107
|
+
*/
|
|
108
|
+
focusContentOnOpen?: boolean;
|
|
109
|
+
|
|
110
|
+
/*
|
|
111
|
+
* By default, we function either as overlay or disclosure. In some cases, this should be dynamically set (think of responsive changes).
|
|
112
|
+
* or it depends on the context (a top level menu is not openable (unless it's a context menu), its children menus are).
|
|
113
|
+
*/
|
|
114
|
+
isOpenable?: boolean;
|
|
110
115
|
|
|
116
|
+
/**
|
|
117
|
+
* By default, an error is thrown when contentNode is not connected to the DOM.
|
|
118
|
+
* This allows to prepare nodes and later connect them to dom.
|
|
119
|
+
*/
|
|
120
|
+
requireConnectedNodes?: boolean;
|
|
121
|
+
}
|
|
@@ -832,6 +832,7 @@ describe('lion-select-rich', () => {
|
|
|
832
832
|
await waitUntil(isSelectRichRendered);
|
|
833
833
|
getInvoker()?.click();
|
|
834
834
|
await waitUntil(isDialogVisible);
|
|
835
|
+
// @ts-ignore - NodeList array access
|
|
835
836
|
const optionBlue = /** @type { HTMLElement | undefined } */ (
|
|
836
837
|
wrapperElementShadowRoot?.querySelectorAll('lion-option')
|
|
837
838
|
)?.[1];
|
|
@@ -955,6 +956,7 @@ describe('lion-select-rich', () => {
|
|
|
955
956
|
await waitUntil(isSelectRichRendered);
|
|
956
957
|
getInvoker()?.click();
|
|
957
958
|
await waitUntil(isDialogVisible);
|
|
959
|
+
// @ts-ignore - NodeList array access
|
|
958
960
|
const optionBlue = /** @type { HTMLElement | undefined } */ (
|
|
959
961
|
wrapperElementShadowRoot?.querySelectorAll('lion-option')
|
|
960
962
|
)?.[1];
|
|
@@ -1082,6 +1084,7 @@ describe('lion-select-rich', () => {
|
|
|
1082
1084
|
await waitUntil(isSelectRichRendered);
|
|
1083
1085
|
getInvoker()?.click();
|
|
1084
1086
|
await waitUntil(isDialogVisible);
|
|
1087
|
+
// @ts-ignore - NodeList array access
|
|
1085
1088
|
const optionBlue = /** @type { HTMLElement | undefined } */ (
|
|
1086
1089
|
wrapperElementShadowRoot?.querySelectorAll('lion-option')
|
|
1087
1090
|
)?.[1];
|