@indielayer/ui 1.0.0-alpha.7 → 1.0.0

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 (209) hide show
  1. package/README.md +6 -3
  2. package/lib/index.cjs.js +1 -15
  3. package/lib/index.es.js +4453 -3651
  4. package/lib/nuxt.js +2 -1
  5. package/package.json +16 -6
  6. package/src/common/icons.ts +15 -0
  7. package/src/common/utils.ts +68 -0
  8. package/src/components/alert/Alert.theme.ts +57 -0
  9. package/src/components/alert/Alert.vue +51 -127
  10. package/src/components/alert/__tests__/Alert.spec.ts +14 -0
  11. package/src/components/avatar/Avatar.theme.ts +39 -0
  12. package/src/components/avatar/Avatar.vue +58 -96
  13. package/src/components/avatar/__tests__/Avatar.spec.ts +11 -0
  14. package/src/components/badge/Badge.theme.ts +13 -0
  15. package/src/components/badge/Badge.vue +58 -65
  16. package/src/components/badge/__tests__/Badge.spec.ts +11 -0
  17. package/src/components/breadcrumbs/Breadcrumbs.theme.ts +9 -0
  18. package/src/components/breadcrumbs/Breadcrumbs.vue +34 -24
  19. package/src/components/breadcrumbs/__tests__/Breadcrumbs.spec.ts +11 -0
  20. package/src/components/button/Button.theme.ts +234 -0
  21. package/src/components/button/Button.vue +94 -356
  22. package/src/components/button/ButtonGroup.theme.ts +5 -0
  23. package/src/components/button/ButtonGroup.vue +30 -29
  24. package/src/components/button/__tests__/ Button.spec.ts +11 -0
  25. package/src/components/button/__tests__/ ButtonGroup.spec.ts +11 -0
  26. package/src/components/card/Card.theme.ts +7 -0
  27. package/src/components/card/Card.vue +18 -11
  28. package/src/components/card/__tests__/Card.spec.ts +11 -0
  29. package/src/components/checkbox/Checkbox.theme.ts +92 -0
  30. package/src/components/checkbox/Checkbox.vue +69 -156
  31. package/src/components/checkbox/__tests__/Checkbox.spec.ts +11 -0
  32. package/src/components/collapse/Collapse.theme.ts +11 -0
  33. package/src/components/collapse/Collapse.vue +99 -118
  34. package/src/components/collapse/__tests__/Collapse.spec.ts +11 -0
  35. package/src/components/container/Container.theme.ts +7 -0
  36. package/src/components/container/Container.vue +17 -9
  37. package/src/components/container/__tests__/Container.spec.ts +11 -0
  38. package/src/components/divider/Divider.theme.ts +11 -0
  39. package/src/components/divider/Divider.vue +22 -18
  40. package/src/components/divider/__tests__/Divider.spec.ts +11 -0
  41. package/src/components/drawer/Drawer.theme.ts +9 -0
  42. package/src/components/drawer/Drawer.vue +160 -177
  43. package/src/components/drawer/__tests__/Drawer.spec.ts +11 -0
  44. package/src/components/form/Form.theme.ts +7 -0
  45. package/src/components/form/Form.vue +90 -73
  46. package/src/components/form/__tests__/Form.spec.ts +11 -0
  47. package/src/components/helpers/InputError.tsx +14 -0
  48. package/src/components/icon/Icon.theme.ts +16 -0
  49. package/src/components/icon/Icon.vue +72 -88
  50. package/src/components/icon/__tests__/Icon.spec.ts +11 -0
  51. package/src/components/image/Image.theme.ts +7 -0
  52. package/src/components/image/Image.vue +22 -23
  53. package/src/components/image/__tests__/Image.spec.ts +11 -0
  54. package/src/components/index.ts +3 -3
  55. package/src/components/input/Input.theme.ts +44 -0
  56. package/src/components/input/Input.vue +97 -130
  57. package/src/components/input/__tests__/Input.spec.ts +11 -0
  58. package/src/components/link/Link.theme.ts +26 -0
  59. package/src/components/link/Link.vue +41 -66
  60. package/src/components/link/__tests__/Link.spec.ts +11 -0
  61. package/src/components/menu/Menu.theme.ts +7 -0
  62. package/src/components/menu/Menu.vue +54 -45
  63. package/src/components/menu/MenuItem.theme.ts +107 -0
  64. package/src/components/menu/MenuItem.vue +97 -199
  65. package/src/components/menu/__tests__/Menu.spec.ts +11 -0
  66. package/src/components/menu/__tests__/MenuItem.spec.ts +11 -0
  67. package/src/components/modal/Modal.theme.ts +29 -0
  68. package/src/components/modal/Modal.vue +78 -101
  69. package/src/components/modal/__tests__/Modal.spec.ts +11 -0
  70. package/src/components/notifications/Notifications.theme.ts +11 -0
  71. package/src/components/notifications/Notifications.vue +233 -247
  72. package/src/components/notifications/__tests__/Notifications.spec.ts +11 -0
  73. package/src/components/pagination/Pagination.theme.ts +27 -0
  74. package/src/components/pagination/Pagination.vue +142 -164
  75. package/src/components/pagination/PaginationItem.theme.ts +14 -0
  76. package/src/components/pagination/PaginationItem.vue +26 -33
  77. package/src/components/pagination/__tests__/Pagination.spec.ts +11 -0
  78. package/src/components/pagination/__tests__/PaginationItem.spec.ts +11 -0
  79. package/src/components/popover/Popover.theme.ts +9 -0
  80. package/src/components/popover/Popover.vue +153 -101
  81. package/src/components/popover/PopoverContainer.theme.ts +7 -0
  82. package/src/components/popover/PopoverContainer.vue +17 -9
  83. package/src/components/popover/__tests__/Popover.spec.ts +11 -0
  84. package/src/components/popover/__tests__/PopoverContainer.spec.ts +11 -0
  85. package/src/components/progress/Progress.theme.ts +26 -0
  86. package/src/components/progress/Progress.vue +29 -53
  87. package/src/components/progress/__tests__/Progress.spec.ts +11 -0
  88. package/src/components/radio/Radio.theme.ts +121 -0
  89. package/src/components/radio/Radio.vue +81 -158
  90. package/src/components/radio/__tests__/Radio.spec.ts +11 -0
  91. package/src/components/scroll/Scroll.theme.ts +7 -0
  92. package/src/components/scroll/Scroll.vue +34 -36
  93. package/src/components/scroll/__tests__/Scroll.spec.ts +11 -0
  94. package/src/components/select/Select.theme.ts +54 -0
  95. package/src/components/select/Select.vue +219 -273
  96. package/src/components/select/__tests__/Select.spec.ts +11 -0
  97. package/src/components/skeleton/Skeleton.theme.ts +7 -0
  98. package/src/components/skeleton/Skeleton.vue +17 -9
  99. package/src/components/skeleton/__tests__/Skeleton.spec.ts +11 -0
  100. package/src/components/slider/Slider.theme.ts +30 -0
  101. package/src/components/slider/Slider.vue +135 -168
  102. package/src/components/slider/__tests__/Slider.spec.ts +11 -0
  103. package/src/components/spacer/{Spacer.vue → Spacer.tsx} +3 -6
  104. package/src/components/spacer/__tests__/Spacer.spec.ts +11 -0
  105. package/src/components/spinner/Spinner.vue +10 -34
  106. package/src/components/spinner/__tests__/Spinner.spec.ts +11 -0
  107. package/src/components/tab/Tab.theme.ts +22 -0
  108. package/src/components/tab/Tab.vue +89 -93
  109. package/src/components/tab/TabGroup.theme.ts +43 -0
  110. package/src/components/tab/TabGroup.vue +94 -127
  111. package/src/components/tab/__tests__/Tab.spec.ts +11 -0
  112. package/src/components/tab/__tests__/TabGroup.spec.ts +11 -0
  113. package/src/components/table/Table.theme.ts +19 -0
  114. package/src/components/table/Table.vue +136 -147
  115. package/src/components/table/{TableBody.vue → TableBody.tsx} +3 -8
  116. package/src/components/table/TableCell.theme.ts +27 -0
  117. package/src/components/table/TableCell.vue +30 -58
  118. package/src/components/table/TableHead.tsx +14 -0
  119. package/src/components/table/TableHeader.vue +18 -20
  120. package/src/components/table/TableRow.vue +23 -20
  121. package/src/components/table/__tests__/Table.spec.ts +11 -0
  122. package/src/components/tag/Tag.theme.ts +32 -0
  123. package/src/components/tag/Tag.vue +40 -68
  124. package/src/components/tag/__tests__/Tag.spec.ts +11 -0
  125. package/src/components/textarea/Textarea.theme.ts +62 -0
  126. package/src/components/textarea/Textarea.vue +100 -115
  127. package/src/components/textarea/__tests__/Textarea.spec.ts +11 -0
  128. package/src/components/toggle/Toggle.theme.ts +51 -0
  129. package/src/components/toggle/Toggle.vue +51 -81
  130. package/src/components/toggle/__tests__/Toggle.spec.ts +11 -0
  131. package/src/components/tooltip/Tooltip.theme.ts +51 -0
  132. package/src/components/tooltip/Tooltip.vue +9 -14
  133. package/src/components/tooltip/__tests__/Tooltip.spec.ts +11 -0
  134. package/src/composables/colors-utils.ts +68 -68
  135. package/src/composables/colors.ts +18 -6
  136. package/src/composables/common.ts +1 -0
  137. package/src/composables/css.ts +7 -2
  138. package/src/composables/index.ts +1 -1
  139. package/src/composables/inputtable.ts +1 -1
  140. package/src/composables/interactive.ts +8 -4
  141. package/src/composables/keys.ts +1 -0
  142. package/src/composables/notifications.ts +10 -0
  143. package/src/composables/theme.ts +88 -0
  144. package/src/create.ts +9 -4
  145. package/src/exports/nuxt.js +2 -1
  146. package/src/version.ts +1 -1
  147. package/volar.d.ts +1 -0
  148. package/lib/components/alert/Alert.vue.d.ts +0 -42
  149. package/lib/components/avatar/Avatar.vue.d.ts +0 -49
  150. package/lib/components/badge/Badge.vue.d.ts +0 -75
  151. package/lib/components/breadcrumbs/Breadcrumbs.vue.d.ts +0 -30
  152. package/lib/components/button/Button.vue.d.ts +0 -87
  153. package/lib/components/button/ButtonGroup.vue.d.ts +0 -49
  154. package/lib/components/card/Card.vue.d.ts +0 -17
  155. package/lib/components/checkbox/Checkbox.vue.d.ts +0 -81
  156. package/lib/components/collapse/Collapse.vue.d.ts +0 -47
  157. package/lib/components/container/Container.vue.d.ts +0 -14
  158. package/lib/components/divider/Divider.vue.d.ts +0 -10
  159. package/lib/components/drawer/Drawer.vue.d.ts +0 -73
  160. package/lib/components/form/Form.vue.d.ts +0 -46
  161. package/lib/components/icon/Icon.vue.d.ts +0 -40
  162. package/lib/components/image/Image.vue.d.ts +0 -8
  163. package/lib/components/index.d.ts +0 -45
  164. package/lib/components/input/Input.vue.d.ts +0 -117
  165. package/lib/components/link/Link.vue.d.ts +0 -36
  166. package/lib/components/menu/Menu.vue.d.ts +0 -62
  167. package/lib/components/menu/MenuItem.vue.d.ts +0 -114
  168. package/lib/components/modal/Modal.vue.d.ts +0 -34
  169. package/lib/components/notifications/Notifications.vue.d.ts +0 -104
  170. package/lib/components/pagination/Pagination.vue.d.ts +0 -58
  171. package/lib/components/pagination/PaginationItem.vue.d.ts +0 -32
  172. package/lib/components/popover/Popover.vue.d.ts +0 -64
  173. package/lib/components/popover/PopoverContainer.vue.d.ts +0 -14
  174. package/lib/components/progress/Progress.vue.d.ts +0 -42
  175. package/lib/components/radio/Radio.vue.d.ts +0 -79
  176. package/lib/components/scroll/Scroll.vue.d.ts +0 -29
  177. package/lib/components/select/Select.vue.d.ts +0 -100
  178. package/lib/components/skeleton/Skeleton.vue.d.ts +0 -14
  179. package/lib/components/slider/Slider.vue.d.ts +0 -96
  180. package/lib/components/spacer/Spacer.vue.d.ts +0 -2
  181. package/lib/components/spinner/Spinner.vue.d.ts +0 -16
  182. package/lib/components/tab/Tab.vue.d.ts +0 -52
  183. package/lib/components/tab/TabGroup.vue.d.ts +0 -61
  184. package/lib/components/table/Table.vue.d.ts +0 -82
  185. package/lib/components/table/TableBody.vue.d.ts +0 -2
  186. package/lib/components/table/TableCell.vue.d.ts +0 -33
  187. package/lib/components/table/TableHead.vue.d.ts +0 -2
  188. package/lib/components/table/TableHeader.vue.d.ts +0 -33
  189. package/lib/components/table/TableRow.vue.d.ts +0 -23
  190. package/lib/components/tag/Tag.vue.d.ts +0 -45
  191. package/lib/components/textarea/Textarea.vue.d.ts +0 -106
  192. package/lib/components/toggle/Toggle.vue.d.ts +0 -79
  193. package/lib/components/tooltip/Tooltip.vue.d.ts +0 -2
  194. package/lib/composables/colors-utils.d.ts +0 -8
  195. package/lib/composables/colors.d.ts +0 -26
  196. package/lib/composables/common.d.ts +0 -14
  197. package/lib/composables/css.d.ts +0 -5
  198. package/lib/composables/index.d.ts +0 -7
  199. package/lib/composables/inputtable.d.ts +0 -37
  200. package/lib/composables/interactive.d.ts +0 -10
  201. package/lib/composables/keys.d.ts +0 -7
  202. package/lib/composables/notification.d.ts +0 -1
  203. package/lib/create.d.ts +0 -12
  204. package/lib/index.d.ts +0 -6
  205. package/lib/install.d.ts +0 -4
  206. package/lib/style.css +0 -1
  207. package/lib/version.d.ts +0 -2
  208. package/src/components/table/TableHead.vue +0 -15
  209. package/src/composables/notification.ts +0 -10
@@ -1,152 +1,132 @@
1
1
  <script lang="ts">
2
- import { defineComponent, ref, computed } from 'vue'
3
- import { useCSS } from '../../composables/css'
2
+ export default { name: 'XInput' }
3
+ </script>
4
+
5
+ <script setup lang="ts">
6
+ import { computed, reactive, ref } from 'vue'
7
+ import { useTheme } from '../../composables/theme'
4
8
  import { useColors } from '../../composables/colors'
5
9
  import { useCommon } from '../../composables/common'
6
10
  import { useInputtable } from '../../composables/inputtable'
7
11
  import { useInteractive } from '../../composables/interactive'
12
+ import { eyeIcon, eyeVisibleIcon } from '../../common/icons'
8
13
 
9
- export default defineComponent({
10
- name: 'XInput',
14
+ import XIcon from '../icon/Icon.vue'
15
+ import XInputError from '../helpers/InputError'
11
16
 
12
- validators: {
13
- ...useCommon.validators(),
14
- },
17
+ import theme from './Input.theme'
15
18
 
16
- props: {
17
- ...useCommon.props(),
18
- ...useInteractive.props(),
19
- ...useInputtable.props(),
20
- showPasswordToggle: {
21
- type: Boolean,
22
- default: true,
23
- },
24
- helper: String,
25
- label: String,
26
- dir: {
27
- type: String,
28
- default: 'ltr',
29
- },
30
- icon: String,
31
- iconRight: String,
32
- max: Number,
33
- maxlength: Number,
34
- min: Number,
35
- minlength: Number,
36
- placeholder: String,
37
- type: {
38
- type: String,
39
- default: 'text',
40
- },
41
- inputClass: String,
42
- block: Boolean,
19
+ const props = defineProps({
20
+ ...useCommon.props(),
21
+ ...useColors.props('primary'),
22
+ ...useInteractive.props(),
23
+ ...useInputtable.props(),
24
+ showPasswordToggle: {
25
+ type: Boolean,
26
+ default: true,
43
27
  },
28
+ helper: String,
29
+ label: String,
30
+ dir: {
31
+ type: String,
32
+ default: 'ltr',
33
+ },
34
+ icon: String,
35
+ iconLeft: String,
36
+ iconRight: String,
37
+ max: [Number, String],
38
+ maxlength: [Number, String],
39
+ min: [Number, String],
40
+ minlength: [Number, String],
41
+ placeholder: String,
42
+ type: {
43
+ type: String,
44
+ default: 'text',
45
+ },
46
+ block: Boolean,
47
+ })
44
48
 
45
- emits: useInputtable.emits(),
46
-
47
- setup(props, { emit }) {
48
- const elRef = ref<HTMLInputElement>()
49
- const currentType = ref(props.type)
50
-
51
- const labelClasses = computed(() => {
52
- if (props.size === 'xs') return 'text-xs'
53
- else if (props.size === 'sm') return 'text-sm'
54
- else if (props.size === 'lg') return 'text-lg'
55
- else if (props.size === 'xl') return 'text-xl'
49
+ const emit = defineEmits(useInputtable.emits())
56
50
 
57
- return ''
58
- })
51
+ const elRef = ref<HTMLInputElement | null>(null)
52
+ const currentType = ref(props.type)
59
53
 
60
- const sizeClasses = computed(() => {
61
- if (props.size === 'xs') return 'px-2 py-1 text-xs'
62
- else if (props.size === 'sm') return 'px-2 py-2 text-sm'
63
- else if (props.size === 'lg') return 'px-4 py-3 text-lg'
64
- else if (props.size === 'xl') return 'px-5 py-4 text-xl'
54
+ function onChange(e: Event) {
55
+ if (!e.target) return
65
56
 
66
- return 'px-3 py-2'
67
- })
57
+ const target = (e.target as HTMLInputElement)
68
58
 
69
- const css = useCSS('input')
70
- const colors = useColors()
71
- const color = colors.getPalette('primary')
72
- const style = css.get('border', color[500])
59
+ if (props.type === 'number') {
60
+ const value = Number(target.value)
73
61
 
74
- function onChange(e: Event) {
75
- if (!e.target) return
62
+ if (typeof props.min !== 'undefined') {
63
+ if (value < props.min) target.value = props.min.toString()
64
+ }
76
65
 
77
- const target = (e.target as HTMLInputElement)
66
+ if (typeof props.max !== 'undefined') {
67
+ if (value > props.max) target.value = props.max.toString()
68
+ }
69
+ }
70
+ }
78
71
 
79
- if (props.type === 'number') {
80
- const value = Number(target.value)
72
+ function togglePasswordVisibility() {
73
+ currentType.value = currentType.value === 'password' ? 'text' : 'password'
74
+ }
81
75
 
82
- if (typeof props.min !== 'undefined') {
83
- if (value < props.min) target.value = props.min.toString()
84
- }
76
+ const { focus, blur } = useInteractive(elRef)
85
77
 
86
- if (typeof props.max !== 'undefined') {
87
- if (value > props.max) target.value = props.max.toString()
88
- }
89
- }
90
- }
78
+ const {
79
+ errorInternal,
80
+ isInsideForm,
81
+ inputListeners,
82
+ reset,
83
+ validate,
84
+ setError,
85
+ } = useInputtable(props, { focus, emit })
91
86
 
92
- function togglePasswordVisibility() {
93
- currentType.value = currentType.value === 'password' ? 'text' : 'password'
94
- }
87
+ const { styles, classes, className } = useTheme('input', theme, props, { errorInternal })
95
88
 
96
- const interactive = useInteractive(elRef)
97
-
98
- return {
99
- ...interactive,
100
- ...useInputtable(props, { focus: interactive.focus, emit }),
101
- currentType,
102
- labelClasses,
103
- sizeClasses,
104
- style,
105
- elRef,
106
- onChange,
107
- togglePasswordVisibility,
108
- }
109
- },
110
- })
89
+ defineExpose({ focus, blur, reset, validate, setError })
111
90
  </script>
112
91
 
113
92
  <template>
114
93
  <label
115
- class="inline-block relative align-bottom text-left"
116
- :class="{ 'mb-3': isInsideForm, 'w-full': block }"
94
+ :style="styles"
95
+ class="relative"
96
+ :class="[
97
+ className,
98
+ classes.wrapper,
99
+ { 'mb-3': isInsideForm, 'w-full': block }
100
+ ]"
117
101
  >
118
102
  <p
119
103
  v-if="label"
120
- class="font-medium text-gray-800 dark:text-gray-200 mb-1"
121
- :class="labelClasses"
104
+ :class="classes.label"
122
105
  v-text="label"
123
106
  ></p>
124
107
 
125
108
  <div class="relative">
126
109
  <x-icon
127
- v-if="icon"
110
+ v-if="iconLeft"
128
111
  :size="size"
129
- :icon="icon"
130
- class="text-gray-600 dark:text-gray-300 absolute ml-2 left-0 my-auto inset-y-0"
112
+ :icon="iconLeft"
113
+ class="ml-2 left-1"
114
+ :class="classes.icon"
131
115
  />
132
116
 
133
117
  <input
134
118
  ref="elRef"
135
- class="appearance-none block w-full placeholder-gray-400 dark:placeholder-gray-500 focus:outline-none transition-colors duration-150 ease-in-out border-gray-300 hover:border-gray-400 dark:border-gray-700 border shadow-sm rounded-md
136
- focus:border-[color:var(--x-input-border)]
137
- "
138
- :style="style"
139
119
  :class="[
140
- sizeClasses,
141
- disabled ? 'bg-gray-100 dark:bg-gray-700 text-gray-500 cursor-not-allowed' : 'bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-200',
142
- type === 'password' ? 'pr-9' : '',
120
+ classes.input,
121
+ type === 'password' ? 'pr-10' : '',
122
+ // error
123
+ errorInternal
124
+ ? 'border-red-500 dark:border-red-400 focus:outline-red-500'
125
+ : 'focus:outline-[color:var(--x-input-border)]',
143
126
  {
144
- '!pl-9': icon,
145
- '!pr-9': iconRight,
146
- // error
147
- 'border-red-500 focus:border-red-500 dark:focus:border-red-500': errorInternal,
127
+ '!pl-10': iconLeft,
128
+ '!pr-10': iconRight,
148
129
  },
149
- inputClass,
150
130
  ]"
151
131
  :disabled="disabled"
152
132
  :min="min"
@@ -168,33 +148,20 @@ export default defineComponent({
168
148
  v-if="iconRight"
169
149
  :size="size"
170
150
  :icon="iconRight"
171
- class="text-gray-600 dark:text-gray-300 absolute mr-2 right-0 my-auto inset-y-0"
151
+ class="mr-2 right-1"
152
+ :class="classes.icon"
172
153
  />
173
154
 
174
- <svg
155
+ <x-icon
175
156
  v-else-if="type === 'password' && showPasswordToggle"
176
- width="24"
177
- height="24"
178
- viewBox="0 0 24 24"
179
- stroke="currentColor"
180
- stroke-linejoin="round"
181
- stroke-linecap="round"
182
- fill="none"
183
- class="text-gray-600 dark:text-gray-300 stroke-2 w-5 h-5 absolute my-auto mr-2 inset-y-0 right-1 cursor-pointer"
157
+ :size="size"
158
+ :icon="currentType === 'password' ? eyeIcon : eyeVisibleIcon"
159
+ class="mr-2 right-1 cursor-pointer"
160
+ :class="classes.icon"
184
161
  @click="togglePasswordVisibility()"
185
- >
186
- <template v-if="currentType === 'password'">
187
- <path d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
188
- <path d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
189
- </template>
190
-
191
- <template v-else>
192
- <path d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21" />
193
- </template>
194
- </svg>
162
+ />
195
163
  </div>
196
164
 
197
- <p v-if="errorInternal" class="text-sm text-red-500 mt-1" v-text="errorInternal"></p>
198
- <p v-else-if="helper" class="text-sm text-gray-500 mt-1" v-text="helper"></p>
165
+ <x-input-error :error="errorInternal" :helper="helper"/>
199
166
  </label>
200
167
  </template>
@@ -0,0 +1,11 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { mount } from '@vue/test-utils'
3
+ import Input from '../Input.vue'
4
+
5
+ describe('Input', () => {
6
+ it('renders without errors', () => {
7
+ const wrapper = mount(Input)
8
+
9
+ expect(wrapper.vm).toBeTruthy()
10
+ })
11
+ })
@@ -0,0 +1,26 @@
1
+ import type { ThemeParams } from '../../composables/theme'
2
+
3
+ export default {
4
+ classes: {
5
+ wrapper: 'transition duration-300 ease-in-out cursor-pointer inline-flex',
6
+ },
7
+
8
+ styles: ({ colors, props, css }: ThemeParams) => {
9
+ const color = colors.getPalette(props.color || 'gray')
10
+
11
+ return css.variables({
12
+ text: props.color ? color[600] : '',
13
+ hover: {
14
+ text: !props.shadow ? color[700] : '',
15
+ },
16
+ shadow: color[100],
17
+ dark: {
18
+ text: props.color ? color[400] : '',
19
+ hover: {
20
+ text: color[300],
21
+ },
22
+ shadow: color[900],
23
+ },
24
+ })
25
+ },
26
+ }
@@ -1,66 +1,42 @@
1
1
  <script lang="ts">
2
- import { defineComponent, computed } from 'vue'
3
- import { useColors } from '../../composables/colors'
4
- import { useCSS } from '../../composables/css'
5
-
6
- export default defineComponent({
7
- name: 'XLink',
2
+ export default { name: 'XLink' }
3
+ </script>
8
4
 
9
- props: {
10
- ...useColors.props(),
11
- tag: {
12
- type: String,
13
- default: 'a',
14
- },
15
- to: [String, Object],
16
- shadow: Boolean,
17
- external: Boolean,
18
- underline: Boolean,
19
- },
5
+ <script setup lang="ts">
6
+ import { useColors } from '../../composables/colors'
7
+ import { useTheme } from '../../composables/theme'
8
+ import { externalIcon } from '../../common/icons'
20
9
 
21
- setup(props) {
22
- const css = useCSS()
23
- const colors = useColors()
24
- const styles = computed(() => {
25
- const color = colors.getPalette(props.color || 'gray')
10
+ import XIcon from '../icon/Icon.vue'
26
11
 
27
- return css.variables({
28
- text: props.color ? color[500] : '',
29
- hover: {
30
- text: !props.shadow ? color[600] : '',
31
- },
32
- shadow: color[100],
33
- dark: {
34
- text: props.color ? color[400] : '',
35
- hover: {
36
- text: color[300],
37
- },
38
- shadow: color[900],
39
- },
40
- })
41
- })
12
+ import theme from './Link.theme'
42
13
 
43
- return {
44
- styles,
45
- }
14
+ const props = defineProps({
15
+ ...useColors.props(),
16
+ tag: {
17
+ type: String,
18
+ default: 'a',
46
19
  },
20
+ to: [String, Object],
21
+ shadow: Boolean,
22
+ external: Boolean,
23
+ underline: Boolean,
47
24
  })
25
+
26
+ const { styles, classes, className } = useTheme('link', theme, props)
48
27
  </script>
49
28
 
50
29
  <template>
51
30
  <component
52
31
  :is="to ? 'router-link' : tag"
53
32
  :to="to"
54
- class="transition duration-300 ease-in-out cursor-pointer inline-flex
55
- text-[color:var(--x-text)]
56
- dark:text-[color:var(--x-dark-text)]
57
- "
58
33
  :style="styles"
59
34
  :class="[
35
+ className,
36
+ $style['link'],
37
+ classes.wrapper,
60
38
  [shadow ? $style['link--shadow'] : ''],
61
- {
62
- 'underline': underline
63
- },
39
+ { 'underline': underline },
64
40
  ]"
65
41
  >
66
42
  <span
@@ -68,20 +44,7 @@ export default defineComponent({
68
44
  class="inline-flex items-center"
69
45
  >
70
46
  <slot></slot>
71
- <svg
72
- width="24"
73
- height="24"
74
- viewBox="0 0 24 24"
75
- stroke="currentColor"
76
- stroke-linejoin="round"
77
- stroke-linecap="round"
78
- fill="none"
79
- role="presentation"
80
- class="stroke-2 w-4 h-4 ml"
81
- >
82
- <line x1="7" y1="17" x2="17" y2="7" />
83
- <polyline points="7 7 17 7 17 17" />
84
- </svg>
47
+ <x-icon :icon="externalIcon" />
85
48
  </span>
86
49
  <template v-else>
87
50
  <slot></slot>
@@ -91,18 +54,30 @@ export default defineComponent({
91
54
 
92
55
  <style lang="postcss" module scoped>
93
56
  .link {
57
+ color: var(--x-link-text);
58
+
59
+ &:hover {
60
+ color: var(--x-link-text-hover, var(--x-link-text));
61
+ }
62
+
94
63
  &--shadow {
95
- box-shadow: inset 0 -0.315em 0 0 var(--x-shadow);
64
+ box-shadow: inset 0 -0.315em 0 0 var(--x-link-shadow);
96
65
  &:hover {
97
- box-shadow: inset 0 -1.125em 0 0 var(--x-shadow);
66
+ box-shadow: inset 0 -1.325em 0 0 var(--x-link-shadow);
98
67
  }
99
68
  }
100
69
 
101
- :global(.dark) & {
70
+ :global(.dark) &, &:global(.dark) {
71
+ color: var(--x-link-dark-text);
72
+
73
+ &:hover {
74
+ color: var(--x-link-dark-text-hover, var(--x-link-dark-text));
75
+ }
76
+
102
77
  &--shadow {
103
- box-shadow: inset 0 -0.315em 0 0 var(--x-dark-shadow);
78
+ box-shadow: inset 0 -0.315em 0 0 var(--x-link-dark-shadow);
104
79
  &:hover {
105
- box-shadow: inset 0 -1.125em 0 0 var(--x-dark-shadow);
80
+ box-shadow: inset 0 -1.325em 0 0 var(--x-link-dark-shadow);
106
81
  }
107
82
  }
108
83
  }
@@ -0,0 +1,11 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { mount } from '@vue/test-utils'
3
+ import Link from '../Link.vue'
4
+
5
+ describe('Link', () => {
6
+ it('renders without errors', () => {
7
+ const wrapper = mount(Link)
8
+
9
+ expect(wrapper.vm).toBeTruthy()
10
+ })
11
+ })
@@ -0,0 +1,7 @@
1
+ import type { ThemeParams } from '../../composables/theme'
2
+
3
+ export default {
4
+ classes: {
5
+ wrapper: '',
6
+ },
7
+ }
@@ -1,48 +1,55 @@
1
1
  <script lang="ts">
2
- import { defineComponent, type PropType } from 'vue'
2
+ export default { name: 'XMenu' }
3
+ </script>
4
+
5
+ <script setup lang="ts">
6
+ import type { PropType } from 'vue'
3
7
  import { useCommon } from '../../composables/common'
4
8
  import { useColors } from '../../composables/colors'
9
+ import { useTheme } from '../../composables/theme'
5
10
 
6
11
  import XMenuItem from './MenuItem.vue'
7
12
  import XCollapse from '../../components/collapse/Collapse.vue'
8
13
  import XDivider from '../../components/divider/Divider.vue'
9
14
 
10
- export default defineComponent({
11
- name: 'XMenu',
15
+ import theme from './Menu.theme'
12
16
 
13
- components: {
14
- XDivider,
15
- XCollapse,
16
- XMenuItem,
17
+ const props = defineProps({
18
+ ...useCommon.props(),
19
+ ...useColors.props('primary'),
20
+ items: Array as PropType<Array<any>>,
21
+ collapsible: {
22
+ type: Boolean,
23
+ default: true,
17
24
  },
18
-
19
- props: {
20
- ...useCommon.props(),
21
- ...useColors.props('primary'),
22
- items: Array as PropType<Array<any>>,
23
- collapsible: {
24
- type: Boolean,
25
- default: true,
26
- },
27
- collapseIcon: String,
28
- expanded: Boolean,
29
- disabled: Boolean,
30
- rounded: {
31
- type: Boolean,
32
- default: true,
33
- },
34
- filled: {
35
- type: Boolean,
36
- default: true,
37
- },
25
+ collapseIcon: String,
26
+ expanded: Boolean,
27
+ disabled: Boolean,
28
+ rounded: {
29
+ type: Boolean,
30
+ default: true,
31
+ },
32
+ filled: {
33
+ type: Boolean,
34
+ default: true,
38
35
  },
39
-
40
- emits: ['expand'],
41
36
  })
37
+
38
+ const emit = defineEmits(['expand'])
39
+
40
+ const { styles, classes, className } = useTheme('menu', theme, props)
42
41
  </script>
43
42
 
44
43
  <template>
45
- <div v-if="items">
44
+ <div
45
+ v-if="items"
46
+ :style="styles"
47
+ :class="[
48
+ 'space-y-1',
49
+ className,
50
+ classes.wrapper
51
+ ]"
52
+ >
46
53
  <template v-for="(item, index) in items" :key="index">
47
54
  <template v-if="item.items">
48
55
  <x-collapse
@@ -50,7 +57,7 @@ export default defineComponent({
50
57
  :icon="item.collapseIcon || collapseIcon"
51
58
  :expanded="item.expanded || expanded"
52
59
  :disabled="disabled || item.disabled"
53
- class="x-menu-inner"
60
+ class="x-menu-inner space-y-1"
54
61
  @expand="$emit('expand')"
55
62
  >
56
63
  <template #default="{ }">
@@ -66,7 +73,7 @@ export default defineComponent({
66
73
  </template>
67
74
  <template #content="{ expand }">
68
75
  <x-menu
69
- class="border-l ml-4 border-gray-100 dark:border-gray-700 mt-2 mb-1"
76
+ class="border-l ml-4 border-gray-100 dark:border-gray-700"
70
77
  :class="{ 'pl-1': filled }"
71
78
  :items="item.items"
72
79
  :color="item.color || color"
@@ -92,7 +99,7 @@ export default defineComponent({
92
99
  inactive
93
100
  />
94
101
  <x-menu
95
- class="x-menu-inner ml-4 border-l border-gray-100 dark:border-gray-700"
102
+ class="x-menu-inner space-y-1 ml-4 border-l border-gray-100 dark:border-gray-700"
96
103
  :class="{ 'pl-1': filled }"
97
104
  :items="item.items"
98
105
  :color="item.color || color"
@@ -107,18 +114,20 @@ export default defineComponent({
107
114
  />
108
115
  </template>
109
116
  </template>
110
- <component
111
- :is="item.divider ? 'x-divider' : 'x-menu-item'"
112
- v-else
113
- :color="item.color || color"
114
- :size="item.size || size"
115
- :item="item"
116
- :disabled="disabled || item.disabled"
117
- :filled="filled"
118
- :rounded="rounded"
119
- :class="{ 'my-2': item.divider }"
120
- @active="$emit('expand')"
121
- />
117
+ <template v-else>
118
+ <x-divider v-if="item.divider"/>
119
+ <x-menu-item
120
+ v-else
121
+ :color="item.color || color"
122
+ :size="item.size || size"
123
+ :item="item"
124
+ :disabled="disabled || item.disabled"
125
+ :filled="filled"
126
+ :rounded="rounded"
127
+ :class="{ 'my-2': item.divider }"
128
+ @active="$emit('expand')"
129
+ />
130
+ </template>
122
131
  </template>
123
132
  </div>
124
133
  </template>