@lion/ui 0.14.1 → 0.14.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 (62) hide show
  1. package/components/dialog/test/lion-dialog.test.js +114 -1
  2. package/components/overlays/src/OverlayMixin.js +12 -5
  3. package/components/overlays/test/OverlayController.test.js +2 -0
  4. package/components/overlays/test-suites/OverlayMixin.suite.js +4 -1
  5. package/components/select-rich/src/LionSelectRich.js +4 -2
  6. package/components/select-rich/test/lion-select-rich.test.js +376 -1
  7. package/custom-elements.json +30 -30
  8. package/dist-types/components/dialog/test/lion-dialog.test.d.ts.map +1 -1
  9. package/dist-types/components/overlays/src/OverlayMixin.d.ts.map +1 -1
  10. package/dist-types/components/overlays/test-suites/OverlayMixin.suite.d.ts.map +1 -1
  11. package/dist-types/components/select-rich/src/LionSelectRich.d.ts.map +1 -1
  12. package/dist-types/components/select-rich/test/lion-select-rich.test.d.ts.map +1 -1
  13. package/dist-types/tsconfig.tsbuildinfo +1 -1
  14. package/docs/components/checkbox-group/overview.md +2 -2
  15. package/docs/components/collapsible/overview.md +1 -1
  16. package/docs/components/combobox/overview.md +1 -1
  17. package/docs/components/combobox/use-cases.md +1 -1
  18. package/docs/components/dialog/overview.md +1 -1
  19. package/docs/components/fieldset/overview.md +5 -5
  20. package/docs/components/form/overview.md +3 -3
  21. package/docs/components/form/use-cases.md +2 -2
  22. package/docs/components/icon/use-cases.md +1 -1
  23. package/docs/components/input/overview.md +1 -1
  24. package/docs/components/input-amount/overview.md +3 -3
  25. package/docs/components/input-date/overview.md +3 -3
  26. package/docs/components/input-datepicker/overview.md +5 -5
  27. package/docs/components/input-email/overview.md +2 -2
  28. package/docs/components/input-file/overview.md +1 -1
  29. package/docs/components/input-iban/overview.md +2 -2
  30. package/docs/components/input-range/overview.md +2 -2
  31. package/docs/components/input-stepper/overview.md +1 -1
  32. package/docs/components/input-tel/overview.md +1 -1
  33. package/docs/components/input-tel/use-cases.md +6 -6
  34. package/docs/components/input-tel-dropdown/overview.md +1 -1
  35. package/docs/components/listbox/use-cases.md +1 -1
  36. package/docs/components/radio-group/overview.md +3 -3
  37. package/docs/components/select/use-cases.md +1 -1
  38. package/docs/components/select-rich/use-cases.md +16 -2
  39. package/docs/components/tabs/examples.md +1 -1
  40. package/docs/fundamentals/index.md +4 -4
  41. package/docs/fundamentals/node-tools/publish-docs/overview.md +3 -3
  42. package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +2 -2
  43. package/docs/fundamentals/rationales/accessibility.md +1 -1
  44. package/docs/fundamentals/systems/core/SlotMixin.md +1 -1
  45. package/docs/fundamentals/systems/core/overview.md +1 -1
  46. package/docs/fundamentals/systems/form/formatting-and-parsing.md +4 -4
  47. package/docs/fundamentals/systems/form/model-value.md +1 -1
  48. package/docs/fundamentals/systems/form/overview.md +28 -28
  49. package/docs/fundamentals/systems/form/validate.md +2 -2
  50. package/docs/fundamentals/systems/localize/overview.md +4 -4
  51. package/docs/fundamentals/systems/overlays/configuration.md +2 -2
  52. package/docs/fundamentals/systems/overlays/overview.md +5 -5
  53. package/docs/fundamentals/systems/overlays/use-cases.md +2 -2
  54. package/docs/fundamentals/tools/helpers/overview.md +1 -1
  55. package/docs/fundamentals/tools/singleton-manager/overview.md +4 -4
  56. package/docs/guides/how-to/create-a-custom-field.md +5 -5
  57. package/docs/guides/how-to/create-a-form.md +4 -4
  58. package/docs/guides/how-to/extend-a-native-input.md +2 -2
  59. package/docs/guides/index.md +8 -8
  60. package/docs/guides/principles/index.md +5 -5
  61. package/docs/guides/principles/styling.md +1 -1
  62. package/package.json +1 -1
@@ -1,9 +1,20 @@
1
1
  /* eslint-disable lit-a11y/no-autofocus */
2
- import { expect, fixture as _fixture, html, unsafeStatic, aTimeout } from '@open-wc/testing';
2
+ import {
3
+ expect,
4
+ fixture as _fixture,
5
+ html,
6
+ unsafeStatic,
7
+ aTimeout,
8
+ defineCE,
9
+ waitUntil,
10
+ } from '@open-wc/testing';
11
+ import { cache } from 'lit/directives/cache.js';
12
+ import { LitElement, nothing } from 'lit';
3
13
  import { runOverlayMixinSuite } from '../../overlays/test-suites/OverlayMixin.suite.js';
4
14
  import { isActiveElement } from '../../core/test-helpers/isActiveElement.js';
5
15
  import '../test-helpers/test-router.js';
6
16
  import '@lion/ui/define/lion-dialog.js';
17
+ import '@lion/ui/define/lion-tabs.js';
7
18
 
8
19
  /**
9
20
  * @typedef {import('../src/LionDialog.js').LionDialog} LionDialog
@@ -296,5 +307,107 @@ describe('lion-dialog', () => {
296
307
  await dialogAfterRouteChange._overlayCtrl._showComplete;
297
308
  expect(dialogAfterRouteChange.opened).to.be.true;
298
309
  });
310
+
311
+ it('should close the popup dialog after rendered from cache', async () => {
312
+ /**
313
+ *
314
+ * @param {Event} e
315
+ * @returns
316
+ */
317
+ const closeButtonHandler = e =>
318
+ e.target?.dispatchEvent(new Event('close-overlay', { bubbles: true }));
319
+ const dialog = html` <lion-dialog>
320
+ <button slot="invoker" class="invoker-button">Click me to open dialog</button>
321
+ <div slot="content" class="demo-dialog-content">
322
+ Hello! You can close this dialog here:
323
+ <button class="close-button" @click="${closeButtonHandler}">⨯</button>
324
+ </div>
325
+ </lion-dialog>`;
326
+
327
+ /**
328
+ * Note, inactive tab content is **destroyed** on every tab switch.
329
+ */
330
+ class Wrapper extends LitElement {
331
+ static properties = {
332
+ ...super.properties,
333
+ activeTabIndex: { type: Number },
334
+ };
335
+
336
+ constructor() {
337
+ super();
338
+ this.activeTabIndex = 0;
339
+ }
340
+
341
+ /**
342
+ * @param {number} index
343
+ */
344
+ changeActiveTabIndex(index) {
345
+ this.activeTabIndex = index;
346
+ }
347
+
348
+ render() {
349
+ const changeActiveTabIndexRef = this.changeActiveTabIndex.bind(this);
350
+ return html`
351
+ <lion-tabs>
352
+ <button slot="tab" class="first-button" @click=${() => changeActiveTabIndexRef(0)}>
353
+ First
354
+ </button>
355
+ <p slot="panel">${cache(this.activeTabIndex === 0 ? dialog : nothing)}</p>
356
+ <button slot="tab" class="second-button" @click=${() => changeActiveTabIndexRef(1)}>
357
+ Second
358
+ </button>
359
+ <p slot="panel">Info page with lots of information about us.</p>
360
+ </lion-tabs>
361
+ `;
362
+ }
363
+ }
364
+
365
+ const wrapperFixture = /** @type {(arg: TemplateResult) => Promise<Wrapper>} */ (_fixture);
366
+ const tagString = defineCE(Wrapper);
367
+ const wrapperTag = unsafeStatic(tagString);
368
+ const wrapperElement = /** @type {Wrapper} */ (
369
+ await wrapperFixture(html`<${wrapperTag}></${wrapperTag}>`)
370
+ );
371
+ await wrapperElement.updateComplete;
372
+ const wrapperElementShadowRoot = wrapperElement.shadowRoot;
373
+ /**
374
+ * @returns { HTMLElement | null | undefined }
375
+ */
376
+ const getFirstButton = () => wrapperElementShadowRoot?.querySelector('.first-button');
377
+ /**
378
+ * @returns { HTMLElement | null | undefined }
379
+ */
380
+ const getSecondButton = () => wrapperElementShadowRoot?.querySelector('.second-button');
381
+ /**
382
+ * @returns { HTMLElement | null | undefined }
383
+ */
384
+ const getInvokerButton = () => wrapperElementShadowRoot?.querySelector('.invoker-button');
385
+ /**
386
+ * @returns { HTMLElement | null | undefined }
387
+ */
388
+ const getCloseButton = () => wrapperElementShadowRoot?.querySelector('.close-button');
389
+ /**
390
+ * @returns { Element | null | undefined }
391
+ */
392
+ const getDialog = () =>
393
+ wrapperElementShadowRoot?.querySelector('lion-dialog')?.shadowRoot?.querySelector('dialog');
394
+ // @ts-ignore
395
+ const isDialogVisible = () => getDialog()?.checkVisibility() === true;
396
+ const isDialogRendered = () =>
397
+ !!wrapperElement.shadowRoot?.querySelector('lion-dialog')?.shadowRoot?.childNodes.length;
398
+ getInvokerButton()?.click();
399
+ await waitUntil(isDialogVisible);
400
+ getCloseButton()?.click();
401
+ await waitUntil(() => !isDialogVisible());
402
+ getSecondButton()?.click();
403
+ await waitUntil(() => !isDialogRendered());
404
+ getFirstButton()?.click();
405
+ await waitUntil(isDialogRendered);
406
+ getInvokerButton()?.click();
407
+ await waitUntil(isDialogVisible);
408
+ getCloseButton()?.click();
409
+ await waitUntil(() => !isDialogVisible());
410
+ expect(isDialogVisible()).to.equal(false);
411
+ });
299
412
  });
300
413
  });
@@ -246,16 +246,23 @@ export const OverlayMixinImplementation = superclass =>
246
246
 
247
247
  /** @protected */
248
248
  _setupOverlayCtrl() {
249
- if (this._overlayCtrl) return;
250
-
251
- /** @type {OverlayController} */
252
- this._overlayCtrl = this._defineOverlay({
249
+ if (this.#hasSetup) return;
250
+ const config = {
253
251
  contentNode: this._overlayContentNode,
254
252
  contentWrapperNode: this._overlayContentWrapperNode,
255
253
  invokerNode: this._overlayInvokerNode,
256
254
  referenceNode: this._overlayReferenceNode,
257
255
  backdropNode: this._overlayBackdropNode,
258
- });
256
+ };
257
+
258
+ if (this._overlayCtrl) {
259
+ // when `lit` `cache` attaches node to the DOM, register the controller back in the OverlaysManager
260
+ this._overlayCtrl.updateConfig(config);
261
+ } else {
262
+ /** @type {OverlayController} */
263
+ this._overlayCtrl = this._defineOverlay(config);
264
+ }
265
+
259
266
  this.__syncToOverlayController();
260
267
  this.__setupSyncFromOverlayController();
261
268
  this._setupOpenCloseListeners();
@@ -153,6 +153,8 @@ async function createNestedEscControllers(parentContent) {
153
153
 
154
154
  afterEach(() => {
155
155
  overlays.teardown();
156
+ // clean document.body from the DOM nodes left by previous tests
157
+ document.body.innerHTML = '';
156
158
  });
157
159
 
158
160
  describe('OverlayController', () => {
@@ -533,8 +533,11 @@ export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) {
533
533
 
534
534
  el.switched = false;
535
535
  await el.updateComplete;
536
-
537
536
  expect(setupSpy.callCount).to.equal(1);
537
+
538
+ const elCtrl = /** @type {OverlayEl} */ (el.overlayEl)?._overlayCtrl;
539
+ const isCtrlRegisteredAtOverlaysManager = elCtrl.manager.list.some(ctrl => elCtrl === ctrl);
540
+ expect(isCtrlRegisteredAtOverlaysManager).to.equal(true);
538
541
  });
539
542
 
540
543
  it('correctly removes event listeners when disconnected from dom', async () => {
@@ -146,8 +146,10 @@ export class LionSelectRich extends SlotMixin(ScopedElementsMixin(OverlayMixin(L
146
146
 
147
147
  connectedCallback() {
148
148
  super.connectedCallback();
149
- this._invokerNode.selectedElement =
150
- this.formElements[/** @type {number} */ (this.checkedIndex)];
149
+ this.registrationComplete.then(() => {
150
+ this._invokerNode.selectedElement =
151
+ this.formElements[/** @type {number} */ (this.checkedIndex)];
152
+ });
151
153
 
152
154
  this._invokerNode.hostElement = this;
153
155
 
@@ -6,7 +6,8 @@ import { LionOption } from '@lion/ui/listbox.js';
6
6
  import '@lion/ui/define/lion-select-rich.js';
7
7
  import '@lion/ui/define/lion-listbox.js';
8
8
  import '@lion/ui/define/lion-option.js';
9
- import { LitElement } from 'lit';
9
+ import '@lion/ui/define/lion-tabs.js';
10
+ import { LitElement, nothing } from 'lit';
10
11
  import sinon from 'sinon';
11
12
  import {
12
13
  fixture as _fixture,
@@ -16,7 +17,9 @@ import {
16
17
  defineCE,
17
18
  expect,
18
19
  html,
20
+ waitUntil,
19
21
  } from '@open-wc/testing';
22
+ import { cache } from 'lit/directives/cache.js';
20
23
 
21
24
  import { isActiveElement } from '../../core/test-helpers/isActiveElement.js';
22
25
 
@@ -724,6 +727,378 @@ describe('lion-select-rich', () => {
724
727
  });
725
728
  });
726
729
 
730
+ describe('Render from `lit` `cache`', () => {
731
+ describe('when `lion-option` is set by `.choiceValue` property with and no `checked` attribute', () => {
732
+ it('should display the second option', async () => {
733
+ const colours = [
734
+ {
735
+ label: 'Red',
736
+ value: 'red',
737
+ },
738
+ {
739
+ label: 'Blue',
740
+ value: 'blue',
741
+ },
742
+ ];
743
+
744
+ /**
745
+ * Note, inactive tab content is **destroyed** on every tab switch.
746
+ */
747
+ class Wrapper extends LitElement {
748
+ static properties = {
749
+ ...super.properties,
750
+ activeTabIndex: { type: Number },
751
+ };
752
+
753
+ constructor() {
754
+ super();
755
+ this.activeTabIndex = 0;
756
+ }
757
+
758
+ /**
759
+ * @param {number} index
760
+ */
761
+ changeActiveTabIndex(index) {
762
+ this.activeTabIndex = index;
763
+ }
764
+
765
+ render() {
766
+ const changeActiveTabIndexRef = this.changeActiveTabIndex.bind(this);
767
+ return html`
768
+ <lion-tabs>
769
+ <button slot="tab" class="first-button" @click=${() => changeActiveTabIndexRef(0)}>
770
+ Info
771
+ </button>
772
+ <p slot="panel">
773
+ ${cache(
774
+ this.activeTabIndex === 0
775
+ ? html`<lion-select-rich name="favoriteColor" label="Favorite color">
776
+ ${colours.map(
777
+ colour =>
778
+ html`<lion-option .choiceValue="${colour.value}"
779
+ >${colour.label}</lion-option
780
+ >`,
781
+ )}
782
+ </lion-select-rich>`
783
+ : nothing,
784
+ )}
785
+ </p>
786
+ <button slot="tab" class="second-button" @click=${() => changeActiveTabIndexRef(1)}>
787
+ Work
788
+ </button>
789
+ <p slot="panel">Info page with lots of information about us.</p>
790
+ </lion-tabs>
791
+ `;
792
+ }
793
+ }
794
+
795
+ const wrapperFixture = /** @type {(arg: TemplateResult) => Promise<Wrapper>} */ (_fixture);
796
+ const tagString = defineCE(Wrapper);
797
+ const wrapperTag = unsafeStatic(tagString);
798
+ const wrapperElement = /** @type {Wrapper} */ (
799
+ await wrapperFixture(html`<${wrapperTag}></${wrapperTag}>`)
800
+ );
801
+ await wrapperElement.updateComplete;
802
+ const wrapperElementShadowRoot = wrapperElement.shadowRoot;
803
+ /**
804
+ * @returns { HTMLElement | null | undefined }
805
+ */
806
+ const getFirstButton = () => wrapperElementShadowRoot?.querySelector('.first-button');
807
+ /**
808
+ * @returns { HTMLElement | null | undefined }
809
+ */
810
+ const getSecondButton = () => wrapperElementShadowRoot?.querySelector('.second-button');
811
+ /**
812
+ * @returns { HTMLElement | null | undefined }
813
+ */
814
+ const getInvoker = () => wrapperElementShadowRoot?.querySelector('lion-select-invoker');
815
+ /**
816
+ * @returns { boolean }
817
+ */
818
+ const isSelectRichRendered = () => !!getInvoker()?.shadowRoot?.childNodes.length;
819
+ /**
820
+ * @returns { string | undefined }
821
+ */
822
+ const getSelectedColourLabel = () =>
823
+ getInvoker()?.shadowRoot?.querySelector('#content-wrapper')?.textContent?.trim();
824
+ const getDialog = () =>
825
+ wrapperElementShadowRoot
826
+ ?.querySelector('lion-select-rich')
827
+ ?.shadowRoot?.querySelector('dialog');
828
+ const isDialogVisible = () =>
829
+ // @ts-ignore
830
+ getDialog()?.checkVisibility() === true &&
831
+ getDialog()?.querySelector('#overlay-content-node-wrapper[data-popper-placement]');
832
+ await waitUntil(isSelectRichRendered);
833
+ getInvoker()?.click();
834
+ await waitUntil(isDialogVisible);
835
+ const optionBlue = /** @type { HTMLElement | undefined } */ (
836
+ wrapperElementShadowRoot?.querySelectorAll('lion-option')
837
+ )?.[1];
838
+ optionBlue?.click();
839
+ await waitUntil(() => !isDialogVisible());
840
+ const selectedColourLabelBeforeTabSwitch = getSelectedColourLabel();
841
+ expect(selectedColourLabelBeforeTabSwitch).to.equal('Blue');
842
+ getSecondButton()?.click();
843
+ await waitUntil(() => !isSelectRichRendered());
844
+ getFirstButton()?.click();
845
+ await waitUntil(isSelectRichRendered);
846
+ const selectedColourAfterTabSwitch = getSelectedColourLabel();
847
+ expect(selectedColourAfterTabSwitch).to.equal('Blue');
848
+ });
849
+ });
850
+ describe('when `lion-option` is set by `.choiceValue` property and `checked` attribute', () => {
851
+ it('should display the second option', async () => {
852
+ const colours = [
853
+ {
854
+ label: 'Red',
855
+ value: 'red',
856
+ checked: true,
857
+ },
858
+ {
859
+ label: 'Blue',
860
+ value: 'blue',
861
+ checked: false,
862
+ },
863
+ ];
864
+
865
+ /**
866
+ * Note, inactive tab content is **destroyed** on every tab switch.
867
+ */
868
+ class Wrapper extends LitElement {
869
+ static properties = {
870
+ ...super.properties,
871
+ activeTabIndex: { type: Number },
872
+ };
873
+
874
+ constructor() {
875
+ super();
876
+ this.activeTabIndex = 0;
877
+ }
878
+
879
+ /**
880
+ * @param {number} index
881
+ */
882
+ changeActiveTabIndex(index) {
883
+ this.activeTabIndex = index;
884
+ }
885
+
886
+ render() {
887
+ const changeActiveTabIndexRef = this.changeActiveTabIndex.bind(this);
888
+ return html`
889
+ <lion-tabs>
890
+ <button slot="tab" class="first-button" @click=${() => changeActiveTabIndexRef(0)}>
891
+ Info
892
+ </button>
893
+ <p slot="panel">
894
+ ${cache(
895
+ this.activeTabIndex === 0
896
+ ? html`<lion-select-rich name="favoriteColor" label="Favorite color">
897
+ ${colours.map(
898
+ colour =>
899
+ html`<lion-option
900
+ .choiceValue="${colour.value}"
901
+ checked="${colour.checked || nothing}"
902
+ >${colour.label}</lion-option
903
+ >`,
904
+ )}
905
+ </lion-select-rich>`
906
+ : nothing,
907
+ )}
908
+ </p>
909
+ <button slot="tab" class="second-button" @click=${() => changeActiveTabIndexRef(1)}>
910
+ Work
911
+ </button>
912
+ <p slot="panel">Info page with lots of information about us.</p>
913
+ </lion-tabs>
914
+ `;
915
+ }
916
+ }
917
+
918
+ const wrapperFixture = /** @type {(arg: TemplateResult) => Promise<Wrapper>} */ (_fixture);
919
+ const tagString = defineCE(Wrapper);
920
+ const wrapperTag = unsafeStatic(tagString);
921
+ const wrapperElement = /** @type {Wrapper} */ (
922
+ await wrapperFixture(html`<${wrapperTag}></${wrapperTag}>`)
923
+ );
924
+ await wrapperElement.updateComplete;
925
+ const wrapperElementShadowRoot = wrapperElement.shadowRoot;
926
+ /**
927
+ * @returns { HTMLElement | null | undefined }
928
+ */
929
+ const getFirstButton = () => wrapperElementShadowRoot?.querySelector('.first-button');
930
+ /**
931
+ * @returns { HTMLElement | null | undefined }
932
+ */
933
+ const getSecondButton = () => wrapperElementShadowRoot?.querySelector('.second-button');
934
+ /**
935
+ * @returns { HTMLElement | null | undefined }
936
+ */
937
+ const getInvoker = () => wrapperElementShadowRoot?.querySelector('lion-select-invoker');
938
+ /**
939
+ * @returns { boolean }
940
+ */
941
+ const isSelectRichRendered = () => !!getInvoker()?.shadowRoot?.childNodes.length;
942
+ /**
943
+ * @returns { string | undefined }
944
+ */
945
+ const getSelectedColourLabel = () =>
946
+ getInvoker()?.shadowRoot?.querySelector('#content-wrapper')?.textContent?.trim();
947
+ const getDialog = () =>
948
+ wrapperElementShadowRoot
949
+ ?.querySelector('lion-select-rich')
950
+ ?.shadowRoot?.querySelector('dialog');
951
+ const isDialogVisible = () =>
952
+ // @ts-ignore
953
+ getDialog()?.checkVisibility() === true &&
954
+ getDialog()?.querySelector('#overlay-content-node-wrapper[data-popper-placement]');
955
+ await waitUntil(isSelectRichRendered);
956
+ getInvoker()?.click();
957
+ await waitUntil(isDialogVisible);
958
+ const optionBlue = /** @type { HTMLElement | undefined } */ (
959
+ wrapperElementShadowRoot?.querySelectorAll('lion-option')
960
+ )?.[1];
961
+ optionBlue?.click();
962
+ await waitUntil(() => !isDialogVisible());
963
+ const selectedColourLabelBeforeTabSwitch = getSelectedColourLabel();
964
+ expect(selectedColourLabelBeforeTabSwitch).to.equal('Blue');
965
+ getSecondButton()?.click();
966
+ await waitUntil(() => !isSelectRichRendered());
967
+ getFirstButton()?.click();
968
+ await waitUntil(isSelectRichRendered);
969
+ const selectedColourAfterTabSwitch = getSelectedColourLabel();
970
+ expect(selectedColourAfterTabSwitch).to.equal('Blue');
971
+ });
972
+ });
973
+ describe('when `lion-option` is set by `.modelValue` property', () => {
974
+ it('should display the second option', async () => {
975
+ const colours = [
976
+ {
977
+ label: 'Red',
978
+ value: 'red',
979
+ checked: true,
980
+ },
981
+ {
982
+ label: 'Blue',
983
+ value: 'blue',
984
+ checked: false,
985
+ },
986
+ ];
987
+
988
+ /**
989
+ * Note, inactive tab content is **destroyed** on every tab switch.
990
+ */
991
+ class Wrapper extends LitElement {
992
+ static properties = {
993
+ ...super.properties,
994
+ activeTabIndex: { type: Number },
995
+ };
996
+
997
+ constructor() {
998
+ super();
999
+ this.activeTabIndex = 0;
1000
+ }
1001
+
1002
+ /**
1003
+ * @param {number} index
1004
+ */
1005
+ changeActiveTabIndex(index) {
1006
+ this.activeTabIndex = index;
1007
+ }
1008
+
1009
+ render() {
1010
+ const changeActiveTabIndexRef = this.changeActiveTabIndex.bind(this);
1011
+ return html`
1012
+ <lion-tabs>
1013
+ <button slot="tab" class="first-button" @click=${() => changeActiveTabIndexRef(0)}>
1014
+ Info
1015
+ </button>
1016
+ <p slot="panel">
1017
+ ${cache(
1018
+ this.activeTabIndex === 0
1019
+ ? html`<lion-select-rich name="favoriteColor" label="Favorite color">
1020
+ ${colours.map(
1021
+ colour =>
1022
+ html`<lion-option
1023
+ @model-value-changed=${(/** @type {Event} */ ev) => {
1024
+ const lionOption = /** @type {LionOption} */ (ev.target);
1025
+ // eslint-disable-next-line no-param-reassign
1026
+ colour.checked = lionOption.modelValue.checked;
1027
+ }}
1028
+ .modelValue=${{ value: colour.value, checked: colour.checked }}
1029
+ >${colour.label}</lion-option
1030
+ >`,
1031
+ )}
1032
+ </lion-select-rich>`
1033
+ : nothing,
1034
+ )}
1035
+ </p>
1036
+ <button slot="tab" class="second-button" @click=${() => changeActiveTabIndexRef(1)}>
1037
+ Work
1038
+ </button>
1039
+ <p slot="panel">Info page with lots of information about us.</p>
1040
+ </lion-tabs>
1041
+ `;
1042
+ }
1043
+ }
1044
+
1045
+ const wrapperFixture = /** @type {(arg: TemplateResult) => Promise<Wrapper>} */ (_fixture);
1046
+ const tagString = defineCE(Wrapper);
1047
+ const wrapperTag = unsafeStatic(tagString);
1048
+ const wrapperElement = /** @type {Wrapper} */ (
1049
+ await wrapperFixture(html`<${wrapperTag}></${wrapperTag}>`)
1050
+ );
1051
+ await wrapperElement.updateComplete;
1052
+ const wrapperElementShadowRoot = wrapperElement.shadowRoot;
1053
+ /**
1054
+ * @returns { HTMLElement | null | undefined }
1055
+ */
1056
+ const getFirstButton = () => wrapperElementShadowRoot?.querySelector('.first-button');
1057
+ /**
1058
+ * @returns { HTMLElement | null | undefined }
1059
+ */
1060
+ const getSecondButton = () => wrapperElementShadowRoot?.querySelector('.second-button');
1061
+ /**
1062
+ * @returns { HTMLElement | null | undefined }
1063
+ */
1064
+ const getInvoker = () => wrapperElementShadowRoot?.querySelector('lion-select-invoker');
1065
+ /**
1066
+ * @returns { boolean }
1067
+ */
1068
+ const isSelectRichRendered = () => !!getInvoker()?.shadowRoot?.childNodes.length;
1069
+ /**
1070
+ * @returns { string | undefined }
1071
+ */
1072
+ const getSelectedColourLabel = () =>
1073
+ getInvoker()?.shadowRoot?.querySelector('#content-wrapper')?.textContent?.trim();
1074
+ const getDialog = () =>
1075
+ wrapperElementShadowRoot
1076
+ ?.querySelector('lion-select-rich')
1077
+ ?.shadowRoot?.querySelector('dialog');
1078
+ const isDialogVisible = () =>
1079
+ // @ts-ignore
1080
+ getDialog()?.checkVisibility() === true &&
1081
+ getDialog()?.querySelector('#overlay-content-node-wrapper[data-popper-placement]');
1082
+ await waitUntil(isSelectRichRendered);
1083
+ getInvoker()?.click();
1084
+ await waitUntil(isDialogVisible);
1085
+ const optionBlue = /** @type { HTMLElement | undefined } */ (
1086
+ wrapperElementShadowRoot?.querySelectorAll('lion-option')
1087
+ )?.[1];
1088
+ optionBlue?.click();
1089
+ await waitUntil(() => !isDialogVisible());
1090
+ const selectedColourLabelBeforeTabSwitch = getSelectedColourLabel();
1091
+ expect(selectedColourLabelBeforeTabSwitch).to.equal('Blue');
1092
+ getSecondButton()?.click();
1093
+ await waitUntil(() => !isSelectRichRendered());
1094
+ getFirstButton()?.click();
1095
+ await waitUntil(isSelectRichRendered);
1096
+ const selectedColourAfterTabSwitch = getSelectedColourLabel();
1097
+ expect(selectedColourAfterTabSwitch).to.equal('Blue');
1098
+ });
1099
+ });
1100
+ });
1101
+
727
1102
  describe('Teardown', () => {
728
1103
  it('correctly removes event listeners when disconnected from dom', async () => {
729
1104
  const el = await fixture(html`
@@ -2145,6 +2145,36 @@
2145
2145
  }
2146
2146
  ]
2147
2147
  },
2148
+ {
2149
+ "kind": "javascript-module",
2150
+ "path": "exports/define-helpers/sb-action-logger.js",
2151
+ "declarations": [],
2152
+ "exports": [
2153
+ {
2154
+ "kind": "custom-element-definition",
2155
+ "name": "sb-action-logger",
2156
+ "declaration": {
2157
+ "name": "SbActionLogger",
2158
+ "module": "/exports/helpers.js"
2159
+ }
2160
+ }
2161
+ ]
2162
+ },
2163
+ {
2164
+ "kind": "javascript-module",
2165
+ "path": "exports/define-helpers/sb-locale-switcher.js",
2166
+ "declarations": [],
2167
+ "exports": [
2168
+ {
2169
+ "kind": "custom-element-definition",
2170
+ "name": "sb-locale-switcher",
2171
+ "declaration": {
2172
+ "name": "SbLocaleSwitcher",
2173
+ "module": "/exports/helpers.js"
2174
+ }
2175
+ }
2176
+ ]
2177
+ },
2148
2178
  {
2149
2179
  "kind": "javascript-module",
2150
2180
  "path": "exports/define/lion-accordion.js",
@@ -2850,36 +2880,6 @@
2850
2880
  }
2851
2881
  ]
2852
2882
  },
2853
- {
2854
- "kind": "javascript-module",
2855
- "path": "exports/define-helpers/sb-action-logger.js",
2856
- "declarations": [],
2857
- "exports": [
2858
- {
2859
- "kind": "custom-element-definition",
2860
- "name": "sb-action-logger",
2861
- "declaration": {
2862
- "name": "SbActionLogger",
2863
- "module": "/exports/helpers.js"
2864
- }
2865
- }
2866
- ]
2867
- },
2868
- {
2869
- "kind": "javascript-module",
2870
- "path": "exports/define-helpers/sb-locale-switcher.js",
2871
- "declarations": [],
2872
- "exports": [
2873
- {
2874
- "kind": "custom-element-definition",
2875
- "name": "sb-locale-switcher",
2876
- "declaration": {
2877
- "name": "SbLocaleSwitcher",
2878
- "module": "/exports/helpers.js"
2879
- }
2880
- }
2881
- ]
2882
- },
2883
2883
  {
2884
2884
  "kind": "javascript-module",
2885
2885
  "path": "components/accordion/src/LionAccordion.js",
@@ -1 +1 @@
1
- {"version":3,"file":"lion-dialog.test.d.ts","sourceRoot":"","sources":["../../../../components/dialog/test/lion-dialog.test.js"],"names":[],"mappings":"yBAQa,OAAO,sBAAsB,EAAE,UAAU;6BACzC,OAAO,KAAK,EAAE,cAAc"}
1
+ {"version":3,"file":"lion-dialog.test.d.ts","sourceRoot":"","sources":["../../../../components/dialog/test/lion-dialog.test.js"],"names":[],"mappings":"yBAmBa,OAAO,sBAAsB,EAAE,UAAU;6BACzC,OAAO,KAAK,EAAE,cAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"OverlayMixin.d.ts","sourceRoot":"","sources":["../../../../components/overlays/src/OverlayMixin.js"],"names":[],"mappings":"AAIA;;;;GAIG;AAEH;;;;;;;GAOG;AACH,yCAHU,YAAY,CA8YlB;2BAtZS,OAAO,+BAA+B,EAAE,YAAY;AAuZjE,gGAAoE;4BAzZvD,OAAO,2BAA2B,EAAE,aAAa;kCACjD,OAAO,+BAA+B,EAAE,mBAAmB"}
1
+ {"version":3,"file":"OverlayMixin.d.ts","sourceRoot":"","sources":["../../../../components/overlays/src/OverlayMixin.js"],"names":[],"mappings":"AAIA;;;;GAIG;AAEH;;;;;;;GAOG;AACH,yCAHU,YAAY,CAqZlB;2BA7ZS,OAAO,+BAA+B,EAAE,YAAY;AA8ZjE,gGAAoE;4BAhavD,OAAO,2BAA2B,EAAE,aAAa;kCACjD,OAAO,+BAA+B,EAAE,mBAAmB"}
@@ -1 +1 @@
1
- {"version":3,"file":"OverlayMixin.suite.d.ts","sourceRoot":"","sources":["../../../../components/overlays/test-suites/OverlayMixin.suite.js"],"names":[],"mappings":"AAwDA;;GAEG;AACH,iEAFW;IAAC,SAAS,EAAC,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAC,MAAM,CAAA;CAAC,QA4mBzD;kCAlpBY,OAAO,+BAA+B,EAAE,mBAAmB;wBAC3D,UAAU,GAAG,WAAW,GAAG;IAAC,YAAY,EAAC,iBAAiB,CAAA;CAAC;2BAC3D,OAAO,+BAA+B,EAAE,YAAY;0BACpD,OAAO,+BAA+B,EAAE,WAAW;4BACnD,OAAO,2BAA2B,EAAE,aAAa"}
1
+ {"version":3,"file":"OverlayMixin.suite.d.ts","sourceRoot":"","sources":["../../../../components/overlays/test-suites/OverlayMixin.suite.js"],"names":[],"mappings":"AAwDA;;GAEG;AACH,iEAFW;IAAC,SAAS,EAAC,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAC,MAAM,CAAA;CAAC,QA+mBzD;kCArpBY,OAAO,+BAA+B,EAAE,mBAAmB;wBAC3D,UAAU,GAAG,WAAW,GAAG;IAAC,YAAY,EAAC,iBAAiB,CAAA;CAAC;2BAC3D,OAAO,+BAA+B,EAAE,YAAY;0BACpD,OAAO,+BAA+B,EAAE,WAAW;4BACnD,OAAO,2BAA2B,EAAE,aAAa"}