@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,681 @@
|
|
|
1
|
+
import React, { useId, useState } from 'react'
|
|
2
|
+
import { Switch, switchRootVariants, switchThumbVariants, Label } from '~/components/catalyst-ui'
|
|
3
|
+
import { MoonIcon, SunIcon, CheckIcon, XIcon, DatabaseIcon, CodeIcon, PaletteIcon, ShieldIcon } from 'lucide-react'
|
|
4
|
+
import { cn } from '~/components/catalyst-ui'
|
|
5
|
+
|
|
6
|
+
export function SwitchXGroup({ variant, className, children }: any) {
|
|
7
|
+
switch (variant) {
|
|
8
|
+
case 'vertical':
|
|
9
|
+
return (
|
|
10
|
+
<div className={cn('flex flex-col *:rounded-none *:shadow-none *:not-last:border-b-0 *:first:rounded-t-xl *:last:rounded-b-xl', className)}>
|
|
11
|
+
{children}
|
|
12
|
+
</div>
|
|
13
|
+
)
|
|
14
|
+
default:
|
|
15
|
+
return (
|
|
16
|
+
<div className={cn('flex *:rounded-none *:shadow-none max-xl:flex-col max-xl:*:not-last:border-b-0 max-xl:*:first:rounded-t-xl max-xl:*:last:rounded-b-xl xl:*:not-last:border-r-0 xl:*:first:rounded-l-xl xl:*:last:rounded-r-xl', className)}>
|
|
17
|
+
{children}
|
|
18
|
+
</div>
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
export function SwitchX({ switch: switchType = 'default', ...props }: any) {
|
|
25
|
+
switch (switchType) {
|
|
26
|
+
case 'toggleLabel':
|
|
27
|
+
return <ToggleLabel {...props} />
|
|
28
|
+
case 'dualToggleLabel':
|
|
29
|
+
return <DualToggleLabel {...props} />
|
|
30
|
+
case 'iconLabel':
|
|
31
|
+
return <IconLabel {...props} />
|
|
32
|
+
case 'dualIconLabel':
|
|
33
|
+
return <DualIconLabel {...props} />
|
|
34
|
+
case 'iconIndicator':
|
|
35
|
+
return <IconIndicator {...props} />
|
|
36
|
+
case 'permanentIndicator':
|
|
37
|
+
return <PermanentIndicator {...props} />
|
|
38
|
+
case 'squarePermanentIndicator':
|
|
39
|
+
return <SquarePermanentIndicator {...props} />
|
|
40
|
+
case 'animated':
|
|
41
|
+
return <Animated {...props} />
|
|
42
|
+
case 'animatedGradient':
|
|
43
|
+
return <AnimatedGradient {...props} />
|
|
44
|
+
case 'card':
|
|
45
|
+
return <Card {...props} />
|
|
46
|
+
case 'gradient':
|
|
47
|
+
return <Gradient {...props} />
|
|
48
|
+
case 'colors':
|
|
49
|
+
return <Colors {...props} />
|
|
50
|
+
case 'sizes':
|
|
51
|
+
return <Sizes {...props} />
|
|
52
|
+
case 'square':
|
|
53
|
+
return <Square {...props} />
|
|
54
|
+
case 'mini':
|
|
55
|
+
return <Mini {...props} />
|
|
56
|
+
case 'outline':
|
|
57
|
+
return <Outline {...props} />
|
|
58
|
+
default:
|
|
59
|
+
return <DefaultSwitch {...props} />
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const DefaultSwitch = ({ label, className, size, variant, shape, style, mini, ...props }) => {
|
|
64
|
+
const id = useId()
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<div className='flex items-center space-x-2'>
|
|
68
|
+
<Switch id={id} size={size} variant={variant} shape={shape} style={style} mini={mini} className={className} {...props} />
|
|
69
|
+
{label && <Label htmlFor={id}>{label}</Label>}
|
|
70
|
+
</div>
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const ToggleLabel = ({ checked: controlledChecked, onCheckedChange, label, yesLabel = 'Yes', noLabel = 'No', className, size, variant, shape, style, mini, ...props }) => {
|
|
75
|
+
const id = useId()
|
|
76
|
+
const [internalChecked, setInternalChecked] = useState(false)
|
|
77
|
+
const checked = controlledChecked !== undefined ? controlledChecked : internalChecked
|
|
78
|
+
const handleChange = (value: boolean) => {
|
|
79
|
+
if (onCheckedChange) {
|
|
80
|
+
onCheckedChange(value)
|
|
81
|
+
} else {
|
|
82
|
+
setInternalChecked(value)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<div className='inline-flex items-center gap-2'>
|
|
88
|
+
<Switch id={id} checked={checked} onCheckedChange={handleChange} size={size} variant={variant} shape={shape} style={style} mini={mini} className={className} {...props} />
|
|
89
|
+
<Label htmlFor={id} className='text-sm font-medium'>
|
|
90
|
+
{checked ? yesLabel : noLabel}
|
|
91
|
+
</Label>
|
|
92
|
+
</div>
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const DualToggleLabel = ({ checked: controlledChecked, onCheckedChange, yesLabel = 'Yes', noLabel = 'No', className, size, variant, shape, style, mini, ...props }) => {
|
|
97
|
+
const id = useId()
|
|
98
|
+
const [internalChecked, setInternalChecked] = useState(false)
|
|
99
|
+
const checked = controlledChecked !== undefined ? controlledChecked : internalChecked
|
|
100
|
+
const handleChange = (value: boolean) => {
|
|
101
|
+
if (onCheckedChange) {
|
|
102
|
+
onCheckedChange(value)
|
|
103
|
+
} else {
|
|
104
|
+
setInternalChecked(value)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return (
|
|
109
|
+
<div className='group inline-flex items-center gap-2' data-state={checked ? 'checked' : 'unchecked'}>
|
|
110
|
+
<span
|
|
111
|
+
id={`${id}-yes`}
|
|
112
|
+
className='group-data-[state=checked]:text-muted-foreground/70 cursor-pointer text-right text-sm font-medium'
|
|
113
|
+
aria-controls={id}
|
|
114
|
+
onClick={() => handleChange(false)}
|
|
115
|
+
>
|
|
116
|
+
{yesLabel}
|
|
117
|
+
</span>
|
|
118
|
+
<Switch id={id} checked={checked} onCheckedChange={handleChange} size={size} variant={variant} shape={shape} style={style} mini={mini} className={className} {...props} />
|
|
119
|
+
<span
|
|
120
|
+
id={`${id}-no`}
|
|
121
|
+
className='group-data-[state=unchecked]:text-muted-foreground/70 cursor-pointer text-left text-sm font-medium'
|
|
122
|
+
aria-controls={id}
|
|
123
|
+
onClick={() => handleChange(true)}
|
|
124
|
+
>
|
|
125
|
+
{noLabel}
|
|
126
|
+
</span>
|
|
127
|
+
</div>
|
|
128
|
+
)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const IconLabel = ({ checked: controlledChecked, onCheckedChange, checkedIcon: CheckedIcon = MoonIcon, uncheckedIcon: UncheckedIcon = SunIcon, className, size, variant, shape, style, mini, ...props }) => {
|
|
132
|
+
const id = useId()
|
|
133
|
+
const [internalChecked, setInternalChecked] = useState(true)
|
|
134
|
+
const checked = controlledChecked !== undefined ? controlledChecked : internalChecked
|
|
135
|
+
const handleChange = (value: boolean) => {
|
|
136
|
+
if (onCheckedChange) {
|
|
137
|
+
onCheckedChange(value)
|
|
138
|
+
} else {
|
|
139
|
+
setInternalChecked(value)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return (
|
|
144
|
+
<div className='inline-flex items-center gap-2'>
|
|
145
|
+
<Switch id={id} checked={checked} onCheckedChange={handleChange} size={size} variant={variant} shape={shape} style={style} mini={mini} className={className} {...props} />
|
|
146
|
+
<Label htmlFor={id}>
|
|
147
|
+
<span className='sr-only'>Toggle switch</span>
|
|
148
|
+
{checked ? (
|
|
149
|
+
<CheckedIcon className='size-4' aria-hidden='true' />
|
|
150
|
+
) : (
|
|
151
|
+
<UncheckedIcon className='size-4' aria-hidden='true' />
|
|
152
|
+
)}
|
|
153
|
+
</Label>
|
|
154
|
+
</div>
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const DualIconLabel = ({ checked: controlledChecked, onCheckedChange, checkedIcon: CheckedIcon = MoonIcon, uncheckedIcon: UncheckedIcon = SunIcon, className, size, variant, shape, style, mini, ...props }) => {
|
|
159
|
+
const id = useId()
|
|
160
|
+
const [internalChecked, setInternalChecked] = useState(true)
|
|
161
|
+
const checked = controlledChecked !== undefined ? controlledChecked : internalChecked
|
|
162
|
+
const handleChange = (value: boolean) => {
|
|
163
|
+
if (onCheckedChange) {
|
|
164
|
+
onCheckedChange(value)
|
|
165
|
+
} else {
|
|
166
|
+
setInternalChecked(value)
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return (
|
|
171
|
+
<div className='group inline-flex items-center gap-2' data-state={checked ? 'checked' : 'unchecked'}>
|
|
172
|
+
<span
|
|
173
|
+
id={`${id}-light`}
|
|
174
|
+
className='group-data-[state=checked]:text-muted-foreground/70 cursor-pointer text-left text-sm font-medium'
|
|
175
|
+
aria-controls={id}
|
|
176
|
+
onClick={() => handleChange(false)}
|
|
177
|
+
>
|
|
178
|
+
<UncheckedIcon className='size-4' aria-hidden='true' />
|
|
179
|
+
</span>
|
|
180
|
+
<Switch
|
|
181
|
+
id={id}
|
|
182
|
+
checked={checked}
|
|
183
|
+
onCheckedChange={handleChange}
|
|
184
|
+
size={size}
|
|
185
|
+
variant={variant}
|
|
186
|
+
shape={shape}
|
|
187
|
+
style={style}
|
|
188
|
+
mini={mini}
|
|
189
|
+
className={className}
|
|
190
|
+
{...props}
|
|
191
|
+
/>
|
|
192
|
+
<span
|
|
193
|
+
id={`${id}-dark`}
|
|
194
|
+
className='group-data-[state=unchecked]:text-muted-foreground/70 cursor-pointer text-right text-sm font-medium'
|
|
195
|
+
aria-controls={id}
|
|
196
|
+
onClick={() => handleChange(true)}
|
|
197
|
+
>
|
|
198
|
+
<CheckedIcon className='size-4' aria-hidden='true' />
|
|
199
|
+
</span>
|
|
200
|
+
</div>
|
|
201
|
+
)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const IconIndicator = ({ checked: controlledChecked, onCheckedChange, checkedIcon: CheckedIcon = CheckIcon, uncheckedIcon: UncheckedIcon = XIcon, className, size, variant, shape, style, mini, ...props }) => {
|
|
205
|
+
const [internalChecked, setInternalChecked] = useState(true)
|
|
206
|
+
const checked = controlledChecked !== undefined ? controlledChecked : internalChecked
|
|
207
|
+
const handleChange = (value: boolean) => {
|
|
208
|
+
if (onCheckedChange) {
|
|
209
|
+
onCheckedChange(value)
|
|
210
|
+
} else {
|
|
211
|
+
setInternalChecked(value)
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return (
|
|
216
|
+
<div>
|
|
217
|
+
<div className='relative inline-grid h-7 grid-cols-[1fr_1fr] items-center text-sm font-medium'>
|
|
218
|
+
<Switch
|
|
219
|
+
checked={checked}
|
|
220
|
+
onCheckedChange={handleChange}
|
|
221
|
+
className={cn(
|
|
222
|
+
switchRootVariants({ size, variant, shape, style, mini }),
|
|
223
|
+
'peer data-[state=checked]:bg-input/50 data-[state=unchecked]:bg-input/50 [&_span]:!bg-background absolute inset-0 h-[inherit] w-14 [&_span]:size-6.5 [&_span]:transition-transform [&_span]:duration-300 [&_span]:ease-[cubic-bezier(0.16,1,0.3,1)] [&_span]:data-[state=checked]:translate-x-7 [&_span]:data-[state=checked]:rtl:-translate-x-7',
|
|
224
|
+
className
|
|
225
|
+
)}
|
|
226
|
+
{...props}
|
|
227
|
+
/>
|
|
228
|
+
<span className='peer-data-[state=checked]:text-muted-foreground/70 pointer-events-none relative ml-1.75 flex min-w-7 items-center text-center'>
|
|
229
|
+
<CheckedIcon className='size-4' aria-hidden='true' />
|
|
230
|
+
</span>
|
|
231
|
+
<span className='peer-data-[state=unchecked]:text-muted-foreground/70 pointer-events-none relative -ms-0.25 flex min-w-7 items-center text-center'>
|
|
232
|
+
<UncheckedIcon className='size-4' aria-hidden='true' />
|
|
233
|
+
</span>
|
|
234
|
+
</div>
|
|
235
|
+
</div>
|
|
236
|
+
)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const PermanentIndicator = ({ checked: controlledChecked, onCheckedChange, checkedIcon: CheckedIcon = CheckIcon, uncheckedIcon: UncheckedIcon = XIcon, className, size, variant, shape, style, mini, ...props }) => {
|
|
240
|
+
const [internalChecked, setInternalChecked] = useState(true)
|
|
241
|
+
const checked = controlledChecked !== undefined ? controlledChecked : internalChecked
|
|
242
|
+
const handleChange = (value: boolean) => {
|
|
243
|
+
if (onCheckedChange) {
|
|
244
|
+
onCheckedChange(value)
|
|
245
|
+
} else {
|
|
246
|
+
setInternalChecked(value)
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return (
|
|
251
|
+
<div>
|
|
252
|
+
<div className='relative inline-grid h-7 grid-cols-[1fr_1fr] items-center text-sm font-medium'>
|
|
253
|
+
<Switch
|
|
254
|
+
checked={checked}
|
|
255
|
+
onCheckedChange={handleChange}
|
|
256
|
+
className={cn(
|
|
257
|
+
switchRootVariants({ size, variant, shape, style, mini }),
|
|
258
|
+
'peer data-[state=unchecked]:bg-input/50 absolute inset-0 h-[inherit] w-14 [&_span]:z-10 [&_span]:size-6.5 [&_span]:transition-transform [&_span]:duration-300 [&_span]:ease-[cubic-bezier(0.16,1,0.3,1)] [&_span]:data-[state=checked]:translate-x-7 [&_span]:data-[state=checked]:rtl:-translate-x-7',
|
|
259
|
+
className
|
|
260
|
+
)}
|
|
261
|
+
{...props}
|
|
262
|
+
/>
|
|
263
|
+
<span className='pointer-events-none relative ml-0.5 flex min-w-8 items-center justify-center text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:invisible peer-data-[state=unchecked]:translate-x-6 peer-data-[state=unchecked]:rtl:-translate-x-6'>
|
|
264
|
+
<UncheckedIcon className='size-4' aria-hidden='true' />
|
|
265
|
+
</span>
|
|
266
|
+
<span className='peer-data-[state=checked]:text-background pointer-events-none relative flex min-w-8 items-center justify-center text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:-translate-x-full peer-data-[state=unchecked]:invisible peer-data-[state=checked]:rtl:translate-x-full'>
|
|
267
|
+
<CheckedIcon className='size-4' aria-hidden='true' />
|
|
268
|
+
</span>
|
|
269
|
+
</div>
|
|
270
|
+
</div>
|
|
271
|
+
)
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const SquarePermanentIndicator = ({ checked: controlledChecked, onCheckedChange, yesLabel = 'Yes', noLabel = 'No', className, size, variant, shape, style, mini, ...props }) => {
|
|
275
|
+
const [internalChecked, setInternalChecked] = useState(true)
|
|
276
|
+
const checked = controlledChecked !== undefined ? controlledChecked : internalChecked
|
|
277
|
+
const handleChange = (value: boolean) => {
|
|
278
|
+
if (onCheckedChange) {
|
|
279
|
+
onCheckedChange(value)
|
|
280
|
+
} else {
|
|
281
|
+
setInternalChecked(value)
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return (
|
|
286
|
+
<div>
|
|
287
|
+
<div className='relative inline-grid h-8 grid-cols-[1fr_1fr] items-center text-sm font-medium'>
|
|
288
|
+
<Switch
|
|
289
|
+
checked={checked}
|
|
290
|
+
onCheckedChange={handleChange}
|
|
291
|
+
className={cn(
|
|
292
|
+
switchRootVariants({ size, variant, shape, style, mini }),
|
|
293
|
+
'peer data-[state=unchecked]:bg-input/50 absolute inset-0 h-[inherit] w-auto rounded-md [&_span]:z-10 [&_span]:h-full [&_span]:w-1/2 [&_span]:rounded-sm [&_span]:transition-transform [&_span]:duration-300 [&_span]:ease-[cubic-bezier(0.16,1,0.3,1)] [&_span]:data-[state=checked]:translate-x-8.75 [&_span]:data-[state=checked]:rtl:-translate-x-8.75',
|
|
294
|
+
className
|
|
295
|
+
)}
|
|
296
|
+
{...props}
|
|
297
|
+
/>
|
|
298
|
+
<span className='pointer-events-none relative ml-0.5 flex items-center justify-center px-2 text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:invisible peer-data-[state=unchecked]:translate-x-full peer-data-[state=unchecked]:rtl:-translate-x-full'>
|
|
299
|
+
<span className='text-[10px] font-medium uppercase'>{noLabel}</span>
|
|
300
|
+
</span>
|
|
301
|
+
<span className='peer-data-[state=checked]:text-background pointer-events-none relative mr-0.5 flex items-center justify-center px-2 text-center transition-transform duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] peer-data-[state=checked]:-translate-x-full peer-data-[state=unchecked]:invisible peer-data-[state=checked]:rtl:translate-x-full'>
|
|
302
|
+
<span className='text-[10px] font-medium uppercase'>{yesLabel}</span>
|
|
303
|
+
</span>
|
|
304
|
+
</div>
|
|
305
|
+
</div>
|
|
306
|
+
)
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const Animated = ({ label, className, size, variant, shape, style, mini, ...props }) => {
|
|
310
|
+
const id = useId()
|
|
311
|
+
|
|
312
|
+
return (
|
|
313
|
+
<div className='flex items-center space-x-2'>
|
|
314
|
+
<Switch id={id} size={size} variant={variant} shape={shape} style={style} mini={mini} className={className} {...props} />
|
|
315
|
+
{label && <Label htmlFor={id}>{label}</Label>}
|
|
316
|
+
</div>
|
|
317
|
+
)
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
const AnimatedGradient = ({ label, className, size, variant, shape, style, mini, ...props }) => {
|
|
321
|
+
const id = useId()
|
|
322
|
+
|
|
323
|
+
return (
|
|
324
|
+
<div className='flex items-center space-x-2'>
|
|
325
|
+
<Switch
|
|
326
|
+
id={id}
|
|
327
|
+
size={size}
|
|
328
|
+
variant={variant}
|
|
329
|
+
shape={shape}
|
|
330
|
+
style={style}
|
|
331
|
+
mini={mini}
|
|
332
|
+
className={cn(
|
|
333
|
+
'focus-visible:border-destructive to-destructive/60 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 border-none bg-gradient-to-r from-amber-500 data-[state=checked]:from-sky-400 data-[state=checked]:to-indigo-700 [&_span]:size-5 [&_span]:!translate-x-0.25',
|
|
334
|
+
className
|
|
335
|
+
)}
|
|
336
|
+
{...props}
|
|
337
|
+
/>
|
|
338
|
+
{label && <Label htmlFor={id}>{label}</Label>}
|
|
339
|
+
</div>
|
|
340
|
+
)
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const Card = ({ icon: Icon = DatabaseIcon, title, description, className, size, variant, shape, style, mini, ...props }) => {
|
|
344
|
+
const id = useId()
|
|
345
|
+
|
|
346
|
+
return (
|
|
347
|
+
<div className='border-input has-data-[state=checked]:border-primary/50 relative flex w-full items-start gap-2 rounded-md border p-4 shadow-xs outline-none'>
|
|
348
|
+
<Switch
|
|
349
|
+
id={id}
|
|
350
|
+
size={size}
|
|
351
|
+
variant={variant}
|
|
352
|
+
shape={shape}
|
|
353
|
+
style={style}
|
|
354
|
+
mini={mini}
|
|
355
|
+
className={cn(
|
|
356
|
+
'order-1 h-4 w-6 after:absolute after:inset-0 [&_span]:size-3 data-[state=checked]:[&_span]:translate-x-2.5 data-[state=checked]:[&_span]:rtl:-translate-x-2.5',
|
|
357
|
+
className
|
|
358
|
+
)}
|
|
359
|
+
{...props}
|
|
360
|
+
/>
|
|
361
|
+
<div className='flex grow items-center gap-3'>
|
|
362
|
+
{Icon && <Icon className='size-5' />}
|
|
363
|
+
<div className='grid grow gap-2'>
|
|
364
|
+
{title && <Label htmlFor={id}>{title}</Label>}
|
|
365
|
+
{description && (
|
|
366
|
+
<p id={`${id}-description`} className='text-muted-foreground text-xs'>
|
|
367
|
+
{description}
|
|
368
|
+
</p>
|
|
369
|
+
)}
|
|
370
|
+
</div>
|
|
371
|
+
</div>
|
|
372
|
+
</div>
|
|
373
|
+
)
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
const Gradient = ({ label, className, size, variant, shape, style, mini, ...props }) => {
|
|
378
|
+
const id = useId()
|
|
379
|
+
|
|
380
|
+
return (
|
|
381
|
+
<div className='flex items-center space-x-2'>
|
|
382
|
+
<Switch
|
|
383
|
+
id={id}
|
|
384
|
+
size={size}
|
|
385
|
+
variant={variant}
|
|
386
|
+
shape={shape}
|
|
387
|
+
style={style}
|
|
388
|
+
mini={mini}
|
|
389
|
+
className={cn(
|
|
390
|
+
'focus-visible:border-destructive to-destructive/60 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 h-6 w-10 border-none bg-gradient-to-r from-amber-500 data-[state=checked]:from-sky-400 data-[state=checked]:to-indigo-700 [&_span]:size-5 [&_span]:!translate-x-0.25 data-[state=checked]:[&_span]:!translate-x-4.75 data-[state=checked]:[&_span]:rtl:!-translate-x-4.75',
|
|
391
|
+
className
|
|
392
|
+
)}
|
|
393
|
+
{...props}
|
|
394
|
+
/>
|
|
395
|
+
{label && <Label htmlFor={id}>{label}</Label>}
|
|
396
|
+
</div>
|
|
397
|
+
)
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
const Colors = ({ colorVariant = 'destructive', label, className, size, variant, shape, style, mini, ...props }) => {
|
|
401
|
+
const id = useId()
|
|
402
|
+
|
|
403
|
+
return (
|
|
404
|
+
<div className='flex items-center gap-3'>
|
|
405
|
+
<Switch
|
|
406
|
+
id={id}
|
|
407
|
+
size={size}
|
|
408
|
+
variant={colorVariant}
|
|
409
|
+
shape={shape}
|
|
410
|
+
style={style}
|
|
411
|
+
mini={mini}
|
|
412
|
+
className={className}
|
|
413
|
+
defaultChecked
|
|
414
|
+
{...props}
|
|
415
|
+
/>
|
|
416
|
+
{label && <Label htmlFor={id}>{label}</Label>}
|
|
417
|
+
</div>
|
|
418
|
+
)
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
const Sizes = ({ sizeVariant = 'sm', label, className, variant, shape, style, mini, ...props }) => {
|
|
422
|
+
const id = useId()
|
|
423
|
+
|
|
424
|
+
return (
|
|
425
|
+
<div className='flex items-center gap-3'>
|
|
426
|
+
<Switch
|
|
427
|
+
id={id}
|
|
428
|
+
size={sizeVariant}
|
|
429
|
+
variant={variant}
|
|
430
|
+
shape={shape}
|
|
431
|
+
style={style}
|
|
432
|
+
mini={mini}
|
|
433
|
+
className={className}
|
|
434
|
+
{...props}
|
|
435
|
+
/>
|
|
436
|
+
{label && <Label htmlFor={id}>{label}</Label>}
|
|
437
|
+
</div>
|
|
438
|
+
)
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
const Square = ({ label, className, size, variant, shape, style, mini, ...props }) => {
|
|
442
|
+
const id = useId()
|
|
443
|
+
|
|
444
|
+
return (
|
|
445
|
+
<div className='flex items-center space-x-2'>
|
|
446
|
+
<Switch
|
|
447
|
+
id={id}
|
|
448
|
+
size={size}
|
|
449
|
+
variant={variant}
|
|
450
|
+
shape='square'
|
|
451
|
+
style={style}
|
|
452
|
+
mini={mini}
|
|
453
|
+
className={className}
|
|
454
|
+
{...props}
|
|
455
|
+
/>
|
|
456
|
+
{label && <Label htmlFor={id}>{label}</Label>}
|
|
457
|
+
</div>
|
|
458
|
+
)
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
const Mini = ({ label, className, size, variant, shape, style, ...props }) => {
|
|
462
|
+
const id = useId()
|
|
463
|
+
|
|
464
|
+
return (
|
|
465
|
+
<div className='flex items-center space-x-2'>
|
|
466
|
+
<Switch
|
|
467
|
+
id={id}
|
|
468
|
+
size={size}
|
|
469
|
+
variant={variant}
|
|
470
|
+
shape={shape}
|
|
471
|
+
style={style}
|
|
472
|
+
mini={true}
|
|
473
|
+
className={className}
|
|
474
|
+
{...props}
|
|
475
|
+
/>
|
|
476
|
+
{label && <Label htmlFor={id}>{label}</Label>}
|
|
477
|
+
</div>
|
|
478
|
+
)
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
const Outline = ({ colorVariant = 'default', label, className, size, variant, shape, mini, ...props }) => {
|
|
482
|
+
const id = useId()
|
|
483
|
+
|
|
484
|
+
return (
|
|
485
|
+
<div className='flex items-center gap-3'>
|
|
486
|
+
<Switch
|
|
487
|
+
id={id}
|
|
488
|
+
size={size}
|
|
489
|
+
variant={colorVariant}
|
|
490
|
+
shape={shape}
|
|
491
|
+
style='outline'
|
|
492
|
+
mini={mini}
|
|
493
|
+
className={className}
|
|
494
|
+
defaultChecked
|
|
495
|
+
{...props}
|
|
496
|
+
/>
|
|
497
|
+
{label && <Label htmlFor={id}>{label}</Label>}
|
|
498
|
+
</div>
|
|
499
|
+
)
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
export function SwitchXDemo() {
|
|
503
|
+
const [checked1, setChecked1] = useState(false)
|
|
504
|
+
const [checked2, setChecked2] = useState(true)
|
|
505
|
+
const [checked3, setChecked3] = useState(false)
|
|
506
|
+
const [checked4, setChecked4] = useState(true)
|
|
507
|
+
const [checked5, setChecked5] = useState(true)
|
|
508
|
+
const [checked6, setChecked6] = useState(true)
|
|
509
|
+
const [checked7, setChecked7] = useState(true)
|
|
510
|
+
const [checked8, setChecked8] = useState(true)
|
|
511
|
+
const [checked9, setChecked9] = useState(false)
|
|
512
|
+
const [checked10, setChecked10] = useState(false)
|
|
513
|
+
const [checked11, setChecked11] = useState(false)
|
|
514
|
+
const [checked12, setChecked12] = useState(false)
|
|
515
|
+
const [checked13, setChecked13] = useState(false)
|
|
516
|
+
const [checked14, setChecked14] = useState(false)
|
|
517
|
+
const [checked15, setChecked15] = useState(false)
|
|
518
|
+
const [checked16, setChecked16] = useState(false)
|
|
519
|
+
const [checked17, setChecked17] = useState(false)
|
|
520
|
+
|
|
521
|
+
const [listItems, setListItems] = useState([
|
|
522
|
+
{ label: 'React', icon: CodeIcon, checked: false },
|
|
523
|
+
{ label: 'Design', icon: PaletteIcon, checked: false },
|
|
524
|
+
{ label: 'Security', icon: ShieldIcon, checked: false },
|
|
525
|
+
])
|
|
526
|
+
|
|
527
|
+
const handleListItemChange = (index: number, checked: boolean) => {
|
|
528
|
+
const newItems = [...listItems]
|
|
529
|
+
newItems[index].checked = checked
|
|
530
|
+
setListItems(newItems)
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
return (
|
|
534
|
+
<div className='space-y-12 p-6 max-w-3xl mx-auto'>
|
|
535
|
+
<div>
|
|
536
|
+
<h3 className='text-lg font-semibold mb-4'>Default</h3>
|
|
537
|
+
<SwitchX label='Airplane Mode' checked={checked1} onCheckedChange={setChecked1} />
|
|
538
|
+
</div>
|
|
539
|
+
|
|
540
|
+
<div>
|
|
541
|
+
<h3 className='text-lg font-semibold mb-4'>Square</h3>
|
|
542
|
+
<SwitchX switch='square' label='Square Switch' checked={checked15} onCheckedChange={setChecked15} />
|
|
543
|
+
</div>
|
|
544
|
+
|
|
545
|
+
<div>
|
|
546
|
+
<h3 className='text-lg font-semibold mb-4'>Mini</h3>
|
|
547
|
+
<SwitchX switch='mini' label='Mini Switch' checked={checked16} onCheckedChange={setChecked16} />
|
|
548
|
+
</div>
|
|
549
|
+
|
|
550
|
+
<div>
|
|
551
|
+
<h3 className='text-lg font-semibold mb-4'>Colors</h3>
|
|
552
|
+
<div className='flex items-center gap-3'>
|
|
553
|
+
<SwitchX switch='colors' colorVariant='destructive' />
|
|
554
|
+
<SwitchX switch='colors' colorVariant='success' />
|
|
555
|
+
<SwitchX switch='colors' colorVariant='info' />
|
|
556
|
+
<SwitchX switch='colors' colorVariant='warning' />
|
|
557
|
+
</div>
|
|
558
|
+
</div>
|
|
559
|
+
|
|
560
|
+
<div>
|
|
561
|
+
<h3 className='text-lg font-semibold mb-4'>Sizes</h3>
|
|
562
|
+
<div className='flex items-center gap-3'>
|
|
563
|
+
<SwitchX switch='sizes' sizeVariant='sm' />
|
|
564
|
+
<SwitchX switch='sizes' sizeVariant='md' />
|
|
565
|
+
<SwitchX switch='sizes' sizeVariant='lg' />
|
|
566
|
+
</div>
|
|
567
|
+
</div>
|
|
568
|
+
|
|
569
|
+
<div>
|
|
570
|
+
<h3 className='text-lg font-semibold mb-4'>Outline</h3>
|
|
571
|
+
<div className='flex items-center gap-3'>
|
|
572
|
+
<SwitchX switch='outline' colorVariant='default' />
|
|
573
|
+
<SwitchX switch='outline' colorVariant='destructive' />
|
|
574
|
+
<SwitchX switch='outline' colorVariant='success' />
|
|
575
|
+
<SwitchX switch='outline' colorVariant='info' />
|
|
576
|
+
<SwitchX switch='outline' colorVariant='warning' />
|
|
577
|
+
</div>
|
|
578
|
+
</div>
|
|
579
|
+
|
|
580
|
+
<div>
|
|
581
|
+
<h3 className='text-lg font-semibold mb-4'>Gradient</h3>
|
|
582
|
+
<SwitchX switch='gradient' label='Gradient Switch' checked={checked17} onCheckedChange={setChecked17} />
|
|
583
|
+
</div>
|
|
584
|
+
|
|
585
|
+
<div>
|
|
586
|
+
<h3 className='text-lg font-semibold mb-4'>Toggle Label</h3>
|
|
587
|
+
<SwitchX switch='toggleLabel' checked={checked2} onCheckedChange={setChecked2} />
|
|
588
|
+
</div>
|
|
589
|
+
|
|
590
|
+
<div>
|
|
591
|
+
<h3 className='text-lg font-semibold mb-4'>Dual Toggle Label</h3>
|
|
592
|
+
<SwitchX switch='dualToggleLabel' checked={checked3} onCheckedChange={setChecked3} />
|
|
593
|
+
</div>
|
|
594
|
+
|
|
595
|
+
<div>
|
|
596
|
+
<h3 className='text-lg font-semibold mb-4'>Icon Label</h3>
|
|
597
|
+
<SwitchX switch='iconLabel' checked={checked4} onCheckedChange={setChecked4} />
|
|
598
|
+
</div>
|
|
599
|
+
|
|
600
|
+
<div>
|
|
601
|
+
<h3 className='text-lg font-semibold mb-4'>Dual Icon Label</h3>
|
|
602
|
+
<SwitchX switch='dualIconLabel' checked={checked5} onCheckedChange={setChecked5} />
|
|
603
|
+
</div>
|
|
604
|
+
|
|
605
|
+
<div>
|
|
606
|
+
<h3 className='text-lg font-semibold mb-4'>Icon Indicator</h3>
|
|
607
|
+
<SwitchX switch='iconIndicator' checked={checked6} onCheckedChange={setChecked6} />
|
|
608
|
+
</div>
|
|
609
|
+
|
|
610
|
+
<div>
|
|
611
|
+
<h3 className='text-lg font-semibold mb-4'>Permanent Indicator</h3>
|
|
612
|
+
<SwitchX switch='permanentIndicator' checked={checked7} onCheckedChange={setChecked7} />
|
|
613
|
+
</div>
|
|
614
|
+
|
|
615
|
+
<div>
|
|
616
|
+
<h3 className='text-lg font-semibold mb-4'>Square Permanent Indicator</h3>
|
|
617
|
+
<SwitchX switch='squarePermanentIndicator' checked={checked8} onCheckedChange={setChecked8} />
|
|
618
|
+
</div>
|
|
619
|
+
|
|
620
|
+
<div>
|
|
621
|
+
<h3 className='text-lg font-semibold mb-4'>Card 1</h3>
|
|
622
|
+
<SwitchX
|
|
623
|
+
switch='card'
|
|
624
|
+
icon={DatabaseIcon}
|
|
625
|
+
title='Backup'
|
|
626
|
+
description='Backup every file from your project.'
|
|
627
|
+
checked={checked9}
|
|
628
|
+
onCheckedChange={setChecked9}
|
|
629
|
+
/>
|
|
630
|
+
</div>
|
|
631
|
+
|
|
632
|
+
<div>
|
|
633
|
+
<h3 className='text-lg font-semibold mb-4'>Card 2</h3>
|
|
634
|
+
<SwitchX
|
|
635
|
+
switch='card'
|
|
636
|
+
icon={() => (
|
|
637
|
+
<img
|
|
638
|
+
src='https://cdn.shadcnstudio.com/ss-assets/brand-logo/google-icon.png?width=20&height=20&format=auto'
|
|
639
|
+
alt='Google Icon'
|
|
640
|
+
className='size-5'
|
|
641
|
+
/>
|
|
642
|
+
)}
|
|
643
|
+
title='Google Cloud Backup'
|
|
644
|
+
description='Backup every picture, video and PDFs.'
|
|
645
|
+
checked={checked10}
|
|
646
|
+
onCheckedChange={setChecked10}
|
|
647
|
+
/>
|
|
648
|
+
</div>
|
|
649
|
+
|
|
650
|
+
<div>
|
|
651
|
+
<h3 className='text-lg font-semibold mb-4'>Card 3</h3>
|
|
652
|
+
<SwitchX
|
|
653
|
+
switch='card'
|
|
654
|
+
icon={() => (
|
|
655
|
+
<img
|
|
656
|
+
src='https://cdn.shadcnstudio.com/ss-assets/brand-logo/github-icon.png?width=20&height=20&format=auto'
|
|
657
|
+
alt='GitHub Icon'
|
|
658
|
+
className='size-5'
|
|
659
|
+
/>
|
|
660
|
+
)}
|
|
661
|
+
title='Connect with GitHub'
|
|
662
|
+
description='Access your projects direct from GitHub.'
|
|
663
|
+
checked={checked11}
|
|
664
|
+
onCheckedChange={setChecked11}
|
|
665
|
+
/>
|
|
666
|
+
</div>
|
|
667
|
+
|
|
668
|
+
<div>
|
|
669
|
+
<h3 className='text-lg font-semibold mb-4'>List Group</h3>
|
|
670
|
+
<SwitchX
|
|
671
|
+
switch='listGroup'
|
|
672
|
+
items={listItems.map((item, index) => ({
|
|
673
|
+
...item,
|
|
674
|
+
onCheckedChange: (checked: boolean) => handleListItemChange(index, checked),
|
|
675
|
+
}))}
|
|
676
|
+
/>
|
|
677
|
+
</div>
|
|
678
|
+
|
|
679
|
+
</div>
|
|
680
|
+
)
|
|
681
|
+
}
|