@lion/ui 0.15.0 → 0.15.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -12
- package/components/combobox/test/lion-combobox.test.js +50 -2
- package/components/core/src/SlotMixin.js +52 -0
- package/components/core/test/SlotMixin.test.js +85 -0
- package/components/dialog/test/lion-dialog.integration.test.js +170 -0
- package/components/input-amount-dropdown/src/localizeNamespaceLoader.js +53 -0
- package/components/input-amount-dropdown/translations/bg.js +5 -0
- package/components/input-amount-dropdown/translations/cs.js +5 -0
- package/components/input-amount-dropdown/translations/de.js +5 -0
- package/components/input-amount-dropdown/translations/es.js +5 -0
- package/components/input-amount-dropdown/translations/fr.js +5 -0
- package/components/input-amount-dropdown/translations/hu.js +5 -0
- package/components/input-amount-dropdown/translations/id.js +5 -0
- package/components/input-amount-dropdown/translations/it.js +5 -0
- package/components/input-amount-dropdown/translations/nl.js +5 -0
- package/components/input-amount-dropdown/translations/pl.js +5 -0
- package/components/input-amount-dropdown/translations/ro.js +5 -0
- package/components/input-amount-dropdown/translations/ru.js +5 -0
- package/components/input-amount-dropdown/translations/sk.js +5 -0
- package/components/input-amount-dropdown/translations/uk.js +5 -0
- package/components/input-amount-dropdown/translations/zh.js +5 -0
- package/components/listbox/src/ListboxMixin.js +3 -35
- package/components/overlays/src/ArrowMixin.js +10 -4
- package/components/overlays/src/OverlayController.js +34 -7
- package/components/overlays/test/OverlayController.test.js +4 -1
- package/components/overlays/test/OverlayMixin.test.js +2 -2
- package/components/overlays/test-suites/OverlayMixin.suite.js +57 -0
- package/custom-elements.json +2969 -207
- package/dist-types/components/core/src/ScopedElementsMixin.d.ts.map +1 -1
- package/dist-types/components/core/src/SlotMixin.d.ts +35 -0
- package/dist-types/components/core/src/SlotMixin.d.ts.map +1 -1
- package/dist-types/components/core/test/SlotMixin.test.d.ts.map +1 -1
- package/dist-types/components/dialog/test/lion-dialog.integration.test.d.ts +3 -0
- package/dist-types/components/dialog/test/lion-dialog.integration.test.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/src/localizeNamespaceLoader.d.ts +1 -1
- package/dist-types/components/input-amount-dropdown/src/localizeNamespaceLoader.d.ts.map +1 -1
- package/dist-types/components/input-amount-dropdown/translations/bg.d.ts +7 -0
- package/dist-types/components/input-amount-dropdown/translations/bg.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/translations/cs.d.ts +7 -0
- package/dist-types/components/input-amount-dropdown/translations/cs.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/translations/de.d.ts +7 -0
- package/dist-types/components/input-amount-dropdown/translations/de.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/translations/es.d.ts +7 -0
- package/dist-types/components/input-amount-dropdown/translations/es.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/translations/fr.d.ts +7 -0
- package/dist-types/components/input-amount-dropdown/translations/fr.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/translations/hu.d.ts +7 -0
- package/dist-types/components/input-amount-dropdown/translations/hu.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/translations/id.d.ts +7 -0
- package/dist-types/components/input-amount-dropdown/translations/id.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/translations/it.d.ts +7 -0
- package/dist-types/components/input-amount-dropdown/translations/it.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/translations/nl.d.ts +7 -0
- package/dist-types/components/input-amount-dropdown/translations/nl.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/translations/pl.d.ts +7 -0
- package/dist-types/components/input-amount-dropdown/translations/pl.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/translations/ro.d.ts +7 -0
- package/dist-types/components/input-amount-dropdown/translations/ro.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/translations/ru.d.ts +7 -0
- package/dist-types/components/input-amount-dropdown/translations/ru.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/translations/sk.d.ts +7 -0
- package/dist-types/components/input-amount-dropdown/translations/sk.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/translations/uk.d.ts +7 -0
- package/dist-types/components/input-amount-dropdown/translations/uk.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/translations/zh.d.ts +7 -0
- package/dist-types/components/input-amount-dropdown/translations/zh.d.ts.map +1 -0
- package/dist-types/components/listbox/src/ListboxMixin.d.ts.map +1 -1
- package/dist-types/components/overlays/src/ArrowMixin.d.ts.map +1 -1
- package/dist-types/components/overlays/src/OverlayController.d.ts +13 -4
- package/dist-types/components/overlays/src/OverlayController.d.ts.map +1 -1
- package/dist-types/components/overlays/test-suites/OverlayMixin.suite.d.ts.map +1 -1
- package/dist-types/tsconfig.tsbuildinfo +1 -1
- package/docs/components/accordion/index.md +1 -1
- package/docs/components/accordion/overview.md +1 -1
- package/docs/components/accordion/reference.md +1 -1
- package/docs/components/accordion/use-cases.md +1 -1
- package/docs/components/button/{extensions/bootstrap-button.mjs → assets/bootstrap-button.js} +10 -5
- package/docs/components/button/examples.md +1 -1
- package/docs/components/button/extensions.md +2 -2
- package/docs/components/button/index.md +2 -2
- package/docs/components/button/overview.md +4 -4
- package/docs/components/button/use-cases.md +6 -6
- package/docs/components/calendar/index.md +1 -1
- package/docs/components/calendar/overview.md +1 -1
- package/docs/components/calendar/use-cases.md +2 -2
- package/docs/components/checkbox-group/index.md +1 -1
- package/docs/components/checkbox-group/overview.md +3 -3
- package/docs/components/checkbox-group/use-cases.md +1 -1
- package/docs/components/collapsible/examples.md +1 -1
- package/docs/components/collapsible/index.md +1 -1
- package/docs/components/collapsible/overview.md +2 -2
- package/docs/components/collapsible/use-cases.md +1 -1
- package/docs/components/combobox/extensions.md +2 -1
- package/docs/components/combobox/index.md +1 -1
- package/docs/components/combobox/overview.md +2 -2
- package/docs/components/combobox/use-cases.md +2 -2
- package/docs/components/dialog/index.md +1 -1
- package/docs/components/dialog/overview.md +2 -2
- package/docs/components/dialog/use-cases.md +3 -3
- package/docs/components/drawer/index.md +1 -1
- package/docs/components/drawer/overview.md +1 -1
- package/docs/components/drawer/use-cases.md +1 -1
- package/docs/components/fieldset/index.md +1 -1
- package/docs/components/fieldset/overview.md +6 -6
- package/docs/components/fieldset/use-cases.md +1 -1
- package/docs/components/form/index.md +1 -1
- package/docs/components/form/overview.md +4 -4
- package/docs/components/form/use-cases.md +3 -3
- package/docs/components/icon/index.md +1 -1
- package/docs/components/icon/overview.md +1 -1
- package/docs/components/icon/use-cases.md +2 -15
- package/docs/components/index.md +1 -1
- package/docs/components/input/index.md +1 -1
- package/docs/components/input/overview.md +2 -2
- package/docs/components/input/use-cases.md +1 -1
- package/docs/components/input-amount/index.md +1 -1
- package/docs/components/input-amount/overview.md +4 -4
- package/docs/components/input-amount/use-cases.md +1 -1
- package/docs/components/input-amount-dropdown/index.md +1 -1
- package/docs/components/input-amount-dropdown/use-cases.md +1 -1
- package/docs/components/input-date/index.md +1 -1
- package/docs/components/input-date/overview.md +4 -4
- package/docs/components/input-date/use-cases.md +1 -1
- package/docs/components/input-datepicker/index.md +1 -1
- package/docs/components/input-datepicker/overview.md +6 -6
- package/docs/components/input-datepicker/use-cases.md +1 -1
- package/docs/components/input-email/index.md +1 -1
- package/docs/components/input-email/overview.md +3 -3
- package/docs/components/input-email/use-cases.md +1 -1
- package/docs/components/input-file/index.md +1 -1
- package/docs/components/input-file/overview.md +2 -2
- package/docs/components/input-file/use-cases.md +1 -1
- package/docs/components/input-iban/index.md +1 -1
- package/docs/components/input-iban/overview.md +3 -3
- package/docs/components/input-iban/use-cases.md +1 -1
- package/docs/components/input-range/index.md +1 -1
- package/docs/components/input-range/overview.md +3 -3
- package/docs/components/input-range/use-cases.md +1 -1
- package/docs/components/input-stepper/index.md +1 -1
- package/docs/components/input-stepper/overview.md +2 -2
- package/docs/components/input-stepper/use-cases.md +1 -1
- package/docs/components/input-tel/index.md +1 -1
- package/docs/components/input-tel/overview.md +2 -2
- package/docs/components/input-tel/use-cases.md +7 -7
- package/docs/components/input-tel-dropdown/extensions.md +1 -1
- package/docs/components/input-tel-dropdown/index.md +1 -1
- package/docs/components/input-tel-dropdown/overview.md +2 -2
- package/docs/components/input-tel-dropdown/use-cases.md +1 -1
- package/docs/components/listbox/index.md +1 -1
- package/docs/components/listbox/overview.md +1 -1
- package/docs/components/listbox/use-cases.md +2 -2
- package/docs/components/pagination/index.md +1 -1
- package/docs/components/pagination/overview.md +1 -1
- package/docs/components/pagination/use-cases.md +1 -1
- package/docs/components/progress-indicator/examples.md +1 -1
- package/docs/components/progress-indicator/index.md +1 -1
- package/docs/components/progress-indicator/overview.md +1 -1
- package/docs/components/radio-group/index.md +1 -1
- package/docs/components/radio-group/overview.md +4 -4
- package/docs/components/radio-group/use-cases.md +1 -1
- package/docs/components/select/index.md +1 -1
- package/docs/components/select/overview.md +1 -1
- package/docs/components/select/use-cases.md +2 -2
- package/docs/components/select-rich/examples.md +1 -1
- package/docs/components/select-rich/index.md +1 -1
- package/docs/components/select-rich/overview.md +1 -1
- package/docs/components/select-rich/use-cases.md +3 -3
- package/docs/components/steps/index.md +1 -1
- package/docs/components/steps/overview.md +1 -1
- package/docs/components/steps/use-cases.md +1 -1
- package/docs/components/switch/index.md +1 -1
- package/docs/components/switch/overview.md +1 -1
- package/docs/components/switch/reference.md +1 -1
- package/docs/components/switch/use-cases.md +1 -1
- package/docs/components/tabs/examples.md +2 -2
- package/docs/components/tabs/index.md +1 -1
- package/docs/components/tabs/overview.md +1 -1
- package/docs/components/tabs/use-cases.md +1 -1
- package/docs/components/textarea/index.md +1 -1
- package/docs/components/textarea/overview.md +1 -1
- package/docs/components/textarea/use-cases.md +1 -1
- package/docs/components/tooltip/examples.md +1 -1
- package/docs/components/tooltip/index.md +1 -1
- package/docs/components/tooltip/overview.md +1 -1
- package/docs/components/tooltip/use-cases.md +1 -1
- package/docs/fundamentals/index.md +4 -4
- package/docs/fundamentals/node-tools/babel-plugin-extend-docs/index.md +1 -1
- package/docs/fundamentals/node-tools/babel-plugin-extend-docs/overview.md +1 -1
- package/docs/fundamentals/node-tools/index.md +1 -1
- package/docs/fundamentals/node-tools/providence-analytics/index.md +1 -1
- package/docs/fundamentals/node-tools/providence-analytics/overview.md +1 -1
- package/docs/fundamentals/node-tools/publish-docs/index.md +1 -1
- package/docs/fundamentals/node-tools/publish-docs/overview.md +4 -4
- package/docs/fundamentals/node-tools/remark-extend/index.md +1 -1
- package/docs/fundamentals/node-tools/remark-extend/overview.md +1 -1
- package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/index.md +1 -1
- package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +3 -3
- package/docs/fundamentals/rationales/TypeScript.md +1 -1
- package/docs/fundamentals/rationales/accessibility.md +2 -2
- package/docs/fundamentals/rationales/index.md +1 -1
- package/docs/fundamentals/rationales/side-effects.md +1 -1
- package/docs/fundamentals/rationales/versioning.md +1 -1
- package/docs/fundamentals/systems/core/SlotMixin.md +2 -2
- package/docs/fundamentals/systems/core/index.md +1 -1
- package/docs/fundamentals/systems/core/overview.md +2 -2
- package/docs/fundamentals/systems/form/formatting-and-parsing.md +5 -5
- package/docs/fundamentals/systems/form/index.md +1 -1
- package/docs/fundamentals/systems/form/interaction-states.md +1 -1
- package/docs/fundamentals/systems/form/model-value.md +2 -2
- package/docs/fundamentals/systems/form/overview.md +29 -29
- package/docs/fundamentals/systems/form/styling.md +1 -1
- package/docs/fundamentals/systems/form/use-cases.md +1 -1
- package/docs/fundamentals/systems/form/validate.md +3 -3
- package/docs/fundamentals/systems/icon/index.md +1 -1
- package/docs/fundamentals/systems/icon/overview.md +1 -1
- package/docs/fundamentals/systems/index.md +1 -1
- package/docs/fundamentals/systems/localize/api-table.md +3 -0
- package/docs/fundamentals/systems/localize/dates.md +1 -1
- package/docs/fundamentals/systems/localize/index.md +1 -1
- package/docs/fundamentals/systems/localize/numbers.md +1 -1
- package/docs/fundamentals/systems/localize/overview.md +5 -5
- package/docs/fundamentals/systems/localize/rationale.md +1 -1
- package/docs/fundamentals/systems/localize/text.md +5 -4
- package/docs/fundamentals/systems/localize/use-cases.md +1 -1
- package/docs/fundamentals/systems/overlays/_configuration-positioning.md +3 -3
- package/docs/fundamentals/systems/overlays/_edge-cases.md +3 -3
- package/docs/fundamentals/systems/overlays/api-table.md +3 -0
- package/docs/fundamentals/systems/overlays/assets/demo-overlay-positioning.mjs +1 -1
- package/docs/fundamentals/systems/overlays/configuration.md +5 -5
- package/docs/fundamentals/systems/overlays/index.md +1 -1
- package/docs/fundamentals/systems/overlays/overview.md +6 -6
- package/docs/fundamentals/systems/overlays/rationale.md +1 -1
- package/docs/fundamentals/systems/overlays/use-cases.md +6 -6
- package/docs/fundamentals/tools/ajax/index.md +1 -1
- package/docs/fundamentals/tools/ajax/overview.md +2 -2
- package/docs/fundamentals/tools/ajax/use-cases.md +3 -3
- package/docs/fundamentals/tools/helpers/action-logger.md +1 -1
- package/docs/fundamentals/tools/helpers/index.md +2 -2
- package/docs/fundamentals/tools/helpers/overview.md +2 -2
- package/docs/fundamentals/tools/index.md +1 -1
- package/docs/fundamentals/tools/singleton-manager/example-complex/index.md +1 -1
- package/docs/fundamentals/tools/singleton-manager/example-fail/demo-app.js +4 -4
- package/docs/fundamentals/tools/singleton-manager/example-fail/index.md +2 -2
- package/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/{page-a/page-a.js → page-c/page-c.js} +2 -2
- package/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/{page-b/page-b.js → page-d/page-d.js} +2 -2
- package/docs/fundamentals/tools/singleton-manager/example-success/demo-app.js +4 -4
- package/docs/fundamentals/tools/singleton-manager/example-success/index.md +2 -2
- package/docs/fundamentals/tools/singleton-manager/example-success/node_modules/{page-a/page-a.js → page-e/page-e.js} +2 -3
- package/docs/fundamentals/tools/singleton-manager/example-success/node_modules/{page-b/page-b.js → page-f/page-f.js} +2 -2
- package/docs/fundamentals/tools/singleton-manager/index.md +2 -2
- package/docs/fundamentals/tools/singleton-manager/overview.md +5 -5
- 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/index.md +8 -8
- package/docs/guides/principles/index.md +5 -5
- package/docs/guides/principles/styling.md +1 -1
- package/package.json +1 -1
- /package/docs/fundamentals/systems/overlays/assets/{applyDemoOverlayStyles.mjs → applyDemoOverlayStyles.js} +0 -0
- /package/docs/fundamentals/systems/overlays/assets/{demo-el-using-overlaymixin.mjs → demo-el-using-overlaymixin.js} +0 -0
- /package/docs/fundamentals/systems/overlays/assets/{demo-overlay-backdrop.mjs → demo-overlay-backdrop.js} +0 -0
- /package/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/{page-b → page-d}/node_modules/overlays/index.js +0 -0
- /package/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/{page-b → page-d}/node_modules/overlays/instance.js +0 -0
- /package/docs/fundamentals/tools/singleton-manager/example-success/node_modules/{page-b → page-f}/node_modules/overlays/index.js +0 -0
- /package/docs/fundamentals/tools/singleton-manager/example-success/node_modules/{page-b → page-f}/node_modules/overlays/instance.js +0 -0
|
@@ -4,6 +4,7 @@ import { dedupeMixin } from '@open-wc/dedupe-mixin';
|
|
|
4
4
|
import { ChoiceGroupMixin, FormControlMixin, FormRegistrarMixin } from '@lion/ui/form-core.js';
|
|
5
5
|
import { ScopedElementsMixin } from '../../core/src/ScopedElementsMixin.js';
|
|
6
6
|
import { LionOptions } from './LionOptions.js';
|
|
7
|
+
import { moveUserProvidedDefaultSlottablesToTarget } from '../../core/src/SlotMixin.js';
|
|
7
8
|
|
|
8
9
|
// TODO: extract ListNavigationWithActiveDescendantMixin that can be reused in [role="menu"]
|
|
9
10
|
// having children with [role="menuitem|menuitemcheckbox|menuitemradio|option"] and
|
|
@@ -21,39 +22,6 @@ import { LionOptions } from './LionOptions.js';
|
|
|
21
22
|
|
|
22
23
|
// TODO: consider adding methods below to @lion/helpers
|
|
23
24
|
|
|
24
|
-
/**
|
|
25
|
-
* Sometimes, we want to provide best DX (direct slottables) and be accessible
|
|
26
|
-
* at the same time.
|
|
27
|
-
* In the first example below, we need to wrap our options in light dom in an element with
|
|
28
|
-
* [role=listbox]. We could achieve this via the second example, but it would affect our
|
|
29
|
-
* public api negatively. not allowing us to be forward compatible with the AOM spec:
|
|
30
|
-
* https://wicg.github.io/aom/explainer.html
|
|
31
|
-
* With this method, it's possible to watch elements in the default slot and move them
|
|
32
|
-
* to the desired target (the element with [role=listbox]) in light dom.
|
|
33
|
-
*
|
|
34
|
-
* @example
|
|
35
|
-
* # desired api
|
|
36
|
-
* <sel-ect>
|
|
37
|
-
* <opt-ion></opt-ion>
|
|
38
|
-
* </sel-ect>
|
|
39
|
-
* # desired end state
|
|
40
|
-
* <sel-ect>
|
|
41
|
-
* <div role="listbox" slot="lisbox">
|
|
42
|
-
* <opt-ion></opt-ion>
|
|
43
|
-
* </div>
|
|
44
|
-
* </sel-ect>
|
|
45
|
-
* @param {HTMLElement} source host of ShadowRoot with default <slot>
|
|
46
|
-
* @param {HTMLElement} target the desired target in light dom
|
|
47
|
-
*/
|
|
48
|
-
function moveDefaultSlottablesToTarget(source, target) {
|
|
49
|
-
Array.from(source.childNodes).forEach((/** @type {* & Element} */ c) => {
|
|
50
|
-
const isNamedSlottable = c.hasAttribute && c.hasAttribute('slot');
|
|
51
|
-
if (!isNamedSlottable) {
|
|
52
|
-
target.appendChild(c);
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
|
|
57
25
|
/**
|
|
58
26
|
* @type {ListboxMixin}
|
|
59
27
|
* @param {import('@open-wc/dedupe-mixin').Constructor<import('lit').LitElement>} superclass
|
|
@@ -899,9 +867,9 @@ const ListboxMixinImplementation = superclass =>
|
|
|
899
867
|
);
|
|
900
868
|
|
|
901
869
|
if (slot) {
|
|
902
|
-
|
|
870
|
+
moveUserProvidedDefaultSlottablesToTarget(this, this._listboxNode);
|
|
903
871
|
slot.addEventListener('slotchange', () => {
|
|
904
|
-
|
|
872
|
+
moveUserProvidedDefaultSlottablesToTarget(this, this._listboxNode);
|
|
905
873
|
});
|
|
906
874
|
}
|
|
907
875
|
}
|
|
@@ -64,8 +64,11 @@ export const ArrowMixinImplementation = superclass =>
|
|
|
64
64
|
|
|
65
65
|
[data-popper-placement^='left'] .arrow {
|
|
66
66
|
right: calc(
|
|
67
|
-
-1 *
|
|
68
|
-
|
|
67
|
+
-1 *
|
|
68
|
+
(
|
|
69
|
+
var(--tooltip-arrow-height) +
|
|
70
|
+
(var(--tooltip-arrow-width) - var(--tooltip-arrow-height)) / 2
|
|
71
|
+
)
|
|
69
72
|
);
|
|
70
73
|
}
|
|
71
74
|
|
|
@@ -75,8 +78,11 @@ export const ArrowMixinImplementation = superclass =>
|
|
|
75
78
|
|
|
76
79
|
[data-popper-placement^='right'] .arrow {
|
|
77
80
|
left: calc(
|
|
78
|
-
-1 *
|
|
79
|
-
|
|
81
|
+
-1 *
|
|
82
|
+
(
|
|
83
|
+
var(--tooltip-arrow-height) +
|
|
84
|
+
(var(--tooltip-arrow-width) - var(--tooltip-arrow-height)) / 2
|
|
85
|
+
)
|
|
80
86
|
);
|
|
81
87
|
}
|
|
82
88
|
|
|
@@ -197,15 +197,24 @@ export class OverlayController extends EventTarget {
|
|
|
197
197
|
this._contentId = `overlay-content--${Math.random().toString(36).slice(2, 10)}`;
|
|
198
198
|
/** @private */
|
|
199
199
|
this.__originalAttrs = new Map();
|
|
200
|
+
/** @private */
|
|
201
|
+
this.__escKeyHandler = this.__escKeyHandler.bind(this);
|
|
200
202
|
this.updateConfig(config);
|
|
201
203
|
/** @private */
|
|
202
204
|
this.__hasActiveTrapsKeyboardFocus = false;
|
|
203
205
|
/** @private */
|
|
204
206
|
this.__hasActiveBackdrop = true;
|
|
205
207
|
/** @private */
|
|
206
|
-
this.__escKeyHandler = this.__escKeyHandler.bind(this);
|
|
207
|
-
/** @private */
|
|
208
208
|
this.__cancelHandler = this.__cancelHandler.bind(this);
|
|
209
|
+
/**
|
|
210
|
+
* The property is used to skip `__escKeyHandler` handler for overlays that have been closed
|
|
211
|
+
* by `__escKeyHandlerCalled` previously.
|
|
212
|
+
* `__escKeyHandlerCalled` is set to `false` right before overlay show up
|
|
213
|
+
* `__escKeyHandlerCalled` is set to `true` when `__escKeyHandler` is called at least one time
|
|
214
|
+
* after each 'show' phase
|
|
215
|
+
* @private
|
|
216
|
+
*/
|
|
217
|
+
this.__escKeyHandlerCalled = false;
|
|
209
218
|
}
|
|
210
219
|
|
|
211
220
|
/**
|
|
@@ -1211,13 +1220,21 @@ export class OverlayController extends EventTarget {
|
|
|
1211
1220
|
* @returns {void}
|
|
1212
1221
|
*/
|
|
1213
1222
|
__escKeyHandler(event) {
|
|
1214
|
-
if (
|
|
1223
|
+
if (
|
|
1224
|
+
event.key !== 'Escape' ||
|
|
1225
|
+
childDialogsClosedInEventLoopWeakmap.has(event) ||
|
|
1226
|
+
(!this.isShown && this.__escKeyHandlerCalled)
|
|
1227
|
+
) {
|
|
1228
|
+
return;
|
|
1229
|
+
}
|
|
1215
1230
|
|
|
1216
1231
|
const hasPressedInside =
|
|
1217
1232
|
event.composedPath().includes(this.contentNode) ||
|
|
1233
|
+
(this.invokerNode && event.composedPath().includes(this.invokerNode)) ||
|
|
1218
1234
|
deepContains(this.contentNode, /** @type {HTMLElement|ShadowRoot} */ (event.target));
|
|
1219
1235
|
|
|
1220
1236
|
if (hasPressedInside) {
|
|
1237
|
+
this.__escKeyHandlerCalled = true;
|
|
1221
1238
|
this.hide();
|
|
1222
1239
|
// We could do event.stopPropagation() here, but we don't want to hide info for
|
|
1223
1240
|
// the outside world about user interactions. Instead, we store the event in a WeakMap
|
|
@@ -1245,12 +1262,21 @@ export class OverlayController extends EventTarget {
|
|
|
1245
1262
|
* @protected
|
|
1246
1263
|
*/
|
|
1247
1264
|
_handleHidesOnEsc({ phase }) {
|
|
1248
|
-
if (phase === '
|
|
1265
|
+
if (phase === 'init') {
|
|
1266
|
+
// we remove previously added (if any) event listener to guarantee
|
|
1267
|
+
// there is only one Escape handler added here.
|
|
1268
|
+
// Note `init` phase triggered on every `updateConfig` call and that
|
|
1269
|
+
// could happen multiple times during the component life cycle
|
|
1270
|
+
this.contentNode.removeEventListener('keyup', this.__escKeyHandler);
|
|
1249
1271
|
this.contentNode.addEventListener('keyup', this.__escKeyHandler);
|
|
1250
1272
|
if (this.invokerNode) {
|
|
1251
1273
|
this.invokerNode.addEventListener('keyup', this.__escKeyHandler);
|
|
1252
1274
|
}
|
|
1253
|
-
}
|
|
1275
|
+
}
|
|
1276
|
+
if (phase === 'show') {
|
|
1277
|
+
this.__escKeyHandlerCalled = false;
|
|
1278
|
+
}
|
|
1279
|
+
if (phase === 'teardown') {
|
|
1254
1280
|
this.contentNode.removeEventListener('keyup', this.__escKeyHandler);
|
|
1255
1281
|
if (this.invokerNode) {
|
|
1256
1282
|
this.invokerNode.removeEventListener('keyup', this.__escKeyHandler);
|
|
@@ -1263,9 +1289,10 @@ export class OverlayController extends EventTarget {
|
|
|
1263
1289
|
* @protected
|
|
1264
1290
|
*/
|
|
1265
1291
|
_handleHidesOnOutsideEsc({ phase }) {
|
|
1266
|
-
if (phase === '
|
|
1292
|
+
if (phase === 'init') {
|
|
1293
|
+
document.removeEventListener('keyup', this.#outsideEscKeyHandler);
|
|
1267
1294
|
document.addEventListener('keyup', this.#outsideEscKeyHandler);
|
|
1268
|
-
} else if (phase === '
|
|
1295
|
+
} else if (phase === 'teardown') {
|
|
1269
1296
|
document.removeEventListener('keyup', this.#outsideEscKeyHandler);
|
|
1270
1297
|
}
|
|
1271
1298
|
}
|
|
@@ -799,6 +799,9 @@ describe('OverlayController', () => {
|
|
|
799
799
|
const { parentOverlay, childOverlay } = await createNestedEscControllers(parentContent);
|
|
800
800
|
await mimicEscapePress(childOverlay.contentNode);
|
|
801
801
|
|
|
802
|
+
// without this line, the test is unstable on FF sometimes
|
|
803
|
+
await aTimeout(0);
|
|
804
|
+
|
|
802
805
|
expect(parentOverlay.isShown).to.be.false;
|
|
803
806
|
expect(childOverlay.isShown).to.be.true;
|
|
804
807
|
|
|
@@ -1040,7 +1043,7 @@ describe('OverlayController', () => {
|
|
|
1040
1043
|
// Don't hide on inside shadowDom click
|
|
1041
1044
|
/** @type {ShadowRoot} */
|
|
1042
1045
|
// @ts-expect-error
|
|
1043
|
-
|
|
1046
|
+
ctrl.contentNode.querySelector(tagString).shadowRoot.querySelector('button').click();
|
|
1044
1047
|
|
|
1045
1048
|
await aTimeout(0);
|
|
1046
1049
|
expect(ctrl.isShown).to.be.true;
|
|
@@ -7,9 +7,9 @@ const tagString = defineCE(
|
|
|
7
7
|
class extends OverlayMixin(LitElement) {
|
|
8
8
|
render() {
|
|
9
9
|
return html`
|
|
10
|
-
<
|
|
10
|
+
<slot name="invoker"></slot>
|
|
11
11
|
<div id="overlay-content-node-wrapper">
|
|
12
|
-
<
|
|
12
|
+
<slot name="content"></slot>
|
|
13
13
|
</div>
|
|
14
14
|
`;
|
|
15
15
|
}
|
|
@@ -111,6 +111,63 @@ export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) {
|
|
|
111
111
|
expect(el.opened).to.be.false;
|
|
112
112
|
});
|
|
113
113
|
|
|
114
|
+
/**
|
|
115
|
+
* In case OverlayMixin has a handler for Escape which sets `opened` to `false`,
|
|
116
|
+
* make sure it does not conflict with the Escape handler in OverlayController.
|
|
117
|
+
* */
|
|
118
|
+
it('syncs opened between overlayController and OverlayMixin on Escape', async () => {
|
|
119
|
+
const config = { hidesOnEsc: true };
|
|
120
|
+
const el = /** @type {OverlayEl} */ (
|
|
121
|
+
await fixture(html`
|
|
122
|
+
<${tag} id="main-dialog" .config="${config}">
|
|
123
|
+
<div slot="content" id="mainContent">
|
|
124
|
+
open nested overlay:
|
|
125
|
+
<${tag} id="sub-dialog" .config="${config}">
|
|
126
|
+
<div slot="content" id="nestedContent">
|
|
127
|
+
<input id="nestedContentInput">
|
|
128
|
+
</div>
|
|
129
|
+
<button slot="invoker" id="nestedInvoker">nested invoker button</button>
|
|
130
|
+
</${tag}>
|
|
131
|
+
</div>
|
|
132
|
+
<button slot="invoker" id="mainInvoker">invoker button</button>
|
|
133
|
+
</${tag}>
|
|
134
|
+
`)
|
|
135
|
+
);
|
|
136
|
+
await el.updateComplete;
|
|
137
|
+
const subDialog = /** @type {OverlayEl} */ (el.querySelector('#sub-dialog'));
|
|
138
|
+
const nestedContentInput = /** @type {OverlayEl} */ (el.querySelector('#nestedContentInput'));
|
|
139
|
+
|
|
140
|
+
// Note, OverlayController has Escape key listener added to "#nestedContent".
|
|
141
|
+
// And the sub-dialog adds the Escape key listener to "#nestedContentInput" which is a child evelement of "#nestedContent"
|
|
142
|
+
// In this case when "#nestedContentInput" is focused and Escape is pressed, the listener of "#nestedContentInput"
|
|
143
|
+
// is always called before the listener set for "#nestedContent" inside OverlayController.
|
|
144
|
+
// This way we check the scenario when OverlayController's `hide()` is called first from
|
|
145
|
+
// The OverlayMixin and it does not prevent OverlayController `hidesOnEsc` handler from being called
|
|
146
|
+
nestedContentInput?.addEventListener('keyup', (/** @type {* & KeyboardEvent} */ event) => {
|
|
147
|
+
if (event.key === 'Escape') {
|
|
148
|
+
subDialog.opened = false;
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
el.opened = true;
|
|
153
|
+
await el.updateComplete;
|
|
154
|
+
await el._overlayCtrl._showComplete;
|
|
155
|
+
expect(el.opened).to.be.true;
|
|
156
|
+
expect(el._overlayCtrl.isShown).to.be.true;
|
|
157
|
+
|
|
158
|
+
subDialog.opened = true;
|
|
159
|
+
await subDialog.updateComplete;
|
|
160
|
+
await subDialog._overlayCtrl._showComplete;
|
|
161
|
+
expect(subDialog.opened).to.be.true;
|
|
162
|
+
expect(subDialog._overlayCtrl.isShown).to.be.true;
|
|
163
|
+
|
|
164
|
+
await mimicEscapePress(nestedContentInput);
|
|
165
|
+
expect(subDialog.opened).to.be.false;
|
|
166
|
+
expect(subDialog._overlayCtrl.isShown).to.be.false;
|
|
167
|
+
expect(el.opened).to.be.true;
|
|
168
|
+
expect(el._overlayCtrl.isShown).to.be.true;
|
|
169
|
+
});
|
|
170
|
+
|
|
114
171
|
// TODO: put this tests in OverlayController.test.js instead?
|
|
115
172
|
it('does not change the body size when opened', async () => {
|
|
116
173
|
const parentNode = document.createElement('div');
|