@catalystsoftware/ui 1.0.5 → 1.0.6

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 (155) hide show
  1. package/dist/data/data.tsx +29 -29
  2. package/dist/data/tailwind.config.js +3821 -261
  3. package/dist/data.tsx +29 -29
  4. package/package.json +4 -3
  5. package/components/catalyst-ui/buttons/burger.tsx +0 -207
  6. package/components/catalyst-ui/core/data-display/timeline.tsx +0 -210
  7. package/components/catalyst-ui/core/feedback/alert.tsx +0 -491
  8. package/components/catalyst-ui/core/feedback/spinner-1.tsx +0 -65
  9. package/components/catalyst-ui/core/feedback/toast.tsx +0 -1857
  10. package/components/catalyst-ui/core/navigation/menu.tsx +0 -164
  11. package/components/catalyst-ui/forms/toggle-class.tsx +0 -176
  12. package/components/catalyst-ui/hooks/use-copy-to-clipboard.tsx +0 -419
  13. package/components/catalyst-ui/hooks/use-counter.tsx +0 -13
  14. package/components/catalyst-ui/hooks/use-event-listener.tsx +0 -23
  15. package/components/catalyst-ui/hooks/use-export-markdown.tsx +0 -47
  16. package/components/catalyst-ui/hooks/use-focus.tsx +0 -17
  17. package/components/catalyst-ui/hooks/use-interval.tsx +0 -23
  18. package/components/catalyst-ui/hooks/use-is-client.tsx +0 -16
  19. package/components/catalyst-ui/hooks/use-media-query.tsx +0 -19
  20. package/components/catalyst-ui/hooks/use-mobile.tsx +0 -19
  21. package/components/catalyst-ui/hooks/use-resize-observer.tsx +0 -81
  22. package/components/catalyst-ui/hooks/use-timeout.tsx +0 -21
  23. package/components/catalyst-ui/hooks/use-timer.tsx +0 -209
  24. package/components/catalyst-ui/hooks/use-toggle.tsx +0 -12
  25. package/components/catalyst-ui/media/image.tsx +0 -13
  26. package/components/catalyst-ui/overlays/dual-sidebar.tsx +0 -4142
  27. package/components/catalyst-ui/overlays/sidebar-original.tsx +0 -726
  28. package/components/catalyst-ui/primitives/accordion.tsx +0 -250
  29. package/components/catalyst-ui/primitives/alert-dialog.tsx +0 -126
  30. package/components/catalyst-ui/primitives/aspect-ratio.tsx +0 -9
  31. package/components/catalyst-ui/primitives/avatar.tsx +0 -296
  32. package/components/catalyst-ui/primitives/badge.tsx +0 -57
  33. package/components/catalyst-ui/primitives/breadcrumb.tsx +0 -101
  34. package/components/catalyst-ui/primitives/button.tsx +0 -265
  35. package/components/catalyst-ui/primitives/calendar-v4.tsx +0 -208
  36. package/components/catalyst-ui/primitives/calendar.tsx +0 -295
  37. package/components/catalyst-ui/primitives/card.tsx +0 -618
  38. package/components/catalyst-ui/primitives/carousel.tsx +0 -238
  39. package/components/catalyst-ui/primitives/chart.tsx +0 -347
  40. package/components/catalyst-ui/primitives/checkbox.tsx +0 -225
  41. package/components/catalyst-ui/primitives/collapsible.tsx +0 -212
  42. package/components/catalyst-ui/primitives/command.tsx +0 -393
  43. package/components/catalyst-ui/primitives/context-menu.tsx +0 -236
  44. package/components/catalyst-ui/primitives/dialog.tsx +0 -471
  45. package/components/catalyst-ui/primitives/drawer.tsx +0 -761
  46. package/components/catalyst-ui/primitives/dropdown-menu.tsx +0 -290
  47. package/components/catalyst-ui/primitives/empty.tsx +0 -104
  48. package/components/catalyst-ui/primitives/field.tsx +0 -244
  49. package/components/catalyst-ui/primitives/hover-card.tsx +0 -124
  50. package/components/catalyst-ui/primitives/input-otp.tsx +0 -76
  51. package/components/catalyst-ui/primitives/input.tsx +0 -64
  52. package/components/catalyst-ui/primitives/item.tsx +0 -196
  53. package/components/catalyst-ui/primitives/kbd.tsx +0 -75
  54. package/components/catalyst-ui/primitives/label.tsx +0 -24
  55. package/components/catalyst-ui/primitives/navigation-menu.tsx +0 -150
  56. package/components/catalyst-ui/primitives/pagination.tsx +0 -198
  57. package/components/catalyst-ui/primitives/popover.tsx +0 -232
  58. package/components/catalyst-ui/primitives/progress.tsx +0 -34
  59. package/components/catalyst-ui/primitives/radio-group.tsx +0 -43
  60. package/components/catalyst-ui/primitives/resizable.tsx +0 -56
  61. package/components/catalyst-ui/primitives/select.tsx +0 -155
  62. package/components/catalyst-ui/primitives/separator.tsx +0 -74
  63. package/components/catalyst-ui/primitives/sheet.tsx +0 -126
  64. package/components/catalyst-ui/primitives/skeleton.tsx +0 -15
  65. package/components/catalyst-ui/primitives/slider.tsx +0 -27
  66. package/components/catalyst-ui/primitives/switch.tsx +0 -187
  67. package/components/catalyst-ui/primitives/tabs.tsx +0 -335
  68. package/components/catalyst-ui/primitives/textarea.tsx +0 -24
  69. package/components/catalyst-ui/primitives/toggle-group.tsx +0 -55
  70. package/components/catalyst-ui/primitives/toggle.tsx +0 -42
  71. package/components/catalyst-ui/primitives/tooltip.tsx +0 -116
  72. package/components/catalyst-ui/utils/basic-auth.tsx +0 -40
  73. package/components/catalyst-ui/utils/context-storage.tsx +0 -19
  74. package/components/catalyst-ui/utils/cors-middleware.tsx +0 -71
  75. package/components/catalyst-ui/utils/deferred-content.tsx +0 -595
  76. package/components/catalyst-ui/utils/honeypot-middleware.tsx +0 -38
  77. package/components/catalyst-ui/utils/incId.tsx +0 -75
  78. package/components/catalyst-ui/utils/jwk-auth.tsx +0 -36
  79. package/components/catalyst-ui/utils/request-id.tsx +0 -14
  80. package/components/catalyst-ui/utils/secure-headers.tsx +0 -37
  81. package/components/catalyst-ui/utils/server-timing.tsx +0 -23
  82. package/components/catalyst-ui/utils/utils.ts +0 -43
  83. package/components/catalyst-ui/utils/with-cookie.tsx +0 -43
  84. package/components/catalyst-ui/x/accordian-x.tsx +0 -428
  85. package/components/catalyst-ui/x/alert-x.tsx +0 -413
  86. package/components/catalyst-ui/x/animated-text-x.tsx +0 -2242
  87. package/components/catalyst-ui/x/avatar-x.tsx +0 -515
  88. package/components/catalyst-ui/x/badge-x.tsx +0 -670
  89. package/components/catalyst-ui/x/button-X.tsx +0 -2857
  90. package/components/catalyst-ui/x/button-group-x.tsx +0 -847
  91. package/components/catalyst-ui/x/calendar-x.tsx +0 -1910
  92. package/components/catalyst-ui/x/card-x.tsx +0 -2597
  93. package/components/catalyst-ui/x/checkbox-x.tsx +0 -656
  94. package/components/catalyst-ui/x/collapsible-x.tsx +0 -1360
  95. package/components/catalyst-ui/x/combobox-x.tsx +0 -911
  96. package/components/catalyst-ui/x/data-table-x.tsx +0 -1753
  97. package/components/catalyst-ui/x/date-picker-x.tsx +0 -648
  98. package/components/catalyst-ui/x/dialog-x.tsx +0 -659
  99. package/components/catalyst-ui/x/dropdown-menu-x.tsx +0 -612
  100. package/components/catalyst-ui/x/hover-card-x.tsx +0 -375
  101. package/components/catalyst-ui/x/icon-x.tsx +0 -840
  102. package/components/catalyst-ui/x/input-mask-x.tsx +0 -981
  103. package/components/catalyst-ui/x/input-otp-x.tsx +0 -659
  104. package/components/catalyst-ui/x/loader-x.tsx +0 -1757
  105. package/components/catalyst-ui/x/pagination-x.tsx +0 -622
  106. package/components/catalyst-ui/x/popover-x.tsx +0 -744
  107. package/components/catalyst-ui/x/radio-group-x.tsx +0 -499
  108. package/components/catalyst-ui/x/select-x.tsx +0 -1127
  109. package/components/catalyst-ui/x/sheet-x.tsx +0 -668
  110. package/components/catalyst-ui/x/switch-x.tsx +0 -681
  111. package/components/catalyst-ui/x/table-x.tsx +0 -574
  112. package/components/catalyst-ui/x/tabs-x.tsx +0 -839
  113. package/components/catalyst-ui/x/textarea-x.tsx +0 -1263
  114. package/components/catalyst-ui/x/tooltip-x.tsx +0 -396
  115. package/components/catalyst-ui/x/tracker-x.tsx +0 -560
  116. package/data/bg-data.tsx +0 -901
  117. package/data/buttons-data.tsx +0 -2327
  118. package/data/charts-data.tsx +0 -102
  119. package/data/chat-data.tsx +0 -83
  120. package/data/code-data.tsx +0 -1040
  121. package/data/comboboxes-data.tsx +0 -1843
  122. package/data/command-data.tsx +0 -1381
  123. package/data/core-data.tsx +0 -15953
  124. package/data/crm-data.tsx +0 -47
  125. package/data/data.tsx +0 -159
  126. package/data/date-and-time-data.tsx +0 -554
  127. package/data/dependencies.tsx +0 -7
  128. package/data/ecommerce-data.tsx +0 -1387
  129. package/data/forms-data.tsx +0 -7890
  130. package/data/hooks-data.tsx +0 -5487
  131. package/data/index.ts +0 -34
  132. package/data/inputs-data.tsx +0 -557
  133. package/data/interactive-data.tsx +0 -5394
  134. package/data/lofi-data.tsx +0 -18295
  135. package/data/marketing-data.tsx +0 -2546
  136. package/data/media-data.tsx +0 -1510
  137. package/data/motion-data.tsx +0 -5801
  138. package/data/overlay-data.tsx +0 -4136
  139. package/data/pdf-data.tsx +0 -124
  140. package/data/pos-data.tsx +0 -213
  141. package/data/postcss.config.js +0 -6
  142. package/data/primitive-data.tsx +0 -5170
  143. package/data/prompt-data.tsx +0 -1226
  144. package/data/requiredLibs.ts +0 -4
  145. package/data/sandbox-data.tsx +0 -1
  146. package/data/sidebars-data.tsx +0 -5421
  147. package/data/stacks-data.tsx +0 -32
  148. package/data/table-data.tsx +0 -706
  149. package/data/tailwind.config.js +0 -270
  150. package/data/tailwind.config.ngin.js +0 -3830
  151. package/data/tailwind.css +0 -431
  152. package/data/tools-data.tsx +0 -6910
  153. package/data/typography-data.tsx +0 -2050
  154. package/data/utils-data.tsx +0 -6500
  155. package/data/x-data.tsx +0 -1171
@@ -1,656 +0,0 @@
1
- import {Field, Checkbox, FieldLabel, FieldDescription, Badge,MotionCheckbox, } from "~/components/catalyst-ui"
2
- import { useId } from 'react'
3
- import { HeartIcon, CircleCheckIcon, } from 'lucide-react'
4
-
5
-
6
- /**
7
- * ★ ━━━━ ☆ ━━━━ CheckboxX ━━━━ ☆ ━━━━ ★
8
- * type CheckboxXType =
9
- * | 'default' | 'Indeterminate' | 'TodoList' | 'Badge' | 'CustomIcons' // Basic & Interactive
10
- * | 'FilledIcon' | 'Card' | 'Tree' | 'Form' // Visual & Layout
11
- * | 'Animated' | 'AnimatedTodoList' | 'Confetti' // Animated
12
- *
13
- * ★ ━━━━ ☆ ━━━━ USAGE ━━━━ ☆ ━━━━ ★
14
- *
15
- * ★ ━━━━━━━━━ Default Checkbox ━━━━━━━━━ ★
16
- * ```jsx
17
- * <CheckboxX
18
- * checked={checked}
19
- * setChecked={setChecked}
20
- * label="Accept terms"
21
- * description="Click to agree"
22
- * />
23
- * ```
24
- *
25
- * ★ ━━━━━━━━━ Indeterminate Checkbox ━━━━━━━━━ ★
26
- * ```jsx
27
- * <CheckboxX
28
- * checkbox="Indeterminate"
29
- * checked={checked}
30
- * setChecked={setChecked}
31
- * label="Select all"
32
- * description="Check/uncheck all items"
33
- * />
34
- * ```
35
- *
36
- * ★ ━━━━━━━━━ Todo List Checkbox ━━━━━━━━━ ★
37
- * ```jsx
38
- * <CheckboxX
39
- * checkbox="TodoList"
40
- * items={todoItems}
41
- * setItems={setTodoItems}
42
- * />
43
- *
44
- * // Todo items array structure:
45
- * const [todoItems, setTodoItems] = useState([
46
- * { label: 'Buy groceries', description: 'Milk, eggs, bread', checked: false },
47
- * { label: 'Call mom', description: 'Wish happy birthday', checked: false },
48
- * { label: 'Finish report', description: 'Due by Friday', checked: true }
49
- * ]);
50
- * ```
51
- *
52
- * ★ ━━━━━━━━━ Badge Checkbox Group ━━━━━━━━━ ★
53
- * ```jsx
54
- * <CheckboxX
55
- * checkbox="Badge"
56
- * orientation="horizontal"
57
- * items={badgeItems}
58
- * />
59
- *
60
- * // Badge items array structure:
61
- * const badgeItems = [
62
- * { label: 'React', checked: false },
63
- * { label: 'TypeScript', checked: true },
64
- * { label: 'Tailwind', checked: false }
65
- * ];
66
- * ```
67
- *
68
- * ★ ━━━━━━━━━ Custom Icons Checkbox ━━━━━━━━━ ★
69
- * ```jsx
70
- * import { HeartIcon, StarIcon } from 'lucide-react';
71
- *
72
- * <CheckboxX
73
- * checkbox="CustomIcons"
74
- * checked={checked}
75
- * setChecked={setChecked}
76
- * uncheckedIcon={HeartIcon}
77
- * checkedIcon={StarIcon}
78
- * label="Favorite"
79
- * description="Add to favorites"
80
- * ciCN="stroke-1 text-gray-400"
81
- * uiCN="fill-yellow-400 stroke-yellow-400 stroke-1"
82
- * />
83
- * ```
84
- *
85
- * ★ ━━━━━━━━━ Filled Icon Checkbox ━━━━━━━━━ ★
86
- * ```jsx
87
- * <CheckboxX
88
- * checkbox="FilledIcon"
89
- * checked={checked}
90
- * setChecked={setChecked}
91
- * color="bg-blue-500 data-[state=checked]:bg-blue-500"
92
- * label="Confirm"
93
- * description="Circle check icon"
94
- * />
95
- * ```
96
- *
97
- * ★ ━━━━━━━━━ Card Style Checkbox ━━━━━━━━━ ★
98
- * ```jsx
99
- * <CheckboxX
100
- * checkbox="Card"
101
- * checked={checked}
102
- * setChecked={setChecked}
103
- * label="Premium Plan"
104
- * description="Includes advanced features"
105
- * />
106
- * ```
107
- *
108
- * ★ ━━━━━━━━━ Tree Structure Checkbox ━━━━━━━━━ ★
109
- * ```jsx
110
- * <CheckboxX
111
- * checkbox="Tree"
112
- * checked={checked}
113
- * setChecked={setChecked}
114
- * selected={selectedItems}
115
- * setSelected={setSelectedItems}
116
- * items={['Child 1', 'Child 2', 'Child 3']}
117
- * />
118
- * ```
119
- *
120
- * ★ ━━━━━━━━━ Form Checkbox ━━━━━━━━━ ★
121
- * ```jsx
122
- * <CheckboxX
123
- * checkbox="Form"
124
- * label="Accept terms and conditions"
125
- * description="By clicking this checkbox, you agree to the terms and conditions."
126
- * />
127
- * ```
128
- *
129
- * ★ ━━━━━━━━━ Animated Checkbox ━━━━━━━━━ ★
130
- * ```jsx
131
- * <CheckboxX
132
- * checkbox="Animated"
133
- * checked={checked}
134
- * setChecked={setChecked}
135
- * label="Animated toggle"
136
- * description="Smooth animation on change"
137
- * />
138
- * ```
139
- *
140
- * ★ ━━━━━━━━━ Animated Todo List ━━━━━━━━━ ★
141
- * ```jsx
142
- * <CheckboxX
143
- * checkbox="AnimatedTodoList"
144
- * items={todoItems}
145
- * setItems={setTodoItems}
146
- * />
147
- * ```
148
- *
149
- * ★ ━━━━━━━━━ Confetti Checkbox ━━━━━━━━━ ★
150
- * ```jsx
151
- * <CheckboxX
152
- * checkbox="Confetti"
153
- * checked={checked}
154
- * setChecked={setChecked}
155
- * label="Celebration!"
156
- * description="Check to celebrate"
157
- * />
158
- * ```
159
- *
160
- * ★ ━━━━━━━━━ Props ━━━━━━━━━ ★
161
- *
162
- * Common Props (available for most variants):
163
- * - `checkbox`: CheckboxXType - Specifies which variant to use
164
- * - `checked`: boolean | 'indeterminate' - Checked state
165
- * - `setChecked`: (checked: boolean | 'indeterminate') => void - State change callback
166
- * - `label`: string - Label text
167
- * - `description`: string - Description text
168
- * - `side`: 'left' | 'right' - Label position relative to checkbox
169
- * - `className`: string - Additional CSS classes
170
- *
171
- * Variant-Specific Props:
172
- *
173
- * TodoList:
174
- * - `items`: Array<{ label?: string, description?: string, checked: boolean, className?: string }>
175
- * - `setItems`: (items: TodoItem[]) => void
176
- *
177
- * Badge:
178
- * - `orientation`: string - Layout orientation
179
- * - `items`: Array<{ label?: string, description?: string, checked: boolean, className?: string }>
180
- *
181
- * CustomIcons:
182
- * - `uncheckedIcon`: IconComponent - Icon to show when unchecked
183
- * - `checkedIcon`: IconComponent - Icon to show when checked
184
- * - `ciCN`: string - CSS classes for checked icon
185
- * - `uiCN`: string - CSS classes for unchecked icon
186
- *
187
- * FilledIcon:
188
- * - `color`: string - CSS classes for background color
189
- *
190
- * Tree:
191
- * - `selected`: string[] - Array of selected child labels
192
- * - `setSelected`: (selected: string[]) => void
193
- * - `items`: string[] - Array of child item labels
194
- *
195
- * AnimatedTodoList:
196
- * - `items`: Array<{ label?: string, description?: string, checked: boolean, className?: string }>
197
- * - `setItems`: (items: TodoItem[]) => void
198
- *
199
- * Confetti:
200
- * - Uses same props as DefaultCheckbox with confetti animation
201
- *
202
- * ★ ━━━━━━━━━ Import ━━━━━━━━━ ★
203
- * ```javascript
204
- * import { CheckboxX } from "./CheckboxX";
205
- *
206
- * // Lucide icons (for CustomIcons variant)
207
- * import { HeartIcon, StarIcon, CircleCheckIcon } from 'lucide-react';
208
- * ```
209
- *
210
- * ★ ━━━━━━━━━ State Management Examples ━━━━━━━━━ ★
211
- * ```typescript
212
- * // Single checkbox state
213
- * const [checked, setChecked] = useState(false);
214
- *
215
- * // Todo list state
216
- * const [todoItems, setTodoItems] = useState([
217
- * { label: 'Task 1', description: 'Description', checked: false },
218
- * { label: 'Task 2', description: 'Description', checked: true }
219
- * ]);
220
- *
221
- * // Tree selection state
222
- * const [checked, setChecked] = useState<'indeterminate' | boolean>(false);
223
- * const [selected, setSelected] = useState<string[]>(['Child 1', 'Child 2']);
224
- * const items = ['Child 1', 'Child 2', 'Child 3'];
225
- * ```
226
- *
227
- */
228
-
229
- export function CheckboxX({ checkbox = 'default', children, ...props }: any) {
230
- switch (checkbox) {
231
- case 'Indeterminate':
232
- return <Indeterminate {...props} />
233
- case 'TodoList':
234
- return <TodoList {...props} />
235
- case 'Badge':
236
- return <BadgeCheckbox {...props} />
237
- case 'CustomIcons':
238
- return <CustomIcons {...props} />
239
- case 'FilledIcon':
240
- return <FilledIcon {...props} />
241
- case 'Card':
242
- return <Card {...props} />
243
- case 'Tree':
244
- return <Tree {...props} />
245
- case 'Form':
246
- return <Form {...props} />
247
- case 'Animated':
248
- return <Animated {...props} />
249
- case 'AnimatedTodoList':
250
- return <AnimatedTodoList {...props} />
251
- case 'Confetti':
252
- return <Confetti {...props} />
253
- default:
254
- return <DefaultCheckbox {...props} />;
255
- }
256
- }
257
-
258
- const DefaultCheckbox = ({ checked, setChecked, label, description, className, side = "right", ...props }) => {
259
- const id = useId()
260
-
261
- return (
262
- <Field className="flex items-start gap-2">
263
- {side === 'left' && (
264
- <div className="flex-1">
265
- {label && (<FieldLabel>{label}</FieldLabel>)}
266
- {description && (<FieldDescription>{description}</FieldDescription>)}
267
- </div>
268
- )}
269
- <Checkbox
270
- id={id}
271
- checked={checked}
272
- onCheckedChange={setChecked}
273
- {...props}
274
- className={className}
275
- />
276
- {side === 'right' && (
277
- <div className="flex-1">
278
- {label && (<FieldLabel>{label}</FieldLabel>)}
279
- {description && (<FieldDescription>{description}</FieldDescription>)}
280
- </div>
281
- )}
282
- </Field>
283
- )
284
- }
285
- const Indeterminate = ({ checked = 'indeterminate', setChecked, label, description, className, side = "right", ...props }) => {
286
- const id = useId()
287
- return (
288
- <Field className="flex items-start gap-2">
289
- {side === 'left' && (
290
- <div className="flex-1">
291
- {label && (<FieldLabel>{label}</FieldLabel>)}
292
- {description && (<FieldDescription>{description}</FieldDescription>)}
293
- </div>
294
- )}
295
- <Checkbox
296
- id={id}
297
- checked={checked}
298
- onCheckedChange={setChecked}
299
- {...props}
300
- className={className}
301
- />
302
- {side === 'right' && (
303
- <div className="flex-1">
304
- {label && (<FieldLabel>{label}</FieldLabel>)}
305
- {description && (<FieldDescription>{description}</FieldDescription>)}
306
- </div>
307
- )}
308
- </Field>
309
- )
310
- }
311
- const items = [
312
- { label: '', description: '', checked: false }
313
- ]
314
- const TodoList = ({ items, setItems }) => {
315
- const handleCheckedChange = (index: number, checked: boolean) => {
316
- const newItems = [...items]
317
- newItems[index].checked = checked
318
- setItems(newItems)
319
- }
320
- const id = useId()
321
-
322
- return (
323
- <div className='flex flex-col gap-2'>
324
- {items.map((i, index) => {
325
- return (
326
- <Field className="flex items-start gap-2" key={index}>
327
- <Checkbox
328
- id={id}
329
- checked={i.checked}
330
- onCheckedChange={(checked) => handleCheckedChange(index, checked)}
331
- className={i.className}
332
- />
333
- <div className="flex-1">
334
- {i.label && (<FieldLabel htmlFor={id} className='after:bg-primary peer-data-[state=checked]:text-primary relative after:absolute after:top-1/2 after:left-0 after:h-px after:w-full after:origin-bottom after:scale-x-0 after:transition-transform after:duration-500 after:ease-in-out peer-data-[state=checked]:after:origin-bottom peer-data-[state=checked]:after:scale-x-100'>{i.label}</FieldLabel>)}
335
- {i.description && (<FieldDescription htmlFor={id} className='after:bg-primary peer-data-[state=checked]:text-primary relative after:absolute after:top-1/2 after:left-0 after:h-px after:w-full after:origin-bottom after:scale-x-0 after:transition-transform after:duration-500 after:ease-in-out peer-data-[state=checked]:after:origin-bottom peer-data-[state=checked]:after:scale-x-100'>{i.description}</FieldDescription>)}
336
- </div>
337
- </Field>
338
- )
339
- })}
340
- </div>
341
- )
342
- }
343
- const BadgeCheckbox = ({ orientation, items }) => {
344
- const handleCheckedChange = (index: number, checked: boolean) => {
345
- const newItems = [...items]
346
- newItems[index].checked = checked
347
- setItems(newItems)
348
- }
349
- return (
350
- <CheckboxGroup varian={orientation}>
351
- {items.map((i, index) => {
352
- return (
353
- <Badge key={label} variant='secondary' className='relative gap-2 rounded-sm px-3 py-1.5'>
354
- <Field className="flex items-start gap-2" key={index}>
355
- <Checkbox
356
- checked={i.checked}
357
- onCheckedChange={(checked) => handleCheckedChange(index, checked)}
358
- className={i.className}
359
- />
360
- <div className="flex-1">
361
- {i.label && (<FieldLabel>{i.label}</FieldLabel>)}
362
- {i.description && (<FieldDescription>{i.description}</FieldDescription>)}
363
- </div>
364
- </Field>
365
- </Badge>
366
- )
367
- })}
368
- </CheckboxGroup>
369
- )
370
- }
371
- const CustomIcons = ({ checkedIcon, ciCN = 'stroke-1', uncheckedIcon, uiCN = 'fill-destructive stroke-destructive stroke-1', checked, setChecked, label, description, className, side = "right", ...props }) => {
372
- const Icon1 = uncheckedIcon ? uncheckedIcon : HeartIcon
373
- const Icon2 = checkedIcon ? checkedIcon : HeartIcon
374
- return (
375
- <Field className="flex items-start gap-2">
376
- {side === 'left' && (
377
- <div className="flex-1">
378
- {label && (<FieldLabel>{label}</FieldLabel>)}
379
- {description && (<FieldDescription>{description}</FieldDescription>)}
380
- </div>
381
- )}
382
- <Checkbox
383
- id={id}
384
- checked={checked}
385
- onCheckedChange={setChecked}
386
- {...props}
387
- className={className}
388
- >
389
- <CheckboxIndicator>
390
- <span className='group-data-[state=checked]:hidden'>
391
- <Icon1 className={ciCN} />
392
- </span>
393
- <span className='group-data-[state=unchecked]:hidden'>
394
- <Icon2 className={uiCN} />
395
- </span>
396
- </CheckboxIndicator>
397
- </Checkbox>
398
- {side === 'right' && (
399
- <div className="flex-1">
400
- {label && (<FieldLabel>{label}</FieldLabel>)}
401
- {description && (<FieldDescription>{description}</FieldDescription>)}
402
- </div>
403
- )}
404
- </Field>
405
-
406
- )
407
- }
408
- const FilledIcon = ({ color, checked, setChecked, label, description, className, side = "right", ...props }) => {
409
- return (
410
- <Field className="flex items-start gap-2">
411
- {side === 'left' && (
412
- <div className="flex-1">
413
- {label && (<FieldLabel>{label}</FieldLabel>)}
414
- {description && (<FieldDescription>{description}</FieldDescription>)}
415
- </div>
416
- )}
417
- <CheckboxPrimitive.Root
418
- data-slot='checkbox'
419
- checked={checked}
420
- onCheckedChange={setChecked}
421
- {...props}
422
- className={cn('peer bg-destructive data-[state=checked]:text-destructive focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 w-7 h-7 shrink-0 rounded-full shadow-xs transition-shadow outline-none focus-visible:ring-[3px]', color, className)}
423
- >
424
- <CheckboxPrimitive.Indicator data-slot='checkbox-indicator' className='flex items-center justify-center text-current transition-none' >
425
- <CircleCheckIcon className='size-5.5 fill-white stroke-current' />
426
- </CheckboxPrimitive.Indicator>
427
- </CheckboxPrimitive.Root>
428
- {side === 'right' && (
429
- <div className="flex-1">
430
- {label && (<FieldLabel>{label}</FieldLabel>)}
431
- {description && (<FieldDescription>{description}</FieldDescription>)}
432
- </div>
433
- )}
434
- </Field>
435
- )
436
- }
437
- const Card = ({ checked, setChecked, label, description, className, side = "right", ...props }) => {
438
- return (
439
- <Field className="flex items-start gap-2 hover:bg-accent/50 flex items-start gap-2 rounded-lg border p-3 has-[[aria-checked=true]]:border-blue-600 has-[[aria-checked=true]]:bg-blue-50 dark:has-[[aria-checked=true]]:border-blue-900 dark:has-[[aria-checked=true]]:bg-blue-950">
440
- {side === 'left' && (
441
- <div className="flex-1">
442
- {label && (<FieldLabel>{label}</FieldLabel>)}
443
- {description && (<FieldDescription>{description}</FieldDescription>)}
444
- </div>
445
- )}
446
- <Checkbox
447
- id={id}
448
- checked={checked}
449
- onCheckedChange={setChecked}
450
- {...props}
451
- className={cn('data-[state=checked]:border-blue-600 data-[state=checked]:bg-blue-600 data-[state=checked]:text-white dark:data-[state=checked]:border-blue-700 dark:data-[state=checked]:bg-blue-700', className)}
452
- />
453
- {side === 'right' && (
454
- <div className="grid gap-1.5 font-normal">
455
- {label && (<FieldLabel className='text-sm leading-none font-medium'>{label}</FieldLabel>)}
456
- {description && (<FieldDescription className='text-muted-foreground text-sm'>{description}</FieldDescription>)}
457
- </div>
458
- )}
459
- </Field>
460
- )
461
- }
462
- const Tree = ({ checked = 'indeterminate', setChecked, selected = ['Child 1', 'Child 2'], setSelected, label, description, className, side = "right", ...props }) => {
463
- useEffect(() => {
464
- if (selected.length === items.length) {
465
- setChecked(true)
466
- } else if (selected.length > 0) {
467
- setChecked('indeterminate')
468
- } else {
469
- setChecked(false)
470
- }
471
- }, [selected])
472
-
473
- const handleCheckedChange = (checked: CheckboxPrimitive.CheckedState) => {
474
- setChecked(checked)
475
-
476
- if (checked === true) {
477
- setSelected([...items])
478
- } else if (checked === false) {
479
- setSelected([])
480
- }
481
- }
482
-
483
- return (
484
- <div className='flex flex-col gap-4'>
485
- <div className='flex items-center gap-2'>
486
- <Checkbox id='parent' checked={checked} onCheckedChange={handleCheckedChange} />
487
- <Label htmlFor='parent'>Parent</Label>
488
- </div>
489
- <div className='flex flex-col gap-2 pl-6'>
490
- {items.map(label => (
491
- <div key={label} className='flex items-center gap-2'>
492
- <Checkbox
493
- id={label}
494
- checked={selected.includes(label)}
495
- onCheckedChange={checked =>
496
- setSelected(checked ? [...selected, label] : selected.filter(item => item !== label))
497
- }
498
- />
499
- <Label htmlFor={label}>{label}</Label>
500
- </div>
501
- ))}
502
- </div>
503
- </div>
504
- )
505
- }
506
- const Form = ({ checked, setChecked, label, description, className, side = "right", ...props }) => {
507
- const id = useId()
508
-
509
- return (
510
- <div className='flex items-start gap-2'>
511
- <Checkbox id={id} defaultChecked />
512
- <div className='grid gap-2'>
513
- <Label htmlFor={id} className='gap-1 leading-4'>
514
- Accept terms and conditions
515
- </Label>
516
- <p className='text-muted-foreground text-xs'>
517
- By clicking this checkbox, you agree to the terms and conditions.
518
- </p>
519
- <div className='flex flex-wrap gap-2'>
520
- <Button variant='outline' size='sm'>
521
- Reset
522
- </Button>
523
- <Button size='sm'>Submit</Button>
524
- </div>
525
- </div>
526
- </div>
527
- )
528
- }
529
- const Animated = ({ checked, setChecked, label, description, className, side = "right", ...props }) => {
530
- const id = useId()
531
-
532
- return (
533
- <Field className="flex items-start gap-2">
534
- {side === 'left' && (
535
- <div className="flex-1">
536
- {label && (<FieldLabel>{label}</FieldLabel>)}
537
- {description && (<FieldDescription>{description}</FieldDescription>)}
538
- </div>
539
- )}
540
- <MotionCheckbox
541
- id={id}
542
- checked={checked}
543
- onCheckedChange={setChecked}
544
- {...props}
545
- className={className}
546
- />
547
- {side === 'right' && (
548
- <div className="flex-1">
549
- {label && (<FieldLabel>{label}</FieldLabel>)}
550
- {description && (<FieldDescription>{description}</FieldDescription>)}
551
- </div>
552
- )}
553
- </Field>
554
- )
555
- }
556
- const AnimatedTodoList = ({ items, setItems }) => {
557
- const id = useId()
558
- const handleCheckedChange = (index: number, checked: boolean) => {
559
- const newItems = [...items]
560
- newItems[index].checked = checked
561
- setItems(newItems)
562
- }
563
- return (
564
- <div className='flex flex-col gap-2'>
565
- {items.map((i, index) => {
566
- return (
567
- <Field className="flex items-start gap-2" key={index}>
568
- <Checkbox
569
- id={id}
570
- checked={i.checked}
571
- onCheckedChange={(checked) => handleCheckedChange(index, checked)}
572
- className={i.className}
573
- />
574
- <div className="flex-1">
575
- {i.label && (<FieldLabel htmlFor={id} className='after:bg-primary peer-data-[state=checked]:text-primary relative after:absolute after:top-1/2 after:left-0 after:h-px after:w-full after:origin-bottom after:scale-x-0 after:transition-transform after:duration-500 after:ease-in-out peer-data-[state=checked]:after:origin-bottom peer-data-[state=checked]:after:scale-x-100'>{i.label}</FieldLabel>)}
576
- {i.description && (<FieldDescription htmlFor={id} className='after:bg-primary peer-data-[state=checked]:text-primary relative after:absolute after:top-1/2 after:left-0 after:h-px after:w-full after:origin-bottom after:scale-x-0 after:transition-transform after:duration-500 after:ease-in-out peer-data-[state=checked]:after:origin-bottom peer-data-[state=checked]:after:scale-x-100'>{i.description}</FieldDescription>)}
577
- </div>
578
- </Field>
579
- )
580
- })}
581
- </div>
582
- )
583
- }
584
- const particleAnimation = ({ index, checked, setChecked, label, description, className, side = "right", ...props }) => {
585
- const angle = Math.random() * Math.PI * 2
586
- const distance = 30 + Math.random() * 20
587
-
588
- return {
589
- initial: { x: '50%', y: '50%', scale: 0, opacity: 0 },
590
- animate: {
591
- x: `calc(50% + ${Math.cos(angle) * distance}px)`,
592
- y: `calc(50% + ${Math.sin(angle) * distance}px)`,
593
- scale: [0, 1, 0],
594
- opacity: [0, 1, 0]
595
- },
596
- transition: { duration: 0.4, delay: index * 0.05, ease: easeOut }
597
- }
598
- }
599
- const ConfettiPiece = ({ index, checked, setChecked, label, description, className, side = "right", ...props }) => {
600
- const colors = ['#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#FF00FF', '#00FFFF']
601
- const color = colors[index % colors.length]
602
-
603
- return (
604
- <motion.div
605
- className='absolute size-1 rounded-full'
606
- style={{ backgroundColor: color }}
607
- {...particleAnimation(index)}
608
- />
609
- )
610
- }
611
- const Confetti = ({ checked, setChecked, label, description, className, side = "right", ...props }) => {
612
- const [showConfetti, setShowConfetti] = useState(false)
613
-
614
- const id = useId()
615
-
616
- const handleCheckedChange = (checked: boolean) => {
617
- if (checked) {
618
- setShowConfetti(true)
619
- setTimeout(() => setShowConfetti(false), 800)
620
- }
621
- setChecked(checked)
622
- }
623
-
624
- return (
625
- <Field className="flex items-start gap-2">
626
- {side === 'left' && (
627
- <div className="flex-1">
628
- {label && (<FieldLabel>{label}</FieldLabel>)}
629
- {description && (<FieldDescription>{description}</FieldDescription>)}
630
- </div>
631
- )}
632
- <Checkbox
633
- id={id}
634
- checked={checked}
635
- onCheckedChange={handleCheckedChange}
636
- {...props}
637
- className={className}
638
- />
639
- {side === 'right' && (
640
- <div className="flex-1">
641
- {label && (<FieldLabel>{label}</FieldLabel>)}
642
- {description && (<FieldDescription>{description}</FieldDescription>)}
643
- </div>
644
- )}
645
- <AnimatePresence>
646
- {showConfetti && (
647
- <div className='pointer-events-none absolute inset-0'>
648
- {[...Array(12)].map((_, i) => (
649
- <ConfettiPiece key={i} index={i} />
650
- ))}
651
- </div>
652
- )}
653
- </AnimatePresence>
654
- </Field>
655
- )
656
- }