@cnamts/synapse 1.0.6 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. package/dist/{DateFilter-BlOpwEVq.js → DateFilter-DkqG0pmr.js} +1 -1
  2. package/dist/{NumberFilter-BPUXE4wY.js → NumberFilter-Ck7AwD39.js} +1 -1
  3. package/dist/{PeriodFilter-B2yx329_.js → PeriodFilter-LRI6YpgU.js} +1 -1
  4. package/dist/{SelectFilter-CedKn1oV.js → SelectFilter-DPc70Jk7.js} +1 -1
  5. package/dist/{TextFilter-DkhJjRtR.js → TextFilter-DRQL7uD8.js} +1 -1
  6. package/dist/components/Amelipro/AmeliproAccordionGroup/AmeliproAccordionGroup.d.ts +116 -0
  7. package/dist/components/Amelipro/AmeliproAccordionGroup/types.d.ts +4 -0
  8. package/dist/components/Amelipro/AmeliproAccordionList/AmeliproAccordionList.d.ts +220 -0
  9. package/dist/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResult.d.ts +68 -0
  10. package/dist/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResultTemplate/AmeliproAccordionResultTemplate.d.ts +70 -0
  11. package/dist/components/Amelipro/AmeliproAccordionResultList/AmeliproAccordionResultList.d.ts +204 -0
  12. package/dist/components/Amelipro/AmeliproAutoCompleteField/AmeliproAutoCompleteField.d.ts +26 -26
  13. package/dist/components/Amelipro/AmeliproBadge/AmeliproBadge.d.ts +59 -0
  14. package/dist/components/Amelipro/AmeliproBtn/AmeliproBtn.d.ts +3 -3
  15. package/dist/components/Amelipro/AmeliproCaptcha/AmeliproCaptcha.d.ts +1 -1
  16. package/dist/components/Amelipro/AmeliproCarousel/AmeliproCarousel.d.ts +214 -0
  17. package/dist/components/Amelipro/AmeliproCarousel/AmeliproCarouselItem/AmeliproCarouselItem.d.ts +70 -0
  18. package/dist/components/Amelipro/AmeliproCarousel/types.d.ts +7 -0
  19. package/dist/components/Amelipro/AmeliproClickableTile/AmeliproClickableTile.d.ts +125 -0
  20. package/dist/components/Amelipro/AmeliproIconBtn/AmeliproIconBtn.d.ts +1 -1
  21. package/dist/components/Amelipro/AmeliproIllustratedDataTile/AmeliproIllustratedDataTile.d.ts +2 -2
  22. package/dist/components/Amelipro/AmeliproResultList/AmeliproResultList.d.ts +164 -0
  23. package/dist/components/Amelipro/AmeliproSelect/AmeliproSelect.d.ts +27 -27
  24. package/dist/components/Amelipro/AmeliproStateTile/AmeliproStateTile.d.ts +1 -1
  25. package/dist/components/Amelipro/AmeliproTable/AmeliproTable.d.ts +1 -1
  26. package/dist/components/Amelipro/AmeliproTabs/AmeliproTabs.d.ts +32 -32
  27. package/dist/components/Amelipro/AmeliproTextArea/AmeliproTextArea.d.ts +6 -6
  28. package/dist/components/Amelipro/AmeliproTextField/AmeliproTextField.d.ts +7 -7
  29. package/dist/components/Amelipro/AmeliproTileBtn/AmeliproTileBtn.d.ts +1 -1
  30. package/dist/components/Amelipro/AmeliproTooltips/AmeliproTooltips.d.ts +2 -2
  31. package/dist/components/ChipList/ChipList.d.ts +4 -0
  32. package/dist/components/ChipList/locales.d.ts +4 -2
  33. package/dist/components/CookiesSelection/CookiesInformation/CookiesInformation.d.ts +8 -8
  34. package/dist/components/Customs/Selects/SySelect/SySelect.d.ts +329 -1296
  35. package/dist/components/Customs/Selects/SySelect/composables/useSySelectKeyboard.d.ts +0 -1
  36. package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +2 -0
  37. package/dist/components/Customs/SyTabs/SyTabs.d.ts +71 -0
  38. package/dist/components/Customs/SyTabs/config.d.ts +17 -0
  39. package/dist/components/Customs/SyTabs/types.d.ts +11 -0
  40. package/dist/components/Customs/SyTextField/SyTextField.d.ts +9 -9
  41. package/dist/components/DataList/DataList.d.ts +1 -1
  42. package/dist/components/DatePicker/CalendarMode/DatePicker.d.ts +4811 -240
  43. package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +52 -33
  44. package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +23 -10
  45. package/dist/components/DatePicker/composables/useDateInputEditing.d.ts +1 -0
  46. package/dist/components/DatePicker/composables/useTodayButton.d.ts +1 -0
  47. package/dist/components/DialogBox/DialogBox.d.ts +219 -0
  48. package/dist/components/HeaderLoading/HeaderLoading.d.ts +27 -0
  49. package/dist/components/HeaderNavigationBar/HeaderNavigationBar.d.ts +110 -3
  50. package/dist/components/HeaderNavigationBar/HorizontalNavbar/HorizontalNavbar.d.ts +19 -1
  51. package/dist/components/LangBtn/LangBtn.d.ts +2 -2
  52. package/dist/components/NirField/NirField.d.ts +18 -18
  53. package/dist/components/PeriodField/PeriodField.d.ts +10766 -1620
  54. package/dist/components/PhoneField/PhoneField.d.ts +1866 -2
  55. package/dist/components/PhoneField/indicatifs.d.ts +1 -0
  56. package/dist/components/PhoneField/locales.d.ts +1 -0
  57. package/dist/components/RangeField/RangeField.d.ts +1 -1
  58. package/dist/components/RangeField/RangeSlider/RangeSlider.d.ts +1 -1
  59. package/dist/components/SubHeader/SubHeader.d.ts +8 -0
  60. package/dist/components/SubHeader/locales.d.ts +1 -0
  61. package/dist/components/SyTextArea/SyTextArea.d.ts +6 -6
  62. package/dist/components/Tables/SyServerTable/SyServerTable.d.ts +5 -4
  63. package/dist/components/Tables/SyTable/SyTable.d.ts +5 -4
  64. package/dist/components/Tables/common/SyTablePagination.d.ts +333 -1296
  65. package/dist/components/Tables/common/organizeColumns/OrganizeColumns.d.ts +2 -2
  66. package/dist/components/Tables/common/types.d.ts +2 -0
  67. package/dist/components/index.d.ts +9 -0
  68. package/dist/design-system-v3.js +173 -164
  69. package/dist/design-system-v3.umd.cjs +286 -263
  70. package/dist/{main-BXPFSAB4.js → main-DXMoMtj5.js} +13176 -11457
  71. package/dist/services/NotificationService.d.ts +1 -0
  72. package/dist/style.css +1 -1
  73. package/package.json +1 -1
  74. package/src/assets/amelipro/icons.ts +38 -11
  75. package/src/components/Amelipro/AmeliproAccordionGroup/AmeliproAccordionGroup.mdx +20 -0
  76. package/src/components/Amelipro/AmeliproAccordionGroup/AmeliproAccordionGroup.stories.ts +135 -0
  77. package/src/components/Amelipro/AmeliproAccordionGroup/AmeliproAccordionGroup.vue +107 -0
  78. package/src/components/Amelipro/AmeliproAccordionGroup/__tests__/AmeliproAccordionGroup.spec.ts +37 -0
  79. package/src/components/Amelipro/AmeliproAccordionGroup/__tests__/__snapshots__/AmeliproAccordionGroup.spec.ts.snap +513 -0
  80. package/src/components/Amelipro/AmeliproAccordionGroup/types.d.ts +4 -0
  81. package/src/components/Amelipro/AmeliproAccordionList/AmeliproAccordionList.mdx +16 -0
  82. package/src/components/Amelipro/AmeliproAccordionList/AmeliproAccordionList.stories.ts +300 -0
  83. package/src/components/Amelipro/AmeliproAccordionList/AmeliproAccordionList.vue +288 -0
  84. package/src/components/Amelipro/AmeliproAccordionList/__tests__/AmeliproAccordionList.spec.ts +38 -0
  85. package/src/components/Amelipro/AmeliproAccordionList/__tests__/__snapshots__/AmeliproAccordionList.spec.ts.snap +1712 -0
  86. package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResult.mdx +19 -0
  87. package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResult.stories.ts +68 -0
  88. package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResult.vue +66 -0
  89. package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResultTemplate/AmeliproAccordionResultTemplate.vue +145 -0
  90. package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResultTemplate/__tests__/AmeliproAccordionResultTemplate.spec.ts +24 -0
  91. package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResultTemplate/__tests__/__snapshots__/AmeliproAccordionResultTemplate.spec.ts.snap +127 -0
  92. package/src/components/Amelipro/AmeliproAccordionResult/__tests__/AmeliproAccordionResult.spec.ts +24 -0
  93. package/src/components/Amelipro/AmeliproAccordionResult/__tests__/__snapshots__/AmeliproAccordionResult.spec.ts.snap +123 -0
  94. package/src/components/Amelipro/AmeliproAccordionResultList/AmeliproAccordionResultList.mdx +20 -0
  95. package/src/components/Amelipro/AmeliproAccordionResultList/AmeliproAccordionResultList.stories.ts +273 -0
  96. package/src/components/Amelipro/AmeliproAccordionResultList/AmeliproAccordionResultList.vue +275 -0
  97. package/src/components/Amelipro/AmeliproAccordionResultList/__tests__/AmeliproAccordionResultList.spec.ts +38 -0
  98. package/src/components/Amelipro/AmeliproAccordionResultList/__tests__/__snapshots__/AmeliproAccordionResultList.spec.ts.snap +1593 -0
  99. package/src/components/Amelipro/AmeliproBadge/AmeliproBadge.mdx +15 -0
  100. package/src/components/Amelipro/AmeliproBadge/AmeliproBadge.stories.ts +54 -0
  101. package/src/components/Amelipro/AmeliproBadge/AmeliproBadge.vue +76 -0
  102. package/src/components/Amelipro/AmeliproBadge/__tests__/AmeliproBadge.spec.ts +20 -0
  103. package/src/components/Amelipro/AmeliproBadge/__tests__/__snapshots__/AmeliproBadge.spec.ts.snap +19 -0
  104. package/src/components/Amelipro/AmeliproCarousel/AmeliproCarousel.mdx +15 -0
  105. package/src/components/Amelipro/AmeliproCarousel/AmeliproCarousel.stories.ts +191 -0
  106. package/src/components/Amelipro/AmeliproCarousel/AmeliproCarousel.vue +263 -0
  107. package/src/components/Amelipro/AmeliproCarousel/AmeliproCarouselItem/AmeliproCarouselItem.vue +93 -0
  108. package/src/components/Amelipro/AmeliproCarousel/AmeliproCarouselItem/__tests__/AmeliproCarouselItem.spec.ts +24 -0
  109. package/src/components/Amelipro/AmeliproCarousel/AmeliproCarouselItem/__tests__/__snapshots__/AmeliproCarouselItem.spec.ts.snap +43 -0
  110. package/src/components/Amelipro/AmeliproCarousel/__tests__/AmeliproCarousel.spec.ts +40 -0
  111. package/src/components/Amelipro/AmeliproCarousel/__tests__/__snapshots__/AmeliproCarousel.spec.ts.snap +342 -0
  112. package/src/components/Amelipro/AmeliproCarousel/types.d.ts +8 -0
  113. package/src/components/Amelipro/AmeliproClickableTile/AmeliproClickableTile.mdx +18 -0
  114. package/src/components/Amelipro/AmeliproClickableTile/AmeliproClickableTile.stories.ts +67 -0
  115. package/src/components/Amelipro/AmeliproClickableTile/AmeliproClickableTile.vue +233 -0
  116. package/src/components/Amelipro/AmeliproClickableTile/tests/AmeliproClickableTile.spec.ts +21 -0
  117. package/src/components/Amelipro/AmeliproClickableTile/tests/__snapshots__/AmeliproClickableTile.spec.ts.snap +140 -0
  118. package/src/components/Amelipro/AmeliproHeader/AmeliproHeader.vue +7 -1
  119. package/src/components/Amelipro/AmeliproHeader/tests/__snapshots__/AmeliproHeader.spec.ts.snap +5 -4
  120. package/src/components/Amelipro/AmeliproIcon/iconList.ts +6 -0
  121. package/src/components/Amelipro/AmeliproPageLayout/tests/__snapshots__/AmeliproPageLayout.spec.ts.snap +5 -4
  122. package/src/components/Amelipro/AmeliproResultList/AmeliproResultList.mdx +15 -0
  123. package/src/components/Amelipro/AmeliproResultList/AmeliproResultList.stories.ts +264 -0
  124. package/src/components/Amelipro/AmeliproResultList/AmeliproResultList.vue +231 -0
  125. package/src/components/Amelipro/AmeliproResultList/__tests__/AmeliproResultList.spec.ts +37 -0
  126. package/src/components/Amelipro/AmeliproResultList/__tests__/__snapshots__/AmeliproResultList.spec.ts.snap +434 -0
  127. package/src/components/Amelipro/AmeliproTable/AmeliproTable.vue +6 -5
  128. package/src/components/Amelipro/AmeliproTable/__tests__/__snapshots__/AmeliproTable.spec.ts.snap +23 -26
  129. package/src/components/Amelipro/AmeliproTileBtn/AmeliproTileBtn.stories.ts +2 -2
  130. package/src/components/ChipList/Accessibilite.stories.ts +4 -0
  131. package/src/components/ChipList/ChipList.vue +185 -42
  132. package/src/components/ChipList/locales.ts +4 -2
  133. package/src/components/ChipList/tests/chipList.spec.ts +7 -4
  134. package/src/components/Customs/Selects/SelectOverview.mdx +34 -66
  135. package/src/components/Customs/Selects/SyBtnSelect/SyBtnSelect.stories.ts +10 -10
  136. package/src/components/Customs/Selects/SyInputSelect/SyInputSelect.mdx +3 -0
  137. package/src/components/Customs/Selects/SyInputSelect/SyInputSelect.stories.ts +14 -0
  138. package/src/components/Customs/Selects/SySelect/SySelect.stories.ts +14 -6
  139. package/src/components/Customs/Selects/SySelect/SySelect.vue +268 -205
  140. package/src/components/Customs/Selects/SySelect/composables/tests/useSySelectKeyboard.spec.ts +0 -10
  141. package/src/components/Customs/Selects/SySelect/composables/useSySelectKeyboard.ts +0 -5
  142. package/src/components/Customs/Selects/SySelect/tests/SySelect.spec.ts +184 -25
  143. package/src/components/Customs/SyCheckbox/SyCheckbox.mdx +3 -1
  144. package/src/components/Customs/SyCheckbox/SyCheckbox.stories.ts +165 -0
  145. package/src/components/Customs/SyCheckbox/SyCheckbox.vue +28 -9
  146. package/src/components/Customs/SyTabs/Accessibilite.mdx +309 -0
  147. package/src/components/Customs/SyTabs/SyTabs.mdx +117 -0
  148. package/src/components/Customs/SyTabs/SyTabs.stories.ts +354 -0
  149. package/src/components/Customs/SyTabs/SyTabs.vue +413 -0
  150. package/src/components/Customs/SyTabs/config.ts +17 -0
  151. package/src/components/Customs/SyTabs/tests/SyTabs.spec.ts +425 -0
  152. package/src/components/Customs/SyTabs/types.ts +12 -0
  153. package/src/components/Customs/SyTextField/SyTextField.mdx +3 -0
  154. package/src/components/Customs/SyTextField/SyTextField.stories.ts +142 -1
  155. package/src/components/Customs/SyTextField/SyTextField.vue +19 -16
  156. package/src/components/DataList/DataList.vue +47 -49
  157. package/src/components/DataListGroup/DataListGroup.vue +1 -1
  158. package/src/components/DataListItem/DataListItem.vue +67 -63
  159. package/src/components/DataListItem/tests/DataListItem.spec.ts +2 -2
  160. package/src/components/DatePicker/CalendarMode/DatePicker.stories.ts +3 -3
  161. package/src/components/DatePicker/CalendarMode/DatePicker.vue +49 -13
  162. package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.vue +412 -649
  163. package/src/components/DatePicker/DatePickerValidationExample/CalendarMode.stories.ts +215 -0
  164. package/src/components/DatePicker/DatePickerValidationExample/ComplexDatePicker.stories.ts +218 -0
  165. package/src/components/DatePicker/DatePickerValidationExample/DatePickerValidation.mdx +2 -0
  166. package/src/components/DatePicker/DatePickerValidationExample/DatePickerValidation.stories.ts +1 -1
  167. package/src/components/DatePicker/DatePickerValidationExample/DateTextInput.stories.ts +218 -0
  168. package/src/components/DatePicker/DatePickerValidationExample/MultiMode.stories.ts +281 -0
  169. package/src/components/DatePicker/DateTextInput/DateTextInput.events.spec.ts +17 -4
  170. package/src/components/DatePicker/DateTextInput/DateTextInput.range.spec.ts +111 -18
  171. package/src/components/DatePicker/DateTextInput/DateTextInput.spec.ts +238 -6
  172. package/src/components/DatePicker/DateTextInput/DateTextInput.vue +716 -757
  173. package/src/components/DatePicker/composables/tests/useDateInputEditing.spec.ts +4 -4
  174. package/src/components/DatePicker/composables/tests/useDisplayedDateString.spec.ts +17 -10
  175. package/src/components/DatePicker/composables/useDateInputEditing.ts +52 -22
  176. package/src/components/DatePicker/composables/useDisplayedDateString.ts +18 -4
  177. package/src/components/DatePicker/composables/useTodayButton.ts +13 -1
  178. package/src/components/DatePicker/utils/dateFormattingUtils.ts +79 -14
  179. package/src/components/DialogBox/DialogBox.stories.ts +12 -0
  180. package/src/components/DialogBox/DialogBox.vue +16 -11
  181. package/src/components/DialogBox/tests/DialogBox.spec.ts +22 -0
  182. package/src/components/HeaderLoading/Accessibilite.mdx +429 -8
  183. package/src/components/HeaderLoading/Accessibilite.stories.ts +4 -0
  184. package/src/components/HeaderLoading/HeaderLoading.vue +59 -0
  185. package/src/components/HeaderNavigationBar/HeaderNavigationBar.mdx +17 -2
  186. package/src/components/HeaderNavigationBar/HeaderNavigationBar.stories.ts +91 -2
  187. package/src/components/HeaderNavigationBar/HeaderNavigationBar.vue +37 -1
  188. package/src/components/HeaderNavigationBar/HorizontalNavbar/HorizontalNavbar.vue +284 -21
  189. package/src/components/HeaderNavigationBar/tests/HeaderNavigationBar.spec.ts +2 -2
  190. package/src/components/NirField/NirField.mdx +3 -0
  191. package/src/components/NirField/NirField.vue +10 -1
  192. package/src/components/NirField/tests/NirField.spec.ts +81 -0
  193. package/src/components/NotificationBar/NotificationBar.stories.ts +128 -2
  194. package/src/components/NotificationBar/NotificationBar.vue +16 -1
  195. package/src/components/NotificationBar/tests/NotificationBar.spec.ts +65 -0
  196. package/src/components/PasswordField/PasswordField.mdx +3 -0
  197. package/src/components/PeriodField/PeriodField.mdx +2 -0
  198. package/src/components/PeriodField/PeriodField.stories.ts +195 -0
  199. package/src/components/PhoneField/Accessibilite.stories.ts +4 -0
  200. package/src/components/PhoneField/PhoneField.mdx +3 -1
  201. package/src/components/PhoneField/PhoneField.stories.ts +285 -1
  202. package/src/components/PhoneField/PhoneField.vue +228 -95
  203. package/src/components/PhoneField/indicatifs.ts +102 -102
  204. package/src/components/PhoneField/locales.ts +1 -0
  205. package/src/components/PhoneField/tests/PhoneField.spec.ts +419 -2
  206. package/src/components/SkipLink/SkipLink.vue +3 -31
  207. package/src/components/SkipLink/tests/skipLink.spec.ts +0 -21
  208. package/src/components/SubHeader/Accessibilite.stories.ts +8 -0
  209. package/src/components/SubHeader/SubHeader.mdx +1 -0
  210. package/src/components/SubHeader/SubHeader.stories.ts +179 -60
  211. package/src/components/SubHeader/SubHeader.vue +45 -15
  212. package/src/components/SubHeader/locales.ts +1 -0
  213. package/src/components/SyAlert/SyAlert.vue +6 -0
  214. package/src/components/Tables/SyServerTable/SyServerTable.mdx +3 -10
  215. package/src/components/Tables/SyServerTable/SyServerTable.stories.ts +242 -0
  216. package/src/components/Tables/SyServerTable/SyServerTable.vue +29 -10
  217. package/src/components/Tables/SyTable/SyTable.mdx +3 -10
  218. package/src/components/Tables/SyTable/SyTable.stories.ts +242 -0
  219. package/src/components/Tables/SyTable/SyTable.vue +2 -0
  220. package/src/components/Tables/common/SyTablePagination.vue +13 -6
  221. package/src/components/Tables/common/filters/tests/SelectFilter.spec.ts +6 -1
  222. package/src/components/Tables/common/tests/SyTablePagination.spec.ts +157 -0
  223. package/src/components/Tables/common/types.ts +2 -0
  224. package/src/components/index.ts +9 -0
  225. package/src/composables/useFilterable/useFilterable.ts +10 -0
  226. package/src/designTokens/tokens/amelipro/apColors.ts +1 -1
  227. package/src/designTokens/tokens/cnam/cnamSemantic.ts +3 -3
  228. package/src/services/NotificationService.ts +9 -0
  229. package/src/stories/Components/Components.stories.ts +1 -1
  230. package/src/stories/GuideDuDev/FormValidationGuide.mdx +342 -0
  231. package/src/stories/Templates/Templates.stories.ts +1 -1
  232. package/src/utils/functions/ameliproColors/ameliproColors.ts +1 -1
  233. package/dist/components/DataList/locales.d.ts +0 -3
  234. package/src/components/DataList/locales.ts +0 -3
  235. package/src/components/PhoneField/tests/PhoneField.additional.spec.ts +0 -266
@@ -7,7 +7,7 @@
7
7
  import { ref, watch, onMounted, onUnmounted, computed, nextTick, type PropType } from 'vue'
8
8
  import { useSySelectKeyboard } from './composables/useSySelectKeyboard'
9
9
  import { vRgaaSvgFix } from '../../../../directives/rgaaSvgFix'
10
- import type { VTextField } from 'vuetify/components'
10
+ import type { VList, VTextField } from 'vuetify/components'
11
11
  import { VChip } from 'vuetify/components'
12
12
  import SyCheckbox from '@/components/Customs/SyCheckbox/SyCheckbox.vue'
13
13
  import SyIcon from '@/components/Customs/SyIcon/SyIcon.vue'
@@ -60,6 +60,10 @@
60
60
  type: String,
61
61
  default: 'text',
62
62
  },
63
+ plainTextKey: {
64
+ type: String,
65
+ default: '',
66
+ },
63
67
  valueKey: {
64
68
  type: String,
65
69
  default: 'value',
@@ -112,6 +116,14 @@
112
116
  type: String,
113
117
  default: '',
114
118
  },
119
+ allowHtml: {
120
+ type: Boolean,
121
+ default: false,
122
+ },
123
+ autocomplete: {
124
+ type: String,
125
+ default: '',
126
+ },
115
127
  })
116
128
 
117
129
  const emit = defineEmits(['update:modelValue'])
@@ -123,12 +135,13 @@
123
135
 
124
136
  const labelWidth = ref(0)
125
137
  const labelRef = ref<HTMLElement | null>(null)
138
+ const list = ref<VList | null>(null)
139
+ const textInput = ref<InstanceType<typeof VTextField> | null>(null)
126
140
 
127
141
  const toggleMenu = (skipInitialFocus = false) => {
128
142
  if (props.readonly) return
129
143
  isOpen.value = !isOpen.value
130
144
  if (isOpen.value) {
131
- updateListPosition()
132
145
  // Initialiser la sélection à l'ouverture seulement si pas ouvert via clavier
133
146
  if (!skipInitialFocus) {
134
147
  nextTick(() => {
@@ -148,7 +161,7 @@
148
161
  const closeList = (event?: Event) => {
149
162
  // Check if the click is inside the dropdown list
150
163
  const target = event?.target as HTMLElement
151
- const listElement = document.querySelector('.v-list')
164
+ const listElement = list.value?.$el
152
165
 
153
166
  // In multiple selection mode, don't close the dropdown when clicking on list items
154
167
  if (props.multiple && listElement && listElement.contains(target)) {
@@ -160,18 +173,6 @@
160
173
  const inputId = ref(`sy-select-${Math.random().toString(36).substring(7)}`)
161
174
  // Generate unique menu ID for each component instance to avoid conflicts and validation issues
162
175
  const uniqueMenuId = ref(props.menuId === 'sy-select-menu' ? `sy-select-menu-${Math.random().toString(36).substring(7)}` : props.menuId)
163
- const listStyles = ref<Record<string, string>>({})
164
- const updateListPosition = () => {
165
- if (input.value?.$el) {
166
- const rect = input.value.$el.getBoundingClientRect()
167
- listStyles.value = {
168
- position: 'fixed',
169
- top: props.density === 'compact' ? `${rect.bottom + 22}px` : `${rect.bottom}px`,
170
- left: `${rect.left}px`,
171
- zIndex: '999',
172
- }
173
- }
174
- }
175
176
 
176
177
  const selectItem = (item: ItemType | null, event?: Event) => {
177
178
  // Prevent default action if event is provided
@@ -204,13 +205,12 @@
204
205
  if (event?.type === 'keydown' || event?.type === 'click') {
205
206
  if (!isOpen.value) {
206
207
  isOpen.value = true
207
- updateListPosition()
208
208
  }
209
209
 
210
210
  // S'assurer que le focus DOM revient à l'input et restaurer le focus visuel
211
211
  nextTick(() => {
212
212
  // Focus DOM sur l'input
213
- const inputElement = document.querySelector('.v-field__input')
213
+ const inputElement = textInput.value!.$el.querySelector('input')
214
214
  if (inputElement) {
215
215
  (inputElement as HTMLInputElement).focus()
216
216
  }
@@ -297,6 +297,16 @@
297
297
  return (item as Record<string, any>)[props.textKey]
298
298
  }
299
299
 
300
+ const getPlainItemText = (item: unknown) => {
301
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
302
+ const itemObj = item as Record<string, any>
303
+ // Use plainTextKey if available and allowHtml is true, otherwise use textKey
304
+ if (props.plainTextKey && props.allowHtml && itemObj[props.plainTextKey]) {
305
+ return itemObj[props.plainTextKey]
306
+ }
307
+ return itemObj[props.textKey]
308
+ }
309
+
300
310
  const selectedItemText = computed(() => {
301
311
  // If chips are enabled and we have selected items, return empty string to hide text
302
312
  if (hasChips.value) {
@@ -309,7 +319,7 @@
309
319
  // Find default option and return its text
310
320
  const defaultOption = props.items.find(item => isDefaultOption(item))
311
321
  if (defaultOption) {
312
- return defaultOption[props.textKey] as string
322
+ return getPlainItemText(defaultOption) as string
313
323
  }
314
324
  return ''
315
325
  }
@@ -319,9 +329,10 @@
319
329
 
320
330
  return selectedArray.map((selected) => {
321
331
  if (props.returnObject) {
322
- return selected?.[props.textKey]
332
+ return getPlainItemText(selected)
323
333
  }
324
- return props.items.find((item: ItemType) => item[props.valueKey] === selected)?.[props.textKey] || ''
334
+ const foundItem = props.items.find((item: ItemType) => item[props.valueKey] === selected)
335
+ return foundItem ? getPlainItemText(foundItem) : ''
325
336
  }).join(', ')
326
337
  }
327
338
  else {
@@ -329,10 +340,11 @@
329
340
  if (!selectedItem.value) return ''
330
341
 
331
342
  if (props.returnObject) {
332
- return selectedItem.value[props.textKey]
343
+ return getPlainItemText(selectedItem.value)
333
344
  }
334
345
 
335
- return props.items.find(item => item[props.valueKey] === selectedItem.value)?.[props.textKey] || ''
346
+ const foundItem = props.items.find(item => item[props.valueKey] === selectedItem.value)
347
+ return foundItem ? getPlainItemText(foundItem) : ''
336
348
  }
337
349
  })
338
350
 
@@ -363,8 +375,6 @@
363
375
  return (props.required || props.errorMessages.length > 0) && !selectedItem.value
364
376
  })
365
377
 
366
- const input = ref<InstanceType<typeof VTextField> | null>(null)
367
-
368
378
  // Détecte s'il y a des messages d'erreur, de succès ou d'avertissement
369
379
  const hasMessages = computed(() => {
370
380
  if (props.disableErrorHandling) return false
@@ -383,10 +393,19 @@
383
393
  })
384
394
 
385
395
  const calculatedWidth = computed(() => {
386
- const baseWidth = props.width ? Number(props.width) : 0
387
- const selectedText = typeof selectedItemText.value === 'string' ? selectedItemText.value : ''
388
- const clearableAdjustment = props.clearable ? 4 : 0
389
- return `${baseWidth + selectedText.length * (4 + clearableAdjustment)}px`
396
+ // If width prop is provided and not 'undefined', return it directly as a CSS value
397
+ if (props.width && props.width !== 'undefined') {
398
+ // Check if it's a pure number (for backward compatibility)
399
+ const numericValue = Number(props.width)
400
+ if (!isNaN(numericValue) && props.width === numericValue.toString()) {
401
+ // It's a pure number, add 'px' unit
402
+ return `${numericValue}px`
403
+ }
404
+ // It's already a CSS value (like "300px", "50%", "auto"), return as-is
405
+ return props.width
406
+ }
407
+ // No width specified, return undefined for auto-sizing
408
+ return undefined
390
409
  })
391
410
 
392
411
  watch(() => props.modelValue, (newValue) => {
@@ -415,7 +434,6 @@
415
434
  toggleMenu,
416
435
  selectItem,
417
436
  getItemText,
418
- updateListPosition,
419
437
  })
420
438
 
421
439
  // Function to check if an item is the default option (e.g., "-choisir-")
@@ -507,11 +525,6 @@
507
525
 
508
526
  // Then emit the update to the parent
509
527
  emit('update:modelValue', updatedArray)
510
-
511
- // Force update of the UI
512
- nextTick(() => {
513
- updateListPosition()
514
- })
515
528
  }
516
529
  }
517
530
 
@@ -539,9 +552,9 @@
539
552
 
540
553
  // Function to set up proper ARIA attributes
541
554
  const setupAriaAttributes = () => {
542
- if (input.value && input.value.$el) {
555
+ if (textInput.value && textInput.value.$el) {
543
556
  // Find the input element
544
- const inputElement = input.value.$el?.querySelector?.('input')
557
+ const inputElement = textInput.value.$el?.querySelector?.('input')
545
558
  if (inputElement) {
546
559
  // Remove problematic attributes that shouldn't be on input
547
560
  inputElement.removeAttribute('aria-describedby')
@@ -573,7 +586,7 @@
573
586
  }
574
587
 
575
588
  // Clean up parent element - remove any conflicting attributes
576
- const parentElement = input.value.$el
589
+ const parentElement = textInput.value.$el
577
590
  if (parentElement) {
578
591
  // Remove any role or ARIA attributes from parent that should be on input
579
592
  parentElement.removeAttribute('role')
@@ -584,6 +597,13 @@
584
597
  parentElement.removeAttribute('aria-required')
585
598
  parentElement.removeAttribute('aria-invalid')
586
599
  parentElement.removeAttribute('aria-hidden')
600
+
601
+ // Remove role="alert" and aria-live from message containers to prevent screen reader interruption
602
+ const messagesElements = parentElement.querySelectorAll('[role="alert"]')
603
+ messagesElements.forEach((element: Element) => {
604
+ element.removeAttribute('role')
605
+ element.removeAttribute('aria-live')
606
+ })
587
607
  }
588
608
  }
589
609
  }
@@ -592,8 +612,6 @@
592
612
  if (labelRef.value) {
593
613
  labelWidth.value = labelRef.value.offsetWidth + 64
594
614
  }
595
- window.addEventListener('scroll', updateListPosition, true)
596
- window.addEventListener('resize', updateListPosition)
597
615
 
598
616
  // Use nextTick to ensure the DOM is fully rendered
599
617
  nextTick(() => {
@@ -601,7 +619,7 @@
601
619
  setupAriaAttributes()
602
620
 
603
621
  // Set up MutationObserver to monitor attribute changes
604
- if (input.value && input.value.$el) {
622
+ if (textInput.value && textInput.value.$el) {
605
623
  mutationObserver = new MutationObserver((mutations) => {
606
624
  let needsCleanup = false
607
625
  mutations.forEach((mutation) => {
@@ -621,7 +639,15 @@
621
639
  }
622
640
 
623
641
  // Check if aria-hidden was added to parent
624
- if (target === input.value?.$el && attributeName === 'aria-hidden') {
642
+ if (target === textInput.value?.$el && attributeName === 'aria-hidden') {
643
+ needsCleanup = true
644
+ }
645
+
646
+ // Check if role="alert" or aria-live was added to any element (error messages)
647
+ if (attributeName === 'role' && (target as HTMLElement).getAttribute('role') === 'alert') {
648
+ needsCleanup = true
649
+ }
650
+ if (attributeName === 'aria-live') {
625
651
  needsCleanup = true
626
652
  }
627
653
  }
@@ -634,10 +660,10 @@
634
660
  })
635
661
 
636
662
  // Observe both the parent element and its children
637
- mutationObserver.observe(input.value.$el, {
663
+ mutationObserver.observe(textInput.value.$el, {
638
664
  attributes: true,
639
665
  subtree: true,
640
- attributeFilter: ['role', 'aria-hidden', 'aria-expanded', 'aria-controls', 'aria-haspopup'],
666
+ attributeFilter: ['role', 'aria-hidden', 'aria-expanded', 'aria-controls', 'aria-haspopup', 'aria-live'],
641
667
  })
642
668
  }
643
669
  })
@@ -646,8 +672,8 @@
646
672
  // Watchers to update ARIA attributes dynamically on input element
647
673
  watch(isOpen, (newValue) => {
648
674
  nextTick(() => {
649
- if (input.value && input.value.$el) {
650
- const inputElement = input.value.$el?.querySelector?.('input')
675
+ if (textInput.value && textInput.value.$el) {
676
+ const inputElement = textInput.value.$el?.querySelector?.('input')
651
677
  if (inputElement) {
652
678
  inputElement.setAttribute('aria-expanded', newValue ? 'true' : 'false')
653
679
  if (newValue && activeDescendantId.value) {
@@ -663,8 +689,8 @@
663
689
 
664
690
  watch(activeDescendantId, (newValue) => {
665
691
  nextTick(() => {
666
- if (input.value && input.value.$el && isOpen.value) {
667
- const inputElement = input.value.$el?.querySelector?.('input')
692
+ if (textInput.value && textInput.value.$el && isOpen.value) {
693
+ const inputElement = textInput.value.$el?.querySelector?.('input')
668
694
  if (inputElement) {
669
695
  if (newValue) {
670
696
  inputElement.setAttribute('aria-activedescendant', newValue)
@@ -679,8 +705,8 @@
679
705
 
680
706
  watch(hasError, (newValue) => {
681
707
  nextTick(() => {
682
- if (input.value && input.value.$el) {
683
- const inputElement = input.value.$el?.querySelector?.('input')
708
+ if (textInput.value && textInput.value.$el) {
709
+ const inputElement = textInput.value.$el?.querySelector?.('input')
684
710
  if (inputElement) {
685
711
  if (newValue) {
686
712
  inputElement.setAttribute('aria-invalid', 'true')
@@ -697,8 +723,8 @@
697
723
  // This prevents Vuetify from overriding our combobox attributes
698
724
  watch(selectedItem, () => {
699
725
  nextTick(() => {
700
- if (input.value && input.value.$el) {
701
- const inputElement = input.value.$el?.querySelector?.('input')
726
+ if (textInput.value && textInput.value.$el) {
727
+ const inputElement = textInput.value.$el?.querySelector?.('input')
702
728
  if (inputElement) {
703
729
  // Ensure combobox role is maintained on input
704
730
  inputElement.setAttribute('role', 'combobox')
@@ -726,7 +752,7 @@
726
752
  }
727
753
 
728
754
  // Clean up parent element
729
- const parentElement = input.value.$el
755
+ const parentElement = textInput.value.$el
730
756
  if (parentElement) {
731
757
  parentElement.removeAttribute('role')
732
758
  parentElement.removeAttribute('aria-hidden')
@@ -740,9 +766,6 @@
740
766
  }, { deep: true })
741
767
 
742
768
  onUnmounted(() => {
743
- window.removeEventListener('scroll', updateListPosition, true)
744
- window.removeEventListener('resize', updateListPosition)
745
-
746
769
  // Clean up MutationObserver
747
770
  if (mutationObserver) {
748
771
  mutationObserver.disconnect()
@@ -754,162 +777,187 @@
754
777
  isOpen,
755
778
  closeList,
756
779
  })
780
+
781
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
782
+ function initializeActivatorProps(activatorProps: Record<string, any>) {
783
+ return {
784
+ // the ref is needed by Vuetify to position the menu and by us for accessibility
785
+ ref: (el) => {
786
+ textInput.value = el
787
+ activatorProps.ref?.(el)
788
+ },
789
+ }
790
+ }
757
791
  </script>
758
792
 
759
793
  <template>
760
- <VTextField
761
- :id="inputId"
762
- ref="input"
763
- v-model="selectedItemText"
764
- v-click-outside="closeList"
765
- v-rgaa-svg-fix="true"
766
- :title="$attrs['aria-label'] || labelWithAsterisk"
767
- color="primary"
768
- :disabled="disabled"
769
- :label="labelWithAsterisk"
770
- :aria-label="$attrs['aria-label'] || labelWithAsterisk"
771
- :error-messages="props.disableErrorHandling ? [] : errorMessages"
772
- :variant="outlined ? 'outlined' : 'underlined'"
773
- :rules="isRequired && !props.disableErrorHandling ? ['Le champ est requis.'] : []"
774
- :bg-color="props.bgColor"
775
- :density="props.density"
776
- :active="hasChips || isOpen"
777
- readonly
778
- :hide-details="props.hideMessages && !showHelpTextAsMessage"
779
- :hint="showHelpTextAsMessage ? props.helpText : ''"
780
- :persistent-hint="!!showHelpTextAsMessage"
781
- class="sy-select"
782
- :width="calculatedWidth"
783
- :style="hasError ? { minWidth: `${labelWidth + 18}px`} : {minWidth: `${labelWidth}px`}"
784
- v-bind="Object.fromEntries(Object.entries($attrs).filter(([key]) => key !== 'display-asterisk'))"
785
- @click="toggleMenu"
786
- @keydown.enter.prevent="handleEnterKey"
787
- @keydown.space.prevent="handleSpaceKey"
788
- @keydown.down.prevent="handleDownKey"
789
- @keydown.up.prevent="handleUpKey"
790
- @keydown.esc.prevent="handleEscapeKey"
791
- @keydown.home.prevent="handleHomeKey"
792
- @keydown.end.prevent="handleEndKey"
793
- @keydown.page-up.prevent="handlePageUpKey"
794
- @keydown.page-down.prevent="handlePageDownKey"
795
- @keydown.tab="handleTabKey"
796
- @keydown="(e) => {
797
- // Handle printable characters for keyboard navigation
798
- if (!e.ctrlKey && !e.altKey && !e.metaKey) {
799
- handleCharacterKey(e.key)
800
- }
801
- }"
794
+ <VMenu
795
+ v-model="isOpen"
796
+ transition="slide-y-transition"
802
797
  >
803
- <div
804
- v-if="hasChips"
805
- class="d-flex flex-wrap gap-1"
806
- >
807
- <VChip
808
- v-for="item in selectedItem"
809
- :key="props.returnObject ? item[props.valueKey] : item"
810
- size="small"
811
- class="ma-1"
812
- closable
813
- :close-label="`Supprimer ${getChipText(item)}`"
814
- @click:close="removeChip(item)"
815
- >
816
- {{ getChipText(item) }}
817
- </VChip>
818
- </div>
819
- <template #append-inner>
820
- <SyIcon
821
- v-if="hasError"
822
- class="mr-6"
823
- color="error"
824
- :icon="mdiInformation"
825
- :decorative="false"
826
- label="Information"
827
- role="img"
828
- />
829
- <button
830
- v-if="props.clearable && selectedItemText"
831
- type="button"
832
- class="sy-select__clear-button"
833
- :style="{ right: hasError ? '38px' : '32px' }"
834
- :aria-label="locales.clear"
835
- @keydown.enter.prevent="$event => selectItem(null, $event)"
836
- @keydown.space.prevent="$event => selectItem(null, $event)"
837
- @click.stop.prevent="$event => selectItem(null, $event)"
798
+ <template #activator="{ props: activatorProps }">
799
+ <VTextField
800
+ :id="inputId"
801
+ v-model="selectedItemText"
802
+ v-click-outside="closeList"
803
+ v-rgaa-svg-fix="true"
804
+ :title="$attrs['aria-label'] || labelWithAsterisk"
805
+ color="primary"
806
+ :disabled="disabled"
807
+ :label="labelWithAsterisk"
808
+ :aria-label="$attrs['aria-label'] || labelWithAsterisk"
809
+ :error-messages="props.disableErrorHandling ? [] : errorMessages"
810
+ :variant="outlined ? 'outlined' : 'underlined'"
811
+ :rules="isRequired && !props.disableErrorHandling ? ['Le champ est requis.'] : []"
812
+ :bg-color="props.bgColor"
813
+ :density="props.density"
814
+ :active="hasChips || isOpen"
815
+ readonly
816
+ :hide-details="props.hideMessages && !showHelpTextAsMessage"
817
+ :hint="showHelpTextAsMessage ? props.helpText : ''"
818
+ :persistent-hint="!!showHelpTextAsMessage"
819
+ :autocomplete="props.autocomplete"
820
+ class="sy-select"
821
+ :class="{ 'sy-select--clearable': props.clearable }"
822
+ :width="calculatedWidth"
823
+ :style="hasError ? { minWidth: `${labelWidth + 18}px`} : {minWidth: `${labelWidth}px`}"
824
+ v-bind="{
825
+ ...Object.fromEntries(Object.entries($attrs).filter(([key]) => key !== 'display-asterisk')),
826
+ ...initializeActivatorProps(activatorProps),
827
+ }"
828
+ @click="toggleMenu"
829
+ @keydown.enter.prevent="handleEnterKey"
830
+ @keydown.space.prevent="handleSpaceKey"
831
+ @keydown.down.prevent="handleDownKey"
832
+ @keydown.up.prevent="handleUpKey"
833
+ @keydown.esc.prevent="handleEscapeKey"
834
+ @keydown.home.prevent="handleHomeKey"
835
+ @keydown.end.prevent="handleEndKey"
836
+ @keydown.page-up.prevent="handlePageUpKey"
837
+ @keydown.page-down.prevent="handlePageDownKey"
838
+ @keydown.tab="handleTabKey"
839
+ @keydown="(e) => {
840
+ // Handle printable characters for keyboard navigation
841
+ if (!e.ctrlKey && !e.altKey && !e.metaKey) {
842
+ handleCharacterKey(e.key)
843
+ }
844
+ }"
838
845
  >
839
- <SyIcon
840
- class="sy-select__clear-icon"
841
- :icon="mdiCloseCircle"
842
- :decorative="true"
843
- />
844
- </button>
845
- <SyIcon
846
- class="arrow"
847
- :icon="mdiMenuDown"
848
- :decorative="true"
849
- />
846
+ <div
847
+ v-if="hasChips"
848
+ class="d-flex flex-wrap gap-1"
849
+ >
850
+ <VChip
851
+ v-for="item in selectedItem"
852
+ :key="props.returnObject ? item[props.valueKey] : item"
853
+ size="small"
854
+ class="ma-1"
855
+ closable
856
+ :close-label="`Supprimer ${getChipText(item)}`"
857
+ @click:close="removeChip(item)"
858
+ >
859
+ {{ getChipText(item) }}
860
+ </VChip>
861
+ </div>
862
+ <template #append-inner>
863
+ <SyIcon
864
+ v-if="hasError"
865
+ class="mr-6"
866
+ color="error"
867
+ :icon="mdiInformation"
868
+ :decorative="false"
869
+ label="Information"
870
+ role="img"
871
+ />
872
+ <button
873
+ v-if="props.clearable && selectedItemText"
874
+ type="button"
875
+ class="sy-select__clear-button"
876
+ :style="{ right: hasError ? '62px' : '42px' }"
877
+ :aria-label="locales.clear"
878
+ @keydown.enter.prevent="$event => selectItem(null, $event)"
879
+ @keydown.space.prevent="$event => selectItem(null, $event)"
880
+ @click.stop.prevent="$event => selectItem(null, $event)"
881
+ >
882
+ <SyIcon
883
+ class="sy-select__clear-icon"
884
+ :icon="mdiCloseCircle"
885
+ :decorative="true"
886
+ />
887
+ </button>
888
+ <SyIcon
889
+ class="arrow"
890
+ :icon="mdiMenuDown"
891
+ :decorative="true"
892
+ />
893
+ </template>
894
+ </VTextField>
895
+ <span
896
+ ref="labelRef"
897
+ class="hidden-label"
898
+ >{{ label }}</span>
850
899
  </template>
851
- </VTextField>
852
- <span
853
- ref="labelRef"
854
- class="hidden-label"
855
- >{{ label }}</span>
856
- <VList
857
- v-if="isOpen"
858
- :id="uniqueMenuId"
859
- class="v-list"
860
- role="listbox"
861
- :aria-multiselectable="props.multiple ? 'true' : undefined"
862
- :aria-label="$attrs['aria-label'] || labelWithAsterisk"
863
- :style="{
864
- minWidth: `${input?.$el.offsetWidth}px`,
865
- ...listStyles
866
- }"
867
- bg-color="white"
868
- tabindex="0"
869
- :title="props.multiple ? 'Sélection multiple' : 'Sélection'"
870
- @keydown.esc.prevent="closeList"
871
- @keydown.tab="handleTabKey"
872
- @keydown.enter.prevent="handleEnterKey"
873
- @keydown.down.prevent="handleDownKey"
874
- @keydown.up.prevent="handleUpKey"
875
- @keydown.home.prevent="handleHomeKey"
876
- @keydown.end.prevent="handleEndKey"
877
- @keydown.page-up.prevent="handlePageUpKey"
878
- @keydown.page-down.prevent="handlePageDownKey"
879
- @click.stop
880
- >
881
- <VListItem
882
- v-for="(item, index) in formattedItems"
883
- :id="`option-${index}`"
884
- :key="index"
885
- :ref="'options-' + index"
886
- role="option"
887
- class="v-list-item"
888
- :aria-selected="isItemSelected(item) ? 'true' : 'false'"
889
- tabindex="-1"
890
- :class="{ active: isItemSelected(item) || `option-${index}` === activeDescendantId }"
891
- @click.stop="(event) => selectItem(item, event)"
900
+ <VList
901
+ :id="uniqueMenuId"
902
+ ref="list"
903
+ class="v-list"
904
+ role="listbox"
905
+ :aria-multiselectable="props.multiple ? 'true' : undefined"
906
+ :aria-label="$attrs['aria-label'] || labelWithAsterisk"
907
+ :style="{
908
+ minWidth: `${textInput?.$el.offsetWidth}px`,
909
+ }"
910
+ bg-color="white"
911
+ tabindex="0"
912
+ :title="props.multiple ? 'Sélection multiple' : 'Sélection'"
913
+ @keydown.esc.prevent="closeList"
914
+ @keydown.tab="handleTabKey"
915
+ @keydown.enter.prevent="handleEnterKey"
916
+ @keydown.down.prevent="handleDownKey"
917
+ @keydown.up.prevent="handleUpKey"
918
+ @keydown.home.prevent="handleHomeKey"
919
+ @keydown.end.prevent="handleEndKey"
920
+ @keydown.page-up.prevent="handlePageUpKey"
921
+ @keydown.page-down.prevent="handlePageDownKey"
922
+ @click.stop
892
923
  >
893
- <template
894
- v-if="props.multiple && !isDefaultOption(item)"
895
- #prepend
924
+ <VListItem
925
+ v-for="(item, index) in formattedItems"
926
+ :id="`option-${index}`"
927
+ :key="index"
928
+ :ref="'options-' + index"
929
+ role="option"
930
+ class="v-list-item"
931
+ :aria-selected="isItemSelected(item) ? 'true' : 'false'"
932
+ tabindex="-1"
933
+ :class="{ active: isItemSelected(item) || `option-${index}` === activeDescendantId }"
934
+ @click.stop="(event) => selectItem(item, event)"
896
935
  >
897
- <SyCheckbox
898
- :model-value="isItemSelected(item)"
899
- density="compact"
900
- hide-details
901
- color="primary"
902
- class="mt-0 pt-0 mr-1"
903
- :title="getItemText(item)"
904
- :aria-label="getItemText(item)"
905
- @click.stop="(event) => selectItem(item, event)"
906
- />
907
- </template>
908
- <VListItemTitle>
909
- {{ getItemText(item) }}
910
- </VListItemTitle>
911
- </VListItem>
912
- </VList>
936
+ <template
937
+ v-if="props.multiple && !isDefaultOption(item)"
938
+ #prepend
939
+ >
940
+ <SyCheckbox
941
+ :model-value="isItemSelected(item)"
942
+ density="compact"
943
+ hide-details
944
+ color="primary"
945
+ class="mt-0 pt-0 mr-1"
946
+ :title="getItemText(item)"
947
+ :aria-label="getItemText(item)"
948
+ @click.stop="(event) => selectItem(item, event)"
949
+ />
950
+ </template>
951
+ <VListItemTitle>
952
+ <span
953
+ v-if="allowHtml"
954
+ v-html="getItemText(item)"
955
+ />
956
+ <span v-else>{{ getItemText(item) }}</span>
957
+ </VListItemTitle>
958
+ </VListItem>
959
+ </VList>
960
+ </VMenu>
913
961
 
914
962
  <div
915
963
  v-if="showHelpTextBelow"
@@ -1010,7 +1058,11 @@
1010
1058
  justify-content: center;
1011
1059
  top: 50%;
1012
1060
  transform: translateY(-50%);
1013
- right: 10px;
1061
+ right: 20px;
1062
+
1063
+ .v-icon {
1064
+ position: static;
1065
+ }
1014
1066
  }
1015
1067
 
1016
1068
  .v-chip {
@@ -1018,9 +1070,20 @@
1018
1070
  }
1019
1071
 
1020
1072
  :deep(.v-field__input) {
1021
- color: tokens.$grey-darken-20;
1073
+ opacity: 1;
1074
+ color: tokens.$grey-darken-20 !important;
1022
1075
  cursor: pointer;
1023
1076
  caret-color: transparent;
1077
+ padding-right: 25px;
1078
+ }
1079
+
1080
+ .sy-select--clearable :deep(.v-field__input),
1081
+ .sy-select :deep(.v-field--error .v-field__input) {
1082
+ padding-right: 55px;
1083
+ }
1084
+
1085
+ :deep(.v-field__input input) {
1086
+ text-overflow: ellipsis;
1024
1087
  }
1025
1088
 
1026
1089
  .hidden-label {