@lion/ui 0.18.0-menu-system.5 → 0.18.0

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 (242) hide show
  1. package/collapsible.js +0 -1
  2. package/components/button/src/LionButton.js +0 -4
  3. package/components/button/test-suites/LionButton.suite.js +0 -1
  4. package/components/calendar/src/LionCalendar.js +1 -3
  5. package/components/combobox/test/lion-combobox.test.js +0 -1
  6. package/components/form-core/src/form-group/FormGroupMixin.js +0 -7
  7. package/components/form-core/src/registration/FormRegistrarMixin.js +0 -11
  8. package/components/form-core/test/FormControlMixin.test.js +0 -1
  9. package/components/form-core/test/validate/Validator.test.js +0 -2
  10. package/components/form-core/test-suites/ValidateMixin.suite.js +0 -2
  11. package/components/form-core/test-suites/ValidateMixinFeedbackPart.suite.js +0 -1
  12. package/components/input-datepicker/src/localizeNamespaceLoader.js +0 -1
  13. package/components/input-datepicker/test/lion-input-datepicker.test.js +6 -5
  14. package/components/listbox/test-suites/ListboxMixin.suite.js +1 -7
  15. package/components/localize/src/date/utils/normalizeIntlDate.js +2 -3
  16. package/components/localize/test/date/formatDate.test.js +2 -3
  17. package/components/overlays/src/OverlayController.js +110 -278
  18. package/components/overlays/src/OverlayMixin.js +11 -58
  19. package/components/overlays/src/OverlaysManager.js +2 -2
  20. package/components/overlays/src/configurations/withDropdownConfig.js +2 -22
  21. package/components/overlays/src/configurations/withPopoverConfig.js +32 -0
  22. package/components/overlays/src/utils/adopt-styles.js +5 -4
  23. package/components/overlays/src/utils/get-focusable-elements.js +0 -4
  24. package/components/overlays/src/utils/is-equal-config.js +6 -10
  25. package/components/overlays/test/OverlayController.test.js +21 -128
  26. package/components/overlays/test/utils-tests/is-equal-config.test.js +1 -1
  27. package/components/overlays/test-suites/OverlayMixin.suite.js +8 -8
  28. package/components/overlays/types/ArrowMixinTypes.ts +1 -3
  29. package/components/overlays/types/OverlayConfig.ts +5 -20
  30. package/components/select-rich/test/lion-select-rich.test.js +0 -3
  31. package/components/switch/src/LionSwitchButton.js +8 -3
  32. package/components/switch/test/lion-switch-button.test.js +38 -0
  33. package/custom-elements.json +17566 -30468
  34. package/dist-types/components/button/src/LionButton.d.ts +0 -1
  35. package/dist-types/components/button/src/LionButton.d.ts.map +1 -1
  36. package/dist-types/components/button/test-suites/LionButton.suite.d.ts.map +1 -1
  37. package/dist-types/components/calendar/src/LionCalendar.d.ts.map +1 -1
  38. package/dist-types/components/dialog/src/LionDialog.d.ts +1 -5
  39. package/dist-types/components/dialog/src/LionDialog.d.ts.map +1 -1
  40. package/dist-types/components/form-core/src/form-group/FormGroupMixin.d.ts.map +1 -1
  41. package/dist-types/components/form-core/src/registration/FormRegistrarMixin.d.ts.map +1 -1
  42. package/dist-types/components/form-core/test-suites/ValidateMixin.suite.d.ts.map +1 -1
  43. package/dist-types/components/form-core/test-suites/ValidateMixinFeedbackPart.suite.d.ts.map +1 -1
  44. package/dist-types/components/input-datepicker/src/localizeNamespaceLoader.d.ts.map +1 -1
  45. package/dist-types/components/listbox/test-suites/ListboxMixin.suite.d.ts.map +1 -1
  46. package/dist-types/components/localize/src/date/utils/normalizeIntlDate.d.ts.map +1 -1
  47. package/dist-types/components/overlays/src/OverlayController.d.ts +12 -24
  48. package/dist-types/components/overlays/src/OverlayController.d.ts.map +1 -1
  49. package/dist-types/components/overlays/src/OverlayMixin.d.ts.map +1 -1
  50. package/dist-types/components/overlays/src/configurations/withDropdownConfig.d.ts +0 -1
  51. package/dist-types/components/overlays/src/configurations/withDropdownConfig.d.ts.map +1 -1
  52. package/dist-types/components/overlays/src/configurations/withPopoverConfig.d.ts +6 -0
  53. package/dist-types/components/overlays/src/configurations/withPopoverConfig.d.ts.map +1 -0
  54. package/dist-types/components/overlays/src/utils/get-focusable-elements.d.ts.map +1 -1
  55. package/dist-types/components/overlays/src/utils/is-equal-config.d.ts.map +1 -1
  56. package/dist-types/components/overlays/types/ArrowMixinTypes.d.ts.map +1 -1
  57. package/dist-types/components/overlays/types/OverlayConfig.d.ts +2 -12
  58. package/dist-types/components/overlays/types/OverlayConfig.d.ts.map +1 -1
  59. package/dist-types/components/select-rich/src/LionSelectRich.d.ts +2 -10
  60. package/dist-types/components/select-rich/src/LionSelectRich.d.ts.map +1 -1
  61. package/dist-types/components/switch/src/LionSwitchButton.d.ts +6 -0
  62. package/dist-types/components/switch/src/LionSwitchButton.d.ts.map +1 -1
  63. package/dist-types/exports/overlays.d.ts +1 -3
  64. package/dist-types/exports/overlays.d.ts.map +1 -1
  65. package/dist-types/tsconfig.tsbuildinfo +1 -1
  66. package/docs/components/checkbox-group/overview.md +2 -2
  67. package/docs/components/collapsible/overview.md +1 -1
  68. package/docs/components/combobox/api-table.md +8 -21
  69. package/docs/components/combobox/overview.md +1 -1
  70. package/docs/components/combobox/use-cases.md +1 -1
  71. package/docs/components/dialog/api-table.md +6 -31
  72. package/docs/components/dialog/overview.md +1 -1
  73. package/docs/components/fieldset/overview.md +5 -5
  74. package/docs/components/form/overview.md +3 -3
  75. package/docs/components/form/use-cases.md +2 -2
  76. package/docs/components/icon/use-cases.md +1 -1
  77. package/docs/components/input/overview.md +1 -1
  78. package/docs/components/input-amount/overview.md +3 -3
  79. package/docs/components/input-date/overview.md +3 -3
  80. package/docs/components/input-datepicker/api-table.md +4 -21
  81. package/docs/components/input-datepicker/overview.md +5 -5
  82. package/docs/components/input-email/overview.md +2 -2
  83. package/docs/components/input-file/overview.md +1 -1
  84. package/docs/components/input-iban/overview.md +2 -2
  85. package/docs/components/input-range/overview.md +2 -2
  86. package/docs/components/input-stepper/overview.md +1 -1
  87. package/docs/components/input-tel/overview.md +1 -1
  88. package/docs/components/input-tel/use-cases.md +6 -6
  89. package/docs/components/input-tel-dropdown/overview.md +1 -1
  90. package/docs/components/listbox/use-cases.md +1 -1
  91. package/docs/components/radio-group/overview.md +3 -3
  92. package/docs/components/select/use-cases.md +1 -1
  93. package/docs/components/select-rich/api-table.md +5 -21
  94. package/docs/components/select-rich/use-cases.md +2 -2
  95. package/docs/components/switch/api-table.md +2 -0
  96. package/docs/components/tabs/examples.md +1 -1
  97. package/docs/components/tooltip/api-table.md +11 -36
  98. package/docs/fundamentals/index.md +4 -4
  99. package/docs/fundamentals/node-tools/publish-docs/overview.md +3 -3
  100. package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +2 -2
  101. package/docs/fundamentals/rationales/accessibility.md +1 -1
  102. package/docs/fundamentals/systems/core/SlotMixin.md +1 -1
  103. package/docs/fundamentals/systems/core/overview.md +1 -1
  104. package/docs/fundamentals/systems/form/formatting-and-parsing.md +4 -4
  105. package/docs/fundamentals/systems/form/model-value.md +1 -1
  106. package/docs/fundamentals/systems/form/overview.md +28 -28
  107. package/docs/fundamentals/systems/form/validate.md +2 -2
  108. package/docs/fundamentals/systems/localize/overview.md +4 -4
  109. package/docs/fundamentals/systems/overlays/api-table.md +34 -36
  110. package/docs/fundamentals/systems/overlays/configuration.md +2 -2
  111. package/docs/fundamentals/systems/overlays/overview.md +5 -5
  112. package/docs/fundamentals/systems/overlays/use-cases.md +2 -2
  113. package/docs/fundamentals/tools/helpers/overview.md +1 -1
  114. package/docs/fundamentals/tools/singleton-manager/overview.md +4 -4
  115. package/docs/guides/how-to/create-a-custom-field.md +5 -5
  116. package/docs/guides/how-to/create-a-form.md +4 -4
  117. package/docs/guides/how-to/extend-a-native-input.md +2 -2
  118. package/docs/guides/how-to/index.md +1 -1
  119. package/docs/guides/index.md +8 -8
  120. package/docs/guides/principles/index.md +5 -5
  121. package/docs/guides/principles/styling.md +1 -1
  122. package/exports/collapsible.js +0 -1
  123. package/exports/overlays.js +1 -6
  124. package/overlays.js +1 -6
  125. package/package.json +1 -1
  126. package/components/collapsible/src/DisclosureMixin.js +0 -313
  127. package/components/collapsible/test-suites/DisclosureMixin.suite.js +0 -30
  128. package/components/collapsible/types/DisclosureMixinTypes.ts +0 -48
  129. package/components/menu/CHANGELOG.md +0 -37
  130. package/components/menu/README.md +0 -335
  131. package/components/menu/index.js +0 -2
  132. package/components/menu/lion-menu-overlay.js +0 -3
  133. package/components/menu/lion-menu.js +0 -3
  134. package/components/menu/lion-spinbutton.js +0 -3
  135. package/components/menu/lion-toolbar.js +0 -3
  136. package/components/menu/lion-tree.js +0 -3
  137. package/components/menu/package.json +0 -46
  138. package/components/menu/requirements.temp.md +0 -12
  139. package/components/menu/src/InteractiveListMixin.js +0 -838
  140. package/components/menu/src/LionMenu.js +0 -250
  141. package/components/menu/src/LionMenuHybrid.js +0 -46
  142. package/components/menu/src/LionMenuOverlay.js +0 -155
  143. package/components/menu/src/LionSpinbutton.js +0 -213
  144. package/components/menu/src/LionToolbar.js +0 -94
  145. package/components/menu/src/LionTree.js +0 -52
  146. package/components/menu/src/MoreButtonMenuMixin.js +0 -287
  147. package/components/menu/src/MultiLevelListMixin.js +0 -274
  148. package/components/menu/src/utils/isInView.js +0 -26
  149. package/components/menu/src/utils/listItemInteractions.js +0 -123
  150. package/components/menu/src/utils/uuid.js +0 -3
  151. package/components/menu/test/lion-menu.test.js +0 -4
  152. package/components/menu/test-suites/InteractiveListMixin.suite.js +0 -304
  153. package/components/menu/types/InteractiveListMixinTypes.d.ts +0 -82
  154. package/components/navigation-bar/README.md +0 -1
  155. package/components/navigation-bar/src/LionNavigationBar.js +0 -439
  156. package/components/navigation-bar/src/types.js +0 -41
  157. package/components/overlays/NEXT.md +0 -49
  158. package/dist-types/components/collapsible/src/DisclosureMixin.d.ts +0 -3
  159. package/dist-types/components/collapsible/src/DisclosureMixin.d.ts.map +0 -1
  160. package/dist-types/components/collapsible/test-suites/DisclosureMixin.suite.d.ts +0 -2
  161. package/dist-types/components/collapsible/test-suites/DisclosureMixin.suite.d.ts.map +0 -1
  162. package/dist-types/components/collapsible/types/DisclosureMixinTypes.d.ts +0 -24
  163. package/dist-types/components/collapsible/types/DisclosureMixinTypes.d.ts.map +0 -1
  164. package/dist-types/components/menu/index.d.ts +0 -3
  165. package/dist-types/components/menu/index.d.ts.map +0 -1
  166. package/dist-types/components/menu/lion-menu-overlay.d.ts +0 -2
  167. package/dist-types/components/menu/lion-menu-overlay.d.ts.map +0 -1
  168. package/dist-types/components/menu/lion-menu.d.ts +0 -2
  169. package/dist-types/components/menu/lion-menu.d.ts.map +0 -1
  170. package/dist-types/components/menu/lion-spinbutton.d.ts +0 -2
  171. package/dist-types/components/menu/lion-spinbutton.d.ts.map +0 -1
  172. package/dist-types/components/menu/lion-toolbar.d.ts +0 -2
  173. package/dist-types/components/menu/lion-toolbar.d.ts.map +0 -1
  174. package/dist-types/components/menu/lion-tree.d.ts +0 -2
  175. package/dist-types/components/menu/lion-tree.d.ts.map +0 -1
  176. package/dist-types/components/menu/src/InteractiveListMixin.d.ts +0 -617
  177. package/dist-types/components/menu/src/InteractiveListMixin.d.ts.map +0 -1
  178. package/dist-types/components/menu/src/LionMenu.d.ts +0 -565
  179. package/dist-types/components/menu/src/LionMenu.d.ts.map +0 -1
  180. package/dist-types/components/menu/src/LionMenuHybrid.d.ts +0 -19
  181. package/dist-types/components/menu/src/LionMenuHybrid.d.ts.map +0 -1
  182. package/dist-types/components/menu/src/LionMenuOverlay.d.ts +0 -1013
  183. package/dist-types/components/menu/src/LionMenuOverlay.d.ts.map +0 -1
  184. package/dist-types/components/menu/src/LionSpinbutton.d.ts +0 -58
  185. package/dist-types/components/menu/src/LionSpinbutton.d.ts.map +0 -1
  186. package/dist-types/components/menu/src/LionToolbar.d.ts +0 -8
  187. package/dist-types/components/menu/src/LionToolbar.d.ts.map +0 -1
  188. package/dist-types/components/menu/src/LionTree.d.ts +0 -447
  189. package/dist-types/components/menu/src/LionTree.d.ts.map +0 -1
  190. package/dist-types/components/menu/src/MoreButtonMenuMixin.d.ts +0 -40
  191. package/dist-types/components/menu/src/MoreButtonMenuMixin.d.ts.map +0 -1
  192. package/dist-types/components/menu/src/MultiLevelListMixin.d.ts +0 -495
  193. package/dist-types/components/menu/src/MultiLevelListMixin.d.ts.map +0 -1
  194. package/dist-types/components/menu/src/utils/isInView.d.ts +0 -9
  195. package/dist-types/components/menu/src/utils/isInView.d.ts.map +0 -1
  196. package/dist-types/components/menu/src/utils/listItemInteractions.d.ts +0 -48
  197. package/dist-types/components/menu/src/utils/listItemInteractions.d.ts.map +0 -1
  198. package/dist-types/components/menu/src/utils/uuid.d.ts +0 -2
  199. package/dist-types/components/menu/src/utils/uuid.d.ts.map +0 -1
  200. package/dist-types/components/menu/test/lion-menu.test.d.ts +0 -2
  201. package/dist-types/components/menu/test/lion-menu.test.d.ts.map +0 -1
  202. package/dist-types/components/menu/test-suites/InteractiveListMixin.suite.d.ts +0 -14
  203. package/dist-types/components/menu/test-suites/InteractiveListMixin.suite.d.ts.map +0 -1
  204. package/dist-types/components/navigation-bar/src/LionNavigationBar.d.ts +0 -238
  205. package/dist-types/components/navigation-bar/src/LionNavigationBar.d.ts.map +0 -1
  206. package/dist-types/components/navigation-bar/src/types.d.ts +0 -85
  207. package/dist-types/components/navigation-bar/src/types.d.ts.map +0 -1
  208. package/dist-types/exports/define/lion-item.d.ts +0 -2
  209. package/dist-types/exports/define/lion-item.d.ts.map +0 -1
  210. package/dist-types/exports/define/lion-menu-overlay.d.ts +0 -2
  211. package/dist-types/exports/define/lion-menu-overlay.d.ts.map +0 -1
  212. package/dist-types/exports/define/lion-menu.d.ts +0 -2
  213. package/dist-types/exports/define/lion-menu.d.ts.map +0 -1
  214. package/dist-types/exports/define/lion-navigation-bar.d.ts +0 -2
  215. package/dist-types/exports/define/lion-navigation-bar.d.ts.map +0 -1
  216. package/dist-types/exports/define/lion-toolbar.d.ts +0 -2
  217. package/dist-types/exports/define/lion-toolbar.d.ts.map +0 -1
  218. package/dist-types/exports/define/lion-tree.d.ts +0 -2
  219. package/dist-types/exports/define/lion-tree.d.ts.map +0 -1
  220. package/dist-types/exports/menu-test-suites.d.ts +0 -2
  221. package/dist-types/exports/menu-test-suites.d.ts.map +0 -1
  222. package/dist-types/exports/menu.d.ts +0 -7
  223. package/dist-types/exports/menu.d.ts.map +0 -1
  224. package/dist-types/exports/navigation-bar.d.ts +0 -2
  225. package/dist-types/exports/navigation-bar.d.ts.map +0 -1
  226. package/docs/components/menu/api-table.md +0 -455
  227. package/docs/components/menu/applyMenuDemoStyles.js +0 -173
  228. package/docs/components/menu/extensions.md +0 -262
  229. package/docs/components/menu/index.md +0 -13
  230. package/docs/components/menu/overview.md +0 -422
  231. package/exports/define/lion-item.js +0 -3
  232. package/exports/define/lion-menu-overlay.js +0 -3
  233. package/exports/define/lion-menu.js +0 -3
  234. package/exports/define/lion-navigation-bar.js +0 -3
  235. package/exports/define/lion-toolbar.js +0 -3
  236. package/exports/define/lion-tree.js +0 -3
  237. package/exports/menu-test-suites.js +0 -2
  238. package/exports/menu.js +0 -7
  239. package/exports/navigation-bar.js +0 -1
  240. package/menu-test-suites.js +0 -2
  241. package/menu.js +0 -7
  242. package/navigation-bar.js +0 -1
@@ -1,26 +0,0 @@
1
- /**
2
- * Determines whether element is visible within container
3
- *
4
- * @param {HTMLElement} container
5
- * @param {HTMLElement} element
6
- * @param {Boolean} [partial]
7
- */
8
- export function isInView(container, element, partial = false) {
9
- const cTop = container.scrollTop;
10
- const cBottom = cTop + container.clientHeight;
11
- const eTop = element.offsetTop;
12
- const eBottom = eTop + element.clientHeight;
13
- const isTotal = eTop >= cTop && eBottom <= cBottom;
14
- let isPartial;
15
-
16
- if (partial === true) {
17
- isPartial = (eTop < cTop && eBottom > cTop) || (eBottom > cBottom && eTop < cBottom);
18
- } else if (typeof partial === 'number') {
19
- if (eTop < cTop && eBottom > cTop) {
20
- isPartial = ((eBottom - cTop) * 100) / element.clientHeight > partial;
21
- } else if (eBottom > cBottom && eTop < cBottom) {
22
- isPartial = ((cBottom - eTop) * 100) / element.clientHeight > partial;
23
- }
24
- }
25
- return isTotal || isPartial;
26
- }
@@ -1,123 +0,0 @@
1
- /**
2
- * Set of universal interactive list item state methods that are both compatible with
3
- * 'smart' (LionOption) and 'regular' items
4
- */
5
-
6
- /**
7
- * @typedef {import('@lion/ui/checkbox-group.js').LionCheckboxIndeterminate} LionCheckboxIndeterminate
8
- */
9
-
10
- /**
11
- * @param {HTMLElement} item
12
- */
13
- export function isDisabled(item) {
14
- return item.hasAttribute('disabled') || item.getAttribute('aria-disabled') === 'true';
15
- }
16
-
17
- /**
18
- * @param {HTMLElement} item
19
- */
20
- export function setDisabled(item, unset = false) {
21
- if (unset) {
22
- item.removeAttribute('disabled');
23
- item.setAttribute('aria-disabled', 'false');
24
- } else {
25
- item.setAttribute('disabled', '');
26
- item.setAttribute('aria-disabled', 'true');
27
- }
28
- }
29
-
30
- /**
31
- * @param {HTMLElement} item
32
- */
33
- export function toggleDisabled(item) {
34
- setDisabled(item, isDisabled(item));
35
- }
36
-
37
- /**
38
- * @param {HTMLElement} item
39
- */
40
- export function isChecked(item) {
41
- return item.hasAttribute('checked');
42
- }
43
-
44
- /**
45
- * @param {HTMLElement} item
46
- * @param {Object} [options]
47
- * @param {boolean} [options.unset=false]
48
- * @param {'page'|'mixed'} [options.text] - optional text to set for aria-checked/aria-selected/aria-current (e.g. "mixed")
49
- */
50
- export function setChecked(item, unset = false) {
51
- const role = item.getAttribute('role');
52
- let ariaAttr = 'current';
53
- if (role?.endsWith('checkbox') || role?.endsWith('radio')) {
54
- ariaAttr = 'checked';
55
- } else if (role === 'option' || role === 'treeitem') {
56
- ariaAttr = 'selected';
57
- }
58
- let text;
59
- if (/** @type {HTMLAnchorElement} */ (item).href) {
60
- text = 'page';
61
- }
62
- if (/** @type {LionCheckboxIndeterminate} */ (item).mixedState) {
63
- text = 'mixed';
64
- }
65
- if (!unset) {
66
- item.setAttribute('checked', '');
67
- item.setAttribute(`aria-${ariaAttr}`, text || 'true');
68
- } else {
69
- item.removeAttribute('checked');
70
- item.setAttribute(`aria-${ariaAttr}`, 'false');
71
- }
72
- }
73
-
74
- /**
75
- * @param {HTMLElement} item
76
- */
77
- export function toggleChecked(item) {
78
- setChecked(item, !isChecked(item));
79
- }
80
-
81
- /**
82
- * @param {HTMLElement} item
83
- */
84
- export function isActive(item) {
85
- return item.hasAttribute('active');
86
- }
87
-
88
- /**
89
- * @param {HTMLElement} item
90
- */
91
- export function setActive(item, unset = false) {
92
- if (unset) {
93
- item.removeAttribute('active');
94
- } else {
95
- item.setAttribute('active', '');
96
- }
97
- }
98
-
99
- /**
100
- * @param {HTMLElement} item
101
- */
102
- function getDirectTextContent(item) {
103
- return Array.from(item.childNodes)
104
- .filter(n => n.nodeName === '#text')
105
- .map(n => n.textContent)
106
- .join('')
107
- .trim();
108
- }
109
-
110
- /**
111
- * @param {HTMLElement} item
112
- */
113
- export function getValue(item) {
114
- return (
115
- // @ts-ignore - choiceValue is a custom property
116
- item.choiceValue ||
117
- // @ts-ignore - value might not exist on all HTMLElements
118
- item.value ||
119
- item.getAttribute('value') ||
120
- item.getAttribute('data-value') ||
121
- getDirectTextContent(item)
122
- );
123
- }
@@ -1,3 +0,0 @@
1
- export function uuid() {
2
- return Math.random().toString(36).substr(2, 10);
3
- }
@@ -1,4 +0,0 @@
1
- import { runInteractiveListMixinSuite } from '../test-suites/InteractiveListMixin.suite.js';
2
- import '@lion/ui/define/lion-menu.js';
3
-
4
- runInteractiveListMixinSuite({ tagString: 'lion-menu' });
@@ -1,304 +0,0 @@
1
- import { LitElement } from 'lit';
2
- import { expect, html, fixture as _fixture, unsafeStatic, defineCE } from '@open-wc/testing';
3
- import { InteractiveListMixin } from '../src/InteractiveListMixin.js';
4
-
5
- class InteractiveListClass extends InteractiveListMixin(LitElement) {}
6
-
7
- /**
8
- * @typedef {import('../types/InteractiveListMixinTypes.js').InteractiveListItemRole} InteractiveListItemRole
9
- */
10
-
11
- /** @type {InteractiveListItemRole[]} */
12
- const supportedRoles = [
13
- 'menuitem',
14
- 'menuitemcheckbox',
15
- 'menuitemradio',
16
- 'option',
17
- 'treeitem',
18
- 'radio',
19
- 'checkbox',
20
- ];
21
-
22
- /**
23
- * @typedef {import('../src/LionMenu.js').LionMenu} LionMenu
24
- * @typedef {import('lit').TemplateResult} TemplateResult
25
- *
26
- * * @typedef {Object} TestConfig
27
- * @property {string} tagString
28
- */
29
-
30
- const fixture = /** @type {(arg: TemplateResult) => Promise<LionMenu>} */ (_fixture);
31
-
32
- /**
33
- * @param {TestConfig} [customConfig]
34
- */
35
- export function runInteractiveListMixinSuite(customConfig) {
36
- const cfg = {
37
- tagString: customConfig?.tagString || defineCE(InteractiveListClass),
38
- };
39
-
40
- const { tagString } = cfg;
41
- const tag = unsafeStatic(tagString);
42
-
43
- describe('InteractiveListMixin', () => {
44
- it(`supports items with role="${supportedRoles.join('|')}"`, async () => {
45
- const el = await fixture(html`
46
- <${tag} name="foo">
47
- ${supportedRoles.map(role => html` <div role="${role}"></div> `)}
48
- </${tag}>
49
- `);
50
- // @ts-ignore - test element with InteractiveListMixin properties
51
- expect(el.listItems.length).to.equal(supportedRoles.length);
52
- supportedRoles.forEach((role, i) => {
53
- // @ts-ignore - test element with InteractiveListMixin properties
54
- expect(el.listItems[i].getAttribute('role')).to.equal(role);
55
- });
56
- });
57
-
58
- it('moves elements to a private [slot=list] for optimal DX and a11y', async () => {
59
- const el = await fixture(html`
60
- <${tag} name="foo">
61
- <div role="menuitem" id="item1">Item 1</div>
62
- <div role="menuitem" id="item2">Item 2</div>
63
- </${tag}>
64
- `);
65
- // @ts-ignore - test element with InteractiveListMixin properties
66
- const listSlotNode = Array.from(el.children).find(c => c.slot === 'list');
67
- // @ts-ignore - accessing children property
68
- const listItemEls = Array.from(listSlotNode.children);
69
- // @ts-ignore - test element with InteractiveListMixin properties
70
- expect(listItemEls.includes(el.listItems[0])).to.be.true;
71
- // @ts-ignore - test element with InteractiveListMixin properties
72
- expect(listItemEls.includes(el.listItems[1])).to.be.true;
73
- });
74
-
75
- it('inherits from DisclosureMixin', async () => {});
76
-
77
- describe('Active mode', async () => {
78
- it('supports "activedescendant" pattern', async () => {
79
- const el = await fixture(html`
80
- <${tag} name="foo" ._activeMode="${'activedescendant'}">
81
- <div role="menuitem" id="item1">Item 1</div>
82
- <div role="menuitem" id="item2">Item 2</div>
83
- </${tag}>
84
- `);
85
- // @ts-ignore - test element with InteractiveListMixin properties
86
- el.checkedIndex = 0;
87
- // @ts-ignore - test element with InteractiveListMixin properties
88
- const listSlotNode = Array.from(el.children).find(c => c.slot === 'list');
89
-
90
- // @ts-ignore - test element with InteractiveListMixin properties
91
- // @ts-ignore - test element with InteractiveListMixin properties
92
- expect(el.listItems[0].hasAttribute('id')).to.be.true;
93
- // @ts-ignore - test element with InteractiveListMixin properties
94
- expect(el.listItems[1].hasAttribute('id')).to.be.true;
95
- expect(listSlotNode?.hasAttribute('aria-activedescendant')).to.be.false;
96
- // @ts-ignore - test element with InteractiveListMixin properties
97
- el.activeIndex = 1;
98
- expect(listSlotNode?.hasAttribute('aria-activedescendant')).to.be.true;
99
- });
100
-
101
- it('supports "roving-tabindex" pattern', async () => {
102
- const el = await fixture(html`
103
- <${tag} name="foo" ._activeMode="${'roving-tabindex'}">
104
- <div role="menuitem" id="item1">Item 1</div>
105
- <div role="menuitem" id="item2">Item 2</div>
106
- </${tag}>
107
- `);
108
-
109
- // @ts-ignore - test element with InteractiveListMixin properties
110
- el.activeIndex = 0;
111
- // @ts-ignore - test element with InteractiveListMixin properties
112
- expect(el.listItems[0].getAttribute('tabindex')).to.equal('0');
113
- // @ts-ignore - test element with InteractiveListMixin properties
114
- expect(el.listItems[1].getAttribute('tabindex')).to.equal('-1');
115
-
116
- // @ts-ignore - test element with InteractiveListMixin properties
117
- el.activeIndex = 1;
118
- // @ts-ignore - test element with InteractiveListMixin properties
119
- expect(el.listItems[0].getAttribute('tabindex')).to.equal('-1');
120
- // @ts-ignore - test element with InteractiveListMixin properties
121
- expect(el.listItems[1].getAttribute('tabindex')).to.equal('0');
122
-
123
- // @ts-ignore - test element with InteractiveListMixin properties
124
- el.activeIndex = 1;
125
- // @ts-ignore - test element with InteractiveListMixin properties
126
- expect(document.activeElement).to.equal(el.listItems[1]);
127
- });
128
- });
129
-
130
- describe('Programmatic interaction', () => {
131
- // If we have the item line directly in the fixture the linting rule lit-a11y/role-has-required-aria-attrs
132
- // will fail. Inside our code we set the required aria attributes, but the linter doesn't know that.
133
- const item = /** @param {number} i, @param {string} role */ (i, role) => html`
134
- <div role="${role}" id="item${i}">Item ${i}</div>
135
- `;
136
-
137
- it('set checked state sets aria-current attribute with role="listitem"', async () => {
138
- const el = await fixture(html`
139
- <${tag}>
140
- ${item(1, 'listitem')}
141
- ${item(2, 'listitem')}
142
- </${tag}>
143
- `);
144
- el.setCheckedIndex(1);
145
- const item1 = el.listItems[1];
146
- expect(item1.getAttribute('aria-current')).to.equal('true');
147
- el.setCheckedIndex(0);
148
- expect(item1.getAttribute('aria-current')).to.equal('false');
149
- });
150
-
151
- it('set checked state sets aria-selected attribute with role="option"', async () => {
152
- const el = await fixture(html`
153
- <${tag}>
154
- ${item(1, 'option')}
155
- ${item(2, 'option')}
156
- </${tag}>
157
- `);
158
- console.debug('listItems', el.listItems);
159
- const item1 = el.listItems[1];
160
- expect(item1.getAttribute('aria-selected')).to.equal('false');
161
-
162
- el.setCheckedIndex(1);
163
- expect(item1.getAttribute('aria-selected')).to.equal('true');
164
-
165
- el.setCheckedIndex(0);
166
- expect(item1.getAttribute('aria-selected')).to.equal('false');
167
- });
168
-
169
- it('set checked state sets aria-selected attribute with role="treeitem"', async () => {
170
- const el = await fixture(html`
171
- <${tag}>
172
- ${item(1, 'treeitem')}
173
- ${item(2, 'treeitem')}
174
- </${tag}>
175
- `);
176
- el.setCheckedIndex(1);
177
- // @ts-ignore - test element with InteractiveListMixin properties
178
- const item1 = el.listItems[1];
179
- expect(item1.getAttribute('aria-selected')).to.equal('true');
180
- el.setCheckedIndex(0);
181
- expect(item1.getAttribute('aria-selected')).to.equal('false');
182
- });
183
-
184
- it('set checked state sets aria-current attribute with role="menuitem"', async () => {
185
- const el = await fixture(html`
186
- <${tag}>
187
- ${item(1, 'menuitem')}
188
- ${item(2, 'menuitem')}
189
- </${tag}>
190
- `);
191
- el.setCheckedIndex(1);
192
- const item1 = el.listItems[1];
193
- expect(item1.getAttribute('aria-current')).to.equal('true');
194
- el.setCheckedIndex(0);
195
- expect(item1.getAttribute('aria-current')).to.equal('false');
196
- });
197
-
198
- it('set checked state sets aria-checked attribute with role="menuitemradio"', async () => {
199
- const el = await fixture(html`
200
- <${tag}>
201
- ${item(1, 'menuitemradio')}
202
- ${item(2, 'menuitemradio')}
203
- </${tag}>
204
- `);
205
- el.setCheckedIndex(1);
206
- const item1 = el.listItems[1];
207
- expect(item1.getAttribute('aria-checked')).to.equal('true');
208
- el.setCheckedIndex(0);
209
- expect(item1.getAttribute('aria-checked')).to.equal('false');
210
- });
211
-
212
- it('set checked state sets aria-checked attribute with role="menuitemcheckbox"', async () => {
213
- const el = await fixture(html`
214
- <${tag}>
215
- ${item(1, 'menuitemcheckbox')}
216
- ${item(2, 'menuitemcheckbox')}
217
- </${tag}>
218
- `);
219
- el.setCheckedIndex(1);
220
- const item1 = el.listItems[1];
221
- expect(item1.getAttribute('aria-checked')).to.equal('true');
222
- el.setCheckedIndex(0);
223
- // As this is multiple choice it doesn't unset the checked state
224
- expect(item1.getAttribute('aria-checked')).to.equal('true');
225
- });
226
-
227
- it('can set checked state to "page" for role="listitem"', async () => {
228
- const el = await fixture(html`
229
- <${tag}>
230
- <a role="listitem" id="item1" href="#">Item 1</a>
231
- <a role="listitem" id="item2" href="#">Item 2</a>
232
- </${tag}>
233
- `);
234
- el.setCheckedIndex(1);
235
- const item1 = el.listItems[1];
236
- expect(item1.getAttribute('aria-current')).to.equal('page');
237
- el.setCheckedIndex(0);
238
- expect(item1.getAttribute('aria-current')).to.equal('false');
239
- });
240
-
241
- it('can set checked state to "mixed" for role="menuitemcheckbox"', async () => {
242
- const el = await fixture(html`
243
- <${tag}>
244
- ${item(1, 'menuitemcheckbox')}
245
- ${item(2, 'menuitemcheckbox')}
246
- </${tag}>
247
- `);
248
- const item1 = el.listItems[1];
249
- // @ts-ignore - not yet supported property
250
- item1.mixedState = true;
251
- el.setCheckedIndex(1);
252
- expect(item1.getAttribute('aria-checked')).to.equal('mixed');
253
- el.setCheckedIndex(0);
254
- expect(item1.getAttribute('aria-checked')).to.equal('mixed');
255
- });
256
-
257
- it('does not allow to set checkedIndex or activeIndex to be out of bound', async () => {
258
- const el = await fixture(html`
259
- <${tag} has-no-default-selected autocomplete="list">
260
- <div role="menuitem" id="item1">Item 1</div>
261
- </${tag}>
262
- `);
263
- expect(() => {
264
- el.checkedIndex = -1;
265
- el.checkedIndex = 1;
266
- }).to.not.throw();
267
- expect(el.checkedIndex).to.equal(-1);
268
- });
269
-
270
- it('unsets checked on other options when option becomes checked', async () => {
271
- const el = await fixture(html`
272
- <${tag}>
273
- <div role="menuitem" id="item1">Item 1</div>
274
- <div role="menuitem" id="item2">Item 2</div>
275
- </${tag}>
276
- `);
277
- const { listItems } = el;
278
- el.setCheckedIndex(0);
279
- expect(listItems[0].hasAttribute('checked')).to.be.true;
280
- expect(listItems[1].hasAttribute('checked')).to.be.false;
281
- el.setCheckedIndex(1);
282
- expect(listItems[0].hasAttribute('checked')).to.be.false;
283
- expect(listItems[1].hasAttribute('checked')).to.be.true;
284
- });
285
- });
286
-
287
- // Copy tests from ListboxMixin. Later, make this mixin a fundament of the ListboxMixin
288
-
289
- // orientation
290
- // multipleChoice
291
- // selectionFollowsFocus
292
- // rotateKeyboardNavigation
293
- // noPreselect
294
- // _scrollTargetNode
295
-
296
- describe('Widget extensions', () => {
297
- it('can be extended to [role=listbox]', async () => {});
298
- it('can be extended to [role=menu]', async () => {});
299
- it('can be extended to [role=menubar]', async () => {});
300
- it('can be extended to [role=toolbar]', async () => {});
301
- it('can be extended to [role=tree]', async () => {});
302
- });
303
- });
304
- }
@@ -1,82 +0,0 @@
1
- import { Constructor } from '@open-wc/dedupe-mixin';
2
- import { LitElement } from 'lit';
3
- import { SlotHost } from '../../core/types/SlotMixinTypes.js';
4
- import { DisabledHost } from '../../core/types/DisabledMixinTypes.js';
5
-
6
- export type InteractiveListItemRole =
7
- | 'menuitem'
8
- | 'menuitemcheckbox'
9
- | 'menuitemradio'
10
- | 'option'
11
- | 'treeitem'
12
- | 'radio'
13
- | 'checkbox';
14
-
15
- export declare class InteractiveListHost {
16
- /**
17
- * When true, will synchronize activedescendant and selected element on
18
- * arrow key navigation.
19
- * This behavior can usually be seen on <select> on the Windows platform.
20
- * Note that this behavior cannot be used when multiple-choice is true.
21
- * See: https://www.w3.org/TR/wai-aria-practices/#kbd_selection_follows_focus
22
- */
23
- public selectionFollowsFocus: Boolean;
24
- /**
25
- * Will give first option active state when navigated to the next option from
26
- * last option.
27
- */
28
- public rotateKeyboardNavigation: Boolean;
29
- /**
30
- * Informs screen reader and affects keyboard navigation.
31
- * By default 'vertical'
32
- */
33
- public orientation: 'vertical' | 'horizontal';
34
-
35
- public hasNoDefaultSelected: boolean;
36
-
37
- public singleOption: boolean;
38
-
39
- public checkedIndex: number | number[];
40
-
41
- public activeIndex: number;
42
-
43
- public listItems: HTMLElement[];
44
-
45
- public setCheckedIndex(index: number): void;
46
-
47
- protected _scrollTargetNode: HTMLElement;
48
-
49
- protected _listNode: HTMLElement;
50
-
51
- // private __setupListboxNode(): void;
52
-
53
- protected _getPreviousEnabledOption(currentIndex: number, offset?: number): number;
54
-
55
- protected _getNextEnabledOption(currentIndex: number, offset?: number): number;
56
-
57
- protected _onListKeyDown(ev: KeyboardEvent): void;
58
-
59
- protected _onListKeyUp(ev: KeyboardEvent): void;
60
-
61
- // protected _setupListboxNode(): void;
62
-
63
- // protected _teardownListboxNode(): void;
64
-
65
- protected _onListClick(ev: MouseEvent): void;
66
-
67
- // protected _setupListboxInteractions(): void;
68
-
69
- // protected _onChildActiveChanged(ev: Event): void;
70
- }
71
-
72
- export declare function InteractiveListHostImplementation<T extends Constructor<LitElement>>(
73
- superclass: T,
74
- ): T &
75
- Constructor<InteractiveListHost> &
76
- InteractiveListHost &
77
- Constructor<DisabledHost> &
78
- typeof DisabledHost &
79
- Constructor<SlotHost> &
80
- typeof SlotHost;
81
-
82
- export type InteractiveListMixin = typeof InteractiveListHostImplementation;
@@ -1 +0,0 @@
1
- N.B. api is very very beta