@bupple/vss-ui 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/.turbo/turbo-lint.log +4 -0
  2. package/components.json +21 -0
  3. package/eslint.config.js +4 -0
  4. package/index.ts +2 -0
  5. package/package.json +67 -0
  6. package/postcss.config.mjs +6 -0
  7. package/src/components/accordion.tsx +84 -0
  8. package/src/components/alert-dialog.tsx +198 -0
  9. package/src/components/alert.tsx +77 -0
  10. package/src/components/aspect-ratio.tsx +11 -0
  11. package/src/components/avatar.tsx +109 -0
  12. package/src/components/badge.tsx +50 -0
  13. package/src/components/breadcrumb.tsx +118 -0
  14. package/src/components/button-group.tsx +84 -0
  15. package/src/components/button.tsx +68 -0
  16. package/src/components/calendar.tsx +223 -0
  17. package/src/components/card.tsx +102 -0
  18. package/src/components/carousel.tsx +241 -0
  19. package/src/components/chart.tsx +373 -0
  20. package/src/components/checkbox.tsx +32 -0
  21. package/src/components/collapsible.tsx +33 -0
  22. package/src/components/combobox.tsx +299 -0
  23. package/src/components/command.tsx +194 -0
  24. package/src/components/context-menu.tsx +272 -0
  25. package/src/components/dialog.tsx +171 -0
  26. package/src/components/direction.tsx +20 -0
  27. package/src/components/drawer.tsx +130 -0
  28. package/src/components/dropdown-menu.tsx +278 -0
  29. package/src/components/empty.tsx +102 -0
  30. package/src/components/field.tsx +237 -0
  31. package/src/components/hover-card.tsx +43 -0
  32. package/src/components/input-group.tsx +157 -0
  33. package/src/components/input.tsx +18 -0
  34. package/src/components/item.tsx +197 -0
  35. package/src/components/kbd.tsx +26 -0
  36. package/src/components/label.tsx +21 -0
  37. package/src/components/menubar.tsx +283 -0
  38. package/src/components/native-select.tsx +64 -0
  39. package/src/components/navigation-menu.tsx +166 -0
  40. package/src/components/pagination.tsx +131 -0
  41. package/src/components/popover.tsx +88 -0
  42. package/src/components/progress.tsx +30 -0
  43. package/src/components/radio-group.tsx +46 -0
  44. package/src/components/resizable.tsx +49 -0
  45. package/src/components/scroll-area.tsx +52 -0
  46. package/src/components/select.tsx +209 -0
  47. package/src/components/separator.tsx +25 -0
  48. package/src/components/sheet.tsx +152 -0
  49. package/src/components/sidebar.tsx +703 -0
  50. package/src/components/skeleton.tsx +13 -0
  51. package/src/components/slider.tsx +58 -0
  52. package/src/components/sonner.tsx +45 -0
  53. package/src/components/spinner.tsx +15 -0
  54. package/src/components/switch.tsx +32 -0
  55. package/src/components/table.tsx +115 -0
  56. package/src/components/tabs.tsx +89 -0
  57. package/src/components/textarea.tsx +17 -0
  58. package/src/components/toggle-group.tsx +86 -0
  59. package/src/components/toggle.tsx +48 -0
  60. package/src/components/tooltip.tsx +56 -0
  61. package/src/hooks/use-mobile.ts +19 -0
  62. package/src/lib/portal-container.ts +11 -0
  63. package/src/lib/utils.ts +8 -0
  64. package/src/theme.css +125 -0
  65. package/tsconfig.json +15 -0
@@ -0,0 +1,209 @@
1
+ 'use client'
2
+
3
+ import { usePortalContainer } from '@bupple/vss-ui/lib/portal-container'
4
+ import { cn } from '@bupple/vss-ui/lib/utils'
5
+ import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from 'lucide-react'
6
+ import { Select as SelectPrimitive } from 'radix-ui'
7
+ import * as React from 'react'
8
+
9
+ function Select({
10
+ ...props
11
+ }: React.ComponentProps<typeof SelectPrimitive.Root>) {
12
+ return <SelectPrimitive.Root data-slot='select' {...props} />
13
+ }
14
+
15
+ function SelectGroup({
16
+ className,
17
+ ...props
18
+ }: React.ComponentProps<typeof SelectPrimitive.Group>) {
19
+ return (
20
+ <SelectPrimitive.Group
21
+ data-slot='select-group'
22
+ className={cn('scroll-my-1 p-1', className)}
23
+ {...props}
24
+ />
25
+ )
26
+ }
27
+
28
+ function SelectValue({
29
+ ...props
30
+ }: React.ComponentProps<typeof SelectPrimitive.Value>) {
31
+ return <SelectPrimitive.Value data-slot='select-value' {...props} />
32
+ }
33
+
34
+ function SelectTrigger({
35
+ className,
36
+ size = 'default',
37
+ children,
38
+ triggerIcon,
39
+ ...props
40
+ }: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
41
+ size?: 'sm' | 'default'
42
+ triggerIcon?: React.ReactNode
43
+ }) {
44
+ return (
45
+ <SelectPrimitive.Trigger
46
+ data-slot='select-trigger'
47
+ data-size={size}
48
+ className={cn(
49
+ "flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
50
+ className,
51
+ )}
52
+ {...props}
53
+ >
54
+ {children}
55
+ <SelectPrimitive.Icon asChild>
56
+ {triggerIcon ?? (
57
+ <ChevronDownIcon className='pointer-events-none size-4 text-muted-foreground' />
58
+ )}
59
+ </SelectPrimitive.Icon>
60
+ </SelectPrimitive.Trigger>
61
+ )
62
+ }
63
+
64
+ function SelectContent({
65
+ className,
66
+ children,
67
+ position = 'item-aligned',
68
+ align = 'center',
69
+ ...props
70
+ }: React.ComponentProps<typeof SelectPrimitive.Content>) {
71
+ const container = usePortalContainer()
72
+ return (
73
+ <SelectPrimitive.Portal container={container ?? undefined}>
74
+ <SelectPrimitive.Content
75
+ data-slot='select-content'
76
+ data-align-trigger={position === 'item-aligned'}
77
+ className={cn(
78
+ 'relative z-50 max-h-(--radix-select-content-available-height) min-w-36 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none 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 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95',
79
+ position === 'popper' &&
80
+ 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
81
+ className,
82
+ )}
83
+ position={position}
84
+ align={align}
85
+ {...props}
86
+ >
87
+ <SelectScrollUpButton />
88
+ <SelectPrimitive.Viewport
89
+ data-position={position}
90
+ className={cn(
91
+ 'data-[position=popper]:h-(--radix-select-trigger-height) data-[position=popper]:w-full data-[position=popper]:min-w-(--radix-select-trigger-width)',
92
+ position === 'popper' && '',
93
+ )}
94
+ >
95
+ {children}
96
+ </SelectPrimitive.Viewport>
97
+ <SelectScrollDownButton />
98
+ </SelectPrimitive.Content>
99
+ </SelectPrimitive.Portal>
100
+ )
101
+ }
102
+
103
+ function SelectLabel({
104
+ className,
105
+ ...props
106
+ }: React.ComponentProps<typeof SelectPrimitive.Label>) {
107
+ return (
108
+ <SelectPrimitive.Label
109
+ data-slot='select-label'
110
+ className={cn('px-1.5 py-1 text-xs text-muted-foreground', className)}
111
+ {...props}
112
+ />
113
+ )
114
+ }
115
+
116
+ function SelectItem({
117
+ className,
118
+ children,
119
+ checkIcon,
120
+ ...props
121
+ }: React.ComponentProps<typeof SelectPrimitive.Item> & {
122
+ checkIcon?: React.ReactNode
123
+ }) {
124
+ return (
125
+ <SelectPrimitive.Item
126
+ data-slot='select-item'
127
+ className={cn(
128
+ "relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
129
+ className,
130
+ )}
131
+ {...props}
132
+ >
133
+ <span className='pointer-events-none absolute right-2 flex size-4 items-center justify-center'>
134
+ <SelectPrimitive.ItemIndicator>
135
+ {checkIcon ?? <CheckIcon className='pointer-events-none' />}
136
+ </SelectPrimitive.ItemIndicator>
137
+ </span>
138
+ <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
139
+ </SelectPrimitive.Item>
140
+ )
141
+ }
142
+
143
+ function SelectSeparator({
144
+ className,
145
+ ...props
146
+ }: React.ComponentProps<typeof SelectPrimitive.Separator>) {
147
+ return (
148
+ <SelectPrimitive.Separator
149
+ data-slot='select-separator'
150
+ className={cn('pointer-events-none -mx-1 my-1 h-px bg-border', className)}
151
+ {...props}
152
+ />
153
+ )
154
+ }
155
+
156
+ function SelectScrollUpButton({
157
+ className,
158
+ icon,
159
+ ...props
160
+ }: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton> & {
161
+ icon?: React.ReactNode
162
+ }) {
163
+ return (
164
+ <SelectPrimitive.ScrollUpButton
165
+ data-slot='select-scroll-up-button'
166
+ className={cn(
167
+ "z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
168
+ className,
169
+ )}
170
+ {...props}
171
+ >
172
+ {icon ?? <ChevronUpIcon />}
173
+ </SelectPrimitive.ScrollUpButton>
174
+ )
175
+ }
176
+
177
+ function SelectScrollDownButton({
178
+ className,
179
+ icon,
180
+ ...props
181
+ }: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton> & {
182
+ icon?: React.ReactNode
183
+ }) {
184
+ return (
185
+ <SelectPrimitive.ScrollDownButton
186
+ data-slot='select-scroll-down-button'
187
+ className={cn(
188
+ "z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
189
+ className,
190
+ )}
191
+ {...props}
192
+ >
193
+ {icon ?? <ChevronDownIcon />}
194
+ </SelectPrimitive.ScrollDownButton>
195
+ )
196
+ }
197
+
198
+ export {
199
+ Select,
200
+ SelectContent,
201
+ SelectGroup,
202
+ SelectItem,
203
+ SelectLabel,
204
+ SelectScrollDownButton,
205
+ SelectScrollUpButton,
206
+ SelectSeparator,
207
+ SelectTrigger,
208
+ SelectValue,
209
+ }
@@ -0,0 +1,25 @@
1
+ import { cn } from '@bupple/vss-ui/lib/utils'
2
+ import { Separator as SeparatorPrimitive } from 'radix-ui'
3
+ import * as React from 'react'
4
+
5
+ function Separator({
6
+ className,
7
+ orientation = 'horizontal',
8
+ decorative = true,
9
+ ...props
10
+ }: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
11
+ return (
12
+ <SeparatorPrimitive.Root
13
+ data-slot='separator'
14
+ decorative={decorative}
15
+ orientation={orientation}
16
+ className={cn(
17
+ 'shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch',
18
+ className,
19
+ )}
20
+ {...props}
21
+ />
22
+ )
23
+ }
24
+
25
+ export { Separator }
@@ -0,0 +1,152 @@
1
+ 'use client'
2
+
3
+ import { Button } from '@bupple/vss-ui/components/button'
4
+ import { usePortalContainer } from '@bupple/vss-ui/lib/portal-container'
5
+ import { cn } from '@bupple/vss-ui/lib/utils'
6
+ import { XIcon } from 'lucide-react'
7
+ import { Dialog as SheetPrimitive } from 'radix-ui'
8
+ import * as React from 'react'
9
+
10
+ function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
11
+ return <SheetPrimitive.Root data-slot='sheet' {...props} />
12
+ }
13
+
14
+ function SheetTrigger({
15
+ ...props
16
+ }: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
17
+ return <SheetPrimitive.Trigger data-slot='sheet-trigger' {...props} />
18
+ }
19
+
20
+ function SheetClose({
21
+ ...props
22
+ }: React.ComponentProps<typeof SheetPrimitive.Close>) {
23
+ return <SheetPrimitive.Close data-slot='sheet-close' {...props} />
24
+ }
25
+
26
+ function SheetPortal({
27
+ ...props
28
+ }: React.ComponentProps<typeof SheetPrimitive.Portal>) {
29
+ const container = usePortalContainer()
30
+ return (
31
+ <SheetPrimitive.Portal
32
+ data-slot='sheet-portal'
33
+ container={container ?? undefined}
34
+ {...props}
35
+ />
36
+ )
37
+ }
38
+
39
+ function SheetOverlay({
40
+ className,
41
+ ...props
42
+ }: React.ComponentProps<typeof SheetPrimitive.Overlay>) {
43
+ return (
44
+ <SheetPrimitive.Overlay
45
+ data-slot='sheet-overlay'
46
+ className={cn(
47
+ 'fixed inset-0 z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0',
48
+ className,
49
+ )}
50
+ {...props}
51
+ />
52
+ )
53
+ }
54
+
55
+ function SheetContent({
56
+ className,
57
+ children,
58
+ side = 'right',
59
+ showCloseButton = true,
60
+ closeIcon,
61
+ ...props
62
+ }: React.ComponentProps<typeof SheetPrimitive.Content> & {
63
+ side?: 'top' | 'right' | 'bottom' | 'left'
64
+ showCloseButton?: boolean
65
+ closeIcon?: React.ReactNode
66
+ }) {
67
+ return (
68
+ <SheetPortal>
69
+ <SheetOverlay />
70
+ <SheetPrimitive.Content
71
+ data-slot='sheet-content'
72
+ data-side={side}
73
+ className={cn(
74
+ 'fixed z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-[side=bottom]:data-open:slide-in-from-bottom-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:animate-out data-closed:fade-out-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=right]:data-closed:slide-out-to-right-10 data-[side=top]:data-closed:slide-out-to-top-10',
75
+ className,
76
+ )}
77
+ {...props}
78
+ >
79
+ {children}
80
+ {showCloseButton && (
81
+ <SheetPrimitive.Close data-slot='sheet-close' asChild>
82
+ <Button
83
+ variant='ghost'
84
+ className='absolute top-3 right-3'
85
+ size='icon-sm'
86
+ >
87
+ {closeIcon ?? <XIcon />}
88
+ <span className='sr-only'>Close</span>
89
+ </Button>
90
+ </SheetPrimitive.Close>
91
+ )}
92
+ </SheetPrimitive.Content>
93
+ </SheetPortal>
94
+ )
95
+ }
96
+
97
+ function SheetHeader({ className, ...props }: React.ComponentProps<'div'>) {
98
+ return (
99
+ <div
100
+ data-slot='sheet-header'
101
+ className={cn('flex flex-col gap-0.5 p-4', className)}
102
+ {...props}
103
+ />
104
+ )
105
+ }
106
+
107
+ function SheetFooter({ className, ...props }: React.ComponentProps<'div'>) {
108
+ return (
109
+ <div
110
+ data-slot='sheet-footer'
111
+ className={cn('mt-auto flex flex-col gap-2 p-4', className)}
112
+ {...props}
113
+ />
114
+ )
115
+ }
116
+
117
+ function SheetTitle({
118
+ className,
119
+ ...props
120
+ }: React.ComponentProps<typeof SheetPrimitive.Title>) {
121
+ return (
122
+ <SheetPrimitive.Title
123
+ data-slot='sheet-title'
124
+ className={cn('text-base font-medium text-foreground', className)}
125
+ {...props}
126
+ />
127
+ )
128
+ }
129
+
130
+ function SheetDescription({
131
+ className,
132
+ ...props
133
+ }: React.ComponentProps<typeof SheetPrimitive.Description>) {
134
+ return (
135
+ <SheetPrimitive.Description
136
+ data-slot='sheet-description'
137
+ className={cn('text-sm text-muted-foreground', className)}
138
+ {...props}
139
+ />
140
+ )
141
+ }
142
+
143
+ export {
144
+ Sheet,
145
+ SheetTrigger,
146
+ SheetClose,
147
+ SheetContent,
148
+ SheetHeader,
149
+ SheetFooter,
150
+ SheetTitle,
151
+ SheetDescription,
152
+ }