@vc-shell/framework 1.0.38 → 1.0.40

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 (256) hide show
  1. package/core/api/index.ts +1 -0
  2. package/core/api/platform.ts +8332 -0
  3. package/core/composables/index.ts +8 -0
  4. package/core/composables/useAutosave/index.ts +57 -0
  5. package/core/composables/useFunctions/debounce.ts +18 -0
  6. package/core/composables/useFunctions/delay.ts +7 -0
  7. package/core/composables/useFunctions/index.ts +21 -0
  8. package/core/composables/useFunctions/once.ts +14 -0
  9. package/core/composables/useFunctions/sleep.ts +4 -0
  10. package/core/composables/useFunctions/throttle.ts +17 -0
  11. package/core/composables/useI18n/index.ts +28 -0
  12. package/core/composables/useLogger/index.ts +24 -0
  13. package/core/composables/useNotifications/index.ts +116 -0
  14. package/core/composables/usePermissions/index.ts +32 -0
  15. package/core/composables/useSettings/index.ts +62 -0
  16. package/core/composables/useUser/index.ts +266 -0
  17. package/core/directives/autofocus/index.ts +9 -0
  18. package/core/directives/click-outside/index.ts +21 -0
  19. package/core/directives/index.ts +4 -0
  20. package/core/directives/loading/index.ts +28 -0
  21. package/core/directives/permissions/index.ts +20 -0
  22. package/core/plugins/index.ts +1 -0
  23. package/core/plugins/validation/index.ts +2 -0
  24. package/core/plugins/validation/rules.ts +196 -0
  25. package/core/types/index.ts +92 -0
  26. package/core/utilities/camelToSnake.ts +7 -0
  27. package/core/utilities/index.ts +1 -0
  28. package/dist/core/composables/useNotifications/index.d.ts +1 -1
  29. package/dist/core/composables/useNotifications/index.d.ts.map +1 -1
  30. package/dist/core/composables/useSettings/index.d.ts +10 -1
  31. package/dist/core/composables/useSettings/index.d.ts.map +1 -1
  32. package/dist/core/composables/useUser/index.d.ts +2 -2
  33. package/dist/core/composables/useUser/index.d.ts.map +1 -1
  34. package/dist/core/plugins/validation/index.d.ts.map +1 -1
  35. package/dist/core/types/index.d.ts +1 -1
  36. package/dist/core/types/index.d.ts.map +1 -1
  37. package/dist/framework.js +72 -99
  38. package/dist/framework.js.map +1 -1
  39. package/dist/index.d.ts +3 -1
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/shared/app-switcher/composables/useAppSwitcher/index.d.ts +1 -1
  42. package/dist/shared/app-switcher/composables/useAppSwitcher/index.d.ts.map +1 -1
  43. package/dist/shared/app-switcher/index.d.ts +2 -2
  44. package/dist/shared/app-switcher/index.d.ts.map +1 -1
  45. package/dist/shared/blade-navigation/composables/useBladeNavigation/index.d.ts +1 -1
  46. package/dist/shared/blade-navigation/composables/useBladeNavigation/index.d.ts.map +1 -1
  47. package/dist/shared/blade-navigation/types/index.d.ts +1 -1
  48. package/dist/shared/blade-navigation/types/index.d.ts.map +1 -1
  49. package/dist/style.css +1 -1
  50. package/dist/tsconfig.tsbuildinfo +1 -0
  51. package/dist/ui/components/atoms/vc-badge/index.d.ts +5 -0
  52. package/dist/ui/components/atoms/vc-badge/index.d.ts.map +1 -0
  53. package/dist/ui/components/atoms/vc-badge/vc-badge-model.d.ts +28 -0
  54. package/dist/ui/components/atoms/vc-badge/vc-badge-model.d.ts.map +1 -0
  55. package/dist/{components → ui/components}/atoms/vc-badge/vc-badge.stories.d.ts +0 -0
  56. package/dist/ui/components/atoms/vc-badge/vc-badge.stories.d.ts.map +1 -0
  57. package/dist/ui/components/atoms/vc-button/index.d.ts +5 -0
  58. package/dist/ui/components/atoms/vc-button/index.d.ts.map +1 -0
  59. package/dist/ui/components/atoms/vc-button/vc-button-model.d.ts +28 -0
  60. package/dist/ui/components/atoms/vc-button/vc-button-model.d.ts.map +1 -0
  61. package/dist/{components → ui/components}/atoms/vc-button/vc-button.stories.d.ts +0 -0
  62. package/dist/ui/components/atoms/vc-button/vc-button.stories.d.ts.map +1 -0
  63. package/dist/{components → ui/components}/atoms/vc-checkbox/vc-checkbox.stories.d.ts +0 -0
  64. package/dist/ui/components/atoms/vc-checkbox/vc-checkbox.stories.d.ts.map +1 -0
  65. package/dist/{components → ui/components}/atoms/vc-container/vc-container.stories.d.ts +0 -0
  66. package/dist/ui/components/atoms/vc-container/vc-container.stories.d.ts.map +1 -0
  67. package/dist/{components → ui/components}/atoms/vc-hint/vc-hint.stories.d.ts +0 -0
  68. package/dist/ui/components/atoms/vc-hint/vc-hint.stories.d.ts.map +1 -0
  69. package/dist/{components → ui/components}/atoms/vc-icon/vc-icon.stories.d.ts +0 -0
  70. package/dist/ui/components/atoms/vc-icon/vc-icon.stories.d.ts.map +1 -0
  71. package/dist/{components → ui/components}/atoms/vc-image/vc-image.stories.d.ts +0 -0
  72. package/dist/ui/components/atoms/vc-image/vc-image.stories.d.ts.map +1 -0
  73. package/dist/{components → ui/components}/atoms/vc-label/vc-label.stories.d.ts +0 -0
  74. package/dist/ui/components/atoms/vc-label/vc-label.stories.d.ts.map +1 -0
  75. package/dist/{components → ui/components}/atoms/vc-link/vc-link.stories.d.ts +0 -0
  76. package/dist/ui/components/atoms/vc-link/vc-link.stories.d.ts.map +1 -0
  77. package/dist/{components → ui/components}/atoms/vc-progress/vc-progress.stories.d.ts +0 -0
  78. package/dist/ui/components/atoms/vc-progress/vc-progress.stories.d.ts.map +1 -0
  79. package/dist/{components → ui/components}/atoms/vc-status/vc-status.stories.d.ts +0 -0
  80. package/dist/ui/components/atoms/vc-status/vc-status.stories.d.ts.map +1 -0
  81. package/dist/{components → ui/components}/atoms/vc-switch/vc-switch.stories.d.ts +0 -0
  82. package/dist/ui/components/atoms/vc-switch/vc-switch.stories.d.ts.map +1 -0
  83. package/dist/{components → ui/components}/index.d.ts +4 -3
  84. package/dist/ui/components/index.d.ts.map +1 -0
  85. package/dist/{components → ui/components}/molecules/vc-breadcrumbs/vc-breadcrumbs.stories.d.ts +0 -0
  86. package/dist/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.stories.d.ts.map +1 -0
  87. package/dist/{components → ui/components}/molecules/vc-form/vc-form.stories.d.ts +0 -0
  88. package/dist/ui/components/molecules/vc-form/vc-form.stories.d.ts.map +1 -0
  89. package/dist/ui/components/molecules/vc-input/index.d.ts +5 -0
  90. package/dist/ui/components/molecules/vc-input/index.d.ts.map +1 -0
  91. package/dist/ui/components/molecules/vc-input/vc-input-model.d.ts +140 -0
  92. package/dist/ui/components/molecules/vc-input/vc-input-model.d.ts.map +1 -0
  93. package/dist/ui/components/molecules/vc-input-currency/index.d.ts +5 -0
  94. package/dist/ui/components/molecules/vc-input-currency/index.d.ts.map +1 -0
  95. package/dist/ui/components/molecules/vc-input-currency/vc-input-currency-model.d.ts +124 -0
  96. package/dist/ui/components/molecules/vc-input-currency/vc-input-currency-model.d.ts.map +1 -0
  97. package/dist/{components → ui/components}/molecules/vc-pagination/vc-pagination.stories.d.ts +0 -0
  98. package/dist/ui/components/molecules/vc-pagination/vc-pagination.stories.d.ts.map +1 -0
  99. package/dist/{components → ui/components}/molecules/vc-rating/vc-rating.stories.d.ts +0 -0
  100. package/dist/ui/components/molecules/vc-rating/vc-rating.stories.d.ts.map +1 -0
  101. package/dist/ui/components/molecules/vc-select/index.d.ts +5 -0
  102. package/dist/ui/components/molecules/vc-select/index.d.ts.map +1 -0
  103. package/dist/ui/components/molecules/vc-select/vc-select-model.d.ts +207 -0
  104. package/dist/ui/components/molecules/vc-select/vc-select-model.d.ts.map +1 -0
  105. package/dist/{components → ui/components}/molecules/vc-textarea/vc-textarea.stories.d.ts +0 -0
  106. package/dist/ui/components/molecules/vc-textarea/vc-textarea.stories.d.ts.map +1 -0
  107. package/dist/{components → ui/components}/organisms/vc-app/vc-app.stories.d.ts +0 -0
  108. package/dist/ui/components/organisms/vc-app/vc-app.stories.d.ts.map +1 -0
  109. package/dist/{components → ui/components}/organisms/vc-blade/vc-blade.stories.d.ts +0 -0
  110. package/dist/ui/components/organisms/vc-blade/vc-blade.stories.d.ts.map +1 -0
  111. package/dist/{components → ui/components}/organisms/vc-login-form/vc-login-form.stories.d.ts +0 -0
  112. package/dist/ui/components/organisms/vc-login-form/vc-login-form.stories.d.ts.map +1 -0
  113. package/dist/{components → ui/components}/organisms/vc-popup/vc-popup.stories.d.ts +0 -0
  114. package/dist/ui/components/organisms/vc-popup/vc-popup.stories.d.ts.map +1 -0
  115. package/dist/{components → ui/components}/organisms/vc-table/vc-table.stories.d.ts +0 -0
  116. package/dist/ui/components/organisms/vc-table/vc-table.stories.d.ts.map +1 -0
  117. package/dist/ui/types/index.d.ts +13 -0
  118. package/dist/ui/types/index.d.ts.map +1 -0
  119. package/dist/ui/types/ts-helpers.d.ts +13 -0
  120. package/dist/ui/types/ts-helpers.d.ts.map +1 -0
  121. package/dist/vite.config.d.ts.map +1 -1
  122. package/package.json +30 -10
  123. package/shared/app-switcher/components/index.ts +1 -0
  124. package/shared/app-switcher/components/vc-app-switcher/vc-app-switcher.vue +90 -0
  125. package/shared/app-switcher/composables/index.ts +1 -0
  126. package/shared/app-switcher/composables/useAppSwitcher/index.ts +54 -0
  127. package/shared/app-switcher/index.ts +14 -0
  128. package/shared/assets/components/assets-details/assets-details.vue +138 -0
  129. package/shared/assets/components/index.ts +1 -0
  130. package/shared/assets/index.ts +19 -0
  131. package/shared/assets/locales/en.json +29 -0
  132. package/shared/assets/locales/index.ts +2 -0
  133. package/shared/blade-navigation/components/index.ts +1 -0
  134. package/shared/blade-navigation/components/vc-blade-navigation/vc-blade-navigation.vue +84 -0
  135. package/shared/blade-navigation/composables/index.ts +1 -0
  136. package/shared/blade-navigation/composables/useBladeNavigation/index.ts +216 -0
  137. package/shared/blade-navigation/index.ts +15 -0
  138. package/shared/blade-navigation/types/index.ts +52 -0
  139. package/shared/index.ts +16 -0
  140. package/tailwind.config.js +4 -3
  141. package/ui/components/atoms/vc-badge/index.ts +7 -0
  142. package/ui/components/atoms/vc-badge/vc-badge-model.ts +30 -0
  143. package/ui/components/atoms/vc-badge/vc-badge.stories.ts +27 -0
  144. package/ui/components/atoms/vc-badge/vc-badge.vue +57 -0
  145. package/ui/components/atoms/vc-button/index.ts +7 -0
  146. package/ui/components/atoms/vc-button/vc-button-model.ts +30 -0
  147. package/ui/components/atoms/vc-button/vc-button.stories.ts +34 -0
  148. package/ui/components/atoms/vc-button/vc-button.vue +219 -0
  149. package/ui/components/atoms/vc-card/vc-card.vue +137 -0
  150. package/ui/components/atoms/vc-checkbox/vc-checkbox.stories.ts +25 -0
  151. package/ui/components/atoms/vc-checkbox/vc-checkbox.vue +130 -0
  152. package/ui/components/atoms/vc-col/vc-col.vue +22 -0
  153. package/ui/components/atoms/vc-container/vc-container.stories.ts +31 -0
  154. package/ui/components/atoms/vc-container/vc-container.vue +222 -0
  155. package/ui/components/atoms/vc-hint/vc-hint.stories.ts +23 -0
  156. package/ui/components/atoms/vc-hint/vc-hint.vue +11 -0
  157. package/ui/components/atoms/vc-icon/vc-icon.stories.ts +32 -0
  158. package/ui/components/atoms/vc-icon/vc-icon.vue +36 -0
  159. package/ui/components/atoms/vc-image/vc-image.stories.ts +40 -0
  160. package/ui/components/atoms/vc-image/vc-image.vue +122 -0
  161. package/ui/components/atoms/vc-info-row/vc-info-row.vue +42 -0
  162. package/ui/components/atoms/vc-label/vc-label.stories.ts +23 -0
  163. package/ui/components/atoms/vc-label/vc-label.vue +49 -0
  164. package/ui/components/atoms/vc-link/vc-link.stories.ts +30 -0
  165. package/ui/components/atoms/vc-link/vc-link.vue +46 -0
  166. package/ui/components/atoms/vc-loading/vc-loading.vue +33 -0
  167. package/ui/components/atoms/vc-progress/vc-progress.stories.ts +25 -0
  168. package/ui/components/atoms/vc-progress/vc-progress.vue +65 -0
  169. package/ui/components/atoms/vc-row/vc-row.vue +13 -0
  170. package/ui/components/atoms/vc-status/vc-status.stories.ts +26 -0
  171. package/ui/components/atoms/vc-status/vc-status.vue +78 -0
  172. package/ui/components/atoms/vc-status-icon/vc-status-icon.vue +21 -0
  173. package/ui/components/atoms/vc-switch/vc-switch.stories.ts +27 -0
  174. package/ui/components/atoms/vc-switch/vc-switch.vue +100 -0
  175. package/ui/components/atoms/vc-widget/vc-widget.vue +85 -0
  176. package/ui/components/index.ts +44 -0
  177. package/ui/components/molecules/vc-breadcrumbs/_internal/vc-breadcrumbs-item/vc-breadcrumbs-item.vue +103 -0
  178. package/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.stories.ts +39 -0
  179. package/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.vue +21 -0
  180. package/ui/components/molecules/vc-currency-input/vc-input.vue +436 -0
  181. package/ui/components/molecules/vc-editor/vc-editor.vue +117 -0
  182. package/ui/components/molecules/vc-file-upload/vc-file-upload.vue +134 -0
  183. package/ui/components/molecules/vc-form/vc-form.stories.ts +23 -0
  184. package/ui/components/molecules/vc-form/vc-form.vue +5 -0
  185. package/ui/components/molecules/vc-input/index.ts +8 -0
  186. package/ui/components/molecules/vc-input/vc-input-model.ts +150 -0
  187. package/ui/components/molecules/vc-input/vc-input.vue +324 -0
  188. package/ui/components/molecules/vc-input-currency/index.ts +8 -0
  189. package/ui/components/molecules/vc-input-currency/vc-input-currency-model.ts +128 -0
  190. package/ui/components/molecules/vc-input-currency/vc-input-currency.vue +86 -0
  191. package/ui/components/molecules/vc-multivalue/vc-multivalue.vue +447 -0
  192. package/ui/components/molecules/vc-notification/vc-notification.vue +101 -0
  193. package/ui/components/molecules/vc-pagination/vc-pagination.stories.ts +23 -0
  194. package/ui/components/molecules/vc-pagination/vc-pagination.vue +169 -0
  195. package/ui/components/molecules/vc-rating/vc-rating.stories.ts +23 -0
  196. package/ui/components/molecules/vc-rating/vc-rating.vue +77 -0
  197. package/ui/components/molecules/vc-select/index.ts +7 -0
  198. package/ui/components/molecules/vc-select/vc-select-model.ts +216 -0
  199. package/ui/components/molecules/vc-select/vc-select.vue +727 -0
  200. package/ui/components/molecules/vc-slider/vc-slider.vue +106 -0
  201. package/ui/components/molecules/vc-textarea/vc-textarea.stories.ts +23 -0
  202. package/ui/components/molecules/vc-textarea/vc-textarea.vue +155 -0
  203. package/ui/components/organisms/vc-app/_internal/vc-app-bar/vc-app-bar.vue +150 -0
  204. package/ui/components/organisms/vc-app/_internal/vc-app-menu/_internal/vc-app-menu-item/_internal/vc-app-menu-link.vue +148 -0
  205. package/ui/components/organisms/vc-app/_internal/vc-app-menu/_internal/vc-app-menu-item/vc-app-menu-item.vue +157 -0
  206. package/ui/components/organisms/vc-app/_internal/vc-app-menu/vc-app-menu.vue +110 -0
  207. package/ui/components/organisms/vc-app/vc-app.stories.ts +75 -0
  208. package/ui/components/organisms/vc-app/vc-app.vue +169 -0
  209. package/ui/components/organisms/vc-blade/_internal/vc-blade-header/vc-blade-header.vue +126 -0
  210. package/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/_internal/vc-blade-toolbar-button/vc-blade-toolbar-button.vue +223 -0
  211. package/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/vc-blade-toolbar.vue +67 -0
  212. package/ui/components/organisms/vc-blade/vc-blade.stories.ts +46 -0
  213. package/ui/components/organisms/vc-blade/vc-blade.vue +87 -0
  214. package/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue +426 -0
  215. package/ui/components/organisms/vc-gallery/_internal/vc-gallery-item/vc-gallery-item.vue +123 -0
  216. package/ui/components/organisms/vc-gallery/_internal/vc-gallery-preview/vc-gallery-preview.vue +93 -0
  217. package/ui/components/organisms/vc-gallery/vc-gallery.vue +186 -0
  218. package/ui/components/organisms/vc-login-form/vc-login-form.stories.ts +55 -0
  219. package/ui/components/organisms/vc-login-form/vc-login-form.vue +48 -0
  220. package/ui/components/organisms/vc-popup/vc-popup.stories.ts +23 -0
  221. package/ui/components/organisms/vc-popup/vc-popup.vue +97 -0
  222. package/ui/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue +113 -0
  223. package/ui/components/organisms/vc-table/_internal/vc-table-counter/vc-table-counter.vue +29 -0
  224. package/ui/components/organisms/vc-table/_internal/vc-table-filter/vc-table-filter.vue +152 -0
  225. package/ui/components/organisms/vc-table/_internal/vc-table-mobile-item/vc-table-mobile-item.vue +272 -0
  226. package/ui/components/organisms/vc-table/vc-table.stories.ts +99 -0
  227. package/ui/components/organisms/vc-table/vc-table.vue +638 -0
  228. package/ui/types/index.ts +38 -0
  229. package/ui/types/ts-helpers.ts +46 -0
  230. package/dist/components/atoms/vc-badge/vc-badge.stories.d.ts.map +0 -1
  231. package/dist/components/atoms/vc-button/vc-button.stories.d.ts.map +0 -1
  232. package/dist/components/atoms/vc-checkbox/vc-checkbox.stories.d.ts.map +0 -1
  233. package/dist/components/atoms/vc-container/vc-container.stories.d.ts.map +0 -1
  234. package/dist/components/atoms/vc-hint/vc-hint.stories.d.ts.map +0 -1
  235. package/dist/components/atoms/vc-icon/vc-icon.stories.d.ts.map +0 -1
  236. package/dist/components/atoms/vc-image/vc-image.stories.d.ts.map +0 -1
  237. package/dist/components/atoms/vc-label/vc-label.stories.d.ts.map +0 -1
  238. package/dist/components/atoms/vc-link/vc-link.stories.d.ts.map +0 -1
  239. package/dist/components/atoms/vc-progress/vc-progress.stories.d.ts.map +0 -1
  240. package/dist/components/atoms/vc-status/vc-status.stories.d.ts.map +0 -1
  241. package/dist/components/atoms/vc-switch/vc-switch.stories.d.ts.map +0 -1
  242. package/dist/components/index.d.ts.map +0 -1
  243. package/dist/components/molecules/vc-breadcrumbs/vc-breadcrumbs.stories.d.ts.map +0 -1
  244. package/dist/components/molecules/vc-form/vc-form.stories.d.ts.map +0 -1
  245. package/dist/components/molecules/vc-input/vc-input.stories.d.ts +0 -7
  246. package/dist/components/molecules/vc-input/vc-input.stories.d.ts.map +0 -1
  247. package/dist/components/molecules/vc-pagination/vc-pagination.stories.d.ts.map +0 -1
  248. package/dist/components/molecules/vc-rating/vc-rating.stories.d.ts.map +0 -1
  249. package/dist/components/molecules/vc-select/vc-select.stories.d.ts +0 -7
  250. package/dist/components/molecules/vc-select/vc-select.stories.d.ts.map +0 -1
  251. package/dist/components/molecules/vc-textarea/vc-textarea.stories.d.ts.map +0 -1
  252. package/dist/components/organisms/vc-app/vc-app.stories.d.ts.map +0 -1
  253. package/dist/components/organisms/vc-blade/vc-blade.stories.d.ts.map +0 -1
  254. package/dist/components/organisms/vc-login-form/vc-login-form.stories.d.ts.map +0 -1
  255. package/dist/components/organisms/vc-popup/vc-popup.stories.d.ts.map +0 -1
  256. package/dist/components/organisms/vc-table/vc-table.stories.d.ts.map +0 -1
@@ -0,0 +1,33 @@
1
+ <template>
2
+ <div
3
+ class="tw-absolute tw-items-center tw-justify-center tw-flex-col tw-z-[9998] tw-hidden tw-w-full tw-h-full tw-box-border"
4
+ :class="{
5
+ '!tw-flex tw-backdrop-blur-[3px] tw-bg-[rgba(255, 255, 255, 0.5)]':
6
+ active,
7
+ }"
8
+ >
9
+ <div class="tw-relative tw-w-[142px] tw-h-[40px] tw-z-[1]">
10
+ <span
11
+ class="tw-absolute tw-w-4 tw-h-4 tw-top-[12px] tw-left-[15px] tw-bg-[#319ed4] tw-rounded-full tw-translate-x-0 tw-animate-loadingMarker"
12
+ ></span>
13
+ <div
14
+ class="tw-translate-x-0 tw-mt-3 tw-ml-[31px] tw-animate-loadingMarkers"
15
+ >
16
+ <span
17
+ class="tw-block tw-float-left tw-w-4 tw-h-4 tw-bg-[#319ed4] tw-rounded-full tw-ml-4"
18
+ v-for="item in 3"
19
+ :key="`marker_${item}`"
20
+ ></span>
21
+ </div>
22
+ </div>
23
+ </div>
24
+ </template>
25
+
26
+ <script lang="ts" setup>
27
+ defineProps({
28
+ active: {
29
+ type: Boolean,
30
+ default: false,
31
+ },
32
+ });
33
+ </script>
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Progress component.
3
+ * @author Iurii A Taranov <me@flanker72.ru>
4
+ */
5
+ import { Story } from "@storybook/vue3";
6
+ import VcProgress from "./vc-progress.vue";
7
+
8
+ export default {
9
+ title: "atoms/vc-progress",
10
+ component: VcProgress,
11
+ };
12
+
13
+ const Template: Story = (args) => ({
14
+ components: { VcProgress },
15
+ setup() {
16
+ return { args };
17
+ },
18
+ template: '<vc-progress v-bind="args"></vc-progress>',
19
+ });
20
+
21
+ export const Progress = Template.bind({});
22
+ Progress.storyName = "vc-progress";
23
+ Progress.args = {
24
+ value: 30,
25
+ };
@@ -0,0 +1,65 @@
1
+ <template>
2
+ <div
3
+ :class="[
4
+ 'vc-progress tw-border tw-border-[length:var(--progressbar-border-width)] tw-border-[color:var(--progressbar-border-color)] tw-rounded-[var(--progressbar-border-radius)] tw-h-[var(--progressbar-height)] tw-transition tw-duration-200 tw-box-border tw-bg-[color:var(--progressbar-background-color)]',
5
+ variant,
6
+ ]"
7
+ >
8
+ <div
9
+ class="vc-progress__value tw-bg-[color:var(--progressbar-foreground-color)] tw-transition tw-duration-200 tw-h-full"
10
+ :style="`width: ${value}%`"
11
+ ></div>
12
+ </div>
13
+ </template>
14
+
15
+ <script lang="ts" setup>
16
+ defineProps({
17
+ value: {
18
+ type: Number,
19
+ default: 0,
20
+ },
21
+
22
+ variant: {
23
+ type: String,
24
+ default: "default",
25
+ enum: ["default", "striped"],
26
+ },
27
+ });
28
+ </script>
29
+
30
+ <style lang="scss">
31
+ :root {
32
+ --progressbar-height: 16px;
33
+ --progressbar-border-radius: 2px;
34
+ --progressbar-background-color: #ffffff;
35
+ --progressbar-foreground-color: #e1eff9;
36
+ --progressbar-border-width: 1px;
37
+ --progressbar-border-color: #e1eff9;
38
+ }
39
+
40
+ @keyframes change {
41
+ from {
42
+ background-position: 0 0, left;
43
+ }
44
+ to {
45
+ background-position: 30px 0, left;
46
+ }
47
+ }
48
+
49
+ .vc-progress {
50
+ &.striped {
51
+ .vc-progress__value {
52
+ background: linear-gradient(
53
+ 45deg,
54
+ transparent 50%,
55
+ #acd2f2 50%,
56
+ #acd2f2 75%,
57
+ transparent 75%
58
+ )
59
+ left/30px 30px repeat-x,
60
+ #e1f0fe;
61
+ animation: change 1s linear infinite;
62
+ }
63
+ }
64
+ }
65
+ </style>
@@ -0,0 +1,13 @@
1
+ <template>
2
+ <div class="vc-row tw-flex-nowrap tw-flex tw-items-stretch">
3
+ <slot></slot>
4
+ </div>
5
+ </template>
6
+
7
+ <style lang="scss">
8
+ .vc-row {
9
+ .vc-app_mobile & {
10
+ display: block;
11
+ }
12
+ }
13
+ </style>
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Status component.
3
+ * @author Iurii A Taranov <me@flanker72.ru>
4
+ */
5
+ import { Story } from "@storybook/vue3";
6
+ import VcStatus from "./vc-status.vue";
7
+
8
+ export default {
9
+ title: "atoms/vc-status",
10
+ component: VcStatus,
11
+ };
12
+
13
+ const Template: Story = (args) => ({
14
+ components: { VcStatus },
15
+ setup() {
16
+ return { args };
17
+ },
18
+ template: '<vc-status v-bind="args">Status text</vc-status>',
19
+ });
20
+
21
+ export const Status = Template.bind({});
22
+ Status.storyName = "vc-status";
23
+ Status.args = {
24
+ disabled: false,
25
+ clickable: true,
26
+ };
@@ -0,0 +1,78 @@
1
+ <template>
2
+ <div
3
+ class="vc-status"
4
+ :class="[
5
+ `vc-status_${variant}`,
6
+ { 'vc-status_outline': outline },
7
+ { 'vc-status_extended': extend },
8
+ ]"
9
+ >
10
+ <slot></slot>
11
+ </div>
12
+ </template>
13
+
14
+ <script lang="ts" setup>
15
+ defineProps({
16
+ variant: {
17
+ type: String,
18
+ default: "info",
19
+ enum: ["info", "warning", "danger", "success", "light-danger"],
20
+ },
21
+
22
+ outline: {
23
+ type: Boolean,
24
+ default: true,
25
+ },
26
+
27
+ extend: {
28
+ type: Boolean,
29
+ default: false,
30
+ },
31
+ });
32
+ </script>
33
+
34
+ <style lang="scss">
35
+ :root {
36
+ --status-padding: 4px 14px;
37
+ --status-padding-extended: 12px;
38
+
39
+ --status-border-radius: 2px;
40
+ --status-border-radius-extended: 4px;
41
+ --status-border-width: 1px;
42
+
43
+ --status-info-color: #ffffff;
44
+ --status-info-main-color: #bdd1df;
45
+
46
+ --status-warning-color: #ffffff;
47
+ --status-warning-main-color: #f89406;
48
+
49
+ --status-danger-color: #ffffff;
50
+ --status-danger-main-color: #ef796f;
51
+
52
+ --status-success-color: #ffffff;
53
+ --status-success-main-color: #87b563;
54
+
55
+ --status-light-danger-color: #333333;
56
+ --status-light-danger-main-color: #ffefef;
57
+ }
58
+
59
+ $variants: info, warning, danger, success, light-danger;
60
+
61
+ .vc-status {
62
+ @apply tw-inline-block tw-rounded-[var(--status-border-radius)] tw-py-1 tw-px-3.5 tw-text-base tw-font-normal tw-whitespace-nowrap;
63
+
64
+ @each $variant in $variants {
65
+ &_#{$variant} {
66
+ @apply tw-text-[color:var(--status-#{$variant}-color)] tw-border tw-border-solid tw-border-[color:var(--status-#{$variant}-main-color)] tw-bg-[color:var(--status-#{$variant}-main-color)];
67
+
68
+ &.vc-status_outline {
69
+ @apply tw-text-[color:var(--status-#{$variant}-main-color)] tw-border tw-border-solid tw-border-[color:var(--status-#{$variant}-main-color)] tw-bg-white;
70
+ }
71
+ }
72
+ }
73
+
74
+ &.vc-status_extended {
75
+ @apply tw-whitespace-normal tw-p-[var(--status-padding-extended)] tw-rounded-[var(--status-border-radius-extended)];
76
+ }
77
+ }
78
+ </style>
@@ -0,0 +1,21 @@
1
+ <template>
2
+ <div>
3
+ <template v-if="status">
4
+ <VcIcon icon="fas fa-check-circle" class="tw-text-[color:#87b563]"></VcIcon>
5
+ </template>
6
+ <template v-else>
7
+ <VcIcon icon="fas fa-times-circle" class="tw-text-[color:#bdd1df]"></VcIcon>
8
+ </template>
9
+ </div>
10
+ </template>
11
+
12
+ <script lang="ts" setup>
13
+ import { VcIcon } from "@/ui/components";
14
+
15
+ defineProps({
16
+ status: {
17
+ type: Boolean,
18
+ default: false,
19
+ },
20
+ });
21
+ </script>
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Switch component.
3
+ * @author Iurii A Taranov <me@flanker72.ru>
4
+ */
5
+ import { Story } from "@storybook/vue3";
6
+ import VcSwitch from "./vc-switch.vue";
7
+ import VcHint from "../vc-hint/vc-hint.vue";
8
+
9
+ export default {
10
+ title: "atoms/vc-switch",
11
+ component: VcSwitch,
12
+ };
13
+
14
+ const Template: Story = (args) => ({
15
+ components: { VcSwitch, VcHint },
16
+ setup() {
17
+ return { args };
18
+ },
19
+ template: '<vc-switch v-bind="args"></vc-switch>',
20
+ });
21
+
22
+ export const Switch = Template.bind({});
23
+ Switch.storyName = "vc-switch";
24
+ Switch.args = {
25
+ checked: false,
26
+ disabled: false,
27
+ };
@@ -0,0 +1,100 @@
1
+ <template>
2
+ <div>
3
+ <!-- Switch label -->
4
+ <VcLabel v-if="label" class="tw-mb-2" :required="required">
5
+ <span>{{ label }}</span>
6
+ </VcLabel>
7
+ <div class="tw-relative tw-inline-block tw-w-[54px] tw-h-[18px]">
8
+ <label>
9
+ <input
10
+ type="checkbox"
11
+ class="vc-switch__input"
12
+ :checked="modelValue"
13
+ :disabled="disabled"
14
+ @input="onInput"
15
+ />
16
+ <span class="vc-switch__slider"></span>
17
+ </label>
18
+ <VcHint class="tw-mt-2 tw-w-max" v-if="tooltip">
19
+ {{ tooltip }}
20
+ </VcHint>
21
+ </div>
22
+ </div>
23
+ </template>
24
+
25
+ <script lang="ts" setup>
26
+ defineProps({
27
+ modelValue: {
28
+ type: Boolean,
29
+ default: false,
30
+ },
31
+
32
+ disabled: {
33
+ type: Boolean,
34
+ default: false,
35
+ },
36
+
37
+ tooltip: {
38
+ type: String,
39
+ default: "",
40
+ },
41
+
42
+ required: {
43
+ type: Boolean,
44
+ default: false,
45
+ },
46
+
47
+ label: {
48
+ type: String,
49
+ default: undefined,
50
+ },
51
+ });
52
+
53
+ const emit = defineEmits(["update:modelValue"]);
54
+
55
+ function onInput(e: InputEvent) {
56
+ const newValue = (e.target as HTMLInputElement).checked;
57
+ emit("update:modelValue", newValue);
58
+ }
59
+ </script>
60
+
61
+ <style lang="scss">
62
+ :root {
63
+ --switch-main-color: #43b0e6;
64
+ --switch-secondary-color: #565656;
65
+ --switch-transition: all 0.2s ease-in-out;
66
+ --switch-icon-transition: opacity 0.3s ease-in-out;
67
+ --switch-active-icon: url("data:image/svg+xml;utf8,<svg width='10' height='8' viewBox='0 0 10 8' fill='none' xmlns='http://www.w3.org/2000/svg'><path d='M3.73609 7.34288L0.161085 3.85628C-0.0536949 3.64681 -0.0536949 3.30718 0.161085 3.09769L0.938884 2.3391C1.15366 2.12961 1.50193 2.12961 1.71671 2.3391L4.125 4.68782L8.28329 0.657101C8.49807 0.447633 8.84634 0.447633 9.06112 0.657101L9.83892 1.41569C10.0537 1.62516 10.0537 1.96479 9.83892 2.17428L4.51391 7.3429C4.29911 7.55237 3.95087 7.55237 3.73609 7.34288Z' fill='white'/></svg>");
68
+ --switch-disabled-icon: url("data:image/svg+xml;utf8,<svg width='8' height='8' viewBox='0 0 8 8' fill='none' xmlns='http://www.w3.org/2000/svg'><path d='M5.51636 4L7.79068 1.72568C8.06977 1.44659 8.06977 0.994091 7.79068 0.714773L7.28523 0.209318C7.00614 -0.0697727 6.55364 -0.0697727 6.27432 0.209318L4 2.48364L1.72568 0.209318C1.44659 -0.0697727 0.994091 -0.0697727 0.714773 0.209318L0.209318 0.714773C-0.0697727 0.993864 -0.0697727 1.44636 0.209318 1.72568L2.48364 4L0.209318 6.27432C-0.0697727 6.55341 -0.0697727 7.00591 0.209318 7.28523L0.714773 7.79068C0.993864 8.06977 1.44659 8.06977 1.72568 7.79068L4 5.51636L6.27432 7.79068C6.55341 8.06977 7.00614 8.06977 7.28523 7.79068L7.79068 7.28523C8.06977 7.00614 8.06977 6.55364 7.79068 6.27432L5.51636 4Z' fill='white'/></svg>");
69
+ }
70
+
71
+ .vc-switch {
72
+ &__input {
73
+ @apply tw-w-0 tw-h-0 tw-opacity-0;
74
+
75
+ &:checked + .vc-switch__slider:before {
76
+ @apply tw-translate-x-[29px];
77
+ }
78
+
79
+ &:checked + .vc-switch__slider {
80
+ @apply tw-bg-[color:var(--switch-main-color)] after:tw-bg-[image:var(--switch-active-icon)] after:tw-bg-[position:10px] after:tw-bg-[length:10px_7px];
81
+ }
82
+
83
+ &:disabled + .vc-switch__slider {
84
+ @apply tw-bg-[color:var(--switch-secondary-color)];
85
+ }
86
+ }
87
+
88
+ &__slider {
89
+ @apply tw-absolute tw-top-0 tw-right-0 tw-bottom-0 tw-left-0 tw-bg-[color:var(--switch-secondary-color)] tw-rounded-[3px] tw-cursor-pointer tw-transition tw-duration-200;
90
+
91
+ &:after {
92
+ @apply tw-inline-block tw-w-full tw-h-full tw-bg-[image:var(--switch-disabled-icon)] tw-bg-[position:calc(100%-11px)] tw-bg-no-repeat tw-bg-[length:8px_8px] tw-content-[""];
93
+ }
94
+
95
+ &:before {
96
+ @apply tw-absolute tw-bottom-px tw-left-px tw-flex tw-justify-center tw-items-center tw-w-[23px] tw-h-[16px] tw-bg-white tw-rounded-sm tw-text-[color:#d2d2d2] tw-text-[10px] tw-transition tw-duration-200 tw-content-["|||"];
97
+ }
98
+ }
99
+ }
100
+ </style>
@@ -0,0 +1,85 @@
1
+ <template>
2
+ <div
3
+ class="vc-widget"
4
+ :class="{ 'vc-widget_disabled': disabled }"
5
+ @click="onClick"
6
+ >
7
+ <VcIcon
8
+ v-if="icon"
9
+ class="vc-widget__icon"
10
+ :icon="icon"
11
+ size="xxl"
12
+ ></VcIcon>
13
+ <div v-if="title" class="vc-widget__title">{{ title }}</div>
14
+ <div v-if="value !== undefined" class="vc-widget__value">{{ value }}</div>
15
+ </div>
16
+ </template>
17
+
18
+ <script lang="ts" setup>
19
+ const props = defineProps({
20
+ icon: {
21
+ type: String,
22
+ default: undefined,
23
+ },
24
+
25
+ title: {
26
+ type: String,
27
+ default: undefined,
28
+ },
29
+
30
+ value: {
31
+ type: [String, Number],
32
+ default: undefined,
33
+ },
34
+
35
+ disabled: {
36
+ type: Boolean,
37
+ default: false,
38
+ },
39
+ });
40
+ const emit = defineEmits(["click"]);
41
+
42
+ function onClick() {
43
+ if (!props.disabled) {
44
+ emit("click");
45
+ }
46
+ }
47
+ </script>
48
+
49
+ <style lang="scss">
50
+ .vc-widget {
51
+ @apply tw-flex tw-w-[100px] tw-overflow-hidden tw-p-5
52
+ tw-box-border tw-flex-col tw-items-center
53
+ tw-justify-center tw-border-b tw-border-solid
54
+ tw-border-b-[#eaedf3] tw-cursor-pointer tw-bg-white
55
+ hover:tw-bg-[#eff7fc];
56
+
57
+ &_disabled {
58
+ @apply tw-cursor-default hover:tw-bg-white;
59
+ }
60
+
61
+ &__icon {
62
+ @apply tw-text-[#a9bfd2];
63
+ }
64
+
65
+ &_disabled &__icon {
66
+ @apply tw-text-[#d2d4d7];
67
+ }
68
+
69
+ &__title {
70
+ @apply tw-font-medium tw-text-sm tw-text-[#333333] tw-mt-3 tw-mb-1 tw-mx-0;
71
+ }
72
+
73
+ &_disabled &__title {
74
+ @apply tw-text-[#d2d4d7];
75
+ }
76
+
77
+ &__value {
78
+ @apply tw-font-medium tw-text-[22px] tw-text-[#43b0e6];
79
+ }
80
+
81
+ &_disabled &__value {
82
+ @apply tw-text-[#d2d4d7];
83
+ }
84
+ }
85
+ </style>
@@ -0,0 +1,44 @@
1
+ /* Atoms */
2
+ export { VcBadge } from "./atoms/vc-badge";
3
+ export { default as VcButton } from "./atoms/vc-button/vc-button.vue";
4
+ export { default as VcCard } from "./atoms/vc-card/vc-card.vue";
5
+ export { default as VcCheckbox } from "./atoms/vc-checkbox/vc-checkbox.vue";
6
+ export { default as VcCol } from "./atoms/vc-col/vc-col.vue";
7
+ export { default as VcContainer } from "./atoms/vc-container/vc-container.vue";
8
+ export { default as VcHint } from "./atoms/vc-hint/vc-hint.vue";
9
+ export { default as VcIcon } from "./atoms/vc-icon/vc-icon.vue";
10
+ export { default as VcInfoRow } from "./atoms/vc-info-row/vc-info-row.vue";
11
+ export { default as VcImage } from "./atoms/vc-image/vc-image.vue";
12
+ export { default as VcLabel } from "./atoms/vc-label/vc-label.vue";
13
+ export { default as VcLink } from "./atoms/vc-link/vc-link.vue";
14
+ export { default as VcLoading } from "./atoms/vc-loading/vc-loading.vue";
15
+ export { default as VcProgress } from "./atoms/vc-progress/vc-progress.vue";
16
+ export { default as VcRow } from "./atoms/vc-row/vc-row.vue";
17
+ export { default as VcStatus } from "./atoms/vc-status/vc-status.vue";
18
+ export { default as VcStatusIcon } from "./atoms/vc-status-icon/vc-status-icon.vue";
19
+ export { default as VcSwitch } from "./atoms/vc-switch/vc-switch.vue";
20
+ export { default as VcWidget } from "./atoms/vc-widget/vc-widget.vue";
21
+
22
+ /* Molecules */
23
+ export { default as VcBreadcrumbs } from "./molecules/vc-breadcrumbs/vc-breadcrumbs.vue";
24
+ export { default as VcEditor } from "./molecules/vc-editor/vc-editor.vue";
25
+ export { default as VcForm } from "./molecules/vc-form/vc-form.vue";
26
+ export { default as VcFileUpload } from "./molecules/vc-file-upload/vc-file-upload.vue";
27
+ export { VcInput } from "./molecules/vc-input";
28
+ export { VcInputCurrency } from "./molecules/vc-input-currency";
29
+ export { default as VcMultivalue } from "./molecules/vc-multivalue/vc-multivalue.vue";
30
+ export { default as VcNotification } from "./molecules/vc-notification/vc-notification.vue";
31
+ export { default as VcPagination } from "./molecules/vc-pagination/vc-pagination.vue";
32
+ export { default as VcRating } from "./molecules/vc-rating/vc-rating.vue";
33
+ export { VcSelect } from "./molecules/vc-select";
34
+ export { default as VcSlider } from "./molecules/vc-slider/vc-slider.vue";
35
+ export { default as VcTextarea } from "./molecules/vc-textarea/vc-textarea.vue";
36
+
37
+ /* Organisms */
38
+ export { default as VcApp } from "./organisms/vc-app/vc-app.vue";
39
+ export { default as VcBlade } from "./organisms/vc-blade/vc-blade.vue";
40
+ export { default as VcDynamicProperty } from "./organisms/vc-dynamic-property/vc-dynamic-property.vue";
41
+ export { default as VcGallery } from "./organisms/vc-gallery/vc-gallery.vue";
42
+ export { default as VcLoginForm } from "./organisms/vc-login-form/vc-login-form.vue";
43
+ export { default as VcPopup } from "./organisms/vc-popup/vc-popup.vue";
44
+ export { default as VcTable } from "./organisms/vc-table/vc-table.vue";
@@ -0,0 +1,103 @@
1
+ <template>
2
+ <div
3
+ class="vc-breadcrumbs-item"
4
+ :class="{
5
+ 'vc-breadcrumbs-item_current': current,
6
+ }"
7
+ @click="onClick"
8
+ >
9
+ <VcIcon
10
+ v-if="icon"
11
+ class="vc-breadcrumbs-item__icon"
12
+ :icon="icon"
13
+ size="s"
14
+ />
15
+ <div class="vc-breadcrumbs-item__title">
16
+ {{ title }}
17
+ </div>
18
+ </div>
19
+ </template>
20
+
21
+ <script lang="ts" setup>
22
+ import { VcIcon } from "@/ui/components";
23
+
24
+ const props = defineProps({
25
+ current: {
26
+ type: Boolean,
27
+ default: false,
28
+ },
29
+
30
+ icon: {
31
+ type: String,
32
+ default: undefined,
33
+ },
34
+
35
+ title: {
36
+ type: String,
37
+ default: undefined,
38
+ },
39
+
40
+ clickHandler: {
41
+ type: Function,
42
+ default: undefined,
43
+ },
44
+
45
+ id: {
46
+ type: String,
47
+ default: undefined,
48
+ },
49
+ });
50
+
51
+ const emit = defineEmits(["click"]);
52
+
53
+ function onClick(): void {
54
+ if (!props.current) {
55
+ if (props.clickHandler && typeof props.clickHandler === "function") {
56
+ props.clickHandler(props.id);
57
+ } else {
58
+ emit("click");
59
+ }
60
+ }
61
+ }
62
+ </script>
63
+
64
+ <style lang="scss">
65
+ :root {
66
+ --breadcrumbs-item-height: 28px;
67
+ --breadcrumbs-item-border-color: #a1c0d4;
68
+ --breadcrumbs-item-border-color-hover: #8fb0c6;
69
+ --breadcrumbs-item-border-color-current: #838d9a;
70
+ --breadcrumbs-item-color: #43b0e6;
71
+ --breadcrumbs-item-color-current: #465769;
72
+ --breadcrumbs-item-icon-color: #a1c0d4;
73
+ }
74
+
75
+ .vc-breadcrumbs-item {
76
+ @apply tw-h-[var(--breadcrumbs-item-height)]
77
+ tw-box-border tw-rounded-[calc(var(--breadcrumbs-item-height)/2)]
78
+ tw-border tw-border-solid
79
+ tw-border-[color:var(--breadcrumbs-item-border-color)]
80
+ tw-text-[color:var(--breadcrumbs-item-color)]
81
+ tw-whitespace-nowrap
82
+ tw-px-3 tw-mr-2
83
+ tw-text-sm tw-cursor-pointer tw-inline-flex tw-items-center
84
+ hover:tw-border
85
+ hover:tw-border-solid
86
+ hover:tw-border-[color:var(--breadcrumbs-item-border-color-hover)];
87
+
88
+ &__icon {
89
+ @apply tw-mr-2 tw-text-[color:var(--breadcrumbs-item-icon-color)];
90
+ }
91
+
92
+ &_disabled {
93
+ @apply tw-opacity-[0.4];
94
+ }
95
+
96
+ &_current,
97
+ &_current:hover {
98
+ @apply tw-text-[color:var(--breadcrumbs-item-color-current)]
99
+ tw-border tw-border-solid tw-border-[color:var(--breadcrumbs-item-border-color-current)]
100
+ tw-cursor-default tw-mr-0;
101
+ }
102
+ }
103
+ </style>
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Breadcrumbs component.
3
+ * @author Iurii A Taranov <me@flanker72.ru>
4
+ */
5
+ import { Story } from "@storybook/vue3";
6
+ import VcBreadcrumbs from "./vc-breadcrumbs.vue";
7
+
8
+ export default {
9
+ title: "molecules/vc-breadcrumbs",
10
+ component: VcBreadcrumbs,
11
+ };
12
+
13
+ const Template: Story = (args) => ({
14
+ components: { VcBreadcrumbs },
15
+ setup() {
16
+ return { args };
17
+ },
18
+ template: '<vc-breadcrumbs v-bind="args"></vc-breadcrumbs>',
19
+ });
20
+
21
+ export const Breadcrumbs = Template.bind({});
22
+ Breadcrumbs.storyName = "vc-breadcrumbs";
23
+ Breadcrumbs.args = {
24
+ items: [
25
+ {
26
+ id: 0,
27
+ title: "Back",
28
+ icon: "fas fa-arrow-left",
29
+ },
30
+ {
31
+ id: 1,
32
+ title: "Electronics",
33
+ },
34
+ {
35
+ id: 2,
36
+ title: "Desktop",
37
+ },
38
+ ],
39
+ };
@@ -0,0 +1,21 @@
1
+ <template>
2
+ <div v-if="items" class= "tw-flex tw-items-center tw-flex-nowrap">
3
+ <VcBreadcrumbsItem
4
+ v-for="(item, i) in items"
5
+ :key="item.id"
6
+ v-bind="item"
7
+ :current="i === items.length - 1"
8
+ />
9
+ </div>
10
+ </template>
11
+
12
+ <script lang="ts" setup>
13
+ import VcBreadcrumbsItem from "./_internal/vc-breadcrumbs-item/vc-breadcrumbs-item.vue";
14
+
15
+ defineProps({
16
+ items: {
17
+ type: Array,
18
+ default: () => [],
19
+ },
20
+ });
21
+ </script>