@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,170 @@
1
+ <template>
2
+ <AutocompleteRoot
3
+ v-bind="omit(forwarded, ['class', 'placeholder', 'searchPlaceholder', 'disableFilter', 'disablePortal', 'keys', 'options', 'autofocus', 'modelValue', 'onUpdate:modelValue'])"
4
+ v-model="modelValue"
5
+ v-model:open="open"
6
+ :ignore-filter="disableFilter"
7
+ :reset-search-term-on-blur="false"
8
+ >
9
+ <ComboboxAnchor :class="cn('flex h-8 items-center w-full justify-between rounded-md border border-input bg-background px-2 py-1 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1 [&>span]:break-all', props.class)">
10
+ <ComboboxInput
11
+ ref="input"
12
+ :model-value="selectedOption ? selectedOption[keys.label] : modelValue"
13
+ :auto-focus="autofocus"
14
+ :disabled="disabled"
15
+ :placeholder="placeholder"
16
+ :class="cn(
17
+ 'flex h-8 w-full bg-transparent py-1 text-sm outline-hidden placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50',
18
+ loading ? 'pe-8' : 'pe-2'
19
+ )"
20
+ @update:model-value="modelValue = $event"
21
+ />
22
+ <div v-if="loading" class="pointer-events-none">
23
+ <ProgressCircular class="size-4 text-muted-foreground" />
24
+ </div>
25
+
26
+ <Primitive
27
+ v-else-if="modelValue"
28
+ as="button"
29
+ class="focus:outline-hidden focus:ring-2 rounded focus:ring-ring focus:ring-offset-2"
30
+ @click="reset"
31
+ >
32
+ <X class="w-4 h-4 opacity-50" />
33
+ </Primitive>
34
+ </ComboboxAnchor>
35
+
36
+ <ComboboxPortal v-if="filteredOptions.length > 0" :disabled="disablePortal" :to="opts.portalTo">
37
+ <AutocompleteContent :side-offset="5">
38
+ <ComboboxViewport class="p-1 max-h-[300px] overflow-y-auto overflow-x-hidden">
39
+ <AutocompleteEmpty />
40
+ <AutocompleteGroup>
41
+ <AutocompleteItem
42
+ v-for="(option, index) in filteredOptions"
43
+ :key="option[keys.id] || option[keys.value] || index"
44
+ :value="option[keys.value]"
45
+ :disabled="option[keys.disabled] || disabled"
46
+ @select="onSelect($event, option)"
47
+ >
48
+ <slot name="option" v-bind="{ option }">
49
+ {{ option[keys.label] || option }}
50
+ </slot>
51
+ <ComboboxItemIndicator as-child>
52
+ <Check class="ml-auto h-4 w-4 text-muted-foreground" />
53
+ </ComboboxItemIndicator>
54
+ </AutocompleteItem>
55
+ </AutocompleteGroup>
56
+ </ComboboxViewport>
57
+ </AutocompleteContent>
58
+ </ComboboxPortal>
59
+ </AutocompleteRoot>
60
+ </template>
61
+
62
+ <script setup lang="ts">
63
+ import { type HTMLAttributes, computed, ref, useTemplateRef } from 'vue'
64
+ import { Check } from 'lucide-vue-next'
65
+ import { X } from 'lucide-vue-next'
66
+ import omit from 'lodash/omit'
67
+ import {
68
+ Primitive,
69
+ ComboboxItemIndicator,
70
+ ComboboxAnchor,
71
+ ComboboxPortal,
72
+ ComboboxViewport,
73
+ ComboboxInput,
74
+ type ComboboxItemEmits,
75
+ type ComboboxRootEmits,
76
+ type ComboboxRootProps,
77
+ type ComboboxInputProps
78
+ } from 'reka-ui'
79
+ import { cn } from '@/utils/tailwind'
80
+ import AutocompleteRoot from './AutocompleteRoot.vue'
81
+ import AutocompleteContent from './AutocompleteContent.vue'
82
+ import AutocompleteItem from './AutocompleteItem.vue'
83
+ import AutocompleteGroup from './AutocompleteGroup.vue'
84
+ import AutocompleteEmpty from './AutocompleteEmpty.vue'
85
+ import { ProgressCircular } from '@/components/ui/progress-circular'
86
+ import { useDelegatedProps } from '@/composables/delegated-props'
87
+ import { useEmitAsProps } from '@/composables/emits-as-props'
88
+ import { useForwardPropsEmits } from '@/composables/forward-props-emits'
89
+ import { type CustomOption, type Keys, type Option, prepareOptions } from '@/utils/options'
90
+ import { getOptions } from '@/options-provider'
91
+
92
+ const modelValue = defineModel<ComboboxRootProps['modelValue']>()
93
+ const searchTerm = defineModel<ComboboxInputProps['modelValue']>('searchTerm', { default: '' })
94
+
95
+ const props = withDefaults(defineProps<Omit<ComboboxRootProps, 'modelValue' | 'resetSearchTermOnBlur'> & {
96
+ class?: HTMLAttributes['class']
97
+ placeholder?: string
98
+ loading?: boolean
99
+ disableFilter?: boolean
100
+ disablePortal?: boolean
101
+ autofocus?: boolean
102
+ searchPlaceholder?: string
103
+ keys?: Keys
104
+ options: string[] | Option[] | CustomOption[] | { [key:string]: string }
105
+ }>(), {
106
+ disableFilter: false,
107
+ disablePortal: false,
108
+ loading: false,
109
+ autofocus: false,
110
+ placeholder: 'Select a value...',
111
+ searchPlaceholder: 'Search...',
112
+ keys: () => ({
113
+ id: 'id',
114
+ label: 'label',
115
+ help: 'help',
116
+ value: 'value',
117
+ disabled: 'disabled'
118
+ })
119
+ })
120
+
121
+ const emits = defineEmits<Omit<ComboboxRootEmits, 'update:modelValue'> & {
122
+ blur: [event: MouseEvent]
123
+ focus: [event: MouseEvent]
124
+ select: [option: Option | CustomOption]
125
+ }>()
126
+
127
+ const delegatedProps = useDelegatedProps(props, ['class', 'placeholder', 'loading', 'disableFilter', 'disablePortal', 'autofocus', 'searchPlaceholder', 'keys', 'options'])
128
+ const delegatedEmits = useEmitAsProps(emits, ['blur', 'focus', 'select', 'update:modelValue', 'update:searchTerm'])
129
+ const forwarded = useForwardPropsEmits(delegatedProps, delegatedEmits)
130
+ const opts = getOptions()
131
+
132
+ const open = ref(false)
133
+ const input = useTemplateRef<typeof ComboboxInput>('input')
134
+
135
+ const onSelect = (event: ComboboxItemEmits['select'][0], option: Option | CustomOption) => {
136
+ modelValue.value = event.detail.value
137
+ emits('select', option)
138
+ }
139
+
140
+ const reset = () => {
141
+ modelValue.value = ''
142
+ searchTerm.value = ''
143
+ input.value?.$el.focus()
144
+ }
145
+
146
+ const selectedOption = computed(() => {
147
+ if (modelValue.value) {
148
+ return preparedOptions.value.find((o) => {
149
+ return o[props.keys.value] === modelValue.value
150
+ })
151
+ }
152
+
153
+ return null
154
+ })
155
+
156
+ const filterFunction = (options: any, searchTerm: string) => {
157
+ if (!props.disableFilter) return options
158
+
159
+ return options.filter((option: any) => {
160
+ const result = preparedOptions.value.find((o: Option | CustomOption) => {
161
+ return o[props.keys.value] === option
162
+ })
163
+
164
+ return result ? result[props.keys.label]?.toLowerCase().includes(searchTerm?.toLowerCase()) : false
165
+ })
166
+ }
167
+
168
+ const preparedOptions = computed(() => prepareOptions(props.options, props.keys))
169
+ const filteredOptions = computed(() => filterFunction(preparedOptions.value, String(searchTerm.value)))
170
+ </script>
@@ -0,0 +1,27 @@
1
+ <template>
2
+ <ComboboxContent v-bind="forwarded" :class="cn('z-50 min-w-(--reka-popper-anchor-width) rounded-md border bg-popover text-popover-foreground shadow-md outline-hidden data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', props.class)">
3
+ <div role="presentation">
4
+ <slot />
5
+ </div>
6
+ </ComboboxContent>
7
+ </template>
8
+
9
+ <script setup lang="ts">
10
+ import { type HTMLAttributes, computed } from 'vue'
11
+ import type { ComboboxContentEmits, ComboboxContentProps } from 'reka-ui'
12
+ import { ComboboxContent, useForwardPropsEmits } from 'reka-ui'
13
+ import { cn } from '@/utils/tailwind'
14
+
15
+ const props = withDefaults(defineProps<ComboboxContentProps & { class?: HTMLAttributes['class'] }>(), {
16
+ position: 'popper'
17
+ })
18
+ const emits = defineEmits<ComboboxContentEmits>()
19
+
20
+ const delegatedProps = computed(() => {
21
+ const { class: _, ...delegated } = props
22
+
23
+ return delegated
24
+ })
25
+
26
+ const forwarded = useForwardPropsEmits(delegatedProps, emits)
27
+ </script>
@@ -0,0 +1,20 @@
1
+ <template>
2
+ <ComboboxEmpty v-bind="delegatedProps" :class="cn('py-4 text-center text-sm', props.class)">
3
+ <slot />
4
+ </ComboboxEmpty>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ import { type HTMLAttributes, computed } from 'vue'
9
+ import type { ComboboxEmptyProps } from 'reka-ui'
10
+ import { ComboboxEmpty } from 'reka-ui'
11
+ import { cn } from '@/utils/tailwind'
12
+
13
+ const props = defineProps<ComboboxEmptyProps & { class?: HTMLAttributes['class'] }>()
14
+
15
+ const delegatedProps = computed(() => {
16
+ const { class: _, ...delegated } = props
17
+
18
+ return delegated
19
+ })
20
+ </script>
@@ -0,0 +1,29 @@
1
+ <template>
2
+ <SelectGroup
3
+ v-bind="delegatedProps"
4
+ :class="cn('overflow-hidden text-foreground', props.class)"
5
+ >
6
+ <SelectLabel v-if="heading" class="px-2 py-1.5 text-xs font-medium text-muted-foreground">
7
+ {{ heading }}
8
+ </SelectLabel>
9
+ <slot />
10
+ </SelectGroup>
11
+ </template>
12
+
13
+ <script setup lang="ts">
14
+ import { type HTMLAttributes, computed } from 'vue'
15
+ import type { ComboboxGroupProps } from 'reka-ui'
16
+ import { SelectGroup, SelectLabel } from 'reka-ui'
17
+ import { cn } from '@/utils/tailwind'
18
+
19
+ const props = defineProps<ComboboxGroupProps & {
20
+ class?: HTMLAttributes['class']
21
+ heading?: string
22
+ }>()
23
+
24
+ const delegatedProps = computed(() => {
25
+ const { class: _, ...delegated } = props
26
+
27
+ return delegated
28
+ })
29
+ </script>
@@ -0,0 +1,26 @@
1
+ <template>
2
+ <ComboboxItem
3
+ v-bind="forwarded"
4
+ :class="cn('relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-hidden data-highlighted:bg-accent aria-selected:font-medium data-disabled:pointer-events-none data-disabled:opacity-50', props.class)"
5
+ >
6
+ <slot />
7
+ </ComboboxItem>
8
+ </template>
9
+
10
+ <script setup lang="ts">
11
+ import { type HTMLAttributes, computed } from 'vue'
12
+ import type { ComboboxItemEmits, ComboboxItemProps } from 'reka-ui'
13
+ import { ComboboxItem, useForwardPropsEmits } from 'reka-ui'
14
+ import { cn } from '@/utils/tailwind'
15
+
16
+ const props = defineProps<ComboboxItemProps & { class?: HTMLAttributes['class'] }>()
17
+ const emits = defineEmits<ComboboxItemEmits>()
18
+
19
+ const delegatedProps = computed(() => {
20
+ const { class: _, ...delegated } = props
21
+
22
+ return delegated
23
+ })
24
+
25
+ const forwarded = useForwardPropsEmits(delegatedProps, emits)
26
+ </script>
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <ComboboxRoot
3
+ v-bind="forwarded"
4
+ :class="cn(props.class)"
5
+ as-child
6
+ >
7
+ <slot />
8
+ </ComboboxRoot>
9
+ </template>
10
+
11
+ <script setup lang="ts">
12
+ import { type HTMLAttributes, computed } from 'vue'
13
+ import type { ComboboxRootEmits, ComboboxRootProps } from 'reka-ui'
14
+ import { ComboboxRoot, useForwardPropsEmits } from 'reka-ui'
15
+ import { cn } from '@/utils/tailwind'
16
+
17
+ const props = withDefaults(defineProps<ComboboxRootProps & { class?: HTMLAttributes['class'] }>(), {
18
+ open: true,
19
+ modelValue: ''
20
+ })
21
+
22
+ const emits = defineEmits<ComboboxRootEmits>()
23
+
24
+ const delegatedProps = computed(() => {
25
+ const { class: _, ...delegated } = props
26
+
27
+ return delegated
28
+ })
29
+
30
+ const forwarded = useForwardPropsEmits(delegatedProps, emits)
31
+ </script>
@@ -0,0 +1,23 @@
1
+ <template>
2
+ <ComboboxSeparator
3
+ v-bind="delegatedProps"
4
+ :class="cn('-mx-1 h-px bg-border', props.class)"
5
+ >
6
+ <slot />
7
+ </ComboboxSeparator>
8
+ </template>
9
+
10
+ <script setup lang="ts">
11
+ import { type HTMLAttributes, computed } from 'vue'
12
+ import type { ComboboxSeparatorProps } from 'reka-ui'
13
+ import { ComboboxSeparator } from 'reka-ui'
14
+ import { cn } from '@/utils/tailwind'
15
+
16
+ const props = defineProps<ComboboxSeparatorProps & { class?: HTMLAttributes['class'] }>()
17
+
18
+ const delegatedProps = computed(() => {
19
+ const { class: _, ...delegated } = props
20
+
21
+ return delegated
22
+ })
23
+ </script>
@@ -0,0 +1 @@
1
+ export { default as Autocomplete } from './Autocomplete.vue'
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <AvatarRoot :class="cn(avatarVariant({ size, shape }), props.class)">
3
+ <AvatarImage v-if="src" :src="src" :alt="alt" />
4
+ <AvatarFallback>
5
+ <slot>
6
+ {{ fallback }}
7
+ </slot>
8
+ </AvatarFallback>
9
+ </AvatarRoot>
10
+ </template>
11
+
12
+ <script setup lang="ts">
13
+ import type { HTMLAttributes } from 'vue'
14
+ import { AvatarRoot } from 'reka-ui'
15
+ import { type AvatarVariants, avatarVariant } from '.'
16
+ import AvatarImage from './AvatarImage.vue'
17
+ import AvatarFallback from './AvatarFallback.vue'
18
+ import { cn } from '@/utils/tailwind'
19
+
20
+ const props = withDefaults(defineProps<{
21
+ class?: HTMLAttributes['class']
22
+ size?: AvatarVariants['size']
23
+ shape?: AvatarVariants['shape']
24
+ src?: string
25
+ alt?: string
26
+ fallback: string
27
+ }>(), {
28
+ size: 'sm',
29
+ shape: 'circle'
30
+ })
31
+ </script>
@@ -0,0 +1,11 @@
1
+ <template>
2
+ <AvatarFallback v-bind="props">
3
+ <slot />
4
+ </AvatarFallback>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ import { AvatarFallback, type AvatarFallbackProps } from 'reka-ui'
9
+
10
+ const props = defineProps<AvatarFallbackProps>()
11
+ </script>
@@ -0,0 +1,9 @@
1
+ <template>
2
+ <AvatarImage v-bind="props" class="h-full w-full object-cover" />
3
+ </template>
4
+
5
+ <script setup lang="ts">
6
+ import { AvatarImage, type AvatarImageProps } from 'reka-ui'
7
+
8
+ const props = defineProps<AvatarImageProps>()
9
+ </script>
@@ -0,0 +1,19 @@
1
+ import { type VariantProps, cva } from 'class-variance-authority'
2
+
3
+ export { default as Avatar } from './Avatar.vue'
4
+
5
+ export const avatarVariant = cva('inline-flex items-center justify-center font-normal text-foreground select-none shrink-0 bg-secondary overflow-hidden', {
6
+ variants: {
7
+ size: {
8
+ sm: 'h-10 w-10 text-xs',
9
+ base: 'h-16 w-16 text-2xl',
10
+ lg: 'h-32 w-32 text-5xl'
11
+ },
12
+ shape: {
13
+ circle: 'rounded-full',
14
+ square: 'rounded-md'
15
+ }
16
+ }
17
+ })
18
+
19
+ export type AvatarVariants = VariantProps<typeof avatarVariant>
@@ -0,0 +1,16 @@
1
+ <template>
2
+ <div :class="cn(badgeVariants({ variant }), props.class)">
3
+ <slot />
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ import type { HTMLAttributes } from 'vue'
9
+ import { type BadgeVariants, badgeVariants } from '.'
10
+ import { cn } from '@/utils/tailwind'
11
+
12
+ const props = defineProps<{
13
+ variant?: BadgeVariants['variant']
14
+ class?: HTMLAttributes['class']
15
+ }>()
16
+ </script>
@@ -0,0 +1,22 @@
1
+ import { type VariantProps, cva } from 'class-variance-authority'
2
+
3
+ export { default as Badge } from './Badge.vue'
4
+
5
+ export const badgeVariants = cva('inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-medium transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2', {
6
+ variants: {
7
+ variant: {
8
+ default:
9
+ 'border-transparent bg-primary text-primary-foreground hover:bg-primary/80',
10
+ secondary:
11
+ 'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80',
12
+ destructive:
13
+ 'border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80',
14
+ outline: 'text-foreground'
15
+ }
16
+ },
17
+ defaultVariants: {
18
+ variant: 'default'
19
+ }
20
+ })
21
+
22
+ export type BadgeVariants = VariantProps<typeof badgeVariants>
@@ -0,0 +1,123 @@
1
+ <template>
2
+ <DefineTemplate>
3
+ <component
4
+ v-bind="buildAttrs($attrs)"
5
+ :is="to ? 'router-link' : Primitive"
6
+ :as="!to ? (href ? 'a' : 'button') : null"
7
+ :class="cn(buttonVariants({ variant, size, icon: Boolean(icon || $slots.icon) && !$slots.default }), props.class)"
8
+ :disabled="!href ? disabled || loading : null"
9
+ :to="to || null"
10
+ >
11
+ <Icon
12
+ v-if="iconPosition === 'right' && hasDropdown && $slots.default"
13
+ icon="chevron-down"
14
+ :class="buttonIconVariants({ size })"
15
+ />
16
+
17
+ <template v-if="iconPosition === 'left' && (icon || $slots.icon || loading)">
18
+ <template v-if="loading">
19
+ <ProgressCircular
20
+ v-if="loading"
21
+ class="text-inherit"
22
+ :class="buttonIconVariants({ size })"
23
+ />
24
+ </template>
25
+ <slot v-else name="icon">
26
+ <Icon
27
+ :icon="icon!"
28
+ :class="buttonIconVariants({ size })"
29
+ />
30
+ </slot>
31
+ </template>
32
+
33
+ <slot />
34
+
35
+ <template v-if="iconPosition === 'right' && (icon || $slots.icon || loading)">
36
+ <template v-if="loading">
37
+ <ProgressCircular
38
+ v-if="loading"
39
+ class="text-inherit"
40
+ :class="buttonIconVariants({ size })"
41
+ />
42
+ </template>
43
+ <slot v-else name="icon">
44
+ <Icon
45
+ :icon="icon!"
46
+ :class="buttonIconVariants({ size })"
47
+ />
48
+ </slot>
49
+ </template>
50
+
51
+ <Icon
52
+ v-if="iconPosition === 'left' && hasDropdown && $slots.default"
53
+ icon="chevron-down"
54
+ :class="cn('ml-auto', buttonIconVariants({ size }))"
55
+ />
56
+ </component>
57
+ </DefineTemplate>
58
+
59
+ <Tooltip v-if="tooltip || $slots.tooltip">
60
+ <template #trigger>
61
+ <ReuseTemplate />
62
+ </template>
63
+
64
+ <slot name="tooltip">
65
+ {{ tooltip }}
66
+ </slot>
67
+ </Tooltip>
68
+ <ReuseTemplate v-else />
69
+ </template>
70
+
71
+ <script lang="ts">
72
+ import type { ButtonVariants } from '@/components/ui/button'
73
+ import type { AnchorHTMLAttributes, HTMLAttributes } from 'vue'
74
+
75
+ type ButtonProps = {
76
+ variant?: ButtonVariants['variant']
77
+ tooltip?: string
78
+ to?: any
79
+ icon?: string
80
+ iconPosition?: string
81
+ size?: ButtonVariants['size']
82
+ class?: HTMLAttributes['class']
83
+ disabled?: boolean
84
+ href?: AnchorHTMLAttributes['href']
85
+ loading?: boolean
86
+ }
87
+
88
+ export { type ButtonProps }
89
+ </script>
90
+
91
+ <script setup lang="ts">
92
+ import { inject } from 'vue'
93
+ import { Primitive } from 'reka-ui'
94
+ import { buttonIconVariants, buttonVariants } from '.'
95
+ import { cn } from '@/utils/tailwind'
96
+ import { ProgressCircular } from '@/components/ui/progress-circular'
97
+ import { Icon } from '@/components/ui/icon'
98
+ import { Tooltip } from '@/components/ui/tooltip'
99
+ import { createReusableTemplate } from '@vueuse/core'
100
+
101
+ const [DefineTemplate, ReuseTemplate] = createReusableTemplate()
102
+
103
+ defineOptions({
104
+ inheritAttrs: false
105
+ })
106
+
107
+ const hasDropdown = inject('hasDropdown', false)
108
+
109
+ const buildAttrs = (attrs: { [key: string]: any }) => {
110
+ attrs = { ...attrs }
111
+ if (!props.to) {
112
+ attrs.href = props.href && !(props.disabled || props.loading) ? props.href : null
113
+ }
114
+
115
+ return attrs
116
+ }
117
+
118
+ const props = withDefaults(defineProps<ButtonProps>(), {
119
+ loading: false,
120
+ disabled: false,
121
+ iconPosition: 'left'
122
+ })
123
+ </script>
@@ -0,0 +1,78 @@
1
+ import { type VariantProps, cva } from 'class-variance-authority'
2
+
3
+ export { default as Button } from './Button.vue'
4
+
5
+ export const buttonVariants = cva('inline-flex items-center justify-center whitespace-nowrap rounded-md font-medium text-xs gap-1 ring-offset-background transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50', {
6
+ variants: {
7
+ variant: {
8
+ default: 'bg-primary text-primary-foreground hover:bg-primary/90',
9
+ destructive:
10
+ 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
11
+ outline:
12
+ 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
13
+ secondary:
14
+ 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
15
+ ghost: 'hover:bg-accent hover:text-accent-foreground',
16
+ link: 'text-primary underline-offset-4 hover:underline'
17
+ },
18
+ size: {
19
+ '2xs': 'px-1.5 h-5 rounded-sm font-normal text-2xs gap-0.5',
20
+ xs: 'px-2 h-6 rounded-sm font-normal',
21
+ sm: 'px-2.5 h-7 rounded-sm font-normal',
22
+ md: 'px-3 h-8',
23
+ lg: 'px-4 h-9 text-sm gap-1.5'
24
+ },
25
+ icon: {
26
+ true: '',
27
+ false: ''
28
+ }
29
+ },
30
+ compoundVariants: [
31
+ {
32
+ icon: true,
33
+ size: '2xs',
34
+ class: 'px-0 w-5'
35
+ },
36
+ {
37
+ icon: true,
38
+ size: 'xs',
39
+ class: 'px-0 w-6'
40
+ },
41
+ {
42
+ icon: true,
43
+ size: 'sm',
44
+ class: 'px-0 w-7'
45
+ },
46
+ {
47
+ icon: true,
48
+ size: 'md',
49
+ class: 'px-0 w-8'
50
+ },
51
+ {
52
+ icon: true,
53
+ size: 'lg',
54
+ class: 'px-0 w-9'
55
+ }
56
+ ],
57
+ defaultVariants: {
58
+ variant: 'default',
59
+ size: 'md'
60
+ }
61
+ })
62
+
63
+ export const buttonIconVariants = cva('', {
64
+ variants: {
65
+ size: {
66
+ '2xs': 'w-2.5 h-2.5 min-w-2.5',
67
+ xs: 'w-3 h-3 min-w-3',
68
+ sm: 'w-3 h-3 min-w-3',
69
+ md: 'w-3.5 h-3.5 min-w-3.5',
70
+ lg: 'w-4 h-4 min-w-4'
71
+ }
72
+ },
73
+ defaultVariants: {
74
+ size: 'md'
75
+ }
76
+ })
77
+
78
+ export type ButtonVariants = VariantProps<typeof buttonVariants>