@indielayer/ui 1.0.0-alpha.9 → 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 +4451 -3650
  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 -249
  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 +8 -3
  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
@@ -0,0 +1,11 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { mount } from '@vue/test-utils'
3
+ import Card from '../Card.vue'
4
+
5
+ describe('Card', () => {
6
+ it('renders without errors', () => {
7
+ const wrapper = mount(Card)
8
+
9
+ expect(wrapper.vm).toBeTruthy()
10
+ })
11
+ })
@@ -0,0 +1,92 @@
1
+ import type { ThemeParams } from '../../composables/theme'
2
+
3
+ export default {
4
+ classes: {
5
+ wrapper: 'inline-block relative cursor-pointer align-middle',
6
+
7
+ box: ({ props }: ThemeParams) => {
8
+ const classes = ['rounded flex justify-center items-center shrink-0 border-2 border-[color:var(--x-checkbox-border)] bg-[color:var(--x-checkbox-bg)] dark:border-[color:var(--x-checkbox-dark-border)] dark:bg-[color:var(--x-checkbox-dark-bg)]']
9
+
10
+ if (props.size === 'xs' || props.size === 'sm') classes.push('h-4 w-4')
11
+ else if (props.size === 'xl') classes.push('h-6 w-6')
12
+ else classes.push('h-5 w-5')
13
+
14
+ return classes
15
+ },
16
+
17
+ icon: ({ props }: ThemeParams) => {
18
+ const classes = ['fill-current text-white dark:text-gray-900']
19
+
20
+ if (props.size === 'xs' || props.size === 'sm') classes.push('h-2 w-2')
21
+ else if (props.size === 'xl') classes.push('h-4 w-4')
22
+ else classes.push('h-3 w-3')
23
+
24
+ return classes
25
+ },
26
+
27
+ label: ({ props }: ThemeParams) => {
28
+ const classes = ['inline-block font-medium text-gray-800 dark:text-gray-200 pl-2']
29
+
30
+ if (props.size === 'xs') classes.push('text-xs')
31
+ else if (props.size === 'sm') classes.push('text-sm')
32
+ else if (props.size === 'lg') classes.push('text-lg')
33
+ else if (props.size === 'xl') classes.push('text-xl')
34
+
35
+ return classes
36
+ },
37
+ },
38
+
39
+ styles({ props, colors, css, data }: ThemeParams) {
40
+ const gray = colors.getPalette('gray')
41
+ const color = colors.getPalette(props.color)
42
+ const vars: (object | string)[] = []
43
+
44
+ if (props.loading) {
45
+ return css.variables({
46
+ bg: 'transparent',
47
+ border: 'transparent',
48
+ dark: {
49
+ bg: 'transparent',
50
+ border: 'transparent',
51
+ },
52
+ })
53
+ }
54
+
55
+ if (props.disabled) {
56
+ vars.push(css.variables({
57
+ bg: gray[100],
58
+ border: gray[200],
59
+ dark: {
60
+ bg: gray[800],
61
+ border: gray[700],
62
+ },
63
+ }))
64
+ } else {
65
+ if (data.checked) {
66
+ vars.push(css.variables({
67
+ bg: color[500],
68
+ border: color[500],
69
+ dark: {
70
+ bg: color[500],
71
+ border: color[500],
72
+ },
73
+ }))
74
+ } else {
75
+ vars.push(css.variables({
76
+ bg: '#fff',
77
+ border: props.glow ? color[300] : gray[300],
78
+ dark: {
79
+ bg: gray[900],
80
+ border: props.glow ? color[300] : gray[400],
81
+ },
82
+ }))
83
+ }
84
+
85
+ if (props.glow) {
86
+ vars.push(css.get('glow', colors.getColorOpacity(color[500], 0.5)))
87
+ }
88
+ }
89
+
90
+ return vars
91
+ },
92
+ }
@@ -1,142 +1,71 @@
1
1
  <script lang="ts">
2
- import { defineComponent, ref, watch, computed, type StyleValue } from 'vue'
3
- import { useCSS } from '../../composables/css'
2
+ export default { name: 'XCheckbox' }
3
+ </script>
4
+
5
+ <script setup lang="ts">
6
+ import { ref, watch } from 'vue'
7
+ import { useTheme } from '../../composables/theme'
4
8
  import { useCommon } from '../../composables/common'
5
9
  import { useColors } from '../../composables/colors'
6
10
  import { useInteractive } from '../../composables/interactive'
7
11
  import { useInputtable } from '../../composables/inputtable'
8
12
 
9
13
  import XSpinner from '../../components/spinner/Spinner.vue'
14
+ import XInputError from '../helpers/InputError'
15
+
16
+ import theme from './Checkbox.theme'
17
+
18
+ const props = defineProps({
19
+ ...useCommon.props(),
20
+ ...useColors.props('primary'),
21
+ ...useInteractive.props(),
22
+ ...useInputtable.props(),
23
+ label: String,
24
+ helper: String,
25
+ glow: Boolean,
26
+ })
10
27
 
11
- export default defineComponent({
12
- name: 'XCheckbox',
13
-
14
- components: {
15
- XSpinner,
16
- },
17
-
18
- validators: {
19
- ...useCommon.validators(),
20
- },
21
-
22
- props: {
23
- ...useCommon.props(),
24
- ...useColors.props('primary'),
25
- ...useInteractive.props(),
26
- ...useInputtable.props(),
27
- label: String,
28
- glow: Boolean,
29
- },
30
-
31
- emits: useInputtable.emits(false),
32
-
33
- expose: ['toggle'],
34
-
35
- setup(props, { attrs, emit }) {
36
- const elRef = ref<HTMLElement>()
37
- const checked = ref(false)
38
-
39
- watch(() => props.modelValue, (value) => {
40
- checked.value = !!value
41
- }, { immediate: true })
42
-
43
- watch(() => checked.value, (value) => {
44
- emit('update:modelValue', value)
45
- })
46
-
47
- const sizeClasses = computed(() => {
48
- if (props.size === 'xs' || props.size === 'sm') return 'h-4 w-4'
49
- else if (props.size === 'xl') return 'h-6 w-6'
50
-
51
- return 'h-5 w-5'
52
- })
53
-
54
- const iconSizeClasses = computed(() => {
55
- if (props.size === 'xs' || props.size === 'sm') return 'h-2 w-2'
56
- else if (props.size === 'xl') return 'h-4 w-4'
57
-
58
- return 'h-3 w-3'
59
- })
60
-
61
- const css = useCSS()
62
- const colors = useColors()
63
- const gray = colors.getPalette('gray')
64
-
65
- const cssVariables = computed(() => {
66
- const color = colors.getPalette(props.color)
67
- const vars: (object | string)[] = []
68
-
69
- if (props.loading) {
70
- return css.variables({
71
- bg: 'transparent',
72
- border: 'transparent',
73
- dark: {
74
- bg: 'transparent',
75
- border: 'transparent',
76
- },
77
- })
78
- }
79
-
80
- if (props.disabled) {
81
- vars.push(css.variables({
82
- bg: gray[100],
83
- border: gray[200],
84
- dark: {
85
- bg: gray[800],
86
- border: gray[700],
87
- },
88
- }))
89
- } else {
90
- if (checked.value) {
91
- vars.push(css.variables({
92
- bg: color[500],
93
- border: color[500],
94
- dark: {
95
- bg: color[500],
96
- border: color[500],
97
- },
98
- }))
99
- } else {
100
- vars.push(css.variables({
101
- bg: '#fff',
102
- border: props.glow ? color[300] : gray[300],
103
- dark: {
104
- bg: gray[900],
105
- border: props.glow ? color[300] : gray[400],
106
- },
107
- }))
108
- }
109
-
110
- if (props.glow) {
111
- vars.push(css.get('glow', colors.getColorOpacity(color[500], 0.5)))
112
- }
113
- }
114
-
115
- return vars as StyleValue
116
- })
117
-
118
- function toggle() {
119
- checked.value = !checked.value
120
- }
28
+ const emit = defineEmits(useInputtable.emits(false))
121
29
 
122
- const interactive = useInteractive(elRef)
123
-
124
- return {
125
- ...interactive,
126
- ...useInputtable(props, { focus: interactive.focus, emit, withListeners: false }),
127
- elRef,
128
- checked,
129
- sizeClasses,
130
- iconSizeClasses,
131
- cssVariables,
132
- toggle,
133
- }
134
- },
30
+ const elRef = ref<HTMLElement | null>(null)
31
+ const checked = ref(false)
32
+
33
+ watch(() => props.modelValue, (value) => {
34
+ checked.value = !!value
35
+ }, { immediate: true })
36
+
37
+ watch(() => checked.value, (value) => {
38
+ emit('update:modelValue', value)
135
39
  })
40
+
41
+ function toggle() {
42
+ checked.value = !checked.value
43
+ }
44
+
45
+ const { focus, blur } = useInteractive(elRef)
46
+
47
+ const {
48
+ errorInternal,
49
+ isInsideForm,
50
+ reset,
51
+ validate,
52
+ setError,
53
+ } = useInputtable(props, { focus, emit, withListeners: false })
54
+
55
+ const { styles, classes, className } = useTheme('checkbox', theme, props, { checked })
56
+
57
+ defineExpose({ focus, blur, toggle, reset, validate, setError })
136
58
  </script>
137
59
 
138
60
  <template>
139
- <label class="inline-block relative cursor-pointer align-middle mb-1 pb-2">
61
+ <label
62
+ :style="styles"
63
+ :class="[
64
+ className,
65
+ classes.wrapper,
66
+ { 'mb-3': isInsideForm }
67
+ ]"
68
+ >
140
69
  <div
141
70
  ref="elRef"
142
71
  class="flex items-center"
@@ -155,51 +84,35 @@ export default defineComponent({
155
84
  :required="required"
156
85
  />
157
86
  <div
158
- class="rounded flex justify-center items-center flex-shrink-0 border-2
159
- border-[color:var(--x-border)]
160
- bg-[color:var(--x-bg)]
161
- dark:border-[color:var(--x-dark-border)]
162
- dark:bg-[color:var(--x-dark-bg)]
163
- "
164
- :style="cssVariables"
165
87
  :class="[
88
+ classes.box,
166
89
  [(glow && !disabled && !loading) ? $style['checkbox--glow'] : ''],
167
- sizeClasses,
168
90
  ]"
169
91
  >
170
92
  <x-spinner v-if="loading" :size="size" class="absolute" />
171
- <svg
172
- v-else
173
- class="fill-current text-gray-100 dark:text-gray-900"
174
- :class="[iconSizeClasses, {
175
- 'opacity-0': !checked,
176
- }]"
177
- viewBox="0 0 20 20"
178
- >
179
- <path d="M0 11l2-2 5 5L18 3l2 2L7 18z" />
180
- </svg>
93
+ <slot v-else name="icon">
94
+ <svg
95
+ viewBox="0 0 20 20"
96
+ :class="[classes.icon, { 'opacity-0': !checked }]"
97
+ >
98
+ <path d="M0 11l2-2 5 5L18 3l2 2L7 18z" />
99
+ </svg>
100
+ </slot>
181
101
  </div>
182
- <div
183
- class="inline-block font-medium text-gray-800 dark:text-gray-200 pl-2"
184
- :class="{
185
- 'text-xs': size === 'xs',
186
- 'text-sm': size === 'sm',
187
- 'text-lg': size === 'lg',
188
- 'text-xl': size === 'xl',
189
- }"
190
- >
102
+ <div :class="classes.label">
191
103
  <span v-if="label" v-text="label"></span>
192
104
  <slot v-else></slot>
193
105
  </div>
194
106
  </div>
195
- <p v-if="errorInternal" class="text-sm text-red-500 mt-1" v-text="errorInternal"></p>
107
+
108
+ <x-input-error :error="errorInternal" :helper="helper"/>
196
109
  </label>
197
110
  </template>
198
111
 
199
- <style lang="postcss" module scoped>
112
+ <style lang="postcss" module>
200
113
  .checkbox {
201
114
  &--glow {
202
- box-shadow: 0 0 #000, 0 0 #000, 0 10px 15px -3px var(--x-glow),0 4px 6px -4px var(--x-glow);
115
+ box-shadow: 0 0 #000, 0 0 #000, 0 10px 15px -3px var(--x-checkbox-glow),0 4px 6px -4px var(--x-checkbox-glow);
203
116
  }
204
117
  }
205
118
  </style>
@@ -0,0 +1,11 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { mount } from '@vue/test-utils'
3
+ import Checkbox from '../Checkbox.vue'
4
+
5
+ describe('Checkbox', () => {
6
+ it('renders without errors', () => {
7
+ const wrapper = mount(Checkbox)
8
+
9
+ expect(wrapper.vm).toBeTruthy()
10
+ })
11
+ })
@@ -0,0 +1,11 @@
1
+ import type { ThemeParams } from '../../composables/theme'
2
+
3
+ export default {
4
+ classes: {
5
+ wrapper: ({ props }: ThemeParams) => `relative flex items-center ${props.icon ? 'flex-row-reverse' : ''} ${props.disabled ? '' : 'cursor-pointer'}`,
6
+
7
+ icon: 'absolute top-1/2 transform -translate-y-1/2 right-3',
8
+
9
+ content: 'transition-[height] duration-150 overflow-y-hidden',
10
+ },
11
+ }
@@ -1,142 +1,123 @@
1
1
  <script lang="ts">
2
- import { defineComponent, ref, watch } from 'vue'
2
+ export default { name: 'XCollapse' }
3
+ </script>
4
+
5
+ <script setup lang="ts">
6
+ import { ref, watch } from 'vue'
7
+ import { useTheme } from '../../composables/theme'
8
+ import { useColors } from '../../composables/colors'
3
9
 
4
10
  import XIcon from '../../components/icon/Icon.vue'
5
11
 
6
- export default defineComponent({
7
- name: 'XCollapse',
12
+ import theme from './Collapse.theme'
8
13
 
9
- components: {
10
- XIcon,
14
+ const props = defineProps({
15
+ ...useColors.props(),
16
+ tag: {
17
+ type: String,
18
+ default: 'div',
11
19
  },
20
+ disabled: Boolean,
21
+ expanded: Boolean,
22
+ showIcon: Boolean,
23
+ icon: String,
24
+ })
12
25
 
13
- props: {
14
- tag: {
15
- type: String,
16
- default: 'div',
17
- },
18
- disabled: Boolean,
19
- expanded: Boolean,
20
- showIcon: {
21
- type: Boolean,
22
- default: true,
23
- },
24
- icon: String,
25
- color: String,
26
- },
26
+ const emit = defineEmits(['expand'])
27
27
 
28
- emits: ['expand'],
29
-
30
- expose: ['toggle', 'open', 'close'],
31
-
32
- setup(props, { emit }) {
33
- const collapsed = ref(!props.expanded)
34
- const animated = ref(true)
35
-
36
- watch(() => props.expanded, () => {
37
- collapsed.value = !props.expanded
38
- })
39
-
40
- function onBeforeEnter(el: HTMLElement) {
41
- if (animated.value) el.style.height = '0px'
42
- }
43
-
44
- function onEnter(el: HTMLElement, done: ()=> void) {
45
- if (!animated.value) done()
46
- else {
47
- el.addEventListener('transitionend', done)
48
- setTimeout(() => {
49
- el.style.height = `${el.scrollHeight}px`
50
- }, 1)
51
- }
52
- }
53
-
54
- function onAfterEnter(el: HTMLElement) {
55
- if (!animated.value) {
56
- animated.value = true
57
- } else {
58
- el.style.removeProperty('height')
59
- }
60
- }
61
-
62
- function onBeforeLeave(el: HTMLElement) {
63
- if (!animated.value) return
64
- el.style.height = `${el.scrollHeight}px`
65
- }
66
-
67
- function onLeave(el: HTMLElement ,done: ()=> void) {
68
- if (!animated.value) done()
69
- else {
70
- el.addEventListener('transitionend', done)
71
- setTimeout(() => {
72
- el.style.height = '0px'
73
- }, 1)
74
- }
75
- }
76
-
77
- function onAfterLeave(el: HTMLElement) {
78
- if (!animated.value) {
79
- animated.value = true
80
- } else {
81
- el.style.removeProperty('height')
82
- }
83
- }
84
-
85
- function open(anim = true) {
86
- animated.value = anim
87
- collapsed.value = false
88
- }
89
-
90
- function close(anim = true) {
91
- animated.value = anim
92
- collapsed.value = true
93
- }
94
-
95
- function toggle() {
96
- if (!props.disabled) collapsed.value = !collapsed.value
97
- }
98
-
99
- function onExpand(anim = true) {
100
- open(anim)
101
- emit('expand')
102
- }
103
-
104
- return {
105
- collapsed,
106
- onBeforeEnter,
107
- onEnter,
108
- onAfterEnter,
109
- onBeforeLeave,
110
- onLeave,
111
- onAfterLeave,
112
- onExpand,
113
- toggle,
114
- close,
115
- open,
116
- }
117
- },
28
+ const collapsed = ref(!props.expanded)
29
+ const animated = ref(true)
30
+
31
+ watch(() => props.expanded, () => {
32
+ collapsed.value = !props.expanded
118
33
  })
34
+
35
+ function onBeforeEnter(el: HTMLElement) {
36
+ if (animated.value) el.style.height = '0px'
37
+ }
38
+
39
+ function onEnter(el: HTMLElement, done: ()=> void) {
40
+ if (!animated.value) done()
41
+ else {
42
+ el.addEventListener('transitionend', done)
43
+ setTimeout(() => {
44
+ el.style.height = `${el.scrollHeight}px`
45
+ }, 1)
46
+ }
47
+ }
48
+
49
+ function onAfterEnter(el: HTMLElement) {
50
+ if (!animated.value) {
51
+ animated.value = true
52
+ } else {
53
+ el.style.removeProperty('height')
54
+ }
55
+ }
56
+
57
+ function onBeforeLeave(el: HTMLElement) {
58
+ if (!animated.value) return
59
+ el.style.height = `${el.scrollHeight}px`
60
+ }
61
+
62
+ function onLeave(el: HTMLElement ,done: ()=> void) {
63
+ if (!animated.value) done()
64
+ else {
65
+ el.addEventListener('transitionend', done)
66
+ setTimeout(() => {
67
+ el.style.height = '0px'
68
+ }, 1)
69
+ }
70
+ }
71
+
72
+ function onAfterLeave(el: HTMLElement) {
73
+ if (!animated.value) {
74
+ animated.value = true
75
+ } else {
76
+ el.style.removeProperty('height')
77
+ }
78
+ }
79
+
80
+ function open(anim = true) {
81
+ animated.value = anim
82
+ collapsed.value = false
83
+ }
84
+
85
+ function close(anim = true) {
86
+ animated.value = anim
87
+ collapsed.value = true
88
+ }
89
+
90
+ function toggle() {
91
+ if (!props.disabled) collapsed.value = !collapsed.value
92
+ }
93
+
94
+ function onExpand(anim = true) {
95
+ open(anim)
96
+ emit('expand')
97
+ }
98
+
99
+ const { styles, classes, className } = useTheme('collapse', theme, props)
100
+
101
+ defineExpose({ toggle, open, close })
119
102
  </script>
120
103
 
121
104
  <template>
122
105
  <component
123
106
  :is="tag"
107
+ :style="styles"
108
+ :class="className"
124
109
  :aria-disabled="disabled"
125
110
  :aria-expanded="collapsed ? 'false' : 'true'"
126
111
  >
127
112
  <div
128
- class="flex items-center relative"
129
- :class="{
130
- 'cursor-pointer' : !disabled,
131
- 'flex-row-reverse': icon,
132
- }"
113
+ :class="classes.wrapper"
133
114
  @click="toggle"
134
115
  >
135
116
  <div class="flex-1 overflow-hidden">
136
117
  <slot :collapsed="collapsed"></slot>
137
118
  </div>
138
119
 
139
- <div v-if="showIcon" class="absolute top-1/2 transform -translate-y-1/2 right-3">
120
+ <div v-if="showIcon" :class="classes.icon">
140
121
  <span
141
122
  class="flex transform transition-transform duration-150"
142
123
  :class="[
@@ -165,7 +146,7 @@ export default defineComponent({
165
146
  <slot name="summary"></slot>
166
147
  </template>
167
148
 
168
- <Transition
149
+ <transition
169
150
  @before-enter="onBeforeEnter"
170
151
  @enter="onEnter"
171
152
  @after-enter="onAfterEnter"
@@ -173,9 +154,9 @@ export default defineComponent({
173
154
  @leave="onLeave"
174
155
  @after-leave="onAfterLeave"
175
156
  >
176
- <div v-show="!collapsed" class="transition-[height] duration-150 overflow-y-hidden">
157
+ <div v-show="!collapsed" :class="classes.content">
177
158
  <slot name="content" :expand="onExpand" :collapsed="collapsed"></slot>
178
159
  </div>
179
- </Transition>
160
+ </transition>
180
161
  </component>
181
162
  </template>
@@ -0,0 +1,11 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { mount } from '@vue/test-utils'
3
+ import Collapse from '../Collapse.vue'
4
+
5
+ describe('Collapse', () => {
6
+ it('renders without errors', () => {
7
+ const wrapper = mount(Collapse)
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: 'max-w-screen-2xl mx-auto px-4 md:px-8',
6
+ },
7
+ }