@eunomia/elements 1.0.0-beta.6 → 1.0.0-beta.7

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 (245) hide show
  1. package/README.md +1 -1
  2. package/dist/cdn/components/chunks/{chunk-JYIIWN2P.js → chunk-36KLGY6U.js} +8 -8
  3. package/dist/cdn/components/chunks/chunk-3BMACIDO.js +1 -0
  4. package/dist/cdn/components/chunks/{chunk-KDN4O5W2.js → chunk-3PNGQEG4.js} +3 -3
  5. package/dist/cdn/components/chunks/{chunk-ZKZV2YG5.js → chunk-5XPOGBPL.js} +1 -1
  6. package/dist/cdn/components/chunks/{chunk-LMVW522V.js → chunk-62RLISRD.js} +1 -1
  7. package/dist/cdn/components/chunks/{chunk-PMPSJG5V.js → chunk-6FYW5TQU.js} +3 -3
  8. package/dist/cdn/components/chunks/chunk-AK2DIJX7.js +1 -0
  9. package/dist/cdn/components/chunks/chunk-B5XMGWM7.js +10 -0
  10. package/dist/cdn/components/chunks/chunk-BVASCT2V.js +109 -0
  11. package/dist/cdn/components/chunks/{chunk-VYFR364B.js → chunk-DGI7TKCU.js} +14 -9
  12. package/dist/cdn/components/chunks/chunk-GVS6IUKC.js +1 -0
  13. package/dist/cdn/components/chunks/chunk-GWLD2I3P.js +8 -0
  14. package/dist/cdn/components/chunks/{chunk-UDVB4LAE.js → chunk-I4ERDXSM.js} +5 -3
  15. package/dist/cdn/components/chunks/{chunk-QZ5SHR3I.js → chunk-J3SZBXM6.js} +2 -2
  16. package/dist/cdn/components/chunks/{chunk-MOMYII3P.js → chunk-LVKMAHMU.js} +10 -0
  17. package/dist/cdn/components/chunks/{chunk-XDPRWUKN.js → chunk-MQQJ6DID.js} +1 -1
  18. package/dist/cdn/components/chunks/{chunk-SZYEBMG6.js → chunk-PXF554MD.js} +1 -1
  19. package/dist/cdn/components/chunks/chunk-QL5GSW2A.js +1 -0
  20. package/dist/cdn/components/chunks/{chunk-7KKWYPHY.js → chunk-QXQ25SQS.js} +21 -19
  21. package/dist/cdn/components/chunks/{chunk-L2ADCEN7.js → chunk-SVGWCKWT.js} +1 -1
  22. package/dist/cdn/components/chunks/{chunk-MQQ4BGVJ.js → chunk-TFTRCIIK.js} +7 -6
  23. package/dist/cdn/components/chunks/chunk-TLBXTBMM.js +46 -0
  24. package/dist/cdn/components/chunks/chunk-UVHVQRPT.js +1 -0
  25. package/dist/cdn/components/chunks/chunk-WW4BTWMH.js +1 -0
  26. package/dist/cdn/components/chunks/{chunk-2Y2EU2CI.js → chunk-Z3OFIE7S.js} +1 -1
  27. package/dist/cdn/components/eun-alert.js +13 -6
  28. package/dist/cdn/components/eun-animate.js +3 -3
  29. package/dist/cdn/components/eun-badge.js +1 -1
  30. package/dist/cdn/components/eun-button.js +1 -1
  31. package/dist/cdn/components/eun-calendar.js +2 -2
  32. package/dist/cdn/components/eun-card.js +4 -4
  33. package/dist/cdn/components/eun-carousel.js +21 -18
  34. package/dist/cdn/components/eun-check-card.js +1 -1
  35. package/dist/cdn/components/eun-checkbox-list.js +11 -8
  36. package/dist/cdn/components/eun-checkbox.js +1 -1
  37. package/dist/cdn/components/eun-chip.js +3 -3
  38. package/dist/cdn/components/eun-color-picker.js +60 -68
  39. package/dist/cdn/components/eun-counter.js +10 -10
  40. package/dist/cdn/components/eun-date-picker.js +47 -46
  41. package/dist/cdn/components/eun-description-list.js +2 -2
  42. package/dist/cdn/components/eun-divider.js +3 -3
  43. package/dist/cdn/components/eun-drawer.js +5 -5
  44. package/dist/cdn/components/eun-dropdown-button.js +1 -1
  45. package/dist/cdn/components/eun-fab.js +2 -2
  46. package/dist/cdn/components/eun-icon.js +1 -1
  47. package/dist/cdn/components/eun-image-card.js +1 -1
  48. package/dist/cdn/components/eun-image-carousel.js +10 -10
  49. package/dist/cdn/components/eun-infinite-list.js +1 -1
  50. package/dist/cdn/components/eun-input-file.js +21 -21
  51. package/dist/cdn/components/eun-input-phone.js +10 -9
  52. package/dist/cdn/components/eun-input.js +1 -1
  53. package/dist/cdn/components/eun-link.js +2 -2
  54. package/dist/cdn/components/eun-loader.js +1 -1
  55. package/dist/cdn/components/eun-modal.js +13 -13
  56. package/dist/cdn/components/eun-pagination.js +16 -16
  57. package/dist/cdn/components/eun-password-strength.js +14 -10
  58. package/dist/cdn/components/eun-radio-card.js +1 -1
  59. package/dist/cdn/components/eun-radio-list.js +11 -8
  60. package/dist/cdn/components/eun-radio.js +1 -1
  61. package/dist/cdn/components/eun-rating.js +276 -0
  62. package/dist/cdn/components/eun-scheduler-event-editor.js +10 -10
  63. package/dist/cdn/components/eun-scheduler-event.js +1 -1
  64. package/dist/cdn/components/eun-scheduler.js +28 -28
  65. package/dist/cdn/components/eun-search.js +19 -21
  66. package/dist/cdn/components/eun-select.js +27 -27
  67. package/dist/cdn/components/eun-sidebar.js +10 -8
  68. package/dist/cdn/components/eun-skeleton.js +1 -1
  69. package/dist/cdn/components/eun-slider.js +3 -3
  70. package/dist/cdn/components/eun-sliding-card.js +1 -1
  71. package/dist/cdn/components/eun-step.js +5 -4
  72. package/dist/cdn/components/eun-stepper.js +25 -25
  73. package/dist/cdn/components/eun-switch.js +1 -1
  74. package/dist/cdn/components/eun-tab-group.js +4 -4
  75. package/dist/cdn/components/eun-tab.js +1 -1
  76. package/dist/cdn/components/eun-table-action-bar.js +1 -1
  77. package/dist/cdn/components/eun-table.js +1 -1
  78. package/dist/cdn/components/eun-tag.js +3 -3
  79. package/dist/cdn/components/eun-textarea.js +39 -34
  80. package/dist/cdn/components/eun-time-picker.js +15 -14
  81. package/dist/cdn/components/eun-toast.js +19 -10
  82. package/dist/cdn/components/eun-toggle-group.js +6 -4
  83. package/dist/cdn/components/eun-toggle-item.js +1 -1
  84. package/dist/cdn/components/eun-toggle.js +2 -2
  85. package/dist/cdn/components/eun-toolbar.js +5 -5
  86. package/dist/cdn/components/eun-tooltip.js +3 -3
  87. package/dist/components/action/button/button.d.ts +2 -1
  88. package/dist/components/action/button/button.js +3 -2
  89. package/dist/components/action/button/button.styles.js +10 -5
  90. package/dist/components/action/dropdown-button/dropdown-button.js +10 -5
  91. package/dist/components/action/toggle/toggle-group.js +1 -1
  92. package/dist/components/action/toggle/toggle-group.styles.js +4 -2
  93. package/dist/components/action/toggle/toggle.js +1 -1
  94. package/dist/components/alert/alert/alert.d.ts +9 -7
  95. package/dist/components/alert/alert/alert.js +11 -14
  96. package/dist/components/alert/alert/alert.styles.js +9 -2
  97. package/dist/components/alert/drawer/drawer.d.ts +5 -5
  98. package/dist/components/alert/drawer/drawer.js +8 -12
  99. package/dist/components/alert/drawer/drawer.styles.js +1 -1
  100. package/dist/components/alert/modal/modal.d.ts +10 -10
  101. package/dist/components/alert/modal/modal.js +13 -25
  102. package/dist/components/alert/toast/toast.d.ts +7 -5
  103. package/dist/components/alert/toast/toast.js +9 -13
  104. package/dist/components/alert/toast/toast.styles.js +15 -6
  105. package/dist/components/content/badge/badge.js +2 -2
  106. package/dist/components/content/card/card.js +1 -1
  107. package/dist/components/content/card/card.styles.js +2 -2
  108. package/dist/components/content/chip/chip.d.ts +4 -4
  109. package/dist/components/content/chip/chip.js +8 -8
  110. package/dist/components/content/description-list/description-list.js +3 -3
  111. package/dist/components/content/icon/icon.d.ts +3 -0
  112. package/dist/components/content/icon/icon.js +3 -0
  113. package/dist/components/content/icon/icon.style.d.ts +2 -0
  114. package/dist/components/content/icon/icon.style.js +4 -0
  115. package/dist/components/content/image-carousel/image-carousel.d.ts +12 -12
  116. package/dist/components/content/image-carousel/image-carousel.js +24 -24
  117. package/dist/components/content/password-strength/password-strength.d.ts +21 -6
  118. package/dist/components/content/password-strength/password-strength.js +37 -16
  119. package/dist/components/content/password-strength/password-strength.styles.js +4 -0
  120. package/dist/components/content/tag/tag.js +2 -2
  121. package/dist/components/content/tooltip/tooltip.js +3 -3
  122. package/dist/components/form/checkbox/check-card.d.ts +1 -0
  123. package/dist/components/form/checkbox/check-card.js +1 -0
  124. package/dist/components/form/checkbox/checkbox-list.d.ts +17 -0
  125. package/dist/components/form/checkbox/checkbox-list.js +39 -10
  126. package/dist/components/form/checkbox/checkbox.d.ts +1 -0
  127. package/dist/components/form/checkbox/checkbox.js +3 -1
  128. package/dist/components/form/checkbox/checkbox.styles.js +3 -2
  129. package/dist/components/form/color-picker/color-picker.d.ts +41 -28
  130. package/dist/components/form/color-picker/color-picker.js +66 -50
  131. package/dist/components/form/color-picker/color-picker.styles.js +1 -1
  132. package/dist/components/form/counter/counter.d.ts +22 -18
  133. package/dist/components/form/counter/counter.js +59 -61
  134. package/dist/components/form/date-picker/date-picker.d.ts +27 -6
  135. package/dist/components/form/date-picker/date-picker.js +75 -54
  136. package/dist/components/form/input/input.d.ts +38 -39
  137. package/dist/components/form/input/input.js +85 -109
  138. package/dist/components/form/input-file/input-file.d.ts +26 -13
  139. package/dist/components/form/input-file/input-file.js +35 -35
  140. package/dist/components/form/input-file/input-file.styles.js +4 -4
  141. package/dist/components/form/input-phone/input-phone.d.ts +22 -5
  142. package/dist/components/form/input-phone/input-phone.js +41 -13
  143. package/dist/components/form/radio/radio-card.d.ts +1 -0
  144. package/dist/components/form/radio/radio-card.js +1 -0
  145. package/dist/components/form/radio/radio-list.d.ts +23 -7
  146. package/dist/components/form/radio/radio-list.js +47 -22
  147. package/dist/components/form/radio/radio.d.ts +1 -0
  148. package/dist/components/form/radio/radio.js +1 -0
  149. package/dist/components/form/rating/rating.d.ts +349 -0
  150. package/dist/components/form/rating/rating.js +665 -0
  151. package/dist/components/form/rating/rating.styles.d.ts +1 -0
  152. package/dist/components/form/rating/rating.styles.js +213 -0
  153. package/dist/components/form/search/search.d.ts +8 -8
  154. package/dist/components/form/search/search.js +23 -41
  155. package/dist/components/form/select/select.d.ts +23 -10
  156. package/dist/components/form/select/select.js +59 -41
  157. package/dist/components/form/shared-styles/listbox.styles.js +10 -0
  158. package/dist/components/form/slider/slider.d.ts +7 -8
  159. package/dist/components/form/slider/slider.js +9 -12
  160. package/dist/components/form/switch/switch.d.ts +1 -0
  161. package/dist/components/form/switch/switch.js +1 -0
  162. package/dist/components/form/textarea/textarea.d.ts +89 -23
  163. package/dist/components/form/textarea/textarea.js +192 -43
  164. package/dist/components/form/time-picker/time-picker-columns.d.ts +2 -2
  165. package/dist/components/form/time-picker/time-picker-columns.js +8 -8
  166. package/dist/components/form/time-picker/time-picker.d.ts +24 -8
  167. package/dist/components/form/time-picker/time-picker.js +59 -38
  168. package/dist/components/layout/animate/animate.js +1 -1
  169. package/dist/components/layout/animate/animate.styles.js +2 -2
  170. package/dist/components/layout/divider/divider.js +1 -1
  171. package/dist/components/layout/divider/divider.styles.js +1 -1
  172. package/dist/components/loader/loader/loader.js +2 -2
  173. package/dist/components/loader/loader/loader.styles.js +14 -12
  174. package/dist/components/loader/skeleton/skeleton.js +1 -1
  175. package/dist/components/navigation/carousel/carousel.d.ts +31 -7
  176. package/dist/components/navigation/carousel/carousel.js +74 -35
  177. package/dist/components/navigation/carousel/carousel.styles.js +5 -2
  178. package/dist/components/navigation/pagination/pagination.d.ts +23 -21
  179. package/dist/components/navigation/pagination/pagination.js +30 -53
  180. package/dist/components/navigation/sidebar/sidebar.d.ts +15 -13
  181. package/dist/components/navigation/sidebar/sidebar.js +21 -33
  182. package/dist/components/navigation/sidebar/sidebar.styles.js +5 -3
  183. package/dist/components/navigation/stepper/step.js +9 -8
  184. package/dist/components/navigation/stepper/stepper.js +12 -5
  185. package/dist/components/navigation/tabs/tab-group/tab-group.js +2 -2
  186. package/dist/components/navigation/tabs/tab-group/tab-group.styles.js +2 -2
  187. package/dist/components/navigation/toolbar/toolbar.d.ts +13 -13
  188. package/dist/components/navigation/toolbar/toolbar.js +20 -34
  189. package/dist/features/scheduler/calendar/calendar.js +1 -1
  190. package/dist/features/scheduler/scheduler/scheduler.d.ts +7 -7
  191. package/dist/features/scheduler/scheduler/scheduler.js +15 -24
  192. package/dist/features/scheduler/scheduler-event/scheduler-event.js +3 -3
  193. package/dist/features/scheduler/scheduler-event/scheduler-event.styles.js +1 -1
  194. package/dist/features/scheduler/scheduler-event-editor/scheduler-event-editor.d.ts +6 -4
  195. package/dist/features/scheduler/scheduler-event-editor/scheduler-event-editor.js +6 -7
  196. package/dist/i18n/en.d.ts +68 -0
  197. package/dist/i18n/en.js +68 -0
  198. package/dist/i18n/fr.js +68 -2
  199. package/dist/index.d.ts +2 -0
  200. package/dist/index.js +1 -0
  201. package/dist/mixins/button.mixin.js +3 -2
  202. package/dist/mixins/check.mixin.js +11 -10
  203. package/dist/mixins/disabled.mixin.d.ts +5 -0
  204. package/dist/mixins/disabled.mixin.js +21 -1
  205. package/dist/mixins/editable.mixin.js +28 -5
  206. package/dist/mixins/field-appearance.mixin.js +3 -2
  207. package/dist/mixins/form.mixin.d.ts +4 -0
  208. package/dist/mixins/form.mixin.js +87 -13
  209. package/dist/mixins/localizable.mixin.d.ts +1 -1
  210. package/dist/mixins/localizable.mixin.js +1 -1
  211. package/dist/mixins/radio.mixin.js +11 -10
  212. package/dist/mixins/readonly.mixin.d.ts +2 -1
  213. package/dist/mixins/readonly.mixin.js +10 -3
  214. package/dist/ssr/alert-ssr.css +187 -0
  215. package/dist/ssr/badge-ssr.css +67 -0
  216. package/dist/ssr/breadcrumb-ssr.css +41 -0
  217. package/dist/ssr/card-ssr.css +27 -15
  218. package/dist/ssr/carousel-ssr.css +238 -0
  219. package/dist/ssr/checkbox-ssr.css +67 -0
  220. package/dist/ssr/chip-ssr.css +242 -0
  221. package/dist/ssr/collapse-ssr.css +151 -0
  222. package/dist/ssr/field-ssr.css +163 -0
  223. package/dist/ssr/icon-ssr.css +266 -0
  224. package/dist/ssr/image-carousel-ssr.css +24 -0
  225. package/dist/ssr/links-ssr.css +7 -1
  226. package/dist/ssr/pagination-ssr.css +4 -0
  227. package/dist/ssr/rating-ssr.css +254 -0
  228. package/dist/ssr/sidebar-ssr.css +9 -1
  229. package/dist/ssr/skeleton-ssr.css +63 -0
  230. package/dist/ssr/tabs-ssr.css +129 -0
  231. package/dist/ssr/toggle-group-ssr.css +182 -0
  232. package/dist/ssr/toolbar-ssr.css +31 -2
  233. package/dist/utils/implicit-submission.utils.d.ts +18 -0
  234. package/dist/utils/implicit-submission.utils.js +79 -0
  235. package/dist/utils/listbox-options.utils.d.ts +11 -0
  236. package/dist/utils/listbox-options.utils.js +41 -3
  237. package/package.json +26 -7
  238. package/dist/cdn/components/chunks/chunk-4PI6RDUS.js +0 -1
  239. package/dist/cdn/components/chunks/chunk-A3X4KD2X.js +0 -1
  240. package/dist/cdn/components/chunks/chunk-BQFJR2UP.js +0 -110
  241. package/dist/cdn/components/chunks/chunk-G5SBDQQ3.js +0 -1
  242. package/dist/cdn/components/chunks/chunk-KSZRQRN4.js +0 -1
  243. package/dist/cdn/components/chunks/chunk-PE4DAXHQ.js +0 -3
  244. package/dist/cdn/components/chunks/chunk-RS7TWEMQ.js +0 -1
  245. package/dist/cdn/components/chunks/chunk-VOTRXBDS.js +0 -38
@@ -21,8 +21,9 @@ import { ChangeEvent } from "../../../events/change.event.js";
21
21
  import { formLabelsStyles } from "../shared-styles/form-labels.styles.js";
22
22
  import { selectStyles } from "./select.styles.js";
23
23
  import { isWebKit } from "../../../utils/browser.utils.js";
24
- import { parseListboxOptions, renderHighlightedLabel, } from "../../../utils/listbox-options.utils.js";
24
+ import { parseListboxOptions, renderHighlightedLabel, renderListboxRows, } from "../../../utils/listbox-options.utils.js";
25
25
  import { resolveDurationMs, resolveEasing, } from "../../../utils/motion.utils.js";
26
+ import { LocalizableMixin, } from "../../../mixins/localizable.mixin.js";
26
27
  /**
27
28
  * Tag name of the select component.
28
29
  */
@@ -32,7 +33,7 @@ export const EunomiaSelectTagName = "eun-select";
32
33
  * @internal
33
34
  */
34
35
  const Base = DisabledMixin(ValidatorsMixin(LitElement));
35
- const EunomiaSelectMixinBase = AnchorPositionMixin(FieldAppearanceMixin(FormLabelMixin(ReadonlyMixin(EditableMixin(FormMixin(Base))))));
36
+ const EunomiaSelectMixinBase = LocalizableMixin(AnchorPositionMixin(FieldAppearanceMixin(FormLabelMixin(ReadonlyMixin(EditableMixin(FormMixin(Base)))))));
36
37
  /**
37
38
  * A field that picks one or more values from a list of option and optgroup
38
39
  * children. Set searchable to let the field also filter that list as the
@@ -69,6 +70,7 @@ const EunomiaSelectMixinBase = AnchorPositionMixin(FieldAppearanceMixin(FormLabe
69
70
  * @prop {boolean} [readonly=false] - Whether the field is read only
70
71
  * @prop {boolean} [required=false] - Whether a selection is required
71
72
  * @prop {boolean} [hideError=false] - Whether the errors are hidden. The hint stays visible
73
+ * @prop {boolean} [invalid=false] - Shows the field as invalid without any message, for an error displayed elsewhere
72
74
  * @prop {string} [error] - An error computed outside the field, by the form or by the server. While set, the field is invalid and shows this message right away
73
75
  * @prop {Array<Validators<string | string[]>>} validators - The list of validation rules applied to the field value
74
76
  * @prop {EunomiaIconName} icon - An optional leading icon
@@ -79,10 +81,10 @@ const EunomiaSelectMixinBase = AnchorPositionMixin(FieldAppearanceMixin(FormLabe
79
81
  * @attr {string} [select-placeholder='Select…'] - The fallback for placeholder when searchable isn't set
80
82
  * @prop {boolean} [readonlyAvailable=false] - Whether the field can switch between a static display and an editable one
81
83
  * @attr {boolean} [readonly-available=false] - Whether the field can switch between a static display and an editable one
82
- * @prop {string} [emptyValueLabel='No value set'] - Text displayed in place of the value when readonly and empty
84
+ * @prop {string} [emptyValueLabel] - Text displayed in place of the value when readonly and empty. Defaults to the localized string for the current locale (English: "No value set")
83
85
  * @prop {string} [noResultsLabel='No results'] - Text displayed in the dropdown when no option matches the search
84
- * @prop {string} [confirmLabel='Confirm'] - The label of the confirm button, shown while editing in readonlyAvailable mode or while multiple and the dropdown is open. Set to an empty string to hide the button entirely
85
- * @attr {string} [confirm-label='Confirm'] - The label of the confirm button, shown while editing in readonlyAvailable mode or while multiple and the dropdown is open. Set to an empty string to hide the button entirely
86
+ * @prop {string} [confirmLabel] - The label of the confirm button, shown while editing in readonlyAvailable mode or while multiple and the dropdown is open. Set to an empty string to hide the button entirely. Defaults to the localized string for the current locale (English: "Confirm")
87
+ * @attr {string} [confirm-label] - The label of the confirm button, shown while editing in readonlyAvailable mode or while multiple and the dropdown is open. Set to an empty string to hide the button entirely. Defaults to the localized string for the current locale (English: "Confirm")
86
88
  * @prop {boolean} [noAnimation=false] - Disables the dropdown panel's open and close height transition, on top of the automatic reduced motion handling
87
89
  * @prop {boolean} [loading=false] - Whether options are currently being fetched. Shows a spinning loading indicator in place of the dropdown arrow, and a single disabled loading row instead of the option list. Has no effect while native, beyond the arrow swap
88
90
  * @prop {string} [loadingLabel='Loading…'] - The accessible label announced by the loading indicator while loading is set
@@ -122,6 +124,11 @@ const EunomiaSelectMixinBase = AnchorPositionMixin(FieldAppearanceMixin(FormLabe
122
124
  let EunomiaSelect = EunomiaSelect_1 = class EunomiaSelect extends EunomiaSelectMixinBase {
123
125
  constructor() {
124
126
  super(...arguments);
127
+ /**
128
+ * Every change is a complete choice, so its error shows right away.
129
+ * @internal
130
+ */
131
+ this.errorOnChange = true;
125
132
  /**
126
133
  * Indicates whether the field filters its options as the user types.
127
134
  * When false, the field is read-only and driven by Arrow keys, `Enter`,
@@ -165,27 +172,11 @@ let EunomiaSelect = EunomiaSelect_1 = class EunomiaSelect extends EunomiaSelectM
165
172
  * @default Select…
166
173
  */
167
174
  this.selectPlaceholder = "Select…";
168
- /**
169
- * Text displayed in place of the value when readonly and empty.
170
- * @default No value set
171
- */
172
- this.emptyValueLabel = "No value set";
173
175
  /**
174
176
  * Text displayed in the dropdown when no option matches the search.
175
177
  * @default No results
176
178
  */
177
179
  this.noResultsLabel = "No results";
178
- /**
179
- * Label of the confirm button — shown while editing in `readonlyAvailable`
180
- * mode, or while `multiple` and the dropdown is open (see the class doc).
181
- * Slot content into `confirm` instead for anything richer than plain text
182
- * (an icon, for instance) ; slotted content, when present, overrides this.
183
- * Set to an empty string to hide the button entirely — e.g. for a
184
- * `readonlyAvailable` field where picking an option is already confirmation
185
- * enough on its own, and the extra button would just be clutter.
186
- * @default Confirm
187
- */
188
- this.confirmLabel = "Confirm";
189
180
  /**
190
181
  * Indicates whether options are currently being fetched (e.g. a
191
182
  * server-filtered `searchable` field). Shows a spinning `eun-loader` in
@@ -515,7 +506,8 @@ let EunomiaSelect = EunomiaSelect_1 = class EunomiaSelect extends EunomiaSelectM
515
506
  * @internal
516
507
  */
517
508
  get hasConfirmContent() {
518
- return this.hasConfirmSlot || !!this.confirmLabel;
509
+ return (this.hasConfirmSlot ||
510
+ !!(this.confirmLabel ?? this.dictionary.common.confirm));
519
511
  }
520
512
  /**
521
513
  * The normalised search query driving both filtering and highlighting.
@@ -608,9 +600,22 @@ let EunomiaSelect = EunomiaSelect_1 = class EunomiaSelect extends EunomiaSelectM
608
600
  }
609
601
  if (_changedProperties.has("readonly") ||
610
602
  _changedProperties.has("disabled")) {
611
- this.setAttribute("tabindex", this.disabled || this.readonly ? "-1" : "0");
603
+ if (this.disabled || this.readonly) {
604
+ this.setAttribute("tabindex", "-1");
605
+ }
606
+ else {
607
+ this.removeAttribute("tabindex");
608
+ }
612
609
  }
613
610
  }
611
+ /**
612
+ * The host is never a tab stop of its own : sequential navigation goes
613
+ * straight to the controls inside, in both directions, and
614
+ * {@link focus} covers a direct call on the host.
615
+ */
616
+ get hostTabStop() {
617
+ return false;
618
+ }
614
619
  /**
615
620
  * Returns the field element to focus/anchor on validation errors.
616
621
  *
@@ -929,6 +934,27 @@ let EunomiaSelect = EunomiaSelect_1 = class EunomiaSelect extends EunomiaSelectM
929
934
  }
930
935
  break;
931
936
  }
937
+ case " ": {
938
+ // Space opens the list, then picks the highlighted option, as in
939
+ // a select-only combobox, unless it continues a type-ahead search
940
+ // or is typed into the search text.
941
+ if (this.searchable || this.typeaheadBuffer) {
942
+ if (!this.searchable) {
943
+ this.handleTypeahead(event);
944
+ }
945
+ break;
946
+ }
947
+ event.preventDefault();
948
+ if (!this.isOpen) {
949
+ this.openListbox();
950
+ break;
951
+ }
952
+ const option = this.filteredOptions[this.highlightedIndex];
953
+ if (option) {
954
+ this.handleSelect(option);
955
+ }
956
+ break;
957
+ }
932
958
  default:
933
959
  if (!this.searchable) {
934
960
  this.handleTypeahead(event);
@@ -988,27 +1014,17 @@ let EunomiaSelect = EunomiaSelect_1 = class EunomiaSelect extends EunomiaSelectM
988
1014
  return renderHighlightedLabel(label, this.effectiveQuery);
989
1015
  }
990
1016
  /**
991
- * Renders the dropdown's option rows, inserting a non-interactive group
992
- * heading whenever an option's `group` differs from the previous row's.
1017
+ * Renders the dropdown's option rows, grouped under their `optgroup`
1018
+ * label (see {@link renderListboxRows}).
993
1019
  *
994
1020
  * @param options the options to render, already filtered.
995
1021
  * @returns the rendered rows.
996
1022
  * @private
997
1023
  */
998
1024
  renderOptionRows(options) {
999
- const rows = [];
1000
- let lastGroup;
1001
- options.forEach((option, index) => {
1002
- if (option.group !== lastGroup) {
1003
- lastGroup = option.group;
1004
- if (option.group) {
1005
- rows.push(html `<li class="group-label" role="presentation">
1006
- ${option.group}
1007
- </li>`);
1008
- }
1009
- }
1025
+ return renderListboxRows(options, (option, index) => {
1010
1026
  const selected = this.isSelected(option);
1011
- rows.push(html `
1027
+ return html `
1012
1028
  <li
1013
1029
  id="listbox-option-${index}"
1014
1030
  role="option"
@@ -1034,9 +1050,8 @@ let EunomiaSelect = EunomiaSelect_1 = class EunomiaSelect extends EunomiaSelectM
1034
1050
  ? this.renderHighlighted(option.label)
1035
1051
  : option.label}
1036
1052
  </li>
1037
- `);
1053
+ `;
1038
1054
  });
1039
- return rows;
1040
1055
  }
1041
1056
  /**
1042
1057
  * Whether the confirm trigger should render at all right now — while
@@ -1089,7 +1104,9 @@ let EunomiaSelect = EunomiaSelect_1 = class EunomiaSelect extends EunomiaSelectM
1089
1104
  }
1090
1105
  return html `
1091
1106
  <button type="button" id="confirm-link" @click=${this.handleConfirmClick}>
1092
- <slot name="confirm">${this.confirmLabel}</slot>
1107
+ <slot name="confirm"
1108
+ >${this.confirmLabel ?? this.dictionary.common.confirm}</slot
1109
+ >
1093
1110
  </button>
1094
1111
  `;
1095
1112
  }
@@ -1112,7 +1129,8 @@ let EunomiaSelect = EunomiaSelect_1 = class EunomiaSelect extends EunomiaSelectM
1112
1129
  >
1113
1130
  <slot name="readonly-content">
1114
1131
  <span class=${classMap({ empty: !label })}
1115
- >${label || this.emptyValueLabel}</span
1132
+ >${label ||
1133
+ (this.emptyValueLabel ?? this.dictionary.common.noValue)}</span
1116
1134
  >
1117
1135
  </slot>
1118
1136
  </div>
@@ -89,7 +89,17 @@ const listbox = css `
89
89
  text-align: center;
90
90
  color: var(--_placeholderColor);
91
91
  }
92
+ #listbox li.option-group {
93
+ padding: 0;
94
+ cursor: default;
95
+ }
96
+ #listbox .group-options {
97
+ margin: 0;
98
+ padding: 0;
99
+ list-style: none;
100
+ }
92
101
  #listbox .group-label {
102
+ padding: var(--eun-space-s, 8px) var(--eun-space-m, 16px);
93
103
  cursor: default;
94
104
  padding-block-end: var(--eun-space-xxs, 1.6px);
95
105
  font-size: var(--eun-font-size-xs, 12px);
@@ -46,6 +46,7 @@ declare const EunomiaSliderMixinBase: Constructor<EunomiaSliderBase>;
46
46
  * @prop {boolean} [readonly=false] - Whether the field is read only
47
47
  * @prop {boolean} [required=false] - Present for API consistency with every other field, but inert here, since a slider's value can never be empty the way a text field's can
48
48
  * @prop {boolean} [hideError=false] - Whether the errors are hidden. The hint stays visible
49
+ * @prop {boolean} [invalid=false] - Shows the field as invalid without any message, for an error displayed elsewhere
49
50
  * @prop {string} [error] - An error computed outside the field, by the form or by the server. While set, the field is invalid and shows this message right away
50
51
  * @attr {boolean} [hide-error=false] - Whether the errors are hidden
51
52
  * @prop {boolean} [hideTooltip=false] - Hides the floating value bubble that otherwise appears above the thumb while dragging or focused
@@ -178,14 +179,6 @@ export declare class EunomiaSlider extends EunomiaSliderMixinBase {
178
179
  private hasFocus;
179
180
  connectedCallback(): void;
180
181
  disconnectedCallback(): void;
181
- /**
182
- * Redirects focus to the native field whenever the host itself receives
183
- * it — the same pattern `eun-counter`/`eun-input` use, so the host stays
184
- * in the tab order (`DisabledMixin`) rather than excluded via
185
- * `tabindex="-1"`, which would break Tab from reaching the field at all.
186
- * @private
187
- */
188
- private readonly handleHostFocus;
189
182
  /**
190
183
  * The value a native `<input type="range">` with no `value` attribute
191
184
  * resolves to on its own.
@@ -243,6 +236,12 @@ export declare class EunomiaSlider extends EunomiaSliderMixinBase {
243
236
  * @private
244
237
  */
245
238
  private get tickValues();
239
+ /**
240
+ * The host is never a tab stop of its own : sequential navigation goes
241
+ * straight to the controls inside, in both directions, and
242
+ * {@link focus} covers a direct call on the host.
243
+ */
244
+ protected get hostTabStop(): boolean;
246
245
  /**
247
246
  * Returns the field element to focus/anchor on validation errors.
248
247
  *
@@ -58,6 +58,7 @@ const EunomiaSliderMixinBase = FormLabelMixin(ReadonlyMixin(FormMixin(Base)));
58
58
  * @prop {boolean} [readonly=false] - Whether the field is read only
59
59
  * @prop {boolean} [required=false] - Present for API consistency with every other field, but inert here, since a slider's value can never be empty the way a text field's can
60
60
  * @prop {boolean} [hideError=false] - Whether the errors are hidden. The hint stays visible
61
+ * @prop {boolean} [invalid=false] - Shows the field as invalid without any message, for an error displayed elsewhere
61
62
  * @prop {string} [error] - An error computed outside the field, by the form or by the server. While set, the field is invalid and shows this message right away
62
63
  * @attr {boolean} [hide-error=false] - Whether the errors are hidden
63
64
  * @prop {boolean} [hideTooltip=false] - Hides the floating value bubble that otherwise appears above the thumb while dragging or focused
@@ -133,16 +134,6 @@ let EunomiaSlider = class EunomiaSlider extends EunomiaSliderMixinBase {
133
134
  * @internal
134
135
  */
135
136
  this.hasFocus = false;
136
- /**
137
- * Redirects focus to the native field whenever the host itself receives
138
- * it — the same pattern `eun-counter`/`eun-input` use, so the host stays
139
- * in the tab order (`DisabledMixin`) rather than excluded via
140
- * `tabindex="-1"`, which would break Tab from reaching the field at all.
141
- * @private
142
- */
143
- this.handleHostFocus = () => {
144
- this.fieldEl?.focus();
145
- };
146
137
  /**
147
138
  * Updates the value from dragging or a keyboard-driven native step, and
148
139
  * notifies consumers — fires on every native `input` event, so live and
@@ -256,10 +247,8 @@ let EunomiaSlider = class EunomiaSlider extends EunomiaSliderMixinBase {
256
247
  connectedCallback() {
257
248
  super.connectedCallback?.();
258
249
  this.value ??= this.clamp(this.defaultRangeValue);
259
- this.addEventListener("focus", this.handleHostFocus);
260
250
  }
261
251
  disconnectedCallback() {
262
- this.removeEventListener("focus", this.handleHostFocus);
263
252
  window.removeEventListener("pointerup", this.handlePointerUp);
264
253
  window.removeEventListener("pointercancel", this.handlePointerUp);
265
254
  super.disconnectedCallback?.();
@@ -361,6 +350,14 @@ let EunomiaSlider = class EunomiaSlider extends EunomiaSliderMixinBase {
361
350
  values.push(this.max);
362
351
  return values;
363
352
  }
353
+ /**
354
+ * The host is never a tab stop of its own : sequential navigation goes
355
+ * straight to the controls inside, in both directions, and
356
+ * {@link focus} covers a direct call on the host.
357
+ */
358
+ get hostTabStop() {
359
+ return false;
360
+ }
364
361
  /**
365
362
  * Returns the field element to focus/anchor on validation errors.
366
363
  *
@@ -39,6 +39,7 @@ declare const EunomiaSwitchMixinBase: Constructor<EunomiaSwitchBase>;
39
39
  * @prop {boolean} [hideIcon=false] - Whether the icon inside the thumb is hidden
40
40
  * @attr {boolean} [hide-icon=false] - Whether the icon inside the thumb is hidden
41
41
  * @prop {boolean} [hideError=false] - Whether the errors are hidden. The hint stays visible
42
+ * @prop {boolean} [invalid=false] - Shows the field as invalid without any message, for an error displayed elsewhere
42
43
  * @prop {string} [error] - An error computed outside the field, by the form or by the server. While set, the field is invalid and shows this message right away
43
44
  * @attr {boolean} [hide-error=false] - Whether the error message is hidden
44
45
  * @prop {boolean} [required=false] - Whether the switch must be turned on to be valid
@@ -44,6 +44,7 @@ const EunomiaSwitchMixinBase = CheckMixin(ReadonlyMixin(FormMixin(DisabledMixin(
44
44
  * @prop {boolean} [hideIcon=false] - Whether the icon inside the thumb is hidden
45
45
  * @attr {boolean} [hide-icon=false] - Whether the icon inside the thumb is hidden
46
46
  * @prop {boolean} [hideError=false] - Whether the errors are hidden. The hint stays visible
47
+ * @prop {boolean} [invalid=false] - Shows the field as invalid without any message, for an error displayed elsewhere
47
48
  * @prop {string} [error] - An error computed outside the field, by the form or by the server. While set, the field is invalid and shows this message right away
48
49
  * @attr {boolean} [hide-error=false] - Whether the error message is hidden
49
50
  * @prop {boolean} [required=false] - Whether the switch must be turned on to be valid
@@ -7,6 +7,7 @@ import { FormLabelMixinInterface } from "../../../mixins/form-label.mixin.js";
7
7
  import { EditableMixinInterface } from "../../../mixins/editable.mixin.js";
8
8
  import { FieldAppearanceMixinInterface } from "../../../mixins/field-appearance.mixin.js";
9
9
  import { Constructor } from "../../../utils/constructor.type.js";
10
+ import { LocalizableMixinInterface } from "../../../mixins/localizable.mixin.js";
10
11
  /**
11
12
  * Tag name of the textarea component.
12
13
  */
@@ -15,7 +16,7 @@ export declare const EunomiaTextareaTagName = "eun-textarea";
15
16
  * Type of the textarea base used to declare every necessary Mixin interface elements.
16
17
  * @internal
17
18
  */
18
- type EunomiaTextareaBase = LitElement & DisabledMixinInterface & ReadonlyMixinInterface & ValidatorsMixinInterface<string> & FormMixinInterface<string> & EditableMixinInterface & FormLabelMixinInterface & FieldAppearanceMixinInterface;
19
+ type EunomiaTextareaBase = LitElement & DisabledMixinInterface & ReadonlyMixinInterface & ValidatorsMixinInterface<string> & FormMixinInterface<string> & EditableMixinInterface & FormLabelMixinInterface & FieldAppearanceMixinInterface & LocalizableMixinInterface;
19
20
  declare const EunomiaTextareaMixinBase: Constructor<EunomiaTextareaBase>;
20
21
  /**
21
22
  * A multi-line text field, sharing its label, hint, and error chrome and
@@ -45,13 +46,14 @@ declare const EunomiaTextareaMixinBase: Constructor<EunomiaTextareaBase>;
45
46
  * @prop {boolean} [readonly=false] - Whether the field is read only
46
47
  * @prop {boolean} [required=false] - Whether the field is required
47
48
  * @prop {boolean} [hideError=false] - Whether the errors are hidden. The hint stays visible
49
+ * @prop {boolean} [invalid=false] - Shows the field as invalid without any message, for an error displayed elsewhere
48
50
  * @prop {string} [error] - An error computed outside the field, by the form or by the server. While set, the field is invalid and shows this message right away
49
51
  * @prop {Array<import('../../../types/form-validators.type.js').Validators<string>>} validators - The list of validation rules applied to the field value
50
52
  * @prop {number} rows - The fixed number of visible rows. When omitted, the field automatically grows and shrinks its height to fit its content
51
53
  * @prop {boolean} [readonlyAvailable=false] - Whether the field can switch between a static display and an editable one
52
54
  * @attr {boolean} [readonly-available=false] - Whether the field can switch between a static display and an editable one
53
55
  * @prop {boolean} [formatting=false] - Switches the field to a rich text surface with a formatting toolbar above it, and, combined with readonlyAvailable, renders the static display as formatted rich text instead of raw source
54
- * @prop {string} [formatToolbarLabel='Text formatting'] - The accessible label of the bold, italic, and underline toggle group
56
+ * @prop {string} [formatToolbarLabel='Text formatting'] - The accessible label of the formatting toolbar
55
57
  * @prop {string} [formatBoldLabel='Bold'] - The accessible label of the bold toggle
56
58
  * @prop {string} [formatItalicLabel='Italic'] - The accessible label of the italic toggle
57
59
  * @prop {string} [formatUnderlineLabel='Underline'] - The accessible label of the underline toggle
@@ -66,9 +68,9 @@ declare const EunomiaTextareaMixinBase: Constructor<EunomiaTextareaBase>;
66
68
  * @prop {string} [autocomplete='off'] - The native autocomplete attribute forwarded to the field
67
69
  * @prop {number} minlength - The native minimum length constraint forwarded to the field
68
70
  * @prop {number} maxlength - The field's maximum length. Forwarded natively when not formatting, and enforced manually otherwise. Either way, a live character counter is shown under the field
69
- * @prop {string} [emptyValueLabel='No value set'] - Text displayed in place of the value when readonly and empty
70
- * @prop {string} [confirmLabel='Save'] - The label of the confirm button in edit mode
71
- * @prop {string} [cancelLabel='Cancel'] - The label of the cancel button in edit mode
71
+ * @prop {string} [emptyValueLabel] - Text displayed in place of the value when readonly and empty. Defaults to the localized string for the current locale (English: "No value set")
72
+ * @prop {string} [confirmLabel] - The label of the confirm button in edit mode. Defaults to the localized string for the current locale (English: "Save")
73
+ * @prop {string} [cancelLabel] - The label of the cancel button in edit mode. Defaults to the localized string for the current locale (English: "Cancel")
72
74
  * @fires {ChangeEvent} eunchange - Fired on every value change, including one applied through the formatting toolbar
73
75
  * @fires {CommitEvent} euncommit - Fired when an edit is confirmed in readonlyAvailable mode
74
76
  * @cssprop [--field-background] - Sets the background color of the field
@@ -130,7 +132,7 @@ export declare class EunomiaTextarea extends EunomiaTextareaMixinBase {
130
132
  */
131
133
  formatting: boolean;
132
134
  /**
133
- * Accessible label of the Bold/Italic/Underline toggle group.
135
+ * Accessible label of the formatting toolbar.
134
136
  * @default Text formatting
135
137
  */
136
138
  formatToolbarLabel: string;
@@ -213,19 +215,19 @@ export declare class EunomiaTextarea extends EunomiaTextareaMixinBase {
213
215
  maxlength?: number;
214
216
  /**
215
217
  * Text displayed in place of the value when readonly and empty.
216
- * @default No value set
218
+ * Falls back to the localized string for the current locale when unset.
217
219
  */
218
- emptyValueLabel: string;
220
+ emptyValueLabel?: string;
219
221
  /**
220
222
  * Label of the confirm button in edit mode.
221
- * @default Save
223
+ * Falls back to the localized string for the current locale when unset.
222
224
  */
223
- confirmLabel: string;
225
+ confirmLabel?: string;
224
226
  /**
225
227
  * Label of the cancel button in edit mode.
226
- * @default Cancel
228
+ * Falls back to the localized string for the current locale when unset.
227
229
  */
228
- cancelLabel: string;
230
+ cancelLabel?: string;
229
231
  /**
230
232
  * Which color picker (text-color or highlight) is currently open, if any.
231
233
  * @private
@@ -296,19 +298,18 @@ export declare class EunomiaTextarea extends EunomiaTextareaMixinBase {
296
298
  * @readonly
297
299
  */
298
300
  private readonly toolbarEl?;
299
- connectedCallback(): void;
300
- disconnectedCallback(): void;
301
301
  /**
302
- * Redirects focus to the native field whenever the host itself receives
303
- * it. The host stays in the tab order (`DisabledMixin`) rather than
304
- * being excluded via `tabindex="-1"` — for this form-associated
305
- * component, that turned out to break Tab from reaching the field
306
- * entirely, instead of just skipping the host. Redirecting keeps a
307
- * single, real tab stop from the user's perspective without touching
308
- * that tab order.
309
- * @private
302
+ * Index, among {@link toolbarControls}, of the control holding the
303
+ * toolbar's single Tab stop.
304
+ * @internal
310
305
  */
311
- private handleHostFocus;
306
+ private toolbarFocusIndex;
307
+ /**
308
+ * Pending {@link applyToolbarRoving} call.
309
+ * @internal
310
+ */
311
+ private toolbarRovingTimer?;
312
+ disconnectedCallback(): void;
312
313
  /**
313
314
  * Lifecycle hook called after the first render : populates the
314
315
  * contenteditable surface (when `formatting`) and fits the field height
@@ -343,6 +344,12 @@ export declare class EunomiaTextarea extends EunomiaTextareaMixinBase {
343
344
  * @private
344
345
  */
345
346
  private checkEditableValidators;
347
+ /**
348
+ * The host is never a tab stop of its own : sequential navigation goes
349
+ * straight to the controls inside, in both directions, and
350
+ * {@link focus} covers a direct call on the host.
351
+ */
352
+ protected get hostTabStop(): boolean;
346
353
  /**
347
354
  * Returns the field element to focus/anchor on validation errors.
348
355
  *
@@ -509,6 +516,23 @@ export declare class EunomiaTextarea extends EunomiaTextareaMixinBase {
509
516
  * @private
510
517
  */
511
518
  private toggleColorPicker;
519
+ /**
520
+ * The swatches of the open color picker, in display order.
521
+ *
522
+ * @returns the swatch buttons, empty while no picker is open.
523
+ * @private
524
+ */
525
+ private colorSwatches;
526
+ /**
527
+ * Keyboard support of the open color picker, following the menu pattern
528
+ * : arrows move between swatches (wrapping), Home/End jump to the first
529
+ * and last, Escape closes it, and Tab closes it before leaving it. Both
530
+ * return the focus to the picker's trigger.
531
+ *
532
+ * @param event the keyboard event.
533
+ * @private
534
+ */
535
+ private handleColorPickerKeydown;
512
536
  /**
513
537
  * Closes whichever color picker is open, if any.
514
538
  * @private
@@ -532,6 +556,48 @@ export declare class EunomiaTextarea extends EunomiaTextareaMixinBase {
532
556
  * @private
533
557
  */
534
558
  private selectColor;
559
+ /**
560
+ * The toolbar's controls, in visual order : every format and alignment
561
+ * toggle, then both color picker triggers.
562
+ *
563
+ * @returns the controls, empty while the toolbar isn't rendered.
564
+ * @private
565
+ */
566
+ private toolbarControls;
567
+ /**
568
+ * Applies the toolbar's roving `tabindex` once the toggle groups have
569
+ * applied their own (which they do after their items' updates), so the
570
+ * whole toolbar stays a single Tab stop.
571
+ * @private
572
+ */
573
+ private scheduleToolbarRoving;
574
+ /**
575
+ * Makes the control at {@link toolbarFocusIndex} the toolbar's only Tab
576
+ * stop. Left alone while the toolbar is disabled, every control then
577
+ * being out of the Tab order already.
578
+ * @private
579
+ */
580
+ private applyToolbarRoving;
581
+ /**
582
+ * Remembers the toolbar control receiving the focus, so Tab comes back
583
+ * to it.
584
+ *
585
+ * @param event the focus event.
586
+ * @private
587
+ */
588
+ private handleToolbarFocusIn;
589
+ /**
590
+ * Keyboard support of the toolbar, following the toolbar pattern :
591
+ * Left/Right move between its controls (wrapping), Home/End jump to the
592
+ * first and last, and Enter/Space pick an alignment. Listened to in the
593
+ * capture phase, ahead of the alignment group's own arrow handling.
594
+ * Up/Down are left to the alignment group, which selects the next
595
+ * alignment.
596
+ *
597
+ * @param event the keyboard event.
598
+ * @private
599
+ */
600
+ private readonly handleToolbarKeydown;
535
601
  /**
536
602
  * Renders the formatting toolbar, shown above the field itself (never
537
603
  * above the readonly display) when `formatting` is set.