@personizely/ui 0.0.42

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 (221) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +1 -0
  3. package/dist/personizely-ui.css +6 -0
  4. package/dist/personizely-ui.js +26854 -0
  5. package/dist/personizely-ui.umd.cjs +111 -0
  6. package/package.json +117 -0
  7. package/src/assets/index.css +136 -0
  8. package/src/components/ui/accordion/Accordion.vue +19 -0
  9. package/src/components/ui/accordion/AccordionContent.vue +24 -0
  10. package/src/components/ui/accordion/AccordionItem.vue +37 -0
  11. package/src/components/ui/accordion/AccordionTrigger.vue +39 -0
  12. package/src/components/ui/accordion/index.ts +2 -0
  13. package/src/components/ui/alert/Alert.vue +68 -0
  14. package/src/components/ui/alert/index.ts +22 -0
  15. package/src/components/ui/alert-dialog/AlertDialog.vue +66 -0
  16. package/src/components/ui/alert-dialog/AlertDialogContent.vue +44 -0
  17. package/src/components/ui/alert-dialog/AlertDialogProvider.vue +27 -0
  18. package/src/components/ui/alert-dialog/AlertDialogTrigger.vue +11 -0
  19. package/src/components/ui/alert-dialog/index.ts +3 -0
  20. package/src/components/ui/alert-dialog/useAlertDialog.ts +19 -0
  21. package/src/components/ui/autocomplete/Autocomplete.vue +170 -0
  22. package/src/components/ui/autocomplete/AutocompleteContent.vue +27 -0
  23. package/src/components/ui/autocomplete/AutocompleteEmpty.vue +20 -0
  24. package/src/components/ui/autocomplete/AutocompleteGroup.vue +29 -0
  25. package/src/components/ui/autocomplete/AutocompleteItem.vue +26 -0
  26. package/src/components/ui/autocomplete/AutocompleteRoot.vue +31 -0
  27. package/src/components/ui/autocomplete/AutocompleteSeparator.vue +23 -0
  28. package/src/components/ui/autocomplete/index.ts +1 -0
  29. package/src/components/ui/avatar/Avatar.vue +31 -0
  30. package/src/components/ui/avatar/AvatarFallback.vue +11 -0
  31. package/src/components/ui/avatar/AvatarImage.vue +9 -0
  32. package/src/components/ui/avatar/index.ts +19 -0
  33. package/src/components/ui/badge/Badge.vue +16 -0
  34. package/src/components/ui/badge/index.ts +22 -0
  35. package/src/components/ui/button/Button.vue +123 -0
  36. package/src/components/ui/button/index.ts +78 -0
  37. package/src/components/ui/calendar/Calendar.vue +76 -0
  38. package/src/components/ui/calendar/CalendarCell.vue +24 -0
  39. package/src/components/ui/calendar/CalendarCellTrigger.vue +38 -0
  40. package/src/components/ui/calendar/CalendarGrid.vue +24 -0
  41. package/src/components/ui/calendar/CalendarGridBody.vue +11 -0
  42. package/src/components/ui/calendar/CalendarGridHead.vue +11 -0
  43. package/src/components/ui/calendar/CalendarGridRow.vue +21 -0
  44. package/src/components/ui/calendar/CalendarHeadCell.vue +21 -0
  45. package/src/components/ui/calendar/CalendarHeader.vue +21 -0
  46. package/src/components/ui/calendar/CalendarHeading.vue +27 -0
  47. package/src/components/ui/calendar/CalendarNextButton.vue +32 -0
  48. package/src/components/ui/calendar/CalendarPrevButton.vue +32 -0
  49. package/src/components/ui/calendar/index.ts +1 -0
  50. package/src/components/ui/card/Card.vue +57 -0
  51. package/src/components/ui/card/CardContent.vue +14 -0
  52. package/src/components/ui/card/CardDescription.vue +14 -0
  53. package/src/components/ui/card/CardFooter.vue +14 -0
  54. package/src/components/ui/card/CardHeader.vue +14 -0
  55. package/src/components/ui/card/CardTitle.vue +18 -0
  56. package/src/components/ui/card/CardTray.vue +14 -0
  57. package/src/components/ui/card/index.ts +1 -0
  58. package/src/components/ui/checkbox/Checkbox.vue +63 -0
  59. package/src/components/ui/checkbox/CheckboxBase.vue +39 -0
  60. package/src/components/ui/checkbox/index.ts +1 -0
  61. package/src/components/ui/checkbox-group/CheckboxGroup.vue +65 -0
  62. package/src/components/ui/checkbox-group/index.ts +15 -0
  63. package/src/components/ui/color-picker/Alpha.vue +63 -0
  64. package/src/components/ui/color-picker/Angle.vue +145 -0
  65. package/src/components/ui/color-picker/Checkboard.vue +43 -0
  66. package/src/components/ui/color-picker/Color.vue +255 -0
  67. package/src/components/ui/color-picker/ColorPicker.vue +25 -0
  68. package/src/components/ui/color-picker/Gradient.vue +172 -0
  69. package/src/components/ui/color-picker/Handle.vue +19 -0
  70. package/src/components/ui/color-picker/Hue.vue +80 -0
  71. package/src/components/ui/color-picker/LabelInput.vue +16 -0
  72. package/src/components/ui/color-picker/Rail.vue +100 -0
  73. package/src/components/ui/color-picker/Saturation.vue +142 -0
  74. package/src/components/ui/color-picker/index.ts +4 -0
  75. package/src/components/ui/combobox/Combobox.vue +202 -0
  76. package/src/components/ui/combobox/ComboboxContent.vue +27 -0
  77. package/src/components/ui/combobox/ComboboxEmpty.vue +20 -0
  78. package/src/components/ui/combobox/ComboboxGroup.vue +29 -0
  79. package/src/components/ui/combobox/ComboboxInput.vue +52 -0
  80. package/src/components/ui/combobox/ComboboxItem.vue +26 -0
  81. package/src/components/ui/combobox/ComboboxRoot.vue +31 -0
  82. package/src/components/ui/combobox/ComboboxSeparator.vue +23 -0
  83. package/src/components/ui/combobox/index.ts +1 -0
  84. package/src/components/ui/date-picker/DatePicker.vue +55 -0
  85. package/src/components/ui/date-picker/index.ts +1 -0
  86. package/src/components/ui/date-range-picker/DateRangePicker.vue +137 -0
  87. package/src/components/ui/date-range-picker/index.ts +1 -0
  88. package/src/components/ui/dialog/Dialog.vue +78 -0
  89. package/src/components/ui/dialog/DialogContent.vue +46 -0
  90. package/src/components/ui/dialog/DialogDescription.vue +24 -0
  91. package/src/components/ui/dialog/DialogFooter.vue +19 -0
  92. package/src/components/ui/dialog/DialogHeader.vue +16 -0
  93. package/src/components/ui/dialog/DialogTitle.vue +29 -0
  94. package/src/components/ui/dialog/DialogTrigger.vue +11 -0
  95. package/src/components/ui/dialog/index.ts +1 -0
  96. package/src/components/ui/drawer/Drawer.vue +88 -0
  97. package/src/components/ui/drawer/DrawerContent.vue +57 -0
  98. package/src/components/ui/drawer/DrawerDescription.vue +22 -0
  99. package/src/components/ui/drawer/DrawerFooter.vue +19 -0
  100. package/src/components/ui/drawer/DrawerHeader.vue +16 -0
  101. package/src/components/ui/drawer/DrawerTitle.vue +22 -0
  102. package/src/components/ui/drawer/DrawerTrigger.vue +11 -0
  103. package/src/components/ui/drawer/index.ts +21 -0
  104. package/src/components/ui/dropdown-menu/DropdownCheckboxGroupMenu.vue +87 -0
  105. package/src/components/ui/dropdown-menu/DropdownMenu.vue +72 -0
  106. package/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +40 -0
  107. package/src/components/ui/dropdown-menu/DropdownMenuContent.vue +37 -0
  108. package/src/components/ui/dropdown-menu/DropdownMenuGroup.vue +11 -0
  109. package/src/components/ui/dropdown-menu/DropdownMenuHelp.vue +14 -0
  110. package/src/components/ui/dropdown-menu/DropdownMenuItem.vue +28 -0
  111. package/src/components/ui/dropdown-menu/DropdownMenuLabel.vue +24 -0
  112. package/src/components/ui/dropdown-menu/DropdownMenuPart.vue +64 -0
  113. package/src/components/ui/dropdown-menu/DropdownMenuPartItem.vue +76 -0
  114. package/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +19 -0
  115. package/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +41 -0
  116. package/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue +22 -0
  117. package/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue +14 -0
  118. package/src/components/ui/dropdown-menu/DropdownMenuSub.vue +19 -0
  119. package/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue +30 -0
  120. package/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +33 -0
  121. package/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue +13 -0
  122. package/src/components/ui/dropdown-menu/DropdownRadioGroupMenu.vue +75 -0
  123. package/src/components/ui/dropdown-menu/index.ts +36 -0
  124. package/src/components/ui/file-upload-button/FileUploadButton.vue +55 -0
  125. package/src/components/ui/file-upload-button/index.ts +1 -0
  126. package/src/components/ui/form/Form.vue +13 -0
  127. package/src/components/ui/form/FormControl.vue +16 -0
  128. package/src/components/ui/form/FormDescription.vue +20 -0
  129. package/src/components/ui/form/FormField.vue +61 -0
  130. package/src/components/ui/form/FormLabel.vue +23 -0
  131. package/src/components/ui/form/FormMessage.vue +16 -0
  132. package/src/components/ui/form/index.ts +2 -0
  133. package/src/components/ui/form/useFormField.ts +30 -0
  134. package/src/components/ui/icon/Icon.vue +16 -0
  135. package/src/components/ui/icon/index.ts +1 -0
  136. package/src/components/ui/input/Input.vue +51 -0
  137. package/src/components/ui/input/InputBase.vue +18 -0
  138. package/src/components/ui/input/index.ts +1 -0
  139. package/src/components/ui/label/Label.vue +27 -0
  140. package/src/components/ui/label/index.ts +1 -0
  141. package/src/components/ui/pagination/Pagination.vue +50 -0
  142. package/src/components/ui/pagination/PaginationContent.vue +21 -0
  143. package/src/components/ui/pagination/PaginationEllipsis.vue +24 -0
  144. package/src/components/ui/pagination/PaginationFirst.vue +32 -0
  145. package/src/components/ui/pagination/PaginationItem.vue +32 -0
  146. package/src/components/ui/pagination/PaginationLast.vue +32 -0
  147. package/src/components/ui/pagination/PaginationNext.vue +32 -0
  148. package/src/components/ui/pagination/PaginationPrevious.vue +32 -0
  149. package/src/components/ui/pagination/index.ts +1 -0
  150. package/src/components/ui/popover/Popover.vue +57 -0
  151. package/src/components/ui/popover/PopoverTrigger.vue +15 -0
  152. package/src/components/ui/popover/index.ts +1 -0
  153. package/src/components/ui/progress/Progress.vue +35 -0
  154. package/src/components/ui/progress/ProgressIndicator.vue +19 -0
  155. package/src/components/ui/progress/index.ts +2 -0
  156. package/src/components/ui/progress-circular/ProgressCircular.vue +85 -0
  157. package/src/components/ui/progress-circular/index.ts +1 -0
  158. package/src/components/ui/radio-group/RadioGroup.vue +81 -0
  159. package/src/components/ui/radio-group/RadioGroupItem.vue +39 -0
  160. package/src/components/ui/radio-group/index.ts +15 -0
  161. package/src/components/ui/range-calendar/RangeCalendar.vue +71 -0
  162. package/src/components/ui/range-calendar/RangeCalendarCell.vue +28 -0
  163. package/src/components/ui/range-calendar/RangeCalendarCellTrigger.vue +40 -0
  164. package/src/components/ui/range-calendar/RangeCalendarGrid.vue +24 -0
  165. package/src/components/ui/range-calendar/RangeCalendarGridBody.vue +11 -0
  166. package/src/components/ui/range-calendar/RangeCalendarGridHead.vue +11 -0
  167. package/src/components/ui/range-calendar/RangeCalendarGridRow.vue +21 -0
  168. package/src/components/ui/range-calendar/RangeCalendarHeadCell.vue +21 -0
  169. package/src/components/ui/range-calendar/RangeCalendarHeader.vue +21 -0
  170. package/src/components/ui/range-calendar/RangeCalendarHeading.vue +27 -0
  171. package/src/components/ui/range-calendar/RangeCalendarNextButton.vue +32 -0
  172. package/src/components/ui/range-calendar/RangeCalendarPrevButton.vue +32 -0
  173. package/src/components/ui/range-calendar/index.ts +1 -0
  174. package/src/components/ui/select/Select.vue +120 -0
  175. package/src/components/ui/select/SelectContent.vue +45 -0
  176. package/src/components/ui/select/SelectGroup.vue +19 -0
  177. package/src/components/ui/select/SelectItem.vue +43 -0
  178. package/src/components/ui/select/SelectLabel.vue +13 -0
  179. package/src/components/ui/select/SelectSeparator.vue +17 -0
  180. package/src/components/ui/select/SelectTrigger.vue +31 -0
  181. package/src/components/ui/select/SelectValue.vue +11 -0
  182. package/src/components/ui/select/index.ts +1 -0
  183. package/src/components/ui/slider/Slider.vue +100 -0
  184. package/src/components/ui/slider/index.ts +1 -0
  185. package/src/components/ui/switch/Switch.vue +40 -0
  186. package/src/components/ui/switch/SwitchBase.vue +36 -0
  187. package/src/components/ui/switch/index.ts +1 -0
  188. package/src/components/ui/tabs/Tabs.vue +63 -0
  189. package/src/components/ui/tabs/TabsContent.vue +26 -0
  190. package/src/components/ui/tabs/TabsTrigger.vue +27 -0
  191. package/src/components/ui/tabs/index.ts +28 -0
  192. package/src/components/ui/textarea/Textarea.vue +13 -0
  193. package/src/components/ui/textarea/index.ts +1 -0
  194. package/src/components/ui/toast/Toast.vue +28 -0
  195. package/src/components/ui/toast/ToastAction.vue +26 -0
  196. package/src/components/ui/toast/ToastClose.vue +29 -0
  197. package/src/components/ui/toast/ToastDescription.vue +19 -0
  198. package/src/components/ui/toast/ToastProvider.vue +11 -0
  199. package/src/components/ui/toast/ToastTitle.vue +19 -0
  200. package/src/components/ui/toast/ToastViewport.vue +17 -0
  201. package/src/components/ui/toast/Toaster.vue +30 -0
  202. package/src/components/ui/toast/index.ts +34 -0
  203. package/src/components/ui/toast/useToast.ts +163 -0
  204. package/src/components/ui/toggle/Toggle.vue +51 -0
  205. package/src/components/ui/toggle/index.ts +71 -0
  206. package/src/components/ui/toggle-group/ToggleGroup.vue +58 -0
  207. package/src/components/ui/toggle-group/ToggleGroupItem.vue +54 -0
  208. package/src/components/ui/toggle-group/index.ts +1 -0
  209. package/src/components/ui/tooltip/Tooltip.vue +42 -0
  210. package/src/components/ui/tooltip/TooltipProvider.vue +11 -0
  211. package/src/components/ui/tooltip/index.ts +2 -0
  212. package/src/composables/delegated-props.ts +6 -0
  213. package/src/composables/emits-as-props.ts +17 -0
  214. package/src/composables/forward-props-emits.ts +11 -0
  215. package/src/directives/autofocus.ts +7 -0
  216. package/src/index.ts +159 -0
  217. package/src/options-provider.ts +19 -0
  218. package/src/utils/gradient.ts +158 -0
  219. package/src/utils/options.ts +40 -0
  220. package/src/utils/tailwind.ts +14 -0
  221. package/web-types.json +10560 -0
@@ -0,0 +1,6 @@
1
+ import { type MaybeRefOrGetter, computed } from 'vue'
2
+ import omit from 'lodash/omit'
3
+
4
+ export function useDelegatedProps<T extends Record<string, any>> (props: MaybeRefOrGetter<T>, exclude: Array<string> = []) {
5
+ return computed(() => omit(props, exclude))
6
+ }
@@ -0,0 +1,17 @@
1
+ import { camelize, getCurrentInstance, toHandlerKey } from 'vue'
2
+
3
+ export function useEmitAsProps<Name extends string> (emit: (name: Name, ...args: any[]) => void, exclude: Array<string> = []) {
4
+ const vm = getCurrentInstance()
5
+
6
+ const events = vm?.type.emits as Name[]
7
+ const result: Record<string, any> = {}
8
+
9
+ if (!events?.length) {
10
+ console.warn(`No emitted event found. Please check component: ${vm?.type.__name}`)
11
+ }
12
+
13
+ events?.filter(ev => !exclude.includes(ev)).forEach((ev) => {
14
+ result[toHandlerKey(camelize(ev))] = (...arg: any) => emit(ev, ...arg)
15
+ })
16
+ return result
17
+ }
@@ -0,0 +1,11 @@
1
+ import { type MaybeRefOrGetter, computed, toRef } from 'vue'
2
+ import { useForwardProps } from 'reka-ui'
3
+
4
+ export function useForwardPropsEmits<T extends Record<string, any>> (props: MaybeRefOrGetter<T>, emitProps: T) {
5
+ const parsedProps = toRef(useForwardProps(props))
6
+
7
+ return computed(() => ({
8
+ ...parsedProps.value,
9
+ ...emitProps
10
+ }))
11
+ }
@@ -0,0 +1,7 @@
1
+ export default {
2
+ mounted (el: HTMLElement, { value }: { value: boolean }) {
3
+ if (value) {
4
+ requestAnimationFrame(() => el.focus())
5
+ }
6
+ }
7
+ }
package/src/index.ts ADDED
@@ -0,0 +1,159 @@
1
+ import '@/assets/index.css'
2
+ import type { App, Component } from 'vue'
3
+
4
+ import { Accordion, AccordionItem } from '@/components/ui/accordion'
5
+ import { Alert } from '@/components/ui/alert'
6
+ import { Avatar } from '@/components/ui/avatar'
7
+ import { AlertDialog, AlertDialogProvider, useAlertDialog } from '@/components/ui/alert-dialog'
8
+ import { Autocomplete } from '@/components/ui/autocomplete'
9
+ import { Badge } from '@/components/ui/badge'
10
+ import { Button } from '@/components/ui/button'
11
+ import { Card } from '@/components/ui/card'
12
+ import { Checkbox } from '@/components/ui/checkbox'
13
+ import { CheckboxGroup } from '@/components/ui/checkbox-group'
14
+ import { Color, ColorPicker, Gradient, Checkboard } from '@/components/ui/color-picker'
15
+ import { Combobox } from '@/components/ui/combobox'
16
+ import { DatePicker } from '@/components/ui/date-picker'
17
+ import { DateRangePicker } from '@/components/ui/date-range-picker'
18
+ import { Dialog } from '@/components/ui/dialog'
19
+ import { Drawer } from '@/components/ui/drawer'
20
+ import { DropdownMenu, DropdownCheckboxGroupMenu, DropdownRadioGroupMenu, type MenuItem } from '@/components/ui/dropdown-menu'
21
+ import { Input } from '@/components/ui/input'
22
+ import { FileUploadButton } from '@/components/ui/file-upload-button'
23
+ import { Icon } from '@/components/ui/icon'
24
+ import { Form, FormField } from '@/components/ui/form'
25
+ import { Pagination } from '@/components/ui/pagination'
26
+ import { Popover } from '@/components/ui/popover'
27
+ import { Progress, ProgressIndicator } from '@/components/ui/progress'
28
+ import { ProgressCircular } from '@/components/ui/progress-circular'
29
+ import { RadioGroup } from '@/components/ui/radio-group'
30
+ import { Select } from '@/components/ui/select'
31
+ import { Slider } from '@/components/ui/slider'
32
+ import { Switch } from '@/components/ui/switch'
33
+ import { Tabs, TabsContent } from '@/components/ui/tabs'
34
+ import { Textarea } from '@/components/ui/textarea'
35
+ import { Toaster, ToastAction, useToast } from '@/components/ui/toast'
36
+ import { Toggle } from '@/components/ui/toggle'
37
+ import { ToggleGroup } from '@/components/ui/toggle-group'
38
+ import { Tooltip, TooltipProvider } from '@/components/ui/tooltip'
39
+ import { type Options, setOptions } from './options-provider'
40
+ import { type Option } from '@/utils/options'
41
+
42
+ const components: { [key:string]: Component } = {
43
+ Accordion,
44
+ AccordionItem,
45
+ Alert,
46
+ Avatar,
47
+ AlertDialogProvider,
48
+ AlertDialog,
49
+ Autocomplete,
50
+ Badge,
51
+ Button,
52
+ Card,
53
+ Checkbox,
54
+ CheckboxGroup,
55
+ Color,
56
+ ColorPicker,
57
+ Gradient,
58
+ Checkboard,
59
+ Combobox,
60
+ DatePicker,
61
+ DateRangePicker,
62
+ Dialog,
63
+ Drawer,
64
+ DropdownMenu,
65
+ DropdownCheckboxGroupMenu,
66
+ DropdownRadioGroupMenu,
67
+ Input,
68
+ Icon,
69
+ Form,
70
+ FormField,
71
+ FileUploadButton,
72
+ Pagination,
73
+ Popover,
74
+ Progress,
75
+ ProgressIndicator,
76
+ ProgressCircular,
77
+ RadioGroup,
78
+ Select,
79
+ Slider,
80
+ Switch,
81
+ Tabs,
82
+ TabsContent,
83
+ Textarea,
84
+ Toaster,
85
+ Toggle,
86
+ ToggleGroup,
87
+ TooltipProvider,
88
+ Tooltip
89
+ }
90
+
91
+ export function install (app: App, options: Options = {}) {
92
+ setOptions(options)
93
+
94
+ Object.keys(components).forEach((key) => {
95
+ const Component = components[key]
96
+ app.component(`Ui${key}`, Component)
97
+ })
98
+ }
99
+
100
+ export default {
101
+ install
102
+ }
103
+
104
+ export {
105
+ components,
106
+ useAlertDialog,
107
+ useToast,
108
+ Accordion,
109
+ AccordionItem,
110
+ Alert,
111
+ Avatar,
112
+ AlertDialog,
113
+ AlertDialogProvider,
114
+ Autocomplete,
115
+ Badge,
116
+ Button,
117
+ Card,
118
+ Checkbox,
119
+ CheckboxGroup,
120
+ Color,
121
+ ColorPicker,
122
+ Combobox,
123
+ DatePicker,
124
+ DateRangePicker,
125
+ Dialog,
126
+ Drawer,
127
+ DropdownMenu,
128
+ DropdownCheckboxGroupMenu,
129
+ DropdownRadioGroupMenu,
130
+ Input,
131
+ Icon,
132
+ FileUploadButton,
133
+ Form,
134
+ FormField,
135
+ Pagination,
136
+ Popover,
137
+ Progress,
138
+ ProgressIndicator,
139
+ ProgressCircular,
140
+ RadioGroup,
141
+ Select,
142
+ Slider,
143
+ Switch,
144
+ Tabs,
145
+ TabsContent,
146
+ Textarea,
147
+ Toaster,
148
+ ToastAction,
149
+ Toggle,
150
+ ToggleGroup,
151
+ Tooltip,
152
+ TooltipProvider
153
+ }
154
+
155
+ export type {
156
+ Option,
157
+ Options,
158
+ MenuItem
159
+ }
@@ -0,0 +1,19 @@
1
+ type Options = { portalTo?: string | HTMLElement }
2
+
3
+ const options: Options = {
4
+ portalTo: 'body'
5
+ }
6
+
7
+ const setOptions = (payload: Partial<Options>) => {
8
+ Object.assign(options, payload)
9
+ }
10
+
11
+ const getOptions = () => {
12
+ return options
13
+ }
14
+
15
+ export {
16
+ type Options,
17
+ setOptions,
18
+ getOptions
19
+ }
@@ -0,0 +1,158 @@
1
+ import chroma, { type InterpolationMode } from 'chroma-js'
2
+
3
+
4
+ export type Point = { left: number, color: string }
5
+ type Gradient = {
6
+ points: Point[],
7
+ angle: number,
8
+ type: string,
9
+ precision?: number,
10
+ interpolation?: InterpolationMode
11
+ xAxis?: string
12
+ yAxis?: string
13
+ shape?: string
14
+ }
15
+
16
+ const extractType = (definition: string) => {
17
+ const match = /(linear|radial|conic)/gm.exec(definition)
18
+ return (match && match[0]) || 'linear'
19
+ }
20
+
21
+ const extractAngle = (definition: string) => {
22
+ const match = /((?<angle>\d+)deg)/gis.exec(definition)
23
+
24
+ return (match && Number(match.groups!.angle)) || 0
25
+ }
26
+
27
+ const extractShape = (definition: string, type: string) => {
28
+ if (type !== 'radial') return 'circle'
29
+
30
+ const shape = /(ellipse|circle)/gm.exec(definition)
31
+ return (shape && shape[0]) || 'circle'
32
+ }
33
+
34
+ const extractAxis = (definition: string, type: string) => {
35
+ if (type === 'linear') return { xAxis: '50%', yAxis: '50%' }
36
+
37
+ const match = /at\s(\d+%)\s(\d+%),/gis.exec(definition)
38
+ return match
39
+ ? { xAxis: match[1], yAxis: match[2] }
40
+ : { xAxis: '50%', yAxis: '50%' }
41
+ }
42
+
43
+ const extractColors = (gradient: string) => {
44
+ const rgba = gradient.match(/(rgba?\(\s?\d+,\s+?\d+,\s+?\d+(,\s+?\d+\.?\d*)?\)\s\d+%)/gm)
45
+ const hsla = gradient.match(/(hsla?\(\s?\d+,\s+?\d+%,\s+?\d+%(,\s+?\d+\.?\d*)?\)\s\d+%)/gm)
46
+ const hex = gradient.match(/(#[a-fA-F\d+]{3,6}\s\d+%|#([A-Fa-f0-9]{4}){1,2}\s\d+%)/gm)
47
+
48
+ if (!rgba && !hex && !hsla) {
49
+ console.error('Extract error ', gradient, 'colors [', rgba, '], hex [', hex, '], hsla [', hsla, ']')
50
+ return []
51
+ }
52
+
53
+ return [...rgba || [], ...hex || [], ...hsla || []]
54
+ .reduce((buffer: Array<{ left: number, color: string }>, entry) => {
55
+ const regexp = entry.startsWith('#')
56
+ ? /(?<color>#[a-fA-F\d+]{3,6}|#([A-Fa-f0-9]{4}){1,2})\s(?<left>\d+)%/i
57
+ : /(?<color>rgba?\(\s?\d+,\s+?\d+,\s+?\d+(,\s+?\d+\.?\d*)?\)|hsla?\(\s?\d+,\s+?\d+%,\s+?\d+%(,\s+?\d+\.?\d*)?\))\s(?<left>\d+)%/i
58
+
59
+ const extracted = regexp.exec(entry)
60
+ if (extracted) {
61
+ const { color, left } = extracted.groups as { color: string, left: string }
62
+ if (color && left) {
63
+ buffer.push({
64
+ left: Number(left),
65
+ color
66
+ })
67
+ }
68
+ }
69
+ return buffer
70
+ }, [])
71
+ }
72
+
73
+ const sortPoints = (points: Point[]) => {
74
+ return [...points].sort((a, b) => a.left - b.left)
75
+ }
76
+
77
+ const spread = (arr: string[], from: number, to: number) => {
78
+ const result = []
79
+ for (let i = 0; i <= arr.length - 1; i++) {
80
+ result.push({
81
+ left: Math.floor(from + ((to - from) / (arr.length - 1) * i)),
82
+ color: arr[i]
83
+ })
84
+ }
85
+
86
+ return result
87
+ }
88
+
89
+ export const preparePoints = (points: Point[], interpolation: InterpolationMode, precision: number) => {
90
+ const result = []
91
+ points = sortPoints(points)
92
+ for (let i = 0; i <= points.length - 2; i++) {
93
+ const scale = spread(chroma
94
+ .scale([points[i].color, points[i + 1].color])
95
+ .mode(interpolation)
96
+ .colors(precision + 2), points[i].left, points[i + 1].left)
97
+
98
+ if (i !== 0) {
99
+ scale.splice(0, 1)
100
+ }
101
+
102
+ result.push(...scale)
103
+ }
104
+
105
+ return result
106
+ }
107
+
108
+ const toColor = (point: Point) => {
109
+ return `${point.color} ${point.left}%`
110
+ }
111
+
112
+ const toLinearGradient = (properties: Gradient) => {
113
+ const { angle = 0, points = [], interpolation = 'hsl', precision = 0 } = properties
114
+ return `linear-gradient(${angle}deg, ${preparePoints(points, interpolation, precision).map(point => toColor(point)).join(', ')})`
115
+ }
116
+
117
+ const toRadialGradient = (properties: Gradient) => {
118
+ const { shape = 'circle', xAxis = '50%', yAxis = '50%', points = [], interpolation = 'hsl', precision = 0 } = properties
119
+ return `radial-gradient(${shape} at ${xAxis} ${yAxis}, ${preparePoints(points, interpolation, precision).map(point => toColor(point)).join(', ')})`
120
+ }
121
+
122
+ const toConicGradient = (properties: Gradient) => {
123
+ const { angle = '0deg', xAxis = '50%', yAxis = '50%', points = [], interpolation = 'hsl', precision = 0 } = properties
124
+ return `conic-gradient(from ${angle}deg at ${xAxis} ${yAxis}, ${preparePoints(points, interpolation, precision).map(point => toColor(point)).join(', ')})`
125
+ }
126
+
127
+ export const parseGradient = (gradient: string) => {
128
+ const type = extractType(gradient)
129
+ const axis = extractAxis(gradient, type)
130
+
131
+ return {
132
+ ...axis,
133
+ angle: extractAngle(gradient),
134
+ shape: extractShape(gradient, type),
135
+ points: extractColors(gradient),
136
+ type
137
+ }
138
+ }
139
+
140
+ export const parse = (declaration: string) => {
141
+ const url = declaration.match(/url\("?(.*?)"?\)/m)
142
+ const image = url
143
+ ? url[1].trim()
144
+ : null
145
+
146
+ const gradient = declaration.replace(/,?(\s+)?url\(.*\)/gm, '')
147
+
148
+ return { image, gradient }
149
+ }
150
+
151
+ export const compile = ({ points, interpolation = 'hsl', precision = 0, type = 'linear', angle = 90 }: Gradient) => {
152
+ switch (type) {
153
+ case 'linear': return toLinearGradient({ points, interpolation, precision, type, angle })
154
+ case 'radial': return toRadialGradient({ points, interpolation, precision, type, angle })
155
+ case 'conic': return toConicGradient({ points, interpolation, precision, type, angle })
156
+ default: return ''
157
+ }
158
+ }
@@ -0,0 +1,40 @@
1
+ interface CustomOption {
2
+ [key:string]: any
3
+ }
4
+
5
+ interface Option extends CustomOption {
6
+ label: string
7
+ value: string | number | boolean | Record<string, any>
8
+ id?: any
9
+ help?: string
10
+ disabled?: boolean
11
+ }
12
+
13
+ interface Keys {
14
+ id: string
15
+ label: string
16
+ help: string
17
+ value: string
18
+ disabled: string
19
+ }
20
+
21
+ export function prepareOptions (options: (Option | CustomOption | string)[] | { [p: string]: string }, keys: Keys): (CustomOption | Option)[] {
22
+ if (Array.isArray(options)) {
23
+ return options.map(option => typeof option !== 'object'
24
+ ? { [keys.label]: option, [keys.value]: option }
25
+ : option)
26
+ }
27
+
28
+ if (typeof options === 'object') {
29
+ return Object.keys(options).map((value) => {
30
+ return {
31
+ label: options[value],
32
+ value
33
+ }
34
+ })
35
+ }
36
+
37
+ return []
38
+ }
39
+
40
+ export type { Option, Keys, CustomOption }
@@ -0,0 +1,14 @@
1
+ import { clsx } from 'clsx'
2
+ import { extendTailwindMerge } from 'tailwind-merge'
3
+
4
+ const twMerge = extendTailwindMerge({
5
+ extend: {
6
+ classGroups: {
7
+ 'font-size': ['text-2xs']
8
+ }
9
+ }
10
+ })
11
+
12
+ export function cn (...inputs: unknown[]) {
13
+ return twMerge(clsx(inputs))
14
+ }