vueless 0.0.2 → 0.0.3

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 (436) hide show
  1. package/_readme/README.md +5 -75
  2. package/_readme/UNotify.md +1 -1
  3. package/_readme/UTopLoader.md +2 -2
  4. package/_readme/customization.md +347 -0
  5. package/_readme/installation.md +139 -0
  6. package/_readme/storybook-pages/Customisation.mdx +6 -0
  7. package/_readme/storybook-pages/Installation.mdx +7 -0
  8. package/composable.ui/index.js +341 -30
  9. package/library.vue-tailwind-3/index.js +0 -5
  10. package/library.web-types-gen/lib/build.js +35 -9
  11. package/library.web-types-gen/lib/config.js +10 -4
  12. package/package.json +37 -4
  13. package/plugin.vite/index.js +59 -0
  14. package/plugin.vite/services/iconResolver.service.js +291 -0
  15. package/plugin.vite/services/svgLoader.service.js +76 -0
  16. package/plugin.vite/services/tailwindSafelist.service.js +197 -0
  17. package/plugin.vite/services/unpluginComponentsResolver.js +172 -0
  18. package/service.storybook/index.js +53 -80
  19. package/service.tailwind/index.js +112 -0
  20. package/service.ui/index.js +69 -50
  21. package/ui.button/Docs.mdx +16 -0
  22. package/ui.button/composables/attrs.composable.js +41 -0
  23. package/ui.button/configs/default.config.js +164 -0
  24. package/ui.button/constants/index.js +5 -0
  25. package/ui.button/index.stories.js +8 -7
  26. package/ui.button/index.vue +116 -981
  27. package/ui.button-link/Docs.mdx +16 -0
  28. package/ui.button-link/composables/attrs.composable.js +99 -0
  29. package/ui.button-link/configs/default.config.js +80 -0
  30. package/ui.button-link/constants/index.js +5 -0
  31. package/ui.button-link/index.stories.js +56 -19
  32. package/ui.button-link/index.vue +178 -493
  33. package/ui.button-toggle/Docs.mdx +16 -0
  34. package/ui.button-toggle/composables/attrs.composable.js +16 -0
  35. package/ui.button-toggle/configs/default.config.js +12 -0
  36. package/ui.button-toggle/constants/index.js +7 -0
  37. package/{ui.button-group → ui.button-toggle}/index.stories.js +79 -28
  38. package/ui.button-toggle/index.vue +128 -0
  39. package/ui.button-toggle-item/Docs.mdx +16 -0
  40. package/ui.button-toggle-item/composables/attrs.composable.js +53 -0
  41. package/ui.button-toggle-item/configs/default.config.js +58 -0
  42. package/ui.button-toggle-item/constants/index.js +5 -0
  43. package/{ui.button-group-item → ui.button-toggle-item}/index.stories.js +16 -13
  44. package/ui.button-toggle-item/index.vue +147 -0
  45. package/ui.container-accordion/composables/attrs.composable.js +45 -0
  46. package/ui.container-accordion/configs/default.config.js +32 -0
  47. package/ui.container-accordion/constants/index.js +5 -0
  48. package/ui.container-accordion/index.stories.js +3 -2
  49. package/ui.container-accordion/index.vue +71 -143
  50. package/ui.container-card/Docs.mdx +16 -0
  51. package/ui.container-card/composable/attrs.composable.js +56 -0
  52. package/ui.container-card/configs/default.config.js +31 -0
  53. package/ui.container-card/constants/index.js +5 -0
  54. package/ui.container-card/index.stories.js +51 -9
  55. package/ui.container-card/index.vue +108 -169
  56. package/ui.container-divider/Docs.mdx +16 -0
  57. package/ui.container-divider/composables/attrs.composable.js +65 -0
  58. package/ui.container-divider/configs/default.config.js +79 -0
  59. package/ui.container-divider/constants/index.js +5 -0
  60. package/ui.container-divider/index.stories.js +41 -8
  61. package/ui.container-divider/index.vue +126 -189
  62. package/ui.container-group/Docs.mdx +16 -0
  63. package/ui.container-group/composables/attrs.composable.js +44 -0
  64. package/ui.container-group/configs/default.config.js +29 -0
  65. package/ui.container-group/constants/index.js +5 -0
  66. package/ui.container-group/index.stories.js +7 -6
  67. package/ui.container-group/index.vue +76 -142
  68. package/ui.container-groups/Docs.mdx +16 -0
  69. package/ui.container-groups/composables/attrs.composable.js +12 -0
  70. package/ui.container-groups/configs/default.config.js +3 -0
  71. package/ui.container-groups/index.stories.js +4 -3
  72. package/ui.container-groups/index.vue +26 -11
  73. package/ui.container-modal/Docs.mdx +16 -0
  74. package/ui.container-modal/composables/attrs.composable.js +90 -0
  75. package/ui.container-modal/configs/default.config.js +69 -0
  76. package/ui.container-modal/constants/index.js +5 -0
  77. package/ui.container-modal/index.stories.js +8 -7
  78. package/ui.container-modal/index.vue +289 -370
  79. package/ui.container-modal-confirm/Docs.mdx +16 -0
  80. package/ui.container-modal-confirm/composable/attrs.composable.js +19 -0
  81. package/ui.container-modal-confirm/configs/default.config.js +12 -0
  82. package/ui.container-modal-confirm/constants/index.js +5 -0
  83. package/ui.container-modal-confirm/index.stories.js +66 -7
  84. package/ui.container-modal-confirm/index.vue +126 -116
  85. package/ui.container-page/Docs.mdx +16 -0
  86. package/ui.container-page/composables/attrs.composable.js +96 -0
  87. package/ui.container-page/configs/default.config.js +71 -0
  88. package/ui.container-page/constants/index.js +5 -0
  89. package/ui.container-page/index.stories.js +7 -34
  90. package/ui.container-page/index.vue +193 -408
  91. package/ui.container-row/Docs.mdx +16 -0
  92. package/ui.container-row/composables/attrs.composable.js +23 -0
  93. package/ui.container-row/configs/default.config.js +14 -0
  94. package/ui.container-row/constants/index.js +5 -0
  95. package/ui.container-row/index.stories.js +10 -0
  96. package/ui.container-row/index.vue +32 -39
  97. package/ui.data-list/composables/attrs.composable.js +45 -0
  98. package/ui.data-list/configs/default.config.js +32 -0
  99. package/ui.data-list/constants/index.js +5 -0
  100. package/ui.data-list/index.stories.js +1 -0
  101. package/ui.data-list/index.vue +156 -265
  102. package/ui.data-table/Docs.mdx +16 -0
  103. package/ui.data-table/composables/attrs.composable.js +188 -0
  104. package/ui.data-table/configs/default.config.js +82 -0
  105. package/ui.data-table/constants/index.js +5 -0
  106. package/ui.data-table/index.stories.js +73 -43
  107. package/ui.data-table/index.vue +600 -961
  108. package/ui.data-table/services/table.service.js +15 -0
  109. package/ui.data-table-cell/composables/attrs.composable.js +24 -0
  110. package/ui.data-table-cell/configs/default.config.js +19 -0
  111. package/ui.data-table-cell/constants/index.js +5 -0
  112. package/ui.data-table-cell/index.vue +44 -0
  113. package/ui.dropdown-badge/Docs.mdx +16 -0
  114. package/ui.dropdown-badge/composables/attrs.composable.js +63 -0
  115. package/ui.dropdown-badge/configs/default.config.js +34 -0
  116. package/ui.dropdown-badge/constants/index.js +5 -0
  117. package/{ui.dropdown-tag → ui.dropdown-badge}/index.stories.js +26 -25
  118. package/ui.dropdown-badge/index.vue +233 -0
  119. package/ui.dropdown-button/Docs.mdx +16 -0
  120. package/ui.dropdown-button/composables/attrs.composable.js +63 -0
  121. package/ui.dropdown-button/configs/default.config.js +37 -0
  122. package/ui.dropdown-button/constants/index.js +14 -0
  123. package/ui.dropdown-button/index.stories.js +12 -11
  124. package/ui.dropdown-button/index.vue +231 -291
  125. package/ui.dropdown-item/Docs.mdx +16 -0
  126. package/ui.dropdown-item/composables/attrs.composable.js +13 -0
  127. package/ui.dropdown-item/configs/default.config.js +16 -0
  128. package/ui.dropdown-item/index.stories.js +2 -1
  129. package/ui.dropdown-item/index.vue +38 -55
  130. package/ui.dropdown-link/Docs.mdx +16 -0
  131. package/ui.dropdown-link/composables/attrs.composable.js +65 -0
  132. package/ui.dropdown-link/configs/default.config.js +37 -0
  133. package/ui.dropdown-link/constants/index.js +5 -0
  134. package/ui.dropdown-link/index.stories.js +11 -11
  135. package/ui.dropdown-link/index.vue +217 -287
  136. package/ui.dropdown-list/Docs.mdx +16 -0
  137. package/ui.dropdown-list/composables/attrs.composable.js +91 -0
  138. package/ui.dropdown-list/composables/usePointer.js +77 -0
  139. package/ui.dropdown-list/configs/default.config.js +68 -0
  140. package/ui.dropdown-list/constants/index.js +5 -0
  141. package/ui.dropdown-list/index.stories.js +33 -3
  142. package/ui.dropdown-list/index.vue +271 -112
  143. package/ui.form-calendar/Docs.mdx +52 -0
  144. package/ui.form-calendar/components/DayView.vue +230 -0
  145. package/ui.form-calendar/components/MonthView.vue +114 -0
  146. package/ui.form-calendar/components/YearView.vue +118 -0
  147. package/ui.form-calendar/composables/attrs.composable.js +87 -0
  148. package/ui.form-calendar/configs/default.config.js +115 -0
  149. package/ui.form-calendar/constants/index.js +69 -0
  150. package/ui.form-calendar/index.stories.js +50 -0
  151. package/ui.form-calendar/index.vue +628 -0
  152. package/ui.form-calendar/services/calendar.service.js +201 -0
  153. package/ui.form-calendar/services/date.service.js +121 -0
  154. package/ui.form-calendar/services/formatting.service.js +180 -0
  155. package/ui.form-checkbox/Docs.mdx +16 -0
  156. package/ui.form-checkbox/composables/attrs.composable.js +57 -0
  157. package/ui.form-checkbox/configs/default.config.js +69 -0
  158. package/ui.form-checkbox/constants/index.js +5 -0
  159. package/ui.form-checkbox/index.stories.js +75 -26
  160. package/ui.form-checkbox/index.vue +201 -261
  161. package/ui.form-checkbox-group/Docs.mdx +16 -0
  162. package/ui.form-checkbox-group/composables/attrs.composable.js +17 -0
  163. package/ui.form-checkbox-group/configs/default.config.js +5 -0
  164. package/ui.form-checkbox-group/constants/index.js +5 -0
  165. package/ui.form-checkbox-group/index.stories.js +7 -1
  166. package/ui.form-checkbox-group/index.vue +104 -177
  167. package/ui.form-checkbox-multi-state/Docs.mdx +16 -0
  168. package/ui.form-checkbox-multi-state/composables/attrs.composable.js +24 -0
  169. package/ui.form-checkbox-multi-state/configs/default.config.js +9 -0
  170. package/ui.form-checkbox-multi-state/constants/index.js +5 -0
  171. package/ui.form-checkbox-multi-state/index.stories.js +8 -11
  172. package/ui.form-checkbox-multi-state/index.vue +109 -220
  173. package/ui.form-color-picker/composables/attrs.composable.js +44 -0
  174. package/ui.form-color-picker/configs/default.config.js +52 -0
  175. package/ui.form-color-picker/constants/index.js +5 -0
  176. package/ui.form-color-picker/index.stories.js +63 -0
  177. package/ui.form-color-picker/index.vue +147 -329
  178. package/ui.form-date-picker/Docs.mdx +52 -0
  179. package/ui.form-date-picker/composables/attrs.composable.js +22 -0
  180. package/ui.form-date-picker/configs/default.config.js +27 -0
  181. package/ui.form-date-picker/constants/index.js +5 -0
  182. package/ui.form-date-picker/index.stories.js +21 -8
  183. package/ui.form-date-picker/index.vue +205 -802
  184. package/ui.form-input/Docs.mdx +16 -0
  185. package/ui.form-input/composables/attrs.composable.js +66 -0
  186. package/ui.form-input/configs/default.config.js +72 -0
  187. package/{constant.component-names → ui.form-input/constants}/index.js +1 -2
  188. package/ui.form-input/index.stories.js +46 -12
  189. package/ui.form-input/index.vue +320 -459
  190. package/ui.form-input-file/composables/attrs.composable.js +82 -0
  191. package/ui.form-input-file/configs/default.config.js +51 -0
  192. package/ui.form-input-file/constants/index.js +5 -0
  193. package/ui.form-input-file/index.stories.js +3 -2
  194. package/ui.form-input-file/index.vue +332 -498
  195. package/ui.form-input-money/Docs.mdx +16 -0
  196. package/ui.form-input-money/composables/attrs.composable.js +13 -0
  197. package/ui.form-input-money/composables/useFormatCurrency.js +82 -0
  198. package/ui.form-input-money/configs/default.config.js +16 -0
  199. package/ui.form-input-money/constants/index.js +5 -0
  200. package/ui.form-input-money/index.stories.js +71 -43
  201. package/ui.form-input-money/index.vue +241 -237
  202. package/ui.form-input-money/services/format.service.js +72 -0
  203. package/ui.form-input-number/Docs.mdx +16 -0
  204. package/ui.form-input-number/composables/attrs.composable.js +47 -0
  205. package/ui.form-input-number/configs/default.config.js +33 -0
  206. package/ui.form-input-number/constants/index.js +5 -0
  207. package/ui.form-input-number/index.stories.js +73 -3
  208. package/ui.form-input-number/index.vue +138 -106
  209. package/ui.form-input-rating/composables/attrs.composable.js +34 -0
  210. package/ui.form-input-rating/configs/default.config.js +25 -0
  211. package/ui.form-input-rating/constants/index.js +5 -0
  212. package/ui.form-input-rating/index.stories.js +3 -2
  213. package/ui.form-input-rating/index.vue +152 -209
  214. package/ui.form-input-search/composables/attrs.composable.js +21 -0
  215. package/ui.form-input-search/configs/default.config.js +20 -0
  216. package/ui.form-input-search/constants/index.js +5 -0
  217. package/ui.form-input-search/index.stories.js +8 -4
  218. package/ui.form-input-search/index.vue +192 -189
  219. package/ui.form-label/Docs.mdx +16 -0
  220. package/ui.form-label/composables/attrs.composable.js +65 -0
  221. package/ui.form-label/configs/default.config.js +95 -0
  222. package/ui.form-label/constants/index.js +13 -0
  223. package/ui.form-label/index.stories.js +107 -0
  224. package/ui.form-label/index.vue +170 -0
  225. package/ui.form-radio/Docs.mdx +16 -0
  226. package/ui.form-radio/composables/attrs.composable.js +34 -0
  227. package/ui.form-radio/configs/default.config.js +47 -0
  228. package/ui.form-radio/constants/index.js +5 -0
  229. package/ui.form-radio/index.stories.js +12 -10
  230. package/ui.form-radio/index.vue +141 -148
  231. package/ui.form-radio-card/Docs.mdx +16 -0
  232. package/ui.form-radio-card/composables/attrs.composable.js +30 -0
  233. package/ui.form-radio-card/configs/default.config.js +25 -0
  234. package/ui.form-radio-card/constants/index.js +5 -0
  235. package/ui.form-radio-card/index.stories.js +19 -10
  236. package/ui.form-radio-card/index.vue +132 -146
  237. package/ui.form-radio-card/services/variant.service.js +15 -0
  238. package/ui.form-radio-group/Docs.mdx +16 -0
  239. package/ui.form-radio-group/composables/attrs.composable.js +27 -0
  240. package/ui.form-radio-group/configs/default.config.js +18 -0
  241. package/ui.form-radio-group/constants/index.js +5 -0
  242. package/ui.form-radio-group/index.stories.js +1 -0
  243. package/ui.form-radio-group/index.vue +114 -85
  244. package/ui.form-select/Docs.mdx +16 -0
  245. package/ui.form-select/composables/attrs.composable.js +172 -0
  246. package/ui.form-select/configs/default.config.js +131 -0
  247. package/ui.form-select/constants/index.js +19 -0
  248. package/ui.form-select/index.stories.js +194 -38
  249. package/ui.form-select/index.vue +638 -910
  250. package/ui.form-select/services/select.service.js +98 -0
  251. package/ui.form-switch/composables/attrs.composable.js +77 -0
  252. package/ui.form-switch/configs/default.config.js +72 -0
  253. package/ui.form-switch/constants/index.js +5 -0
  254. package/ui.form-switch/index.stories.js +9 -42
  255. package/ui.form-switch/index.vue +177 -632
  256. package/ui.form-switch/services/variant.service.js +31 -0
  257. package/ui.form-textarea/Docs.mdx +16 -0
  258. package/ui.form-textarea/composables/attrs.composable.js +52 -0
  259. package/ui.form-textarea/configs/default.config.js +68 -0
  260. package/ui.form-textarea/constants/index.js +5 -0
  261. package/ui.form-textarea/index.stories.js +47 -5
  262. package/ui.form-textarea/index.vue +238 -353
  263. package/ui.image-avatar/composables/attrs.composable.js +34 -0
  264. package/ui.image-avatar/configs/default.config.js +42 -0
  265. package/ui.image-avatar/constants/index.js +5 -0
  266. package/ui.image-avatar/index.stories.js +7 -6
  267. package/ui.image-avatar/index.vue +94 -226
  268. package/ui.image-icon/Docs.mdx +16 -0
  269. package/ui.image-icon/composables/attrs.composable.js +65 -0
  270. package/ui.image-icon/configs/default.config.js +90 -0
  271. package/ui.image-icon/constants/index.js +5 -0
  272. package/ui.image-icon/index.stories.js +16 -35
  273. package/ui.image-icon/index.vue +165 -453
  274. package/ui.image-logo/composables/attrs.composable.js +41 -0
  275. package/ui.image-logo/configs/default.config.js +38 -0
  276. package/ui.image-logo/constants/index.js +5 -0
  277. package/ui.image-logo/index.stories.js +8 -8
  278. package/ui.image-logo/index.vue +80 -166
  279. package/ui.navigation-pagination/composables/attrs.composable.js +41 -0
  280. package/ui.navigation-pagination/configs/default.config.js +24 -0
  281. package/ui.navigation-pagination/constants/index.js +8 -0
  282. package/ui.navigation-pagination/index.stories.js +23 -6
  283. package/ui.navigation-pagination/index.vue +262 -102
  284. package/ui.navigation-stepper/composables/attrs.composable.js +25 -0
  285. package/ui.navigation-stepper/configs/default.config.js +13 -0
  286. package/ui.navigation-stepper/constants/index.js +5 -0
  287. package/ui.navigation-stepper/index.stories.js +1 -0
  288. package/ui.navigation-stepper/index.vue +87 -88
  289. package/ui.navigation-tab/composables/attrs.composable.js +30 -0
  290. package/ui.navigation-tab/configs/default.config.js +22 -0
  291. package/ui.navigation-tab/constants/index.js +5 -0
  292. package/ui.navigation-tab/index.stories.js +7 -11
  293. package/ui.navigation-tab/index.vue +58 -85
  294. package/ui.navigation-tabs/composables/attrs.composable.js +24 -0
  295. package/ui.navigation-tabs/configs/default.config.js +14 -0
  296. package/ui.navigation-tabs/constants/index.js +5 -0
  297. package/ui.navigation-tabs/index.stories.js +7 -11
  298. package/ui.navigation-tabs/index.vue +68 -88
  299. package/ui.other-dot/composables/attrs.composable.js +32 -0
  300. package/ui.other-dot/configs/default.config.js +21 -0
  301. package/ui.other-dot/constants/index.js +5 -0
  302. package/ui.other-dot/index.stories.js +5 -5
  303. package/ui.other-dot/index.vue +41 -89
  304. package/ui.other-loader/composables/attrs.composable.js +51 -0
  305. package/ui.other-loader/configs/default.config.js +47 -0
  306. package/ui.other-loader/constants/index.js +5 -0
  307. package/ui.other-loader/index.stories.js +14 -13
  308. package/ui.other-loader/index.vue +58 -107
  309. package/ui.text-alert/composables/attrs.composable.js +48 -0
  310. package/ui.text-alert/configs/default.config.js +51 -0
  311. package/ui.text-alert/constatns/index.js +5 -0
  312. package/ui.text-alert/index.stories.js +39 -6
  313. package/ui.text-alert/index.vue +95 -210
  314. package/ui.text-badge/Docs.mdx +16 -0
  315. package/ui.text-badge/composables/attrs.composable.js +49 -0
  316. package/ui.text-badge/configs/default.config.js +51 -0
  317. package/ui.text-badge/constants/index.js +5 -0
  318. package/ui.text-badge/index.stories.js +190 -0
  319. package/ui.text-badge/index.vue +120 -0
  320. package/ui.text-block/composables/attrs.composable.js +31 -0
  321. package/ui.text-block/configs/default.config.js +35 -0
  322. package/ui.text-block/constatns/index.js +5 -0
  323. package/ui.text-block/index.stories.js +2 -1
  324. package/ui.text-block/index.vue +55 -116
  325. package/ui.text-empty/Docs.mdx +16 -0
  326. package/ui.text-empty/composables/attrs.composable.js +43 -0
  327. package/ui.text-empty/configs/default.config.js +4 -2
  328. package/ui.text-empty/constants/index.js +5 -0
  329. package/ui.text-empty/index.stories.js +3 -3
  330. package/ui.text-empty/index.vue +13 -14
  331. package/ui.text-file/composables/attrs.composable.js +37 -0
  332. package/ui.text-file/configs/default.config.js +15 -0
  333. package/ui.text-file/index.stories.js +2 -1
  334. package/ui.text-file/index.vue +63 -72
  335. package/ui.text-files/composables/attrs.composable.js +19 -0
  336. package/ui.text-files/configs/default.config.js +9 -0
  337. package/ui.text-files/constants/index.js +5 -0
  338. package/ui.text-files/index.stories.js +1 -0
  339. package/ui.text-files/index.vue +73 -50
  340. package/ui.text-header/Docs.mdx +16 -0
  341. package/ui.text-header/composables/attrs.composable.js +34 -0
  342. package/ui.text-header/configs/default.config.js +45 -0
  343. package/ui.text-header/constants/index.js +5 -0
  344. package/ui.text-header/index.stories.js +34 -38
  345. package/ui.text-header/index.vue +67 -221
  346. package/ui.text-money/Docs.mdx +16 -0
  347. package/ui.text-money/composables/attrs.composable.js +65 -0
  348. package/ui.text-money/configs/default.config.js +69 -0
  349. package/ui.text-money/constants/index.js +7 -0
  350. package/ui.text-money/index.stories.js +24 -22
  351. package/ui.text-money/index.vue +187 -506
  352. package/ui.text-money/services/money.services.js +24 -0
  353. package/_readme/layoutAdmin.md +0 -703
  354. package/_readme/layoutApp.md +0 -153
  355. package/_readme/layoutAuth.md +0 -190
  356. package/config.rollup-plugin-visualizer/index.js +0 -11
  357. package/config.unplugin-vue-i18n/index.js +0 -9
  358. package/config.vite-plugin-pwa/index.js +0 -132
  359. package/config.vite-svg-loader/index.js +0 -22
  360. package/index.js +0 -151
  361. package/layout-ui.loader/index.vue +0 -61
  362. package/layout-ui.loader/store/index.js +0 -17
  363. package/layout-ui.loader-top/components/TopProgress.vue +0 -277
  364. package/layout-ui.loader-top/index.vue +0 -218
  365. package/layout-ui.loader-top/store/index.js +0 -55
  366. package/layout-ui.notify/index.stories.js +0 -102
  367. package/layout-ui.notify/index.vue +0 -254
  368. package/layout-ui.viewport/index.vue +0 -78
  369. package/layout-ui.viewport/store/index.js +0 -47
  370. package/layout.admin/AsideBlock.vue +0 -534
  371. package/layout.admin/AsideInfoBlock.vue +0 -85
  372. package/layout.admin/BrandBlock.vue +0 -380
  373. package/layout.admin/ChangeThemeModal.vue +0 -179
  374. package/layout.admin/HelperBlock.vue +0 -132
  375. package/layout.admin/MainMenu.vue +0 -234
  376. package/layout.admin/MainSubMenu.vue +0 -196
  377. package/layout.admin/MobileMainMenu.vue +0 -197
  378. package/layout.admin/MobileSubBlock.vue +0 -171
  379. package/layout.admin/RightInfoBlock.vue +0 -166
  380. package/layout.admin/UserBlock.vue +0 -290
  381. package/layout.admin/images/abstract-01.jpg +0 -0
  382. package/layout.admin/images/abstract-01_preview.jpg +0 -0
  383. package/layout.admin/index.vue +0 -544
  384. package/layout.admin/mixins/index.js +0 -54
  385. package/layout.admin/store/index.js +0 -167
  386. package/layout.auth/FeaturesBlock.vue +0 -57
  387. package/layout.auth/FooterMenu.vue +0 -90
  388. package/layout.auth/LanguageSwitcher.vue +0 -90
  389. package/layout.auth/index.vue +0 -237
  390. package/library.vue-tailwind-3/t-input.js +0 -68
  391. package/library.vue-tailwind-3/t-modal.js +0 -409
  392. package/library.vue-tailwind-3/t-pagination.js +0 -309
  393. package/library.vue-tailwind-3/t-table.js +0 -362
  394. package/library.vue-tailwind-3/t-textarea.js +0 -84
  395. package/resolver.unplugin-vue-components/index.js +0 -94
  396. package/service.api/index.js +0 -275
  397. package/service.data/index.js +0 -75
  398. package/service.date/index.js +0 -222
  399. package/service.i18n/index.js +0 -145
  400. package/service.idb-keyval/index.js +0 -37
  401. package/service.jwt/index.js +0 -27
  402. package/service.money/index.js +0 -86
  403. package/service.notify/index.js +0 -87
  404. package/service.redirect/index.js +0 -20
  405. package/service.validation/index.js +0 -55
  406. package/service.worker/index.js +0 -26
  407. package/ui.button-expand/index.stories.js +0 -44
  408. package/ui.button-expand/index.vue +0 -22
  409. package/ui.button-expand-item/index.stories.js +0 -69
  410. package/ui.button-expand-item/index.vue +0 -154
  411. package/ui.button-group/index.vue +0 -165
  412. package/ui.button-group-item/index.vue +0 -283
  413. package/ui.container-modal/components/ArrowLink.vue +0 -87
  414. package/ui.container-page/components/ArrowLink.vue +0 -87
  415. package/ui.data-table/components/DateSeparator.vue +0 -99
  416. package/ui.data-table/components/EmptyTableMsg.vue +0 -46
  417. package/ui.data-table/components/TableCheckbox.vue +0 -109
  418. package/ui.dropdown-tag/index.vue +0 -285
  419. package/ui.form-date-picker-range/components/VariantButton.vue +0 -136
  420. package/ui.form-date-picker-range/components/VariantInput.vue +0 -101
  421. package/ui.form-date-picker-range/index.stories.js +0 -93
  422. package/ui.form-date-picker-range/index.vue +0 -1537
  423. package/ui.form-date-picker-range/services/dateRange.service.js +0 -178
  424. package/ui.form-input-money/_components/ConvertibleInput.vue +0 -773
  425. package/ui.form-input-money/_components/RangeInput.vue +0 -356
  426. package/ui.form-input-money/_components/SingleInput.vue +0 -378
  427. package/ui.form-select-multi/index.stories.js +0 -131
  428. package/ui.form-select-multi/index.vue +0 -882
  429. package/ui.image-icon/cli.mjs +0 -159
  430. package/ui.text-empty/services/variant.service.js +0 -22
  431. package/ui.text-field/index.stories.js +0 -60
  432. package/ui.text-field/index.vue +0 -109
  433. package/ui.text-tag/index.stories.js +0 -90
  434. package/ui.text-tag/index.vue +0 -178
  435. package/web-types.json +0 -6320
  436. /package/ui.form-input/{text-security-disc.woff → assets/fonts/text-security-disc.woff} +0 -0
@@ -1,1025 +1,753 @@
1
1
  <template>
2
- <div class="mono-select-block">
3
- <div :id="wrapperId" class="mono-select-wrapper" :class="multiselectClass">
4
- <label v-if="label" class="label" :class="labelClasses" :for="id">
5
- {{ label }}
6
- </label>
7
-
8
- <Multiselect
9
- :id="id"
10
- ref="select"
11
- v-model="selectValue"
12
- class="mono-select"
13
- :options="options"
14
- :options-limit="optionsLimit"
15
- :label="itemLabel"
16
- :group-label="groupLabel"
17
- :group-values="groupValues"
18
- :track-by="valueKey"
19
- :open-direction="openDirection"
20
- select-label=""
21
- deselect-label=""
22
- selected-label=""
23
- :hide-selected="false"
24
- :disabled="disabled"
25
- :placeholder="placeholder"
26
- :allow-empty="false"
27
- :loading="isLoading"
28
- :searchable="searchable"
29
- :data-cy="dataCy"
30
- :class="hideInactiveElement(modelValue, options)"
31
- :option-height="optionHeight"
32
- @open="onOpen"
33
- @close="onClose"
34
- @searchChange="onSearchChange"
35
- @remove="removeValue"
2
+ <ULabel
3
+ ref="labelComponentRef"
4
+ :for="id"
5
+ :size="size"
6
+ :label="label"
7
+ :error="errorMessage"
8
+ :description="descriptionMessage"
9
+ :align="labelAlign"
10
+ :disabled="disabled"
11
+ :data-cy="dataCy"
12
+ v-bind="labelAttrs"
13
+ >
14
+ <div
15
+ ref="wrapperRef"
16
+ :tabindex="searchable ? -1 : 0"
17
+ role="combobox"
18
+ :aria-owns="'listbox-' + id"
19
+ v-bind="wrapperAttrs"
20
+ @focus="activate"
21
+ @blur="deactivate"
22
+ @keydown.self.down.prevent="dropdownListRef.pointerForward"
23
+ @keydown.self.up.prevent="dropdownListRef.pointerBackward"
24
+ @keydown.enter.tab.stop.self="dropdownListRef.addPointerElement"
25
+ @keyup.esc="deactivate"
26
+ >
27
+ <div
28
+ v-if="hasSlotContent($slots['after-caret']) && !(multiple && localValue.length)"
29
+ v-bind="afterCaretSlotAttrs"
36
30
  >
37
- <template #singleLabel="props">
38
- <!-- @slot Use it to add single label. -->
39
- <slot :scope-props="props" name="singleLabel" />
40
- <span v-if="!isShownSingleLabelSlot" class="mono-select-single-slot">
41
- {{ props.option[itemLabel] }}
42
- </span>
31
+ <!-- @slot Use it to add something after caret. -->
32
+ <slot :scope-props="props" name="after-caret" />
33
+ </div>
43
34
 
44
- <span>
45
- <!-- @slot Use it to add after single label. -->
46
- <slot :scope-props="props" name="singleLabelAfter" />
47
- </span>
48
- </template>
35
+ <div
36
+ v-show="!multiple || (!isLocalValue && multiple)"
37
+ v-bind="caretToggleAttrs"
38
+ @mousedown.prevent.stop="toggle"
39
+ >
40
+ <UIcon
41
+ interactive
42
+ color="gray"
43
+ :size="size"
44
+ :name="config.iconToggleName"
45
+ v-bind="iconToggleAttrs"
46
+ />
47
+ </div>
48
+
49
+ <div
50
+ v-if="hasSlotContent($slots['before-caret']) && !(multiple && localValue.length)"
51
+ v-bind="beforeCaretSlotAttrs"
52
+ >
53
+ <!-- @slot Use it to add something after caret. -->
54
+ <slot :scope-props="props" name="before-caret" />
55
+ </div>
49
56
 
50
- <template #option="props">
51
- <!-- @slot Use it to add option. -->
52
- <slot :scope-props="props" name="option" />
57
+ <div v-if="isLocalValue && !noClear && !disabled && !multiple" v-bind="caretClearAttrs">
58
+ <UIcon
59
+ interactive
60
+ color="gray"
61
+ :size="size"
62
+ :name="config.iconClearName"
63
+ v-bind="iconClearAttrs"
64
+ @mousedown="removeElement"
65
+ />
66
+ </div>
53
67
 
54
- <div v-if="groupValues && !isShownOptionSlot">
55
- <div v-if="props.option.$groupLabel">
56
- {{ props.option.$groupLabel }}
57
- </div>
68
+ <div ref="innerWrapperRef" v-bind="innerWrapperAttrs">
69
+ <div v-if="multiple" v-bind="selectedLabelsAttrs">
70
+ <span v-for="item in localValue" :key="item[valueKey]" v-bind="selectedLabelAttrs">
71
+ <!-- @slot Use it to add selected value label. -->
72
+ <slot
73
+ name="selected-label"
74
+ :selected-label="getOptionLabel(item)"
75
+ :value="item[valueKey]"
76
+ :raw-option="item"
77
+ >
78
+ {{ getOptionLabel(item) }}
79
+ </slot>
80
+
81
+ <!-- @slot Use it to add selected value label. -->
82
+ <slot :scope-props="props" name="selected-label-after" />
58
83
 
59
84
  <div
60
- v-else-if="props.option.isSubGroup"
61
- class="group-label"
62
- :style="leftMarginForSubCategory(props.option.level)"
85
+ v-if="!disabled"
86
+ v-bind="caretRemoveItemAttrs"
87
+ @mousedown.prevent.capture
88
+ @click.prevent.capture
63
89
  >
64
- {{ props.option[itemLabel] }}
90
+ <UIcon
91
+ interactive
92
+ color="gray"
93
+ :size="size"
94
+ :name="config.iconRemoveItemName"
95
+ v-bind="iconRemoveItemAttrs"
96
+ @mousedown="removeElement(item)"
97
+ />
65
98
  </div>
99
+ </span>
100
+ </div>
101
+
102
+ <div v-bind="searchAttrs">
103
+ <span
104
+ v-if="hasSlotContent($slots['left'])"
105
+ ref="leftSlotWrapperRef"
106
+ v-bind="leftSlotAttrs"
107
+ >
108
+ <!-- @slot Use it to add some component before text. -->
109
+ <slot name="left" />
110
+ </span>
66
111
 
67
- <div v-else :style="leftMarginForSubCategory(props.option.level)" class="select-label">
68
- <!-- @slot Use it to add something before option. -->
69
- <slot :option="props.option" name="beforeOption"></slot>
70
- {{ props.option[itemLabel] }}
71
- </div>
72
- </div>
73
- <div v-else class="select-label">
74
- <!-- @slot Use it to add something before option. -->
75
- <slot :option="props.option" name="beforeOption"></slot>
76
- {{ props.option[itemLabel] }}
77
- </div>
78
- </template>
112
+ <input
113
+ v-show="searchable || !localValue || multiple || !isOpen"
114
+ :id="id"
115
+ ref="searchInputRef"
116
+ v-model="search"
117
+ :name="name"
118
+ type="text"
119
+ autocomplete="off"
120
+ :spellcheck="false"
121
+ :placeholder="inputPlaceholder"
122
+ :value="search"
123
+ :disabled="disabled"
124
+ :aria-controls="'listbox-' + id"
125
+ v-bind="searchInputAttrs"
126
+ @focus="activate"
127
+ @blur.prevent="deactivate"
128
+ @keyup.esc="deactivate"
129
+ @keydown.down.prevent="dropdownListRef.pointerForward"
130
+ @keydown.up.prevent="dropdownListRef.pointerBackward"
131
+ @keydown.enter.prevent.stop.self="dropdownListRef.addPointerElement"
132
+ />
133
+ </div>
134
+
135
+ <span
136
+ v-if="isSelectedValueLabelVisible"
137
+ v-bind="selectedLabelAttrs"
138
+ @mousedown.prevent="toggle"
139
+ >
140
+ <!-- @slot Use it to add selected value label. -->
141
+ <slot name="selected-label" :selected-label="selectedLabel" :value="localValue[valueKey]">
142
+ {{ selectedLabel }}
143
+ </slot>
144
+
145
+ <!-- @slot Use it to add selected value label. -->
146
+ <slot :scope-props="props" name="selected-label-after" />
147
+ </span>
148
+
149
+ <div
150
+ v-if="isLocalValue && !noClear && !disabled && multiple"
151
+ v-bind="caretClearTextAttrs"
152
+ @mousedown.prevent.capture="removeElement(localValue)"
153
+ @click.prevent.capture
154
+ v-text="i18n.clear"
155
+ />
156
+ </div>
79
157
 
80
- <template #noResult>
81
- {{ i18n.listIsEmpty }}
158
+ <UDropdownList
159
+ v-show="isOpen"
160
+ ref="dropdownListRef"
161
+ v-model="dropdownValue"
162
+ :options="filteredOptions"
163
+ :disabled
164
+ :size
165
+ :max-height="optimizedHeight"
166
+ :option-height="optionHeight"
167
+ :value-key
168
+ :label-key
169
+ :add-option
170
+ tabindex="-1"
171
+ v-bind="dropdownListAttrs"
172
+ @focus="activate"
173
+ @addOption="onAddOption"
174
+ @mousedown.prevent.capture
175
+ @click.prevent.capture
176
+ >
177
+ <template #before-option="{ option }">
178
+ <!-- @slot Use it to add something before option. -->
179
+ <slot :option="option" name="before-option" />
82
180
  </template>
83
181
 
84
- <template #noOptions>
85
- {{ i18n.noDataToShow }}
182
+ <template #option="{ option, index }">
183
+ <slot name="option" :option="option" :index="index" />
86
184
  </template>
87
185
 
88
- <template #caret="{ toggle }">
89
- <div class="mono-select-caret-down" @mousedown.prevent.stop="toggle">
90
- <UIcon
91
- interactive
92
- :size="iconSize"
93
- color="gray"
94
- name="expand_more"
95
- class="icon"
96
- :data-cy="`${dataCy}-caret`"
97
- />
98
- </div>
99
-
100
- <div v-if="selectValue && allowEmpty && !disabled" class="mono-select-caret-close">
101
- <UIcon
102
- interactive
103
- :size="iconSize"
104
- color="gray"
105
- name="close"
106
- :data-cy="`${dataCy}-close`"
107
- @mousedown="[onMousedownRemoveValue(), toggle()]"
108
- />
109
- </div>
186
+ <template #after-option="{ option }">
187
+ <!-- @slot Use it to add something after option. -->
188
+ <slot :option="option" name="after-option" />
110
189
  </template>
111
190
 
112
- <template #afterList>
113
- <div v-if="addOption" class="mono-select-add-wrapper" @click="onClickAddOption">
114
- <div class="mono-select-add-title">
115
- {{ i18n.add }}
116
- <span class="mono-select-add-title-command">{{ addOptionKeyCombination }}</span>
117
- </div>
118
-
119
- <UButton ref="addOptionButton" class="mono-select-add-button">
120
- <UIcon name="add" class="mono-select-add-icon" color="white" pill size="2xs" />
121
- </UButton>
122
- </div>
191
+ <template #empty="{ emptyStyles }">
192
+ <span v-show="isEmpty" :class="emptyStyles" v-text="i18n.listIsEmpty" />
193
+ <span
194
+ v-show="options.length === 0 && !search && !isEmpty"
195
+ :class="emptyStyles"
196
+ v-text="i18n.noDataToShow"
197
+ />
123
198
  </template>
124
- </Multiselect>
125
-
126
- <div v-if="isShownAfterCaretSlot" class="after-caret-slot">
127
- <!-- @slot Use it to add something after caret. -->
128
- <slot name="after-caret" />
129
- </div>
199
+ </UDropdownList>
130
200
  </div>
131
-
132
- <div v-if="description && !error" class="description">
133
- {{ description }}
134
- </div>
135
-
136
- <p
137
- v-if="error && !modelValue.length"
138
- class="error-message"
139
- :data-cy="`${dataCy}-error-message`"
140
- >
141
- {{ error }}
142
- </p>
143
- </div>
201
+ </ULabel>
144
202
  </template>
145
203
 
146
- <script>
147
- import Multiselect from "vue-multiselect";
148
- import { getRandomId, isMac, PX_IN_REM } from "vueless/service.ui";
149
- import I18nServiceDefault from "vueless/service.i18n";
204
+ <script setup>
205
+ import { ref, computed, nextTick, watch, useSlots, onMounted } from "vue";
150
206
  import debounce from "lodash.debounce";
151
207
 
152
- import UButton from "vueless/ui.button";
153
- import UIcon from "vueless/ui.image-icon";
208
+ import UIService, { getRandomId, isMac } from "vueless/service.ui";
209
+ import I18nServiceDefault from "@vueless/services/i18n";
154
210
 
155
- export default {
156
- name: "USelect",
157
- components: {
158
- Multiselect,
159
- UButton,
160
- UIcon,
161
- },
211
+ import SelectService from "./services/select.service";
212
+ import useAttrs from "./composables/attrs.composable";
213
+ import defaultConfig from "./configs/default.config";
214
+ import { USelect, DIRECTION, KEY_CODES } from "./constants";
162
215
 
163
- props: {
164
- /**
165
- * Set input select value.
166
- */
167
- modelValue: {
168
- type: [String, Number],
169
- default: "",
170
- },
171
-
172
- /**
173
- * Set options for component.
174
- */
175
- options: {
176
- type: Array,
177
- default: () => [],
178
- },
179
-
180
- /**
181
- * Set component label.
182
- */
183
- label: {
184
- type: String,
185
- default: "",
186
- },
187
-
188
- /**
189
- * Label from option Object, that will be visible in the dropdown.
190
- */
191
- itemLabel: {
192
- type: String,
193
- default: "label",
194
- },
195
-
196
- /**
197
- * Set input placeholder.
198
- */
199
- placeholder: {
200
- type: String,
201
- default: "",
202
- },
203
-
204
- /**
205
- * Set error message.
206
- */
207
- error: {
208
- type: String,
209
- default: "",
210
- },
211
-
212
- /**
213
- * Make input inactive.
214
- */
215
- disabled: {
216
- type: Boolean,
217
- default: false,
218
- },
219
-
220
- /**
221
- * Allows clear selected value.
222
- */
223
- allowEmpty: {
224
- type: Boolean,
225
- default: true,
226
- },
227
-
228
- /**
229
- * Set a name of the property containing the group label.
230
- */
231
- groupLabel: {
232
- type: String,
233
- default: "label",
234
- },
235
-
236
- /**
237
- * Set a name of the property containing the group values.
238
- */
239
- groupValues: {
240
- type: String,
241
- default: "",
242
- },
243
-
244
- /**
245
- * Set limits the options displayed in the dropdown to the first X options.
246
- */
247
- optionsLimit: {
248
- type: Number,
249
- default: 100,
250
- },
251
-
252
- /**
253
- * Set track value key.
254
- */
255
- valueKey: {
256
- type: String,
257
- default: "id",
258
- },
259
-
260
- /**
261
- * Fixed opening direction (instead of auto). Options are "above"/"top" or "below"/"bottom".
262
- * @values auto, top, bottom
263
- */
264
- openDirection: {
265
- type: String,
266
- default: "auto",
267
- },
268
-
269
- /**
270
- * Set description for input.
271
- */
272
- description: {
273
- type: String,
274
- default: "",
275
- },
276
-
277
- /**
278
- * Show add new option button to the list.
279
- */
280
- addOption: {
281
- type: Boolean,
282
- default: false,
283
- },
284
-
285
- /**
286
- * Set input size.
287
- * @values sm, md, lg
288
- */
289
- size: {
290
- type: String,
291
- default: "md",
292
- },
293
-
294
- /**
295
- * Allow search value in list.
296
- */
297
- searchable: {
298
- type: Boolean,
299
- default: true,
300
- },
301
-
302
- /**
303
- * Generates unique element id.
304
- * @ignore
305
- */
306
- id: {
307
- type: String,
308
- default: () => getRandomId(),
309
- },
310
-
311
- /**
312
- * Sets data-cy attribute for automated testing.
313
- */
314
- dataCy: {
315
- type: String,
316
- default: "",
317
- },
318
- },
216
+ /* Should be a string for correct web-types gen */
217
+ defineOptions({ name: "USelect", inheritAttrs: false });
319
218
 
320
- emits: ["update:modelValue", "open", "addOption", "close", "change", "remove", "searchChange"],
321
-
322
- setup() {
323
- const { getTranslation } = new I18nServiceDefault();
324
-
325
- return { getTranslation };
219
+ const props = defineProps({
220
+ /**
221
+ * Select value.
222
+ */
223
+ modelValue: {
224
+ type: [String, Number, Array],
225
+ default: "",
326
226
  },
327
227
 
328
- data: () => ({
329
- isLoading: false,
330
- isOpen: null,
331
- isFocused: false,
332
- optionHeight: 0,
333
- }),
334
-
335
- computed: {
336
- wrapperId() {
337
- return `wrapper${this.id}`;
338
- },
339
-
340
- multiselectClass() {
341
- return {
342
- error: this.error && !this.modelValue.length,
343
- "mono-select-wrapper-disabled": this.disabled,
344
- "group-select": this.groupValues,
345
- "after-caret": this.isShownAfterCaretSlot,
346
- "size-sm": this.size === "sm",
347
- "size-md": this.size === "md",
348
- "size-lg": this.size === "lg",
349
- };
350
- },
351
-
352
- addOptionKeyCombination() {
353
- return isMac ? "(⌘ + Enter)" : "(Ctrl + Enter)";
354
- },
355
-
356
- isShownAfterCaretSlot() {
357
- return !!this.$slots["after-caret"];
358
- },
359
-
360
- isShownOptionSlot() {
361
- return !!this.$slots["option"];
362
- },
363
-
364
- isShownSingleLabelSlot() {
365
- return !!this.$slots["singleLabel"];
366
- },
367
-
368
- isShownSingleLabelAfterSlot() {
369
- return !!this.$slots["singleLabelAfter"];
370
- },
371
-
372
- labelClasses() {
373
- return {
374
- "label-color": this.isOpen,
375
- "error-label": this.error && !this.modelValue.length,
376
- };
377
- },
378
-
379
- i18n() {
380
- return {
381
- listIsEmpty: this.getTranslation("listIsEmpty"),
382
- noDataToShow: this.getTranslation("noDataToShow"),
383
- add: this.getTranslation("add"),
384
- };
385
- },
386
-
387
- selectValue: {
388
- get() {
389
- if (this.groupValues) {
390
- const option = this.options.find((option) => {
391
- return option[this.groupValues]?.find(
392
- (item) => item[this.valueKey] === this.modelValue,
393
- );
394
- });
395
-
396
- return option?.[this.groupValues].find((option) => option.id === this.modelValue);
397
- }
398
-
399
- return this.options.find((option) => option[this.valueKey] === this.modelValue);
400
- },
401
- set(newItem) {
402
- this.$emit("update:modelValue", newItem?.[this.valueKey]);
403
- },
404
- },
405
-
406
- multiselectContentWrapper() {
407
- return document.querySelector(`#${this.wrapperId} .multiselect__content-wrapper`);
408
- },
409
-
410
- iconSize() {
411
- const sizes = {
412
- sm: "sm",
413
- md: "md",
414
- lg: "lg",
415
- };
416
-
417
- return sizes[this.size];
418
- },
228
+ /**
229
+ * Select options.
230
+ */
231
+ options: {
232
+ type: Array,
233
+ default: () => [],
419
234
  },
420
235
 
421
- watch: {
422
- options: {
423
- handler: "onChangeOptions",
424
- deep: true,
425
- },
426
-
427
- isOpen: {
428
- handler: "onChangeOpenState",
429
- deep: true,
430
- },
431
-
432
- selectValue: {
433
- handler: "onChangeSelectValue",
434
- deep: true,
435
- },
236
+ /**
237
+ * Select label.
238
+ */
239
+ label: {
240
+ type: String,
241
+ default: "",
436
242
  },
437
243
 
438
- created() {
439
- if (this.addOption) {
440
- document.addEventListener("keydown", this.onKeydownAddOption);
441
- }
244
+ /**
245
+ * Show label outside the select block.
246
+ */
247
+ labelOutside: {
248
+ type: Boolean,
249
+ default: UIService.get(defaultConfig, USelect).default.labelOutside,
442
250
  },
443
251
 
444
- mounted() {
445
- if (this.addOption) {
446
- this.multiselectContentWrapper.addEventListener("scroll", this.setAddOptionButtonPosition, {
447
- passive: true,
448
- });
449
- }
252
+ /**
253
+ * Select placeholder.
254
+ */
255
+ placeholder: {
256
+ type: String,
257
+ default: "",
450
258
  },
451
259
 
452
- beforeUnmount() {
453
- if (this.addOption) {
454
- document.removeEventListener("keydown", this.onKeydownAddOption);
455
-
456
- this.multiselectContentWrapper.removeEventListener("scroll", this.setAddOptionButtonPosition);
457
- }
260
+ /**
261
+ * Select description.
262
+ */
263
+ description: {
264
+ type: String,
265
+ default: "",
458
266
  },
459
267
 
460
- methods: {
461
- setAddOptionButtonPosition() {
462
- const scrollBottomPosition = -this.multiselectContentWrapper.scrollTop;
463
- const defaultButtonPosition = 9;
464
- const addOptionPosition = (scrollBottomPosition + defaultButtonPosition) / PX_IN_REM;
465
-
466
- this.$refs.addOptionButton.$el.style.bottom = `${addOptionPosition}rem`;
467
- },
468
-
469
- onOpen() {
470
- this.$emit("open");
471
- this.isOpen = true;
472
- this.isFocused = true;
473
- },
474
-
475
- onMousedownRemoveValue() {
476
- this.selectValue = "";
477
- },
478
-
479
- onKeydownAddOption(event) {
480
- if (!this.isFocused) return;
481
-
482
- const isEnter = event.keyCode === 13;
483
- const isCtrl = event.ctrlKey;
484
- const isMeta = event.metaKey;
485
-
486
- if (isMeta && isEnter && isMac) {
487
- this.$emit("addOption");
488
- }
489
-
490
- if (isEnter && isCtrl && !isMac) {
491
- this.$emit("addOption");
492
- }
493
- },
494
-
495
- onClickAddOption() {
496
- this.$emit("addOption");
497
- },
498
-
499
- onChangeOptions() {
500
- const subOptions = document.querySelectorAll(".group-label");
501
-
502
- subOptions.forEach((subOption) => {
503
- const subOptionsParent = subOption.parentElement.parentElement;
268
+ /**
269
+ * Select error message.
270
+ */
271
+ error: {
272
+ type: String,
273
+ default: "",
274
+ },
504
275
 
505
- subOptionsParent.classList.add("multiselect__option", "multiselect__option--disabled");
506
- });
507
- },
276
+ /**
277
+ * Select size.
278
+ * @values sm, md, lg
279
+ */
280
+ size: {
281
+ type: String,
282
+ default: UIService.get(defaultConfig, USelect).default.size,
283
+ },
508
284
 
509
- onClose() {
510
- this.isOpen = false;
285
+ /**
286
+ * Select open direction.
287
+ * @values auto, top, bottom
288
+ */
289
+ openDirection: {
290
+ type: String,
291
+ default: UIService.get(defaultConfig, USelect).default.openDirection,
292
+ },
511
293
 
512
- setTimeout(() => {
513
- this.isFocused = false;
514
- }, 100);
294
+ /**
295
+ * Label key in the item object of options.
296
+ */
297
+ labelKey: {
298
+ type: String,
299
+ default: UIService.get(defaultConfig, USelect).default.labelKey,
300
+ },
515
301
 
516
- this.$emit("close");
517
- },
302
+ /**
303
+ * Value key in the item object of options.
304
+ */
305
+ valueKey: {
306
+ type: String,
307
+ default: UIService.get(defaultConfig, USelect).default.valueKey,
308
+ },
518
309
 
519
- onChangeSelectValue() {
520
- this.$emit("change");
521
- },
310
+ /**
311
+ * Set a name of the property containing the group label.
312
+ */
313
+ // TODO: groupLabelKey ???
314
+ groupLabel: {
315
+ type: String,
316
+ default: "label",
317
+ },
522
318
 
523
- leftMarginForSubCategory(level) {
524
- const baseMargin = 1;
319
+ /**
320
+ * Set a name of the property containing the group values.
321
+ */
322
+ // TODO: groupValueKey ???
323
+ groupValues: {
324
+ type: String,
325
+ default: "",
326
+ },
525
327
 
526
- if (level > 1) {
527
- return `margin-left: ${baseMargin * (level - 1)}rem`;
528
- }
529
- },
328
+ /**
329
+ * name attribute to match optional label element.
330
+ */
331
+ // TODO: what is it?
332
+ name: {
333
+ type: String,
334
+ default: "",
335
+ },
530
336
 
531
- removeValue(itemToRemove) {
532
- this.$emit("remove", itemToRemove);
533
- },
337
+ /**
338
+ * Number of options displayed in the dropdown.
339
+ */
340
+ optionsLimit: {
341
+ type: Number,
342
+ default: UIService.get(defaultConfig, USelect).default.optionsLimit,
343
+ },
534
344
 
535
- onSearchChange: debounce(async function (query) {
536
- this.$emit("searchChange", query);
537
- }, 300),
345
+ /**
346
+ * Sets maxHeight style value of the dropdown
347
+ */
348
+ // TODO: Should be in option amount not in pixels (option may have be different height)
349
+ maxHeight: {
350
+ type: Number,
351
+ default: UIService.get(defaultConfig, USelect).default.maxHeight,
352
+ },
538
353
 
539
- onChangeOpenState() {
540
- this.onChangeOptions();
354
+ // TODO: there is no desc
355
+ optionHeight: {
356
+ type: Number,
357
+ default: UIService.get(defaultConfig, USelect).default.optionHeight,
358
+ },
541
359
 
542
- this.$nextTick(() => {
543
- this.optionHeight = this.$refs.select
544
- ? this.$refs.select.$refs.list.firstChild.firstElementChild.clientHeight
545
- : this.optionHeight;
546
- });
547
- },
360
+ /**
361
+ * Allow clearing selected value.
362
+ */
363
+ noClear: {
364
+ type: Boolean,
365
+ default: UIService.get(defaultConfig, USelect).default.noClear,
366
+ },
548
367
 
549
- hideInactiveElement(id) {
550
- let selectedId = {};
368
+ /**
369
+ * Allows multiple selection.
370
+ */
371
+ multiple: {
372
+ type: Boolean,
373
+ default: UIService.get(defaultConfig, USelect).default.multiple,
374
+ },
551
375
 
552
- if (this.groupValues !== "") {
553
- this.options.forEach((option) => {
554
- option[this.groupValues].forEach((item) => {
555
- if (item.id === id) selectedId = item;
556
- });
557
- });
558
- } else {
559
- selectedId = this.options.find((item) => item.id === id);
560
- }
561
-
562
- if (!selectedId) return;
376
+ /**
377
+ * Allows to search value in a list.
378
+ */
379
+ searchable: {
380
+ type: Boolean,
381
+ default: UIService.get(defaultConfig, USelect).default.searchable,
382
+ },
563
383
 
564
- return selectedId.isHidden ? "cross-out-option" : "";
565
- },
384
+ /**
385
+ * Disable the select.
386
+ */
387
+ disabled: {
388
+ type: Boolean,
389
+ default: UIService.get(defaultConfig, USelect).default.disabled,
566
390
  },
567
- };
568
- </script>
569
391
 
570
- <i18n>
571
- en:
572
- listIsEmpty: "List is empty."
573
- noDataToShow: "No data to show."
574
- add: Add
575
- ru:
576
- listIsEmpty: "Список пуст."
577
- noDataToShow: "Нет данных."
578
- add: Добавить
579
- ua:
580
- listIsEmpty: "Список порожній."
581
- noDataToShow: "Дані відсутні."
582
- add: Додати
583
- </i18n>
392
+ /**
393
+ * Show "Add new option" button in the list.
394
+ */
395
+ addOption: {
396
+ type: Boolean,
397
+ default: UIService.get(defaultConfig, USelect).default.addOption,
398
+ },
584
399
 
585
- <style lang="postcss" scoped>
586
- .mono-select-block {
587
- @apply min-w-0;
588
- @apply relative;
589
- }
400
+ /**
401
+ * Generates unique element id.
402
+ * @ignore
403
+ */
404
+ id: {
405
+ type: String,
406
+ default: () => getRandomId(),
407
+ },
590
408
 
591
- .mono-select-wrapper {
592
- @apply flex w-full items-center;
593
- @apply box-border rounded-lg border border-gray-300 bg-white;
409
+ /**
410
+ * Component ui config object.
411
+ */
412
+ config: {
413
+ type: Object,
414
+ default: () => ({}),
415
+ },
594
416
 
595
- &:hover {
596
- @apply border-gray-400;
597
- @apply transition duration-100 ease-in-out;
598
- }
417
+ /**
418
+ * Data-cy attribute for automated testing.
419
+ */
420
+ dataCy: {
421
+ type: String,
422
+ default: "",
423
+ },
424
+ });
425
+
426
+ const emit = defineEmits([
427
+ "open",
428
+ "close",
429
+ "searchChange",
430
+ "remove",
431
+ "update:modelValue",
432
+ "select",
433
+ "addOption",
434
+ "change",
435
+ ]);
436
+
437
+ const slots = useSlots();
438
+
439
+ const { getTranslation } = new I18nServiceDefault();
440
+
441
+ const isOpen = ref(false);
442
+ const preferredOpenDirection = ref(DIRECTION.bottom);
443
+ const search = ref("");
444
+ const optimizedHeight = ref(props.maxHeight);
445
+
446
+ const dropdownListRef = ref(null);
447
+ const wrapperRef = ref(null);
448
+ const searchInputRef = ref(null);
449
+ const labelComponentRef = ref(null);
450
+ const leftSlotWrapperRef = ref(null);
451
+ const innerWrapperRef = ref(null);
452
+
453
+ const i18n = computed(() => {
454
+ return {
455
+ clear: getTranslation("clear"),
456
+ listIsEmpty: getTranslation("listIsEmpty"),
457
+ noDataToShow: getTranslation("noDataToShow"),
458
+ addMore: getTranslation("addMore"),
459
+ add: getTranslation("add"),
460
+ };
461
+ });
462
+
463
+ const inputPlaceholder = computed(() => {
464
+ return props.multiple && localValue.value.length ? i18n.value.addMore : props.placeholder;
465
+ });
466
+
467
+ const dropdownValue = computed({
468
+ get: () => props.modelValue,
469
+ set: (newValue) => {
470
+ let value = newValue;
471
+
472
+ if (props.multiple) {
473
+ value = Array.isArray(props.modelValue) ? [...props.modelValue, newValue] : [newValue];
474
+ }
599
475
 
600
- &:focus-within {
601
- @apply border-gray-500 ring-4 ring-gray-600 ring-opacity-15;
476
+ emit("update:modelValue", value);
477
+ deactivate();
478
+ },
479
+ });
480
+
481
+ const isSelectedValueLabelVisible = computed(() => {
482
+ return !props.multiple && isLocalValue.value && (!isOpen.value || !props.searchable);
483
+ });
484
+
485
+ const selectedLabel = computed(() => {
486
+ return isLocalValue.value ? getOptionLabel(localValue.value) : "";
487
+ });
488
+
489
+ const labelAlign = computed(() => {
490
+ return props.labelOutside ? "top" : "topInside";
491
+ });
492
+
493
+ const isTop = computed(() => {
494
+ if (props.openDirection === DIRECTION.top) return true;
495
+ if (props.openDirection === DIRECTION.bottom) return false;
496
+
497
+ return preferredOpenDirection.value === DIRECTION.top;
498
+ });
499
+
500
+ const filteredOptions = computed(() => {
501
+ const normalizedSearch = search.value.toLowerCase().trim();
502
+
503
+ let options = props.multiple
504
+ ? SelectService.removeSelectedValues(
505
+ props.options,
506
+ props.groupValues,
507
+ props.valueKey,
508
+ props.modelValue,
509
+ )
510
+ : [...props.options];
511
+
512
+ options = props.groupValues
513
+ ? filterAndFlat(options, normalizedSearch, props.labelKey)
514
+ : SelectService.filterOptions(options, normalizedSearch, props.labelKey);
515
+
516
+ return options.slice(0, props.optionsLimit);
517
+ });
518
+
519
+ const localValue = computed(() => {
520
+ if (!props.multiple) {
521
+ return SelectService.getCurrentOption(
522
+ props.modelValue,
523
+ props.options,
524
+ props.groupValues,
525
+ props.valueKey,
526
+ );
602
527
  }
603
528
 
604
- .mono-select {
605
- @apply flex flex-row-reverse justify-between;
606
- @apply static min-h-full w-full overflow-hidden text-left;
607
-
608
- &-caret-down,
609
- &-caret-close {
610
- @apply -mt-1.5 mr-4;
611
- @apply cursor-pointer;
612
- }
613
-
614
- &-caret-down {
615
- @apply scale-125 h-fit;
616
- }
529
+ return props.modelValue
530
+ ? props.modelValue.map((item) =>
531
+ SelectService.getCurrentOption(item, props.options, props.groupValues, props.valueKey),
532
+ )
533
+ : [];
534
+ });
535
+
536
+ const isEmpty = computed(() => {
537
+ return (
538
+ (filteredOptions.value.length === 0 && search) ||
539
+ (props.multiple && localValue.value.length === props.options.length)
540
+ );
541
+ });
542
+
543
+ const isLocalValue = computed(() => {
544
+ if (props.multiple) return Boolean(localValue.value.length);
545
+
546
+ return typeof localValue.value !== "number"
547
+ ? Boolean(localValue.value)
548
+ : Boolean(String(localValue.value));
549
+ });
550
+
551
+ const errorMessage = computed(() => {
552
+ return !isOpen.value && props.error ? props.error : "";
553
+ });
554
+
555
+ const descriptionMessage = computed(() => {
556
+ return !isOpen.value && props.description ? props.description : "";
557
+ });
558
+
559
+ watch(search, () => onSearchChange);
560
+ watch(
561
+ localValue,
562
+ () => {
563
+ setLabelPosition();
564
+ emit("change");
565
+ },
566
+ { deep: true },
567
+ );
617
568
 
618
- &-caret-close {
619
- @apply mr-1;
620
- }
569
+ if (props.addOption) {
570
+ document.addEventListener("keydown", onKeydownAddOption);
571
+ }
621
572
 
622
- &--active {
623
- @apply z-[inherit];
573
+ onMounted(() => setLabelPosition());
624
574
 
625
- .icon {
626
- @apply rotate-180 transform transition-all duration-300;
627
- }
628
- }
575
+ const onSearchChange = debounce(async function (query) {
576
+ emit("searchChange", query);
577
+ }, 300);
629
578
 
630
- &.multiselect--above {
631
- &:deep(.multiselect__content-wrapper) {
632
- @apply bottom-full top-auto;
633
- }
634
- }
579
+ function getOptionLabel(option) {
580
+ if (!option) return "";
581
+ if (option.$isLabel) return option.$groupLabel;
635
582
 
636
- :deep(.multiselect) {
637
- &__tags {
638
- @apply rounded-none border-0 bg-transparent;
639
- @apply min-h-full w-full overflow-hidden;
640
- }
641
-
642
- &__input {
643
- @apply font-normal text-gray-900;
644
- @apply p-0;
645
- @apply relative inline-block min-h-full w-full align-top;
646
- @apply border-none bg-white;
647
-
648
- &:focus {
649
- @apply shadow-none outline-none ring-0;
650
- }
651
-
652
- &::placeholder {
653
- @apply font-normal text-gray-400;
654
- }
655
- }
656
-
657
- &__placeholder {
658
- @apply inline-block;
659
- @apply whitespace-nowrap font-normal text-gray-400;
660
- @apply mb-0 w-0 pt-px;
661
- }
662
-
663
- &__content-wrapper {
664
- @apply rounded-lg border border-gray-300 shadow;
665
- @apply mb-2 mt-[2.625rem];
666
- @apply absolute right-0;
667
- @apply z-50 flex max-h-60 w-full overflow-auto;
668
- @apply bg-white;
669
- -webkit-overflow-scrolling: touch;
670
- }
671
-
672
- &__content {
673
- @apply inline-block list-none align-top;
674
- @apply m-0 min-w-full p-0;
675
-
676
- .multiselect__element:first-child {
677
- .multiselect__option--group {
678
- @apply !mt-4;
679
- }
680
- }
681
- }
682
-
683
- &__element {
684
- @apply block;
685
- }
686
-
687
- &__option {
688
- @apply whitespace-nowrap text-base font-normal normal-case text-gray-900 no-underline;
689
- @apply relative block cursor-pointer align-middle;
690
- @apply px-3 py-2;
691
-
692
- &:hover {
693
- @apply bg-gray-100;
694
- }
695
-
696
- &:active,
697
- &--selected {
698
- @apply !bg-gray-200 font-medium;
699
- }
700
-
701
- &:disabled {
702
- @apply text-gray-900;
703
- }
704
-
705
- &--highlight {
706
- @apply bg-gray-100;
707
- }
708
-
709
- &--disabled {
710
- @apply pointer-events-none;
711
- }
712
-
713
- &--group {
714
- @apply bg-transparent;
715
- @apply !text-xs font-medium uppercase text-gray-500/[85];
716
- @apply pb-1 pt-6;
717
- }
718
- }
719
-
720
- &__single {
721
- @apply font-normal text-gray-900;
722
- @apply mb-px p-0;
723
- @apply relative inline-block w-full align-top;
724
- @apply border-none bg-white;
725
- @apply overflow-hidden text-ellipsis whitespace-nowrap;
726
- }
727
- }
728
- }
583
+ return option[props.labelKey] || "";
729
584
  }
730
585
 
731
- .mono-select-wrapper-disabled {
732
- @apply border-gray-100 bg-gray-100 text-gray-900;
586
+ function onKeydownAddOption(event) {
587
+ if (!isOpen.value) return;
733
588
 
734
- &:hover {
735
- @apply border-gray-100;
736
- }
589
+ const isEnter = event.keyCode === KEY_CODES.enter;
590
+ const isCtrl = event.ctrlKey;
591
+ const isMeta = event.metaKey;
737
592
 
738
- &:focus-within {
739
- @apply border-gray-100 ring-0;
593
+ if (isMeta && isEnter && isMac) {
594
+ emit("addOption");
740
595
  }
741
596
 
742
- &:deep(.multiselect--disabled) {
743
- @apply rounded-lg bg-transparent;
744
- @apply pointer-events-none opacity-100;
745
-
746
- .multiselect__single {
747
- @apply bg-gray-100;
748
- }
597
+ if (isEnter && isCtrl && !isMac) {
598
+ emit("addOption");
749
599
  }
750
600
  }
751
601
 
752
- .icon {
753
- @apply transition-all duration-300;
602
+ function onAddOption() {
603
+ emit("addOption");
754
604
  }
755
605
 
756
- .label {
757
- @apply absolute left-4 block;
758
- @apply font-normal text-gray-500;
759
- @apply z-10;
760
- @apply w-3/5 overflow-hidden text-ellipsis whitespace-nowrap;
761
-
762
- &-color {
763
- @apply font-normal text-gray-500;
764
- z-index: 9999;
765
- }
766
- }
606
+ function filterAndFlat(options, search, label) {
607
+ const filteredGroups = SelectService.filterGroups(
608
+ options,
609
+ search,
610
+ label,
611
+ props.groupValues,
612
+ props.groupLabel,
613
+ );
767
614
 
768
- .select-label {
769
- @apply flex;
615
+ return SelectService.flattenOptions(filteredGroups, props.groupValues, props.groupLabel);
770
616
  }
771
617
 
772
- .group-label {
773
- @apply bg-transparent;
774
- @apply !text-xs font-medium uppercase text-gray-500/[85] pt-1;
618
+ function toggle() {
619
+ isOpen.value ? deactivate() : activate();
775
620
  }
776
621
 
777
- .size {
778
- &-sm {
779
- .group-label {
780
- @apply !text-2xs;
781
- }
622
+ function deactivate() {
623
+ if (!isOpen.value) return;
782
624
 
783
- > .mono-select {
784
- @apply pt-5;
785
-
786
- :deep(.multiselect__option) {
787
- @apply py-2;
788
- }
789
-
790
- :deep(.multiselect) {
791
- &__tags {
792
- @apply mb-px pb-1.5 pl-4 pr-4 pt-1;
793
- }
794
-
795
- &__content-wrapper {
796
- @apply mt-[2.375rem];
797
- }
798
-
799
- &__content {
800
- .multiselect__element {
801
- .multiselect__option--group {
802
- @apply !text-2xs;
803
- @apply pb-1 mt-4;
804
- }
805
- }
806
- }
807
-
808
- &__input {
809
- @apply mb-0 pt-0.5 text-sm;
810
-
811
- &::placeholder {
812
- @apply text-sm font-normal;
813
- @apply pt-0;
814
- }
815
- }
816
-
817
- &__single {
818
- @apply mt-1 text-sm;
819
- }
820
-
821
- &__placeholder {
822
- @apply text-sm min-h-[0.875rem];
823
- }
824
-
825
- &__option {
826
- @apply text-sm;
827
- }
828
- }
829
- }
625
+ props.searchable && searchInputRef.value ? searchInputRef.value.blur() : wrapperRef.value?.blur();
830
626
 
831
- > .label {
832
- @apply top-2 text-xs;
627
+ search.value = "";
628
+ isOpen.value = false;
833
629
 
834
- &-color {
835
- @apply text-xs;
836
- }
837
- }
838
- }
839
-
840
- &-md {
841
- > .mono-select {
842
- @apply pt-6;
843
-
844
- :deep(.multiselect) {
845
- &__tags {
846
- @apply mb-px pb-2 pl-4 pr-4 pt-1;
847
- }
630
+ nextTick(() => emit("close", localValue.value, props.id));
631
+ }
848
632
 
849
- &__input {
850
- @apply mb-px text-base;
633
+ function activate() {
634
+ if (props.isOpen || props.disabled) return;
851
635
 
852
- &::placeholder {
853
- @apply text-base font-normal;
854
- @apply pt-px;
855
- }
856
- }
636
+ adjustPosition();
857
637
 
858
- &__single {
859
- @apply text-base;
860
- }
638
+ isOpen.value = true;
861
639
 
862
- &__placeholder {
863
- @apply text-base min-h-[1rem];
864
- }
865
- }
866
- }
640
+ if (props.searchable) {
641
+ search.value = "";
867
642
 
868
- > .label {
869
- @apply top-2.5 text-sm;
870
-
871
- &-color {
872
- @apply text-sm;
873
- }
874
- }
643
+ nextTick(() => searchInputRef.value && searchInputRef.value.focus());
875
644
  }
876
645
 
877
- &-lg {
878
- .group-label {
879
- @apply !text-sm;
880
- }
646
+ if (wrapperRef.value !== undefined && !props.searchable) wrapperRef.value.focus();
881
647
 
882
- > .mono-select {
883
- @apply pt-7;
884
-
885
- :deep(.multiselect) {
886
- &__tags {
887
- @apply mb-px pb-2.5 pl-4 pr-4 pt-1;
888
- }
889
-
890
- &__content-wrapper {
891
- @apply mt-[2.875rem];
892
- }
893
-
894
- &__content {
895
- .multiselect__element {
896
- .multiselect__option--group {
897
- @apply !text-sm;
898
- @apply pb-1 mt-4;
899
- }
900
- }
901
- }
902
-
903
- .multiselect__option {
904
- @apply py-4;
905
- }
906
-
907
- &__input {
908
- @apply mb-0 pt-0.5 text-lg;
909
-
910
- &::placeholder {
911
- @apply text-lg font-normal;
912
- @apply pt-0;
913
- }
914
- }
915
-
916
- &__single {
917
- @apply mt-1 text-lg;
918
- }
919
-
920
- &__placeholder {
921
- @apply text-lg min-h-[1.125rem];
922
- }
923
-
924
- &__option {
925
- @apply text-lg;
926
- }
927
- }
928
- }
929
-
930
- > .label {
931
- @apply top-3 text-base;
932
-
933
- &-color {
934
- @apply text-base;
935
- }
936
- }
937
- }
938
- }
939
-
940
- .icon {
941
- @apply transition-all duration-300;
648
+ emit("open", props.id);
942
649
  }
943
650
 
944
- .error {
945
- @apply border-red-300;
651
+ function adjustPosition() {
652
+ if (typeof window === "undefined") return;
946
653
 
947
- &:hover {
948
- @apply border-red-400;
949
- }
654
+ const spaceAbove = wrapperRef.value.getBoundingClientRect().top;
655
+ const spaceBelow = window.innerHeight - wrapperRef.value.getBoundingClientRect().bottom;
656
+ const hasEnoughSpaceBelow = spaceBelow > props.maxHeight;
950
657
 
951
- &:focus-within {
952
- @apply border-red-500 ring-4 ring-red-100;
953
- }
954
-
955
- &-label {
956
- @apply text-red-500;
957
- }
958
-
959
- &-message {
960
- @apply text-xs font-normal text-red-500;
961
- @apply mt-2 pl-4;
658
+ if (hasEnoughSpaceBelow || spaceBelow > spaceAbove || props.openDirection === DIRECTION.bottom) {
659
+ preferredOpenDirection.value = DIRECTION.bottom;
660
+ // TODO: magic numbers
661
+ optimizedHeight.value = Math.min(spaceBelow - 40, props.maxHeight);
662
+ } else {
663
+ preferredOpenDirection.value = DIRECTION.top;
664
+ optimizedHeight.value = Math.min(spaceAbove - 40, props.maxHeight);
962
665
  }
963
666
  }
964
667
 
965
- .description {
966
- @apply text-xs font-normal text-gray-500/[85];
967
- @apply pl-4 pt-2;
968
- }
668
+ function removeElement(option, shouldClose = true) {
669
+ if (props.disabled) return;
670
+ if (option.$isDisabled) return;
969
671
 
970
- .after-caret {
971
- @apply flex-col items-start md:flex-row md:items-center;
672
+ if (props.noClear && !props.multiple) {
673
+ deactivate();
972
674
 
973
- .after-caret-slot {
974
- @apply pb-2.5 pl-4 pr-4 md:pb-0 md:pl-0;
675
+ return;
975
676
  }
976
- }
977
677
 
978
- .mono-select-add {
979
- &-wrapper {
980
- @apply flex items-center justify-between;
981
- @apply cursor-pointer;
982
- @apply p-3;
983
-
984
- &:hover {
985
- @apply bg-gray-100;
986
- }
678
+ let value = "";
987
679
 
988
- &:active {
989
- @apply bg-gray-200 font-medium;
990
- }
680
+ if (props.multiple) {
681
+ value = !Array.isArray(option)
682
+ ? [...props.modelValue].filter((item) => item !== option[props.valueKey])
683
+ : [];
991
684
  }
992
685
 
993
- &-title {
994
- @apply text-base font-medium text-gray-900;
686
+ emit("update:modelValue", value);
687
+ emit("remove", option, props.id);
995
688
 
996
- &-command {
997
- @apply text-gray-500;
998
- }
689
+ if (shouldClose) {
690
+ deactivate();
999
691
  }
692
+ }
1000
693
 
1001
- &-button {
1002
- @apply absolute bottom-[0.5625rem] right-3;
1003
- @apply rounded-full p-0;
1004
- }
694
+ function setLabelPosition() {
695
+ if (props.labelOutside || !hasSlotContent(slots["left"])) return;
1005
696
 
1006
- &-icon {
1007
- @apply bg-transparent;
1008
- @apply p-0;
697
+ const leftSlotWidth = leftSlotWrapperRef.value.getBoundingClientRect().width;
698
+ const innerWrapperPaddingLeft = parseInt(
699
+ window.getComputedStyle(innerWrapperRef.value).paddingLeft,
700
+ );
1009
701
 
1010
- &:deep(svg) {
1011
- @apply !m-1;
1012
- }
702
+ if (props.multiple && localValue.value.length >= 1) {
703
+ labelComponentRef.value.labelElement.style.left = `${leftSlotWidth - innerWrapperPaddingLeft}px`;
704
+ leftSlotWrapperRef.value.classList.remove("group-[]/placement-inside:-mt-4");
705
+ } else {
706
+ labelComponentRef.value.labelElement.style.left = `${leftSlotWidth + innerWrapperPaddingLeft}px`;
1013
707
  }
1014
708
  }
1015
709
 
1016
- .cross-out-option {
1017
- :deep(.multiselect__option--selected) {
1018
- @apply hidden !important;
1019
- }
710
+ const {
711
+ config,
712
+ hasSlotContent,
713
+ labelAttrs,
714
+ wrapperAttrs,
715
+ innerWrapperAttrs,
716
+ leftSlotAttrs,
717
+ beforeCaretSlotAttrs,
718
+ afterCaretSlotAttrs,
719
+ caretToggleAttrs,
720
+ iconToggleAttrs,
721
+ caretClearAttrs,
722
+ caretClearTextAttrs,
723
+ iconClearAttrs,
724
+ caretRemoveItemAttrs,
725
+ iconRemoveItemAttrs,
726
+ searchAttrs,
727
+ searchInputAttrs,
728
+ selectedLabelsAttrs,
729
+ selectedLabelAttrs,
730
+ dropdownListAttrs,
731
+ } = useAttrs(props, { isTop, isOpen, selectedLabel });
732
+ </script>
1020
733
 
1021
- :deep(.multiselect-single-slot) {
1022
- @apply !line-through;
1023
- }
1024
- }
1025
- </style>
734
+ <i18n>
735
+ en:
736
+ listIsEmpty: "List is empty."
737
+ noDataToShow: "No data to show."
738
+ clear: "clear"
739
+ addMore: "Add more..."
740
+ add: Add
741
+ ru:
742
+ listIsEmpty: "Список пуст."
743
+ noDataToShow: "Нет данных."
744
+ clear: "очистить"
745
+ addMore: "Добавить ещё..."
746
+ add: Добавить
747
+ ua:
748
+ listIsEmpty: "Список порожній."
749
+ noDataToShow: "Дані відсутні."
750
+ clear: "очистити"
751
+ addMore: "Додати ще..."
752
+ add: Додати
753
+ </i18n>