@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
@@ -1,16 +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'
8
- import XSpacer from '../../components/spacer/Spacer.vue'
22
+ import XSpacer from '../spacer/Spacer'
9
23
 
10
- const validators = {
11
- align: ['left','right'],
12
- position: ['bottom','top'],
13
- }
24
+ import theme from './Notifications.theme'
14
25
 
15
26
  export type NotificationAlign = 'left' | 'right'
16
27
  export type NotificationPosition = 'bottom' | 'top'
@@ -33,288 +44,261 @@ export type NotificationEvent = {
33
44
  position?: NotificationPosition
34
45
  }
35
46
 
36
- export default defineComponent({
37
- name: 'XNotifications',
38
-
39
- components: {
40
- XIcon,
41
- XSpacer,
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,
42
62
  },
63
+ removable: {
64
+ type: Boolean,
65
+ default: true,
66
+ },
67
+ injectKey: {
68
+ type: [Symbol, String],
69
+ default: injectNotificationKey,
70
+ },
71
+ })
43
72
 
44
- 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
+ })
45
88
 
46
- props: {
47
- ...useColors.props('primary'),
48
- align: {
49
- type: String as PropType<NotificationAlign>,
50
- default: 'right',
51
- validator: (value: string) => validators.align.includes(value),
52
- },
53
- position: {
54
- type: String as PropType<NotificationPosition>,
55
- default: 'bottom',
56
- validator: (value: string) => validators.position.includes(value),
57
- },
58
- timeout: {
59
- type: Number,
60
- 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],
61
186
  },
62
- removable: {
63
- type: Boolean,
64
- default: true,
187
+ dark: {
188
+ icon: color[500],
189
+ action: colorAction[500],
190
+ hover: {
191
+ action: colorAction[600],
192
+ },
65
193
  },
66
- },
194
+ })
67
195
 
68
- expose: ['log', 'info', 'success', 'warn', 'warning', 'error'],
69
-
70
- setup(props) {
71
- const internalAlign = ref(props.align)
72
- const internalPosition = ref(props.position)
73
- const notifications = ref<NotificationEvent []>([])
74
- const listRef = ref<HTMLElement | null>(null)
75
- const css = useCSS('notification')
76
- const colors = useColors()
77
-
78
- const removeIcon = '<path d="M6 18L18 6M6 6l12 12" />'
79
-
80
- provide(injectNotificationKey, {
81
- log,
82
- info,
83
- warn,
84
- error,
85
- warning: warn,
86
- success,
87
- })
88
-
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],
186
- },
187
- dark: {
188
- icon: color[500],
189
- action: colorAction[500],
190
- hover: {
191
- action: colorAction[600],
192
- },
193
- },
194
- })
195
-
196
- merged.style = Object.keys(cssVariables).map((key) => `${key}: ${cssVariables[key]}`).join(';')
197
-
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
- return {
216
- notifications,
217
- listRef,
218
- remove,
219
- log,
220
- info,
221
- warn,
222
- error,
223
- warning: warn,
224
- success,
225
- removeIcon,
226
- internalAlign,
227
- internalPosition,
228
- }
229
- },
196
+ merged.style = Object.keys(cssVariables).map((key) => `${key}: ${cssVariables[key]}`).join(';')
230
197
 
231
- })
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 })
232
218
  </script>
233
219
 
234
220
  <template>
235
221
  <slot></slot>
236
- <Teleport to="body">
222
+ <teleport to="body">
237
223
  <div
238
224
  ref="listRef"
239
- class="fixed z-40 w-full sm:w-auto overflow-y-auto max-h-screen"
240
- :class="{
241
- // align
242
- 'left-0': internalAlign === 'left',
243
- 'right-0': internalAlign === 'right',
244
- // position
245
- 'top-0': internalPosition === 'top',
246
- 'bottom-0': internalPosition === 'bottom',
247
- }"
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
+ }]"
248
237
  >
249
238
  <transition-group
250
239
  tag="ul"
251
- class="flex flex-col items-end"
252
- :class="{ 'flex-col-reverse': internalPosition }"
240
+ :class="[
241
+ classes.list,
242
+ { 'flex-col-reverse': internalPosition }
243
+ ]"
253
244
  enter-active-class="transition ease-out duration-200"
254
245
  leave-active-class="transition ease-out duration-100"
255
- enter-class="transform translate-y-2 opacity-0"
246
+ enter-from-class="transform translate-y-2 opacity-0"
256
247
  enter-to-class="transform translate-y-0 opacity-100"
257
- leave-class="transform translate-y-0 opacity-100"
248
+ leave-from-class="transform translate-y-0 opacity-100"
258
249
  leave-to-class="transform translate-y-2 opacity-0"
259
250
  move-class="ease-in-out duration-200"
260
- mode="out-in"
261
251
  >
262
252
  <li
263
253
  v-for="notification in notifications"
264
254
  :key="notification.id"
265
- class="w-full sm:w-[520px]"
266
255
  :class="[
267
- 'px-4',
256
+ classes.item,
268
257
  {
269
- 'pb-2': internalPosition === 'bottom',
270
- 'pt-2': internalPosition === 'top',
271
- }
272
- ]"
258
+ 'mb-2': internalPosition === 'bottom',
259
+ 'mt-2': internalPosition === 'top',
260
+ }]"
273
261
  :style="notification.style"
274
262
  >
275
- <div
276
- class="flex items-center rounded-md px-4 py-3 bg-gray-800 dark:bg-gray-50 text-white dark:text-gray-900"
277
- >
278
- <x-icon
279
- v-if="notification.icon"
280
- filled
281
- :icon="notification.icon"
282
- class="
283
- mr-4 shrink-0
263
+ <x-icon
264
+ v-if="notification.icon"
265
+ filled
266
+ :icon="notification.icon"
267
+ class="
268
+ mr-4
284
269
  text-[color:var(--x-notification-icon)]
285
- dark:text-[color:var(--x-dark-notification-icon)]
270
+ dark:text-[color:var(--x-notification-dark-icon)]
286
271
  "
287
- viewBox="0 0 20 20"
288
- />
289
- <div class="flex items-center flex-wrap">
290
- <span v-if="notification.title" class="font-semibold mr-2">{{ notification.title }}</span>
291
- <span>{{ notification.message }}</span>
292
- </div>
293
- <x-spacer/>
294
- <div
295
- v-if="notification.action"
296
- 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="
297
282
  ml-3
298
283
  font-semibold
299
284
  cursor-pointer
300
285
  text-[color:var(--x-notification-action)]
301
286
  hover:text-[color:var(--x-notification-action-hover)]
302
- dark:text-[color:var(--x-dark-notification-action)]
303
- 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)]
304
289
  "
305
- @click="notification.action.onClick"
306
- >
307
- {{ notification.action.label }}
308
- </div>
309
- <x-icon
310
- v-if="notification.removable"
311
- :icon="removeIcon"
312
- class="text-gray-400 hover:text-gray-500 ml-3 shrink-0 cursor-pointer"
313
- @click="() => {remove(notification)}"
314
- />
290
+ @click="notification.action.onClick"
291
+ >
292
+ {{ notification.action.label }}
315
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
+ />
316
300
  </li>
317
301
  </transition-group>
318
302
  </div>
319
- </Teleport>
303
+ </teleport>
320
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
+ }