@catalystsoftware/ui 1.0.4 → 1.0.5
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.
- package/data/tailwind.config.js +261 -3821
- package/dist/components/catalyst-ui/buttons/burger.tsx +207 -0
- package/dist/components/catalyst-ui/core/data-display/timeline.tsx +210 -0
- package/dist/components/catalyst-ui/core/feedback/alert.tsx +491 -0
- package/dist/components/catalyst-ui/core/feedback/spinner-1.tsx +65 -0
- package/dist/components/catalyst-ui/core/feedback/toast.tsx +1857 -0
- package/dist/components/catalyst-ui/core/navigation/menu.tsx +164 -0
- package/dist/components/catalyst-ui/forms/toggle-class.tsx +176 -0
- package/dist/components/catalyst-ui/hooks/use-copy-to-clipboard.tsx +419 -0
- package/dist/components/catalyst-ui/hooks/use-counter.tsx +13 -0
- package/dist/components/catalyst-ui/hooks/use-event-listener.tsx +23 -0
- package/dist/components/catalyst-ui/hooks/use-export-markdown.tsx +47 -0
- package/dist/components/catalyst-ui/hooks/use-focus.tsx +17 -0
- package/dist/components/catalyst-ui/hooks/use-interval.tsx +23 -0
- package/dist/components/catalyst-ui/hooks/use-is-client.tsx +16 -0
- package/dist/components/catalyst-ui/hooks/use-media-query.tsx +19 -0
- package/dist/components/catalyst-ui/hooks/use-mobile.tsx +19 -0
- package/dist/components/catalyst-ui/hooks/use-resize-observer.tsx +81 -0
- package/dist/components/catalyst-ui/hooks/use-timeout.tsx +21 -0
- package/dist/components/catalyst-ui/hooks/use-timer.tsx +209 -0
- package/dist/components/catalyst-ui/hooks/use-toggle.tsx +12 -0
- package/dist/components/catalyst-ui/media/image.tsx +13 -0
- package/dist/components/catalyst-ui/overlays/dual-sidebar.tsx +4142 -0
- package/dist/components/catalyst-ui/overlays/sidebar-original.tsx +726 -0
- package/dist/components/catalyst-ui/primitives/accordion.tsx +250 -0
- package/dist/components/catalyst-ui/primitives/alert-dialog.tsx +126 -0
- package/dist/components/catalyst-ui/primitives/aspect-ratio.tsx +9 -0
- package/dist/components/catalyst-ui/primitives/avatar.tsx +296 -0
- package/dist/components/catalyst-ui/primitives/badge.tsx +57 -0
- package/dist/components/catalyst-ui/primitives/breadcrumb.tsx +101 -0
- package/dist/components/catalyst-ui/primitives/button.tsx +265 -0
- package/dist/components/catalyst-ui/primitives/calendar-v4.tsx +208 -0
- package/dist/components/catalyst-ui/primitives/calendar.tsx +295 -0
- package/dist/components/catalyst-ui/primitives/card.tsx +618 -0
- package/dist/components/catalyst-ui/primitives/carousel.tsx +238 -0
- package/dist/components/catalyst-ui/primitives/chart.tsx +347 -0
- package/dist/components/catalyst-ui/primitives/checkbox.tsx +225 -0
- package/dist/components/catalyst-ui/primitives/collapsible.tsx +212 -0
- package/dist/components/catalyst-ui/primitives/command.tsx +393 -0
- package/dist/components/catalyst-ui/primitives/context-menu.tsx +236 -0
- package/dist/components/catalyst-ui/primitives/dialog.tsx +471 -0
- package/dist/components/catalyst-ui/primitives/drawer.tsx +761 -0
- package/dist/components/catalyst-ui/primitives/dropdown-menu.tsx +290 -0
- package/dist/components/catalyst-ui/primitives/empty.tsx +104 -0
- package/dist/components/catalyst-ui/primitives/field.tsx +244 -0
- package/dist/components/catalyst-ui/primitives/hover-card.tsx +124 -0
- package/dist/components/catalyst-ui/primitives/input-otp.tsx +76 -0
- package/dist/components/catalyst-ui/primitives/input.tsx +64 -0
- package/dist/components/catalyst-ui/primitives/item.tsx +196 -0
- package/dist/components/catalyst-ui/primitives/kbd.tsx +75 -0
- package/dist/components/catalyst-ui/primitives/label.tsx +24 -0
- package/dist/components/catalyst-ui/primitives/navigation-menu.tsx +150 -0
- package/dist/components/catalyst-ui/primitives/pagination.tsx +198 -0
- package/dist/components/catalyst-ui/primitives/popover.tsx +232 -0
- package/dist/components/catalyst-ui/primitives/progress.tsx +34 -0
- package/dist/components/catalyst-ui/primitives/radio-group.tsx +43 -0
- package/dist/components/catalyst-ui/primitives/resizable.tsx +56 -0
- package/dist/components/catalyst-ui/primitives/select.tsx +155 -0
- package/dist/components/catalyst-ui/primitives/separator.tsx +74 -0
- package/dist/components/catalyst-ui/primitives/sheet.tsx +126 -0
- package/dist/components/catalyst-ui/primitives/skeleton.tsx +15 -0
- package/dist/components/catalyst-ui/primitives/slider.tsx +27 -0
- package/dist/components/catalyst-ui/primitives/switch.tsx +187 -0
- package/dist/components/catalyst-ui/primitives/tabs.tsx +335 -0
- package/dist/components/catalyst-ui/primitives/textarea.tsx +24 -0
- package/dist/components/catalyst-ui/primitives/toggle-group.tsx +55 -0
- package/dist/components/catalyst-ui/primitives/toggle.tsx +42 -0
- package/dist/components/catalyst-ui/primitives/tooltip.tsx +116 -0
- package/dist/components/catalyst-ui/utils/basic-auth.tsx +40 -0
- package/dist/components/catalyst-ui/utils/context-storage.tsx +19 -0
- package/dist/components/catalyst-ui/utils/cors-middleware.tsx +71 -0
- package/dist/components/catalyst-ui/utils/deferred-content.tsx +595 -0
- package/dist/components/catalyst-ui/utils/honeypot-middleware.tsx +38 -0
- package/dist/components/catalyst-ui/utils/incId.tsx +75 -0
- package/dist/components/catalyst-ui/utils/jwk-auth.tsx +36 -0
- package/dist/components/catalyst-ui/utils/request-id.tsx +14 -0
- package/dist/components/catalyst-ui/utils/secure-headers.tsx +37 -0
- package/dist/components/catalyst-ui/utils/server-timing.tsx +23 -0
- package/dist/components/catalyst-ui/utils/utils.ts +43 -0
- package/dist/components/catalyst-ui/utils/with-cookie.tsx +43 -0
- package/dist/components/catalyst-ui/x/accordian-x.tsx +428 -0
- package/dist/components/catalyst-ui/x/alert-x.tsx +413 -0
- package/dist/components/catalyst-ui/x/animated-text-x.tsx +2242 -0
- package/dist/components/catalyst-ui/x/avatar-x.tsx +515 -0
- package/dist/components/catalyst-ui/x/badge-x.tsx +670 -0
- package/dist/components/catalyst-ui/x/button-X.tsx +2857 -0
- package/dist/components/catalyst-ui/x/button-group-x.tsx +847 -0
- package/dist/components/catalyst-ui/x/calendar-x.tsx +1910 -0
- package/dist/components/catalyst-ui/x/card-x.tsx +2597 -0
- package/dist/components/catalyst-ui/x/checkbox-x.tsx +656 -0
- package/dist/components/catalyst-ui/x/collapsible-x.tsx +1360 -0
- package/dist/components/catalyst-ui/x/combobox-x.tsx +911 -0
- package/dist/components/catalyst-ui/x/data-table-x.tsx +1753 -0
- package/dist/components/catalyst-ui/x/date-picker-x.tsx +648 -0
- package/dist/components/catalyst-ui/x/dialog-x.tsx +659 -0
- package/dist/components/catalyst-ui/x/dropdown-menu-x.tsx +612 -0
- package/dist/components/catalyst-ui/x/hover-card-x.tsx +375 -0
- package/dist/components/catalyst-ui/x/icon-x.tsx +840 -0
- package/dist/components/catalyst-ui/x/input-mask-x.tsx +981 -0
- package/dist/components/catalyst-ui/x/input-otp-x.tsx +659 -0
- package/dist/components/catalyst-ui/x/loader-x.tsx +1757 -0
- package/dist/components/catalyst-ui/x/pagination-x.tsx +622 -0
- package/dist/components/catalyst-ui/x/popover-x.tsx +744 -0
- package/dist/components/catalyst-ui/x/radio-group-x.tsx +499 -0
- package/dist/components/catalyst-ui/x/select-x.tsx +1127 -0
- package/dist/components/catalyst-ui/x/sheet-x.tsx +668 -0
- package/dist/components/catalyst-ui/x/switch-x.tsx +681 -0
- package/dist/components/catalyst-ui/x/table-x.tsx +574 -0
- package/dist/components/catalyst-ui/x/tabs-x.tsx +839 -0
- package/dist/components/catalyst-ui/x/textarea-x.tsx +1263 -0
- package/dist/components/catalyst-ui/x/tooltip-x.tsx +396 -0
- package/dist/components/catalyst-ui/x/tracker-x.tsx +560 -0
- package/dist/data/bg-data.tsx +901 -0
- package/dist/data/buttons-data.tsx +2327 -0
- package/dist/data/charts-data.tsx +102 -0
- package/dist/data/chat-data.tsx +83 -0
- package/dist/data/code-data.tsx +1040 -0
- package/dist/data/comboboxes-data.tsx +1843 -0
- package/dist/data/command-data.tsx +1381 -0
- package/dist/data/core-data.tsx +15953 -0
- package/dist/data/crm-data.tsx +47 -0
- package/dist/data/data.tsx +159 -0
- package/dist/data/date-and-time-data.tsx +554 -0
- package/dist/data/dependencies.tsx +7 -0
- package/dist/data/ecommerce-data.tsx +1387 -0
- package/dist/data/forms-data.tsx +7890 -0
- package/dist/data/hooks-data.tsx +5487 -0
- package/dist/data/index.ts +34 -0
- package/dist/data/inputs-data.tsx +557 -0
- package/dist/data/interactive-data.tsx +5394 -0
- package/dist/data/lofi-data.tsx +18295 -0
- package/dist/data/marketing-data.tsx +2546 -0
- package/dist/data/media-data.tsx +1510 -0
- package/dist/data/motion-data.tsx +5801 -0
- package/dist/data/overlay-data.tsx +4136 -0
- package/dist/data/pdf-data.tsx +124 -0
- package/dist/data/pos-data.tsx +213 -0
- package/dist/data/postcss.config.js +6 -0
- package/dist/data/primitive-data.tsx +5170 -0
- package/dist/data/prompt-data.tsx +1226 -0
- package/dist/data/requiredLibs.ts +4 -0
- package/dist/data/sandbox-data.tsx +1 -0
- package/dist/data/sidebars-data.tsx +5421 -0
- package/dist/data/stacks-data.tsx +32 -0
- package/dist/data/table-data.tsx +706 -0
- package/dist/data/tailwind.config.js +270 -0
- package/dist/data/tailwind.config.ngin.js +3830 -0
- package/dist/data/tailwind.css +431 -0
- package/dist/data/tools-data.tsx +6910 -0
- package/dist/data/typography-data.tsx +2050 -0
- package/dist/data/utils-data.tsx +6500 -0
- package/dist/data/x-data.tsx +1171 -0
- package/dist/data.tsx +159 -0
- package/package.json +1 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -362
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
|
|
2
|
+
import React, { createContext, useContext, useId } from 'react'
|
|
3
|
+
import * as CheckboxPrimitive from '@radix-ui/react-checkbox'
|
|
4
|
+
import { Check, Minus, Heart, Star, Circle, CircleCheck } from 'lucide-react'
|
|
5
|
+
import { cva, type VariantProps } from 'class-variance-authority'
|
|
6
|
+
import { cn } from '~/components/catalyst-ui'
|
|
7
|
+
|
|
8
|
+
// ==================== CVA VARIANTS ====================
|
|
9
|
+
// @dev app/components/catalyst-ui/data/primitive-data.tsx:2792
|
|
10
|
+
export const checkboxVariants = cva(
|
|
11
|
+
'peer shrink-0 border shadow-xs transition-shadow outline-none disabled:cursor-not-allowed disabled:opacity-50',
|
|
12
|
+
{
|
|
13
|
+
variants: {
|
|
14
|
+
variant: {
|
|
15
|
+
default: [
|
|
16
|
+
'border-input dark:bg-input/30',
|
|
17
|
+
'data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=checked]:border-primary',
|
|
18
|
+
'data-[state=indeterminate]:text-foreground',
|
|
19
|
+
'dark:data-[state=checked]:bg-primary',
|
|
20
|
+
'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
|
|
21
|
+
'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive'
|
|
22
|
+
],
|
|
23
|
+
destructive: [
|
|
24
|
+
'data-[state=checked]:bg-destructive data-[state=checked]:border-destructive',
|
|
25
|
+
'focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40',
|
|
26
|
+
'dark:text-white'
|
|
27
|
+
],
|
|
28
|
+
info: [
|
|
29
|
+
'focus-visible:ring-sky-600/20 data-[state=checked]:border-sky-600 data-[state=checked]:bg-sky-600',
|
|
30
|
+
'dark:text-white dark:focus-visible:ring-sky-400/40',
|
|
31
|
+
'dark:data-[state=checked]:border-sky-400 dark:data-[state=checked]:bg-sky-400'
|
|
32
|
+
],
|
|
33
|
+
success: [
|
|
34
|
+
'focus-visible:ring-green-600/20 data-[state=checked]:border-green-600 data-[state=checked]:bg-green-600',
|
|
35
|
+
'dark:text-white dark:focus-visible:ring-green-400/40',
|
|
36
|
+
'dark:data-[state=checked]:border-green-400 dark:data-[state=checked]:bg-green-400'
|
|
37
|
+
],
|
|
38
|
+
card: [
|
|
39
|
+
'data-[state=checked]:border-blue-600 data-[state=checked]:bg-blue-600 data-[state=checked]:text-white',
|
|
40
|
+
'dark:data-[state=checked]:border-blue-700 dark:data-[state=checked]:bg-blue-700'
|
|
41
|
+
],
|
|
42
|
+
animated: [
|
|
43
|
+
'rounded-full focus-visible:border-blue-500 focus-visible:ring-blue-500/20',
|
|
44
|
+
'data-[state=checked]:border-blue-500 data-[state=checked]:bg-blue-500',
|
|
45
|
+
'dark:text-white dark:focus-visible:ring-blue-500/40'
|
|
46
|
+
],
|
|
47
|
+
filled: [
|
|
48
|
+
'rounded-full bg-destructive data-[state=checked]:text-destructive',
|
|
49
|
+
'focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40'
|
|
50
|
+
],
|
|
51
|
+
filledInfo: [
|
|
52
|
+
'rounded-full bg-sky-600 focus-visible:ring-sky-600/20 data-[state=checked]:text-sky-600',
|
|
53
|
+
'dark:bg-sky-400 dark:focus-visible:ring-sky-400/40 dark:data-[state=checked]:text-sky-400'
|
|
54
|
+
],
|
|
55
|
+
filledSuccess: [
|
|
56
|
+
'rounded-full bg-green-600 focus-visible:ring-green-600/20 data-[state=checked]:text-green-600',
|
|
57
|
+
'dark:bg-green-400 dark:focus-visible:ring-green-400/40 dark:data-[state=checked]:text-green-400'
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
size: {
|
|
61
|
+
default: 'size-4 rounded-[4px]',
|
|
62
|
+
sm: 'size-5 rounded-[4px]',
|
|
63
|
+
lg: 'size-6 rounded-[4px]',
|
|
64
|
+
xl: 'size-7 rounded-full'
|
|
65
|
+
},
|
|
66
|
+
border: {
|
|
67
|
+
solid: '',
|
|
68
|
+
dashed: 'border-dashed border-primary'
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
defaultVariants: {
|
|
72
|
+
variant: 'default',
|
|
73
|
+
size: 'default',
|
|
74
|
+
border: 'solid'
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
export const checkboxIndicatorVariants = cva(
|
|
80
|
+
'flex items-center justify-center text-current transition-none',
|
|
81
|
+
{
|
|
82
|
+
variants: {
|
|
83
|
+
icon: {
|
|
84
|
+
check: '',
|
|
85
|
+
minus: '',
|
|
86
|
+
heart: '',
|
|
87
|
+
star: '',
|
|
88
|
+
circle: '',
|
|
89
|
+
circleCheck: ''
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
defaultVariants: {
|
|
93
|
+
icon: 'check'
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
// ==================== CONTEXT ====================
|
|
99
|
+
|
|
100
|
+
type CheckboxContextValue = VariantProps<typeof checkboxVariants> & {
|
|
101
|
+
icon?: VariantProps<typeof checkboxIndicatorVariants>['icon']
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const CheckboxContext = createContext<CheckboxContextValue>({})
|
|
105
|
+
|
|
106
|
+
const useCheckboxContext = () => useContext(CheckboxContext)
|
|
107
|
+
|
|
108
|
+
// ==================== MAIN COMPONENTS ====================
|
|
109
|
+
|
|
110
|
+
interface CheckboxProps
|
|
111
|
+
extends React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>,
|
|
112
|
+
VariantProps<typeof checkboxVariants> {
|
|
113
|
+
icon?: VariantProps<typeof checkboxIndicatorVariants>['icon']
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const Checkbox = React.forwardRef<
|
|
117
|
+
React.ElementRef<typeof CheckboxPrimitive.Root>,
|
|
118
|
+
CheckboxProps
|
|
119
|
+
>(({ className, variant, size, border, icon, children, ...props }, ref) => {
|
|
120
|
+
const contextValue: CheckboxContextValue = { variant, size, border, icon }
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
<CheckboxContext.Provider value={contextValue}>
|
|
124
|
+
<CheckboxPrimitive.Root
|
|
125
|
+
ref={ref}
|
|
126
|
+
data-slot="checkbox"
|
|
127
|
+
className={cn(checkboxVariants({ variant, size, border }), className)}
|
|
128
|
+
{...props}
|
|
129
|
+
>
|
|
130
|
+
{children ? children : <CheckboxIndicator />}
|
|
131
|
+
</CheckboxPrimitive.Root>
|
|
132
|
+
</CheckboxContext.Provider>
|
|
133
|
+
)
|
|
134
|
+
})
|
|
135
|
+
Checkbox.displayName = CheckboxPrimitive.Root.displayName
|
|
136
|
+
|
|
137
|
+
const CheckboxIndicator = React.forwardRef<
|
|
138
|
+
React.ElementRef<typeof CheckboxPrimitive.Indicator>,
|
|
139
|
+
React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Indicator>
|
|
140
|
+
>(({ className, children, ...props }, ref) => {
|
|
141
|
+
const { icon, variant } = useCheckboxContext()
|
|
142
|
+
|
|
143
|
+
const renderIcon = () => {
|
|
144
|
+
if (children) return children
|
|
145
|
+
if (variant?.includes('filled')) {
|
|
146
|
+
return <CircleCheck className="size-5.5 fill-white stroke-current" />
|
|
147
|
+
}
|
|
148
|
+
switch (icon) {
|
|
149
|
+
case 'heart':
|
|
150
|
+
return (
|
|
151
|
+
<>
|
|
152
|
+
<span className='group-data-[state=checked]:hidden'>
|
|
153
|
+
<Heart className='stroke-1' />
|
|
154
|
+
</span>
|
|
155
|
+
<span className='group-data-[state=unchecked]:hidden'>
|
|
156
|
+
<Heart className="fill-destructive stroke-destructive stroke-1" />
|
|
157
|
+
</span>
|
|
158
|
+
</>
|
|
159
|
+
)
|
|
160
|
+
case 'star':
|
|
161
|
+
return (
|
|
162
|
+
<>
|
|
163
|
+
<span className='group-data-[state=checked]:hidden'>
|
|
164
|
+
<Star className='stroke-1' />
|
|
165
|
+
</span>
|
|
166
|
+
<span className='group-data-[state=unchecked]:hidden'>
|
|
167
|
+
<Star className="fill-amber-500 stroke-amber-500 stroke-1 dark:fill-amber-400 dark:stroke-amber-400" />
|
|
168
|
+
</span>
|
|
169
|
+
</>
|
|
170
|
+
)
|
|
171
|
+
case 'circle':
|
|
172
|
+
return (
|
|
173
|
+
<>
|
|
174
|
+
<span className='group-data-[state=checked]:hidden'>
|
|
175
|
+
<Circle className='stroke-1' />
|
|
176
|
+
</span>
|
|
177
|
+
<span className='group-data-[state=unchecked]:hidden'>
|
|
178
|
+
<Circle className="fill-green-600 stroke-green-600 stroke-1 dark:fill-green-400 dark:stroke-green-400" />
|
|
179
|
+
</span>
|
|
180
|
+
</>
|
|
181
|
+
)
|
|
182
|
+
case 'minus':
|
|
183
|
+
return (
|
|
184
|
+
<>
|
|
185
|
+
<Minus className="hidden size-2.5 group-data-[state=indeterminate]:block" />
|
|
186
|
+
<Check className="hidden size-3.5 group-data-[state=checked]:block" />
|
|
187
|
+
</>
|
|
188
|
+
)
|
|
189
|
+
default:
|
|
190
|
+
return <Check className="h-4 w-4" />
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return (
|
|
195
|
+
<CheckboxPrimitive.Indicator
|
|
196
|
+
ref={ref}
|
|
197
|
+
data-slot="checkbox-indicator"
|
|
198
|
+
className={cn(checkboxIndicatorVariants({ icon }), className)}
|
|
199
|
+
{...props}
|
|
200
|
+
>
|
|
201
|
+
{renderIcon()}
|
|
202
|
+
</CheckboxPrimitive.Indicator>
|
|
203
|
+
)
|
|
204
|
+
})
|
|
205
|
+
CheckboxIndicator.displayName = CheckboxPrimitive.Indicator.displayName
|
|
206
|
+
|
|
207
|
+
export function CheckboxGroup({ variant, className, children }) {
|
|
208
|
+
switch (variant) {
|
|
209
|
+
case 'vertical':
|
|
210
|
+
return (
|
|
211
|
+
<div className={cn('flex flex-col gap-3', className)}>
|
|
212
|
+
{children}
|
|
213
|
+
</div>
|
|
214
|
+
)
|
|
215
|
+
default:
|
|
216
|
+
return (
|
|
217
|
+
<div className={cn('flex items-center gap-3', className)}>
|
|
218
|
+
{children}
|
|
219
|
+
</div>
|
|
220
|
+
)
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
export { Checkbox }
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import React, { useContext } from "react";
|
|
2
|
+
import { cn } from "~/components/catalyst-ui";
|
|
3
|
+
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
|
|
4
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
5
|
+
|
|
6
|
+
type CollapsibleContextValue = {
|
|
7
|
+
variant?: "default" | "card" | "filter" | "form" | "sidebar";
|
|
8
|
+
contentSpacing?: "none" | "sm" | "md" | "lg";
|
|
9
|
+
animated?: boolean;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const CollapsibleContext = React.createContext<CollapsibleContextValue>({});
|
|
13
|
+
|
|
14
|
+
const useCollapsibleContext = () => useContext(CollapsibleContext)
|
|
15
|
+
|
|
16
|
+
// Root Collapsible with context
|
|
17
|
+
interface CollapsibleProps
|
|
18
|
+
extends React.ComponentPropsWithoutRef<typeof CollapsiblePrimitive.Root>,
|
|
19
|
+
CollapsibleContextValue { }
|
|
20
|
+
|
|
21
|
+
const Collapsible = React.forwardRef<
|
|
22
|
+
React.ElementRef<typeof CollapsiblePrimitive.Root>,
|
|
23
|
+
CollapsibleProps
|
|
24
|
+
>(({ variant, spacing, layout, padding, animated, size, align, indent, children, ...props }, ref) => {
|
|
25
|
+
const contextValue: CollapsibleContextValue = {variant, spacing, layout, padding, animated, size, align, indent }
|
|
26
|
+
return (
|
|
27
|
+
<CollapsibleContext.Provider value={contextValue}>
|
|
28
|
+
<CollapsiblePrimitive.Root ref={ref} {...props}>
|
|
29
|
+
{children}
|
|
30
|
+
</CollapsiblePrimitive.Root>
|
|
31
|
+
</CollapsibleContext.Provider>
|
|
32
|
+
);
|
|
33
|
+
});
|
|
34
|
+
Collapsible.displayName = "Collapsible";
|
|
35
|
+
|
|
36
|
+
// CollapsibleTrigger variants
|
|
37
|
+
const collapsibleTriggerVariants = cva(
|
|
38
|
+
"outline-none transition-all",
|
|
39
|
+
{
|
|
40
|
+
variants: {
|
|
41
|
+
variant: {
|
|
42
|
+
default: "",
|
|
43
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
44
|
+
icon: "rounded-md p-1",
|
|
45
|
+
text: "underline text-muted-foreground hover:text-foreground",
|
|
46
|
+
filter: "group",
|
|
47
|
+
},
|
|
48
|
+
size: {
|
|
49
|
+
default: "",
|
|
50
|
+
sm: "h-8 text-sm",
|
|
51
|
+
icon: "h-8 w-8",
|
|
52
|
+
"icon-sm": "h-6 w-6",
|
|
53
|
+
},
|
|
54
|
+
align: {
|
|
55
|
+
left: "justify-start",
|
|
56
|
+
center: "justify-center",
|
|
57
|
+
right: "justify-end",
|
|
58
|
+
between: "justify-between",
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
defaultVariants: {
|
|
62
|
+
variant: "default",
|
|
63
|
+
size: "default",
|
|
64
|
+
align: "left",
|
|
65
|
+
},
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
interface CollapsibleTriggerProps
|
|
70
|
+
extends React.ComponentPropsWithoutRef<typeof CollapsiblePrimitive.CollapsibleTrigger>,
|
|
71
|
+
VariantProps<typeof collapsibleTriggerVariants> { }
|
|
72
|
+
|
|
73
|
+
const CollapsibleTrigger = React.forwardRef<
|
|
74
|
+
React.ElementRef<typeof CollapsiblePrimitive.CollapsibleTrigger>,
|
|
75
|
+
CollapsibleTriggerProps
|
|
76
|
+
>(({ className, ...props }, ref) => {
|
|
77
|
+
const context = useCollapsibleContext()
|
|
78
|
+
return (
|
|
79
|
+
<CollapsiblePrimitive.CollapsibleTrigger
|
|
80
|
+
ref={ref}
|
|
81
|
+
className={cn(collapsibleTriggerVariants({ variant: context.variant, size: context.size, align: context.align }), className)}
|
|
82
|
+
{...props}
|
|
83
|
+
/>
|
|
84
|
+
);
|
|
85
|
+
});
|
|
86
|
+
CollapsibleTrigger.displayName = "CollapsibleTrigger";
|
|
87
|
+
|
|
88
|
+
// CollapsibleContent variants
|
|
89
|
+
const collapsibleContentVariants = cva(
|
|
90
|
+
"overflow-hidden",
|
|
91
|
+
{
|
|
92
|
+
variants: {
|
|
93
|
+
spacing: {
|
|
94
|
+
none: "gap-0",
|
|
95
|
+
sm: "gap-1.5",
|
|
96
|
+
md: "gap-2",
|
|
97
|
+
lg: "gap-4",
|
|
98
|
+
},
|
|
99
|
+
layout: {
|
|
100
|
+
default: "flex flex-col",
|
|
101
|
+
grid: "grid",
|
|
102
|
+
inline: "inline-flex",
|
|
103
|
+
},
|
|
104
|
+
padding: {
|
|
105
|
+
none: "p-0",
|
|
106
|
+
sm: "px-2",
|
|
107
|
+
md: "px-4",
|
|
108
|
+
lg: "px-6",
|
|
109
|
+
},
|
|
110
|
+
animated: {
|
|
111
|
+
true: "data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down transition-all duration-300",
|
|
112
|
+
false: "",
|
|
113
|
+
},
|
|
114
|
+
indent: {
|
|
115
|
+
none: "",
|
|
116
|
+
sm: "pl-4",
|
|
117
|
+
md: "pl-6",
|
|
118
|
+
lg: "pl-8",
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
defaultVariants: {
|
|
122
|
+
spacing: "md",
|
|
123
|
+
layout: "default",
|
|
124
|
+
padding: "none",
|
|
125
|
+
animated: false,
|
|
126
|
+
indent: "none",
|
|
127
|
+
},
|
|
128
|
+
}
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
interface CollapsibleContentProps
|
|
132
|
+
extends React.ComponentPropsWithoutRef<typeof CollapsiblePrimitive.CollapsibleContent>,
|
|
133
|
+
VariantProps<typeof collapsibleContentVariants> { }
|
|
134
|
+
|
|
135
|
+
const CollapsibleContent = React.forwardRef<
|
|
136
|
+
React.ElementRef<typeof CollapsiblePrimitive.CollapsibleContent>,
|
|
137
|
+
CollapsibleContentProps
|
|
138
|
+
>(({ className, ...props }, ref) => {
|
|
139
|
+
const context = React.useContext(CollapsibleContext);
|
|
140
|
+
|
|
141
|
+
return (
|
|
142
|
+
<CollapsiblePrimitive.CollapsibleContent
|
|
143
|
+
ref={ref}
|
|
144
|
+
className={cn( collapsibleContentVariants({ spacing: context.spacing, layout: context.layout, padding: context.padding, animated: context.animated, indent: context.indent, }), className )}
|
|
145
|
+
{...props}
|
|
146
|
+
/>
|
|
147
|
+
);
|
|
148
|
+
});
|
|
149
|
+
CollapsibleContent.displayName = "CollapsibleContent";
|
|
150
|
+
|
|
151
|
+
// Header wrapper component with variants
|
|
152
|
+
const collapsibleHeaderVariants = cva(
|
|
153
|
+
"flex items-center",
|
|
154
|
+
{
|
|
155
|
+
variants: {
|
|
156
|
+
spacing: {
|
|
157
|
+
none: "gap-0",
|
|
158
|
+
sm: "gap-2",
|
|
159
|
+
md: "gap-4",
|
|
160
|
+
lg: "gap-6",
|
|
161
|
+
},
|
|
162
|
+
padding: {
|
|
163
|
+
none: "p-0",
|
|
164
|
+
sm: "px-2 py-1",
|
|
165
|
+
md: "px-4 py-2",
|
|
166
|
+
lg: "px-6 py-3",
|
|
167
|
+
},
|
|
168
|
+
align: {
|
|
169
|
+
start: "justify-start",
|
|
170
|
+
center: "justify-center",
|
|
171
|
+
end: "justify-end",
|
|
172
|
+
between: "justify-between",
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
defaultVariants: {
|
|
176
|
+
spacing: "md",
|
|
177
|
+
padding: "md",
|
|
178
|
+
align: "between",
|
|
179
|
+
},
|
|
180
|
+
}
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
interface CollapsibleHeaderProps
|
|
184
|
+
extends React.HTMLAttributes<HTMLDivElement>,
|
|
185
|
+
VariantProps<typeof collapsibleHeaderVariants> { }
|
|
186
|
+
|
|
187
|
+
const CollapsibleHeader = React.forwardRef<HTMLDivElement, CollapsibleHeaderProps>(
|
|
188
|
+
({ className, ...props }, ref) => {
|
|
189
|
+
const {spacing, align, padding} = React.useContext(CollapsibleContext);
|
|
190
|
+
return (
|
|
191
|
+
<div
|
|
192
|
+
ref={ref}
|
|
193
|
+
className={cn(collapsibleHeaderVariants({ spacing, padding, align, }), className)}
|
|
194
|
+
{...props}
|
|
195
|
+
/>
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
);
|
|
199
|
+
CollapsibleHeader.displayName = "CollapsibleHeader";
|
|
200
|
+
|
|
201
|
+
export {
|
|
202
|
+
Collapsible,
|
|
203
|
+
CollapsibleTrigger,
|
|
204
|
+
CollapsibleContent,
|
|
205
|
+
CollapsibleHeader,
|
|
206
|
+
collapsibleTriggerVariants,
|
|
207
|
+
collapsibleContentVariants,
|
|
208
|
+
collapsibleHeaderVariants,
|
|
209
|
+
type CollapsibleTriggerProps,
|
|
210
|
+
type CollapsibleContentProps,
|
|
211
|
+
type CollapsibleHeaderProps,
|
|
212
|
+
};
|