@lion/ui 0.8.1 → 0.8.3

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.
Files changed (132) hide show
  1. package/components/calendar/src/LionCalendar.js +6 -0
  2. package/components/core/src/DisabledWithTabIndexMixin.js +7 -0
  3. package/components/core/src/ScopedElementsMixin.js +58 -37
  4. package/components/core/test/ScopedElementsMixin.test.js +131 -0
  5. package/components/core/test/ssr-definitions/ScopedElementsHost.define.js +1 -0
  6. package/components/form-core/src/FormControlMixin.js +6 -0
  7. package/components/form-core/src/utils/SyncUpdatableMixin.js +7 -0
  8. package/components/form-core/src/validate/LionValidationFeedback.js +4 -2
  9. package/components/form-core/test/validate/lion-validation-feedback.test.js +12 -0
  10. package/components/icon/src/LionIcon.js +6 -0
  11. package/components/localize/src/LocalizeManager.js +258 -178
  12. package/components/overlays/src/OverlayController.js +40 -13
  13. package/components/overlays/src/OverlayMixin.js +7 -0
  14. package/components/overlays/test/OverlayController.test.js +233 -30
  15. package/components/overlays/test-helpers/mimicClick.js +2 -2
  16. package/components/progress-indicator/src/LionProgressIndicator.js +6 -0
  17. package/components/steps/src/LionStep.js +6 -0
  18. package/components/steps/src/LionSteps.js +6 -0
  19. package/components/tabs/src/LionTabs.js +6 -0
  20. package/components/tooltip/src/LionTooltip.js +6 -0
  21. package/custom-elements.json +716 -163
  22. package/dist-types/components/calendar/src/LionCalendar.d.ts +5 -0
  23. package/dist-types/components/calendar/src/LionCalendar.d.ts.map +1 -1
  24. package/dist-types/components/core/src/DisabledWithTabIndexMixin.d.ts.map +1 -1
  25. package/dist-types/components/core/src/ScopedElementsMixin.d.ts +43 -6
  26. package/dist-types/components/core/src/ScopedElementsMixin.d.ts.map +1 -1
  27. package/dist-types/components/core/test/ScopedElementsMixin.test.d.ts +2 -0
  28. package/dist-types/components/core/test/ScopedElementsMixin.test.d.ts.map +1 -0
  29. package/dist-types/components/core/test/ssr-definitions/ScopedElementsHost.define.d.ts +2 -0
  30. package/dist-types/components/core/test/ssr-definitions/ScopedElementsHost.define.d.ts.map +1 -0
  31. package/dist-types/components/form-core/src/FormControlMixin.d.ts.map +1 -1
  32. package/dist-types/components/form-core/src/utils/SyncUpdatableMixin.d.ts.map +1 -1
  33. package/dist-types/components/form-core/src/validate/LionValidationFeedback.d.ts.map +1 -1
  34. package/dist-types/components/form-integrations/test/helpers/helpers.d.ts +3 -3
  35. package/dist-types/components/form-integrations/test/helpers/helpers.d.ts.map +1 -1
  36. package/dist-types/components/icon/src/LionIcon.d.ts +5 -0
  37. package/dist-types/components/icon/src/LionIcon.d.ts.map +1 -1
  38. package/dist-types/components/input-datepicker/src/LionInputDatepicker.d.ts +1 -1
  39. package/dist-types/components/input-file/src/LionInputFile.d.ts +1 -1
  40. package/dist-types/components/input-file/src/LionSelectedFileList.d.ts +1 -1
  41. package/dist-types/components/localize/src/LocalizeManager.d.ts +108 -93
  42. package/dist-types/components/localize/src/LocalizeManager.d.ts.map +1 -1
  43. package/dist-types/components/overlays/src/OverlayController.d.ts +9 -5
  44. package/dist-types/components/overlays/src/OverlayController.d.ts.map +1 -1
  45. package/dist-types/components/overlays/src/OverlayMixin.d.ts.map +1 -1
  46. package/dist-types/components/overlays/test/OverlayController.test.d.ts +1 -1
  47. package/dist-types/components/overlays/test/OverlayController.test.d.ts.map +1 -1
  48. package/dist-types/components/overlays/test-helpers/mimicClick.d.ts +1 -1
  49. package/dist-types/components/progress-indicator/src/LionProgressIndicator.d.ts +5 -0
  50. package/dist-types/components/progress-indicator/src/LionProgressIndicator.d.ts.map +1 -1
  51. package/dist-types/components/select-rich/src/LionSelectRich.d.ts +1 -1
  52. package/dist-types/components/steps/src/LionStep.d.ts +5 -0
  53. package/dist-types/components/steps/src/LionStep.d.ts.map +1 -1
  54. package/dist-types/components/steps/src/LionSteps.d.ts +5 -0
  55. package/dist-types/components/steps/src/LionSteps.d.ts.map +1 -1
  56. package/dist-types/components/switch/src/LionSwitch.d.ts +1 -1
  57. package/dist-types/components/tabs/src/LionTabs.d.ts +5 -0
  58. package/dist-types/components/tabs/src/LionTabs.d.ts.map +1 -1
  59. package/dist-types/components/tooltip/src/LionTooltip.d.ts +5 -0
  60. package/dist-types/components/tooltip/src/LionTooltip.d.ts.map +1 -1
  61. package/dist-types/tsconfig.tsbuildinfo +1 -1
  62. package/docs/components/checkbox-group/overview.md +2 -2
  63. package/docs/components/collapsible/overview.md +1 -1
  64. package/docs/components/combobox/overview.md +1 -1
  65. package/docs/components/combobox/use-cases.md +1 -1
  66. package/docs/components/dialog/overview.md +1 -1
  67. package/docs/components/fieldset/overview.md +5 -5
  68. package/docs/components/form/overview.md +3 -3
  69. package/docs/components/icon/use-cases.md +1 -1
  70. package/docs/components/input/api-table.md +1 -1
  71. package/docs/components/input/overview.md +1 -1
  72. package/docs/components/input-amount/api-table.md +1 -1
  73. package/docs/components/input-amount/overview.md +3 -3
  74. package/docs/components/input-date/api-table.md +1 -1
  75. package/docs/components/input-date/overview.md +3 -3
  76. package/docs/components/input-datepicker/api-table.md +1 -1
  77. package/docs/components/input-datepicker/overview.md +5 -5
  78. package/docs/components/input-email/api-table.md +1 -1
  79. package/docs/components/input-email/overview.md +2 -2
  80. package/docs/components/input-file/api-table.md +1 -1
  81. package/docs/components/input-file/overview.md +1 -1
  82. package/docs/components/input-iban/api-table.md +1 -1
  83. package/docs/components/input-iban/overview.md +2 -2
  84. package/docs/components/input-range/api-table.md +1 -1
  85. package/docs/components/input-range/overview.md +2 -2
  86. package/docs/components/input-stepper/api-table.md +1 -1
  87. package/docs/components/input-stepper/overview.md +1 -1
  88. package/docs/components/input-tel/api-table.md +1 -1
  89. package/docs/components/input-tel/overview.md +1 -1
  90. package/docs/components/input-tel/use-cases.md +6 -6
  91. package/docs/components/input-tel-dropdown/api-table.md +1 -1
  92. package/docs/components/input-tel-dropdown/overview.md +1 -1
  93. package/docs/components/listbox/use-cases.md +1 -1
  94. package/docs/components/radio-group/api-table.md +1 -1
  95. package/docs/components/radio-group/overview.md +3 -3
  96. package/docs/components/select/api-table.md +1 -1
  97. package/docs/components/select/use-cases.md +1 -1
  98. package/docs/components/select-rich/api-table.md +1 -1
  99. package/docs/components/select-rich/use-cases.md +1 -1
  100. package/docs/components/switch/api-table.md +1 -1
  101. package/docs/components/tabs/examples.md +1 -1
  102. package/docs/components/textarea/api-table.md +1 -1
  103. package/docs/fundamentals/index.md +4 -4
  104. package/docs/fundamentals/node-tools/providence-analytics/LocalConfiguration.md +1 -1
  105. package/docs/fundamentals/node-tools/providence-analytics/QueryResult.md +1 -1
  106. package/docs/fundamentals/node-tools/providence-analytics/analyzer.md +1 -1
  107. package/docs/fundamentals/node-tools/providence-analytics/dashboard.md +1 -1
  108. package/docs/fundamentals/node-tools/providence-analytics/overview.md +3 -3
  109. package/docs/fundamentals/node-tools/publish-docs/overview.md +3 -3
  110. package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +2 -2
  111. package/docs/fundamentals/rationales/accessibility.md +1 -1
  112. package/docs/fundamentals/systems/core/SlotMixin.md +1 -1
  113. package/docs/fundamentals/systems/core/overview.md +1 -1
  114. package/docs/fundamentals/systems/form/formatting-and-parsing.md +4 -4
  115. package/docs/fundamentals/systems/form/model-value.md +1 -1
  116. package/docs/fundamentals/systems/form/overview.md +28 -28
  117. package/docs/fundamentals/systems/form/validate.md +2 -2
  118. package/docs/fundamentals/systems/localize/api-table.md +38 -37
  119. package/docs/fundamentals/systems/localize/overview.md +4 -4
  120. package/docs/fundamentals/systems/overlays/api-table.md +1 -0
  121. package/docs/fundamentals/systems/overlays/configuration.md +2 -2
  122. package/docs/fundamentals/systems/overlays/overview.md +5 -5
  123. package/docs/fundamentals/systems/overlays/use-cases.md +2 -2
  124. package/docs/fundamentals/tools/helpers/overview.md +1 -1
  125. package/docs/fundamentals/tools/singleton-manager/overview.md +4 -4
  126. package/docs/guides/how-to/create-a-custom-field.md +5 -5
  127. package/docs/guides/how-to/create-a-form.md +4 -4
  128. package/docs/guides/how-to/extend-a-native-input.md +2 -2
  129. package/docs/guides/index.md +8 -8
  130. package/docs/guides/principles/index.md +5 -5
  131. package/docs/guides/principles/styling.md +1 -1
  132. package/package.json +1 -1
@@ -1,28 +1,41 @@
1
1
  /* eslint-disable no-new */
2
+ import { OverlayController, overlays } from '@lion/ui/overlays.js';
3
+ import { mimicClick } from '@lion/ui/overlays-test-helpers.js';
4
+ import sinon from 'sinon';
2
5
  import {
3
- aTimeout,
6
+ unsafeStatic,
7
+ fixtureSync,
4
8
  defineCE,
5
- expect,
9
+ aTimeout,
6
10
  fixture,
11
+ expect,
7
12
  html,
8
- unsafeStatic,
9
- fixtureSync,
10
13
  } from '@open-wc/testing';
11
- import sinon from 'sinon';
12
- import { OverlayController, overlays } from '@lion/ui/overlays.js';
13
- import { mimicClick } from '@lion/ui/overlays-test-helpers.js';
14
- import { keyCodes } from '../src/utils/key-codes.js';
15
- import { simulateTab } from '../src/utils/simulate-tab.js';
16
- import { _adoptStyleUtils } from '../src/utils/adopt-styles.js';
14
+
17
15
  import { createShadowHost } from '../test-helpers/createShadowHost.js';
16
+ import { _adoptStyleUtils } from '../src/utils/adopt-styles.js';
17
+ import { simulateTab } from '../src/utils/simulate-tab.js';
18
+ import { keyCodes } from '../src/utils/key-codes.js';
18
19
 
19
20
  /**
20
- * @typedef {import('../types/OverlayConfig.js').OverlayConfig} OverlayConfig
21
21
  * @typedef {import('../types/OverlayConfig.js').ViewportPlacement} ViewportPlacement
22
+ * @typedef {import('../types/OverlayConfig.js').OverlayConfig} OverlayConfig
22
23
  */
23
24
 
24
25
  const wrappingDialogNodeStyle = 'display: none; z-index: 9999; padding: 0px;';
25
26
 
27
+ /**
28
+ * A small wrapper function that closely mimics an escape press from a user
29
+ * (prevents common mistakes like no bubbling or keydown)
30
+ * @param {Element|Document} element
31
+ */
32
+ async function mimicEscapePress(element) {
33
+ element.dispatchEvent(
34
+ new KeyboardEvent('keyup', { key: 'Escape', bubbles: true, composed: true }),
35
+ );
36
+ await aTimeout(0);
37
+ }
38
+
26
39
  /**
27
40
  * Make sure that all browsers serialize html in a similar way
28
41
  * (Firefox tends to output empty style attrs)
@@ -74,6 +87,50 @@ const withLocalTestConfig = () =>
74
87
  ),
75
88
  });
76
89
 
90
+ /**
91
+ * @param {HTMLDivElement} parentContent
92
+ * @returns {Promise<{parentOverlay: OverlayController; childOverlay: OverlayController}>}
93
+ */
94
+ async function createNestedEscControllers(parentContent) {
95
+ const childContent = /** @type {HTMLDivElement} */ (parentContent.querySelector('div[id]'));
96
+ // Assert valid fixure
97
+ const isValid =
98
+ (parentContent.id === 'parent-overlay--hidesOnEsc' ||
99
+ parentContent.id === 'parent-overlay--hidesOnOutsideEsc') &&
100
+ (childContent.id === 'child-overlay--hidesOnEsc' ||
101
+ childContent.id === 'child-overlay--hidesOnOutsideEsc');
102
+ if (!isValid) {
103
+ throw new Error('Provide a valid fixture');
104
+ }
105
+
106
+ if (parentContent.hasAttribute('data-convert-to-shadow-root')) {
107
+ const shadowRootParent = parentContent.attachShadow({ mode: 'open' });
108
+ shadowRootParent.appendChild(childContent);
109
+ }
110
+
111
+ const parentHasOutsideOnEsc = parentContent.id === 'parent-overlay--hidesOnOutsideEsc';
112
+ const childHasOutsideOnEsc = childContent.id === 'child-overlay--hidesOnOutsideEsc';
113
+
114
+ const parentConfig = parentHasOutsideOnEsc ? { hidesOnOutsideEsc: true } : { hidesOnEsc: true };
115
+ const childConfig = childHasOutsideOnEsc ? { hidesOnOutsideEsc: true } : { hidesOnEsc: true };
116
+
117
+ const parentOverlay = new OverlayController({
118
+ ...withGlobalTestConfig(),
119
+ contentNode: parentContent,
120
+ ...parentConfig,
121
+ });
122
+ const childOverlay = new OverlayController({
123
+ ...withGlobalTestConfig(),
124
+ contentNode: childContent,
125
+ ...childConfig,
126
+ });
127
+
128
+ await parentOverlay.show();
129
+ await childOverlay.show();
130
+
131
+ return { parentOverlay, childOverlay };
132
+ }
133
+
77
134
  afterEach(() => {
78
135
  overlays.teardown();
79
136
  });
@@ -574,74 +631,221 @@ describe('OverlayController', () => {
574
631
  });
575
632
 
576
633
  describe('hidesOnEsc', () => {
577
- it('hides when [escape] is pressed', async () => {
634
+ it('hides on [Escape] press', async () => {
578
635
  const ctrl = new OverlayController({
579
636
  ...withGlobalTestConfig(),
580
637
  hidesOnEsc: true,
581
638
  });
582
639
  await ctrl.show();
583
- ctrl.contentNode.dispatchEvent(new KeyboardEvent('keyup', { key: 'Escape' }));
584
- await aTimeout(0);
640
+ await mimicEscapePress(ctrl.contentNode);
585
641
  expect(ctrl.isShown).to.be.false;
586
642
  });
587
643
 
588
- it("doesn't hide when [escape] is pressed and hidesOnEsc is set to false", async () => {
644
+ it('stays shown on [Escape] press with `.hidesOnEsc` set to false', async () => {
589
645
  const ctrl = new OverlayController({
590
646
  ...withGlobalTestConfig(),
591
647
  hidesOnEsc: false,
592
648
  });
593
649
  await ctrl.show();
594
- ctrl.contentNode.dispatchEvent(new KeyboardEvent('keyup', { key: 'Escape' }));
595
- await aTimeout(0);
650
+ await mimicEscapePress(ctrl.contentNode);
596
651
  expect(ctrl.isShown).to.be.true;
597
652
  });
598
653
 
599
- it('stays shown when [escape] is pressed on outside element', async () => {
654
+ it('stays shown on [Escape] press on outside element', async () => {
600
655
  const ctrl = new OverlayController({
601
656
  ...withGlobalTestConfig(),
602
657
  hidesOnEsc: true,
603
658
  });
604
659
  await ctrl.show();
605
- document.dispatchEvent(new KeyboardEvent('keyup', { key: 'Escape' }));
660
+ await mimicEscapePress(document);
606
661
  expect(ctrl.isShown).to.be.true;
607
662
  });
608
663
 
609
- it('does not hide when [escape] is pressed with modal <dialog> and "hidesOnEsc" is false', async () => {
664
+ it('stays shown on [Escape] press with modal <dialog> and `.hidesOnEsc` is false', async () => {
610
665
  const ctrl = new OverlayController({
611
666
  ...withGlobalTestConfig(),
612
667
  trapsKeyboardFocus: true,
613
668
  hidesOnEsc: false,
614
669
  });
615
670
  await ctrl.show();
616
- ctrl.contentNode.dispatchEvent(new KeyboardEvent('keyup', { key: 'Escape' }));
617
- await aTimeout(0);
671
+ await mimicEscapePress(ctrl.contentNode);
618
672
  expect(ctrl.isShown).to.be.true;
619
673
  });
674
+
675
+ it('parent stays shown on [Escape] press in a nested overlay', async () => {
676
+ const parentContent = /** @type {HTMLDivElement} */ (
677
+ await fixture(
678
+ html` <!-- -->
679
+ <div id="parent-overlay--hidesOnEsc">
680
+ <div id="child-overlay--hidesOnEsc">we press [Escape] here</div>
681
+ </div>`,
682
+ )
683
+ );
684
+ const { parentOverlay, childOverlay } = await createNestedEscControllers(parentContent);
685
+ await mimicEscapePress(childOverlay.contentNode);
686
+
687
+ expect(parentOverlay.isShown).to.be.true;
688
+ expect(childOverlay.isShown).to.be.false;
689
+ });
620
690
  });
621
691
 
622
692
  describe('hidesOnOutsideEsc', () => {
623
- it('hides when [escape] is pressed on outside element', async () => {
693
+ it('hides on [Escape] press on outside element', async () => {
624
694
  const ctrl = new OverlayController({
625
695
  ...withGlobalTestConfig(),
626
696
  hidesOnOutsideEsc: true,
627
697
  });
628
698
  await ctrl.show();
629
- document.dispatchEvent(new KeyboardEvent('keyup', { key: 'Escape' }));
630
- await aTimeout(0);
699
+ await mimicEscapePress(document);
631
700
  expect(ctrl.isShown).to.be.false;
632
701
  });
633
702
 
634
- it('stays shown when [escape] is pressed on inside element', async () => {
703
+ it('stays shown on [Escape] press on inside element', async () => {
635
704
  const ctrl = new OverlayController({
636
705
  ...withGlobalTestConfig(),
637
706
  hidesOnOutsideEsc: true,
638
707
  });
639
708
  await ctrl.show();
640
- ctrl.contentNode.dispatchEvent(new KeyboardEvent('keyup', { key: 'Escape' }));
709
+ await mimicEscapePress(ctrl.contentNode);
641
710
  expect(ctrl.isShown).to.be.true;
642
711
  });
712
+
713
+ it('stays shown on [Escape] press in a nested overlay', async () => {
714
+ const parentContent = /** @type {HTMLDivElement} */ (
715
+ await fixture(
716
+ html` <!-- -->
717
+ <div id="parent-overlay--hidesOnOutsideEsc">
718
+ <div id="child-overlay--hidesOnOutsideEsc">we press [Escape] here</div>
719
+ </div>`,
720
+ )
721
+ );
722
+ const { parentOverlay, childOverlay } = await createNestedEscControllers(parentContent);
723
+ mimicEscapePress(childOverlay.contentNode);
724
+
725
+ expect(parentOverlay.isShown).to.be.true;
726
+ expect(childOverlay.isShown).to.be.true;
727
+ });
643
728
  });
644
729
 
730
+ describe('Nested hidesOnEsc / hidesOnOutsideEsc', () => {
731
+ describe('Parent has hidesOnEsc and child has hidesOnOutsideEsc', () => {
732
+ it('on [Escape] press in child overlay: parent hides, child stays shown', async () => {
733
+ const parentContent = /** @type {HTMLDivElement} */ (
734
+ await fixture(
735
+ html` <!-- -->
736
+ <div id="parent-overlay--hidesOnEsc">
737
+ <div id="child-overlay--hidesOnOutsideEsc">we press [Escape] here</div>
738
+ </div>`,
739
+ )
740
+ );
741
+ const { parentOverlay, childOverlay } = await createNestedEscControllers(parentContent);
742
+ await mimicEscapePress(childOverlay.contentNode);
743
+
744
+ expect(parentOverlay.isShown).to.be.false;
745
+ expect(childOverlay.isShown).to.be.true;
746
+ });
747
+
748
+ it('on [Escape] press outside overlays: parent stays shown, child hides', async () => {
749
+ const parentContent = /** @type {HTMLDivElement} */ (
750
+ await fixture(
751
+ html` <!-- we press [Escape] here -->
752
+ <div id="parent-overlay--hidesOnEsc">
753
+ <div id="child-overlay--hidesOnOutsideEsc"></div>
754
+ </div>`,
755
+ )
756
+ );
757
+ const { parentOverlay, childOverlay } = await createNestedEscControllers(parentContent);
758
+ await mimicEscapePress(document);
759
+
760
+ expect(parentOverlay.isShown).to.be.true;
761
+ expect(childOverlay.isShown).to.be.false;
762
+ });
763
+
764
+ it('on [Escape] press in parent overlay: parent is hidden, child is hidden', async () => {
765
+ const parentContent = /** @type {HTMLDivElement} */ (
766
+ await fixture(
767
+ html` <!-- -->
768
+ <div id="parent-overlay--hidesOnEsc">
769
+ we press [Escape] here
770
+ <div id="child-overlay--hidesOnOutsideEsc"></div>
771
+ </div>`,
772
+ )
773
+ );
774
+ const { parentOverlay, childOverlay } = await createNestedEscControllers(parentContent);
775
+ await mimicEscapePress(parentContent);
776
+
777
+ expect(parentOverlay.isShown).to.be.false;
778
+ expect(childOverlay.isShown).to.be.false;
779
+ });
780
+ });
781
+ describe('Parent has hidesOnOutsideEsc and child has hidesOnEsc', () => {
782
+ it('on [Escape] press in child overlay: parent stays shown, child hides', async () => {
783
+ const parentContent = /** @type {HTMLDivElement} */ (
784
+ await fixture(
785
+ html` <!-- -->
786
+ <div id="parent-overlay--hidesOnOutsideEsc">
787
+ <div id="child-overlay--hidesOnEsc">we press [Escape] here</div>
788
+ </div>`,
789
+ )
790
+ );
791
+ const { parentOverlay, childOverlay } = await createNestedEscControllers(parentContent);
792
+ await mimicEscapePress(childOverlay.contentNode);
793
+
794
+ expect(parentOverlay.isShown).to.be.true;
795
+ expect(childOverlay.isShown).to.be.false;
796
+ });
797
+
798
+ it('on [Escape] press outside overlays: parent hides, child stays shown', async () => {
799
+ const parentContent = /** @type {HTMLDivElement} */ (
800
+ await fixture(
801
+ html` <!-- we press [Escape] here -->
802
+ <div id="parent-overlay--hidesOnOutsideEsc">
803
+ <div id="child-overlay--hidesOnEsc"></div>
804
+ </div>`,
805
+ )
806
+ );
807
+ const { parentOverlay, childOverlay } = await createNestedEscControllers(parentContent);
808
+ await mimicEscapePress(document);
809
+
810
+ expect(parentOverlay.isShown).to.be.false;
811
+ expect(childOverlay.isShown).to.be.true;
812
+ });
813
+
814
+ it('on [Escape] press in parent overlay: parent hides, child stays shown', async () => {
815
+ const parentContent = /** @type {HTMLDivElement} */ (
816
+ await fixture(
817
+ html` <!-- we press [Escape] here -->
818
+ <div id="parent-overlay--hidesOnOutsideEsc">
819
+ <div id="child-overlay--hidesOnEsc"></div>
820
+ </div>`,
821
+ )
822
+ );
823
+ const { parentOverlay, childOverlay } = await createNestedEscControllers(parentContent);
824
+ await mimicEscapePress(document);
825
+
826
+ expect(parentOverlay.isShown).to.be.false;
827
+ expect(childOverlay.isShown).to.be.true;
828
+ });
829
+ });
830
+
831
+ describe('With shadow dom', () => {
832
+ it('on [Escape] press in child overlay in shadow root: parent hides, child stays shown', async () => {
833
+ const parentContent = /** @type {HTMLDivElement} */ (
834
+ await fixture(
835
+ html` <!-- -->
836
+ <div id="parent-overlay--hidesOnEsc" data-convert-to-shadow-root>
837
+ <div id="child-overlay--hidesOnOutsideEsc">we press [Escape] here</div>
838
+ </div>`,
839
+ )
840
+ );
841
+ const { parentOverlay, childOverlay } = await createNestedEscControllers(parentContent);
842
+ await mimicEscapePress(childOverlay.contentNode);
843
+
844
+ expect(parentOverlay.isShown).to.be.false;
845
+ expect(childOverlay.isShown).to.be.true;
846
+ });
847
+ });
848
+ });
645
849
  describe('hidesOnOutsideClick', () => {
646
850
  it('hides on outside click', async () => {
647
851
  const contentNode = /** @type {HTMLElement} */ (await fixture('<div>Content</div>'));
@@ -684,9 +888,8 @@ describe('OverlayController', () => {
684
888
  expect(ctrl.isShown).to.be.true;
685
889
 
686
890
  // Don't hide on inside mousedown & outside mouseup
687
- ctrl.contentNode.dispatchEvent(new MouseEvent('mousedown'));
688
- await aTimeout(0);
689
- document.body.dispatchEvent(new MouseEvent('mouseup'));
891
+ await mimicClick(ctrl.contentNode, { releaseElement: document.body, isAsync: true });
892
+
690
893
  await aTimeout(0);
691
894
  expect(ctrl.isShown).to.be.true;
692
895
 
@@ -8,9 +8,9 @@ async function sleep(t = 0) {
8
8
 
9
9
  /**
10
10
  * @param {HTMLElement} el
11
- * @param {{isAsync?:boolean, releaseElement?: HTMLElement}} config
11
+ * @param {{isAsync?:boolean, releaseElement?: HTMLElement}} config releaseElement can be different when the mouse is dragged before release
12
12
  */
13
- export async function mimicClick(el, { isAsync, releaseElement } = { isAsync: false }) {
13
+ export async function mimicClick(el, { isAsync = false, releaseElement } = {}) {
14
14
  const releaseEl = releaseElement || el;
15
15
  el.dispatchEvent(new MouseEvent('mousedown'));
16
16
  if (isAsync) {
@@ -93,6 +93,12 @@ export class LionProgressIndicator extends LocalizeMixin(LitElement) {
93
93
  return !this.hasAttribute('value');
94
94
  }
95
95
 
96
+ /**
97
+ * // TODO: check if this is a false positive or if we can improve
98
+ * @configure ReactiveElement
99
+ */
100
+ static enabledWarnings = super.enabledWarnings?.filter(w => w !== 'change-in-update') || [];
101
+
96
102
  /**
97
103
  * In case of a determinate progress-indicator it returns the progress percentage
98
104
  * based on value, min & max.
@@ -115,4 +115,10 @@ export class LionStep extends LitElement {
115
115
  const result = this.condition(data);
116
116
  return this.invertCondition ? !result : result;
117
117
  }
118
+
119
+ /**
120
+ * // TODO: check if this is a false positive or if we can improve
121
+ * @configure ReactiveElement
122
+ */
123
+ static enabledWarnings = super.enabledWarnings?.filter(w => w !== 'change-in-update') || [];
118
124
  }
@@ -108,6 +108,12 @@ export class LionSteps extends LitElement {
108
108
  );
109
109
  }
110
110
 
111
+ /**
112
+ * // TODO: check if this is a false positive or if we can improve
113
+ * @configure ReactiveElement
114
+ */
115
+ static enabledWarnings = super.enabledWarnings?.filter(w => w !== 'change-in-update') || [];
116
+
111
117
  /**
112
118
  * @param {number} newCurrent
113
119
  * @param {number} oldCurrent
@@ -188,6 +188,12 @@ export class LionTabs extends LitElement {
188
188
  );
189
189
  }
190
190
 
191
+ /**
192
+ * // TODO: check if this is a false positive or if we can improve
193
+ * @configure ReactiveElement
194
+ */
195
+ static enabledWarnings = super.enabledWarnings?.filter(w => w !== 'change-in-update') || [];
196
+
191
197
  /** @private */
192
198
  __setupSlots() {
193
199
  if (this.shadowRoot) {
@@ -55,6 +55,12 @@ export class LionTooltip extends ArrowMixin(OverlayMixin(LitElement)) {
55
55
  this.invokerRelation = 'description';
56
56
  }
57
57
 
58
+ /**
59
+ * // TODO: check if this is a false positive or if we can improve
60
+ * @configure ReactiveElement
61
+ */
62
+ static enabledWarnings = super.enabledWarnings?.filter(w => w !== 'change-in-update') || [];
63
+
58
64
  /** @protected */
59
65
  // eslint-disable-next-line class-methods-use-this
60
66
  _defineOverlayConfig() {