@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,120 @@
1
+ <template>
2
+ <SelectRoot v-bind="forwarded"
3
+ v-model="modelValue"
4
+ @change.stop
5
+ >
6
+ <SelectTrigger :class="cn((multiple && Array.isArray(modelValue) && modelValue.length === 0) || !modelValue ? 'text-muted-foreground' : '', props.class)">
7
+ <SelectValue :placeholder="placeholder">
8
+ <slot v-if="multiple && Array.isArray(modelValue) && (modelValue.length || $slots.label)" name="label" v-bind="{ options: selectedOptions }">
9
+ {{ selectedOptionsLabel || modelValue!.length + ' selected' }}
10
+ </slot>
11
+ <slot v-else-if="!multiple && (modelValue || $slots.label)" name="label" v-bind="{ option: selectedOption }">
12
+ {{ selectedOptionLabel || modelValue }}
13
+ </slot>
14
+ </SelectValue>
15
+ </SelectTrigger>
16
+ <SelectPortal :disabled="disablePortal" :to="opts.portalTo">
17
+ <SelectContent :body-lock="false">
18
+ <SelectItem
19
+ v-for="(option, index) in preparedOptions"
20
+ :key="option[keys.id] || index"
21
+ :value="option[keys.value]"
22
+ :disabled="option[keys.disabled] || disabled"
23
+ >
24
+ <slot name="option" v-bind="{ option }">
25
+ {{ option[keys.label] || option }}
26
+ </slot>
27
+ </SelectItem>
28
+ </SelectContent>
29
+ </SelectPortal>
30
+ </SelectRoot>
31
+ </template>
32
+
33
+ <script setup lang="ts">
34
+ import {
35
+ SelectRoot,
36
+ SelectPortal,
37
+ type SelectRootEmits,
38
+ type SelectRootProps
39
+ } from 'reka-ui'
40
+ import { computed, type HTMLAttributes } from 'vue'
41
+ import { type CustomOption, type Keys, type Option, prepareOptions } from '@/utils/options'
42
+ import SelectContent from './SelectContent.vue'
43
+ import SelectTrigger from './SelectTrigger.vue'
44
+ import SelectValue from './SelectValue.vue'
45
+ import SelectItem from './SelectItem.vue'
46
+ import { cn } from '@/utils/tailwind'
47
+ import { useDelegatedProps } from '@/composables/delegated-props'
48
+ import { useForwardPropsEmits } from '@/composables/forward-props-emits'
49
+ import { useEmitAsProps } from '@/composables/emits-as-props'
50
+ import { getOptions } from '@/options-provider'
51
+
52
+ const modelValue = defineModel<SelectRootProps['modelValue']>()
53
+
54
+ const props = withDefaults(defineProps<Omit<SelectRootProps, 'modelValue'> & {
55
+ class?: HTMLAttributes['class']
56
+ placeholder?: string
57
+ disablePortal?: boolean
58
+ keys?: Keys
59
+ options: string[] | Option[] | CustomOption[] | { [key:string]: string }
60
+ }>(), {
61
+ disablePortal: false,
62
+ placeholder: 'Select a value...',
63
+ keys: () => ({
64
+ id: 'id',
65
+ label: 'label',
66
+ help: 'help',
67
+ value: 'value',
68
+ disabled: 'disabled'
69
+ })
70
+ })
71
+ const emits = defineEmits<Omit<SelectRootEmits, 'update:modelValue'>>()
72
+
73
+ const delegatedProps = useDelegatedProps(props, ['class', 'placeholder', 'keys', 'options', 'disablePortal', 'modelValue'])
74
+ const delegatedEmits = useEmitAsProps(emits, ['update:modelValue'])
75
+ const forwarded = useForwardPropsEmits(delegatedProps, delegatedEmits)
76
+ const opts = getOptions()
77
+
78
+ defineSlots<{
79
+ 'label'(props: { option: CustomOption | undefined | null } | { options: Array<Option | CustomOption> }): any
80
+ 'option'(props: { option: Option | CustomOption }): any
81
+ }>()
82
+
83
+ const selectedOption = computed(() => {
84
+ if (modelValue.value) {
85
+ return preparedOptions.value.find((o) => {
86
+ return o[props.keys.value] === modelValue.value
87
+ })
88
+ }
89
+
90
+ return null
91
+ })
92
+
93
+ const selectedOptions = computed(() => {
94
+ if (Array.isArray(modelValue.value)) {
95
+ return preparedOptions.value.filter((o) => {
96
+ return (<Array<unknown>>modelValue.value).includes(o[props.keys.value])
97
+ })
98
+ }
99
+
100
+ return []
101
+ })
102
+
103
+ const selectedOptionLabel = computed(() => {
104
+ if (selectedOption.value) {
105
+ return selectedOption.value[props.keys.label]
106
+ }
107
+
108
+ return null
109
+ })
110
+
111
+ const selectedOptionsLabel = computed(() => {
112
+ if (selectedOptions.value) {
113
+ return selectedOptions.value.map(o => o[props.keys.label]).join(', ')
114
+ }
115
+
116
+ return null
117
+ })
118
+
119
+ const preparedOptions = computed(() => prepareOptions(props.options, props.keys))
120
+ </script>
@@ -0,0 +1,45 @@
1
+ <template>
2
+ <SelectContent
3
+ v-bind="{ ...forwarded, ...$attrs }"
4
+ :class="cn(
5
+ 'relative z-50 max-h-96 min-w-32 overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md 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',
6
+ position === 'popper'
7
+ && 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
8
+ props.class,
9
+ )
10
+ "
11
+ >
12
+ <SelectViewport :class="cn('p-1', position === 'popper' && 'h-(--reka-select-trigger-height) w-full min-w-(--reka-select-trigger-width)')">
13
+ <slot />
14
+ </SelectViewport>
15
+ </SelectContent>
16
+ </template>
17
+
18
+ <script setup lang="ts">
19
+ import { type HTMLAttributes, computed } from 'vue'
20
+ import {
21
+ SelectContent,
22
+ type SelectContentEmits,
23
+ type SelectContentProps,
24
+ SelectViewport,
25
+ useForwardPropsEmits
26
+ } from 'reka-ui'
27
+ import { cn } from '@/utils/tailwind'
28
+
29
+ defineOptions({
30
+ inheritAttrs: false
31
+ })
32
+
33
+ const props = withDefaults(defineProps<SelectContentProps & { class?: HTMLAttributes['class'] }>(), {
34
+ position: 'popper'
35
+ })
36
+ const emits = defineEmits<SelectContentEmits>()
37
+
38
+ const delegatedProps = computed(() => {
39
+ const { class: _, ...delegated } = props
40
+
41
+ return delegated
42
+ })
43
+
44
+ const forwarded = useForwardPropsEmits(delegatedProps, emits)
45
+ </script>
@@ -0,0 +1,19 @@
1
+ <template>
2
+ <SelectGroup :class="cn('p-1 w-full', props.class)" v-bind="delegatedProps">
3
+ <slot />
4
+ </SelectGroup>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ import { type HTMLAttributes, computed } from 'vue'
9
+ import { SelectGroup, type SelectGroupProps } from 'reka-ui'
10
+ import { cn } from '@/utils/tailwind'
11
+
12
+ const props = defineProps<SelectGroupProps & { class?: HTMLAttributes['class'] }>()
13
+
14
+ const delegatedProps = computed(() => {
15
+ const { class: _, ...delegated } = props
16
+
17
+ return delegated
18
+ })
19
+ </script>
@@ -0,0 +1,43 @@
1
+ <template>
2
+ <SelectItem
3
+ v-bind="forwardedProps"
4
+ :class="
5
+ cn(
6
+ 'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 aria-selected:font-medium',
7
+ props.class,
8
+ )
9
+ "
10
+ >
11
+ <SelectItemText>
12
+ <slot />
13
+ </SelectItemText>
14
+ <SelectItemIndicator as-child>
15
+ <span class="absolute right-2 flex h-3.5 w-3.5 items-center justify-center">
16
+ <Check class="h-4 w-4" />
17
+ </span>
18
+ </SelectItemIndicator>
19
+ </SelectItem>
20
+ </template>
21
+
22
+ <script setup lang="ts">
23
+ import { type HTMLAttributes, computed } from 'vue'
24
+ import {
25
+ SelectItem,
26
+ SelectItemIndicator,
27
+ SelectItemText,
28
+ useForwardProps,
29
+ type SelectItemProps
30
+ } from 'reka-ui'
31
+ import { Check } from 'lucide-vue-next'
32
+ import { cn } from '@/utils/tailwind'
33
+
34
+ const props = defineProps<SelectItemProps & { class?: HTMLAttributes['class'] }>()
35
+
36
+ const delegatedProps = computed(() => {
37
+ const { class: _, ...delegated } = props
38
+
39
+ return delegated
40
+ })
41
+
42
+ const forwardedProps = useForwardProps(delegatedProps)
43
+ </script>
@@ -0,0 +1,13 @@
1
+ <template>
2
+ <SelectLabel :class="cn('py-1.5 pl-2 pr-8 text-sm font-medium', props.class)">
3
+ <slot />
4
+ </SelectLabel>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ import type { HTMLAttributes } from 'vue'
9
+ import { SelectLabel, type SelectLabelProps } from 'reka-ui'
10
+ import { cn } from '@/utils/tailwind'
11
+
12
+ const props = defineProps<SelectLabelProps & { class?: HTMLAttributes['class'] }>()
13
+ </script>
@@ -0,0 +1,17 @@
1
+ <template>
2
+ <SelectSeparator v-bind="delegatedProps" :class="cn('-mx-1 my-1 h-px bg-muted', props.class)" />
3
+ </template>
4
+
5
+ <script setup lang="ts">
6
+ import { type HTMLAttributes, computed } from 'vue'
7
+ import { SelectSeparator, type SelectSeparatorProps } from 'reka-ui'
8
+ import { cn } from '@/utils/tailwind'
9
+
10
+ const props = defineProps<SelectSeparatorProps & { class?: HTMLAttributes['class'] }>()
11
+
12
+ const delegatedProps = computed(() => {
13
+ const { class: _, ...delegated } = props
14
+
15
+ return delegated
16
+ })
17
+ </script>
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <SelectTrigger
3
+ v-bind="forwardedProps"
4
+ :class="cn(
5
+ 'flex gap-1.5 text-left h-8 w-full items-center 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',
6
+ props.class,
7
+ )"
8
+ >
9
+ <slot />
10
+ <SelectIcon as-child>
11
+ <ChevronDown class="w-4 h-4 min-w-4 opacity-50" />
12
+ </SelectIcon>
13
+ </SelectTrigger>
14
+ </template>
15
+
16
+ <script setup lang="ts">
17
+ import { type HTMLAttributes, computed } from 'vue'
18
+ import { SelectIcon, SelectTrigger, type SelectTriggerProps, useForwardProps } from 'reka-ui'
19
+ import { ChevronDown } from 'lucide-vue-next'
20
+ import { cn } from '@/utils/tailwind'
21
+
22
+ const props = defineProps<SelectTriggerProps & { class?: HTMLAttributes['class'] }>()
23
+
24
+ const delegatedProps = computed(() => {
25
+ const { class: _, ...delegated } = props
26
+
27
+ return delegated
28
+ })
29
+
30
+ const forwardedProps = useForwardProps(delegatedProps)
31
+ </script>
@@ -0,0 +1,11 @@
1
+ <template>
2
+ <SelectValue v-bind="props">
3
+ <slot v-if="$slots.default" />
4
+ </SelectValue>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ import { SelectValue, type SelectValueProps } from 'reka-ui'
9
+
10
+ const props = defineProps<SelectValueProps>()
11
+ </script>
@@ -0,0 +1 @@
1
+ export { default as Select } from './Select.vue'
@@ -0,0 +1,100 @@
1
+ <template>
2
+ <SliderRoot
3
+ v-bind="forwarded"
4
+ v-model="value"
5
+ :class="cn(
6
+ 'relative flex touch-none select-none data-disabled:opacity-50',
7
+ (orientation === 'horizontal' ? 'w-full h-2 items-center' : 'h-full w-2 justify-center'),
8
+ props.class,
9
+ )"
10
+ >
11
+ <SliderTrack
12
+ class="relative grow overflow-hidden rounded-full bg-secondary"
13
+ :class="orientation === 'horizontal' ? 'h-2 w-full' : 'h-full w-2'"
14
+ >
15
+ <SliderRange
16
+ class="absolute bg-primary"
17
+ :class="orientation === 'horizontal' ? 'h-full' : 'w-full'"
18
+ />
19
+ </SliderTrack>
20
+ <SliderThumb
21
+ v-for="(thumbValue, index) in value ? value : []"
22
+ :key="index"
23
+ class="flex h-5 w-5 rounded-full border-2 border-primary bg-background ring-offset-background transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 data-disabled:pointer-events-none"
24
+ :class="orientation === 'horizontal' ? 'justify-center' : 'items-center'"
25
+ @focus="onFocus({ index, value: thumbValue }, $event)"
26
+ @blur="onBlur({ value: thumbValue }, $event)"
27
+ >
28
+ <div
29
+ v-if="showMarker && (visibleMarker === index)"
30
+ class="absolute z-1 bg-primary rounded-sm px-1.5 py-1 shadow-sm text-xs text-primary-foreground min-w-6 text-center"
31
+ :class="orientation === 'horizontal' ? 'bottom-6' : 'left-6'"
32
+ >
33
+ <slot name="marker" v-bind="{ value: thumbValue }">
34
+ {{ thumbValue }}
35
+ </slot>
36
+ </div>
37
+ </SliderThumb>
38
+ </SliderRoot>
39
+ </template>
40
+
41
+ <script setup lang="ts">
42
+ import { type HTMLAttributes, computed, ref } from 'vue'
43
+ import {
44
+ SliderRange,
45
+ SliderRoot,
46
+ SliderThumb,
47
+ SliderTrack,
48
+ type SliderRootProps,
49
+ type SliderRootEmits
50
+ } from 'reka-ui'
51
+ import { cn } from '@/utils/tailwind'
52
+ import { useDelegatedProps } from '@/composables/delegated-props'
53
+ import { useEmitAsProps } from '@/composables/emits-as-props'
54
+ import { useForwardPropsEmits } from '@/composables/forward-props-emits'
55
+
56
+ const props = withDefaults(defineProps<Omit<SliderRootProps, 'modelValue'> & {
57
+ class?: HTMLAttributes['class']
58
+ showMarker?: boolean
59
+ modelValue: number | number[]
60
+ }>(), {
61
+ min: 0,
62
+ max: 100,
63
+ step: 10,
64
+ orientation: 'horizontal',
65
+ showMarker: false
66
+ })
67
+
68
+ const emits = defineEmits<Omit<SliderRootEmits, 'update:modelValue'> & {
69
+ focus: [payload: number, event: FocusEvent]
70
+ blur: [payload: number, event: FocusEvent]
71
+ dragstart: [payload: number]
72
+ dragend: [payload: number]
73
+ 'update:modelValue': [value: number | number[]]
74
+ }>()
75
+
76
+ const delegatedProps = useDelegatedProps(props, ['class', 'showMarker', 'modelValue'])
77
+ const delegatedEmits = useEmitAsProps(emits, ['update:modelValue', 'focus', 'blur', 'dragstart', 'dragend'])
78
+ const forwarded = useForwardPropsEmits(delegatedProps, delegatedEmits)
79
+
80
+ const visibleMarker = ref<number | null>(null)
81
+
82
+ const value = computed({
83
+ get () {
84
+ return Array.isArray(props.modelValue) ? props.modelValue : [props.modelValue]
85
+ },
86
+ set (value) {
87
+ emits('update:modelValue', value ? (value.length === 2 ? value : value[0]) : value)
88
+ }
89
+ })
90
+
91
+ const onFocus = ({ index, value }: { index: number, value: number }, e: FocusEvent) => {
92
+ emits('focus', value, e)
93
+ visibleMarker.value = index
94
+ }
95
+
96
+ const onBlur = ({ value }: { value: number }, e: FocusEvent) => {
97
+ emits('blur', value, e)
98
+ visibleMarker.value = null
99
+ }
100
+ </script>
@@ -0,0 +1 @@
1
+ export { default as Slider } from './Slider.vue'
@@ -0,0 +1,40 @@
1
+ <template>
2
+ <div class="flex items-center gap-x-2">
3
+ <SwitchBase
4
+ :id="id"
5
+ v-model="modelValue"
6
+ :disabled="disabled"
7
+ :required="required"
8
+ :name="name"
9
+ :value="value"
10
+ @blur="$emit('blur', $event)"
11
+ @focus="$emit('focus', $event)"
12
+ />
13
+ <Label v-if="label || $slots.default" :for="id">
14
+ <slot>{{ label }}</slot>
15
+ </Label>
16
+ </div>
17
+ </template>
18
+
19
+ <script setup lang="ts">
20
+ import { Label } from '@/components/ui/label'
21
+ import SwitchBase from './SwitchBase.vue'
22
+ import { useId } from 'reka-ui'
23
+ import type { Events } from 'vue'
24
+
25
+ const modelValue = defineModel<boolean>()
26
+ withDefaults(defineProps<{
27
+ name?: string
28
+ id?: string
29
+ label?: string
30
+ value?: string
31
+ required?: boolean
32
+ disabled?: boolean
33
+ }>(), {
34
+ id: () => useId()
35
+ })
36
+ defineEmits<{
37
+ focus: [event: Events['onFocus']]
38
+ blur: [event: Events['onBlur']]
39
+ }>()
40
+ </script>
@@ -0,0 +1,36 @@
1
+ <template>
2
+ <SwitchRoot
3
+ v-bind="forwarded"
4
+ :class="cn(
5
+ 'peer inline-flex h-5 w-8 shrink-0 cursor-pointer items-center rounded-full p-1 border-transparent transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input',
6
+ props.class,
7
+ )"
8
+ >
9
+ <SwitchThumb
10
+ :class="cn('pointer-events-none block h-3.5 w-3.5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-2.5 data-[state=unchecked]:translate-x-0')"
11
+ />
12
+ </SwitchRoot>
13
+ </template>
14
+
15
+ <script setup lang="ts">
16
+ import { type HTMLAttributes, computed } from 'vue'
17
+ import {
18
+ SwitchRoot,
19
+ SwitchThumb,
20
+ type SwitchRootEmits,
21
+ type SwitchRootProps,
22
+ useForwardPropsEmits
23
+ } from 'reka-ui'
24
+ import { cn } from '@/utils/tailwind'
25
+
26
+ const props = defineProps<SwitchRootProps & { class?: HTMLAttributes['class'] }>()
27
+ const emits = defineEmits<SwitchRootEmits>()
28
+
29
+ const delegatedProps = computed(() => {
30
+ const { class: _, ...delegated } = props
31
+
32
+ return delegated
33
+ })
34
+
35
+ const forwarded = useForwardPropsEmits(delegatedProps, emits)
36
+ </script>
@@ -0,0 +1 @@
1
+ export { default as Switch } from './Switch.vue'
@@ -0,0 +1,63 @@
1
+ <template>
2
+ <TabsRoot v-bind="forwarded" :class="cn(tabsVariants({ orientation }), props.class)">
3
+ <TabsList :class="cn(tabsListVariants({ orientation }), 'rounded-md bg-muted p-1 text-muted-foreground')">
4
+ <template v-for="tab in getTabs($slots.default ? $slots.default() : [])">
5
+ <Tooltip v-if="tab.props?.tooltip" :key="'tooltip-' + tab.props?.value">
6
+ <template #trigger>
7
+ <TabsTrigger :value="tab.props?.value" :disabled="tab.props?.disabled">
8
+ <template v-if="tab.props?.title">
9
+ {{ tab.props?.title }}
10
+ </template>
11
+ <Icon v-else-if="tab.props?.icon" :icon="tab.props.icon" />
12
+ </TabsTrigger>
13
+ </template>
14
+ {{ tab.props?.tooltip }}
15
+ </Tooltip>
16
+ <TabsTrigger
17
+ v-else
18
+ :key="tab.props?.value"
19
+ :value="tab.props?.value"
20
+ :disabled="tab.props?.disabled"
21
+ >
22
+ <template v-if="tab.props?.title">
23
+ {{ tab.props?.title }}
24
+ </template>
25
+ <Icon v-else-if="tab.props?.icon" :icon="tab.props.icon" />
26
+ </TabsTrigger>
27
+ </template>
28
+ </TabsList>
29
+ <slot />
30
+ </TabsRoot>
31
+ </template>
32
+
33
+ <script setup lang="ts">
34
+ import { TabsRoot, useForwardPropsEmits, TabsList } from 'reka-ui'
35
+ import type { TabsRootEmits, TabsRootProps } from 'reka-ui'
36
+ import TabsTrigger from './TabsTrigger.vue'
37
+ import { Icon } from '@/components/ui/icon'
38
+ import { Tooltip } from '@/components/ui/tooltip'
39
+ import { cn } from '@/utils/tailwind'
40
+ import { tabsVariants, tabsListVariants } from '@/components/ui/tabs/index'
41
+ import type { HTMLAttributes, VNode } from 'vue'
42
+ const props = defineProps<TabsRootProps & {
43
+ class?: HTMLAttributes['class']
44
+ }>()
45
+ const emits = defineEmits<TabsRootEmits>()
46
+
47
+ const isFragment = (vNode: VNode) => vNode.type === Symbol.for('v-fgt')
48
+
49
+ const getTabs = (nodes: VNode[]) => {
50
+ const tabs = [] as VNode[]
51
+ nodes.forEach((node) => {
52
+ if (isFragment(node) && node.children) {
53
+ tabs.push(...getTabs(node.children as VNode[]))
54
+ } else {
55
+ tabs.push(node)
56
+ }
57
+ })
58
+
59
+ return tabs
60
+ }
61
+
62
+ const forwarded = useForwardPropsEmits(props, emits)
63
+ </script>
@@ -0,0 +1,26 @@
1
+ <template>
2
+ <TabsContent
3
+ :class="cn('data-[orientation=horizontal]:mt-4 data-[orientation=vertical]:ml-4 rounded-sm ring-offset-background focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2', props.class)"
4
+ v-bind="delegatedProps"
5
+ >
6
+ <slot />
7
+ </TabsContent>
8
+ </template>
9
+
10
+ <script setup lang="ts">
11
+ import { type HTMLAttributes, computed } from 'vue'
12
+ import { TabsContent, type TabsContentProps } from 'reka-ui'
13
+ import { cn } from '@/utils/tailwind'
14
+
15
+ const props = defineProps<TabsContentProps & { class?: HTMLAttributes['class'] }>()
16
+
17
+ const delegatedProps = computed(() => {
18
+ const { class: _, ...delegated } = props
19
+
20
+ return delegated
21
+ })
22
+
23
+ defineOptions({
24
+ inheritAttrs: false
25
+ })
26
+ </script>
@@ -0,0 +1,27 @@
1
+ <template>
2
+ <TabsTrigger
3
+ v-bind="forwardedProps"
4
+ :class="cn(
5
+ 'inline-flex items-center whitespace-nowrap rounded-sm px-3 text-xs font-medium ring-offset-background transition-all focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-xs',
6
+ props.class,
7
+ )"
8
+ >
9
+ <slot />
10
+ </TabsTrigger>
11
+ </template>
12
+
13
+ <script setup lang="ts">
14
+ import { type HTMLAttributes, computed } from 'vue'
15
+ import { TabsTrigger, type TabsTriggerProps, useForwardProps } from 'reka-ui'
16
+ import { cn } from '@/utils/tailwind'
17
+
18
+ const props = defineProps<TabsTriggerProps & { class?: HTMLAttributes['class'] }>()
19
+
20
+ const delegatedProps = computed(() => {
21
+ const { class: _, ...delegated } = props
22
+
23
+ return delegated
24
+ })
25
+
26
+ const forwardedProps = useForwardProps(delegatedProps)
27
+ </script>
@@ -0,0 +1,28 @@
1
+ import { cva } from 'class-variance-authority'
2
+
3
+ export { default as Tabs } from './Tabs.vue'
4
+ export { default as TabsContent } from './TabsContent.vue'
5
+
6
+ export const tabsVariants = cva('', {
7
+ variants: {
8
+ orientation: {
9
+ vertical: 'flex',
10
+ horizontal: ''
11
+ }
12
+ },
13
+ defaultVariants: {
14
+ orientation: 'horizontal'
15
+ }
16
+ })
17
+
18
+ export const tabsListVariants = cva('*:h-8', {
19
+ variants: {
20
+ orientation: {
21
+ vertical: 'flex flex-col items-start *:w-full',
22
+ horizontal: 'grid auto-cols-[1fr] grid-flow-col h-10 inline-grid items-center justify-center *:justify-center'
23
+ }
24
+ },
25
+ defaultVariants: {
26
+ orientation: 'horizontal'
27
+ }
28
+ })
@@ -0,0 +1,13 @@
1
+ <template>
2
+ <textarea v-model="modelValue" :class="cn('flex min-h-20 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50', props.class)" />
3
+ </template>
4
+
5
+ <script setup lang="ts">
6
+ import type { HTMLAttributes } from 'vue'
7
+ import { cn } from '@/utils/tailwind'
8
+
9
+ const modelValue = defineModel<string | undefined | null>()
10
+ const props = defineProps<{
11
+ class?: HTMLAttributes['class']
12
+ }>()
13
+ </script>
@@ -0,0 +1 @@
1
+ export { default as Textarea } from './Textarea.vue'