vueless 1.0.2-beta.2 → 1.0.2-beta.20

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 (138) hide show
  1. package/README.md +3 -1
  2. package/composables/useUI.ts +1 -2
  3. package/icons/internal/home.svg +1 -0
  4. package/icons/storybook/account_balance.svg +1 -0
  5. package/icons/storybook/credit_card.svg +1 -0
  6. package/icons/storybook/description.svg +1 -0
  7. package/icons/storybook/directions_bike.svg +1 -0
  8. package/icons/storybook/directions_car.svg +1 -0
  9. package/icons/storybook/done_all.svg +1 -0
  10. package/icons/storybook/east.svg +1 -0
  11. package/icons/storybook/handyman.svg +1 -0
  12. package/icons/storybook/phone_iphone.svg +1 -0
  13. package/icons/storybook/question_mark.svg +1 -0
  14. package/icons/storybook/schedule.svg +1 -0
  15. package/icons/storybook/straighten.svg +1 -0
  16. package/icons/storybook/trending_up.svg +1 -0
  17. package/package.json +4 -4
  18. package/ui.boilerplate/UBoilerplate.vue +1 -1
  19. package/ui.boilerplate/tests/UBoilerplate.test.ts +60 -0
  20. package/ui.button/tests/UButton.test.ts +2 -1
  21. package/ui.container-accordion/tests/UAccordion.test.ts +248 -0
  22. package/ui.container-card/tests/UCard.test.ts +229 -0
  23. package/ui.container-col/tests/UCol.test.ts +192 -0
  24. package/ui.container-divider/tests/UDivider.test.ts +250 -0
  25. package/ui.container-group/tests/UGroup.test.ts +204 -0
  26. package/ui.container-groups/tests/UGroups.test.ts +75 -0
  27. package/ui.container-modal/tests/UModal.test.ts +640 -0
  28. package/ui.container-modal-confirm/tests/UModalConfirm.test.ts +506 -0
  29. package/ui.container-page/tests/UPage.test.ts +331 -0
  30. package/ui.container-row/tests/URow.test.ts +190 -0
  31. package/ui.data-table/UTable.vue +1 -1
  32. package/ui.data-table/config.ts +3 -2
  33. package/ui.dropdown-badge/UDropdownBadge.vue +7 -1
  34. package/ui.dropdown-badge/config.ts +3 -12
  35. package/ui.dropdown-badge/tests/UDropdownBadge.test.ts +421 -0
  36. package/ui.dropdown-button/UDropdownButton.vue +7 -1
  37. package/ui.dropdown-button/config.ts +4 -10
  38. package/ui.dropdown-button/tests/UDropdownButton.test.ts +449 -0
  39. package/ui.dropdown-link/UDropdownLink.vue +7 -1
  40. package/ui.dropdown-link/config.ts +6 -12
  41. package/ui.dropdown-link/storybook/stories.ts +6 -2
  42. package/ui.dropdown-link/tests/UDropdownLink.test.ts +454 -0
  43. package/ui.form-calendar/UCalendar.vue +22 -3
  44. package/ui.form-calendar/UCalendarDayView.vue +23 -57
  45. package/ui.form-calendar/config.ts +0 -2
  46. package/ui.form-color-picker/UColorPicker.vue +4 -3
  47. package/ui.form-date-picker/UDatePicker.vue +4 -1
  48. package/ui.form-date-picker/storybook/stories.ts +1 -0
  49. package/ui.form-date-picker-range/UDatePickerRange.vue +19 -8
  50. package/ui.form-date-picker-range/UDatePickerRangeInputs.vue +6 -2
  51. package/ui.form-date-picker-range/storybook/stories.ts +1 -0
  52. package/ui.form-input/storybook/stories.ts +35 -8
  53. package/ui.form-input-file/UInputFile.vue +3 -2
  54. package/ui.form-input-file/storybook/stories.ts +25 -9
  55. package/ui.form-input-number/storybook/stories.ts +38 -8
  56. package/ui.form-input-password/storybook/stories.ts +27 -6
  57. package/ui.form-input-rating/storybook/stories.ts +15 -3
  58. package/ui.form-input-search/storybook/stories.ts +39 -14
  59. package/ui.form-label/ULabel.vue +7 -4
  60. package/ui.form-label/config.ts +5 -3
  61. package/ui.form-listbox/UListbox.vue +15 -17
  62. package/ui.form-listbox/config.ts +14 -8
  63. package/ui.form-select/USelect.vue +56 -20
  64. package/ui.form-select/config.ts +1 -0
  65. package/ui.form-select/storybook/assets/images/alex-johnson.png +0 -0
  66. package/ui.form-select/storybook/assets/images/emily-davis.png +0 -0
  67. package/ui.form-select/storybook/assets/images/john-doe.png +0 -0
  68. package/ui.form-select/storybook/assets/images/pat-morgan.png +0 -0
  69. package/ui.form-select/storybook/stories.ts +333 -115
  70. package/ui.form-select/types.ts +5 -0
  71. package/ui.form-textarea/storybook/stories.ts +5 -10
  72. package/ui.image-avatar/tests/UAvatar.test.ts +240 -0
  73. package/ui.image-icon/UIcon.vue +1 -0
  74. package/ui.image-icon/tests/UIcon.test.ts +234 -0
  75. package/ui.loader/tests/ULoader.test.ts +146 -0
  76. package/ui.loader-overlay/tests/ULoaderOverlay.test.ts +168 -0
  77. package/ui.loader-progress/ULoaderProgress.vue +38 -2
  78. package/ui.loader-progress/tests/ULoaderProgress.test.ts +165 -0
  79. package/ui.loader-progress/types.ts +6 -0
  80. package/ui.loader-progress/useLoaderProgress.ts +18 -34
  81. package/ui.navigation-breadcrumbs/UBreadcrumbs.vue +1 -1
  82. package/ui.navigation-breadcrumbs/tests/UBreadcrumbs.test.ts +417 -0
  83. package/ui.navigation-pagination/tests/UPagination.test.ts +442 -0
  84. package/ui.navigation-progress/UProgress.vue +8 -3
  85. package/ui.navigation-progress/tests/UProgress.test.ts +250 -0
  86. package/ui.navigation-tab/tests/UTab.test.ts +486 -0
  87. package/ui.navigation-tabs/tests/UTabs.test.ts +339 -0
  88. package/ui.other-chip/UChip.vue +2 -2
  89. package/ui.other-chip/tests/UChip.test.ts +254 -0
  90. package/ui.other-dot/tests/UDot.test.ts +86 -0
  91. package/ui.other-theme-color-toggle/UThemeColorToggle.vue +10 -3
  92. package/ui.other-theme-color-toggle/tests/UThemeColorToggle.test.ts +249 -0
  93. package/ui.skeleton/USkeleton.vue +1 -0
  94. package/ui.skeleton/tests/USkeleton.test.ts +61 -0
  95. package/ui.skeleton-choice/USkeletonChoice.vue +1 -0
  96. package/ui.skeleton-choice/config.ts +15 -19
  97. package/ui.skeleton-choice/tests/USkeletonChoice.test.ts +194 -0
  98. package/ui.skeleton-input/USkeletonInput.vue +10 -2
  99. package/ui.skeleton-input/config.ts +36 -46
  100. package/ui.skeleton-input/storybook/stories.ts +15 -17
  101. package/ui.skeleton-input/tests/USkeletonInput.test.ts +256 -0
  102. package/ui.skeleton-text/tests/USkeletonText.test.ts +130 -0
  103. package/ui.text-alert/UAlert.vue +2 -2
  104. package/ui.text-alert/storybook/stories.ts +71 -29
  105. package/ui.text-alert/tests/UAlert.test.ts +331 -0
  106. package/ui.text-badge/UBadge.vue +3 -1
  107. package/ui.text-badge/storybook/stories.ts +13 -24
  108. package/ui.text-badge/types.ts +5 -0
  109. package/ui.text-block/UText.vue +4 -4
  110. package/ui.text-block/config.ts +22 -1
  111. package/ui.text-block/storybook/stories.ts +71 -34
  112. package/ui.text-block/tests/UText.test.ts +74 -11
  113. package/ui.text-block/types.ts +28 -2
  114. package/ui.text-file/UFile.vue +1 -1
  115. package/ui.text-file/storybook/stories.ts +4 -4
  116. package/ui.text-file/tests/UFile.test.ts +257 -0
  117. package/ui.text-files/UFiles.vue +20 -21
  118. package/ui.text-files/storybook/stories.ts +2 -2
  119. package/ui.text-files/tests/UFiles.test.ts +325 -0
  120. package/ui.text-header/UHeader.vue +1 -0
  121. package/ui.text-header/config.ts +18 -2
  122. package/ui.text-header/storybook/stories.ts +4 -8
  123. package/ui.text-header/tests/UHeader.test.ts +25 -1
  124. package/ui.text-header/types.ts +7 -1
  125. package/ui.text-notify/storybook/docs.mdx +16 -16
  126. package/ui.text-notify/storybook/stories.ts +37 -47
  127. package/ui.text-notify/tests/UNotify.test.ts +276 -0
  128. package/ui.text-number/storybook/stories.ts +19 -45
  129. package/ui.text-number/tests/UNumber.test.ts +351 -0
  130. package/utils/helper.ts +12 -1
  131. package/utils/node/helper.js +4 -1
  132. package/utils/node/loaderIcon.js +1 -1
  133. package/utils/node/vuelessConfig.js +4 -1
  134. package/utils/storybook.ts +5 -1
  135. package/utils/theme.ts +35 -32
  136. package/icons/storybook/heart_plus.svg +0 -1
  137. package/icons/storybook/label.svg +0 -1
  138. package/icons/storybook/warning.svg +0 -1
package/README.md CHANGED
@@ -13,6 +13,7 @@ Vueless is simple enough for everyday use and powerful enough for advanced scena
13
13
  ### Key features
14
14
 
15
15
  - 🧩 65+ UI components (including range date picker, multi-selects, and nested table)
16
+ - 🪄 Automatic on-demand component import (as you use them)
16
17
  - 📘 Built-in Storybook support
17
18
  - 🌈 Beautiful, modern default UI theme
18
19
  - 🌗 Light and dark mode support
@@ -66,12 +67,13 @@ createApp(App).use(vueless).mount('#app');
66
67
  4. Add Vite plugins.
67
68
 
68
69
  ```javascript
69
- import { Vueless, UnpluginComponents } from "vueless/plugin-vite";
70
+ import { Vueless, TailwindCSS, UnpluginComponents } from "vueless/plugin-vite";
70
71
 
71
72
  export default defineConfig({
72
73
  plugins: [
73
74
  ...
74
75
  Vueless(),
76
+ TailwindCSS(),
75
77
  UnpluginComponents(),
76
78
  ],
77
79
  ...
@@ -2,7 +2,6 @@ import { ref, watch, getCurrentInstance, toValue, useAttrs, computed } from "vue
2
2
  import { isEqual } from "lodash-es";
3
3
 
4
4
  import { cx, cva, setColor, vuelessConfig, getMergedConfig } from "../utils/ui.ts";
5
- import { isCSR } from "../utils/helper.ts";
6
5
  import {
7
6
  CVA_CONFIG_KEY,
8
7
  SYSTEM_CONFIG_KEY,
@@ -141,7 +140,7 @@ export default function useUI<T>(
141
140
  keyConfig = config.value[configKey] as NestedComponent;
142
141
  }
143
142
 
144
- const isDev = isCSR && import.meta.env?.DEV;
143
+ const isDev = import.meta.env?.DEV;
145
144
  const isTopLevelKey = (topLevelClassKey || firstClassKey) === configKey;
146
145
 
147
146
  const extendsClasses = getExtendsClasses(configKey);
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M222.15-182.15h143.78v-251.92h228.14v251.92h143.78v-386.89L480-762.37 222.15-568.96v386.81Zm-68.13 68.13v-489.09L480-847.65l326.22 244.54v489.09H528.57v-254.55h-97.14v254.55H154.02ZM480-472.76Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M206.5-239.09v-339H272v339h-65.5Zm244.87 0v-339h65.26v339h-65.26ZM74.02-116.46v-68.13h812.2v68.13H74.02ZM688-239.09v-339h65.5v339H688ZM74.02-632.59v-63.04L480-926.5l406.22 230.87v63.04H74.02Zm149.31-68.37h513.34-513.34Zm0 0h513.34L480-848.17 223.33-700.96Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M886.22-737.85v515.7q0 27.6-20.34 47.86-20.33 20.27-48.03 20.27h-675.7q-27.6 0-47.86-20.27-20.27-20.26-20.27-47.86v-515.7q0-27.7 20.27-48.03 20.26-20.34 47.86-20.34h675.7q27.7 0 48.03 20.34 20.34 20.33 20.34 48.03ZM142.15-631.48h675.7v-106.37h-675.7v106.37Zm0 129v280.33h675.7v-280.33h-675.7Zm0 280.33v-515.7 515.7Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M319-249.52h322v-62.63H319v62.63Zm0-170h322v-62.63H319v62.63Zm-96.85 345.5q-27.6 0-47.86-20.27-20.27-20.26-20.27-47.86v-675.7q0-27.7 20.27-48.03 20.26-20.34 47.86-20.34h361.48l222.59 222.59v521.48q0 27.6-20.34 47.86-20.33 20.27-48.03 20.27h-515.7Zm326.7-557.83v-186h-326.7v675.7h515.7v-489.7h-189Zm-326.7-186v186-186 675.7-675.7Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M193.44-74.02q-80.29 0-136.86-56.41Q0-186.84 0-267.24q0-80.39 56.55-136.91 56.55-56.52 136.78-56.52 80.52 0 137.04 56.55 56.52 56.55 56.52 136.78 0 80.51-56.58 136.92-56.59 56.4-136.87 56.4Zm-.09-66.46q53.63 0 90.36-36.59 36.72-36.58 36.72-90.14 0-53.55-36.68-90.28-36.69-36.73-90.31-36.73-53.63 0-90.3 36.64-36.68 36.64-36.68 90.26 0 53.62 36.63 90.23 36.64 36.61 90.26 36.61Zm253.54-55.24v-201.67l-133.8-118.28q-11.48-9.48-16.84-22.86-5.36-13.37-5.36-28.13 0-14.54 5.74-27.31t15.98-23.25l120.9-120.66q11.01-11.01 24.91-16.49 13.9-5.48 29.15-5.48 15.63 0 29.84 5.24 14.22 5.24 25.46 16.48l79.02 79.02q29.46 29.46 67.09 47.22 37.64 17.76 79.45 17.76v66.46q-55.61 0-105.78-22.12t-89.41-61.36l-38.81-38.81L426.3-540.83l87.05 93.57v251.54h-66.46Zm175.54-557.32q-30.8 0-52.78-21.82t-21.98-52.82q0-30.99 21.9-52.97t52.82-21.98q30.91 0 52.89 21.87t21.98 52.93q0 31.07-21.88 52.93-21.87 21.86-52.95 21.86ZM766.67-74.02q-80.52 0-136.92-56.41-56.4-56.41-56.4-136.81 0-80.39 56.41-136.91 56.41-56.52 136.8-56.52 80.4 0 136.92 56.55Q960-347.57 960-267.34q0 80.51-56.55 136.92-56.55 56.4-136.78 56.4Zm-.14-66.46q53.56 0 90.29-36.59 36.72-36.58 36.72-90.14 0-53.55-36.63-90.28-36.64-36.73-90.26-36.73-53.63 0-90.24 36.64-36.61 36.64-36.61 90.26 0 53.62 36.59 90.23 36.59 36.61 90.14 36.61Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M200.48-198.02v48.5q0 15.09-10.42 25.29-10.42 10.21-25.56 10.21H150q-15.14 0-25.56-10.42-10.42-10.42-10.42-25.56v-325.26l85.24-256.65q5.48-15.92 18.61-25.11 13.13-9.2 30.13-9.2h464q17 0 30.13 9.2 13.13 9.19 18.61 25.11l85.48 256.65V-150q0 15.14-10.59 25.56-10.58 10.42-25.63 10.42h-15.5q-15.39 0-25.18-10.21-9.8-10.2-9.8-25.29v-48.5H200.48ZM205.63-534h548.98l-54.28-163.85H259.67L205.63-534Zm-23.48 60v207.85V-474Zm104.81 158.8q23 0 38.62-15.75 15.62-15.75 15.62-38.25 0-23.33-15.87-39.66-15.87-16.34-38.13-16.34-23.58 0-39.79 16.27-16.21 16.26-16.21 39.5 0 23.23 16.14 38.73 16.15 15.5 39.62 15.5Zm387.08 0q23.34 0 39.67-15.75 16.33-15.75 16.33-38.25 0-23.33-16.26-39.66-16.27-16.34-39.5-16.34-23.24 0-38.74 16.27-15.5 16.26-15.5 39.5 0 23.23 15.75 38.73 15.75 15.5 38.25 15.5Zm-491.89 49.05h595.7V-474h-595.7v207.85Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M294.24-230.52 64.5-460.26 113-509l181 181 48.74 48.74-48.5 48.74ZM464-236.26 234.02-466.48l48.98-48.5 181 181L847.76-717.5l48.98 48.5L464-236.26Zm0-175.98-48.5-48.74 257-257 48.5 48.74-257 257Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="m600-193.78-47.74-47.98 204.41-204.17H74.26v-68.14h682.41L552.02-718.48 600-766.22 886.22-480 600-193.78Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M771.65-67.33q-6.72 0-12.55-2.35-5.84-2.36-11.32-7.84L502.2-323.11q-5.48-5.48-7.84-11.31-2.36-5.84-2.36-12.56 0-6.72 2.36-12.67 2.36-5.96 7.84-11.44l85.47-85.48q5.48-5.47 11.32-7.95 5.84-2.48 12.79-2.48 6.72 0 12.56 2.48 5.83 2.48 11.31 7.95l245.59 245.83q5.48 5.48 7.96 11.2 2.47 5.71 2.47 12.67 0 6.72-2.59 12.67-2.6 5.96-7.84 11.2l-85.48 85.48q-5.48 5.48-11.31 7.84-5.84 2.35-12.8 2.35Zm.24-77.97 41.57-41.57-201.92-202.15-41.56 41.56L771.89-145.3Zm-584.3 77.74q-6.72 0-13.06-2.24-6.33-2.24-11.81-7.72L78.24-162q-5.48-5.24-7.72-11.46-2.24-6.21-2.24-13.17 0-6.72 2.24-12.67 2.24-5.96 7.72-11.44L308.74-441h87.15l37.28-37.28L255.3-656.15h-58.43L66.85-786.17l104.5-104.5 130.02 130.02v58.43l177.87 177.87 130.72-130.72-68.2-68.19 56-55.76h-113l-20.15-20.39 134.22-134.46 20.39 20.63v112.76l56-56 174.02 174.26q15.48 15.72 24.46 35.94 8.97 20.21 8.97 42.93 0 21.44-7.45 41.25-7.46 19.82-20.42 35.77l-87.15-87.15-57.43 57.44-53.2-53.2-215.06 215.07v86.39L211.46-77.52q-5.48 5.48-11.2 7.72-5.72 2.24-12.67 2.24Zm0-77.74 202.39-202.16v-41.56h-41.57L146.02-186.87l41.57 41.57Zm0 0-41.57-41.57 21.28 20.28 20.29 21.29Zm584.3 0 41.57-41.57-41.57 41.57Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M262.39-34.02q-28.45 0-48.41-19.89-19.96-19.89-19.96-48.24v-755.7q0-27.7 20.34-48.03 20.33-20.34 48.03-20.34h433.22q28.45 0 48.41 19.96 19.96 19.96 19.96 48.41v144.65q18 4.05 30.12 18.6 12.12 14.55 12.12 32.7v73.7q0 19.48-12.12 34.2-12.12 14.72-30.12 18.69v433.16q0 28.35-19.96 48.24t-48.41 19.89H262.39Zm-.24-67.89h433.7v-756.18h-433.7v756.18Zm0 0v-756.18 756.18Zm110.48-83.59h212.98q14.37 0 24.1-9.87 9.72-9.87 9.72-24.55 0-14.68-9.65-24.19-9.66-9.52-24.17-9.52H372.63q-14.48 0-24.27 9.87t-9.79 24.41q0 14.53 9.82 24.19 9.82 9.66 24.24 9.66Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M428.13-330.96q1-75.58 17.46-110.74 16.45-35.15 60.17-72.95 41.28-36.33 62.83-68.26 21.54-31.92 21.54-68.63 0-43.57-28.92-72.49-28.93-28.93-80.54-28.93-50.56 0-78.8 28.67-28.24 28.66-41.48 62.81l-92.61-40.59q23.2-62.58 77.49-105.28 54.3-42.69 135.35-42.69 102.2 0 157.4 57.09t55.2 137.65q0 50.87-20.62 91.42-20.62 40.55-65.86 82.84-48.28 45.32-58.52 70.44-10.24 25.12-11 79.64H428.13ZM480.62-73.3q-31.34 0-53.39-22.06-22.06-22.05-22.06-53.32t22.04-53.33q22.03-22.06 53.44-22.06 31.42 0 53.47 22.06 22.05 22.06 22.05 53.33t-22.1 53.32Q511.96-73.3 480.62-73.3Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="m624.37-286.04 49.06-48.59-157.8-158.86v-198.55h-65.26v224.89l174 181.11ZM480.03-74.02q-83.46 0-157.51-31.95-74.05-31.94-129.32-87.21-55.28-55.26-87.23-129.3-31.95-74.03-31.95-157.49 0-83.46 32-157.54 32-74.07 87.2-129.27 55.2-55.2 129.25-87.32 74.05-32.12 157.53-32.12t157.53 32.12q74.05 32.12 129.25 87.32 55.2 55.2 87.32 129.25 32.12 74.05 32.12 157.53T854.1-322.47q-32.12 74.05-87.32 129.25-55.2 55.2-129.24 87.2t-157.51 32ZM480-480Zm-.12 337.85q139.16 0 238.57-99.17 99.4-99.16 99.4-238.56t-99.37-238.69Q619.11-817.85 480-817.85q-139.28 0-238.57 99.26-99.28 99.25-99.28 238.59 0 139.52 99.28 238.68 99.28 99.17 238.45 99.17Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M142.63-235.46q-27.6 0-47.86-20.33-20.27-20.34-20.27-48.04v-352.34q0-26.7 20.27-47.54 20.26-20.83 47.86-20.83h674.74q27.6 0 47.86 20.83 20.27 20.84 20.27 47.54v352.34q0 27.7-20.27 48.04-20.26 20.33-47.86 20.33H142.63Zm0-68.37h674.74v-352.34H690V-480h-60v-176.17H510V-480h-60v-176.17H330V-480h-60v-176.17H142.63v352.34ZM270-480h60-60Zm180 0h60-60Zm180 0h60-60Zm-150 0Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="m122.76-234.74-48.74-48.74 298.94-297.69 167 167 231.91-232.4H647.02v-68.36h239.2v239.19h-67.37v-121.09L538.96-316.7l-167-167-249.2 248.96Z"/></svg>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vueless",
3
- "version": "1.0.2-beta.2",
3
+ "version": "1.0.2-beta.20",
4
4
  "license": "MIT",
5
5
  "description": "Vue Styleless UI Component Library, powered by Tailwind CSS.",
6
6
  "keywords": [
@@ -30,13 +30,13 @@
30
30
  "scripts": {
31
31
  "pre:start": "npx node .scripts/icons",
32
32
  "dev:docs": "storybook dev -p 6006 --docs --no-open",
33
- "dev": "STORYBOOK_FULL=1 storybook dev -p 6006 --no-open",
33
+ "dev": "storybook dev -p 6006 --no-open",
34
34
  "build": "storybook build --docs",
35
35
  "preview": "vite preview --host --outDir=storybook-static",
36
36
  "ts:check": "vue-tsc --build --force",
37
37
  "release:prepare": "npm run pre:start && rm -rf dist && mkdir -p dist && cp -r src/. package.json LICENSE README.md dist/ && npx node .scripts/writeLocales",
38
38
  "release:beta": "release-it --ci --npm.publish --preRelease=beta --increment=prerelease",
39
- "release:patch": "release-it patch --ci --npm.publish",
39
+ "release:patch": "release-it patch --ci --npm.publish --git.tag --github.release",
40
40
  "release:minor": "release-it minor --ci --npm.publish --git.tag --github.release",
41
41
  "release:major": "release-it major --ci --npm.publish --git.tag --github.release",
42
42
  "lint": "eslint --no-fix src/ .storybook/",
@@ -75,7 +75,7 @@
75
75
  "@vue/eslint-config-typescript": "^14.5.0",
76
76
  "@vue/test-utils": "^2.4.6",
77
77
  "@vue/tsconfig": "^0.7.0",
78
- "@vueless/storybook": "^1.0.0",
78
+ "@vueless/storybook": "^1.0.1-beta.1",
79
79
  "eslint": "^9.27.0",
80
80
  "eslint-plugin-storybook": "^0.12.0",
81
81
  "eslint-plugin-vue": "^10.1.0",
@@ -35,5 +35,5 @@ const { wrapperAttrs } = useUI<Config>(defaultConfig, mutatedProps);
35
35
  </script>
36
36
 
37
37
  <template>
38
- <div v-bind="wrapperAttrs">Boilerplate</div>
38
+ <div v-bind="wrapperAttrs" :data-test="dataTest">Boilerplate</div>
39
39
  </template>
@@ -0,0 +1,60 @@
1
+ import { mount } from "@vue/test-utils";
2
+ import { describe, it, expect } from "vitest";
3
+
4
+ import UBoilerplate from "../UBoilerplate.vue";
5
+ import defaultConfig from "../config.ts";
6
+
7
+ describe("UBoilerplate.vue", () => {
8
+ // Props tests
9
+ describe("Props", () => {
10
+ // DataTest prop
11
+ it("accepts the dataTest prop", () => {
12
+ const dataTest = "test-boilerplate";
13
+
14
+ const component = mount(UBoilerplate, {
15
+ props: {
16
+ dataTest,
17
+ },
18
+ });
19
+
20
+ expect(component.attributes("data-test")).toBe(dataTest);
21
+ });
22
+
23
+ // Config prop
24
+ it("applies custom config when provided", () => {
25
+ const customClass = "custom-class";
26
+ const config = {
27
+ wrapper: customClass,
28
+ };
29
+
30
+ const component = mount(UBoilerplate, {
31
+ props: {
32
+ config,
33
+ },
34
+ });
35
+
36
+ expect(component.attributes("class")).toContain(customClass);
37
+ // The default config is merged with the custom config, not replaced
38
+ expect(component.attributes("class")).toContain(defaultConfig.wrapper);
39
+ });
40
+ });
41
+
42
+ /*
43
+ // Slots tests
44
+ describe("Slots", () => {
45
+ // Default slot
46
+ it("renders content from default slot", () => {
47
+ const slotContent = "Custom Content";
48
+
49
+ const component = mount(UBoilerplate, {
50
+ slots: {
51
+ default: slotContent,
52
+ },
53
+ });
54
+
55
+ expect(component.text()).not.toBe("Boilerplate");
56
+ expect(component.text()).toBe(slotContent);
57
+ });
58
+ });
59
+ */
60
+ });
@@ -12,6 +12,7 @@ describe("UButton.vue", () => {
12
12
  describe("Props", () => {
13
13
  // Variant prop
14
14
  it("applies the correct variant class", async () => {
15
+ const color = "primary";
15
16
  const variants = {
16
17
  solid: "text-inverted bg-primary",
17
18
  outlined: "text-primary border-primary",
@@ -24,7 +25,7 @@ describe("UButton.vue", () => {
24
25
  const component = mount(UButton, {
25
26
  props: {
26
27
  variant: variant as Props["variant"],
27
- color: "primary",
28
+ color,
28
29
  },
29
30
  });
30
31
 
@@ -0,0 +1,248 @@
1
+ import { mount } from "@vue/test-utils";
2
+ import { describe, it, expect } from "vitest";
3
+
4
+ import UAccordion from "../UAccordion.vue";
5
+ import UIcon from "../../ui.image-icon/UIcon.vue";
6
+
7
+ import type { Props } from "../types.ts";
8
+
9
+ describe("UAccordion", () => {
10
+ // Props
11
+ describe("Props", () => {
12
+ // Title prop
13
+ it("renders with title prop", () => {
14
+ const title = "Accordion Title";
15
+
16
+ const component = mount(UAccordion, {
17
+ props: {
18
+ title,
19
+ },
20
+ });
21
+
22
+ expect(component.find("[vl-key='title']").text()).toContain(title);
23
+ });
24
+
25
+ // Description prop
26
+ it("renders with description prop", () => {
27
+ const description = "Accordion Description";
28
+
29
+ const component = mount(UAccordion, {
30
+ props: {
31
+ description,
32
+ },
33
+ });
34
+
35
+ expect(component.find("[vl-key='description']").text()).toBe(description);
36
+ });
37
+
38
+ // Size prop
39
+ it("applies correct size classes", () => {
40
+ const sizeClasses = {
41
+ sm: "text-small",
42
+ md: "text-medium",
43
+ lg: "text-large",
44
+ };
45
+
46
+ Object.entries(sizeClasses).forEach(([size, classes]) => {
47
+ const component = mount(UAccordion, {
48
+ props: {
49
+ size: size as Props["size"],
50
+ },
51
+ });
52
+
53
+ expect(component.find("[vl-key='title']").classes()).toContain(classes);
54
+ });
55
+ });
56
+
57
+ // ToggleIcon prop
58
+ it("applies correct toggle icon behavior", () => {
59
+ const toggleIconTests = [
60
+ { toggleIcon: true, exists: true, iconName: "keyboard_arrow_down" },
61
+ { toggleIcon: "custom_icon", exists: true, iconName: "custom_icon" },
62
+ { toggleIcon: false, exists: false, iconName: undefined },
63
+ ];
64
+
65
+ toggleIconTests.forEach(({ toggleIcon, exists, iconName }) => {
66
+ const component = mount(UAccordion, {
67
+ props: {
68
+ toggleIcon: toggleIcon as Props["toggleIcon"],
69
+ },
70
+ });
71
+
72
+ const icon = component.findComponent(UIcon);
73
+
74
+ expect(icon.exists()).toBe(exists);
75
+
76
+ if (exists) {
77
+ expect(icon.props("name")).toBe(iconName);
78
+ }
79
+ });
80
+ });
81
+
82
+ // ID prop
83
+ it("uses provided id prop", () => {
84
+ const id = "custom-id";
85
+
86
+ const component = mount(UAccordion, {
87
+ props: {
88
+ id,
89
+ },
90
+ });
91
+
92
+ expect(component.find(`[id="description-${id}"]`).exists()).toBe(true);
93
+ });
94
+
95
+ // DataTest prop
96
+ it("applies data-test attribute", () => {
97
+ const dataTest = "accordion-test";
98
+
99
+ const component = mount(UAccordion, {
100
+ props: {
101
+ dataTest,
102
+ },
103
+ });
104
+
105
+ expect(component.attributes("data-test")).toBe(dataTest);
106
+ });
107
+ });
108
+
109
+ // Slots
110
+ describe("Slots", () => {
111
+ // Toggle slot
112
+ it("renders default toggle icon when toggle slot is not provided", () => {
113
+ const toggleIcon = true;
114
+
115
+ const component = mount(UAccordion, {
116
+ props: {
117
+ toggleIcon,
118
+ },
119
+ });
120
+
121
+ const icon = component.findComponent(UIcon);
122
+
123
+ expect(icon.exists()).toBe(true);
124
+ });
125
+
126
+ // Custom toggle slot
127
+ it("renders custom content in toggle slot", () => {
128
+ const toggleIcon = true;
129
+ const slotClass = "custom-toggle";
130
+ const slotContent = "Custom Toggle";
131
+
132
+ const component = mount(UAccordion, {
133
+ props: {
134
+ toggleIcon,
135
+ },
136
+ slots: {
137
+ toggle: `<div class="${slotClass}">${slotContent}</div>`,
138
+ },
139
+ });
140
+
141
+ expect(component.find(`.${slotClass}`).exists()).toBe(true);
142
+ expect(component.find(`.${slotClass}`).text()).toBe(slotContent);
143
+ expect(component.findComponent(UIcon).exists()).toBe(false);
144
+ });
145
+
146
+ // Toggle slot bindings
147
+ it("provides icon-name and opened bindings to toggle slot", async () => {
148
+ const toggleIcon = true;
149
+ const toggleClass = "custom-toggle";
150
+ const defaultIconName = "keyboard_arrow_down";
151
+
152
+ const component = mount(UAccordion, {
153
+ props: {
154
+ toggleIcon,
155
+ },
156
+ slots: {
157
+ toggle: `
158
+ <template #default="{ iconName, opened }">
159
+ <div class="${toggleClass}" :data-icon="iconName" :data-opened="opened"></div>
160
+ </template>
161
+ `,
162
+ },
163
+ });
164
+
165
+ const toggleElement = component.find(`.${toggleClass}`);
166
+
167
+ expect(toggleElement.exists()).toBe(true);
168
+ expect(toggleElement.attributes("data-icon")).toBe(defaultIconName);
169
+ expect(toggleElement.attributes("data-opened")).toBe("false");
170
+
171
+ // Click to toggle
172
+ await component.trigger("click");
173
+
174
+ expect(toggleElement.attributes("data-opened")).toBe("true");
175
+ });
176
+ });
177
+
178
+ // Events
179
+ describe("Events", () => {
180
+ // Click event
181
+ it("emits click event with id and opened state when clicked", async () => {
182
+ const id = "test-id";
183
+
184
+ const component = mount(UAccordion, {
185
+ props: {
186
+ id,
187
+ },
188
+ });
189
+
190
+ await component.trigger("click");
191
+
192
+ const emitted = component.emitted("click");
193
+
194
+ expect(emitted).toBeTruthy();
195
+ expect(emitted?.[0]).toEqual([id, true]);
196
+
197
+ // Click again to toggle back
198
+ await component.trigger("click");
199
+
200
+ const emittedAgain = component.emitted("click");
201
+
202
+ expect(emittedAgain?.[1]).toEqual([id, false]);
203
+ });
204
+ });
205
+
206
+ // Exposed refs
207
+ describe("Exposed refs", () => {
208
+ // WrapperRef
209
+ it("exposes wrapperRef", () => {
210
+ const component = mount(UAccordion);
211
+
212
+ expect(component.vm.wrapperRef).toBeDefined();
213
+ expect(component.vm.wrapperRef instanceof HTMLDivElement).toBe(true);
214
+ });
215
+ });
216
+
217
+ // Component behavior
218
+ describe("Component behavior", () => {
219
+ // Toggle behavior
220
+ it("toggles opened state when clicked", async () => {
221
+ const description = "Test Description";
222
+ const openedClass = "opacity-100";
223
+
224
+ const component = mount(UAccordion, {
225
+ props: {
226
+ description,
227
+ },
228
+ });
229
+
230
+ const descriptionElement = component.find("[id^='description-']");
231
+
232
+ // Initially not opened
233
+ expect(descriptionElement.classes()).not.toContain(openedClass);
234
+
235
+ // Click to open
236
+ await component.trigger("click");
237
+
238
+ // Should be opened
239
+ expect(descriptionElement.classes()).toContain(openedClass);
240
+
241
+ // Click to close
242
+ await component.trigger("click");
243
+
244
+ // Should be closed again
245
+ expect(descriptionElement.classes()).not.toContain(openedClass);
246
+ });
247
+ });
248
+ });