katecms 0.0.0-stage → 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (552) hide show
  1. package/README.md +5 -3
  2. package/dist/module.d.mts +93 -0
  3. package/dist/module.json +9 -0
  4. package/dist/module.mjs +579 -0
  5. package/dist/runtime/assets/img/katecms-logo.svg +17 -0
  6. package/dist/runtime/composables/getCollection.d.ts +62 -0
  7. package/dist/runtime/composables/getCollection.js +167 -0
  8. package/dist/runtime/composables/getOptions.d.ts +22 -0
  9. package/dist/runtime/composables/getOptions.js +22 -0
  10. package/dist/runtime/composables/getQueryCollection.d.ts +95 -0
  11. package/dist/runtime/composables/getQueryCollection.js +199 -0
  12. package/dist/runtime/composables/getTerms.d.ts +79 -0
  13. package/dist/runtime/composables/getTerms.js +148 -0
  14. package/dist/runtime/composables/useAuth.d.ts +14 -0
  15. package/dist/runtime/composables/useAuth.js +33 -0
  16. package/dist/runtime/composables/useAuthCooldown.d.ts +6 -0
  17. package/dist/runtime/composables/useAuthCooldown.js +44 -0
  18. package/dist/runtime/composables/useCmsPaths.d.ts +15 -0
  19. package/dist/runtime/composables/useCmsPaths.js +21 -0
  20. package/dist/runtime/composables/useKateCmsExtensions.d.ts +49 -0
  21. package/dist/runtime/composables/useKateCmsExtensions.js +29 -0
  22. package/dist/runtime/composables/useMediaLibrary.d.ts +84 -0
  23. package/dist/runtime/composables/useMediaLibrary.js +140 -0
  24. package/dist/runtime/composables/useMenuAccess.d.ts +8 -0
  25. package/dist/runtime/composables/useMenuAccess.js +16 -0
  26. package/dist/runtime/internal/admin/AdminHeader.d.vue.ts +24 -0
  27. package/dist/runtime/internal/admin/AdminHeader.vue +91 -0
  28. package/dist/runtime/internal/admin/AdminHeader.vue.d.ts +24 -0
  29. package/dist/runtime/internal/admin/AppMenu.d.vue.ts +3 -0
  30. package/dist/runtime/internal/admin/AppMenu.vue +244 -0
  31. package/dist/runtime/internal/admin/AppMenu.vue.d.ts +3 -0
  32. package/dist/runtime/internal/admin/AppUser.d.vue.ts +3 -0
  33. package/dist/runtime/internal/admin/AppUser.vue +227 -0
  34. package/dist/runtime/internal/admin/AppUser.vue.d.ts +3 -0
  35. package/dist/runtime/internal/admin/CollectionEntryForm.d.vue.ts +41 -0
  36. package/dist/runtime/internal/admin/CollectionEntryForm.vue +916 -0
  37. package/dist/runtime/internal/admin/CollectionEntryForm.vue.d.ts +41 -0
  38. package/dist/runtime/internal/admin/ConfirmDialog.d.vue.ts +28 -0
  39. package/dist/runtime/internal/admin/ConfirmDialog.vue +136 -0
  40. package/dist/runtime/internal/admin/ConfirmDialog.vue.d.ts +28 -0
  41. package/dist/runtime/internal/admin/DictionaryTermForm.d.vue.ts +33 -0
  42. package/dist/runtime/internal/admin/DictionaryTermForm.vue +328 -0
  43. package/dist/runtime/internal/admin/DictionaryTermForm.vue.d.ts +33 -0
  44. package/dist/runtime/internal/admin/EntryRevisions.d.vue.ts +15 -0
  45. package/dist/runtime/internal/admin/EntryRevisions.vue +125 -0
  46. package/dist/runtime/internal/admin/EntryRevisions.vue.d.ts +15 -0
  47. package/dist/runtime/internal/admin/MediaLibraryFilters.d.vue.ts +16 -0
  48. package/dist/runtime/internal/admin/MediaLibraryFilters.vue +153 -0
  49. package/dist/runtime/internal/admin/MediaLibraryFilters.vue.d.ts +16 -0
  50. package/dist/runtime/internal/admin/MediaLibraryModal.d.vue.ts +65 -0
  51. package/dist/runtime/internal/admin/MediaLibraryModal.vue +451 -0
  52. package/dist/runtime/internal/admin/MediaLibraryModal.vue.d.ts +65 -0
  53. package/dist/runtime/internal/admin/OptionPageForm.d.vue.ts +26 -0
  54. package/dist/runtime/internal/admin/OptionPageForm.vue +222 -0
  55. package/dist/runtime/internal/admin/OptionPageForm.vue.d.ts +26 -0
  56. package/dist/runtime/internal/admin/UserAvatarField.d.vue.ts +12 -0
  57. package/dist/runtime/internal/admin/UserAvatarField.vue +305 -0
  58. package/dist/runtime/internal/admin/UserAvatarField.vue.d.ts +12 -0
  59. package/dist/runtime/internal/fields/AccordionField.d.vue.ts +0 -0
  60. package/dist/runtime/internal/fields/AccordionField.vue +220 -0
  61. package/dist/runtime/internal/fields/AccordionField.vue.d.ts +0 -0
  62. package/dist/runtime/internal/fields/ButtonGroupField.d.vue.ts +0 -0
  63. package/dist/runtime/internal/fields/ButtonGroupField.vue +109 -0
  64. package/dist/runtime/internal/fields/ButtonGroupField.vue.d.ts +0 -0
  65. package/dist/runtime/internal/fields/CheckboxField.d.vue.ts +0 -0
  66. package/dist/runtime/internal/fields/CheckboxField.vue +190 -0
  67. package/dist/runtime/internal/fields/CheckboxField.vue.d.ts +0 -0
  68. package/dist/runtime/internal/fields/ColorPickerField.d.vue.ts +0 -0
  69. package/dist/runtime/internal/fields/ColorPickerField.vue +791 -0
  70. package/dist/runtime/internal/fields/ColorPickerField.vue.d.ts +0 -0
  71. package/dist/runtime/internal/fields/DatePickerField.d.vue.ts +0 -0
  72. package/dist/runtime/internal/fields/DatePickerField.vue +26 -0
  73. package/dist/runtime/internal/fields/DatePickerField.vue.d.ts +0 -0
  74. package/dist/runtime/internal/fields/DateTimePickerField.d.vue.ts +0 -0
  75. package/dist/runtime/internal/fields/DateTimePickerField.vue +26 -0
  76. package/dist/runtime/internal/fields/DateTimePickerField.vue.d.ts +0 -0
  77. package/dist/runtime/internal/fields/DictionaryField.d.vue.ts +0 -0
  78. package/dist/runtime/internal/fields/DictionaryField.vue +345 -0
  79. package/dist/runtime/internal/fields/DictionaryField.vue.d.ts +0 -0
  80. package/dist/runtime/internal/fields/EmailField.d.vue.ts +0 -0
  81. package/dist/runtime/internal/fields/EmailField.vue +21 -0
  82. package/dist/runtime/internal/fields/EmailField.vue.d.ts +0 -0
  83. package/dist/runtime/internal/fields/FileField.d.vue.ts +0 -0
  84. package/dist/runtime/internal/fields/FileField.vue +408 -0
  85. package/dist/runtime/internal/fields/FileField.vue.d.ts +0 -0
  86. package/dist/runtime/internal/fields/FlexibleContentField.d.vue.ts +0 -0
  87. package/dist/runtime/internal/fields/FlexibleContentField.vue +1114 -0
  88. package/dist/runtime/internal/fields/FlexibleContentField.vue.d.ts +0 -0
  89. package/dist/runtime/internal/fields/GalleryField.d.vue.ts +0 -0
  90. package/dist/runtime/internal/fields/GalleryField.vue +584 -0
  91. package/dist/runtime/internal/fields/GalleryField.vue.d.ts +0 -0
  92. package/dist/runtime/internal/fields/GroupField.d.vue.ts +0 -0
  93. package/dist/runtime/internal/fields/GroupField.vue +111 -0
  94. package/dist/runtime/internal/fields/GroupField.vue.d.ts +0 -0
  95. package/dist/runtime/internal/fields/ImageField.d.vue.ts +0 -0
  96. package/dist/runtime/internal/fields/ImageField.vue +638 -0
  97. package/dist/runtime/internal/fields/ImageField.vue.d.ts +0 -0
  98. package/dist/runtime/internal/fields/ImageSelectField.d.vue.ts +0 -0
  99. package/dist/runtime/internal/fields/ImageSelectField.vue +179 -0
  100. package/dist/runtime/internal/fields/ImageSelectField.vue.d.ts +0 -0
  101. package/dist/runtime/internal/fields/LinkField.d.vue.ts +0 -0
  102. package/dist/runtime/internal/fields/LinkField.vue +303 -0
  103. package/dist/runtime/internal/fields/LinkField.vue.d.ts +0 -0
  104. package/dist/runtime/internal/fields/NumberField.d.vue.ts +0 -0
  105. package/dist/runtime/internal/fields/NumberField.vue +25 -0
  106. package/dist/runtime/internal/fields/NumberField.vue.d.ts +0 -0
  107. package/dist/runtime/internal/fields/OembedField.d.vue.ts +0 -0
  108. package/dist/runtime/internal/fields/OembedField.vue +161 -0
  109. package/dist/runtime/internal/fields/OembedField.vue.d.ts +0 -0
  110. package/dist/runtime/internal/fields/OpenStreetMapField.d.vue.ts +0 -0
  111. package/dist/runtime/internal/fields/OpenStreetMapField.vue +1502 -0
  112. package/dist/runtime/internal/fields/OpenStreetMapField.vue.d.ts +0 -0
  113. package/dist/runtime/internal/fields/PageLinkField.d.vue.ts +0 -0
  114. package/dist/runtime/internal/fields/PageLinkField.vue +153 -0
  115. package/dist/runtime/internal/fields/PageLinkField.vue.d.ts +0 -0
  116. package/dist/runtime/internal/fields/PasswordField.d.vue.ts +0 -0
  117. package/dist/runtime/internal/fields/PasswordField.vue +108 -0
  118. package/dist/runtime/internal/fields/PasswordField.vue.d.ts +0 -0
  119. package/dist/runtime/internal/fields/PostObjectField.d.vue.ts +0 -0
  120. package/dist/runtime/internal/fields/PostObjectField.vue +151 -0
  121. package/dist/runtime/internal/fields/PostObjectField.vue.d.ts +0 -0
  122. package/dist/runtime/internal/fields/RadioField.d.vue.ts +0 -0
  123. package/dist/runtime/internal/fields/RadioField.vue +163 -0
  124. package/dist/runtime/internal/fields/RadioField.vue.d.ts +0 -0
  125. package/dist/runtime/internal/fields/RangeField.d.vue.ts +0 -0
  126. package/dist/runtime/internal/fields/RangeField.vue +48 -0
  127. package/dist/runtime/internal/fields/RangeField.vue.d.ts +0 -0
  128. package/dist/runtime/internal/fields/RelationshipField.d.vue.ts +0 -0
  129. package/dist/runtime/internal/fields/RelationshipField.vue +525 -0
  130. package/dist/runtime/internal/fields/RelationshipField.vue.d.ts +0 -0
  131. package/dist/runtime/internal/fields/RepeaterField.d.vue.ts +0 -0
  132. package/dist/runtime/internal/fields/RepeaterField.vue +856 -0
  133. package/dist/runtime/internal/fields/RepeaterField.vue.d.ts +0 -0
  134. package/dist/runtime/internal/fields/SelectField.d.vue.ts +21 -0
  135. package/dist/runtime/internal/fields/SelectField.vue +101 -0
  136. package/dist/runtime/internal/fields/SelectField.vue.d.ts +21 -0
  137. package/dist/runtime/internal/fields/SeparatorField.d.vue.ts +0 -0
  138. package/dist/runtime/internal/fields/SeparatorField.vue +63 -0
  139. package/dist/runtime/internal/fields/SeparatorField.vue.d.ts +0 -0
  140. package/dist/runtime/internal/fields/TabField.d.vue.ts +0 -0
  141. package/dist/runtime/internal/fields/TabField.vue +210 -0
  142. package/dist/runtime/internal/fields/TabField.vue.d.ts +0 -0
  143. package/dist/runtime/internal/fields/TextField.d.vue.ts +0 -0
  144. package/dist/runtime/internal/fields/TextField.vue +22 -0
  145. package/dist/runtime/internal/fields/TextField.vue.d.ts +0 -0
  146. package/dist/runtime/internal/fields/TextareaField.d.vue.ts +0 -0
  147. package/dist/runtime/internal/fields/TextareaField.vue +62 -0
  148. package/dist/runtime/internal/fields/TextareaField.vue.d.ts +0 -0
  149. package/dist/runtime/internal/fields/TimePickerField.d.vue.ts +0 -0
  150. package/dist/runtime/internal/fields/TimePickerField.vue +24 -0
  151. package/dist/runtime/internal/fields/TimePickerField.vue.d.ts +0 -0
  152. package/dist/runtime/internal/fields/TrueFalseField.d.vue.ts +0 -0
  153. package/dist/runtime/internal/fields/TrueFalseField.vue +151 -0
  154. package/dist/runtime/internal/fields/TrueFalseField.vue.d.ts +0 -0
  155. package/dist/runtime/internal/fields/UrlField.d.vue.ts +0 -0
  156. package/dist/runtime/internal/fields/UrlField.vue +21 -0
  157. package/dist/runtime/internal/fields/UrlField.vue.d.ts +0 -0
  158. package/dist/runtime/internal/fields/UserField.d.vue.ts +0 -0
  159. package/dist/runtime/internal/fields/UserField.vue +164 -0
  160. package/dist/runtime/internal/fields/UserField.vue.d.ts +0 -0
  161. package/dist/runtime/internal/fields/WysiwygField.d.vue.ts +0 -0
  162. package/dist/runtime/internal/fields/WysiwygField.vue +971 -0
  163. package/dist/runtime/internal/fields/WysiwygField.vue.d.ts +0 -0
  164. package/dist/runtime/internal/parts/DateTimeControl.d.vue.ts +90 -0
  165. package/dist/runtime/internal/parts/DateTimeControl.vue +568 -0
  166. package/dist/runtime/internal/parts/DateTimeControl.vue.d.ts +90 -0
  167. package/dist/runtime/internal/parts/FieldAddon.d.vue.ts +0 -0
  168. package/dist/runtime/internal/parts/FieldAddon.vue +43 -0
  169. package/dist/runtime/internal/parts/FieldAddon.vue.d.ts +0 -0
  170. package/dist/runtime/internal/parts/FieldInstructions.d.vue.ts +0 -0
  171. package/dist/runtime/internal/parts/FieldInstructions.vue +24 -0
  172. package/dist/runtime/internal/parts/FieldInstructions.vue.d.ts +0 -0
  173. package/dist/runtime/internal/parts/FieldLabel.d.vue.ts +0 -0
  174. package/dist/runtime/internal/parts/FieldLabel.vue +40 -0
  175. package/dist/runtime/internal/parts/FieldLabel.vue.d.ts +0 -0
  176. package/dist/runtime/internal/parts/FieldWrapper.d.vue.ts +0 -0
  177. package/dist/runtime/internal/parts/FieldWrapper.vue +47 -0
  178. package/dist/runtime/internal/parts/FieldWrapper.vue.d.ts +0 -0
  179. package/dist/runtime/internal/parts/ImageCropper.d.vue.ts +17 -0
  180. package/dist/runtime/internal/parts/ImageCropper.vue +363 -0
  181. package/dist/runtime/internal/parts/ImageCropper.vue.d.ts +17 -0
  182. package/dist/runtime/internal/parts/InputControl.d.vue.ts +0 -0
  183. package/dist/runtime/internal/parts/InputControl.vue +163 -0
  184. package/dist/runtime/internal/parts/InputControl.vue.d.ts +0 -0
  185. package/dist/runtime/internal/ui/UiButton.d.vue.ts +35 -0
  186. package/dist/runtime/internal/ui/UiButton.vue +204 -0
  187. package/dist/runtime/internal/ui/UiButton.vue.d.ts +35 -0
  188. package/dist/runtime/internal/ui/UiNotice.d.vue.ts +40 -0
  189. package/dist/runtime/internal/ui/UiNotice.vue +253 -0
  190. package/dist/runtime/internal/ui/UiNotice.vue.d.ts +40 -0
  191. package/dist/runtime/internal/ui/UiSelect.d.vue.ts +61 -0
  192. package/dist/runtime/internal/ui/UiSelect.vue +1212 -0
  193. package/dist/runtime/internal/ui/UiSelect.vue.d.ts +61 -0
  194. package/dist/runtime/middleware/auth-guard.d.ts +9 -0
  195. package/dist/runtime/middleware/auth-guard.js +37 -0
  196. package/dist/runtime/pages/admin/collections/[id].d.vue.ts +3 -0
  197. package/dist/runtime/pages/admin/collections/[id].vue +423 -0
  198. package/dist/runtime/pages/admin/collections/[id].vue.d.ts +3 -0
  199. package/dist/runtime/pages/admin/collections/create.d.vue.ts +3 -0
  200. package/dist/runtime/pages/admin/collections/create.vue +179 -0
  201. package/dist/runtime/pages/admin/collections/create.vue.d.ts +3 -0
  202. package/dist/runtime/pages/admin/collections/index.d.vue.ts +3 -0
  203. package/dist/runtime/pages/admin/collections/index.vue +828 -0
  204. package/dist/runtime/pages/admin/collections/index.vue.d.ts +3 -0
  205. package/dist/runtime/pages/admin/demo-fields.d.vue.ts +3 -0
  206. package/dist/runtime/pages/admin/demo-fields.vue +1327 -0
  207. package/dist/runtime/pages/admin/demo-fields.vue.d.ts +3 -0
  208. package/dist/runtime/pages/admin/dictionaries/[id].d.vue.ts +3 -0
  209. package/dist/runtime/pages/admin/dictionaries/[id].vue +213 -0
  210. package/dist/runtime/pages/admin/dictionaries/[id].vue.d.ts +3 -0
  211. package/dist/runtime/pages/admin/dictionaries/index.d.vue.ts +3 -0
  212. package/dist/runtime/pages/admin/dictionaries/index.vue +387 -0
  213. package/dist/runtime/pages/admin/dictionaries/index.vue.d.ts +3 -0
  214. package/dist/runtime/pages/admin/index.d.vue.ts +3 -0
  215. package/dist/runtime/pages/admin/index.vue +138 -0
  216. package/dist/runtime/pages/admin/index.vue.d.ts +3 -0
  217. package/dist/runtime/pages/admin/login.d.vue.ts +3 -0
  218. package/dist/runtime/pages/admin/login.vue +373 -0
  219. package/dist/runtime/pages/admin/login.vue.d.ts +3 -0
  220. package/dist/runtime/pages/admin/media.d.vue.ts +3 -0
  221. package/dist/runtime/pages/admin/media.vue +1054 -0
  222. package/dist/runtime/pages/admin/media.vue.d.ts +3 -0
  223. package/dist/runtime/pages/admin/options/[page].d.vue.ts +3 -0
  224. package/dist/runtime/pages/admin/options/[page].vue +151 -0
  225. package/dist/runtime/pages/admin/options/[page].vue.d.ts +3 -0
  226. package/dist/runtime/pages/admin/register.d.vue.ts +3 -0
  227. package/dist/runtime/pages/admin/register.vue +391 -0
  228. package/dist/runtime/pages/admin/register.vue.d.ts +3 -0
  229. package/dist/runtime/pages/admin/users/[id].d.vue.ts +3 -0
  230. package/dist/runtime/pages/admin/users/[id].vue +337 -0
  231. package/dist/runtime/pages/admin/users/[id].vue.d.ts +3 -0
  232. package/dist/runtime/pages/admin/users/create.d.vue.ts +3 -0
  233. package/dist/runtime/pages/admin/users/create.vue +201 -0
  234. package/dist/runtime/pages/admin/users/create.vue.d.ts +3 -0
  235. package/dist/runtime/pages/admin/users/index.d.vue.ts +3 -0
  236. package/dist/runtime/pages/admin/users/index.vue +329 -0
  237. package/dist/runtime/pages/admin/users/index.vue.d.ts +3 -0
  238. package/dist/runtime/pages/index.d.vue.ts +3 -0
  239. package/dist/runtime/pages/index.vue +399 -0
  240. package/dist/runtime/pages/index.vue.d.ts +3 -0
  241. package/dist/runtime/server/api/_katecms/auth/login.post.d.ts +5 -0
  242. package/dist/runtime/server/api/_katecms/auth/login.post.js +44 -0
  243. package/dist/runtime/server/api/_katecms/auth/logout.post.d.ts +4 -0
  244. package/dist/runtime/server/api/_katecms/auth/logout.post.js +6 -0
  245. package/dist/runtime/server/api/_katecms/auth/register.post.d.ts +19 -0
  246. package/dist/runtime/server/api/_katecms/auth/register.post.js +83 -0
  247. package/dist/runtime/server/api/_katecms/auth/state.get.d.ts +9 -0
  248. package/dist/runtime/server/api/_katecms/auth/state.get.js +12 -0
  249. package/dist/runtime/server/api/_katecms/collections/[collection]/[id].delete.d.ts +15 -0
  250. package/dist/runtime/server/api/_katecms/collections/[collection]/[id].delete.js +59 -0
  251. package/dist/runtime/server/api/_katecms/collections/[collection]/[id].get.d.ts +4 -0
  252. package/dist/runtime/server/api/_katecms/collections/[collection]/[id].get.js +50 -0
  253. package/dist/runtime/server/api/_katecms/collections/[collection]/[id].patch.d.ts +4 -0
  254. package/dist/runtime/server/api/_katecms/collections/[collection]/[id].patch.js +130 -0
  255. package/dist/runtime/server/api/_katecms/collections/[collection]/revisions/[revisionId].post.d.ts +4 -0
  256. package/dist/runtime/server/api/_katecms/collections/[collection]/revisions/[revisionId].post.js +123 -0
  257. package/dist/runtime/server/api/_katecms/collections/[collection]/revisions.get.d.ts +6 -0
  258. package/dist/runtime/server/api/_katecms/collections/[collection]/revisions.get.js +31 -0
  259. package/dist/runtime/server/api/_katecms/collections/[collection].get.d.ts +8 -0
  260. package/dist/runtime/server/api/_katecms/collections/[collection].get.js +135 -0
  261. package/dist/runtime/server/api/_katecms/collections/[collection].post.d.ts +4 -0
  262. package/dist/runtime/server/api/_katecms/collections/[collection].post.js +91 -0
  263. package/dist/runtime/server/api/_katecms/dictionaries/[dictionary]/[id].delete.d.ts +7 -0
  264. package/dist/runtime/server/api/_katecms/dictionaries/[dictionary]/[id].delete.js +31 -0
  265. package/dist/runtime/server/api/_katecms/dictionaries/[dictionary]/[id].get.d.ts +4 -0
  266. package/dist/runtime/server/api/_katecms/dictionaries/[dictionary]/[id].get.js +45 -0
  267. package/dist/runtime/server/api/_katecms/dictionaries/[dictionary]/[id].patch.d.ts +4 -0
  268. package/dist/runtime/server/api/_katecms/dictionaries/[dictionary]/[id].patch.js +83 -0
  269. package/dist/runtime/server/api/_katecms/dictionaries/[dictionary].get.d.ts +4 -0
  270. package/dist/runtime/server/api/_katecms/dictionaries/[dictionary].get.js +38 -0
  271. package/dist/runtime/server/api/_katecms/dictionaries/[dictionary].post.d.ts +4 -0
  272. package/dist/runtime/server/api/_katecms/dictionaries/[dictionary].post.js +64 -0
  273. package/dist/runtime/server/api/_katecms/media/[id]/regenerate.post.d.ts +8 -0
  274. package/dist/runtime/server/api/_katecms/media/[id]/regenerate.post.js +30 -0
  275. package/dist/runtime/server/api/_katecms/media/[id].delete.d.ts +7 -0
  276. package/dist/runtime/server/api/_katecms/media/[id].delete.js +22 -0
  277. package/dist/runtime/server/api/_katecms/media/[id].get.d.ts +9 -0
  278. package/dist/runtime/server/api/_katecms/media/[id].get.js +17 -0
  279. package/dist/runtime/server/api/_katecms/media/[id].patch.d.ts +6 -0
  280. package/dist/runtime/server/api/_katecms/media/[id].patch.js +48 -0
  281. package/dist/runtime/server/api/_katecms/media/index.get.d.ts +5 -0
  282. package/dist/runtime/server/api/_katecms/media/index.get.js +75 -0
  283. package/dist/runtime/server/api/_katecms/media/index.post.d.ts +9 -0
  284. package/dist/runtime/server/api/_katecms/media/index.post.js +84 -0
  285. package/dist/runtime/server/api/_katecms/media/regenerate.post.d.ts +7 -0
  286. package/dist/runtime/server/api/_katecms/media/regenerate.post.js +30 -0
  287. package/dist/runtime/server/api/_katecms/menu.get.d.ts +8 -0
  288. package/dist/runtime/server/api/_katecms/menu.get.js +14 -0
  289. package/dist/runtime/server/api/_katecms/oembed.get.d.ts +2 -0
  290. package/dist/runtime/server/api/_katecms/oembed.get.js +53 -0
  291. package/dist/runtime/server/api/_katecms/options/[page].get.d.ts +7 -0
  292. package/dist/runtime/server/api/_katecms/options/[page].get.js +28 -0
  293. package/dist/runtime/server/api/_katecms/options/[page].patch.d.ts +4 -0
  294. package/dist/runtime/server/api/_katecms/options/[page].patch.js +36 -0
  295. package/dist/runtime/server/api/_katecms/query.get.d.ts +24 -0
  296. package/dist/runtime/server/api/_katecms/query.get.js +270 -0
  297. package/dist/runtime/server/api/_katecms/relation/entries.get.d.ts +17 -0
  298. package/dist/runtime/server/api/_katecms/relation/entries.get.js +74 -0
  299. package/dist/runtime/server/api/_katecms/relation/terms.get.d.ts +17 -0
  300. package/dist/runtime/server/api/_katecms/relation/terms.get.js +51 -0
  301. package/dist/runtime/server/api/_katecms/resolve.get.d.ts +17 -0
  302. package/dist/runtime/server/api/_katecms/resolve.get.js +116 -0
  303. package/dist/runtime/server/api/_katecms/terms.get.d.ts +20 -0
  304. package/dist/runtime/server/api/_katecms/terms.get.js +201 -0
  305. package/dist/runtime/server/api/_katecms/users/[id].delete.d.ts +11 -0
  306. package/dist/runtime/server/api/_katecms/users/[id].delete.js +45 -0
  307. package/dist/runtime/server/api/_katecms/users/[id].patch.d.ts +19 -0
  308. package/dist/runtime/server/api/_katecms/users/[id].patch.js +129 -0
  309. package/dist/runtime/server/api/_katecms/users.get.d.ts +10 -0
  310. package/dist/runtime/server/api/_katecms/users.get.js +34 -0
  311. package/dist/runtime/server/api/_katecms/users.post.d.ts +10 -0
  312. package/dist/runtime/server/api/_katecms/users.post.js +62 -0
  313. package/dist/runtime/server/api/uploads/[...key].get.d.ts +3 -0
  314. package/dist/runtime/server/api/uploads/[...key].get.js +28 -0
  315. package/dist/runtime/server/kit.d.ts +5 -0
  316. package/dist/runtime/server/kit.js +5 -0
  317. package/dist/runtime/server/middleware/admin-headers.d.ts +3 -0
  318. package/dist/runtime/server/middleware/admin-headers.js +12 -0
  319. package/dist/runtime/server/plugins/auto-migrate.d.ts +2 -0
  320. package/dist/runtime/server/plugins/auto-migrate.js +45 -0
  321. package/dist/runtime/server/tsconfig.json +3 -0
  322. package/dist/runtime/server/utils/auth-attempts.d.ts +22 -0
  323. package/dist/runtime/server/utils/auth-attempts.js +42 -0
  324. package/dist/runtime/server/utils/auth-rate-limit.d.ts +11 -0
  325. package/dist/runtime/server/utils/auth-rate-limit.js +36 -0
  326. package/dist/runtime/server/utils/client-address.d.ts +16 -0
  327. package/dist/runtime/server/utils/client-address.js +23 -0
  328. package/dist/runtime/server/utils/collections.d.ts +42 -0
  329. package/dist/runtime/server/utils/collections.js +300 -0
  330. package/dist/runtime/server/utils/db.d.ts +3 -0
  331. package/dist/runtime/server/utils/db.js +25 -0
  332. package/dist/runtime/server/utils/dictionaries.d.ts +53 -0
  333. package/dist/runtime/server/utils/dictionaries.js +301 -0
  334. package/dist/runtime/server/utils/media-list.d.ts +18 -0
  335. package/dist/runtime/server/utils/media-list.js +84 -0
  336. package/dist/runtime/server/utils/media.d.ts +12 -0
  337. package/dist/runtime/server/utils/media.js +77 -0
  338. package/dist/runtime/server/utils/oembed-fetch.d.ts +4 -0
  339. package/dist/runtime/server/utils/oembed-fetch.js +142 -0
  340. package/dist/runtime/server/utils/options.d.ts +17 -0
  341. package/dist/runtime/server/utils/options.js +66 -0
  342. package/dist/runtime/server/utils/permissions.d.ts +13 -0
  343. package/dist/runtime/server/utils/permissions.js +20 -0
  344. package/dist/runtime/server/utils/public-fields-query.d.ts +6 -0
  345. package/dist/runtime/server/utils/public-fields-query.js +8 -0
  346. package/dist/runtime/server/utils/public-term.d.ts +8 -0
  347. package/dist/runtime/server/utils/public-term.js +80 -0
  348. package/dist/runtime/server/utils/regenerate.d.ts +12 -0
  349. package/dist/runtime/server/utils/regenerate.js +40 -0
  350. package/dist/runtime/server/utils/relation.d.ts +18 -0
  351. package/dist/runtime/server/utils/relation.js +77 -0
  352. package/dist/runtime/server/utils/request-address.d.ts +6 -0
  353. package/dist/runtime/server/utils/request-address.js +10 -0
  354. package/dist/runtime/server/utils/revisions.d.ts +20 -0
  355. package/dist/runtime/server/utils/revisions.js +172 -0
  356. package/dist/runtime/server/utils/session.d.ts +18 -0
  357. package/dist/runtime/server/utils/session.js +71 -0
  358. package/dist/runtime/server/utils/upload-headers.d.ts +2 -0
  359. package/dist/runtime/server/utils/upload-headers.js +30 -0
  360. package/dist/runtime/server/utils/users.d.ts +13 -0
  361. package/dist/runtime/server/utils/users.js +47 -0
  362. package/dist/runtime/utils/admin-users.d.ts +20 -0
  363. package/dist/runtime/utils/admin-users.js +19 -0
  364. package/dist/runtime/utils/auth-error.d.ts +6 -0
  365. package/dist/runtime/utils/auth-error.js +11 -0
  366. package/dist/runtime/utils/cms-paths.d.ts +5 -0
  367. package/dist/runtime/utils/cms-paths.js +13 -0
  368. package/dist/runtime/utils/collections.d.ts +176 -0
  369. package/dist/runtime/utils/collections.js +30 -0
  370. package/dist/runtime/utils/dictionaries.d.ts +65 -0
  371. package/dist/runtime/utils/dictionaries.js +14 -0
  372. package/dist/runtime/utils/field-errors.d.ts +4 -0
  373. package/dist/runtime/utils/field-errors.js +9 -0
  374. package/dist/runtime/utils/field-values.d.ts +19 -0
  375. package/dist/runtime/utils/field-values.js +82 -0
  376. package/dist/runtime/utils/helpers.d.ts +4 -0
  377. package/dist/runtime/utils/helpers.js +20 -0
  378. package/dist/runtime/utils/media-library-query.d.ts +54 -0
  379. package/dist/runtime/utils/media-library-query.js +190 -0
  380. package/dist/runtime/utils/options.d.ts +19 -0
  381. package/dist/runtime/utils/options.js +3 -0
  382. package/dist/runtime/utils/preview.d.ts +22 -0
  383. package/dist/runtime/utils/preview.js +33 -0
  384. package/dist/runtime/utils/relation.d.ts +33 -0
  385. package/dist/runtime/utils/relation.js +23 -0
  386. package/dist/runtime/utils/slugify.d.ts +2 -0
  387. package/dist/runtime/utils/slugify.js +4 -0
  388. package/dist/types.d.mts +7 -0
  389. package/package.json +84 -3
  390. package/src/admin-components.ts +124 -0
  391. package/src/module.ts +592 -0
  392. package/src/runtime/assets/img/katecms-logo.svg +17 -0
  393. package/src/runtime/assets/styles/_functions.scss +70 -0
  394. package/src/runtime/assets/styles/_index.scss +3 -0
  395. package/src/runtime/assets/styles/_mixins.scss +256 -0
  396. package/src/runtime/assets/styles/_variables.scss +35 -0
  397. package/src/runtime/composables/getCollection.ts +253 -0
  398. package/src/runtime/composables/getOptions.ts +42 -0
  399. package/src/runtime/composables/getQueryCollection.ts +325 -0
  400. package/src/runtime/composables/getTerms.ts +231 -0
  401. package/src/runtime/composables/useAuth.ts +43 -0
  402. package/src/runtime/composables/useAuthCooldown.ts +52 -0
  403. package/src/runtime/composables/useCmsPaths.ts +24 -0
  404. package/src/runtime/composables/useKateCmsExtensions.ts +81 -0
  405. package/src/runtime/composables/useMediaLibrary.ts +168 -0
  406. package/src/runtime/composables/useMenuAccess.ts +25 -0
  407. package/src/runtime/internal/admin/AdminHeader.vue +106 -0
  408. package/src/runtime/internal/admin/AppMenu.vue +290 -0
  409. package/src/runtime/internal/admin/AppUser.vue +260 -0
  410. package/src/runtime/internal/admin/CollectionEntryForm.vue +1044 -0
  411. package/src/runtime/internal/admin/ConfirmDialog.vue +164 -0
  412. package/src/runtime/internal/admin/DictionaryTermForm.vue +400 -0
  413. package/src/runtime/internal/admin/EntryRevisions.vue +145 -0
  414. package/src/runtime/internal/admin/MediaLibraryFilters.vue +186 -0
  415. package/src/runtime/internal/admin/MediaLibraryModal.vue +526 -0
  416. package/src/runtime/internal/admin/OptionPageForm.vue +277 -0
  417. package/src/runtime/internal/admin/UserAvatarField.vue +337 -0
  418. package/src/runtime/internal/fields/AccordionField.vue +258 -0
  419. package/src/runtime/internal/fields/ButtonGroupField.vue +144 -0
  420. package/src/runtime/internal/fields/CheckboxField.vue +228 -0
  421. package/src/runtime/internal/fields/ColorPickerField.vue +926 -0
  422. package/src/runtime/internal/fields/DatePickerField.vue +33 -0
  423. package/src/runtime/internal/fields/DateTimePickerField.vue +33 -0
  424. package/src/runtime/internal/fields/DictionaryField.vue +403 -0
  425. package/src/runtime/internal/fields/EmailField.vue +28 -0
  426. package/src/runtime/internal/fields/FileField.vue +480 -0
  427. package/src/runtime/internal/fields/FlexibleContentField.vue +1296 -0
  428. package/src/runtime/internal/fields/GalleryField.vue +677 -0
  429. package/src/runtime/internal/fields/GroupField.vue +136 -0
  430. package/src/runtime/internal/fields/ImageField.vue +730 -0
  431. package/src/runtime/internal/fields/ImageSelectField.vue +213 -0
  432. package/src/runtime/internal/fields/LinkField.vue +338 -0
  433. package/src/runtime/internal/fields/NumberField.vue +32 -0
  434. package/src/runtime/internal/fields/OembedField.vue +187 -0
  435. package/src/runtime/internal/fields/OpenStreetMapField.vue +1716 -0
  436. package/src/runtime/internal/fields/PageLinkField.vue +186 -0
  437. package/src/runtime/internal/fields/PasswordField.vue +127 -0
  438. package/src/runtime/internal/fields/PostObjectField.vue +187 -0
  439. package/src/runtime/internal/fields/RadioField.vue +195 -0
  440. package/src/runtime/internal/fields/RangeField.vue +62 -0
  441. package/src/runtime/internal/fields/RelationshipField.vue +604 -0
  442. package/src/runtime/internal/fields/RepeaterField.vue +999 -0
  443. package/src/runtime/internal/fields/SelectField.vue +118 -0
  444. package/src/runtime/internal/fields/SeparatorField.vue +77 -0
  445. package/src/runtime/internal/fields/TabField.vue +249 -0
  446. package/src/runtime/internal/fields/TextField.vue +29 -0
  447. package/src/runtime/internal/fields/TextareaField.vue +61 -0
  448. package/src/runtime/internal/fields/TimePickerField.vue +31 -0
  449. package/src/runtime/internal/fields/TrueFalseField.vue +181 -0
  450. package/src/runtime/internal/fields/UrlField.vue +28 -0
  451. package/src/runtime/internal/fields/UserField.vue +203 -0
  452. package/src/runtime/internal/fields/WysiwygField.vue +1061 -0
  453. package/src/runtime/internal/parts/DateTimeControl.vue +657 -0
  454. package/src/runtime/internal/parts/FieldAddon.vue +60 -0
  455. package/src/runtime/internal/parts/FieldInstructions.vue +38 -0
  456. package/src/runtime/internal/parts/FieldLabel.vue +56 -0
  457. package/src/runtime/internal/parts/FieldWrapper.vue +63 -0
  458. package/src/runtime/internal/parts/ImageCropper.vue +415 -0
  459. package/src/runtime/internal/parts/InputControl.vue +189 -0
  460. package/src/runtime/internal/ui/UiButton.vue +274 -0
  461. package/src/runtime/internal/ui/UiNotice.vue +302 -0
  462. package/src/runtime/internal/ui/UiSelect.vue +1420 -0
  463. package/src/runtime/middleware/auth-guard.ts +52 -0
  464. package/src/runtime/pages/admin/collections/[id].vue +486 -0
  465. package/src/runtime/pages/admin/collections/create.vue +208 -0
  466. package/src/runtime/pages/admin/collections/index.vue +955 -0
  467. package/src/runtime/pages/admin/demo-fields.vue +1354 -0
  468. package/src/runtime/pages/admin/dictionaries/[id].vue +246 -0
  469. package/src/runtime/pages/admin/dictionaries/index.vue +438 -0
  470. package/src/runtime/pages/admin/index.vue +155 -0
  471. package/src/runtime/pages/admin/login.vue +159 -0
  472. package/src/runtime/pages/admin/media.vue +1176 -0
  473. package/src/runtime/pages/admin/options/[page].vue +174 -0
  474. package/src/runtime/pages/admin/register.vue +179 -0
  475. package/src/runtime/pages/admin/users/[id].vue +382 -0
  476. package/src/runtime/pages/admin/users/create.vue +232 -0
  477. package/src/runtime/pages/admin/users/index.vue +374 -0
  478. package/src/runtime/pages/index.vue +265 -0
  479. package/src/runtime/server/api/_katecms/auth/login.post.ts +62 -0
  480. package/src/runtime/server/api/_katecms/auth/logout.post.ts +7 -0
  481. package/src/runtime/server/api/_katecms/auth/register.post.ts +112 -0
  482. package/src/runtime/server/api/_katecms/auth/state.get.ts +19 -0
  483. package/src/runtime/server/api/_katecms/collections/[collection]/[id].delete.ts +77 -0
  484. package/src/runtime/server/api/_katecms/collections/[collection]/[id].get.ts +57 -0
  485. package/src/runtime/server/api/_katecms/collections/[collection]/[id].patch.ts +157 -0
  486. package/src/runtime/server/api/_katecms/collections/[collection]/revisions/[revisionId].post.ts +133 -0
  487. package/src/runtime/server/api/_katecms/collections/[collection]/revisions.get.ts +35 -0
  488. package/src/runtime/server/api/_katecms/collections/[collection].get.ts +177 -0
  489. package/src/runtime/server/api/_katecms/collections/[collection].post.ts +111 -0
  490. package/src/runtime/server/api/_katecms/dictionaries/[dictionary]/[id].delete.ts +37 -0
  491. package/src/runtime/server/api/_katecms/dictionaries/[dictionary]/[id].get.ts +51 -0
  492. package/src/runtime/server/api/_katecms/dictionaries/[dictionary]/[id].patch.ts +101 -0
  493. package/src/runtime/server/api/_katecms/dictionaries/[dictionary].get.ts +43 -0
  494. package/src/runtime/server/api/_katecms/dictionaries/[dictionary].post.ts +78 -0
  495. package/src/runtime/server/api/_katecms/media/[id]/regenerate.post.ts +39 -0
  496. package/src/runtime/server/api/_katecms/media/[id].delete.ts +28 -0
  497. package/src/runtime/server/api/_katecms/media/[id].get.ts +25 -0
  498. package/src/runtime/server/api/_katecms/media/[id].patch.ts +60 -0
  499. package/src/runtime/server/api/_katecms/media/index.get.ts +96 -0
  500. package/src/runtime/server/api/_katecms/media/index.post.ts +104 -0
  501. package/src/runtime/server/api/_katecms/media/regenerate.post.ts +38 -0
  502. package/src/runtime/server/api/_katecms/menu.get.ts +19 -0
  503. package/src/runtime/server/api/_katecms/oembed.get.ts +62 -0
  504. package/src/runtime/server/api/_katecms/options/[page].get.ts +35 -0
  505. package/src/runtime/server/api/_katecms/options/[page].patch.ts +46 -0
  506. package/src/runtime/server/api/_katecms/query.get.ts +332 -0
  507. package/src/runtime/server/api/_katecms/relation/entries.get.ts +98 -0
  508. package/src/runtime/server/api/_katecms/relation/terms.get.ts +61 -0
  509. package/src/runtime/server/api/_katecms/resolve.get.ts +148 -0
  510. package/src/runtime/server/api/_katecms/terms.get.ts +258 -0
  511. package/src/runtime/server/api/_katecms/users/[id].delete.ts +57 -0
  512. package/src/runtime/server/api/_katecms/users/[id].patch.ts +177 -0
  513. package/src/runtime/server/api/_katecms/users.get.ts +48 -0
  514. package/src/runtime/server/api/_katecms/users.post.ts +85 -0
  515. package/src/runtime/server/api/uploads/[...key].get.ts +33 -0
  516. package/src/runtime/server/kit.ts +5 -0
  517. package/src/runtime/server/middleware/admin-headers.ts +14 -0
  518. package/src/runtime/server/plugins/auto-migrate.ts +53 -0
  519. package/src/runtime/server/tsconfig.json +3 -0
  520. package/src/runtime/server/utils/auth-attempts.ts +71 -0
  521. package/src/runtime/server/utils/auth-rate-limit.ts +48 -0
  522. package/src/runtime/server/utils/client-address.ts +41 -0
  523. package/src/runtime/server/utils/collections.ts +381 -0
  524. package/src/runtime/server/utils/db.ts +36 -0
  525. package/src/runtime/server/utils/dictionaries.ts +397 -0
  526. package/src/runtime/server/utils/media-list.ts +131 -0
  527. package/src/runtime/server/utils/media.ts +94 -0
  528. package/src/runtime/server/utils/oembed-fetch.ts +157 -0
  529. package/src/runtime/server/utils/options.ts +86 -0
  530. package/src/runtime/server/utils/permissions.ts +44 -0
  531. package/src/runtime/server/utils/public-fields-query.ts +14 -0
  532. package/src/runtime/server/utils/public-term.ts +98 -0
  533. package/src/runtime/server/utils/regenerate.ts +56 -0
  534. package/src/runtime/server/utils/relation.ts +96 -0
  535. package/src/runtime/server/utils/request-address.ts +16 -0
  536. package/src/runtime/server/utils/revisions.ts +256 -0
  537. package/src/runtime/server/utils/session.ts +112 -0
  538. package/src/runtime/server/utils/upload-headers.ts +35 -0
  539. package/src/runtime/server/utils/users.ts +67 -0
  540. package/src/runtime/utils/admin-users.ts +43 -0
  541. package/src/runtime/utils/auth-error.ts +22 -0
  542. package/src/runtime/utils/cms-paths.ts +17 -0
  543. package/src/runtime/utils/collections.ts +228 -0
  544. package/src/runtime/utils/dictionaries.ts +89 -0
  545. package/src/runtime/utils/field-errors.ts +12 -0
  546. package/src/runtime/utils/field-values.ts +101 -0
  547. package/src/runtime/utils/helpers.ts +33 -0
  548. package/src/runtime/utils/media-library-query.ts +263 -0
  549. package/src/runtime/utils/options.ts +25 -0
  550. package/src/runtime/utils/preview.ts +56 -0
  551. package/src/runtime/utils/relation.ts +60 -0
  552. package/src/runtime/utils/slugify.ts +10 -0
@@ -0,0 +1,1212 @@
1
+ <script setup>
2
+ import {
3
+ computed,
4
+ nextTick,
5
+ onBeforeUnmount,
6
+ onMounted,
7
+ ref,
8
+ useId,
9
+ watch
10
+ } from "vue";
11
+ import {
12
+ isSelectChoiceGroup as isGroup,
13
+ selectChoiceValue as getValue,
14
+ walkSelectChoices as walkLeafOptions
15
+ } from "@katecms/core";
16
+ const rootClass = "katecms-select";
17
+ const EMPTY_IMG = "data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'/>";
18
+ const props = defineProps({
19
+ id: { type: String, required: false, default: "" },
20
+ name: { type: String, required: false, default: "" },
21
+ choices: { type: Array, required: false, default: () => [] },
22
+ placeholder: { type: String, required: false, default: "" },
23
+ disabled: { type: Boolean, required: false, default: false },
24
+ required: { type: Boolean, required: false, default: false },
25
+ selectedOptImage: { type: Boolean, required: false, default: false },
26
+ selectedOptClearable: { type: Boolean, required: false, default: false },
27
+ optionIcon: { type: Boolean, required: false, default: false },
28
+ search: { type: Boolean, required: false, default: false },
29
+ searchClearable: { type: Boolean, required: false, default: false },
30
+ searchPlaceholder: { type: String, required: false, default: "" },
31
+ maxHeight: { type: [Number, String], required: false, default: 300 },
32
+ multiple: { type: Boolean, required: false, default: false },
33
+ min: { type: Number, required: false, default: 0 },
34
+ max: { type: Number, required: false, default: Infinity },
35
+ allowCustomChoices: { type: Boolean, required: false, default: false },
36
+ ariaLabel: { type: String, required: false, default: "Select" },
37
+ noResultsText: { type: String, required: false, default: "No Option Found" },
38
+ addOptionText: { type: String, required: false, default: "Add" }
39
+ });
40
+ const model = defineModel({ type: [String, Number, Array, null] });
41
+ const uid = useId();
42
+ const listboxId = computed(() => `${rootClass}-listbox-${props.id || uid}`);
43
+ const searchId = computed(() => `${rootClass}-search-${props.id || uid}`);
44
+ const selectRef = ref(null);
45
+ const selectElement = ref(null);
46
+ const selectionRef = ref(null);
47
+ const dropdownRef = ref(null);
48
+ const optionsRef = ref(null);
49
+ const searchInputRef = ref(null);
50
+ const dropdownActive = ref(false);
51
+ const positionClass = ref("below");
52
+ const searchTerm = ref("");
53
+ const highlightedIndex = ref(-1);
54
+ const customOptions = ref([]);
55
+ const tabPressed = ref(false);
56
+ const isMobileOrTablet = ref(false);
57
+ const isIos = ref(false);
58
+ function valuesEqual(a, b) {
59
+ return String(a ?? "") === String(b ?? "");
60
+ }
61
+ function flattenOptions(options) {
62
+ const result = [];
63
+ walkLeafOptions(options, (opt) => result.push(opt));
64
+ return result;
65
+ }
66
+ const allOptions = computed(() => [
67
+ ...flattenOptions(props.choices),
68
+ ...customOptions.value
69
+ ]);
70
+ function findOption(value) {
71
+ return allOptions.value.find((opt) => valuesEqual(getValue(opt), value));
72
+ }
73
+ function findLbl(value) {
74
+ if (value === null || value === void 0 || value === "") return "";
75
+ const found = findOption(value);
76
+ if (found) return found.lbl || String(getValue(found));
77
+ return String(value);
78
+ }
79
+ function findImage(value) {
80
+ if (value === null || value === void 0 || value === "") return "";
81
+ return findOption(value)?.img ?? "";
82
+ }
83
+ function imageSrc(image) {
84
+ return image || EMPTY_IMG;
85
+ }
86
+ function emptySingle() {
87
+ return "";
88
+ }
89
+ function emptyMultiple() {
90
+ return [];
91
+ }
92
+ function normalizeModel(value) {
93
+ if (props.multiple) {
94
+ if (Array.isArray(value)) return value;
95
+ if (value === null || value === void 0 || value === "") return emptyMultiple();
96
+ return [value];
97
+ }
98
+ if (Array.isArray(value)) return value[0] ?? emptySingle();
99
+ if (value === null || value === void 0) return emptySingle();
100
+ return value;
101
+ }
102
+ function findCheckedValue() {
103
+ if (props.multiple) {
104
+ const checked = [];
105
+ walkLeafOptions(props.choices, (opt) => {
106
+ if (opt.check === true) checked.push(getValue(opt));
107
+ });
108
+ return checked.length ? checked : null;
109
+ }
110
+ let found = null;
111
+ walkLeafOptions(props.choices, (opt) => {
112
+ if (found === null && opt.check === true) found = getValue(opt);
113
+ });
114
+ return found;
115
+ }
116
+ function getFirstAvailableOption() {
117
+ for (const opt of flattenOptions(props.choices)) {
118
+ if (!opt.disabled && (opt.val !== void 0 || opt.lbl)) {
119
+ return opt;
120
+ }
121
+ }
122
+ return null;
123
+ }
124
+ function resolveInitialValue() {
125
+ const checked = findCheckedValue();
126
+ if (checked !== null) return checked;
127
+ if (!props.multiple && !props.placeholder) {
128
+ const first = getFirstAvailableOption();
129
+ if (first) return getValue(first);
130
+ }
131
+ return props.multiple ? emptyMultiple() : emptySingle();
132
+ }
133
+ const modelWasProvided = model.value !== void 0;
134
+ function ensureModelSeeded() {
135
+ if (modelWasProvided) return;
136
+ model.value = resolveInitialValue();
137
+ }
138
+ ensureModelSeeded();
139
+ const selectedValue = computed({
140
+ get() {
141
+ return normalizeModel(model.value);
142
+ },
143
+ set(value) {
144
+ model.value = value;
145
+ }
146
+ });
147
+ const nativeModel = computed({
148
+ get() {
149
+ const value = selectedValue.value;
150
+ if (props.multiple) {
151
+ return (Array.isArray(value) ? value : []).map(String);
152
+ }
153
+ return String(value ?? "");
154
+ },
155
+ set(value) {
156
+ if (props.multiple) {
157
+ const next = Array.isArray(value) ? value : [];
158
+ setMultiple(next.map((raw2) => {
159
+ const found2 = findOption(raw2);
160
+ return found2 ? getValue(found2) : raw2;
161
+ }));
162
+ return;
163
+ }
164
+ const raw = Array.isArray(value) ? value[0] ?? "" : value;
165
+ if (raw === "") {
166
+ setSingle("");
167
+ return;
168
+ }
169
+ const found = findOption(raw);
170
+ setSingle(found ? getValue(found) : raw);
171
+ }
172
+ });
173
+ const selectedArray = computed(() => {
174
+ const value = selectedValue.value;
175
+ return Array.isArray(value) ? value : [];
176
+ });
177
+ const hasSelection = computed(() => {
178
+ const value = selectedValue.value;
179
+ return Array.isArray(value) ? value.length > 0 : value !== "" && value !== null && value !== void 0;
180
+ });
181
+ const canClearAll = computed(() => {
182
+ if (!props.selectedOptClearable || !hasSelection.value || props.disabled) return false;
183
+ if (props.multiple) return selectedArray.value.length > props.min;
184
+ return true;
185
+ });
186
+ const isSelected = (optionValue) => {
187
+ const val = selectedValue.value;
188
+ if (Array.isArray(val)) return val.some((v) => valuesEqual(v, optionValue));
189
+ return valuesEqual(val, optionValue);
190
+ };
191
+ const atMax = computed(
192
+ () => props.multiple && selectedArray.value.length >= props.max
193
+ );
194
+ const atMin = computed(
195
+ () => props.multiple && selectedArray.value.length <= props.min
196
+ );
197
+ function isOptionDisabled(opt) {
198
+ if (opt.disabled) return true;
199
+ return props.multiple && atMax.value && !isSelected(getValue(opt));
200
+ }
201
+ const defaultLabel = computed(() => {
202
+ if (props.placeholder) return props.placeholder;
203
+ const first = getFirstAvailableOption();
204
+ return first ? String(getValue(first)) : "";
205
+ });
206
+ const displayValue = computed(() => {
207
+ const value = selectedValue.value;
208
+ if (props.multiple) {
209
+ if (Array.isArray(value) && value.length) {
210
+ return value.map((v) => {
211
+ const img = findImage(v);
212
+ return {
213
+ lbl: findLbl(v),
214
+ val: v,
215
+ img: imageSrc(img || void 0),
216
+ imgClass: img ? "" : "no-img"
217
+ };
218
+ });
219
+ }
220
+ return props.placeholder || "";
221
+ }
222
+ if (value === "" || value === null || value === void 0) {
223
+ return props.placeholder || findLbl(defaultLabel.value);
224
+ }
225
+ return findLbl(value) || props.placeholder || findLbl(defaultLabel.value);
226
+ });
227
+ const displayImage = computed(() => {
228
+ const value = selectedValue.value;
229
+ const empty = value === "" || value === null || value === void 0;
230
+ const image = empty ? props.placeholder ? "" : findImage(defaultLabel.value) : findImage(value);
231
+ return {
232
+ src: imageSrc(image || void 0),
233
+ class: image ? "" : "no-img"
234
+ };
235
+ });
236
+ const isPlaceholderShown = computed(() => {
237
+ const value = selectedValue.value;
238
+ const empty = Array.isArray(value) ? value.length === 0 : value === "";
239
+ return empty && !!props.placeholder;
240
+ });
241
+ function filterOptions(options, term) {
242
+ if (!term.trim()) return options;
243
+ const lower = term.toLowerCase();
244
+ return options.map((opt) => {
245
+ if (isGroup(opt)) {
246
+ const childs = filterOptions(opt.childs ?? [], term);
247
+ return childs.length ? { ...opt, childs } : null;
248
+ }
249
+ const lbl = opt.lbl?.toLowerCase() ?? "";
250
+ const val = String(opt.val ?? "").toLowerCase();
251
+ return lbl.includes(lower) || val.includes(lower) ? opt : null;
252
+ }).filter((opt) => opt !== null);
253
+ }
254
+ const filteredOptions = computed(() => {
255
+ const base = filterOptions(props.choices, searchTerm.value);
256
+ const term = searchTerm.value.trim().toLowerCase();
257
+ if (!term || !customOptions.value.length) return base;
258
+ const matchedCustom = customOptions.value.filter((opt) => {
259
+ const lbl = opt.lbl.toLowerCase();
260
+ const val = String(opt.val ?? "").toLowerCase();
261
+ return lbl.includes(term) || val.includes(term);
262
+ });
263
+ return matchedCustom.length ? [...base, ...matchedCustom] : base;
264
+ });
265
+ const flatFiltered = computed(() => flattenOptions(filteredOptions.value));
266
+ const optionIndexMap = computed(() => {
267
+ const map = /* @__PURE__ */ new Map();
268
+ flatFiltered.value.forEach((opt, index) => map.set(opt, index));
269
+ return map;
270
+ });
271
+ function optionIndex(opt) {
272
+ return optionIndexMap.value.get(opt) ?? -1;
273
+ }
274
+ const canAddCustom = computed(() => {
275
+ if (!props.allowCustomChoices || !props.search) return false;
276
+ const term = searchTerm.value.trim();
277
+ if (!term) return false;
278
+ return !allOptions.value.some((opt) => {
279
+ const lbl = opt.lbl.toLowerCase();
280
+ const val = String(getValue(opt)).toLowerCase();
281
+ const lower = term.toLowerCase();
282
+ return lbl === lower || val === lower;
283
+ });
284
+ });
285
+ const dropdownMaxHeight = computed(() => {
286
+ const value = props.maxHeight;
287
+ return typeof value === "number" ? `${value}px` : value;
288
+ });
289
+ const useCustomDropdown = computed(() => !isMobileOrTablet.value || isIos.value);
290
+ function closeDropdown() {
291
+ dropdownActive.value = false;
292
+ highlightedIndex.value = -1;
293
+ searchTerm.value = "";
294
+ }
295
+ function openDropdown() {
296
+ if (props.disabled) return;
297
+ dropdownActive.value = true;
298
+ nextTick(() => {
299
+ updatePosition();
300
+ if (props.search) searchInputRef.value?.focus();
301
+ scrollHighlightedIntoView();
302
+ });
303
+ }
304
+ function toggleDropdown(e) {
305
+ const target = e?.target;
306
+ if (target?.closest(`.${rootClass}__clear`) || target?.closest(`.${rootClass}__chip-clear`)) {
307
+ return;
308
+ }
309
+ if (props.disabled) return;
310
+ if (useCustomDropdown.value) {
311
+ if (dropdownActive.value) closeDropdown();
312
+ else openDropdown();
313
+ } else if (selectElement.value) {
314
+ selectElement.value.showPicker?.();
315
+ }
316
+ }
317
+ function setSingle(value) {
318
+ selectedValue.value = value;
319
+ }
320
+ function setMultiple(values) {
321
+ selectedValue.value = values;
322
+ }
323
+ function selectOption(value) {
324
+ const opt = findOption(value);
325
+ if (opt?.disabled) return;
326
+ if (props.multiple) {
327
+ const current = [...selectedArray.value];
328
+ const index = current.findIndex((v) => valuesEqual(v, value));
329
+ if (index >= 0) {
330
+ if (current.length <= props.min) return;
331
+ current.splice(index, 1);
332
+ setMultiple(current);
333
+ return;
334
+ }
335
+ if (current.length >= props.max) return;
336
+ setMultiple([...current, value]);
337
+ return;
338
+ }
339
+ setSingle(value);
340
+ closeDropdown();
341
+ }
342
+ function clearAll() {
343
+ if (!canClearAll.value) return;
344
+ if (props.multiple) {
345
+ if (props.min > 0) {
346
+ setMultiple(selectedArray.value.slice(0, props.min));
347
+ } else {
348
+ setMultiple(emptyMultiple());
349
+ }
350
+ } else {
351
+ setSingle(emptySingle());
352
+ }
353
+ closeDropdown();
354
+ }
355
+ function clearChip(value) {
356
+ if (!props.multiple || props.disabled) return;
357
+ if (selectedArray.value.length <= props.min) return;
358
+ setMultiple(selectedArray.value.filter((v) => !valuesEqual(v, value)));
359
+ }
360
+ function addCustomOption() {
361
+ if (!canAddCustom.value) return;
362
+ const term = searchTerm.value.trim();
363
+ const option = { val: term, lbl: term };
364
+ customOptions.value = [...customOptions.value, option];
365
+ if (props.multiple) {
366
+ if (selectedArray.value.length >= props.max) return;
367
+ setMultiple([...selectedArray.value, term]);
368
+ } else {
369
+ setSingle(term);
370
+ closeDropdown();
371
+ }
372
+ searchTerm.value = "";
373
+ }
374
+ function updatePosition() {
375
+ if (!dropdownActive.value || !dropdownRef.value || !selectionRef.value) return;
376
+ const triggerRect = selectionRef.value.getBoundingClientRect();
377
+ const elementHeight = dropdownRef.value.offsetHeight;
378
+ const viewportHeight = window.innerHeight;
379
+ const hasSpaceAbove = triggerRect.top - elementHeight > 0;
380
+ const hasSpaceBelow = triggerRect.bottom + elementHeight < viewportHeight;
381
+ positionClass.value = hasSpaceBelow || !hasSpaceAbove ? "below" : "above";
382
+ }
383
+ function scrollHighlightedIntoView() {
384
+ const container = optionsRef.value;
385
+ if (!container || highlightedIndex.value < 0) return;
386
+ const el = container.querySelector(
387
+ `[data-option-index="${highlightedIndex.value}"]`
388
+ );
389
+ el?.scrollIntoView({ block: "nearest" });
390
+ }
391
+ function moveHighlight(delta) {
392
+ const items = flatFiltered.value;
393
+ if (!items.length && !canAddCustom.value) return;
394
+ const total = items.length + (canAddCustom.value ? 1 : 0);
395
+ if (!dropdownActive.value) openDropdown();
396
+ let next = highlightedIndex.value;
397
+ if (next < 0) next = delta > 0 ? 0 : total - 1;
398
+ else next = (next + delta + total) % total;
399
+ highlightedIndex.value = next;
400
+ nextTick(scrollHighlightedIntoView);
401
+ }
402
+ function activateHighlighted() {
403
+ const items = flatFiltered.value;
404
+ if (highlightedIndex.value < 0) return;
405
+ if (highlightedIndex.value >= items.length) {
406
+ addCustomOption();
407
+ return;
408
+ }
409
+ const opt = items[highlightedIndex.value];
410
+ if (!opt || isOptionDisabled(opt)) return;
411
+ selectOption(getValue(opt));
412
+ }
413
+ function onSelectionKeydown(e) {
414
+ if (props.disabled) return;
415
+ switch (e.key) {
416
+ case "ArrowDown":
417
+ e.preventDefault();
418
+ if (!dropdownActive.value) openDropdown();
419
+ else moveHighlight(1);
420
+ break;
421
+ case "ArrowUp":
422
+ e.preventDefault();
423
+ if (!dropdownActive.value) openDropdown();
424
+ else moveHighlight(-1);
425
+ break;
426
+ case "Home":
427
+ if (dropdownActive.value) {
428
+ e.preventDefault();
429
+ highlightedIndex.value = 0;
430
+ nextTick(scrollHighlightedIntoView);
431
+ }
432
+ break;
433
+ case "End": {
434
+ if (dropdownActive.value) {
435
+ e.preventDefault();
436
+ const total = flatFiltered.value.length + (canAddCustom.value ? 1 : 0);
437
+ highlightedIndex.value = Math.max(0, total - 1);
438
+ nextTick(scrollHighlightedIntoView);
439
+ }
440
+ break;
441
+ }
442
+ case "Enter":
443
+ case " ":
444
+ e.preventDefault();
445
+ if (!dropdownActive.value) openDropdown();
446
+ else activateHighlighted();
447
+ break;
448
+ case "Escape":
449
+ if (dropdownActive.value) {
450
+ e.preventDefault();
451
+ closeDropdown();
452
+ }
453
+ break;
454
+ case "Tab":
455
+ tabPressed.value = true;
456
+ break;
457
+ }
458
+ }
459
+ function onSearchKeydown(e) {
460
+ switch (e.key) {
461
+ case "ArrowDown":
462
+ e.preventDefault();
463
+ moveHighlight(1);
464
+ break;
465
+ case "ArrowUp":
466
+ e.preventDefault();
467
+ moveHighlight(-1);
468
+ break;
469
+ case "Enter":
470
+ e.preventDefault();
471
+ if (canAddCustom.value && (highlightedIndex.value < 0 || highlightedIndex.value >= flatFiltered.value.length)) {
472
+ addCustomOption();
473
+ } else {
474
+ activateHighlighted();
475
+ }
476
+ break;
477
+ case "Escape":
478
+ e.preventDefault();
479
+ closeDropdown();
480
+ selectionRef.value?.focus();
481
+ break;
482
+ }
483
+ }
484
+ function onFocusOut(e) {
485
+ if (tabPressed.value && !selectRef.value?.contains(e.relatedTarget)) {
486
+ closeDropdown();
487
+ }
488
+ tabPressed.value = false;
489
+ }
490
+ function onDocPointerDown(e) {
491
+ if (!dropdownActive.value || !selectRef.value) return;
492
+ if (!selectRef.value.contains(e.target)) closeDropdown();
493
+ }
494
+ function onViewportChange() {
495
+ if (dropdownActive.value) updatePosition();
496
+ }
497
+ function detectDevice() {
498
+ if (!import.meta.client) return;
499
+ const ua = navigator.userAgent;
500
+ isIos.value = /iPad|iPhone|iPod/.test(ua) || navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1;
501
+ isMobileOrTablet.value = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(ua) || "ontouchstart" in window && window.innerWidth < 1024;
502
+ }
503
+ watch(dropdownActive, (open) => {
504
+ if (open) {
505
+ highlightedIndex.value = flatFiltered.value.findIndex((opt) => isSelected(getValue(opt)));
506
+ nextTick(updatePosition);
507
+ }
508
+ });
509
+ watch(searchTerm, () => {
510
+ highlightedIndex.value = flatFiltered.value.length || canAddCustom.value ? 0 : -1;
511
+ });
512
+ watch(() => props.choices, () => {
513
+ if (!modelWasProvided && !hasSelection.value) {
514
+ model.value = resolveInitialValue();
515
+ }
516
+ });
517
+ onMounted(() => {
518
+ detectDevice();
519
+ document.addEventListener("pointerdown", onDocPointerDown);
520
+ window.addEventListener("resize", onViewportChange);
521
+ window.addEventListener("scroll", onViewportChange, true);
522
+ });
523
+ onBeforeUnmount(() => {
524
+ document.removeEventListener("pointerdown", onDocPointerDown);
525
+ window.removeEventListener("resize", onViewportChange);
526
+ window.removeEventListener("scroll", onViewportChange, true);
527
+ });
528
+ defineExpose({
529
+ selectElement,
530
+ openDropdown,
531
+ closeDropdown
532
+ });
533
+ </script>
534
+
535
+ <template>
536
+ <div
537
+ ref="selectRef"
538
+ :class="[rootClass, positionClass, { [`${rootClass}--disabled`]: disabled, [`${rootClass}--open`]: dropdownActive }]"
539
+ @keydown.tab="tabPressed = true"
540
+ @focusout="onFocusOut"
541
+ >
542
+ <select
543
+ :id="id || void 0"
544
+ ref="selectElement"
545
+ v-model="nativeModel"
546
+ :name="name || void 0"
547
+ :disabled="disabled"
548
+ :required="required"
549
+ :multiple="multiple || void 0"
550
+ aria-hidden="true"
551
+ tabindex="-1"
552
+ >
553
+ <option
554
+ v-if="placeholder"
555
+ value=""
556
+ >
557
+ {{ placeholder }}
558
+ </option>
559
+
560
+ <template
561
+ v-for="(opt, i) in choices"
562
+ :key="isGroup(opt) ? `g-${opt.title}-${i}` : `o-${getValue(opt)}-${i}`"
563
+ >
564
+ <optgroup
565
+ v-if="isGroup(opt)"
566
+ :label="opt.title"
567
+ :disabled="opt.disabled"
568
+ >
569
+ <option
570
+ v-for="child in opt.childs"
571
+ :key="String(getValue(child))"
572
+ :value="String(getValue(child))"
573
+ :disabled="child.disabled"
574
+ >
575
+ {{ child.lbl }}
576
+ </option>
577
+ </optgroup>
578
+
579
+ <option
580
+ v-else
581
+ :value="String(getValue(opt))"
582
+ :disabled="opt.disabled"
583
+ >
584
+ {{ opt.lbl }}
585
+ </option>
586
+ </template>
587
+
588
+ <option
589
+ v-for="opt in customOptions"
590
+ :key="`custom-${getValue(opt)}`"
591
+ :value="String(getValue(opt))"
592
+ >
593
+ {{ opt.lbl }}
594
+ </option>
595
+ </select>
596
+
597
+ <div
598
+ ref="selectionRef"
599
+ :class="[`${rootClass}__selection`, { active: dropdownActive }]"
600
+ role="combobox"
601
+ :aria-label="ariaLabel"
602
+ :aria-expanded="dropdownActive"
603
+ :aria-controls="listboxId"
604
+ aria-haspopup="listbox"
605
+ :aria-activedescendant="highlightedIndex >= 0 ? `${listboxId}-opt-${highlightedIndex}` : void 0"
606
+ :aria-disabled="disabled || void 0"
607
+ :tabindex="disabled ? -1 : 0"
608
+ @click="toggleDropdown"
609
+ @keydown="onSelectionKeydown"
610
+ >
611
+ <div
612
+ v-if="selectedOptImage && (!multiple || multiple && !Array.isArray(displayValue))"
613
+ :class="[`${rootClass}__image`]"
614
+ >
615
+ <img
616
+ :key="String(selectedValue ?? '')"
617
+ :src="displayImage.src"
618
+ :class="displayImage.class || void 0"
619
+ aria-hidden="true"
620
+ alt=""
621
+ >
622
+ </div>
623
+
624
+ <div
625
+ :class="[
626
+ `${rootClass}__text`,
627
+ { [`${rootClass}__text--placeholder`]: isPlaceholderShown },
628
+ { [`${rootClass}__text--multiple`]: Array.isArray(displayValue) }
629
+ ]"
630
+ >
631
+ <template v-if="Array.isArray(displayValue)">
632
+ <div
633
+ v-for="chip in displayValue"
634
+ :key="String(chip.val)"
635
+ :class="[`${rootClass}__chip`]"
636
+ >
637
+ <img
638
+ v-if="selectedOptImage"
639
+ :src="chip.img"
640
+ :class="chip.imgClass || void 0"
641
+ aria-hidden="true"
642
+ alt=""
643
+ >
644
+ {{ chip.lbl }}
645
+ <button
646
+ type="button"
647
+ :class="[`${rootClass}__chip-clear`]"
648
+ :aria-label="`Remove ${chip.lbl}`"
649
+ :disabled="disabled || atMin"
650
+ :tabindex="dropdownActive ? 0 : -1"
651
+ @click.stop="clearChip(chip.val)"
652
+ >
653
+ <svg
654
+ width="13"
655
+ height="13"
656
+ viewBox="0 0 13 13"
657
+ fill="none"
658
+ xmlns="http://www.w3.org/2000/svg"
659
+ aria-hidden="true"
660
+ >
661
+ <path
662
+ d="M9.75 3.25L3.25 9.75"
663
+ stroke="currentColor"
664
+ stroke-width="1.08333"
665
+ stroke-linecap="round"
666
+ stroke-linejoin="round"
667
+ />
668
+ <path
669
+ d="M3.25 3.25L9.75 9.75"
670
+ stroke="currentColor"
671
+ stroke-width="1.08333"
672
+ stroke-linecap="round"
673
+ stroke-linejoin="round"
674
+ />
675
+ </svg>
676
+ </button>
677
+ </div>
678
+ </template>
679
+ <template v-else>
680
+ <span>{{ displayValue }}</span>
681
+ </template>
682
+ </div>
683
+
684
+ <button
685
+ v-if="canClearAll"
686
+ type="button"
687
+ :class="[`${rootClass}__clear`]"
688
+ aria-label="Clear selected value"
689
+ tabindex="0"
690
+ @click.stop="clearAll"
691
+ >
692
+ <svg
693
+ width="13"
694
+ height="13"
695
+ viewBox="0 0 13 13"
696
+ fill="none"
697
+ xmlns="http://www.w3.org/2000/svg"
698
+ aria-hidden="true"
699
+ >
700
+ <path
701
+ d="M9.75 3.25L3.25 9.75"
702
+ stroke="currentColor"
703
+ stroke-width="1.08333"
704
+ stroke-linecap="round"
705
+ stroke-linejoin="round"
706
+ />
707
+ <path
708
+ d="M3.25 3.25L9.75 9.75"
709
+ stroke="currentColor"
710
+ stroke-width="1.08333"
711
+ stroke-linecap="round"
712
+ stroke-linejoin="round"
713
+ />
714
+ </svg>
715
+ </button>
716
+
717
+ <div
718
+ :class="[`${rootClass}__arrow`, { active: dropdownActive }]"
719
+ aria-hidden="true"
720
+ >
721
+ <svg
722
+ width="20"
723
+ height="20"
724
+ viewBox="0 0 20 20"
725
+ fill="none"
726
+ xmlns="http://www.w3.org/2000/svg"
727
+ >
728
+ <path
729
+ d="M8.82683 15.181C9.47787 15.832 10.5352 15.832 11.1862 15.181L19.5195 6.84766C20.1706 6.19661 20.1706 5.13932 19.5195 4.48828C18.8685 3.83724 17.8112 3.83724 17.1602 4.48828L10.0039 11.6445L2.84766 4.49349C2.19662 3.84245 1.13932 3.84245 0.488281 4.49349C-0.16276 5.14453 -0.16276 6.20182 0.488281 6.85287L8.82162 15.1862L8.82683 15.181Z"
730
+ fill="currentColor"
731
+ />
732
+ </svg>
733
+ </div>
734
+ </div>
735
+
736
+ <div
737
+ v-if="useCustomDropdown"
738
+ :id="listboxId"
739
+ ref="dropdownRef"
740
+ :class="[`${rootClass}__dropdown`, { active: dropdownActive }]"
741
+ role="listbox"
742
+ :aria-multiselectable="multiple || void 0"
743
+ :aria-hidden="!dropdownActive || void 0"
744
+ >
745
+ <div
746
+ v-if="search"
747
+ :class="[`${rootClass}__search`]"
748
+ >
749
+ <input
750
+ :id="searchId"
751
+ ref="searchInputRef"
752
+ v-model="searchTerm"
753
+ type="search"
754
+ autocomplete="off"
755
+ autocapitalize="off"
756
+ spellcheck="false"
757
+ :tabindex="dropdownActive ? 0 : -1"
758
+ :placeholder="searchPlaceholder || void 0"
759
+ @keydown="onSearchKeydown"
760
+ @click.stop
761
+ >
762
+
763
+ <button
764
+ v-if="searchClearable && searchTerm"
765
+ type="button"
766
+ :class="[`${rootClass}__search-clear`]"
767
+ aria-label="Clear search"
768
+ :tabindex="dropdownActive ? 0 : -1"
769
+ @click.stop="searchTerm = ''"
770
+ >
771
+ <svg
772
+ width="13"
773
+ height="13"
774
+ viewBox="0 0 13 13"
775
+ fill="none"
776
+ xmlns="http://www.w3.org/2000/svg"
777
+ aria-hidden="true"
778
+ >
779
+ <path
780
+ d="M9.75 3.25L3.25 9.75"
781
+ stroke="currentColor"
782
+ stroke-width="1.08333"
783
+ stroke-linecap="round"
784
+ stroke-linejoin="round"
785
+ />
786
+ <path
787
+ d="M3.25 3.25L9.75 9.75"
788
+ stroke="currentColor"
789
+ stroke-width="1.08333"
790
+ stroke-linecap="round"
791
+ stroke-linejoin="round"
792
+ />
793
+ </svg>
794
+ </button>
795
+ </div>
796
+
797
+ <div
798
+ ref="optionsRef"
799
+ :class="[`${rootClass}__options`]"
800
+ >
801
+ <template
802
+ v-for="(opt, i) in filteredOptions"
803
+ :key="isGroup(opt) ? `fg-${opt.title}-${i}` : `fo-${getValue(opt)}-${i}`"
804
+ >
805
+ <div
806
+ v-if="isGroup(opt)"
807
+ :class="[`${rootClass}__optgroup`]"
808
+ :data-disabled="opt.disabled || void 0"
809
+ >
810
+ <div :class="[`${rootClass}__optgroup-title`]">
811
+ {{ opt.title }}
812
+ </div>
813
+
814
+ <button
815
+ v-for="child in opt.childs"
816
+ :id="`${listboxId}-opt-${optionIndex(child)}`"
817
+ :key="String(getValue(child))"
818
+ type="button"
819
+ role="option"
820
+ :class="[
821
+ `${rootClass}__option`,
822
+ { [`${rootClass}__option--highlighted`]: highlightedIndex === optionIndex(child) }
823
+ ]"
824
+ :data-option-index="optionIndex(child)"
825
+ :aria-selected="isSelected(getValue(child))"
826
+ :disabled="isOptionDisabled(child) || opt.disabled"
827
+ :tabindex="dropdownActive ? 0 : -1"
828
+ @click="selectOption(getValue(child))"
829
+ @mouseenter="highlightedIndex = optionIndex(child)"
830
+ >
831
+ <img
832
+ v-if="optionIcon"
833
+ :src="imageSrc(child.img)"
834
+ :class="{ 'no-img': !child.img }"
835
+ aria-hidden="true"
836
+ alt=""
837
+ >
838
+ <span>
839
+ {{ child.lbl }}
840
+ </span>
841
+ </button>
842
+ </div>
843
+
844
+ <button
845
+ v-else
846
+ :id="`${listboxId}-opt-${optionIndex(opt)}`"
847
+ type="button"
848
+ role="option"
849
+ :class="[
850
+ `${rootClass}__option`,
851
+ { [`${rootClass}__option--highlighted`]: highlightedIndex === optionIndex(opt) }
852
+ ]"
853
+ :data-option-index="optionIndex(opt)"
854
+ :aria-selected="isSelected(getValue(opt))"
855
+ :disabled="isOptionDisabled(opt)"
856
+ :tabindex="dropdownActive ? 0 : -1"
857
+ @click="selectOption(getValue(opt))"
858
+ @mouseenter="highlightedIndex = optionIndex(opt)"
859
+ >
860
+ <img
861
+ v-if="optionIcon"
862
+ :src="imageSrc(opt.img)"
863
+ :class="{ 'no-img': !opt.img }"
864
+ aria-hidden="true"
865
+ alt=""
866
+ >
867
+ <span>
868
+ {{ opt.lbl }}
869
+ </span>
870
+ </button>
871
+ </template>
872
+
873
+ <button
874
+ v-if="canAddCustom"
875
+ :id="`${listboxId}-opt-${flatFiltered.length}`"
876
+ type="button"
877
+ role="option"
878
+ :class="[
879
+ `${rootClass}__option`,
880
+ `${rootClass}__option--custom`,
881
+ { [`${rootClass}__option--highlighted`]: highlightedIndex === flatFiltered.length }
882
+ ]"
883
+ :data-option-index="flatFiltered.length"
884
+ aria-selected="false"
885
+ :tabindex="dropdownActive ? 0 : -1"
886
+ @click="addCustomOption"
887
+ @mouseenter="highlightedIndex = flatFiltered.length"
888
+ >
889
+ {{ addOptionText }} "{{ searchTerm.trim() }}"
890
+ </button>
891
+
892
+ <div
893
+ v-if="!filteredOptions.length && !canAddCustom"
894
+ :class="[`${rootClass}__no-results`]"
895
+ >
896
+ {{ noResultsText }}
897
+ </div>
898
+ </div>
899
+ </div>
900
+ </div>
901
+ </template>
902
+
903
+ <style scoped>
904
+ .katecms-select {
905
+ position: relative;
906
+ width: 100%;
907
+ }
908
+ .katecms-select--disabled .katecms-select__selection {
909
+ cursor: not-allowed;
910
+ opacity: 0.6;
911
+ background-color: var(--katecms-color-bg);
912
+ }
913
+ .katecms-select select {
914
+ opacity: 0;
915
+ visibility: hidden;
916
+ border: 0 !important;
917
+ clip: rect(0 0 0 0) !important;
918
+ clip-path: inset(50%) !important;
919
+ height: 1px !important;
920
+ overflow: hidden !important;
921
+ padding: 0 !important;
922
+ position: absolute !important;
923
+ width: 1px !important;
924
+ white-space: nowrap !important;
925
+ }
926
+ .katecms-select.below .katecms-select__dropdown {
927
+ top: calc(100% + 5px);
928
+ box-shadow: 0 8px 15px rgba(20, 26, 42, 0.1);
929
+ }
930
+ .katecms-select.above .katecms-select__dropdown {
931
+ bottom: calc(100% + 5px);
932
+ box-shadow: 0 -8px 15px rgba(20, 26, 42, 0.1);
933
+ }
934
+ .katecms-select__selection {
935
+ width: 100%;
936
+ background-color: var(--katecms-color-surface);
937
+ display: flex;
938
+ justify-content: space-between;
939
+ border: 1px solid var(--katecms-color-border);
940
+ border-radius: var(--katecms-border-radius);
941
+ cursor: pointer;
942
+ position: relative;
943
+ padding: 0 10px;
944
+ gap: 0.5rem;
945
+ }
946
+ .katecms-select__selection:focus-visible {
947
+ outline: 2px solid rgb(from var(--katecms-color-accent) r g b / 0.4);
948
+ outline-offset: 2px;
949
+ }
950
+ .katecms-select__image {
951
+ flex: 0 0 25px;
952
+ align-content: center;
953
+ }
954
+ .katecms-select__image img {
955
+ display: block;
956
+ width: 100%;
957
+ height: 17px !important;
958
+ object-fit: contain;
959
+ border-radius: 3px;
960
+ background-color: var(--katecms-color-border);
961
+ }
962
+ .katecms-select__image img.no-img {
963
+ background-color: var(--katecms-color-border);
964
+ }
965
+ .katecms-select__text {
966
+ min-height: 36px;
967
+ flex-basis: 0;
968
+ flex-grow: 1;
969
+ max-width: 100%;
970
+ text-align: left;
971
+ line-height: 1.5;
972
+ display: flex;
973
+ flex-wrap: wrap;
974
+ align-items: center;
975
+ gap: 4px;
976
+ color: var(--katecms-color-ink);
977
+ overflow: hidden;
978
+ }
979
+ .katecms-select__text--placeholder {
980
+ color: var(--katecms-color-muted);
981
+ }
982
+ .katecms-select__text--multiple {
983
+ padding-top: 3px;
984
+ padding-bottom: 3px;
985
+ }
986
+ .katecms-select__text > span {
987
+ white-space: nowrap;
988
+ overflow: hidden;
989
+ text-overflow: ellipsis;
990
+ }
991
+ .katecms-select__chip {
992
+ display: flex;
993
+ align-items: center;
994
+ gap: 10px;
995
+ background-color: var(--katecms-color-bg);
996
+ border-radius: 3px;
997
+ padding: 5px 10px;
998
+ font-size: 0.8125rem;
999
+ }
1000
+ .katecms-select__chip img {
1001
+ width: 25px;
1002
+ height: 17px !important;
1003
+ object-fit: contain;
1004
+ object-position: center;
1005
+ background-color: var(--katecms-color-border);
1006
+ }
1007
+ .katecms-select__chip img.no-img {
1008
+ background-color: var(--katecms-color-border);
1009
+ }
1010
+ .katecms-select__chip-clear {
1011
+ width: 20px;
1012
+ height: 20px;
1013
+ align-content: center;
1014
+ align-self: center;
1015
+ border: none;
1016
+ border-radius: 3px;
1017
+ background-color: transparent;
1018
+ padding: 0;
1019
+ color: var(--katecms-color-muted);
1020
+ cursor: pointer;
1021
+ transition: background-color 0.2s;
1022
+ }
1023
+ .katecms-select__chip-clear:hover:not(:disabled) {
1024
+ background-color: var(--katecms-color-border);
1025
+ }
1026
+ .katecms-select__chip-clear:disabled {
1027
+ cursor: not-allowed;
1028
+ opacity: 0.4;
1029
+ }
1030
+ .katecms-select__chip-clear svg {
1031
+ width: 18px;
1032
+ height: auto;
1033
+ display: block;
1034
+ margin-inline: auto;
1035
+ }
1036
+ .katecms-select__clear {
1037
+ width: 20px;
1038
+ height: 20px;
1039
+ align-content: center;
1040
+ align-self: center;
1041
+ border: none;
1042
+ border-radius: 3px;
1043
+ background-color: transparent;
1044
+ padding: 0;
1045
+ color: var(--katecms-color-muted);
1046
+ cursor: pointer;
1047
+ transition: background-color 0.2s;
1048
+ }
1049
+ .katecms-select__clear:hover {
1050
+ background-color: var(--katecms-color-border);
1051
+ }
1052
+ .katecms-select__clear svg {
1053
+ width: 18px;
1054
+ height: auto;
1055
+ display: block;
1056
+ margin-inline: auto;
1057
+ }
1058
+ .katecms-select__arrow {
1059
+ flex: 0 0 10px;
1060
+ max-width: 10px;
1061
+ display: flex;
1062
+ align-items: center;
1063
+ color: var(--katecms-color-muted);
1064
+ }
1065
+ .katecms-select__arrow svg {
1066
+ width: 10px;
1067
+ height: auto;
1068
+ display: block;
1069
+ transition: transform 0.3s;
1070
+ }
1071
+ .katecms-select__arrow.active svg {
1072
+ transform: rotate(180deg);
1073
+ }
1074
+ .katecms-select__dropdown {
1075
+ position: absolute;
1076
+ z-index: 900;
1077
+ background-color: var(--katecms-color-surface);
1078
+ border: 1px solid var(--katecms-color-border);
1079
+ border-radius: var(--katecms-border-radius);
1080
+ left: 0;
1081
+ width: 100%;
1082
+ max-height: v-bind(dropdownMaxHeight);
1083
+ display: none;
1084
+ }
1085
+ .katecms-select__dropdown.active {
1086
+ display: flex;
1087
+ flex-direction: column;
1088
+ }
1089
+ .katecms-select__search {
1090
+ padding: 8px;
1091
+ position: relative;
1092
+ }
1093
+ .katecms-select__search input {
1094
+ width: 100%;
1095
+ box-sizing: border-box;
1096
+ border: 1px solid var(--katecms-color-border);
1097
+ border-radius: var(--katecms-border-radius-inter);
1098
+ padding: 0 28px 0 10px;
1099
+ font: inherit;
1100
+ font-size: 0.9375rem;
1101
+ height: 2.25rem;
1102
+ outline: none;
1103
+ }
1104
+ .katecms-select__search-clear {
1105
+ position: absolute;
1106
+ top: 50%;
1107
+ right: 15px;
1108
+ transform: translateY(-50%);
1109
+ width: 20px;
1110
+ height: 20px;
1111
+ align-content: center;
1112
+ border: none;
1113
+ border-radius: 3px;
1114
+ background-color: transparent;
1115
+ padding: 0;
1116
+ color: var(--katecms-color-muted);
1117
+ cursor: pointer;
1118
+ transition: background-color 0.2s;
1119
+ }
1120
+ .katecms-select__search-clear:hover {
1121
+ background-color: var(--katecms-color-border);
1122
+ }
1123
+ .katecms-select__search-clear svg {
1124
+ width: 18px;
1125
+ height: auto;
1126
+ display: block;
1127
+ margin-inline: auto;
1128
+ }
1129
+ .katecms-select__options {
1130
+ overflow-y: auto;
1131
+ overscroll-behavior: contain;
1132
+ }
1133
+ .katecms-select__no-results {
1134
+ text-align: center;
1135
+ padding: 0.625rem 0.5rem;
1136
+ font-size: 0.875rem;
1137
+ color: var(--katecms-color-muted);
1138
+ }
1139
+ .katecms-select__optgroup:not(:last-child) {
1140
+ border-bottom: 1px solid var(--katecms-color-border);
1141
+ }
1142
+ .katecms-select__optgroup-title {
1143
+ padding: 0 10px;
1144
+ line-height: 32px;
1145
+ font-weight: 700;
1146
+ cursor: default;
1147
+ color: var(--katecms-color-ink);
1148
+ }
1149
+ .katecms-select__optgroup-title:not(:last-child) {
1150
+ border-bottom: 1px solid var(--katecms-color-border);
1151
+ }
1152
+ .katecms-select__optgroup .katecms-select__option {
1153
+ padding-left: 25px;
1154
+ }
1155
+ .katecms-select__option {
1156
+ width: 100%;
1157
+ min-height: 2.125rem;
1158
+ border: none;
1159
+ background-color: transparent;
1160
+ text-align: left;
1161
+ padding: 0 10px;
1162
+ display: flex;
1163
+ align-items: center;
1164
+ gap: 10px;
1165
+ color: var(--katecms-color-ink);
1166
+ cursor: pointer;
1167
+ font: inherit;
1168
+ overflow: hidden;
1169
+ }
1170
+ .katecms-select__option img {
1171
+ display: block;
1172
+ width: 25px;
1173
+ height: 25px !important;
1174
+ object-fit: contain;
1175
+ border-radius: 3px;
1176
+ }
1177
+ .katecms-select__option img.no-img {
1178
+ background-color: var(--katecms-color-border);
1179
+ }
1180
+ .katecms-select__option:not(:last-child) {
1181
+ border-bottom: 1px solid var(--katecms-color-border);
1182
+ }
1183
+ .katecms-select__option:first-child {
1184
+ border-radius: 3px 3px 0 0;
1185
+ }
1186
+ .katecms-select__option:last-child {
1187
+ border-radius: 0 0 3px 3px;
1188
+ }
1189
+ .katecms-select__option[aria-selected=true] {
1190
+ background-color: var(--katecms-color-accent);
1191
+ color: var(--katecms-color-on-accent);
1192
+ }
1193
+ .katecms-select__option--highlighted:not([aria-selected=true]):not([disabled]) {
1194
+ background-color: var(--katecms-color-bg);
1195
+ }
1196
+ .katecms-select__option--custom {
1197
+ font-style: italic;
1198
+ color: var(--katecms-color-accent);
1199
+ }
1200
+ .katecms-select__option[disabled] {
1201
+ cursor: not-allowed;
1202
+ color: var(--katecms-color-muted);
1203
+ background-color: var(--katecms-color-bg);
1204
+ }
1205
+ .katecms-select__option:hover:not([aria-selected=true]):not([disabled]) {
1206
+ background-color: var(--katecms-color-accent-wash);
1207
+ border-bottom-color: var(--katecms-color-accent-wash);
1208
+ }
1209
+ .katecms-select__option > span {
1210
+ overflow: hidden;
1211
+ }
1212
+ </style>