@lion/ui 0.7.6 → 0.7.8

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 (135) hide show
  1. package/README.md +1 -2
  2. package/components/button/test-suites/LionButton.suite.js +3 -1
  3. package/components/calendar/src/LionCalendar.js +9 -5
  4. package/components/calendar/test/lion-calendar.test.js +33 -6
  5. package/components/combobox/src/LionCombobox.js +33 -9
  6. package/components/combobox/test/lion-combobox.test.js +134 -7
  7. package/components/dialog/test/lion-dialog.test.js +59 -1
  8. package/components/input-datepicker/src/LionInputDatepicker.js +1 -21
  9. package/components/input-datepicker/test/lion-input-datepicker.test.js +30 -3
  10. package/components/input-file/src/FileHandle.js +1 -1
  11. package/components/input-file/src/LionInputFile.js +1 -3
  12. package/components/input-file/test/lion-input-file.test.js +11 -14
  13. package/components/overlays/src/OverlayController.js +13 -7
  14. package/components/overlays/src/OverlayMixin.js +5 -1
  15. package/components/overlays/test/OverlayController.test.js +46 -0
  16. package/components/select-rich/src/LionSelectRich.js +12 -0
  17. package/components/select-rich/test/lion-select-rich.test.js +26 -0
  18. package/custom-elements.json +60 -73
  19. package/dist-types/components/button/test-suites/LionButton.suite.d.ts.map +1 -1
  20. package/dist-types/components/calendar/src/LionCalendar.d.ts +1 -0
  21. package/dist-types/components/calendar/src/LionCalendar.d.ts.map +1 -1
  22. package/dist-types/components/combobox/src/LionCombobox.d.ts +9 -0
  23. package/dist-types/components/combobox/src/LionCombobox.d.ts.map +1 -1
  24. package/dist-types/components/input-datepicker/src/LionInputDatepicker.d.ts +0 -5
  25. package/dist-types/components/input-datepicker/src/LionInputDatepicker.d.ts.map +1 -1
  26. package/dist-types/components/input-file/src/LionInputFile.d.ts.map +1 -1
  27. package/dist-types/components/overlays/src/OverlayController.d.ts.map +1 -1
  28. package/dist-types/components/overlays/src/OverlayMixin.d.ts.map +1 -1
  29. package/dist-types/components/select-rich/src/LionSelectRich.d.ts.map +1 -1
  30. package/dist-types/tsconfig.tsbuildinfo +1 -1
  31. package/docs/components/button/use-cases.md +2 -2
  32. package/docs/components/calendar/use-cases.md +4 -4
  33. package/docs/components/checkbox-group/api-table.md +49 -55
  34. package/docs/components/checkbox-group/overview.md +5 -5
  35. package/docs/components/checkbox-group/use-cases.md +33 -33
  36. package/docs/components/collapsible/overview.md +1 -1
  37. package/docs/components/collapsible/use-cases.md +3 -3
  38. package/docs/components/combobox/api-table.md +84 -89
  39. package/docs/components/combobox/extensions.md +20 -20
  40. package/docs/components/combobox/overview.md +1 -1
  41. package/docs/components/combobox/use-cases.md +6 -6
  42. package/docs/components/dialog/api-table.md +3 -3
  43. package/docs/components/dialog/overview.md +2 -2
  44. package/docs/components/dialog/src/external-dialog.js +32 -0
  45. package/docs/components/dialog/src/slots-dialog-content.js +1 -1
  46. package/docs/components/dialog/src/styled-dialog-content.js +1 -1
  47. package/docs/components/dialog/use-cases.md +49 -3
  48. package/docs/components/drawer/use-cases.md +3 -3
  49. package/docs/components/fieldset/api-table.md +45 -51
  50. package/docs/components/fieldset/overview.md +7 -7
  51. package/docs/components/fieldset/use-cases.md +15 -15
  52. package/docs/components/form/overview.md +7 -7
  53. package/docs/components/form/use-cases.md +4 -4
  54. package/docs/components/icon/use-cases.md +1 -1
  55. package/docs/components/input/overview.md +1 -1
  56. package/docs/components/input/use-cases.md +3 -3
  57. package/docs/components/input-amount/overview.md +3 -3
  58. package/docs/components/input-amount/use-cases.md +8 -8
  59. package/docs/components/input-date/overview.md +3 -3
  60. package/docs/components/input-date/use-cases.md +8 -8
  61. package/docs/components/input-datepicker/api-table.md +1 -3
  62. package/docs/components/input-datepicker/overview.md +5 -5
  63. package/docs/components/input-datepicker/use-cases.md +5 -5
  64. package/docs/components/input-email/overview.md +2 -2
  65. package/docs/components/input-email/use-cases.md +3 -3
  66. package/docs/components/input-file/overview.md +1 -1
  67. package/docs/components/input-iban/overview.md +2 -2
  68. package/docs/components/input-iban/use-cases.md +8 -8
  69. package/docs/components/input-range/overview.md +2 -2
  70. package/docs/components/input-stepper/api-table.md +65 -69
  71. package/docs/components/input-stepper/overview.md +1 -1
  72. package/docs/components/input-tel/overview.md +1 -1
  73. package/docs/components/input-tel/use-cases.md +9 -9
  74. package/docs/components/input-tel-dropdown/api-table.md +70 -73
  75. package/docs/components/input-tel-dropdown/extensions.md +1 -1
  76. package/docs/components/input-tel-dropdown/overview.md +1 -1
  77. package/docs/components/input-tel-dropdown/use-cases.md +5 -5
  78. package/docs/components/listbox/api-table.md +64 -70
  79. package/docs/components/listbox/overview.md +5 -5
  80. package/docs/components/listbox/use-cases.md +61 -61
  81. package/docs/components/pagination/use-cases.md +5 -5
  82. package/docs/components/radio-group/api-table.md +49 -55
  83. package/docs/components/radio-group/overview.md +6 -6
  84. package/docs/components/radio-group/use-cases.md +18 -18
  85. package/docs/components/select/use-cases.md +2 -2
  86. package/docs/components/select-rich/api-table.md +79 -85
  87. package/docs/components/select-rich/overview.md +3 -3
  88. package/docs/components/select-rich/use-cases.md +33 -33
  89. package/docs/components/steps/overview.md +4 -4
  90. package/docs/components/steps/use-cases.md +7 -7
  91. package/docs/components/tabs/examples.md +1 -1
  92. package/docs/components/tabs/use-cases.md +1 -1
  93. package/docs/components/textarea/use-cases.md +3 -3
  94. package/docs/components/tooltip/api-table.md +3 -3
  95. package/docs/components/tooltip/use-cases.md +6 -6
  96. package/docs/fundamentals/index.md +4 -4
  97. package/docs/fundamentals/node-tools/providence-analytics/LocalConfiguration.md +1 -1
  98. package/docs/fundamentals/node-tools/providence-analytics/QueryResult.md +1 -1
  99. package/docs/fundamentals/node-tools/providence-analytics/analyzer.md +1 -1
  100. package/docs/fundamentals/node-tools/providence-analytics/dashboard.md +1 -1
  101. package/docs/fundamentals/node-tools/providence-analytics/overview.md +3 -3
  102. package/docs/fundamentals/node-tools/publish-docs/overview.md +3 -3
  103. package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +2 -2
  104. package/docs/fundamentals/rationales/accessibility.md +1 -1
  105. package/docs/fundamentals/systems/core/SlotMixin.md +1 -1
  106. package/docs/fundamentals/systems/core/overview.md +1 -1
  107. package/docs/fundamentals/systems/form/formatting-and-parsing.md +8 -8
  108. package/docs/fundamentals/systems/form/model-value.md +1 -1
  109. package/docs/fundamentals/systems/form/overview.md +28 -28
  110. package/docs/fundamentals/systems/form/use-cases.md +19 -19
  111. package/docs/fundamentals/systems/form/validate.md +50 -50
  112. package/docs/fundamentals/systems/localize/api-table.md +10 -17
  113. package/docs/fundamentals/systems/localize/overview.md +4 -4
  114. package/docs/fundamentals/systems/localize/use-cases.md +4 -4
  115. package/docs/fundamentals/systems/overlays/_configuration-positioning.md +4 -4
  116. package/docs/fundamentals/systems/overlays/api-table.md +34 -90
  117. package/docs/fundamentals/systems/overlays/assets/umbrella-form.js +9 -9
  118. package/docs/fundamentals/systems/overlays/configuration.md +30 -30
  119. package/docs/fundamentals/systems/overlays/overview.md +6 -6
  120. package/docs/fundamentals/systems/overlays/use-cases.md +30 -30
  121. package/docs/fundamentals/tools/ajax/use-cases.md +20 -20
  122. package/docs/fundamentals/tools/helpers/action-logger.md +3 -3
  123. package/docs/fundamentals/tools/helpers/overview.md +1 -1
  124. package/docs/fundamentals/tools/singleton-manager/example-complex/demo-app.js +2 -2
  125. package/docs/fundamentals/tools/singleton-manager/example-fail/demo-app.js +2 -2
  126. package/docs/fundamentals/tools/singleton-manager/example-success/demo-app.js +2 -2
  127. package/docs/fundamentals/tools/singleton-manager/overview.md +4 -4
  128. package/docs/guides/how-to/create-a-custom-field.md +7 -7
  129. package/docs/guides/how-to/create-a-form.md +4 -4
  130. package/docs/guides/how-to/extend-a-native-input.md +2 -2
  131. package/docs/guides/index.md +8 -8
  132. package/docs/guides/principles/index.md +5 -5
  133. package/docs/guides/principles/scoped-elements.md +1 -1
  134. package/docs/guides/principles/styling.md +1 -1
  135. package/package.json +1 -1
@@ -640,13 +640,14 @@ export class OverlayController extends EventTarget {
640
640
  __setupTeardownAccessibility({ phase }) {
641
641
  if (phase === 'init') {
642
642
  this.__storeOriginalAttrs(this.contentNode, ['role', 'id']);
643
+ const isModal = this.trapsKeyboardFocus;
643
644
 
644
645
  if (this.invokerNode) {
645
- this.__storeOriginalAttrs(this.invokerNode, [
646
- 'aria-expanded',
647
- 'aria-labelledby',
648
- 'aria-describedby',
649
- ]);
646
+ const attributesToStore = ['aria-labelledby', 'aria-describedby'];
647
+ if (!isModal) {
648
+ attributesToStore.push('aria-expanded');
649
+ }
650
+ this.__storeOriginalAttrs(this.invokerNode, attributesToStore);
650
651
  }
651
652
 
652
653
  if (!this.contentNode.id) {
@@ -661,7 +662,7 @@ export class OverlayController extends EventTarget {
661
662
  }
662
663
  this.contentNode.setAttribute('role', 'tooltip');
663
664
  } else {
664
- if (this.invokerNode) {
665
+ if (this.invokerNode && !isModal) {
665
666
  this.invokerNode.setAttribute('aria-expanded', `${this.isShown}`);
666
667
  }
667
668
  if (!this.contentNode.getAttribute('role')) {
@@ -787,6 +788,10 @@ export class OverlayController extends EventTarget {
787
788
  * @protected
788
789
  */
789
790
  _keepBodySize({ phase }) {
791
+ if (!this.preventsScroll) {
792
+ return;
793
+ }
794
+
790
795
  switch (phase) {
791
796
  case 'before-show':
792
797
  this.__bodyClientWidth = document.body.clientWidth;
@@ -1299,7 +1304,8 @@ export class OverlayController extends EventTarget {
1299
1304
  if (phase === 'init' || phase === 'teardown') {
1300
1305
  this.__setupTeardownAccessibility({ phase });
1301
1306
  }
1302
- if (this.invokerNode && !this.isTooltip) {
1307
+ const isModal = this.trapsKeyboardFocus;
1308
+ if (this.invokerNode && !this.isTooltip && !isModal) {
1303
1309
  this.invokerNode.setAttribute('aria-expanded', `${phase === 'show'}`);
1304
1310
  }
1305
1311
  }
@@ -72,7 +72,11 @@ export const OverlayMixinImplementation = superclass =>
72
72
  requestUpdate(name, oldValue, options) {
73
73
  super.requestUpdate(name, oldValue, options);
74
74
  if (name === 'opened' && this.opened !== oldValue) {
75
- this.dispatchEvent(new Event('opened-changed'));
75
+ this.dispatchEvent(
76
+ new CustomEvent('opened-changed', {
77
+ detail: { opened: this.opened },
78
+ }),
79
+ );
76
80
  }
77
81
  }
78
82
 
@@ -1528,6 +1528,23 @@ describe('OverlayController', () => {
1528
1528
  expect(ctrl.invokerNode?.getAttribute('aria-expanded')).to.equal('false');
1529
1529
  });
1530
1530
 
1531
+ it('does not synchronize [aria-expanded] on invoker when the overlay is modal', async () => {
1532
+ const invokerNode = /** @type {HTMLElement} */ (
1533
+ await fixture('<div role="button">invoker</div>')
1534
+ );
1535
+ const ctrl = new OverlayController({
1536
+ ...withLocalTestConfig(),
1537
+ trapsKeyboardFocus: true,
1538
+ handlesAccessibility: true,
1539
+ invokerNode,
1540
+ });
1541
+ expect(ctrl.invokerNode?.getAttribute('aria-expanded')).to.equal(null);
1542
+ await ctrl.show();
1543
+ expect(ctrl.invokerNode?.getAttribute('aria-expanded')).to.equal(null);
1544
+ await ctrl.hide();
1545
+ expect(ctrl.invokerNode?.getAttribute('aria-expanded')).to.equal(null);
1546
+ });
1547
+
1531
1548
  it('creates unique id for content', async () => {
1532
1549
  const ctrl = new OverlayController({
1533
1550
  ...withLocalTestConfig(),
@@ -1764,4 +1781,33 @@ describe('OverlayController', () => {
1764
1781
  );
1765
1782
  });
1766
1783
  });
1784
+
1785
+ describe('run _keepBodySize only with scroll prevention', () => {
1786
+ /**
1787
+ * @type {OverlayController}
1788
+ */
1789
+ const overlayControllerNoPrevent = new OverlayController({
1790
+ ...withLocalTestConfig(),
1791
+ preventsScroll: false,
1792
+ });
1793
+
1794
+ const overlayControllerPreventsScroll = new OverlayController({
1795
+ ...withLocalTestConfig(),
1796
+ preventsScroll: true,
1797
+ });
1798
+
1799
+ it('should not run with scroll prevention', async () => {
1800
+ await overlayControllerNoPrevent.show();
1801
+
1802
+ expect(overlayControllerNoPrevent.__bodyMarginRightInline).to.equal(undefined);
1803
+ expect(overlayControllerNoPrevent.__bodyMarginRight).to.equal(undefined);
1804
+ });
1805
+
1806
+ it('should run with scroll prevention', async () => {
1807
+ await overlayControllerPreventsScroll.show();
1808
+
1809
+ expect(overlayControllerPreventsScroll.__bodyMarginRightInline).to.not.equal(undefined);
1810
+ expect(overlayControllerPreventsScroll.__bodyMarginRight).to.not.equal(undefined);
1811
+ });
1812
+ });
1767
1813
  });
@@ -196,6 +196,18 @@ export class LionSelectRich extends SlotMixin(ScopedElementsMixin(OverlayMixin(L
196
196
  }
197
197
  }
198
198
 
199
+ if (changedProperties.has('singleOption')) {
200
+ if (this.singleOption) {
201
+ this._invokerNode.removeAttribute('role');
202
+ this._invokerNode.removeAttribute('aria-haspopup');
203
+ this._invokerNode.removeAttribute('aria-expanded');
204
+ } else {
205
+ this._invokerNode.setAttribute('role', 'button');
206
+ this._invokerNode.setAttribute('aria-haspopup', 'listbox');
207
+ this._invokerNode.setAttribute('aria-expanded', `${this.opened}`);
208
+ }
209
+ }
210
+
199
211
  if (this._inputNode && this._invokerNode) {
200
212
  if (changedProperties.has('_ariaLabelledNodes')) {
201
213
  this._invokerNode.setAttribute(
@@ -148,6 +148,32 @@ describe('lion-select-rich', () => {
148
148
  expect(_invokerNode.hasAttribute('single-option')).to.be.true;
149
149
  });
150
150
 
151
+ it('sets and removes the button role and aria attributes on change of singleOption', async () => {
152
+ const el = await fixture(html`
153
+ <lion-select-rich>
154
+ <lion-option .choiceValue=${10}>Item 1</lion-option>
155
+ <lion-option .choiceValue=${20}>Item 2</lion-option>
156
+ </lion-select-rich>
157
+ `);
158
+ const { _invokerNode } = getSelectRichMembers(el);
159
+
160
+ expect(_invokerNode.hasAttribute('role')).to.be.true;
161
+ expect(_invokerNode.hasAttribute('aria-haspopup')).to.be.true;
162
+ expect(_invokerNode.hasAttribute('aria-expanded')).to.be.true;
163
+
164
+ el.singleOption = true;
165
+ await el.updateComplete;
166
+ expect(_invokerNode.hasAttribute('role')).to.be.false;
167
+ expect(_invokerNode.hasAttribute('aria-haspopup')).to.be.false;
168
+ expect(_invokerNode.hasAttribute('aria-expanded')).to.be.false;
169
+
170
+ el.singleOption = false;
171
+ await el.updateComplete;
172
+ expect(_invokerNode.hasAttribute('role')).to.be.true;
173
+ expect(_invokerNode.hasAttribute('aria-haspopup')).to.be.true;
174
+ expect(_invokerNode.hasAttribute('aria-expanded')).to.be.true;
175
+ });
176
+
151
177
  it('updates the invoker when the selected element is the same but the modelValue was updated asynchronously', async () => {
152
178
  const tagString = defineCE(
153
179
  class LionCustomOption extends LionOption {