@saptanshuwanjari/react-component-library 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,1215 @@
1
+ import { createContext, memo, useState, useContext, useTransition, useEffect, useMemo } from 'react';
2
+ import { zodResolver } from '@hookform/resolvers/zod';
3
+ import { Controller, useForm } from 'react-hook-form';
4
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
+ import { Lock, EyeOff, Eye, ChevronDownIcon, Upload, X, Pencil, ArrowUp, ArrowDown, ArrowUpDown, SlidersHorizontal, Table as Table$1, LayoutGrid, CheckIcon, ChevronUpIcon } from 'lucide-react';
6
+ import { clsx } from 'clsx';
7
+ import { twMerge } from 'tailwind-merge';
8
+ import { useReactTable, getPaginationRowModel, getSortedRowModel, getFilteredRowModel, getCoreRowModel, flexRender } from '@tanstack/react-table';
9
+ import { Slot } from '@radix-ui/react-slot';
10
+ import { cva } from 'class-variance-authority';
11
+ import * as SelectPrimitive from '@radix-ui/react-select';
12
+ import * as PopoverPrimitive from '@radix-ui/react-popover';
13
+ import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
14
+
15
+ // src/components/form/root.tsx
16
+ var FormContext = createContext(null);
17
+ var DEFAULT_FORM_KEY = "__default_form__";
18
+ var formRegistry = /* @__PURE__ */ new Map();
19
+ function Root({
20
+ schema,
21
+ defaultValues,
22
+ onSubmit,
23
+ children,
24
+ enableOptimistic = false,
25
+ title,
26
+ description,
27
+ enableEditMode = false,
28
+ formId
29
+ }) {
30
+ const resolver = schema ? zodResolver(schema) : void 0;
31
+ const [isPending, startTransition] = useTransition();
32
+ const [isEditing, setIsEditing] = useState(!enableEditMode);
33
+ const methods = useForm({
34
+ resolver,
35
+ defaultValues
36
+ });
37
+ const handleFormSubmit = methods.handleSubmit((data) => {
38
+ if (enableOptimistic) {
39
+ startTransition(() => {
40
+ void onSubmit(data);
41
+ });
42
+ return;
43
+ }
44
+ return onSubmit(data);
45
+ });
46
+ useEffect(() => {
47
+ const key = formId ?? DEFAULT_FORM_KEY;
48
+ formRegistry.set(key, setIsEditing);
49
+ return () => {
50
+ formRegistry.delete(key);
51
+ };
52
+ }, [formId, setIsEditing]);
53
+ return /* @__PURE__ */ jsx(FormContext.Provider, { value: { ...methods, schema, isPending, isEditing, setIsEditing }, children: /* @__PURE__ */ jsxs(
54
+ "form",
55
+ {
56
+ onSubmit: handleFormSubmit,
57
+ className: "bg-card text-card-foreground rounded-xl border shadow-sm p-6 space-y-6",
58
+ children: [
59
+ (title || description) && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
60
+ title && /* @__PURE__ */ jsx("h2", { className: "text-2xl font-semibold tracking-tight", children: title }),
61
+ description && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: description })
62
+ ] }),
63
+ children
64
+ ]
65
+ }
66
+ ) });
67
+ }
68
+ var root_default = Root;
69
+ function useFormCtx() {
70
+ const ctx = useContext(FormContext);
71
+ if (!ctx) throw new Error("Form components must be used inside Form.Root");
72
+ return ctx;
73
+ }
74
+ var ShadField = ({ children }) => /* @__PURE__ */ jsx("div", { className: "space-y-2", children });
75
+ var FieldLabel = ({ htmlFor, children }) => /* @__PURE__ */ jsx("label", { htmlFor, className: "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70", children });
76
+ var FieldError = ({ children }) => children ? /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-destructive", children }) : null;
77
+ function Field({
78
+ name,
79
+ label,
80
+ children
81
+ }) {
82
+ const form = useFormCtx();
83
+ return /* @__PURE__ */ jsxs(ShadField, { children: [
84
+ label ? /* @__PURE__ */ jsx(FieldLabel, { htmlFor: String(name), children: label }) : null,
85
+ /* @__PURE__ */ jsx(
86
+ Controller,
87
+ {
88
+ control: form.control,
89
+ name,
90
+ render: ({ field }) => /* @__PURE__ */ jsx(Fragment, { children: children(field) })
91
+ }
92
+ ),
93
+ /* @__PURE__ */ jsx(FieldError, { children: form.formState.errors[name]?.message })
94
+ ] });
95
+ }
96
+ var field_default = Field;
97
+ var Input = ({ className = "", ...props }) => /* @__PURE__ */ jsx(
98
+ "input",
99
+ {
100
+ className: `flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 ${className}`,
101
+ ...props
102
+ }
103
+ );
104
+ var InputField = memo(function InputField2({
105
+ name,
106
+ label,
107
+ placeholder,
108
+ type = "text",
109
+ icon,
110
+ iconAlign = "inline-start",
111
+ startAddon,
112
+ endAddon,
113
+ useGroup
114
+ }) {
115
+ const { isEditing } = useFormCtx();
116
+ return /* @__PURE__ */ jsx(field_default, { name, label, children: (field) => /* @__PURE__ */ jsx(
117
+ Input,
118
+ {
119
+ id: String(name),
120
+ type,
121
+ ...field,
122
+ value: field.value ?? "",
123
+ placeholder,
124
+ disabled: !isEditing
125
+ }
126
+ ) });
127
+ });
128
+ var input_field_default = InputField;
129
+ var PasswordField = memo(function PasswordField2({
130
+ name,
131
+ label,
132
+ placeholder
133
+ }) {
134
+ const [show, setShow] = useState(false);
135
+ return /* @__PURE__ */ jsx(field_default, { name, label, children: (field) => /* @__PURE__ */ jsxs("div", { className: "relative", children: [
136
+ /* @__PURE__ */ jsx("div", { className: "absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none", children: /* @__PURE__ */ jsx(Lock, { className: "h-4 w-4 text-muted-foreground" }) }),
137
+ /* @__PURE__ */ jsx(
138
+ "input",
139
+ {
140
+ id: String(name),
141
+ type: show ? "text" : "password",
142
+ ...field,
143
+ value: field.value ?? "",
144
+ placeholder,
145
+ className: "flex h-10 w-full rounded-md border border-input bg-background pl-10 pr-10 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
146
+ }
147
+ ),
148
+ /* @__PURE__ */ jsx(
149
+ "button",
150
+ {
151
+ type: "button",
152
+ onClick: () => setShow(!show),
153
+ className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors",
154
+ children: show ? /* @__PURE__ */ jsx(EyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(Eye, { className: "h-4 w-4" })
155
+ }
156
+ )
157
+ ] }) });
158
+ });
159
+ var password_field_default = PasswordField;
160
+ var Textarea = ({ className = "", ...props }) => /* @__PURE__ */ jsx(
161
+ "textarea",
162
+ {
163
+ className: `flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 ${className}`,
164
+ ...props
165
+ }
166
+ );
167
+ var TextareaField = memo(function TextareaField2({
168
+ name,
169
+ label,
170
+ placeholder,
171
+ rows = 4
172
+ }) {
173
+ const { isEditing } = useFormCtx();
174
+ return /* @__PURE__ */ jsx(field_default, { name, label, children: (field) => /* @__PURE__ */ jsx(
175
+ Textarea,
176
+ {
177
+ id: String(name),
178
+ ...field,
179
+ value: field.value ?? "",
180
+ placeholder,
181
+ rows,
182
+ disabled: !isEditing,
183
+ className: !isEditing ? "bg-background/50 opacity-80" : ""
184
+ }
185
+ ) });
186
+ });
187
+ var textarea_field_default = TextareaField;
188
+ var Select = ({ children, onValueChange, value }) => /* @__PURE__ */ jsx(
189
+ "select",
190
+ {
191
+ className: "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
192
+ onChange: (e) => onValueChange(e.target.value),
193
+ value,
194
+ children
195
+ }
196
+ );
197
+ var SelectValue = ({ placeholder }) => /* @__PURE__ */ jsx("option", { value: "", children: placeholder });
198
+ var SelectItem = ({ value, children }) => /* @__PURE__ */ jsx("option", { value, children });
199
+ var Input2 = ({ className = "", ...props }) => /* @__PURE__ */ jsx(
200
+ "input",
201
+ {
202
+ className: `flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ${className}`,
203
+ ...props
204
+ }
205
+ );
206
+ var SelectField = memo(function SelectField2({
207
+ name,
208
+ label,
209
+ placeholder = "Select an option",
210
+ options
211
+ }) {
212
+ const { isEditing } = useFormCtx();
213
+ return /* @__PURE__ */ jsx(field_default, { name, label, children: (field) => !isEditing ? /* @__PURE__ */ jsx(
214
+ Input2,
215
+ {
216
+ id: String(name),
217
+ value: options.find((opt) => opt.value === field.value)?.label ?? "",
218
+ placeholder,
219
+ disabled: true,
220
+ className: "bg-background/50 opacity-80"
221
+ }
222
+ ) : /* @__PURE__ */ jsxs(Select, { onValueChange: field.onChange, value: field.value ?? "", children: [
223
+ /* @__PURE__ */ jsx(SelectValue, { placeholder }),
224
+ options.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, children: option.label }, option.value))
225
+ ] }) });
226
+ });
227
+ var select_field_default = SelectField;
228
+ var ShadField2 = ({ children }) => /* @__PURE__ */ jsx("div", { className: "space-y-2", children });
229
+ var FieldError2 = ({ children }) => children ? /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-destructive", children }) : null;
230
+ var Checkbox = ({ checked, onCheckedChange, disabled, id }) => /* @__PURE__ */ jsx(
231
+ "input",
232
+ {
233
+ type: "checkbox",
234
+ id,
235
+ checked,
236
+ onChange: (e) => onCheckedChange?.(e.target.checked),
237
+ disabled,
238
+ className: "h-4 w-4 rounded border-gray-300"
239
+ }
240
+ );
241
+ var CheckboxField = memo(function CheckboxField2({
242
+ name,
243
+ label,
244
+ description
245
+ }) {
246
+ const form = useFormCtx();
247
+ return /* @__PURE__ */ jsxs(ShadField2, { children: [
248
+ /* @__PURE__ */ jsx(
249
+ Controller,
250
+ {
251
+ control: form.control,
252
+ name,
253
+ render: ({ field }) => /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
254
+ /* @__PURE__ */ jsx(
255
+ Checkbox,
256
+ {
257
+ id: String(name),
258
+ checked: !!field.value,
259
+ onCheckedChange: form.isEditing ? field.onChange : void 0,
260
+ disabled: !form.isEditing
261
+ }
262
+ ),
263
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-1.5 leading-none", children: [
264
+ label && /* @__PURE__ */ jsx(
265
+ "label",
266
+ {
267
+ htmlFor: String(name),
268
+ className: "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 cursor-pointer",
269
+ children: label
270
+ }
271
+ ),
272
+ description && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: description })
273
+ ] })
274
+ ] })
275
+ }
276
+ ),
277
+ /* @__PURE__ */ jsx(FieldError2, { children: form.formState.errors[name]?.message })
278
+ ] });
279
+ });
280
+ var checkbox_field_default = CheckboxField;
281
+ var Button = ({ children, className = "", ...props }) => /* @__PURE__ */ jsx(
282
+ "button",
283
+ {
284
+ className: `inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium h-10 px-4 py-2 border ${className}`,
285
+ ...props,
286
+ children
287
+ }
288
+ );
289
+ var DateField = memo(function DateField2({
290
+ name,
291
+ label,
292
+ placeholder = "Select date"
293
+ }) {
294
+ const [open, setOpen] = useState(false);
295
+ const { isEditing } = useFormCtx();
296
+ return /* @__PURE__ */ jsx(field_default, { name, label, children: (field) => !isEditing ? /* @__PURE__ */ jsxs(
297
+ Button,
298
+ {
299
+ type: "button",
300
+ id: String(name),
301
+ className: "w-full justify-between font-normal bg-background/50 border-border/50",
302
+ disabled: true,
303
+ children: [
304
+ field.value ? new Date(field.value).toLocaleDateString() : placeholder,
305
+ /* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-4 w-4 text-muted-foreground" })
306
+ ]
307
+ }
308
+ ) : /* @__PURE__ */ jsx(
309
+ "input",
310
+ {
311
+ type: "date",
312
+ id: String(name),
313
+ className: "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm",
314
+ value: field.value ? new Date(field.value).toISOString().split("T")[0] : "",
315
+ onChange: (e) => field.onChange(e.target.value ? new Date(e.target.value) : null)
316
+ }
317
+ ) });
318
+ });
319
+ var date_field_default = DateField;
320
+ var Input3 = ({ className = "", ...props }) => /* @__PURE__ */ jsx(
321
+ "input",
322
+ {
323
+ className: `flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ${className}`,
324
+ ...props
325
+ }
326
+ );
327
+ var InputGroup = ({ children }) => /* @__PURE__ */ jsx("div", { className: "relative flex items-center", children });
328
+ var InputGroupAddon = ({ children }) => /* @__PURE__ */ jsx("div", { className: "absolute left-3 flex items-center", children });
329
+ var InputGroupInput = (props) => /* @__PURE__ */ jsx(Input3, { className: "pl-10", ...props });
330
+ var FileField = memo(function FileField2({
331
+ name,
332
+ label,
333
+ accept,
334
+ multiple
335
+ }) {
336
+ const { isEditing } = useFormCtx();
337
+ return /* @__PURE__ */ jsx(field_default, { name, label, children: (field) => {
338
+ const files = field.value;
339
+ const filename = files && files.length ? files[0].name : "";
340
+ if (!isEditing) {
341
+ return /* @__PURE__ */ jsxs(InputGroup, { children: [
342
+ /* @__PURE__ */ jsx(
343
+ Input3,
344
+ {
345
+ id: `${String(name)}_display`,
346
+ type: "text",
347
+ value: filename,
348
+ placeholder: accept ? `Accepts ${accept}` : "No file selected",
349
+ disabled: true,
350
+ className: "bg-background/50 opacity-80 pl-10"
351
+ }
352
+ ),
353
+ /* @__PURE__ */ jsx(InputGroupAddon, { children: /* @__PURE__ */ jsx(Upload, { className: "text-muted-foreground h-4 w-4" }) })
354
+ ] });
355
+ }
356
+ return /* @__PURE__ */ jsxs(InputGroup, { children: [
357
+ /* @__PURE__ */ jsx(
358
+ InputGroupInput,
359
+ {
360
+ id: String(name),
361
+ type: "file",
362
+ accept,
363
+ multiple,
364
+ onChange: (e) => field.onChange(e.target.files),
365
+ onBlur: field.onBlur,
366
+ name: field.name,
367
+ ref: field.ref
368
+ }
369
+ ),
370
+ /* @__PURE__ */ jsx(InputGroupAddon, { children: /* @__PURE__ */ jsx(Upload, { className: "text-muted-foreground h-4 w-4" }) })
371
+ ] });
372
+ } });
373
+ });
374
+ var file_field_default = FileField;
375
+ function cn(...inputs) {
376
+ return twMerge(clsx(inputs));
377
+ }
378
+ var Avatar = ({ className, children }) => /* @__PURE__ */ jsx("div", { className: cn("relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full", className), children });
379
+ var AvatarImage = ({ src, alt }) => src ? /* @__PURE__ */ jsx("img", { src, alt, className: "aspect-square h-full w-full" }) : null;
380
+ var AvatarFallback = ({ children }) => /* @__PURE__ */ jsx("div", { className: "flex h-full w-full items-center justify-center rounded-full bg-muted", children });
381
+ var Label = ({ htmlFor, children, className }) => /* @__PURE__ */ jsx("label", { htmlFor, className, children });
382
+ var Input4 = (props) => /* @__PURE__ */ jsx("input", { ...props });
383
+ var Button2 = ({ children, ...props }) => /* @__PURE__ */ jsx("button", { className: "px-3 py-1 text-sm rounded hover:bg-accent", ...props, children });
384
+ var ProfilePictureField = memo(function ProfilePictureField2({
385
+ name,
386
+ label,
387
+ className,
388
+ avatarClassName,
389
+ fallback = "User"
390
+ }) {
391
+ const { isEditing } = useFormCtx();
392
+ const [preview, setPreview] = useState(null);
393
+ return /* @__PURE__ */ jsx(field_default, { name, label, children: (field) => {
394
+ const currentValue = field.value;
395
+ const displayUrl = preview || (typeof currentValue === "string" ? currentValue : null);
396
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col items-center gap-4", className), children: [
397
+ /* @__PURE__ */ jsxs(Avatar, { className: cn("h-24 w-24", avatarClassName), children: [
398
+ /* @__PURE__ */ jsx(AvatarImage, { src: displayUrl || "", alt: "Profile picture" }),
399
+ /* @__PURE__ */ jsx(AvatarFallback, { children: fallback })
400
+ ] }),
401
+ isEditing && /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2", children: [
402
+ /* @__PURE__ */ jsxs(
403
+ Label,
404
+ {
405
+ htmlFor: String(name),
406
+ className: "cursor-pointer inline-flex items-center gap-2 rounded-md border border-input bg-background px-4 py-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground",
407
+ children: [
408
+ /* @__PURE__ */ jsx(Upload, { className: "h-4 w-4" }),
409
+ "Upload Picture"
410
+ ]
411
+ }
412
+ ),
413
+ /* @__PURE__ */ jsx(
414
+ Input4,
415
+ {
416
+ id: String(name),
417
+ type: "file",
418
+ accept: "image/*",
419
+ className: "hidden",
420
+ onChange: (e) => {
421
+ const file = e.target.files?.[0];
422
+ if (file) {
423
+ field.onChange(file);
424
+ const reader = new FileReader();
425
+ reader.onloadend = () => {
426
+ setPreview(reader.result);
427
+ };
428
+ reader.readAsDataURL(file);
429
+ }
430
+ },
431
+ onBlur: field.onBlur,
432
+ name: field.name,
433
+ ref: field.ref
434
+ }
435
+ ),
436
+ displayUrl && /* @__PURE__ */ jsx(
437
+ Button2,
438
+ {
439
+ type: "button",
440
+ onClick: () => {
441
+ field.onChange(null);
442
+ setPreview(null);
443
+ },
444
+ children: "Remove"
445
+ }
446
+ )
447
+ ] })
448
+ ] });
449
+ } });
450
+ });
451
+ var profile_picture_field_default = ProfilePictureField;
452
+ var Button3 = ({ children, ...props }) => /* @__PURE__ */ jsx(
453
+ "button",
454
+ {
455
+ className: "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-4 py-2",
456
+ ...props,
457
+ children
458
+ }
459
+ );
460
+ function Submit({ children, ...props }) {
461
+ const form = useFormCtx();
462
+ const isPending = form.isPending || form.formState.isSubmitting;
463
+ const { isEditing } = form;
464
+ if (!isEditing) return null;
465
+ return /* @__PURE__ */ jsx(Button3, { type: "submit", disabled: isPending || props.disabled, ...props, children: isPending ? "Submitting..." : children });
466
+ }
467
+ var submit_default = Submit;
468
+ var Button4 = ({ children, ...props }) => /* @__PURE__ */ jsx(
469
+ "button",
470
+ {
471
+ className: "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-4 py-2",
472
+ ...props,
473
+ children
474
+ }
475
+ );
476
+ function EditButton({ children, formId, ...props }) {
477
+ const ctx = useContext(FormContext);
478
+ if (ctx) {
479
+ const { isEditing, setIsEditing } = ctx;
480
+ if (isEditing) return null;
481
+ return /* @__PURE__ */ jsx(Button4, { type: "button", onClick: () => setIsEditing?.(true), ...props, children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
482
+ /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4 mr-2" }),
483
+ "Edit Profile"
484
+ ] }) });
485
+ }
486
+ const handleClick = () => {
487
+ const key = formId ?? DEFAULT_FORM_KEY;
488
+ const immediate = formRegistry.get(key);
489
+ if (immediate) return immediate(true);
490
+ let attempts = 0;
491
+ const maxAttempts = 20;
492
+ const interval = setInterval(() => {
493
+ attempts += 1;
494
+ const setter = formRegistry.get(key);
495
+ if (setter) {
496
+ setter(true);
497
+ clearInterval(interval);
498
+ } else if (attempts >= maxAttempts) {
499
+ clearInterval(interval);
500
+ }
501
+ }, 100);
502
+ };
503
+ return /* @__PURE__ */ jsx(Button4, { type: "button", onClick: handleClick, ...props, children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
504
+ /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4 mr-2" }),
505
+ "Edit Profile"
506
+ ] }) });
507
+ }
508
+ var edit_button_default = EditButton;
509
+ var Button5 = ({ children, className = "", ...props }) => /* @__PURE__ */ jsx(
510
+ "button",
511
+ {
512
+ className: `inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 border border-input bg-background hover:bg-accent hover:text-accent-foreground h-10 px-4 py-2 ${className}`,
513
+ ...props,
514
+ children
515
+ }
516
+ );
517
+ function CancelButton({ children, ...props }) {
518
+ const { isEditing, setIsEditing, reset } = useFormCtx();
519
+ if (!isEditing) return null;
520
+ return /* @__PURE__ */ jsx(
521
+ Button5,
522
+ {
523
+ type: "button",
524
+ onClick: () => {
525
+ reset();
526
+ setIsEditing?.(false);
527
+ },
528
+ ...props,
529
+ children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
530
+ /* @__PURE__ */ jsx(X, { className: "h-4 w-4 mr-2" }),
531
+ "Cancel"
532
+ ] })
533
+ }
534
+ );
535
+ }
536
+ var cancel_button_default = CancelButton;
537
+ function LinkField({ label, link, LinkComponent }) {
538
+ const LinkTag = LinkComponent || "a";
539
+ const linkProps = LinkComponent ? { href: link } : { href: link };
540
+ return /* @__PURE__ */ jsx(LinkTag, { ...linkProps, className: "text-sm text-primary hover:underline", children: label });
541
+ }
542
+ var link_field_default = LinkField;
543
+ var FieldGroup = ({ children }) => /* @__PURE__ */ jsx("div", { className: "space-y-4", children });
544
+ var field_group_default = FieldGroup;
545
+
546
+ // src/components/form/index.ts
547
+ var Form = Object.assign(root_default, {
548
+ Field: field_default,
549
+ InputField: input_field_default,
550
+ PasswordField: password_field_default,
551
+ TextareaField: textarea_field_default,
552
+ SelectField: select_field_default,
553
+ CheckboxField: checkbox_field_default,
554
+ DateField: date_field_default,
555
+ FileField: file_field_default,
556
+ ProfilePictureField: profile_picture_field_default,
557
+ Submit: submit_default,
558
+ EditButton: edit_button_default,
559
+ CancelButton: cancel_button_default,
560
+ Group: field_group_default,
561
+ LinkField: link_field_default
562
+ });
563
+ var form_default = Form;
564
+ var DataTableContext = createContext(null);
565
+ function useDataTable() {
566
+ const context = useContext(DataTableContext);
567
+ if (!context) {
568
+ throw new Error("DataTable components must be used within DataTable.Root");
569
+ }
570
+ return context;
571
+ }
572
+ function Root2({
573
+ columns,
574
+ data,
575
+ filters = [],
576
+ defaultViewMode = "table",
577
+ defaultPageSize = 10,
578
+ children
579
+ }) {
580
+ const [viewMode, setViewMode] = useState(defaultViewMode);
581
+ const [sorting, setSorting] = useState([]);
582
+ const [columnFilters, setColumnFilters] = useState([]);
583
+ const [columnVisibility, setColumnVisibility] = useState({});
584
+ const [globalFilter, setGlobalFilter] = useState("");
585
+ const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: defaultPageSize });
586
+ const [activeFilters, setActiveFilters] = useState({});
587
+ const filteredData = useMemo(() => {
588
+ if (Object.keys(activeFilters).length === 0) return data;
589
+ return data.filter((row) => {
590
+ return Object.entries(activeFilters).every(([filterId, filterValue]) => {
591
+ if (!filterValue || Array.isArray(filterValue) && filterValue.length === 0) {
592
+ return true;
593
+ }
594
+ const rowValue = row[filterId];
595
+ if (Array.isArray(filterValue)) {
596
+ return filterValue.includes(String(rowValue));
597
+ }
598
+ return String(rowValue) === String(filterValue);
599
+ });
600
+ });
601
+ }, [data, activeFilters]);
602
+ const table = useReactTable({
603
+ data: filteredData,
604
+ columns,
605
+ state: {
606
+ sorting,
607
+ columnFilters,
608
+ columnVisibility,
609
+ globalFilter,
610
+ pagination
611
+ },
612
+ onSortingChange: setSorting,
613
+ onColumnFiltersChange: setColumnFilters,
614
+ onColumnVisibilityChange: setColumnVisibility,
615
+ onGlobalFilterChange: setGlobalFilter,
616
+ onPaginationChange: setPagination,
617
+ getCoreRowModel: getCoreRowModel(),
618
+ getFilteredRowModel: getFilteredRowModel(),
619
+ getSortedRowModel: getSortedRowModel(),
620
+ getPaginationRowModel: getPaginationRowModel()
621
+ });
622
+ return /* @__PURE__ */ jsx(
623
+ DataTableContext.Provider,
624
+ {
625
+ value: {
626
+ table,
627
+ viewMode,
628
+ setViewMode,
629
+ filters,
630
+ activeFilters,
631
+ setActiveFilters
632
+ },
633
+ children: /* @__PURE__ */ jsx("div", { className: "space-y-4", children })
634
+ }
635
+ );
636
+ }
637
+ var root_default2 = Root2;
638
+ function Input5({ className, type, ...props }) {
639
+ return /* @__PURE__ */ jsx(
640
+ "input",
641
+ {
642
+ type,
643
+ "data-slot": "input",
644
+ className: cn(
645
+ "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
646
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
647
+ "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
648
+ className
649
+ ),
650
+ ...props
651
+ }
652
+ );
653
+ }
654
+ var buttonVariants = cva(
655
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
656
+ {
657
+ variants: {
658
+ variant: {
659
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
660
+ destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
661
+ outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
662
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
663
+ ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
664
+ link: "text-primary underline-offset-4 hover:underline"
665
+ },
666
+ size: {
667
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
668
+ sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
669
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
670
+ icon: "size-9",
671
+ "icon-sm": "size-8",
672
+ "icon-lg": "size-10"
673
+ }
674
+ },
675
+ defaultVariants: {
676
+ variant: "default",
677
+ size: "default"
678
+ }
679
+ }
680
+ );
681
+ function Button6({
682
+ className,
683
+ variant = "default",
684
+ size = "default",
685
+ asChild = false,
686
+ ...props
687
+ }) {
688
+ const Comp = asChild ? Slot : "button";
689
+ return /* @__PURE__ */ jsx(
690
+ Comp,
691
+ {
692
+ "data-slot": "button",
693
+ "data-variant": variant,
694
+ "data-size": size,
695
+ className: cn(buttonVariants({ variant, size, className })),
696
+ ...props
697
+ }
698
+ );
699
+ }
700
+ function Select2({
701
+ ...props
702
+ }) {
703
+ return /* @__PURE__ */ jsx(SelectPrimitive.Root, { "data-slot": "select", ...props });
704
+ }
705
+ function SelectValue2({
706
+ ...props
707
+ }) {
708
+ return /* @__PURE__ */ jsx(SelectPrimitive.Value, { "data-slot": "select-value", ...props });
709
+ }
710
+ function SelectTrigger({
711
+ className,
712
+ size = "default",
713
+ children,
714
+ ...props
715
+ }) {
716
+ return /* @__PURE__ */ jsxs(
717
+ SelectPrimitive.Trigger,
718
+ {
719
+ "data-slot": "select-trigger",
720
+ "data-size": size,
721
+ className: cn(
722
+ "border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
723
+ className
724
+ ),
725
+ ...props,
726
+ children: [
727
+ children,
728
+ /* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4 opacity-50" }) })
729
+ ]
730
+ }
731
+ );
732
+ }
733
+ function SelectContent({
734
+ className,
735
+ children,
736
+ position = "item-aligned",
737
+ align = "center",
738
+ ...props
739
+ }) {
740
+ return /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
741
+ SelectPrimitive.Content,
742
+ {
743
+ "data-slot": "select-content",
744
+ className: cn(
745
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md",
746
+ position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
747
+ className
748
+ ),
749
+ position,
750
+ align,
751
+ ...props,
752
+ children: [
753
+ /* @__PURE__ */ jsx(SelectScrollUpButton, {}),
754
+ /* @__PURE__ */ jsx(
755
+ SelectPrimitive.Viewport,
756
+ {
757
+ className: cn(
758
+ "p-1",
759
+ position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"
760
+ ),
761
+ children
762
+ }
763
+ ),
764
+ /* @__PURE__ */ jsx(SelectScrollDownButton, {})
765
+ ]
766
+ }
767
+ ) });
768
+ }
769
+ function SelectItem2({
770
+ className,
771
+ children,
772
+ ...props
773
+ }) {
774
+ return /* @__PURE__ */ jsxs(
775
+ SelectPrimitive.Item,
776
+ {
777
+ "data-slot": "select-item",
778
+ className: cn(
779
+ "focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
780
+ className
781
+ ),
782
+ ...props,
783
+ children: [
784
+ /* @__PURE__ */ jsx(
785
+ "span",
786
+ {
787
+ "data-slot": "select-item-indicator",
788
+ className: "absolute right-2 flex size-3.5 items-center justify-center",
789
+ children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" }) })
790
+ }
791
+ ),
792
+ /* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children })
793
+ ]
794
+ }
795
+ );
796
+ }
797
+ function SelectScrollUpButton({
798
+ className,
799
+ ...props
800
+ }) {
801
+ return /* @__PURE__ */ jsx(
802
+ SelectPrimitive.ScrollUpButton,
803
+ {
804
+ "data-slot": "select-scroll-up-button",
805
+ className: cn(
806
+ "flex cursor-default items-center justify-center py-1",
807
+ className
808
+ ),
809
+ ...props,
810
+ children: /* @__PURE__ */ jsx(ChevronUpIcon, { className: "size-4" })
811
+ }
812
+ );
813
+ }
814
+ function SelectScrollDownButton({
815
+ className,
816
+ ...props
817
+ }) {
818
+ return /* @__PURE__ */ jsx(
819
+ SelectPrimitive.ScrollDownButton,
820
+ {
821
+ "data-slot": "select-scroll-down-button",
822
+ className: cn(
823
+ "flex cursor-default items-center justify-center py-1",
824
+ className
825
+ ),
826
+ ...props,
827
+ children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4" })
828
+ }
829
+ );
830
+ }
831
+ function Popover({
832
+ ...props
833
+ }) {
834
+ return /* @__PURE__ */ jsx(PopoverPrimitive.Root, { "data-slot": "popover", ...props });
835
+ }
836
+ function PopoverTrigger({
837
+ ...props
838
+ }) {
839
+ return /* @__PURE__ */ jsx(PopoverPrimitive.Trigger, { "data-slot": "popover-trigger", ...props });
840
+ }
841
+ function PopoverContent({
842
+ className,
843
+ align = "center",
844
+ sideOffset = 4,
845
+ ...props
846
+ }) {
847
+ return /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
848
+ PopoverPrimitive.Content,
849
+ {
850
+ "data-slot": "popover-content",
851
+ align,
852
+ sideOffset,
853
+ className: cn(
854
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden",
855
+ className
856
+ ),
857
+ ...props
858
+ }
859
+ ) });
860
+ }
861
+ function Checkbox2({
862
+ className,
863
+ ...props
864
+ }) {
865
+ return /* @__PURE__ */ jsx(
866
+ CheckboxPrimitive.Root,
867
+ {
868
+ "data-slot": "checkbox",
869
+ className: cn(
870
+ "peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
871
+ className
872
+ ),
873
+ ...props,
874
+ children: /* @__PURE__ */ jsx(
875
+ CheckboxPrimitive.Indicator,
876
+ {
877
+ "data-slot": "checkbox-indicator",
878
+ className: "grid place-content-center text-current transition-none",
879
+ children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-3.5" })
880
+ }
881
+ )
882
+ }
883
+ );
884
+ }
885
+ function Toolbar() {
886
+ const { table, viewMode, setViewMode, filters, activeFilters, setActiveFilters } = useDataTable();
887
+ const handleFilterChange = (filterId, value) => {
888
+ setActiveFilters((prev) => ({
889
+ ...prev,
890
+ [filterId]: value === "all" ? "" : value
891
+ }));
892
+ };
893
+ const handleMultiFilterToggle = (filterId, value) => {
894
+ setActiveFilters((prev) => {
895
+ const current = prev[filterId];
896
+ if (!current || !Array.isArray(current)) {
897
+ return { ...prev, [filterId]: [value] };
898
+ }
899
+ const newValues = current.includes(value) ? current.filter((v) => v !== value) : [...current, value];
900
+ return { ...prev, [filterId]: newValues };
901
+ });
902
+ };
903
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4", children: [
904
+ /* @__PURE__ */ jsx("div", { className: "flex-1 max-w-sm", children: /* @__PURE__ */ jsx(
905
+ Input5,
906
+ {
907
+ placeholder: "Search...",
908
+ value: table.getState().globalFilter ?? "",
909
+ onChange: (e) => table.setGlobalFilter(e.target.value),
910
+ className: "w-full"
911
+ }
912
+ ) }),
913
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [
914
+ filters.length > 0 && /* @__PURE__ */ jsxs(Popover, { children: [
915
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button6, { variant: "outline", size: "sm", children: [
916
+ /* @__PURE__ */ jsx(SlidersHorizontal, { className: "h-4 w-4 mr-2" }),
917
+ "Filters"
918
+ ] }) }),
919
+ /* @__PURE__ */ jsx(PopoverContent, { className: "w-80", children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
920
+ /* @__PURE__ */ jsx("h4", { className: "font-medium text-sm", children: "Filters" }),
921
+ filters.map((filter) => /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
922
+ /* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: filter.label }),
923
+ filter.multiSelect ? /* @__PURE__ */ jsx("div", { className: "space-y-2", children: filter.options.map((option) => /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2", children: [
924
+ /* @__PURE__ */ jsx(
925
+ Checkbox2,
926
+ {
927
+ id: `${filter.id}-${option.value}`,
928
+ checked: Array.isArray(activeFilters[filter.id]) && activeFilters[filter.id].includes(option.value),
929
+ onCheckedChange: () => handleMultiFilterToggle(filter.id, option.value)
930
+ }
931
+ ),
932
+ /* @__PURE__ */ jsx(
933
+ "label",
934
+ {
935
+ htmlFor: `${filter.id}-${option.value}`,
936
+ className: "text-sm cursor-pointer",
937
+ children: option.label
938
+ }
939
+ )
940
+ ] }, option.value)) }) : /* @__PURE__ */ jsxs(
941
+ Select2,
942
+ {
943
+ value: activeFilters[filter.id] || "all",
944
+ onValueChange: (value) => handleFilterChange(filter.id, value),
945
+ children: [
946
+ /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue2, { placeholder: filter.placeholder || "Select..." }) }),
947
+ /* @__PURE__ */ jsxs(SelectContent, { children: [
948
+ /* @__PURE__ */ jsx(SelectItem2, { value: "all", children: "All" }),
949
+ filter.options.map((option) => /* @__PURE__ */ jsx(SelectItem2, { value: option.value, children: option.label }, option.value))
950
+ ] })
951
+ ]
952
+ }
953
+ )
954
+ ] }, filter.id))
955
+ ] }) })
956
+ ] }),
957
+ /* @__PURE__ */ jsxs(Popover, { children: [
958
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button6, { variant: "outline", size: "sm", children: [
959
+ /* @__PURE__ */ jsx(Eye, { className: "h-4 w-4 mr-2" }),
960
+ "Columns"
961
+ ] }) }),
962
+ /* @__PURE__ */ jsx(PopoverContent, { className: "w-56", children: /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
963
+ /* @__PURE__ */ jsx("h4", { className: "font-medium text-sm", children: "Toggle Columns" }),
964
+ table.getAllColumns().filter((column) => column.getCanHide()).map((column) => /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2", children: [
965
+ /* @__PURE__ */ jsx(
966
+ Checkbox2,
967
+ {
968
+ id: column.id,
969
+ checked: column.getIsVisible(),
970
+ onCheckedChange: (value) => column.toggleVisibility(!!value)
971
+ }
972
+ ),
973
+ /* @__PURE__ */ jsx("label", { htmlFor: column.id, className: "text-sm cursor-pointer", children: column.id })
974
+ ] }, column.id))
975
+ ] }) })
976
+ ] }),
977
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center border rounded-md", children: [
978
+ /* @__PURE__ */ jsx(
979
+ Button6,
980
+ {
981
+ variant: viewMode === "table" ? "default" : "ghost",
982
+ size: "sm",
983
+ onClick: () => setViewMode("table"),
984
+ className: "rounded-r-none",
985
+ children: /* @__PURE__ */ jsx(Table$1, { className: "h-4 w-4" })
986
+ }
987
+ ),
988
+ /* @__PURE__ */ jsx(
989
+ Button6,
990
+ {
991
+ variant: viewMode === "grid" ? "default" : "ghost",
992
+ size: "sm",
993
+ onClick: () => setViewMode("grid"),
994
+ className: "rounded-l-none",
995
+ children: /* @__PURE__ */ jsx(LayoutGrid, { className: "h-4 w-4" })
996
+ }
997
+ )
998
+ ] }),
999
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1000
+ /* @__PURE__ */ jsx("label", { className: "text-sm text-muted-foreground", children: "Rows" }),
1001
+ /* @__PURE__ */ jsxs(
1002
+ Select2,
1003
+ {
1004
+ value: String(table.getState().pagination.pageSize),
1005
+ onValueChange: (value) => table.setPageSize(Number(value)),
1006
+ children: [
1007
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "w-20", children: /* @__PURE__ */ jsx(SelectValue2, {}) }),
1008
+ /* @__PURE__ */ jsx(SelectContent, { children: [10, 20, 30, 40, 50].map((size) => /* @__PURE__ */ jsx(SelectItem2, { value: String(size), children: size }, size)) })
1009
+ ]
1010
+ }
1011
+ )
1012
+ ] })
1013
+ ] })
1014
+ ] });
1015
+ }
1016
+ var toolbar_default = Toolbar;
1017
+ function Table({ className, ...props }) {
1018
+ return /* @__PURE__ */ jsx(
1019
+ "div",
1020
+ {
1021
+ "data-slot": "table-container",
1022
+ className: "relative w-full overflow-x-auto",
1023
+ children: /* @__PURE__ */ jsx(
1024
+ "table",
1025
+ {
1026
+ "data-slot": "table",
1027
+ className: cn("w-full caption-bottom text-sm", className),
1028
+ ...props
1029
+ }
1030
+ )
1031
+ }
1032
+ );
1033
+ }
1034
+ function TableHeader({ className, ...props }) {
1035
+ return /* @__PURE__ */ jsx(
1036
+ "thead",
1037
+ {
1038
+ "data-slot": "table-header",
1039
+ className: cn("[&_tr]:border-b", className),
1040
+ ...props
1041
+ }
1042
+ );
1043
+ }
1044
+ function TableBody({ className, ...props }) {
1045
+ return /* @__PURE__ */ jsx(
1046
+ "tbody",
1047
+ {
1048
+ "data-slot": "table-body",
1049
+ className: cn("[&_tr:last-child]:border-0", className),
1050
+ ...props
1051
+ }
1052
+ );
1053
+ }
1054
+ function TableRow({ className, ...props }) {
1055
+ return /* @__PURE__ */ jsx(
1056
+ "tr",
1057
+ {
1058
+ "data-slot": "table-row",
1059
+ className: cn(
1060
+ "hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors",
1061
+ className
1062
+ ),
1063
+ ...props
1064
+ }
1065
+ );
1066
+ }
1067
+ function TableHead({ className, ...props }) {
1068
+ return /* @__PURE__ */ jsx(
1069
+ "th",
1070
+ {
1071
+ "data-slot": "table-head",
1072
+ className: cn(
1073
+ "text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
1074
+ className
1075
+ ),
1076
+ ...props
1077
+ }
1078
+ );
1079
+ }
1080
+ function TableCell({ className, ...props }) {
1081
+ return /* @__PURE__ */ jsx(
1082
+ "td",
1083
+ {
1084
+ "data-slot": "table-cell",
1085
+ className: cn(
1086
+ "p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
1087
+ className
1088
+ ),
1089
+ ...props
1090
+ }
1091
+ );
1092
+ }
1093
+ function TableView() {
1094
+ const { table } = useDataTable();
1095
+ return /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-md border", children: /* @__PURE__ */ jsxs(Table, { children: [
1096
+ /* @__PURE__ */ jsx(TableHeader, { children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx(TableRow, { children: headerGroup.headers.map((header) => {
1097
+ const canSort = header.column.getCanSort();
1098
+ const sortState = header.column.getIsSorted();
1099
+ return /* @__PURE__ */ jsx(TableHead, { children: header.isPlaceholder ? null : /* @__PURE__ */ jsxs(
1100
+ "button",
1101
+ {
1102
+ className: "flex items-center gap-2",
1103
+ onClick: () => canSort && header.column.toggleSorting(),
1104
+ children: [
1105
+ flexRender(header.column.columnDef.header, header.getContext()),
1106
+ canSort && /* @__PURE__ */ jsx("span", { className: "ml-2", children: sortState === "asc" ? /* @__PURE__ */ jsx(ArrowUp, { className: "h-3 w-3" }) : sortState === "desc" ? /* @__PURE__ */ jsx(ArrowDown, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx(ArrowUpDown, { className: "h-3 w-3 opacity-50" }) })
1107
+ ]
1108
+ }
1109
+ ) }, header.id);
1110
+ }) }, headerGroup.id)) }),
1111
+ /* @__PURE__ */ jsx(TableBody, { children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ jsx(TableRow, { "data-state": row.getIsSelected() && "selected", children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx(TableCell, { children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id)) }, row.id)) : /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan: table.getAllColumns().length, className: "h-24 text-center", children: "No results." }) }) })
1112
+ ] }) });
1113
+ }
1114
+ var table_view_default = TableView;
1115
+ function GridView({ renderCard, columns = 3, gap = 16 }) {
1116
+ const { table } = useDataTable();
1117
+ const rows = table.getRowModel().rows;
1118
+ if (!rows.length) {
1119
+ return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-64 text-muted-foreground", children: "No results." });
1120
+ }
1121
+ return /* @__PURE__ */ jsx(
1122
+ "div",
1123
+ {
1124
+ className: "grid",
1125
+ style: {
1126
+ gridTemplateColumns: `repeat(${columns}, 1fr)`,
1127
+ gap: `${gap}px`
1128
+ },
1129
+ children: rows.map((row, index) => {
1130
+ const item = row.original;
1131
+ return /* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-card p-4 shadow-sm", children: renderCard ? renderCard(item, index) : /* @__PURE__ */ jsx(DefaultCard, { item }) }, row.id);
1132
+ })
1133
+ }
1134
+ );
1135
+ }
1136
+ function DefaultCard({ item }) {
1137
+ return /* @__PURE__ */ jsx("div", { className: "space-y-2", children: Object.entries(item).map(([key, value]) => /* @__PURE__ */ jsxs("div", { children: [
1138
+ /* @__PURE__ */ jsxs("span", { className: "text-sm font-medium", children: [
1139
+ key,
1140
+ ": "
1141
+ ] }),
1142
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: String(value) })
1143
+ ] }, key)) });
1144
+ }
1145
+ var grid_view_default = GridView;
1146
+ function Content3({ renderCard, gridColumns, gridGap }) {
1147
+ const { viewMode } = useDataTable();
1148
+ if (viewMode === "grid") {
1149
+ return /* @__PURE__ */ jsx(grid_view_default, { renderCard, columns: gridColumns, gap: gridGap });
1150
+ }
1151
+ return /* @__PURE__ */ jsx(table_view_default, {});
1152
+ }
1153
+ var content_default = Content3;
1154
+ function Pagination() {
1155
+ const { table } = useDataTable();
1156
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between py-4", children: [
1157
+ /* @__PURE__ */ jsxs("div", { className: "text-sm text-muted-foreground", children: [
1158
+ "Showing",
1159
+ " ",
1160
+ table.getState().pagination.pageIndex * table.getState().pagination.pageSize + 1,
1161
+ " -",
1162
+ " ",
1163
+ Math.min(
1164
+ (table.getState().pagination.pageIndex + 1) * table.getState().pagination.pageSize,
1165
+ table.getFilteredRowModel().rows.length
1166
+ ),
1167
+ " ",
1168
+ "of ",
1169
+ table.getFilteredRowModel().rows.length
1170
+ ] }),
1171
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1172
+ /* @__PURE__ */ jsx(
1173
+ Button6,
1174
+ {
1175
+ variant: "outline",
1176
+ size: "sm",
1177
+ onClick: () => table.previousPage(),
1178
+ disabled: !table.getCanPreviousPage(),
1179
+ children: "Prev"
1180
+ }
1181
+ ),
1182
+ /* @__PURE__ */ jsxs("div", { className: "px-3 text-sm", children: [
1183
+ "Page ",
1184
+ table.getState().pagination.pageIndex + 1,
1185
+ " of ",
1186
+ table.getPageCount()
1187
+ ] }),
1188
+ /* @__PURE__ */ jsx(
1189
+ Button6,
1190
+ {
1191
+ variant: "outline",
1192
+ size: "sm",
1193
+ onClick: () => table.nextPage(),
1194
+ disabled: !table.getCanNextPage(),
1195
+ children: "Next"
1196
+ }
1197
+ )
1198
+ ] })
1199
+ ] });
1200
+ }
1201
+ var pagination_default = Pagination;
1202
+
1203
+ // src/components/data-table/index.tsx
1204
+ var DataTable = Object.assign(root_default2, {
1205
+ Toolbar: toolbar_default,
1206
+ Content: content_default,
1207
+ TableView: table_view_default,
1208
+ GridView: grid_view_default,
1209
+ Pagination: pagination_default
1210
+ });
1211
+ var data_table_default = DataTable;
1212
+
1213
+ export { data_table_default as DataTable, form_default as Form, cn };
1214
+ //# sourceMappingURL=index.mjs.map
1215
+ //# sourceMappingURL=index.mjs.map