@lion/ui 0.1.4 → 0.2.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 (192) hide show
  1. package/README.md +222 -0
  2. package/components/accordion/src/LionAccordion.js +2 -2
  3. package/components/accordion/test/lion-accordion.test.js +31 -0
  4. package/components/combobox/src/LionCombobox.js +179 -17
  5. package/components/combobox/src/validators.js +18 -0
  6. package/components/combobox/test/lion-combobox.test.js +290 -172
  7. package/components/combobox/test/validators.test.js +62 -0
  8. package/components/combobox/test-helpers/combobox-helpers.js +125 -0
  9. package/components/combobox/translations/bg.js +3 -0
  10. package/components/combobox/translations/cs.js +3 -0
  11. package/components/combobox/translations/de.js +3 -0
  12. package/components/combobox/translations/en.js +3 -0
  13. package/components/combobox/translations/es.js +3 -0
  14. package/components/combobox/translations/fr.js +3 -0
  15. package/components/combobox/translations/hu.js +3 -0
  16. package/components/combobox/translations/it.js +3 -0
  17. package/components/combobox/translations/nl.js +3 -0
  18. package/components/combobox/translations/pl.js +3 -0
  19. package/components/combobox/translations/ro.js +3 -0
  20. package/components/combobox/translations/ru.js +3 -0
  21. package/components/combobox/translations/sk.js +3 -0
  22. package/components/combobox/translations/uk.js +3 -0
  23. package/components/combobox/translations/zh.js +3 -0
  24. package/components/form-core/types/choice-group/ChoiceGroupMixinTypes.ts +4 -3
  25. package/components/input-datepicker/src/LionInputDatepicker.js +9 -1
  26. package/components/input-iban/translations/de.js +1 -1
  27. package/components/listbox/src/ListboxMixin.js +6 -0
  28. package/components/listbox/test-suites/ListboxMixin.suite.js +13 -7
  29. package/components/overlays/src/OverlayController.js +2 -1
  30. package/components/overlays/test/OverlayController.test.js +1 -1
  31. package/components/switch/src/LionSwitch.js +0 -3
  32. package/components/switch/src/LionSwitchButton.js +14 -1
  33. package/components/switch/test/lion-switch-button.test.js +15 -1
  34. package/components/switch/test/lion-switch.test.js +21 -6
  35. package/components/validate-messages/src/loadDefaultFeedbackMessagesNoSideEffects.js +11 -8
  36. package/components/validate-messages/translations/bg.js +4 -0
  37. package/components/validate-messages/translations/cs.js +2 -0
  38. package/components/validate-messages/translations/de.js +4 -0
  39. package/components/validate-messages/translations/en.js +2 -0
  40. package/components/validate-messages/translations/es.js +4 -0
  41. package/components/validate-messages/translations/fr.js +4 -0
  42. package/components/validate-messages/translations/hu.js +2 -0
  43. package/components/validate-messages/translations/it.js +4 -0
  44. package/components/validate-messages/translations/nl.js +4 -0
  45. package/components/validate-messages/translations/pl.js +2 -0
  46. package/components/validate-messages/translations/ro.js +4 -0
  47. package/components/validate-messages/translations/ru.js +4 -0
  48. package/components/validate-messages/translations/sk.js +2 -0
  49. package/components/validate-messages/translations/uk.js +4 -0
  50. package/components/validate-messages/translations/zh.js +2 -0
  51. package/custom-elements.json +1850 -115
  52. package/dist-types/components/combobox/src/LionCombobox.d.ts +37 -13
  53. package/dist-types/components/combobox/src/LionCombobox.d.ts.map +1 -1
  54. package/dist-types/components/combobox/src/validators.d.ts +13 -0
  55. package/dist-types/components/combobox/src/validators.d.ts.map +1 -0
  56. package/dist-types/components/combobox/test/lion-combobox.test.d.ts +0 -2
  57. package/dist-types/components/combobox/test/lion-combobox.test.d.ts.map +1 -1
  58. package/dist-types/components/combobox/test/validators.test.d.ts +2 -0
  59. package/dist-types/components/combobox/test/validators.test.d.ts.map +1 -0
  60. package/dist-types/components/combobox/test-helpers/combobox-helpers.d.ts +41 -0
  61. package/dist-types/components/combobox/test-helpers/combobox-helpers.d.ts.map +1 -0
  62. package/dist-types/components/combobox/translations/bg.d.ts +5 -0
  63. package/dist-types/components/combobox/translations/bg.d.ts.map +1 -0
  64. package/dist-types/components/combobox/translations/cs.d.ts +5 -0
  65. package/dist-types/components/combobox/translations/cs.d.ts.map +1 -0
  66. package/dist-types/components/combobox/translations/de.d.ts +5 -0
  67. package/dist-types/components/combobox/translations/de.d.ts.map +1 -0
  68. package/dist-types/components/combobox/translations/en.d.ts +5 -0
  69. package/dist-types/components/combobox/translations/en.d.ts.map +1 -0
  70. package/dist-types/components/combobox/translations/es.d.ts +5 -0
  71. package/dist-types/components/combobox/translations/es.d.ts.map +1 -0
  72. package/dist-types/components/combobox/translations/fr.d.ts +5 -0
  73. package/dist-types/components/combobox/translations/fr.d.ts.map +1 -0
  74. package/dist-types/components/combobox/translations/hu.d.ts +5 -0
  75. package/dist-types/components/combobox/translations/hu.d.ts.map +1 -0
  76. package/dist-types/components/combobox/translations/it.d.ts +5 -0
  77. package/dist-types/components/combobox/translations/it.d.ts.map +1 -0
  78. package/dist-types/components/combobox/translations/nl.d.ts +5 -0
  79. package/dist-types/components/combobox/translations/nl.d.ts.map +1 -0
  80. package/dist-types/components/combobox/translations/pl.d.ts +5 -0
  81. package/dist-types/components/combobox/translations/pl.d.ts.map +1 -0
  82. package/dist-types/components/combobox/translations/ro.d.ts +5 -0
  83. package/dist-types/components/combobox/translations/ro.d.ts.map +1 -0
  84. package/dist-types/components/combobox/translations/ru.d.ts +5 -0
  85. package/dist-types/components/combobox/translations/ru.d.ts.map +1 -0
  86. package/dist-types/components/combobox/translations/sk.d.ts +5 -0
  87. package/dist-types/components/combobox/translations/sk.d.ts.map +1 -0
  88. package/dist-types/components/combobox/translations/uk.d.ts +5 -0
  89. package/dist-types/components/combobox/translations/uk.d.ts.map +1 -0
  90. package/dist-types/components/combobox/translations/zh.d.ts +5 -0
  91. package/dist-types/components/combobox/translations/zh.d.ts.map +1 -0
  92. package/dist-types/components/form-core/types/choice-group/ChoiceGroupMixinTypes.d.ts +4 -3
  93. package/dist-types/components/form-core/types/choice-group/ChoiceGroupMixinTypes.d.ts.map +1 -1
  94. package/dist-types/components/input-datepicker/src/LionInputDatepicker.d.ts +4 -0
  95. package/dist-types/components/input-datepicker/src/LionInputDatepicker.d.ts.map +1 -1
  96. package/dist-types/components/listbox/src/ListboxMixin.d.ts.map +1 -1
  97. package/dist-types/components/listbox/test-suites/ListboxMixin.suite.d.ts.map +1 -1
  98. package/dist-types/components/overlays/src/OverlayController.d.ts.map +1 -1
  99. package/dist-types/components/switch/src/LionSwitch.d.ts +0 -1
  100. package/dist-types/components/switch/src/LionSwitch.d.ts.map +1 -1
  101. package/dist-types/components/switch/src/LionSwitchButton.d.ts +3 -0
  102. package/dist-types/components/switch/src/LionSwitchButton.d.ts.map +1 -1
  103. package/dist-types/components/switch/test/lion-switch.test.d.ts +1 -1
  104. package/dist-types/components/switch/test/lion-switch.test.d.ts.map +1 -1
  105. package/dist-types/components/validate-messages/src/loadDefaultFeedbackMessagesNoSideEffects.d.ts.map +1 -1
  106. package/dist-types/components/validate-messages/translations/bg-BG.d.ts +2 -0
  107. package/dist-types/components/validate-messages/translations/bg.d.ts +3 -0
  108. package/dist-types/components/validate-messages/translations/cs-CZ.d.ts +2 -0
  109. package/dist-types/components/validate-messages/translations/cs.d.ts +3 -0
  110. package/dist-types/components/validate-messages/translations/de-DE.d.ts +2 -0
  111. package/dist-types/components/validate-messages/translations/de.d.ts +3 -0
  112. package/dist-types/components/validate-messages/translations/en-AU.d.ts +2 -0
  113. package/dist-types/components/validate-messages/translations/en-GB.d.ts +2 -0
  114. package/dist-types/components/validate-messages/translations/en-PH.d.ts +2 -0
  115. package/dist-types/components/validate-messages/translations/en-US.d.ts +2 -0
  116. package/dist-types/components/validate-messages/translations/en.d.ts +3 -0
  117. package/dist-types/components/validate-messages/translations/es-ES.d.ts +2 -0
  118. package/dist-types/components/validate-messages/translations/es.d.ts +3 -0
  119. package/dist-types/components/validate-messages/translations/fr-BE.d.ts +2 -0
  120. package/dist-types/components/validate-messages/translations/fr-FR.d.ts +2 -0
  121. package/dist-types/components/validate-messages/translations/fr.d.ts +3 -0
  122. package/dist-types/components/validate-messages/translations/hu-HU.d.ts +2 -0
  123. package/dist-types/components/validate-messages/translations/hu.d.ts +3 -0
  124. package/dist-types/components/validate-messages/translations/it-IT.d.ts +2 -0
  125. package/dist-types/components/validate-messages/translations/it.d.ts +3 -0
  126. package/dist-types/components/validate-messages/translations/nl-BE.d.ts +2 -0
  127. package/dist-types/components/validate-messages/translations/nl-NL.d.ts +2 -0
  128. package/dist-types/components/validate-messages/translations/nl.d.ts +3 -0
  129. package/dist-types/components/validate-messages/translations/pl-PL.d.ts +2 -0
  130. package/dist-types/components/validate-messages/translations/pl.d.ts +3 -0
  131. package/dist-types/components/validate-messages/translations/ro-RO.d.ts +2 -0
  132. package/dist-types/components/validate-messages/translations/ro.d.ts +3 -0
  133. package/dist-types/components/validate-messages/translations/ru-RU.d.ts +2 -0
  134. package/dist-types/components/validate-messages/translations/ru.d.ts +3 -0
  135. package/dist-types/components/validate-messages/translations/sk-SK.d.ts +2 -0
  136. package/dist-types/components/validate-messages/translations/sk.d.ts +3 -0
  137. package/dist-types/components/validate-messages/translations/uk-UA.d.ts +2 -0
  138. package/dist-types/components/validate-messages/translations/uk.d.ts +3 -0
  139. package/dist-types/components/validate-messages/translations/zh.d.ts +3 -0
  140. package/dist-types/exports/combobox-test-helpers.d.ts +2 -0
  141. package/dist-types/exports/combobox-test-helpers.d.ts.map +1 -0
  142. package/dist-types/exports/combobox.d.ts +1 -0
  143. package/dist-types/tsconfig.tsbuildinfo +1 -1
  144. package/docs/components/checkbox-group/overview.md +2 -2
  145. package/docs/components/collapsible/overview.md +1 -1
  146. package/docs/components/combobox/overview.md +12 -2
  147. package/docs/components/combobox/use-cases.md +36 -1
  148. package/docs/components/dialog/overview.md +1 -1
  149. package/docs/components/fieldset/overview.md +5 -5
  150. package/docs/components/form/overview.md +3 -3
  151. package/docs/components/icon/use-cases.md +1 -1
  152. package/docs/components/input/overview.md +1 -1
  153. package/docs/components/input-amount/overview.md +3 -3
  154. package/docs/components/input-date/overview.md +3 -3
  155. package/docs/components/input-datepicker/overview.md +5 -5
  156. package/docs/components/input-email/overview.md +2 -2
  157. package/docs/components/input-iban/overview.md +2 -2
  158. package/docs/components/input-range/overview.md +2 -2
  159. package/docs/components/input-stepper/overview.md +1 -1
  160. package/docs/components/input-tel/overview.md +1 -1
  161. package/docs/components/input-tel/use-cases.md +6 -6
  162. package/docs/components/input-tel-dropdown/overview.md +1 -1
  163. package/docs/components/radio-group/overview.md +3 -3
  164. package/docs/components/select-rich/use-cases.md +1 -1
  165. package/docs/components/tabs/examples.md +1 -1
  166. package/docs/fundamentals/index.md +4 -4
  167. package/docs/fundamentals/node-tools/providence-analytics/LocalConfiguration.md +1 -1
  168. package/docs/fundamentals/node-tools/providence-analytics/QueryResult.md +1 -1
  169. package/docs/fundamentals/node-tools/providence-analytics/analyzer.md +1 -1
  170. package/docs/fundamentals/node-tools/providence-analytics/dashboard.md +1 -1
  171. package/docs/fundamentals/node-tools/providence-analytics/overview.md +3 -3
  172. package/docs/fundamentals/node-tools/publish-docs/overview.md +3 -3
  173. package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +2 -2
  174. package/docs/fundamentals/systems/core/overview.md +1 -1
  175. package/docs/fundamentals/systems/form/formatting-and-parsing.md +4 -4
  176. package/docs/fundamentals/systems/form/model-value.md +1 -1
  177. package/docs/fundamentals/systems/form/overview.md +28 -28
  178. package/docs/fundamentals/systems/form/validate.md +1 -1
  179. package/docs/fundamentals/systems/localize/overview.md +4 -4
  180. package/docs/fundamentals/systems/overlays/configuration.md +2 -2
  181. package/docs/fundamentals/systems/overlays/overview.md +5 -5
  182. package/docs/fundamentals/systems/overlays/use-cases.md +2 -2
  183. package/docs/fundamentals/tools/helpers/overview.md +1 -1
  184. package/docs/fundamentals/tools/singleton-manager/overview.md +4 -4
  185. package/docs/guides/how-to/create-a-custom-field.md +5 -5
  186. package/docs/guides/how-to/extend-a-native-input.md +2 -2
  187. package/docs/guides/index.md +8 -8
  188. package/docs/guides/principles/index.md +5 -5
  189. package/docs/guides/principles/styling.md +1 -1
  190. package/exports/combobox-test-helpers.js +1 -0
  191. package/exports/combobox.js +1 -0
  192. package/package.json +2 -1
package/README.md ADDED
@@ -0,0 +1,222 @@
1
+ <p align="center">
2
+ <img
3
+ width="20%"
4
+ src="./docs/_assets/logo.svg"
5
+ alt="Lion"
6
+ />
7
+ <h1 style="text-align: center;">Lion</h1>
8
+ </p>
9
+
10
+ <p align="center">
11
+ <a href="https://github.com/modernweb-dev/rocket/actions"
12
+ ><img
13
+ src="https://img.shields.io/github/workflow/status/modernweb-dev/rocket/Release/main?label=workflow&style=flat-square"
14
+ alt="GitHub Actions workflow status"
15
+ /></a>
16
+ <a href="https://github.com/modernweb-dev/rocket/actions"
17
+ ><img
18
+ src="https://img.shields.io/github/workflow/status/modernweb-dev/rocket/Release/main?label=workflow&style=flat-square"
19
+ alt="GitHub Actions workflow status"
20
+ /></a>
21
+ <a href="https://www.tickgit.com/browse?repo=github.com/ing-bank/lion"
22
+ ><img
23
+ src="https://badgen.net/https/api.tickgit.com/badgen/github.comgithub.com/ing-bank/lion"
24
+ alt="Todos"
25
+ /></a>
26
+ </p>
27
+
28
+ <p align="center">
29
+ <a href="https://lion-web.netlify.app">Website</a>
30
+ ·
31
+ <a href="https://lion-web.netlify.app/guides/">Guides</a>
32
+ ·
33
+ <a href="https://lion-web.netlify.app/components/">Components</a>
34
+ ·
35
+ <a href="https://lion-web.netlify.app/docs/">Documentation</a>
36
+ ·
37
+ <a href="https://lion-web.netlify.app/blog/">Blog</a>
38
+ </p>
39
+
40
+ **Lion is a set of highly performant, accessible and flexible Web Components.!**
41
+
42
+ They provide an unopinionated, white-label layer that can be extended to your own layer of components.
43
+
44
+ - **High Performance:** Focused on great performance in all relevant browsers with a minimal number of dependencies.
45
+ - **Accessibility:** Aimed at compliance with the WCAG 2.1 AA standard to create components that are accessible for everybody.
46
+ - **Flexibility:** Provides solutions through Web Components and JavaScript classes which can be used, adopted and extended to fit all needs.
47
+ - **Modern Code:** Lion is distributes as pure es modules.
48
+ - **Exposes functions/classes and Web Components:** Ships a functionality in it's most appropriate form.
49
+
50
+ > Note: Our demos may look a little bland but that is on purpose. They only come with functional stylings.
51
+ > This makes sense as the main use case is to extend those components and if you do you do not want to override existing stylings.
52
+
53
+ <p align="center">
54
+ <a href="https://lion-web.netlify.app/guides/"><strong>Explore the Lion Guides&nbsp;&nbsp;▶</strong></a>
55
+ </p>
56
+
57
+ ## How to install
58
+
59
+ ```bash
60
+ npm i @lion/<package-name>
61
+ ```
62
+
63
+ ## How to use
64
+
65
+ ### Extend a Web Component
66
+
67
+ **This is the main use case for lion**. To import component classes, and extend them for your own design system's components.
68
+
69
+ ```js
70
+ import { css } from 'lit';
71
+ import { LionInput } from '@lion/input';
72
+
73
+ class MyInput extends LionInput {
74
+ static get styles() {
75
+ return [
76
+ super.styles,
77
+ css`
78
+ /* your styles here */
79
+ `,
80
+ ];
81
+ }
82
+ }
83
+ customElements.define('my-input', MyInput);
84
+ ```
85
+
86
+ ### Use a JavaScript system
87
+
88
+ There's a couple of "systems" in lion which have a JavaScript API. Examples are `localize`, `overlays`, `ajax`, etc.
89
+
90
+ ```html
91
+ <script type="module">
92
+ import { ajax } from '@lion/ajax';
93
+
94
+ ajax
95
+ .fetch('data.json')
96
+ .then(response => response.json())
97
+ .then(data => {
98
+ // do something with the data
99
+ });
100
+ </script>
101
+ ```
102
+
103
+ ### Use a Web Component
104
+
105
+ You can also use the lion elements directly, although this is likely not a common use case.
106
+
107
+ ```html
108
+ <script type="module">
109
+ import '@lion/input/define';
110
+ </script>
111
+
112
+ <lion-input name="firstName"></lion-input>
113
+ ```
114
+
115
+ ## Issues
116
+
117
+ If you encounter an issue with any of the packages we are offering please open a [new bug issue](https://github.com/ing-bank/lion/issues/new?assignees=&labels=&template=bug_report.md&title=). Be sure to include a description of the expected and the current behavior - additional adding a [reproduction](https://webcomponents.dev/edit/kpZmz1CJN580OaXsk56f?pm=1) always helps.
118
+
119
+ ## Feature requests
120
+
121
+ When you have an idea on how we could improve, please check our [discussions](https://github.com/ing-bank/lion/discussions) to see if there are similar ideas or feature requests. If there are none, please [start](https://github.com/ing-bank/lion/discussions/new) your feature request as a new discussion topic. Add the title `[Feature Request] My awesome feature` and a description of what you expect from the improvement and what the use case is.
122
+
123
+ ## Content
124
+
125
+ Lion web components is logically organized in groups of systems.
126
+
127
+ The accessibility column indicates whether the functionality is accessible in its core. Aspects like styling and content determine actual accessibility in usage.
128
+
129
+ | Package | Version | Description | Accessibility |
130
+ | ------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | -------------------------- |
131
+ | **-- [Form System](https://lion-web.netlify.app/fundamentals/systems/form/overview/) --** | | A system that lets you make complex forms with ease, including: validation, translations. | ✔️ |
132
+ | [combobox](https://lion-web.netlify.app/components/combobox/overview/) | [![combobox](https://img.shields.io/npm/v/@lion/combobox.svg)](https://www.npmjs.com/package/@lion/form) | Text box controlling popup listbox | ✔️ |
133
+ | [form](https://lion-web.netlify.app/components/form/overview) | [![form](https://img.shields.io/npm/v/@lion/form.svg)](https://www.npmjs.com/package/@lion/form) | Wrapper for multiple form elements | ✔️ |
134
+ | [form-core](https://lion-web.netlify.app/fundamentals/systems/form/overview/) | [![form-core](https://img.shields.io/npm/v/@lion/form-core.svg)](https://www.npmjs.com/package/@lion/form-core) | Core functionality for all form controls | ✔️ |
135
+ | [form-integrations](https://lion-web.netlify.app/fundamentals/systems/form/overview/) | [![form-integrations](https://img.shields.io/npm/v/@lion/form-integrations.svg)](https://www.npmjs.com/package/@lion/form-integrations) | Shows form elements in an integrated way | ✔️ |
136
+ | [fieldset](https://lion-web.netlify.app/components/fieldset/overview/) | [![fieldset](https://img.shields.io/npm/v/@lion/fieldset.svg)](https://www.npmjs.com/package/@lion/fieldset) | Group for form inputs | ✔️ |
137
+ | [checkbox-group](https://lion-web.netlify.app/components/checkbox-group/overview/) | [![checkbox-group](https://img.shields.io/npm/v/@lion/checkbox-group.svg)](https://www.npmjs.com/package/@lion/checkbox-group) | Group of checkboxes | ✔️ |
138
+ | [input](https://lion-web.netlify.app/components/input/overview/) | [![input](https://img.shields.io/npm/v/@lion/input.svg)](https://www.npmjs.com/package/@lion/input) | Input element for strings | ✔️ |
139
+ | [input-amount](https://lion-web.netlify.app/components/input-amount/overview/) | [![input-amount](https://img.shields.io/npm/v/@lion/input-amount.svg)](https://www.npmjs.com/package/@lion/input-amount) | Input element for amounts | ✔️ |
140
+ | [input-date](https://lion-web.netlify.app/components/input-date/overview/) | [![input-date](https://img.shields.io/npm/v/@lion/input-date.svg)](https://www.npmjs.com/package/@lion/input-date) | Input element for dates | ✔️ |
141
+ | [input-datepicker](https://lion-web.netlify.app/components/input-datepicker/overview/) | [![input-datepicker](https://img.shields.io/npm/v/@lion/input-datepicker.svg)](https://www.npmjs.com/package/@lion/input-datepicker) | Input element for dates with a datepicker | ✔️ |
142
+ | [input-email](https://lion-web.netlify.app/components/input-email/overview/) | [![input-email](https://img.shields.io/npm/v/@lion/input-email.svg)](https://www.npmjs.com/package/@lion/input-email) | Input element for e-mails | ✔️ |
143
+ | [input-iban](https://lion-web.netlify.app/components/input-iban/overview/) | [![input-iban](https://img.shields.io/npm/v/@lion/input-iban.svg)](https://www.npmjs.com/package/@lion/input-iban) | Input element for IBANs | ✔️ |
144
+ | [input-range](https://lion-web.netlify.app/components/input-range/overview/) | [![input-range](https://img.shields.io/npm/v/@lion/input-range.svg)](https://www.npmjs.com/package/@lion/input-range) | Input element for a range of values | ✔️ |
145
+ | [input-stepper](https://lion-web.netlify.app/components/input-stepper/overview/) | [![input-stepper](https://img.shields.io/npm/v/@lion/input-stepper.svg)](https://www.npmjs.com/package/@lion/input-stepper) | Input stepper element for the predefined range | ✔️ |
146
+ | [listbox](https://lion-web.netlify.app/components/listbox/overview/) | [![listbox](https://img.shields.io/npm/v/@lion/listbox.svg)](https://www.npmjs.com/package/@lion/form) | Interactive list with selectable options | ✔️ |
147
+ | [radio-group](https://lion-web.netlify.app/components/radio-group/overview/) | [![radio-group](https://img.shields.io/npm/v/@lion/radio-group.svg)](https://www.npmjs.com/package/@lion/radio-group) | Group of radios | ✔️ |
148
+ | [select](https://lion-web.netlify.app/components/select/overview/) | [![select](https://img.shields.io/npm/v/@lion/select.svg)](https://www.npmjs.com/package/@lion/select) | Simple native dropdown element | ✔️ |
149
+ | [select-rich](https://lion-web.netlify.app/components/select-rich/overview/) | [![select-rich](https://img.shields.io/npm/v/@lion/select-rich.svg)](https://www.npmjs.com/package/@lion/select-rich) | 'rich' version of the native dropdown element | [#243][i243] |
150
+ | [textarea](https://lion-web.netlify.app/components/textarea/overview/) | [![textarea](https://img.shields.io/npm/v/@lion/textarea.svg)](https://www.npmjs.com/package/@lion/textarea) | Multiline text input | ✔️ |
151
+ | **-- [Button System](https://lion-web.netlify.app/components/buttons-intro--page) --** | | These web components bring common UX patterns while still full integrated with (native) forms. | |
152
+ | [button](https://lion-web.netlify.app/components/button/overview/) | [![button](https://img.shields.io/npm/v/@lion/button.svg)](https://www.npmjs.com/package/@lion/button) | Button | ✔️ |
153
+ | [switch](https://lion-web.netlify.app/components/switch/overview/) | [![switch](https://img.shields.io/npm/v/@lion/switch.svg)](https://www.npmjs.com/package/@lion/switch) | Switch | ✔️ |
154
+ | **-- [Overlay System](https://lion-web.netlify.app/components/overlays-intro--page) --** | | If something needs to overlay content this is your place. | |
155
+ | [overlays](https://lion-web.netlify.app/fundamentals/systems/overlays/overview/) | [![overlays](https://img.shields.io/npm/v/@lion/overlays.svg)](https://www.npmjs.com/package/@lion/overlays) | Overlay System | ✔️ |
156
+ | [dialog](https://lion-web.netlify.app/components/dialog/overview/) | [![dialog](https://img.shields.io/npm/v/@lion/dialog.svg)](https://www.npmjs.com/package/@lion/dialog) | Dialog element | ✔️ |
157
+ | [tooltip](https://lion-web.netlify.app/components/tooltip/overview/) | [![tooltip](https://img.shields.io/npm/v/@lion/tooltip.svg)](https://www.npmjs.com/package/@lion/tooltip) | Tooltip element | [#175][i175] |
158
+ | **-- [Navigation System](https://lion-web.netlify.app/components/navigation-intro--page) --** | | Components which are used to guide users | |
159
+ | [accordion](https://lion-web.netlify.app/components/accordion/overview/) | [![accordion](https://img.shields.io/npm/v/@lion/accordion.svg)](https://www.npmjs.com/package/@lion/accordion) | Accordion | ✔️ |
160
+ | [pagination](https://lion-web.netlify.app/components/pagination/overview/) | [![pagination](https://img.shields.io/npm/v/@lion/pagination.svg)](https://www.npmjs.com/package/@lion/pagination) | Pagination | ✔️ |
161
+ | [steps](https://lion-web.netlify.app/components/steps/overview) | [![steps](https://img.shields.io/npm/v/@lion/steps.svg)](https://www.npmjs.com/package/@lion/steps) | Multi Step System | n/a |
162
+ | [tabs](https://lion-web.netlify.app/components/tabs/overview) | [![tBS](https://img.shields.io/npm/v/@lion/tabs.svg)](https://www.npmjs.com/package/@lion/tabs) | Move between a small number of equally important views | n/a |
163
+ | **-- [localize System](https://lion-web.netlify.app/fundamentals/systems/localize/overview/) --** | | Localize text, numbers, dates and a way to store/fetch these data. | |
164
+ | [localize](https://lion-web.netlify.app/fundamentals/systems/localize/overview/) | [![localize](https://img.shields.io/npm/v/@lion/localize.svg)](https://www.npmjs.com/package/@lion/localize) | Localize and translate your application/components | n/a |
165
+ | **-- [Icon System](https://lion-web.netlify.app/fundamentals/systems/icon/overview/) --** | | Loading and displaying icons | |
166
+ | [icon](https://lion-web.netlify.app/fundamentals/systems/icon/overview/) | [![icon](https://img.shields.io/npm/v/@lion/icon.svg)](https://www.npmjs.com/package/@lion/icon) | Display our svg icons | [#173][i173], [#172][i172] |
167
+ | **-- Others --** | | Features not fitting any other category | |
168
+ | [core](https://lion-web.netlify.app/fundamentals/systems/core/overview/) | [![core](https://img.shields.io/npm/v/@lion/core.svg)](https://www.npmjs.com/package/@lion/core) | Core System (exports LitElement, lit-html) | n/a |
169
+ | [ajax](https://lion-web.netlify.app/fundamentals/tools/ajax/overview/) | [![ajax](https://img.shields.io/npm/v/@lion/ajax.svg)](https://www.npmjs.com/package/@lion/ajax) | Fetching data via ajax request | n/a |
170
+ | [calendar](https://lion-web.netlify.app/components/calendar/overview/) | [![calendar](https://img.shields.io/npm/v/@lion/calendar.svg)](https://www.npmjs.com/package/@lion/calendar) | Standalone calendar | [#195][i195], [#194][i194] |
171
+ | [collapsible](https://lion-web.netlify.app/components/collapsible/overview/) | [![collapsible](https://img.shields.io/npm/v/@lion/collapsible.svg)](https://www.npmjs.com/package/@lion/collapsible) | Combination of a button and a chunk of extra content | ✔️ |
172
+ | **-- [Helpers](https://lion-web.netlify.app/fundamentals/tools/helpers/overview/) --** | [![helpers](https://img.shields.io/npm/v/@lion/helpers.svg)](https://www.npmjs.com/package/@lion/helpers) | Helpers to make your and your life easier | |
173
+ | [sb-action-logger](https://lion-web.netlify.app/fundamentals/tools/helpers/action-logger/) | | Storybook action logger |
174
+
175
+ ## Technologies
176
+
177
+ Lion Web Components aims to be future-proof and use well-supported proven technology. The stack we have chosen should reflect this.
178
+
179
+ - [lit](https://lit.dev/)
180
+ - [npm](http://npmjs.com)
181
+ - [Open Web Components](https://open-wc.org)
182
+ - [Modern Web](https://modern-web.dev)
183
+ - [Mocha](https://mochajs.org)
184
+ - [Chai](https://www.chaijs.com)
185
+ - [ESLint](https://eslint.org)
186
+ - [prettier](https://prettier.io)
187
+ - [ES modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import)
188
+ - Lots and lots of tests
189
+
190
+ ## Rationale
191
+
192
+ We know from experience that making high quality, accessible UI components is hard and time consuming:
193
+ it takes many iterations, a lot of development time and a lot of testing to get a generic component that works in every
194
+ context, supports many edge cases and is accessible in all relevant screen readers.
195
+
196
+ Lion aims to do the heavy lifting for you.
197
+ This means you only have to apply your own Design System: by delivering styles, configuring components and adding a minimal set of custom logic on top.
198
+
199
+ ## Coding guidelines
200
+
201
+ Check out our [coding guidelines](https://lion-web.netlify.app/guides/principles/definitions-and-terms/) for more detailed information.
202
+
203
+ ## How to contribute
204
+
205
+ **Please note:** This project uses Npm [Workspaces](https://docs.npmjs.com/cli/v8/using-npm/workspaces). If you want to run all demos locally you need to get at least npm 7+ and install all dependencies by executing `npm install`.
206
+
207
+ Lion Web Components are only as good as its contributions.
208
+ Read our [contribution guide](https://github.com/ing-bank/lion/blob/master/CONTRIBUTING.md) and feel free to enhance/improve Lion. We keep feature requests closed while we're not working on them.
209
+
210
+ ## Contact
211
+
212
+ Feel free to create a github issue for any feedback or questions you might have.
213
+ You can also find us on the Lit & Friends slack in the [#lion](https://lit-and-friends.slack.com/archives/CJGFWJN9J) channel.
214
+
215
+ You can join the Lit & Friends slack by visiting [https://lit.dev/slack-invite/](https://lit.dev/slack-invite/).
216
+
217
+ [i172]: https://github.com/ing-bank/lion/issues/172
218
+ [i173]: https://github.com/ing-bank/lion/issues/173
219
+ [i175]: https://github.com/ing-bank/lion/issues/175
220
+ [i194]: https://github.com/ing-bank/lion/issues/194
221
+ [i195]: https://github.com/ing-bank/lion/issues/195
222
+ [i243]: https://github.com/ing-bank/lion/issues/243
@@ -171,12 +171,12 @@ export class LionAccordion extends LitElement {
171
171
 
172
172
  const invokers = /** @type {HTMLElement[]} */ ([
173
173
  ...Array.from(existingInvokers),
174
- ...Array.from(this.querySelectorAll('[slot="invoker"]')),
174
+ ...Array.from(this.querySelectorAll(':scope > [slot="invoker"]')),
175
175
  ]);
176
176
 
177
177
  const contents = /** @type {HTMLElement[]} */ ([
178
178
  ...Array.from(existingContent),
179
- ...Array.from(this.querySelectorAll('[slot="content"]')),
179
+ ...Array.from(this.querySelectorAll(':scope > [slot="content"]')),
180
180
  ]);
181
181
 
182
182
  if (invokers.length !== contents.length) {
@@ -126,6 +126,37 @@ describe('<lion-accordion>', () => {
126
126
  );
127
127
  stub.restore();
128
128
  });
129
+
130
+ it('does not select any elements with slot="invoker" and slot="content" inside slotted elements', async () => {
131
+ const stub = sinon.stub(console, 'warn');
132
+ const el = /** @type {LionAccordion} */ (
133
+ await fixture(html`
134
+ <lion-accordion>
135
+ <h2 slot="invoker">
136
+ <button>invoker 1</button>
137
+ <button slot="invoker">Nested invoker</button>
138
+ </h2>
139
+ <h2 slot="invoker"><button>invoker 2</button></h2>
140
+ <div slot="content">
141
+ content 1
142
+ <p slot="content">Nested content 1</p>
143
+ </div>
144
+ <div slot="content">
145
+ content 2
146
+ <p slot="content">Nested content 2</p>
147
+ </div>
148
+ </lion-accordion>
149
+ `)
150
+ );
151
+
152
+ const invokers = Array.from(getInvokers(el));
153
+ const contents = Array.from(getContents(el));
154
+
155
+ expect(stub.called).to.be.false;
156
+ expect(invokers.length).to.equal(contents.length);
157
+
158
+ stub.restore();
159
+ });
129
160
  });
130
161
 
131
162
  describe('Accordion navigation', () => {
@@ -1,8 +1,11 @@
1
1
  import { browserDetection } from '@lion/ui/core.js';
2
+ import { Unparseable } from '@lion/ui/form-core.js';
2
3
  import { LionListbox } from '@lion/ui/listbox.js';
4
+ import { LocalizeMixin } from '@lion/ui/localize-no-side-effects.js';
3
5
  import { OverlayMixin, withDropdownConfig } from '@lion/ui/overlays.js';
4
6
  import { css, html } from 'lit';
5
7
  import { makeMatchingTextBold, unmakeMatchingTextBold } from './utils/makeMatchingTextBold.js';
8
+ import { MatchesOption } from './validators.js';
6
9
 
7
10
  const matchA11ySpanReverseFns = new WeakMap();
8
11
 
@@ -11,12 +14,12 @@ const matchA11ySpanReverseFns = new WeakMap();
11
14
  // on Listbox or ListNavigationWithActiveDescendantMixin
12
15
 
13
16
  /**
14
- * @typedef {import('../../listbox/src/LionOption.js').LionOption} LionOption
15
- * @typedef {import('../../listbox/src/LionOptions.js').LionOptions} LionOptions
16
- * @typedef {import('../../overlays/types/OverlayConfig.js').OverlayConfig} OverlayConfig
17
- * @typedef {import('../../core/types/SlotMixinTypes.js').SlotsMap} SlotsMap
18
- * @typedef {import('../../form-core/types/choice-group/ChoiceInputMixinTypes.js').ChoiceInputHost} ChoiceInputHost
19
- * @typedef {import('../../form-core/types/FormControlMixinTypes.js').FormControlHost} FormControlHost
17
+ * @typedef {import('@lion/ui/listbox.js').LionOption} LionOption
18
+ * @typedef {import('@lion/ui/listbox.js').LionOptions} LionOptions
19
+ * @typedef {import('@lion/ui/types/overlays.js').OverlayConfig} OverlayConfig
20
+ * @typedef {import('@lion/ui/types/core.js').SlotsMap} SlotsMap
21
+ * @typedef {import('@lion/ui/types/form-core.js').ChoiceInputHost} ChoiceInputHost
22
+ * @typedef {import('@lion/ui/types/form-core.js').FormControlHost} FormControlHost
20
23
  * @typedef {import('../types/SelectionDisplay.js').SelectionDisplay} SelectionDisplay
21
24
  */
22
25
 
@@ -24,7 +27,7 @@ const matchA11ySpanReverseFns = new WeakMap();
24
27
  * LionCombobox: implements the wai-aria combobox design pattern and integrates it as a Lion
25
28
  * FormControl
26
29
  */
27
- export class LionCombobox extends OverlayMixin(LionListbox) {
30
+ export class LionCombobox extends LocalizeMixin(OverlayMixin(LionListbox)) {
28
31
  /** @type {any} */
29
32
  static get properties() {
30
33
  return {
@@ -37,6 +40,9 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
37
40
  type: Boolean,
38
41
  attribute: 'show-all-on-empty',
39
42
  },
43
+ requireOptionMatch: {
44
+ type: Boolean,
45
+ },
40
46
  __shouldAutocompleteNextUpdate: Boolean,
41
47
  };
42
48
  }
@@ -75,6 +81,125 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
75
81
  ];
76
82
  }
77
83
 
84
+ static get localizeNamespaces() {
85
+ return [
86
+ {
87
+ 'lion-combobox': /** @param {string} locale */ locale => {
88
+ switch (locale) {
89
+ case 'bg-BG':
90
+ case 'bg':
91
+ return import('@lion/ui/combobox-translations/bg.js');
92
+ case 'cs-CZ':
93
+ case 'cs':
94
+ return import('@lion/ui/combobox-translations/cs.js');
95
+ case 'de-AT':
96
+ case 'de-DE':
97
+ case 'de':
98
+ return import('@lion/ui/combobox-translations/de.js');
99
+ case 'en-AU':
100
+ case 'en-GB':
101
+ case 'en-PH':
102
+ case 'en-US':
103
+ case 'en':
104
+ return import('@lion/ui/combobox-translations/en.js');
105
+ case 'es-ES':
106
+ case 'es':
107
+ return import('@lion/ui/combobox-translations/es.js');
108
+ case 'fr-FR':
109
+ case 'fr-BE':
110
+ case 'fr':
111
+ return import('@lion/ui/combobox-translations/fr.js');
112
+ case 'hu-HU':
113
+ case 'hu':
114
+ return import('@lion/ui/combobox-translations/hu.js');
115
+ case 'it-IT':
116
+ case 'it':
117
+ return import('@lion/ui/combobox-translations/it.js');
118
+ case 'nl-BE':
119
+ case 'nl-NL':
120
+ case 'nl':
121
+ return import('@lion/ui/combobox-translations/nl.js');
122
+ case 'pl-PL':
123
+ case 'pl':
124
+ return import('@lion/ui/combobox-translations/pl.js');
125
+ case 'ro-RO':
126
+ case 'ro':
127
+ return import('@lion/ui/combobox-translations/ro.js');
128
+ case 'ru-RU':
129
+ case 'ru':
130
+ return import('@lion/ui/combobox-translations/ru.js');
131
+ case 'sk-SK':
132
+ case 'sk':
133
+ return import('@lion/ui/combobox-translations/sk.js');
134
+ case 'uk-UA':
135
+ case 'uk':
136
+ return import('@lion/ui/combobox-translations/uk.js');
137
+ case 'zh-CN':
138
+ case 'zh':
139
+ return import('@lion/ui/combobox-translations/zh.js');
140
+ default:
141
+ return import('@lion/ui/combobox-translations/en.js');
142
+ }
143
+ },
144
+ },
145
+ ...super.localizeNamespaces,
146
+ ];
147
+ }
148
+
149
+ /**
150
+ * @override ChoiceGroupMixin
151
+ */
152
+ // @ts-ignore
153
+ get modelValue() {
154
+ const choiceGroupModelValue = super.modelValue;
155
+ if (choiceGroupModelValue !== '') {
156
+ return choiceGroupModelValue;
157
+ }
158
+ // Since the FormatMixin can't be applied to a [FormGroup](https://github.com/ing-bank/lion/blob/master/packages/ui/components/form-core/src/form-group/FormGroupMixin.js)
159
+ // atm, we treat it in a way analogue to InteractionStateMixin (basically same apis, w/o Mixin applied).
160
+ // Hence, modelValue has no reactivity by default and we need to call parser manually here...
161
+ return this.parser(this.value);
162
+ }
163
+
164
+ // Duplicating from ChoiceGroupMixin, because you cannot independently inherit/override getter + setter.
165
+ // If you override one, gotta override the other, they go in pairs.
166
+ /**
167
+ * @override ChoiceGroupMixin
168
+ */
169
+ set modelValue(value) {
170
+ super.modelValue = value;
171
+ }
172
+
173
+ /**
174
+ * We define the value getter/setter below as also defined in LionField (via FormatMixin).
175
+ * Since FormatMixin is meant for Formgroups/ChoiceGroup it's not applied on Combobox;
176
+ * Combobox is somewhat of a hybrid between a ChoiceGroup and LionField, therefore we copy over
177
+ * some of the LionField members to align with its interface.
178
+ *
179
+ * The view value. Will be delegated to `._inputNode.value`
180
+ */
181
+ get value() {
182
+ return this._inputNode?.value || this.__value || '';
183
+ }
184
+
185
+ /** @param {string} value */
186
+ set value(value) {
187
+ // if not yet connected to dom can't change the value
188
+ if (this._inputNode) {
189
+ this._inputNode.value = value;
190
+ /** @type {string | undefined} */
191
+ this.__value = undefined;
192
+ } else {
193
+ this.__value = value;
194
+ }
195
+ }
196
+
197
+ reset() {
198
+ super.reset();
199
+ // @ts-ignore _initialModelValue comes from ListboxMixin
200
+ this.value = this._initialModelValue;
201
+ }
202
+
78
203
  /**
79
204
  * @enhance FormControlMixin - add slot[name=selection-display]
80
205
  * @protected
@@ -94,9 +219,12 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
94
219
  */
95
220
  // eslint-disable-next-line class-methods-use-this
96
221
  _overlayListboxTemplate() {
97
- // TODO: Localize the aria-label
98
222
  return html`
99
- <div id="overlay-content-node-wrapper" role="dialog" aria-label="Combobox options popup">
223
+ <div
224
+ id="overlay-content-node-wrapper"
225
+ role="dialog"
226
+ aria-label="${this.msgLit(`lion-combobox:optionsPopup`)}"
227
+ >
100
228
  <slot name="listbox"></slot>
101
229
  </div>
102
230
  <slot id="options-outlet"></slot>
@@ -187,7 +315,7 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
187
315
  * @protected
188
316
  */
189
317
  get _inputNode() {
190
- if (this._ariaVersion === '1.1') {
318
+ if (this._ariaVersion === '1.1' && this._comboboxNode) {
191
319
  return /** @type {HTMLInputElement} */ (this._comboboxNode.querySelector('input'));
192
320
  }
193
321
  return /** @type {HTMLInputElement} */ (this._comboboxNode);
@@ -258,7 +386,11 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
258
386
  * By default, the listbox closes on empty, similar to wai-aria example and <datalist>
259
387
  */
260
388
  this.showAllOnEmpty = false;
261
-
389
+ /**
390
+ * If set to false, the value is allowed to not match any of the options.
391
+ * We set the default to true for backwards compatibility
392
+ */
393
+ this.requireOptionMatch = true;
262
394
  /**
263
395
  * @configure ListboxMixin: the wai-aria pattern and <datalist> rotate
264
396
  */
@@ -267,7 +399,7 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
267
399
  * @configure ListboxMixin: the wai-aria pattern and <datalist> have selection follow focus
268
400
  */
269
401
  this.selectionFollowsFocus = true;
270
-
402
+ this.defaultValidators.push(new MatchesOption());
271
403
  /**
272
404
  * For optimal support, we allow aria v1.1 on newer browsers
273
405
  * @type {'1.1'|'1.0'}
@@ -353,6 +485,18 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
353
485
  }
354
486
  }
355
487
 
488
+ /**
489
+ * Converts viewValue to modelValue
490
+ * @param {string} value - viewValue: the formatted value inside <input>
491
+ * @returns {*} modelValue
492
+ */
493
+ parser(value) {
494
+ if (this.requireOptionMatch && this.checkedIndex === -1 && value !== '') {
495
+ return new Unparseable(value);
496
+ }
497
+ return value;
498
+ }
499
+
356
500
  /**
357
501
  * When textbox value doesn't match checkedIndex anymore, update accordingly...
358
502
  * @protected
@@ -363,7 +507,7 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
363
507
  if (!this.multipleChoice && !autoselect && checkedElement) {
364
508
  const textboxValue = this._getTextboxValueFromOption(checkedElement);
365
509
  if (!this._inputNode.value.startsWith(textboxValue)) {
366
- this.checkedIndex = -1;
510
+ this.setCheckedIndex(-1);
367
511
  }
368
512
  }
369
513
  }
@@ -411,6 +555,15 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
411
555
  if (typeof this._selectionDisplayNode?.onComboboxElementUpdated === 'function') {
412
556
  this._selectionDisplayNode.onComboboxElementUpdated(changedProperties);
413
557
  }
558
+
559
+ if (changedProperties.has('requireOptionMatch') || changedProperties.has('multipleChoice')) {
560
+ if (!this.requireOptionMatch && this.multipleChoice) {
561
+ // TODO implement !requireOptionMatch and multipleChoice flow
562
+ throw new Error(
563
+ "multipleChoice and requireOptionMatch=false can't be used at the same time (yet).",
564
+ );
565
+ }
566
+ }
414
567
  }
415
568
 
416
569
  /**
@@ -488,7 +641,13 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
488
641
  */
489
642
  // eslint-disable-next-line class-methods-use-this
490
643
  _getTextboxValueFromOption(option) {
491
- return option.choiceValue;
644
+ if (option) {
645
+ return option.choiceValue;
646
+ }
647
+ if (this.modelValue instanceof Unparseable) {
648
+ return this.modelValue.viewValue;
649
+ }
650
+ return this.modelValue;
492
651
  }
493
652
 
494
653
  /**
@@ -745,7 +904,8 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
745
904
 
746
905
  if (isInlineAutoFillCandidate) {
747
906
  const textboxValue = this._getTextboxValueFromOption(option);
748
- const stringValues = typeof textboxValue === 'string' && typeof curValue === 'string';
907
+ const stringValues =
908
+ textboxValue && typeof textboxValue === 'string' && typeof curValue === 'string';
749
909
  const beginsWith =
750
910
  stringValues && textboxValue.toLowerCase().indexOf(curValue.toLowerCase()) === 0;
751
911
  // We only can do proper inline autofilling when the beginning of the word matches
@@ -793,7 +953,8 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
793
953
  // [7]. If no autofill took place, we are left with the previously matched option; correct this
794
954
  if (autoselect && !hasAutoFilled && !this.multipleChoice) {
795
955
  // This means there is no match for checkedIndex
796
- this.checkedIndex = -1;
956
+ this.setCheckedIndex(-1);
957
+ this.modelValue = this.parser(inputValue);
797
958
  }
798
959
 
799
960
  // [8]. These values will help computing autofill intentions next autocomplete cycle
@@ -856,6 +1017,7 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
856
1017
  ...withDropdownConfig(),
857
1018
  elementToFocusAfterHide: undefined,
858
1019
  invokerNode: this._comboboxNode,
1020
+ visibilityTriggerFunction: undefined,
859
1021
  });
860
1022
  }
861
1023
 
@@ -1020,6 +1182,6 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
1020
1182
 
1021
1183
  clear() {
1022
1184
  super.clear();
1023
- this._inputNode.value = '';
1185
+ this.value = '';
1024
1186
  }
1025
1187
  }
@@ -0,0 +1,18 @@
1
+ /* eslint-disable max-classes-per-file */
2
+ import { Unparseable, Validator } from '@lion/ui/form-core.js';
3
+
4
+ export class MatchesOption extends Validator {
5
+ static get validatorName() {
6
+ return 'MatchesOption';
7
+ }
8
+
9
+ /**
10
+ * @param {unknown} [value]
11
+ * @param {string | undefined} [options]
12
+ * @param {{ node: any }} [config]
13
+ */
14
+ // eslint-disable-next-line class-methods-use-this
15
+ execute(value, options, config) {
16
+ return config?.node.modelValue instanceof Unparseable;
17
+ }
18
+ }