@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,15 +1,27 @@
1
1
  <script lang="ts">
2
- import { defineComponent, ref, provide, watch, type PropType } from 'vue'
2
+ const validators = {
3
+ align: ['left','right'],
4
+ position: ['bottom','top'],
5
+ }
6
+
7
+ export default {
8
+ name: 'XNotifications',
9
+ validators,
10
+ }
11
+ </script>
12
+
13
+ <script setup lang="ts">
14
+ import { ref, provide, watch, type PropType } from 'vue'
3
15
  import { injectNotificationKey } from '../../composables/keys'
4
16
  import { useColors } from '../../composables/colors'
5
17
  import { useCSS } from '../../composables/css'
18
+ import { useTheme } from '../../composables/theme'
19
+ import { closeIcon } from '../../common/icons'
6
20
 
7
21
  import XIcon from '../../components/icon/Icon.vue'
22
+ import XSpacer from '../spacer/Spacer'
8
23
 
9
- const validators = {
10
- align: ['left','right'],
11
- position: ['bottom','top'],
12
- }
24
+ import theme from './Notifications.theme'
13
25
 
14
26
  export type NotificationAlign = 'left' | 'right'
15
27
  export type NotificationPosition = 'bottom' | 'top'
@@ -32,287 +44,261 @@ export type NotificationEvent = {
32
44
  position?: NotificationPosition
33
45
  }
34
46
 
35
- export default defineComponent({
36
- name: 'XNotifications',
37
-
38
- components: {
39
- XIcon,
47
+ const props = defineProps({
48
+ ...useColors.props('primary'),
49
+ align: {
50
+ type: String as PropType<NotificationAlign>,
51
+ default: 'right',
52
+ validator: (value: string) => validators.align.includes(value),
53
+ },
54
+ position: {
55
+ type: String as PropType<NotificationPosition>,
56
+ default: 'bottom',
57
+ validator: (value: string) => validators.position.includes(value),
58
+ },
59
+ timeout: {
60
+ type: Number,
61
+ default: 3500,
40
62
  },
63
+ removable: {
64
+ type: Boolean,
65
+ default: true,
66
+ },
67
+ injectKey: {
68
+ type: [Symbol, String],
69
+ default: injectNotificationKey,
70
+ },
71
+ })
41
72
 
42
- validators,
73
+ const internalAlign = ref(props.align)
74
+ const internalPosition = ref(props.position)
75
+ const notifications = ref<NotificationEvent []>([])
76
+ const listRef = ref<HTMLElement | null>(null)
77
+ const css = useCSS('notification')
78
+ const colors = useColors()
79
+
80
+ provide(props.injectKey, {
81
+ log,
82
+ info,
83
+ warn,
84
+ error,
85
+ warning: warn,
86
+ success,
87
+ })
43
88
 
44
- props: {
45
- ...useColors.props('primary'),
46
- align: {
47
- type: String as PropType<NotificationAlign>,
48
- default: 'right',
49
- validator: (value: string) => validators.align.includes(value),
50
- },
51
- position: {
52
- type: String as PropType<NotificationPosition>,
53
- default: 'bottom',
54
- validator: (value: string) => validators.position.includes(value),
55
- },
56
- timeout: {
57
- type: Number,
58
- default: 3500,
89
+ watch(() => props.align, (align) => { internalAlign.value = align })
90
+ watch(() => props.position, (position) => { internalPosition.value = position })
91
+
92
+ function log(notification: NotificationEvent | string) {
93
+ const isMessage = typeof notification === 'string'
94
+ const preset = {
95
+ message: isMessage ? notification : undefined,
96
+ }
97
+
98
+ add(isMessage ? preset : {
99
+ ...preset,
100
+ ...notification,
101
+ })
102
+ }
103
+
104
+ function info(notification: NotificationEvent | string) {
105
+ const isMessage = typeof notification === 'string'
106
+ const preset = {
107
+ icon: '<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd" />',
108
+ iconColor: 'sky',
109
+ message: isMessage ? notification : undefined,
110
+ }
111
+
112
+ add(isMessage ? preset : {
113
+ ...preset,
114
+ ...notification,
115
+ })
116
+ }
117
+
118
+ function success(notification: NotificationEvent | string) {
119
+ const isMessage = typeof notification === 'string'
120
+ const preset = {
121
+ icon: '<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />',
122
+ iconColor: 'success',
123
+ message: isMessage ? notification : undefined,
124
+ }
125
+
126
+ add(isMessage ? preset : {
127
+ ...preset,
128
+ ...notification,
129
+ })
130
+ }
131
+
132
+ function warn(notification: NotificationEvent | string) {
133
+ const isMessage = typeof notification === 'string'
134
+ const preset = {
135
+ icon: '<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />',
136
+ iconColor: 'warning',
137
+ message: isMessage ? notification : undefined,
138
+ }
139
+
140
+ add(isMessage ? preset : {
141
+ ...preset,
142
+ ...notification,
143
+ })
144
+ }
145
+
146
+ function error(notification: NotificationEvent | string) {
147
+ const isMessage = typeof notification === 'string'
148
+ const preset = {
149
+ icon: '<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />',
150
+ iconColor: 'error',
151
+ message: isMessage ? notification : undefined,
152
+ }
153
+
154
+ add(isMessage ? preset : {
155
+ ...preset,
156
+ ...notification,
157
+ })
158
+ }
159
+
160
+ function add(notification: NotificationEvent) {
161
+ const mergeProps = {
162
+ id: Date.now(),
163
+ iconColor: props.color,
164
+ timeout: props.timeout,
165
+ align: internalAlign.value,
166
+ position: internalPosition.value,
167
+ removable: props.removable,
168
+ }
169
+
170
+ const merged = {
171
+ ...mergeProps,
172
+ ...notification,
173
+ }
174
+
175
+ internalAlign.value = merged.align
176
+ internalPosition.value = merged.position
177
+
178
+ const color = colors.getPalette(merged.iconColor)
179
+ const colorAction = colors.getPalette(merged.action?.color || 'primary')
180
+
181
+ const cssVariables = css.variables({
182
+ icon: color[400],
183
+ action: colorAction[400],
184
+ hover: {
185
+ action: colorAction[500],
59
186
  },
60
- removable: {
61
- type: Boolean,
62
- default: true,
187
+ dark: {
188
+ icon: color[500],
189
+ action: colorAction[500],
190
+ hover: {
191
+ action: colorAction[600],
192
+ },
63
193
  },
64
- },
194
+ })
65
195
 
66
- expose: ['log', 'info', 'success', 'warn', 'warning', 'error'],
67
-
68
- setup(props) {
69
- const internalAlign = ref(props.align)
70
- const internalPosition = ref(props.position)
71
- const notifications = ref<NotificationEvent []>([])
72
- const listRef = ref<HTMLElement | null>(null)
73
- const css = useCSS('notification')
74
- const colors = useColors()
75
-
76
- const removeIcon = '<path d="M6 18L18 6M6 6l12 12" />'
77
-
78
- provide(injectNotificationKey, {
79
- log,
80
- info,
81
- warn,
82
- error,
83
- warning: warn,
84
- success,
85
- })
86
-
87
- watch(() => props.align, (align) => { internalAlign.value = align })
88
- watch(() => props.position, (position) => { internalPosition.value = position })
89
-
90
- function log(notification: NotificationEvent | string) {
91
- const isMessage = typeof notification === 'string'
92
- const preset = {
93
- message: isMessage ? notification : undefined,
94
- }
95
-
96
- add(isMessage ? preset : {
97
- ...preset,
98
- ...notification,
99
- })
100
- }
101
-
102
- function info(notification: NotificationEvent | string) {
103
- const isMessage = typeof notification === 'string'
104
- const preset = {
105
- icon: '<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd" />',
106
- iconColor: 'sky',
107
- message: isMessage ? notification : undefined,
108
- }
109
-
110
- add(isMessage ? preset : {
111
- ...preset,
112
- ...notification,
113
- })
114
- }
115
-
116
- function success(notification: NotificationEvent | string) {
117
- const isMessage = typeof notification === 'string'
118
- const preset = {
119
- icon: '<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />',
120
- iconColor: 'success',
121
- message: isMessage ? notification : undefined,
122
- }
123
-
124
- add(isMessage ? preset : {
125
- ...preset,
126
- ...notification,
127
- })
128
- }
129
-
130
- function warn(notification: NotificationEvent | string) {
131
- const isMessage = typeof notification === 'string'
132
- const preset = {
133
- icon: '<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />',
134
- iconColor: 'warning',
135
- message: isMessage ? notification : undefined,
136
- }
137
-
138
- add(isMessage ? preset : {
139
- ...preset,
140
- ...notification,
141
- })
142
- }
143
-
144
- function error(notification: NotificationEvent | string) {
145
- const isMessage = typeof notification === 'string'
146
- const preset = {
147
- icon: '<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />',
148
- iconColor: 'error',
149
- message: isMessage ? notification : undefined,
150
- }
151
-
152
- add(isMessage ? preset : {
153
- ...preset,
154
- ...notification,
155
- })
156
- }
157
-
158
- function add(notification: NotificationEvent) {
159
- const mergeProps = {
160
- id: Date.now(),
161
- iconColor: props.color,
162
- timeout: props.timeout,
163
- align: internalAlign.value,
164
- position: internalPosition.value,
165
- removable: props.removable,
166
- }
167
-
168
- const merged = {
169
- ...mergeProps,
170
- ...notification,
171
- }
172
-
173
- internalAlign.value = merged.align
174
- internalPosition.value = merged.position
175
-
176
- const color = colors.getPalette(merged.iconColor)
177
- const colorAction = colors.getPalette(merged.action?.color || 'primary')
178
-
179
- const cssVariables = css.variables({
180
- icon: color[400],
181
- action: colorAction[400],
182
- hover: {
183
- action: colorAction[500],
184
- },
185
- dark: {
186
- icon: color[500],
187
- action: colorAction[500],
188
- hover: {
189
- action: colorAction[600],
190
- },
191
- },
192
- })
193
-
194
- merged.style = Object.keys(cssVariables).map((key) => `${key}: ${cssVariables[key]}`).join(';')
195
-
196
- notifications.value.push(merged)
197
-
198
- listRef.value?.scrollTo({ top: 0, behavior: 'smooth' })
199
-
200
- if (merged.timeout) setTimer(merged, merged.timeout)
201
- }
202
-
203
- function remove(event: NotificationEvent) {
204
- notifications.value = notifications.value.filter((e) => e.id !== event.id)
205
- }
206
-
207
- function setTimer(notification: NotificationEvent, timeout: number) {
208
- setTimeout(() => {
209
- remove(notification)
210
- }, timeout)
211
- }
212
-
213
- return {
214
- notifications,
215
- listRef,
216
- remove,
217
- log,
218
- info,
219
- warn,
220
- error,
221
- warning: warn,
222
- success,
223
- removeIcon,
224
- internalAlign,
225
- internalPosition,
226
- }
227
- },
196
+ merged.style = Object.keys(cssVariables).map((key) => `${key}: ${cssVariables[key]}`).join(';')
228
197
 
229
- })
198
+ notifications.value.push(merged)
199
+
200
+ listRef.value?.scrollTo({ top: 0, behavior: 'smooth' })
201
+
202
+ if (merged.timeout) setTimer(merged, merged.timeout)
203
+ }
204
+
205
+ function remove(event: NotificationEvent) {
206
+ notifications.value = notifications.value.filter((e) => e.id !== event.id)
207
+ }
208
+
209
+ function setTimer(notification: NotificationEvent, timeout: number) {
210
+ setTimeout(() => {
211
+ remove(notification)
212
+ }, timeout)
213
+ }
214
+
215
+ const { styles, classes, className } = useTheme('notification', theme, props)
216
+
217
+ defineExpose({ log, info, success, warn, warning: warn, error })
230
218
  </script>
231
219
 
232
220
  <template>
233
221
  <slot></slot>
234
- <Teleport to="body">
222
+ <teleport to="body">
235
223
  <div
236
224
  ref="listRef"
237
- class="fixed z-40 w-full sm:w-auto overflow-y-auto max-h-screen"
238
- :class="{
239
- // align
240
- 'left-0': internalAlign === 'left',
241
- 'right-0': internalAlign === 'right',
242
- // position
243
- 'top-0': internalPosition === 'top',
244
- 'bottom-0': internalPosition === 'bottom',
245
- }"
225
+ :style="styles"
226
+ :class="[
227
+ className,
228
+ classes.wrapper,
229
+ {
230
+ // align
231
+ 'left-0': internalAlign === 'left',
232
+ 'right-0': internalAlign === 'right',
233
+ // position
234
+ 'top-0': internalPosition === 'top',
235
+ 'bottom-0': internalPosition === 'bottom',
236
+ }]"
246
237
  >
247
238
  <transition-group
248
239
  tag="ul"
249
- class="flex flex-col items-end"
250
- :class="{ 'flex-col-reverse': internalPosition }"
240
+ :class="[
241
+ classes.list,
242
+ { 'flex-col-reverse': internalPosition }
243
+ ]"
251
244
  enter-active-class="transition ease-out duration-200"
252
245
  leave-active-class="transition ease-out duration-100"
253
- enter-class="transform translate-y-2 opacity-0"
246
+ enter-from-class="transform translate-y-2 opacity-0"
254
247
  enter-to-class="transform translate-y-0 opacity-100"
255
- leave-class="transform translate-y-0 opacity-100"
248
+ leave-from-class="transform translate-y-0 opacity-100"
256
249
  leave-to-class="transform translate-y-2 opacity-0"
257
250
  move-class="ease-in-out duration-200"
258
- mode="out-in"
259
251
  >
260
252
  <li
261
253
  v-for="notification in notifications"
262
254
  :key="notification.id"
263
- class="w-full sm:w-[520px]"
264
255
  :class="[
265
- 'px-4',
256
+ classes.item,
266
257
  {
267
- 'pb-2': internalPosition === 'bottom',
268
- 'pt-2': internalPosition === 'top',
269
- }
270
- ]"
258
+ 'mb-2': internalPosition === 'bottom',
259
+ 'mt-2': internalPosition === 'top',
260
+ }]"
271
261
  :style="notification.style"
272
262
  >
273
- <div
274
- class="flex items-center rounded-md px-4 py-3 bg-gray-800 dark:bg-gray-50 text-white dark:text-gray-900"
275
- >
276
- <x-icon
277
- v-if="notification.icon"
278
- filled
279
- :icon="notification.icon"
280
- class="
281
- mr-4 shrink-0
263
+ <x-icon
264
+ v-if="notification.icon"
265
+ filled
266
+ :icon="notification.icon"
267
+ class="
268
+ mr-4
282
269
  text-[color:var(--x-notification-icon)]
283
- dark:text-[color:var(--x-dark-notification-icon)]
270
+ dark:text-[color:var(--x-notification-dark-icon)]
284
271
  "
285
- viewBox="0 0 20 20"
286
- />
287
- <div class="flex items-center flex-wrap">
288
- <span v-if="notification.title" class="font-semibold mr-2">{{ notification.title }}</span>
289
- <span>{{ notification.message }}</span>
290
- </div>
291
- <x-spacer/>
292
- <div
293
- v-if="notification.action"
294
- class="
272
+ viewBox="0 0 20 20"
273
+ />
274
+ <div class="flex items-center flex-wrap">
275
+ <span v-if="notification.title" class="font-semibold mr-2">{{ notification.title }}</span>
276
+ <span>{{ notification.message }}</span>
277
+ </div>
278
+ <x-spacer/>
279
+ <div
280
+ v-if="notification.action"
281
+ class="
295
282
  ml-3
296
283
  font-semibold
297
284
  cursor-pointer
298
285
  text-[color:var(--x-notification-action)]
299
286
  hover:text-[color:var(--x-notification-action-hover)]
300
- dark:text-[color:var(--x-dark-notification-action)]
301
- dark:hover:text-[color:var(--x-dark-notification-action-hover)]
287
+ dark:text-[color:var(--x-notification-dark-action)]
288
+ dark:hover:text-[color:var(--x-notification-dark-action-hover)]
302
289
  "
303
- @click="notification.action.onClick"
304
- >
305
- {{ notification.action.label }}
306
- </div>
307
- <x-icon
308
- v-if="notification.removable"
309
- :icon="removeIcon"
310
- class="text-gray-400 hover:text-gray-500 ml-3 shrink-0 cursor-pointer"
311
- @click="() => {remove(notification)}"
312
- />
290
+ @click="notification.action.onClick"
291
+ >
292
+ {{ notification.action.label }}
313
293
  </div>
294
+ <x-icon
295
+ v-if="notification.removable"
296
+ :icon="closeIcon"
297
+ class="text-gray-400 hover:text-gray-500 ml-3 cursor-pointer"
298
+ @click="() => {remove(notification)}"
299
+ />
314
300
  </li>
315
301
  </transition-group>
316
302
  </div>
317
- </Teleport>
303
+ </teleport>
318
304
  </template>
@@ -0,0 +1,11 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { mount } from '@vue/test-utils'
3
+ import Notifications from '../Notifications.vue'
4
+
5
+ describe('Notifications', () => {
6
+ it('renders without errors', () => {
7
+ const wrapper = mount(Notifications)
8
+
9
+ expect(wrapper.vm).toBeTruthy()
10
+ })
11
+ })
@@ -0,0 +1,27 @@
1
+ import type { ThemeParams } from '../../composables/theme'
2
+
3
+ export default {
4
+ classes: {
5
+ wrapper: ({ props }: ThemeParams) => {
6
+ if (props.variant === 'simple') return 'flex items-center space-x-2'
7
+ else if (props.variant === 'dots') return 'flex space-x-6'
8
+
9
+ return 'flex items-center' // quick variant
10
+ },
11
+
12
+ dots: ({ props }: ThemeParams) => {
13
+ if (props.size === 'xs') return 'h-2 w-2'
14
+ else if (props.size === 'sm') return 'h-3 w-3'
15
+ else if (props.size === 'lg') return 'h-4 w-4'
16
+ else if (props.size === 'xl') return 'h-5 w-5'
17
+
18
+ return 'h-3 w-3'
19
+ },
20
+ },
21
+
22
+ styles: ({ props, css, colors }: ThemeParams) => {
23
+ const color = colors.getPalette('primary')
24
+
25
+ return css.get('bg', color[500])
26
+ },
27
+ }