@lion/ui 0.17.0 → 0.18.0-menu-system.1

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 (218) hide show
  1. package/collapsible.js +1 -0
  2. package/components/button/src/LionButton.js +4 -0
  3. package/components/button/test-suites/LionButton.suite.js +1 -0
  4. package/components/calendar/src/LionCalendar.js +2 -0
  5. package/components/collapsible/src/DisclosureMixin.js +313 -0
  6. package/components/collapsible/types/DisclosureMixinTypes.ts +48 -0
  7. package/components/combobox/test/lion-combobox.test.js +1 -0
  8. package/components/form-core/src/form-group/FormGroupMixin.js +7 -0
  9. package/components/form-core/src/registration/FormRegistrarMixin.js +11 -0
  10. package/components/form-core/test/FormControlMixin.test.js +1 -0
  11. package/components/form-core/test/validate/Validator.test.js +2 -0
  12. package/components/form-core/test-suites/ValidateMixin.suite.js +2 -0
  13. package/components/form-core/test-suites/ValidateMixinFeedbackPart.suite.js +1 -0
  14. package/components/input-datepicker/src/localizeNamespaceLoader.js +1 -0
  15. package/components/input-datepicker/test/lion-input-datepicker.test.js +5 -6
  16. package/components/localize/test/date/formatDate.test.js +1 -0
  17. package/components/menu/CHANGELOG.md +37 -0
  18. package/components/menu/README.md +335 -0
  19. package/components/menu/index.js +2 -0
  20. package/components/menu/lion-menu-overlay.js +3 -0
  21. package/components/menu/lion-menu.js +3 -0
  22. package/components/menu/lion-spinbutton.js +3 -0
  23. package/components/menu/lion-toolbar.js +3 -0
  24. package/components/menu/lion-tree.js +3 -0
  25. package/components/menu/package.json +46 -0
  26. package/components/menu/requirements.temp.md +12 -0
  27. package/components/menu/src/InteractiveListMixin.js +805 -0
  28. package/components/menu/src/LionMenu.js +250 -0
  29. package/components/menu/src/LionMenuHybrid.js +46 -0
  30. package/components/menu/src/LionMenuOverlay.js +155 -0
  31. package/components/menu/src/LionSpinbutton.js +213 -0
  32. package/components/menu/src/LionToolbar.js +94 -0
  33. package/components/menu/src/LionTree.js +52 -0
  34. package/components/menu/src/MoreButtonMenuMixin.js +297 -0
  35. package/components/menu/src/MultiLevelListMixin.js +274 -0
  36. package/components/menu/src/utils/isInView.js +26 -0
  37. package/components/menu/src/utils/listItemInteractions.js +104 -0
  38. package/components/menu/src/utils/uuid.js +3 -0
  39. package/components/menu/test/lion-menu.test.js +3 -0
  40. package/components/menu/test-suites/InteractiveListMixin.suite.js +142 -0
  41. package/components/menu/types/InteractiveListMixinTypes.d.ts +82 -0
  42. package/components/navigation-bar/README.md +1 -0
  43. package/components/navigation-bar/src/LionNavigationBar.js +439 -0
  44. package/components/navigation-bar/src/types.js +41 -0
  45. package/components/overlays/NEXT.md +49 -0
  46. package/components/overlays/src/OverlayController.js +244 -111
  47. package/components/overlays/src/OverlayMixin.js +58 -11
  48. package/components/overlays/src/OverlaysManager.js +2 -2
  49. package/components/overlays/src/utils/adopt-styles.js +3 -2
  50. package/components/overlays/src/utils/get-focusable-elements.js +4 -0
  51. package/components/overlays/src/utils/is-equal-config.js +10 -6
  52. package/components/overlays/test/OverlayController.test.js +5 -3
  53. package/components/overlays/test/utils-tests/is-equal-config.test.js +1 -1
  54. package/components/overlays/test-suites/OverlayMixin.suite.js +8 -8
  55. package/components/overlays/types/OverlayConfig.ts +16 -5
  56. package/components/select-rich/test/lion-select-rich.test.js +3 -0
  57. package/custom-elements.json +32144 -19531
  58. package/dist-types/components/button/src/LionButton.d.ts +1 -0
  59. package/dist-types/components/button/src/LionButton.d.ts.map +1 -1
  60. package/dist-types/components/button/test-suites/LionButton.suite.d.ts.map +1 -1
  61. package/dist-types/components/calendar/src/LionCalendar.d.ts.map +1 -1
  62. package/dist-types/components/collapsible/src/DisclosureMixin.d.ts +3 -0
  63. package/dist-types/components/collapsible/src/DisclosureMixin.d.ts.map +1 -0
  64. package/dist-types/components/collapsible/types/DisclosureMixinTypes.d.ts +24 -0
  65. package/dist-types/components/collapsible/types/DisclosureMixinTypes.d.ts.map +1 -0
  66. package/dist-types/components/dialog/src/LionDialog.d.ts +3 -1
  67. package/dist-types/components/dialog/src/LionDialog.d.ts.map +1 -1
  68. package/dist-types/components/form-core/src/form-group/FormGroupMixin.d.ts.map +1 -1
  69. package/dist-types/components/form-core/src/registration/FormRegistrarMixin.d.ts.map +1 -1
  70. package/dist-types/components/form-core/test-suites/ValidateMixin.suite.d.ts.map +1 -1
  71. package/dist-types/components/form-core/test-suites/ValidateMixinFeedbackPart.suite.d.ts.map +1 -1
  72. package/dist-types/components/input-datepicker/src/localizeNamespaceLoader.d.ts.map +1 -1
  73. package/dist-types/components/menu/index.d.ts +3 -0
  74. package/dist-types/components/menu/index.d.ts.map +1 -0
  75. package/dist-types/components/menu/lion-menu-overlay.d.ts +2 -0
  76. package/dist-types/components/menu/lion-menu-overlay.d.ts.map +1 -0
  77. package/dist-types/components/menu/lion-menu.d.ts +2 -0
  78. package/dist-types/components/menu/lion-menu.d.ts.map +1 -0
  79. package/dist-types/components/menu/lion-spinbutton.d.ts +2 -0
  80. package/dist-types/components/menu/lion-spinbutton.d.ts.map +1 -0
  81. package/dist-types/components/menu/lion-toolbar.d.ts +2 -0
  82. package/dist-types/components/menu/lion-toolbar.d.ts.map +1 -0
  83. package/dist-types/components/menu/lion-tree.d.ts +2 -0
  84. package/dist-types/components/menu/lion-tree.d.ts.map +1 -0
  85. package/dist-types/components/menu/src/InteractiveListMixin.d.ts +611 -0
  86. package/dist-types/components/menu/src/InteractiveListMixin.d.ts.map +1 -0
  87. package/dist-types/components/menu/src/LionMenu.d.ts +563 -0
  88. package/dist-types/components/menu/src/LionMenu.d.ts.map +1 -0
  89. package/dist-types/components/menu/src/LionMenuHybrid.d.ts +19 -0
  90. package/dist-types/components/menu/src/LionMenuHybrid.d.ts.map +1 -0
  91. package/dist-types/components/menu/src/LionMenuOverlay.d.ts +1007 -0
  92. package/dist-types/components/menu/src/LionMenuOverlay.d.ts.map +1 -0
  93. package/dist-types/components/menu/src/LionSpinbutton.d.ts +58 -0
  94. package/dist-types/components/menu/src/LionSpinbutton.d.ts.map +1 -0
  95. package/dist-types/components/menu/src/LionToolbar.d.ts +8 -0
  96. package/dist-types/components/menu/src/LionToolbar.d.ts.map +1 -0
  97. package/dist-types/components/menu/src/LionTree.d.ts +445 -0
  98. package/dist-types/components/menu/src/LionTree.d.ts.map +1 -0
  99. package/dist-types/components/menu/src/MoreButtonMenuMixin.d.ts +31 -0
  100. package/dist-types/components/menu/src/MoreButtonMenuMixin.d.ts.map +1 -0
  101. package/dist-types/components/menu/src/MultiLevelListMixin.d.ts +493 -0
  102. package/dist-types/components/menu/src/MultiLevelListMixin.d.ts.map +1 -0
  103. package/dist-types/components/menu/src/utils/isInView.d.ts +9 -0
  104. package/dist-types/components/menu/src/utils/isInView.d.ts.map +1 -0
  105. package/dist-types/components/menu/src/utils/listItemInteractions.d.ts +42 -0
  106. package/dist-types/components/menu/src/utils/listItemInteractions.d.ts.map +1 -0
  107. package/dist-types/components/menu/src/utils/uuid.d.ts +2 -0
  108. package/dist-types/components/menu/src/utils/uuid.d.ts.map +1 -0
  109. package/dist-types/components/menu/test/lion-menu.test.d.ts +2 -0
  110. package/dist-types/components/menu/test/lion-menu.test.d.ts.map +1 -0
  111. package/dist-types/components/menu/test-suites/InteractiveListMixin.suite.d.ts +13 -0
  112. package/dist-types/components/menu/test-suites/InteractiveListMixin.suite.d.ts.map +1 -0
  113. package/dist-types/components/navigation-bar/src/LionNavigationBar.d.ts +238 -0
  114. package/dist-types/components/navigation-bar/src/LionNavigationBar.d.ts.map +1 -0
  115. package/dist-types/components/navigation-bar/src/types.d.ts +85 -0
  116. package/dist-types/components/navigation-bar/src/types.d.ts.map +1 -0
  117. package/dist-types/components/overlays/src/OverlayController.d.ts +9 -13
  118. package/dist-types/components/overlays/src/OverlayController.d.ts.map +1 -1
  119. package/dist-types/components/overlays/src/OverlayMixin.d.ts.map +1 -1
  120. package/dist-types/components/overlays/src/utils/get-focusable-elements.d.ts.map +1 -1
  121. package/dist-types/components/overlays/src/utils/is-equal-config.d.ts.map +1 -1
  122. package/dist-types/components/overlays/types/OverlayConfig.d.ts +10 -2
  123. package/dist-types/components/overlays/types/OverlayConfig.d.ts.map +1 -1
  124. package/dist-types/components/select-rich/src/LionSelectRich.d.ts +8 -2
  125. package/dist-types/components/select-rich/src/LionSelectRich.d.ts.map +1 -1
  126. package/dist-types/exports/define/lion-item.d.ts +2 -0
  127. package/dist-types/exports/define/lion-item.d.ts.map +1 -0
  128. package/dist-types/exports/define/lion-menu-overlay.d.ts +2 -0
  129. package/dist-types/exports/define/lion-menu-overlay.d.ts.map +1 -0
  130. package/dist-types/exports/define/lion-menu.d.ts +2 -0
  131. package/dist-types/exports/define/lion-menu.d.ts.map +1 -0
  132. package/dist-types/exports/define/lion-navigation-bar.d.ts +2 -0
  133. package/dist-types/exports/define/lion-navigation-bar.d.ts.map +1 -0
  134. package/dist-types/exports/define/lion-toolbar.d.ts +2 -0
  135. package/dist-types/exports/define/lion-toolbar.d.ts.map +1 -0
  136. package/dist-types/exports/define/lion-tree.d.ts +2 -0
  137. package/dist-types/exports/define/lion-tree.d.ts.map +1 -0
  138. package/dist-types/exports/menu.d.ts +7 -0
  139. package/dist-types/exports/menu.d.ts.map +1 -0
  140. package/dist-types/exports/navigation-bar.d.ts +2 -0
  141. package/dist-types/exports/navigation-bar.d.ts.map +1 -0
  142. package/dist-types/exports/overlays.d.ts +3 -0
  143. package/dist-types/exports/overlays.d.ts.map +1 -1
  144. package/dist-types/tsconfig.tsbuildinfo +1 -1
  145. package/docs/components/checkbox-group/overview.md +2 -2
  146. package/docs/components/collapsible/overview.md +1 -1
  147. package/docs/components/combobox/api-table.md +21 -8
  148. package/docs/components/combobox/overview.md +1 -1
  149. package/docs/components/combobox/use-cases.md +1 -1
  150. package/docs/components/dialog/api-table.md +31 -6
  151. package/docs/components/dialog/overview.md +1 -1
  152. package/docs/components/fieldset/overview.md +5 -5
  153. package/docs/components/form/overview.md +3 -3
  154. package/docs/components/form/use-cases.md +2 -2
  155. package/docs/components/icon/use-cases.md +1 -1
  156. package/docs/components/input/overview.md +1 -1
  157. package/docs/components/input-amount/overview.md +3 -3
  158. package/docs/components/input-date/overview.md +3 -3
  159. package/docs/components/input-datepicker/api-table.md +21 -4
  160. package/docs/components/input-datepicker/overview.md +5 -5
  161. package/docs/components/input-email/overview.md +2 -2
  162. package/docs/components/input-file/overview.md +1 -1
  163. package/docs/components/input-iban/overview.md +2 -2
  164. package/docs/components/input-range/overview.md +2 -2
  165. package/docs/components/input-stepper/overview.md +1 -1
  166. package/docs/components/input-tel/overview.md +1 -1
  167. package/docs/components/input-tel/use-cases.md +6 -6
  168. package/docs/components/input-tel-dropdown/overview.md +1 -1
  169. package/docs/components/listbox/use-cases.md +1 -1
  170. package/docs/components/menu/api-table.md +450 -0
  171. package/docs/components/menu/applyMenuDemoStyles.js +173 -0
  172. package/docs/components/menu/extensions.md +235 -0
  173. package/docs/components/menu/index.md +13 -0
  174. package/docs/components/menu/overview.md +422 -0
  175. package/docs/components/radio-group/overview.md +3 -3
  176. package/docs/components/select/use-cases.md +1 -1
  177. package/docs/components/select-rich/api-table.md +21 -5
  178. package/docs/components/select-rich/use-cases.md +2 -2
  179. package/docs/components/tabs/examples.md +1 -1
  180. package/docs/components/tooltip/api-table.md +36 -11
  181. package/docs/fundamentals/index.md +4 -4
  182. package/docs/fundamentals/node-tools/publish-docs/overview.md +3 -3
  183. package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +2 -2
  184. package/docs/fundamentals/rationales/accessibility.md +1 -1
  185. package/docs/fundamentals/systems/core/SlotMixin.md +1 -1
  186. package/docs/fundamentals/systems/core/overview.md +1 -1
  187. package/docs/fundamentals/systems/form/formatting-and-parsing.md +4 -4
  188. package/docs/fundamentals/systems/form/model-value.md +1 -1
  189. package/docs/fundamentals/systems/form/overview.md +28 -28
  190. package/docs/fundamentals/systems/form/validate.md +2 -2
  191. package/docs/fundamentals/systems/localize/overview.md +4 -4
  192. package/docs/fundamentals/systems/overlays/api-table.md +34 -34
  193. package/docs/fundamentals/systems/overlays/configuration.md +2 -2
  194. package/docs/fundamentals/systems/overlays/overview.md +5 -5
  195. package/docs/fundamentals/systems/overlays/use-cases.md +2 -2
  196. package/docs/fundamentals/tools/helpers/overview.md +1 -1
  197. package/docs/fundamentals/tools/singleton-manager/overview.md +4 -4
  198. package/docs/guides/how-to/create-a-custom-field.md +5 -5
  199. package/docs/guides/how-to/create-a-form.md +4 -4
  200. package/docs/guides/how-to/extend-a-native-input.md +2 -2
  201. package/docs/guides/how-to/index.md +1 -1
  202. package/docs/guides/index.md +8 -8
  203. package/docs/guides/principles/index.md +5 -5
  204. package/docs/guides/principles/styling.md +1 -1
  205. package/exports/collapsible.js +1 -0
  206. package/exports/define/lion-item.js +3 -0
  207. package/exports/define/lion-menu-overlay.js +3 -0
  208. package/exports/define/lion-menu.js +3 -0
  209. package/exports/define/lion-navigation-bar.js +3 -0
  210. package/exports/define/lion-toolbar.js +3 -0
  211. package/exports/define/lion-tree.js +3 -0
  212. package/exports/menu.js +7 -0
  213. package/exports/navigation-bar.js +1 -0
  214. package/exports/overlays.js +6 -0
  215. package/menu.js +7 -0
  216. package/navigation-bar.js +1 -0
  217. package/overlays.js +6 -0
  218. package/package.json +1 -1
package/collapsible.js CHANGED
@@ -1 +1,2 @@
1
1
  export { LionCollapsible } from './components/collapsible/src/LionCollapsible.js';
2
+ // export { DisclosureMixin } from '../components/collapsible/src/DisclosureMixin.js';
@@ -220,4 +220,8 @@ export class LionButton extends DisabledWithTabIndexMixin(LitElement) {
220
220
  this.click();
221
221
  }
222
222
  }
223
+
224
+ // we want to be able to identify LionButtons w/o instanceof (for perf (loose dep) and dual version support),
225
+ // so we use a static property for that that doesn't get renamed by minifiers
226
+ static ['_$isLionButton$'] = true;
223
227
  }
@@ -279,6 +279,7 @@ export function LionButtonSuite({ klass = LionButton } = {}) {
279
279
 
280
280
  sameProperties.forEach(property => {
281
281
  it(`has same value of the property "${property}" as in native button event`, () => {
282
+ // @ts-ignore - dynamic property access
282
283
  expect(lionButtonEvent[property]).to.equal(nativeButtonEvent[property]);
283
284
  });
284
285
  });
@@ -928,6 +928,7 @@ export class LionCalendar extends LocalizeMixin(LitElement) {
928
928
  if (type !== 'Date') {
929
929
  tmpDate.setDate(1);
930
930
  }
931
+ // @ts-ignore - dynamic method access
931
932
  tmpDate[`set${type}`](tmpDate[`get${type}`]() + modify);
932
933
  // if we've reset the day count,
933
934
  // restore day count as best we can
@@ -935,6 +936,7 @@ export class LionCalendar extends LocalizeMixin(LitElement) {
935
936
  const maxDays = new Date(tmpDate.getFullYear(), tmpDate.getMonth() + 1, 0).getDate();
936
937
  tmpDate.setDate(Math.min(this.centralDate.getDate(), maxDays));
937
938
  }
939
+ // @ts-ignore - dynamic property access
938
940
  this[dateType] = tmpDate;
939
941
  }
940
942
 
@@ -0,0 +1,313 @@
1
+ /**
2
+ * @typedef {import('../types/DisclosureMixinTypes.js').DisclosureHost} DisclosureHost
3
+ * @typedef {import('../types/DisclosureMixinTypes.js').DisclosureMixin} DisclosureMixin
4
+ */
5
+
6
+ // /**
7
+ // * @type {DisclosureMixin}
8
+ // */
9
+ // const DisclosureMixinImplementation = superclass =>
10
+ // // @ts-ignore https://github.com/microsoft/TypeScript/issues/36821#issuecomment-588375051
11
+ // class DisclosureMixin extends superclass {
12
+ // /** @type {any} */
13
+ // static get properties() {
14
+ // return {
15
+ // opened: { type: Boolean, reflect: true },
16
+ // handleFocus: { type: Boolean, attribute: 'handle-focus' },
17
+ // invokerInteraction: { type: String, attribute: 'invoker-interaction' },
18
+ // };
19
+ // }
20
+
21
+ // /**
22
+ // * @param {Element} focusableElOrWrapper
23
+ // * @returns {Element|null}
24
+ // */
25
+ // static _getFocusableInvokerEl(focusableElOrWrapper) {
26
+ // // return focusableElOrWrapper;
27
+ // return (
28
+ // focusableElOrWrapper &&
29
+ // (focusableElOrWrapper.hasAttribute('tabindex') || focusableElOrWrapper.tagName === 'BUTTON'
30
+ // ? focusableElOrWrapper
31
+ // : focusableElOrWrapper.querySelector('[role=button], button'))
32
+ // );
33
+ // }
34
+
35
+ // get _invokerNode() {
36
+ // const ctor = this.constructor;
37
+ // if (!this.__invokerNode) {
38
+ // const slottedNode = Array.from(this.children).find(child => child.slot === 'invoker');
39
+ // if (slottedNode) {
40
+ // this.__invokerNode = ctor._getFocusableInvokerEl(slottedNode);
41
+ // } else {
42
+ // this.__invokerNode =
43
+ // this.previousElementSibling?.hasAttribute('data-invoker') &&
44
+ // ctor._getFocusableInvokerEl(this.previousElementSibling);
45
+ // }
46
+ // }
47
+ // return this.__invokerNode;
48
+ // }
49
+
50
+ // get _contentNode() {
51
+ // if (!this._cachedOverlayContentNode) {
52
+ // this._cachedOverlayContentNode = Array.from(this.children).find(
53
+ // child => child.slot === 'content',
54
+ // );
55
+ // }
56
+ // return this._cachedOverlayContentNode;
57
+ // }
58
+
59
+ // constructor() {
60
+ // super();
61
+ // this.opened = false;
62
+ // /**
63
+ // * @type {'click'|'hover'}
64
+ // */
65
+ // this.invokerInteraction = 'click';
66
+ // /**
67
+ // * Puts focus on `_contentNode` on open and on `_invokerNode` on close.
68
+ // * @type {Boolean}
69
+ // */
70
+ // this.handleFocus = false;
71
+ // this.__disclosureNeedsSetup = true;
72
+
73
+ // this.toggle = this.toggle.bind(this);
74
+ // this.open = this.open.bind(this);
75
+ // this.close = this.close.bind(this);
76
+
77
+ // this.__handleAnimateComplete = this.__handleAnimateComplete.bind(this);
78
+
79
+ // this.__onInvokerMouseenter = this.__onInvokerMouseenter.bind(this);
80
+ // this.__onContentMouseenter = this.__onContentMouseenter.bind(this);
81
+ // this.__onInvokerMouseleave = this.__onInvokerMouseleave.bind(this);
82
+ // this.__onContentMouseleave = this.__onContentMouseleave.bind(this);
83
+ // }
84
+
85
+ // connectedCallback() {
86
+ // super.connectedCallback();
87
+ // // we do a setup after every connectedCallback as firstUpdated will only be called once
88
+ // this.__disclosureNeedsSetup = true;
89
+ // this.updateComplete.then(() => {
90
+ // if (this.__disclosureNeedsSetup) {
91
+ // this._setupDisclosure();
92
+ // }
93
+ // this.__disclosureNeedsSetup = false;
94
+ // });
95
+ // this.__setupAnimation();
96
+ // }
97
+
98
+ // disconnectedCallback() {
99
+ // super.disconnectedCallback();
100
+ // this._teardownDisclosure();
101
+ // this.__teardownAnimation();
102
+ // }
103
+
104
+ // /**
105
+ // * @overridable
106
+ // */
107
+ // _setupDisclosure() {
108
+ // console.log('_setupDisclosure', this.level);
109
+
110
+ // this._setupOpenCloseListeners();
111
+ // }
112
+
113
+ // /**
114
+ // * @overridable
115
+ // */
116
+ // _teardownDisclosure() {
117
+ // this._teardownOpenCloseListeners();
118
+ // }
119
+
120
+ // /**
121
+ // * @overridable
122
+ // */
123
+ // _setupOpenCloseListeners() {
124
+ // console.log('setup listeners', this.level);
125
+ // if (!this._invokerNode) {
126
+ // return;
127
+ // }
128
+
129
+ // const interactions = this.invokerInteraction.split(' ');
130
+
131
+ // if (interactions.includes('hover')) {
132
+ // this._invokerNode.addEventListener('mouseenter', this.__onInvokerMouseenter);
133
+ // this._contentNode?.addEventListener('mouseenter', this.__onContentMouseenter);
134
+ // this._invokerNode.addEventListener('mouseleave', this.__onInvokerMouseleave);
135
+ // this._contentNode?.addEventListener('mouseleave', this.__onContentMouseleave);
136
+ // }
137
+ // if (interactions.includes('click')) {
138
+ // this._invokerNode.addEventListener('click', this.toggle);
139
+ // }
140
+ // }
141
+
142
+ // __onInvokerMouseenter() {
143
+ // this.__invokerHover = true;
144
+ // this.open();
145
+ // }
146
+
147
+ // __onContentMouseenter() {
148
+ // this.__contentHover = true;
149
+ // console.log('this.__contentHover', this.__contentHover);
150
+ // this.open();
151
+ // }
152
+
153
+ // __onInvokerMouseleave() {
154
+ // setTimeout(() => {
155
+ // if (!this.__contentHover) {
156
+ // this.close();
157
+ // }
158
+ // });
159
+ // this.__invokerHover = false;
160
+ // }
161
+
162
+ // __onContentMouseleave() {
163
+ // setTimeout(() => {
164
+ // if (!this.__invokerHover) {
165
+ // this.close();
166
+ // }
167
+ // });
168
+ // this.__contentHover = false;
169
+ // }
170
+
171
+ // /**
172
+ // * @overridable
173
+ // */
174
+ // _teardownOpenCloseListeners() {
175
+ // if (!this._invokerNode) {
176
+ // return;
177
+ // }
178
+
179
+ // this._invokerNode.removeEventListener('mouseenter', this.open);
180
+ // this._invokerNode.removeEventListener('mouseleave', this.close);
181
+ // this._contentNode?.removeEventListener('mouseenter', this.open);
182
+ // this._contentNode?.removeEventListener('mouseleave', this.close);
183
+
184
+ // // console.log(this, 'removetCLick');
185
+
186
+ // this._invokerNode.removeEventListener('click', this.toggle);
187
+ // }
188
+
189
+ // // TODO: fire event on updated?
190
+ // /**
191
+ // * @override
192
+ // * @param {string} name
193
+ // * @param {any} oldValue
194
+ // */
195
+ // requestUpdate(name, oldValue) {
196
+ // super.requestUpdate(name, oldValue);
197
+ // if (name === 'opened') {
198
+ // this.dispatchEvent(new Event('opened-changed'));
199
+ // }
200
+ // }
201
+
202
+ // /**
203
+ // * @param {import('lit-element').PropertyValues } changedProperties
204
+ // */
205
+ // updated(changedProperties) {
206
+ // super.updated(changedProperties);
207
+
208
+ // if (changedProperties.has('opened')) {
209
+ // this._onOpenedChanged();
210
+ // }
211
+ // }
212
+
213
+ // /**
214
+ // * @param {import('lit-element').PropertyValues } changedProperties
215
+ // */
216
+ // firstUpdated(changedProperties) {
217
+ // super.firstUpdated(changedProperties);
218
+ // this._onOpenedChanged();
219
+
220
+ // if (this.handleFocus && !this._contentNode?.hasAttribute('tabindex')) {
221
+ // this._contentNode?.setAttribute('tabindex', '-1');
222
+ // }
223
+ // }
224
+
225
+ // /**
226
+ // * @overridable
227
+ // */
228
+ // async _onOpenedChanged() {
229
+ // this._invokerNode.setAttribute('aria-expanded', `${this.opened}`);
230
+
231
+ // if (this.opened) {
232
+ // this._contentNode.style.setProperty('display', '');
233
+ // await this._showAnimation({ contentNode: this._contentNode });
234
+ // this._onDisclosureShow();
235
+ // } else {
236
+ // this._onDisclosureHide();
237
+ // await this._hideAnimation({ contentNode: this._contentNode });
238
+ // this._contentNode.style.setProperty('display', 'none');
239
+ // }
240
+ // }
241
+
242
+ // _onDisclosureShow() {
243
+ // // if (this.checkedIndex != null) {
244
+ // // this.activeIndex = this.checkedIndex;
245
+ // // }
246
+
247
+ // if (this.handleFocus) {
248
+ // this._contentNode.focus();
249
+ // }
250
+ // }
251
+
252
+ // _onDisclosureHide() {
253
+ // if (this.handleFocus) {
254
+ // this._invokerNode.focus();
255
+ // }
256
+ // }
257
+
258
+ // /**
259
+ // * Show animation implementation in sub-classer.
260
+ // * @param {{ contentNode: HTMLElement; }} cfg
261
+ // */
262
+ // // eslint-disable-next-line class-methods-use-this, no-empty-function
263
+ // async _showAnimation(cfg) {
264
+ // this._refreshAnimateCompletePromise();
265
+ // }
266
+
267
+ // /**
268
+ // * Hide animation implementation in sub-classer.
269
+ // * @param {{ contentNode: HTMLElement; }} cfg
270
+ // */
271
+ // // eslint-disable-next-line class-methods-use-this, no-empty-function
272
+ // async _hideAnimation(cfg) {
273
+ // this._refreshAnimateCompletePromise();
274
+ // }
275
+
276
+ // _refreshAnimateCompletePromise() {
277
+ // this._animateComplete = new Promise(resolve => {
278
+ // // Note that when a lib like GSAP is used, neither 'transitionend' or 'animationend' will be called.
279
+ // // In such a case, a subclasser needs to resolve this pending promise by calling this method
280
+ // this._resolveAnimateComplete = resolve;
281
+ // });
282
+ // }
283
+
284
+ // __setupAnimation() {
285
+ // this._contentNode.addEventListener('transitionend', this.__handleAnimateComplete);
286
+ // this._contentNode.addEventListener('animationend', this.__handleAnimateComplete);
287
+ // }
288
+
289
+ // __teardownAnimation() {
290
+ // this._contentNode.removeEventListener('transitionend', this.__handleAnimateComplete);
291
+ // this._contentNode.removeEventListener('animationend', this.__handleAnimateComplete);
292
+ // }
293
+
294
+ // __handleAnimateComplete() {
295
+ // if (typeof this._resolveAnimateComplete === 'function') {
296
+ // this._resolveAnimateComplete();
297
+ // }
298
+ // }
299
+
300
+ // toggle() {
301
+ // // console.log('toggul', this);
302
+ // this.opened = !this.opened;
303
+ // }
304
+
305
+ // open() {
306
+ // this.opened = true;
307
+ // }
308
+
309
+ // close() {
310
+ // this.opened = false;
311
+ // }
312
+ // };
313
+ // export const DisclosureMixin = dedupeMixin(DisclosureMixinImplementation);
@@ -0,0 +1,48 @@
1
+ import { Constructor } from '@open-wc/dedupe-mixin';
2
+ import { LitElement } from 'lit';
3
+
4
+ export declare class DisclosureHost {
5
+ public opened: Boolean;
6
+
7
+ protected get _invokerNode(): HTMLElement;
8
+
9
+ protected get _contentNode(): HTMLElement;
10
+
11
+ public toggle(): void;
12
+
13
+ public open(): void;
14
+
15
+ public close(): void;
16
+
17
+ protected _onOpenedChanged(): Promise<void>;
18
+
19
+ protected _onDisclosureShow(): void;
20
+
21
+ protected _onDisclosureHide(): void;
22
+
23
+ protected _showAnimation(cfg: object): Promise<void>;
24
+
25
+ protected _hideAnimation(cfg: object): Promise<void>;
26
+
27
+ protected _refreshAnimateCompletePromise(): void;
28
+
29
+ protected _setupOpenCloseListeners(): void;
30
+
31
+ protected _teardownOpenCloseListeners(): void;
32
+
33
+ private __setupAnimation(): void;
34
+
35
+ private __teardownAnimation(): void;
36
+
37
+ private __handleAnimateComplete(): void;
38
+ }
39
+
40
+ export declare function DisclosureImplementation<T extends Constructor<LitElement>>(
41
+ superclass: T,
42
+ ): T &
43
+ Constructor<DisclosureHost> &
44
+ DisclosureHost &
45
+ Pick<typeof DisclosureHost, keyof typeof DisclosureHost> &
46
+ Pick<typeof LitElement, keyof typeof LitElement>;
47
+
48
+ export type DisclosureMixin = typeof DisclosureImplementation;
@@ -3227,6 +3227,7 @@ describe('lion-combobox', () => {
3227
3227
  const [el, options] = await fruitFixture({ autocomplete: 'both', matchMode: 'all' });
3228
3228
  await mimicUserTyping(/** @type {LionCombobox} */ (el), 'choke');
3229
3229
  await el.updateComplete;
3230
+ // @ts-ignore - array index access
3230
3231
  const labelledElement = options[0].querySelector('span[aria-label="Artichoke"]');
3231
3232
  expect(labelledElement).to.not.be.null;
3232
3233
  expect(labelledElement.innerText).to.equal('Artichoke');
@@ -352,11 +352,14 @@ const FormGroupMixinImplementation = superclass =>
352
352
  this.formElements._keys().forEach(name => {
353
353
  const elem = this.formElements[name];
354
354
  if (elem instanceof FormControlsCollection) {
355
+ // @ts-ignore - dynamic property access
355
356
  result[name] = elem.filter(el => _filterFn(el, property)).map(el => el[property]);
356
357
  } else if (_filterFn(elem, property)) {
357
358
  if (typeof elem._getFromAllFormElements === 'function') {
359
+ // @ts-ignore - dynamic property access
358
360
  result[name] = elem._getFromAllFormElements(property);
359
361
  } else {
362
+ // @ts-ignore - dynamic property access
360
363
  result[name] = elem[property];
361
364
  }
362
365
  }
@@ -386,6 +389,7 @@ const FormGroupMixinImplementation = superclass =>
386
389
  if (Array.isArray(this.formElements[name])) {
387
390
  this.formElements[name].forEach(
388
391
  (/** @type {FormControl} */ el, /** @type {number} */ index) => {
392
+ // @ts-ignore - dynamic property access
389
393
  el[property] = values[name][index]; // eslint-disable-line no-param-reassign
390
394
  },
391
395
  );
@@ -393,6 +397,7 @@ const FormGroupMixinImplementation = superclass =>
393
397
  if (this.formElements[name]) {
394
398
  this.formElements[name][property] = values[name];
395
399
  } else {
400
+ // @ts-ignore - dynamic property access
396
401
  this.__pendingValues[property][name] = values[name];
397
402
  }
398
403
  });
@@ -406,6 +411,7 @@ const FormGroupMixinImplementation = superclass =>
406
411
  _anyFormElementHas(property) {
407
412
  return Object.keys(this.formElements).some(name => {
408
413
  if (Array.isArray(this.formElements[name])) {
414
+ // @ts-ignore - dynamic property access
409
415
  return this.formElements[name].some((/** @type {FormControl} */ el) => !!el[property]);
410
416
  }
411
417
  return !!this.formElements[name][property];
@@ -436,6 +442,7 @@ const FormGroupMixinImplementation = superclass =>
436
442
  _everyFormElementHas(property) {
437
443
  return Object.keys(this.formElements).every(name => {
438
444
  if (Array.isArray(this.formElements[name])) {
445
+ // @ts-ignore - dynamic property access
439
446
  return this.formElements[name].every((/** @type {FormControl} */ el) => !!el[property]);
440
447
  }
441
448
  return !!this.formElements[name][property];
@@ -162,15 +162,21 @@ const FormRegistrarMixinImplementation = superclass =>
162
162
  }
163
163
 
164
164
  if (name.substr(-2) === '[]') {
165
+ // @ts-ignore - dynamic named access to form elements
165
166
  if (!Array.isArray(this.formElements[name])) {
167
+ // @ts-ignore
166
168
  this.formElements[name] = new FormControlsCollection();
167
169
  }
168
170
  if (indexToInsertAt > 0) {
171
+ // @ts-ignore
169
172
  this.formElements[name].splice(indexToInsertAt, 0, child);
170
173
  } else {
174
+ // @ts-ignore
171
175
  this.formElements[name].push(child);
172
176
  }
177
+ // @ts-ignore
173
178
  } else if (!this.formElements[name]) {
179
+ // @ts-ignore
174
180
  this.formElements[name] = child;
175
181
  } else {
176
182
  console.info('Error Node:', child); // eslint-disable-line no-console
@@ -194,12 +200,17 @@ const FormRegistrarMixinImplementation = superclass =>
194
200
  // 2. Handle name based object keys
195
201
  if (this._isFormOrFieldset) {
196
202
  const { name } = child; // FIXME: <-- ElementWithParentFormGroup should become LionFieldWithParentFormGroup so that "name" exists
203
+ // @ts-ignore - dynamic named access to form elements
197
204
  if (name.substr(-2) === '[]' && this.formElements[name]) {
205
+ // @ts-ignore
198
206
  const idx = this.formElements[name].indexOf(child);
199
207
  if (idx > -1) {
208
+ // @ts-ignore
200
209
  this.formElements[name].splice(idx, 1);
201
210
  }
211
+ // @ts-ignore
202
212
  } else if (this.formElements[name]) {
213
+ // @ts-ignore
203
214
  delete this.formElements[name];
204
215
  }
205
216
  }
@@ -153,6 +153,7 @@ describe('FormControlMixin', () => {
153
153
  el.shadowRoot?.querySelector('.form-field__label'),
154
154
  );
155
155
  Object.entries(expectedValues).forEach(([key, val]) => {
156
+ // @ts-ignore - dynamic style property access
156
157
  expect(labelStyle[key]).to.equal(val);
157
158
  });
158
159
  });
@@ -191,7 +191,9 @@ describe('Validator', () => {
191
191
  it('adds static ["_$isValidator$"] property as a marker to identify the Validator class across different lion versions (as instanceof cannot be used)', async () => {
192
192
  const myValidator = new Validator();
193
193
 
194
+ // @ts-ignore - static property access
194
195
  expect(myValidator.constructor['_$isValidator$']).to.exist;
196
+ // @ts-ignore - static property access
195
197
  expect(myValidator.constructor['_$isValidator$']).to.be.true;
196
198
  });
197
199
 
@@ -1554,11 +1554,13 @@ export function runValidateMixinSuite(customConfig) {
1554
1554
  // eslint-disable-next-line no-restricted-syntax
1555
1555
  for (const state of ['dirty', 'touched', 'prefilled', 'submitted']) {
1556
1556
  counter += 1;
1557
+ // @ts-ignore - test property access
1557
1558
  el[state] = false;
1558
1559
  // eslint-disable-next-line no-await-in-loop
1559
1560
  await el.updateComplete;
1560
1561
  expect(spy.callCount).to.equal(counter);
1561
1562
  counter += 1;
1563
+ // @ts-ignore - test property access
1562
1564
  el[state] = true;
1563
1565
  // eslint-disable-next-line no-await-in-loop
1564
1566
  await el.updateComplete;
@@ -714,6 +714,7 @@ export function runValidateMixinFeedbackPart() {
714
714
  const results = {
715
715
  'a-string-instead-of-bool': 'Msg based on enum output',
716
716
  };
717
+ // @ts-ignore - test data structure
717
718
  return results[/** @type {string} */ (outcome)];
718
719
  }
719
720
  }
@@ -6,6 +6,7 @@ async function combineLocalizeImports(importPromises) {
6
6
  const combinedResult = localizeObjects[0];
7
7
  for (const localizeObject of localizeObjects.slice(1)) {
8
8
  Object.entries(localizeObject.default).forEach(([key, val]) => {
9
+ // @ts-ignore - dynamic property access
9
10
  combinedResult.default[key] = val;
10
11
  });
11
12
  }
@@ -597,12 +597,11 @@ describe('<lion-input-datepicker>', () => {
597
597
  <lion-input-datepicker label="End date" name="endDate"></lion-input-datepicker>
598
598
  `);
599
599
 
600
- // @ts-expect-error
601
- const elements = el.parentElement.children;
602
- // @ts-expect-error
603
- const startLabel = elements.startDate.querySelector('button').ariaLabel;
604
- // @ts-expect-error
605
- const endLabel = elements.endDate.querySelector('button').ariaLabel;
600
+ const elements = el.parentElement?.children;
601
+ // @ts-ignore - accessing by name property
602
+ const startLabel = elements?.startDate?.querySelector('button')?.ariaLabel;
603
+ // @ts-ignore - accessing by name property
604
+ const endLabel = elements?.endDate?.querySelector('button')?.ariaLabel;
606
605
 
607
606
  expect(startLabel).to.not.equal(endLabel);
608
607
  });
@@ -210,6 +210,7 @@ describe('formatDate', () => {
210
210
  locale,
211
211
  };
212
212
  const parsedDate = /** @type {Date} */ (parseDate('12.10.2019'));
213
+ // @ts-ignore - dynamic locale key access
213
214
  expect(formatDate(parsedDate, options)).to.equal(LOCALE_FORMATTED_DATE_MAP[locale]);
214
215
  });
215
216
  });
@@ -0,0 +1,37 @@
1
+ Allow advanced preprocessing
2
+
3
+ - Turn '1' into '01-__-____'
4
+ - Turn ’20’ into ’20-’, -> ’20-4’ into ’20-04’ etc…
5
+
6
+ See: https://nosir.github.io/cleave.js/(But we should enhance the UX when editing the middle of a date)So:
7
+
8
+ ```js
9
+ /** * @returns {string | { viewValue:string, caretIndex:number } } */
10
+ preprocessor(viewValue, { previousViewValue = ‘’, currentCaretIndex }) {
11
+ const diff = viewValue.length - previousViewValue.length;
12
+ if (diff === -1) && !isNaN(Number(previousViewValue[currentCaretIndex]))) {
13
+ // don’t respond to delete actions
14
+ return viewValue;
15
+ }
16
+
17
+ let newValue = '';
18
+ const strippedVal = viewValue.replace('-', '');
19
+ let dashesPlaced = 0;
20
+ let newCaretIndex;
21
+ for (let i = 0; i < 10; i+= 1) {
22
+ if (i === 2 || i === 4) {
23
+ newValue += ‘-’;
24
+ dashesPlaced += 1;
25
+ }
26
+ else if (i < strippedVal.length + dashesPlaced) {
27
+ newValue += strippedVal[i];
28
+ } else {
29
+ newValue += ‘_’;
30
+ if (newCaretIndex === undefined) {
31
+ newCaretIndex = i;
32
+ }
33
+ }
34
+ }
35
+ return { viewValue: newValue, caretIndex: newCaretIndex };
36
+ }
37
+ ```