@saptanshuwanjari/react-component-library 0.1.10 → 0.1.11

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 CHANGED
@@ -1,120 +1,76 @@
1
- import * as React2 from 'react';
2
- import { createContext, memo, useState, useContext, useTransition, useEffect, useMemo } from 'react';
3
- import { zodResolver } from '@hookform/resolvers/zod';
4
- import { Controller, useForm } from 'react-hook-form';
5
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
- import * as LabelPrimitive from '@radix-ui/react-label';
7
1
  import { clsx } from 'clsx';
8
2
  import { twMerge } from 'tailwind-merge';
9
- import { Lock, EyeOff, Eye, CalendarIcon, Upload, ChevronDownIcon, CheckIcon, ChevronLeftIcon, ChevronRightIcon, X, Pencil, Table as Table$1, LayoutGrid, ArrowUp, ArrowDown, ArrowUpDown, SlidersHorizontal, ChevronUpIcon } from 'lucide-react';
10
- import { cva } from 'class-variance-authority';
11
- import * as SelectPrimitive from '@radix-ui/react-select';
12
- import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
13
- import * as PopoverPrimitive from '@radix-ui/react-popover';
14
- import { getDefaultClassNames, DayPicker } from 'react-day-picker';
15
- import { format } from 'date-fns';
16
- import * as AvatarPrimitive from '@radix-ui/react-avatar';
17
3
  import { useReactTable, getPaginationRowModel, getSortedRowModel, getFilteredRowModel, getCoreRowModel, flexRender } from '@tanstack/react-table';
4
+ import * as React2 from 'react';
5
+ import { createContext, useContext, useState } from 'react';
6
+ import { jsx, jsxs } from 'react/jsx-runtime';
7
+ import * as SelectPrimitive from '@radix-ui/react-select';
8
+ import { Filter, ArrowUp, ArrowDown, ArrowUpDown, TableIcon, LayoutGrid, ChevronDownIcon, CheckIcon, ChevronUpIcon } from 'lucide-react';
9
+ import { cva } from 'class-variance-authority';
18
10
 
19
- // src/components/form/root.tsx
20
- var FormContext = createContext(null);
21
- var DEFAULT_FORM_KEY = "__default_form__";
22
- var formRegistry = /* @__PURE__ */ new Map();
23
- function Root({
24
- schema,
25
- defaultValues,
26
- onSubmit,
27
- children,
28
- enableOptimistic = false,
29
- title,
30
- description,
31
- enableEditMode = false,
32
- formId
33
- }) {
34
- const resolver = schema ? zodResolver(schema) : void 0;
35
- const [isPending, startTransition] = useTransition();
36
- const [isEditing, setIsEditing] = useState(!enableEditMode);
37
- const methods = useForm({
38
- resolver,
39
- defaultValues
40
- });
41
- const handleFormSubmit = methods.handleSubmit((data) => {
42
- if (enableOptimistic) {
43
- startTransition(() => {
44
- void onSubmit(data);
45
- });
46
- return;
47
- }
48
- return onSubmit(data);
49
- });
50
- useEffect(() => {
51
- const key = formId ?? DEFAULT_FORM_KEY;
52
- formRegistry.set(key, setIsEditing);
53
- return () => {
54
- formRegistry.delete(key);
55
- };
56
- }, [formId, setIsEditing]);
57
- return /* @__PURE__ */ jsx(FormContext.Provider, { value: { ...methods, schema, isPending, isEditing, setIsEditing }, children: /* @__PURE__ */ jsxs(
58
- "form",
59
- {
60
- onSubmit: handleFormSubmit,
61
- className: "bg-card text-card-foreground rounded-xl border shadow-sm p-6 space-y-6",
62
- children: [
63
- (title || description) && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
64
- title && /* @__PURE__ */ jsx("h2", { className: "text-2xl font-semibold tracking-tight", children: title }),
65
- description && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: description })
66
- ] }),
67
- children
68
- ]
69
- }
70
- ) });
71
- }
72
- var root_default = Root;
73
- function useFormCtx() {
74
- const ctx = useContext(FormContext);
75
- if (!ctx) throw new Error("Form components must be used inside Form.Root");
76
- return ctx;
77
- }
11
+ // src/lib/utils.ts
78
12
  function cn(...inputs) {
79
13
  return twMerge(clsx(inputs));
80
14
  }
81
- function Label({
82
- className,
83
- ...props
15
+ var DataTableContext = createContext(null);
16
+ function useDataTableContext() {
17
+ const context = useContext(DataTableContext);
18
+ if (!context) {
19
+ throw new Error("useDataTableContext must be used within a DataTableRoot");
20
+ }
21
+ return context;
22
+ }
23
+ function useViewMode(defaultMode = "table") {
24
+ const [viewMode, setViewMode] = useState(defaultMode);
25
+ return { viewMode, setViewMode };
26
+ }
27
+ function Root({
28
+ columns,
29
+ data,
30
+ filters = [],
31
+ defaultViewMode = "table",
32
+ showFilters = true,
33
+ children
84
34
  }) {
35
+ const [globalFilter, setGlobalFilter] = useState("");
36
+ const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 });
37
+ const [sorting, setSorting] = useState([]);
38
+ const [columnFilters, setColumnFilters] = useState([]);
39
+ const [viewMode, setViewMode] = useState(defaultViewMode);
40
+ const table = useReactTable({
41
+ data,
42
+ columns,
43
+ state: {
44
+ globalFilter,
45
+ pagination,
46
+ sorting,
47
+ columnFilters
48
+ },
49
+ onGlobalFilterChange: setGlobalFilter,
50
+ onPaginationChange: setPagination,
51
+ onSortingChange: setSorting,
52
+ onColumnFiltersChange: setColumnFilters,
53
+ getCoreRowModel: getCoreRowModel(),
54
+ getFilteredRowModel: getFilteredRowModel(),
55
+ getSortedRowModel: getSortedRowModel(),
56
+ getPaginationRowModel: getPaginationRowModel()
57
+ });
85
58
  return /* @__PURE__ */ jsx(
86
- LabelPrimitive.Root,
59
+ DataTableContext.Provider,
87
60
  {
88
- "data-slot": "label",
89
- className: cn(
90
- "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
91
- className
92
- ),
93
- ...props
61
+ value: {
62
+ table,
63
+ viewMode,
64
+ setViewMode,
65
+ filters,
66
+ showFilters,
67
+ globalFilter,
68
+ setGlobalFilter
69
+ },
70
+ children: /* @__PURE__ */ jsx("div", { className: "space-y-4", children })
94
71
  }
95
72
  );
96
73
  }
97
- function Field({
98
- name,
99
- label,
100
- children
101
- }) {
102
- const form = useFormCtx();
103
- const error = form.formState.errors[name];
104
- return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
105
- label ? /* @__PURE__ */ jsx(Label, { htmlFor: String(name), children: label }) : null,
106
- /* @__PURE__ */ jsx(
107
- Controller,
108
- {
109
- control: form.control,
110
- name,
111
- render: ({ field }) => /* @__PURE__ */ jsx(Fragment, { children: children(field) })
112
- }
113
- ),
114
- error?.message && /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-destructive", children: error.message })
115
- ] });
116
- }
117
- var field_default = Field;
118
74
  function Input({ className, type, ...props }) {
119
75
  return /* @__PURE__ */ jsx(
120
76
  "input",
@@ -131,258 +87,6 @@ function Input({ className, type, ...props }) {
131
87
  }
132
88
  );
133
89
  }
134
- var InputField = memo(function InputField2({
135
- name,
136
- label,
137
- placeholder,
138
- type = "text",
139
- icon,
140
- iconAlign = "inline-start",
141
- startAddon,
142
- endAddon,
143
- useGroup
144
- }) {
145
- const { isEditing } = useFormCtx();
146
- return /* @__PURE__ */ jsx(field_default, { name, label, children: (field) => /* @__PURE__ */ jsx(
147
- Input,
148
- {
149
- id: String(name),
150
- type,
151
- ...field,
152
- value: field.value ?? "",
153
- placeholder,
154
- disabled: !isEditing
155
- }
156
- ) });
157
- });
158
- var input_field_default = InputField;
159
- function setRef(ref, value) {
160
- if (typeof ref === "function") {
161
- return ref(value);
162
- } else if (ref !== null && ref !== void 0) {
163
- ref.current = value;
164
- }
165
- }
166
- function composeRefs(...refs) {
167
- return (node) => {
168
- let hasCleanup = false;
169
- const cleanups = refs.map((ref) => {
170
- const cleanup = setRef(ref, node);
171
- if (!hasCleanup && typeof cleanup == "function") {
172
- hasCleanup = true;
173
- }
174
- return cleanup;
175
- });
176
- if (hasCleanup) {
177
- return () => {
178
- for (let i = 0; i < cleanups.length; i++) {
179
- const cleanup = cleanups[i];
180
- if (typeof cleanup == "function") {
181
- cleanup();
182
- } else {
183
- setRef(refs[i], null);
184
- }
185
- }
186
- };
187
- }
188
- };
189
- }
190
- // @__NO_SIDE_EFFECTS__
191
- function createSlot(ownerName) {
192
- const SlotClone = /* @__PURE__ */ createSlotClone(ownerName);
193
- const Slot2 = React2.forwardRef((props, forwardedRef) => {
194
- const { children, ...slotProps } = props;
195
- const childrenArray = React2.Children.toArray(children);
196
- const slottable = childrenArray.find(isSlottable);
197
- if (slottable) {
198
- const newElement = slottable.props.children;
199
- const newChildren = childrenArray.map((child) => {
200
- if (child === slottable) {
201
- if (React2.Children.count(newElement) > 1) return React2.Children.only(null);
202
- return React2.isValidElement(newElement) ? newElement.props.children : null;
203
- } else {
204
- return child;
205
- }
206
- });
207
- return /* @__PURE__ */ jsx(SlotClone, { ...slotProps, ref: forwardedRef, children: React2.isValidElement(newElement) ? React2.cloneElement(newElement, void 0, newChildren) : null });
208
- }
209
- return /* @__PURE__ */ jsx(SlotClone, { ...slotProps, ref: forwardedRef, children });
210
- });
211
- Slot2.displayName = `${ownerName}.Slot`;
212
- return Slot2;
213
- }
214
- var Slot = /* @__PURE__ */ createSlot("Slot");
215
- // @__NO_SIDE_EFFECTS__
216
- function createSlotClone(ownerName) {
217
- const SlotClone = React2.forwardRef((props, forwardedRef) => {
218
- const { children, ...slotProps } = props;
219
- if (React2.isValidElement(children)) {
220
- const childrenRef = getElementRef(children);
221
- const props2 = mergeProps(slotProps, children.props);
222
- if (children.type !== React2.Fragment) {
223
- props2.ref = forwardedRef ? composeRefs(forwardedRef, childrenRef) : childrenRef;
224
- }
225
- return React2.cloneElement(children, props2);
226
- }
227
- return React2.Children.count(children) > 1 ? React2.Children.only(null) : null;
228
- });
229
- SlotClone.displayName = `${ownerName}.SlotClone`;
230
- return SlotClone;
231
- }
232
- var SLOTTABLE_IDENTIFIER = /* @__PURE__ */ Symbol("radix.slottable");
233
- function isSlottable(child) {
234
- return React2.isValidElement(child) && typeof child.type === "function" && "__radixId" in child.type && child.type.__radixId === SLOTTABLE_IDENTIFIER;
235
- }
236
- function mergeProps(slotProps, childProps) {
237
- const overrideProps = { ...childProps };
238
- for (const propName in childProps) {
239
- const slotPropValue = slotProps[propName];
240
- const childPropValue = childProps[propName];
241
- const isHandler = /^on[A-Z]/.test(propName);
242
- if (isHandler) {
243
- if (slotPropValue && childPropValue) {
244
- overrideProps[propName] = (...args) => {
245
- const result = childPropValue(...args);
246
- slotPropValue(...args);
247
- return result;
248
- };
249
- } else if (slotPropValue) {
250
- overrideProps[propName] = slotPropValue;
251
- }
252
- } else if (propName === "style") {
253
- overrideProps[propName] = { ...slotPropValue, ...childPropValue };
254
- } else if (propName === "className") {
255
- overrideProps[propName] = [slotPropValue, childPropValue].filter(Boolean).join(" ");
256
- }
257
- }
258
- return { ...slotProps, ...overrideProps };
259
- }
260
- function getElementRef(element) {
261
- let getter = Object.getOwnPropertyDescriptor(element.props, "ref")?.get;
262
- let mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
263
- if (mayWarn) {
264
- return element.ref;
265
- }
266
- getter = Object.getOwnPropertyDescriptor(element, "ref")?.get;
267
- mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
268
- if (mayWarn) {
269
- return element.props.ref;
270
- }
271
- return element.props.ref || element.ref;
272
- }
273
- var buttonVariants = cva(
274
- "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",
275
- {
276
- variants: {
277
- variant: {
278
- default: "bg-primary text-primary-foreground hover:bg-primary/90",
279
- destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
280
- 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",
281
- secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
282
- ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
283
- link: "text-primary underline-offset-4 hover:underline"
284
- },
285
- size: {
286
- default: "h-9 px-4 py-2 has-[>svg]:px-3",
287
- sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
288
- lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
289
- icon: "size-9",
290
- "icon-sm": "size-8",
291
- "icon-lg": "size-10"
292
- }
293
- },
294
- defaultVariants: {
295
- variant: "default",
296
- size: "default"
297
- }
298
- }
299
- );
300
- function Button({
301
- className,
302
- variant = "default",
303
- size = "default",
304
- asChild = false,
305
- ...props
306
- }) {
307
- const Comp = asChild ? Slot : "button";
308
- return /* @__PURE__ */ jsx(
309
- Comp,
310
- {
311
- "data-slot": "button",
312
- "data-variant": variant,
313
- "data-size": size,
314
- className: cn(buttonVariants({ variant, size, className })),
315
- ...props
316
- }
317
- );
318
- }
319
- var PasswordField = memo(function PasswordField2({
320
- name,
321
- label,
322
- placeholder
323
- }) {
324
- const [show, setShow] = useState(false);
325
- return /* @__PURE__ */ jsx(field_default, { name, label, children: (field) => /* @__PURE__ */ jsxs("div", { className: "relative", children: [
326
- /* @__PURE__ */ jsx("div", { className: "absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none z-10", children: /* @__PURE__ */ jsx(Lock, { className: "h-4 w-4 text-muted-foreground" }) }),
327
- /* @__PURE__ */ jsx(
328
- Input,
329
- {
330
- id: String(name),
331
- type: show ? "text" : "password",
332
- ...field,
333
- value: field.value ?? "",
334
- placeholder,
335
- className: "pl-10 pr-10"
336
- }
337
- ),
338
- /* @__PURE__ */ jsx(
339
- Button,
340
- {
341
- variant: "ghost",
342
- size: "sm",
343
- type: "button",
344
- onClick: () => setShow(!show),
345
- className: "absolute right-1 top-1/2 -translate-y-1/2 h-8 w-8 p-0 text-muted-foreground hover:text-foreground",
346
- children: show ? /* @__PURE__ */ jsx(EyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(Eye, { className: "h-4 w-4" })
347
- }
348
- )
349
- ] }) });
350
- });
351
- var password_field_default = PasswordField;
352
- function Textarea({ className, ...props }) {
353
- return /* @__PURE__ */ jsx(
354
- "textarea",
355
- {
356
- "data-slot": "textarea",
357
- className: cn(
358
- "border-input placeholder: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 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
359
- className
360
- ),
361
- ...props
362
- }
363
- );
364
- }
365
- var TextareaField = memo(function TextareaField2({
366
- name,
367
- label,
368
- placeholder,
369
- rows = 4
370
- }) {
371
- const { isEditing } = useFormCtx();
372
- return /* @__PURE__ */ jsx(field_default, { name, label, children: (field) => /* @__PURE__ */ jsx(
373
- Textarea,
374
- {
375
- id: String(name),
376
- ...field,
377
- value: field.value ?? "",
378
- placeholder,
379
- rows,
380
- disabled: !isEditing,
381
- className: !isEditing ? "bg-background/50 opacity-80" : ""
382
- }
383
- ) });
384
- });
385
- var textarea_field_default = TextareaField;
386
90
  function Select({
387
91
  ...props
388
92
  }) {
@@ -493,888 +197,89 @@ function SelectScrollUpButton({
493
197
  className
494
198
  ),
495
199
  ...props,
496
- children: /* @__PURE__ */ jsx(ChevronUpIcon, { className: "size-4" })
497
- }
498
- );
499
- }
500
- function SelectScrollDownButton({
501
- className,
502
- ...props
503
- }) {
504
- return /* @__PURE__ */ jsx(
505
- SelectPrimitive.ScrollDownButton,
506
- {
507
- "data-slot": "select-scroll-down-button",
508
- className: cn(
509
- "flex cursor-default items-center justify-center py-1",
510
- className
511
- ),
512
- ...props,
513
- children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4" })
514
- }
515
- );
516
- }
517
- var SelectField = memo(function SelectField2({
518
- name,
519
- label,
520
- placeholder = "Select an option",
521
- options
522
- }) {
523
- const { isEditing } = useFormCtx();
524
- return /* @__PURE__ */ jsx(field_default, { name, label, children: (field) => !isEditing ? /* @__PURE__ */ jsx(
525
- Input,
526
- {
527
- id: String(name),
528
- value: options.find((opt) => opt.value === field.value)?.label ?? "",
529
- placeholder,
530
- readOnly: true,
531
- disabled: true,
532
- className: "bg-background/50 opacity-80"
533
- }
534
- ) : /* @__PURE__ */ jsxs(Select, { onValueChange: field.onChange, value: field.value ?? "", children: [
535
- /* @__PURE__ */ jsx(SelectTrigger, { className: "w-full", children: /* @__PURE__ */ jsx(SelectValue, { placeholder }) }),
536
- /* @__PURE__ */ jsx(SelectContent, { children: options.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
537
- ] }) });
538
- });
539
- var select_field_default = SelectField;
540
- function Checkbox({
541
- className,
542
- ...props
543
- }) {
544
- return /* @__PURE__ */ jsx(
545
- CheckboxPrimitive.Root,
546
- {
547
- "data-slot": "checkbox",
548
- className: cn(
549
- "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",
550
- className
551
- ),
552
- ...props,
553
- children: /* @__PURE__ */ jsx(
554
- CheckboxPrimitive.Indicator,
555
- {
556
- "data-slot": "checkbox-indicator",
557
- className: "grid place-content-center text-current transition-none",
558
- children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-3.5" })
559
- }
560
- )
561
- }
562
- );
563
- }
564
- var CheckboxField = memo(function CheckboxField2({
565
- name,
566
- label,
567
- description
568
- }) {
569
- const form = useFormCtx();
570
- return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
571
- /* @__PURE__ */ jsx(
572
- Controller,
573
- {
574
- control: form.control,
575
- name,
576
- render: ({ field }) => /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
577
- /* @__PURE__ */ jsx(
578
- Checkbox,
579
- {
580
- id: String(name),
581
- checked: !!field.value,
582
- onCheckedChange: form.isEditing ? field.onChange : void 0,
583
- disabled: !form.isEditing
584
- }
585
- ),
586
- /* @__PURE__ */ jsxs("div", { className: "grid gap-1.5 leading-none", children: [
587
- label && /* @__PURE__ */ jsx(
588
- Label,
589
- {
590
- htmlFor: String(name),
591
- className: "cursor-pointer",
592
- children: label
593
- }
594
- ),
595
- description && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: description })
596
- ] })
597
- ] })
598
- }
599
- ),
600
- form.formState.errors[name]?.message && /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-destructive", children: form.formState.errors[name]?.message })
601
- ] });
602
- });
603
- var checkbox_field_default = CheckboxField;
604
- function Popover({
605
- ...props
606
- }) {
607
- return /* @__PURE__ */ jsx(PopoverPrimitive.Root, { "data-slot": "popover", ...props });
608
- }
609
- function PopoverTrigger({
610
- ...props
611
- }) {
612
- return /* @__PURE__ */ jsx(PopoverPrimitive.Trigger, { "data-slot": "popover-trigger", ...props });
613
- }
614
- function PopoverContent({
615
- className,
616
- align = "center",
617
- sideOffset = 4,
618
- ...props
619
- }) {
620
- return /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
621
- PopoverPrimitive.Content,
622
- {
623
- "data-slot": "popover-content",
624
- align,
625
- sideOffset,
626
- className: cn(
627
- "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",
628
- className
629
- ),
630
- ...props
631
- }
632
- ) });
633
- }
634
- function Calendar({
635
- className,
636
- classNames,
637
- showOutsideDays = true,
638
- captionLayout = "label",
639
- buttonVariant = "ghost",
640
- formatters,
641
- components,
642
- ...props
643
- }) {
644
- const defaultClassNames = getDefaultClassNames();
645
- return /* @__PURE__ */ jsx(
646
- DayPicker,
647
- {
648
- showOutsideDays,
649
- className: cn(
650
- "bg-background group/calendar p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
651
- String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
652
- String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
653
- className
654
- ),
655
- captionLayout,
656
- formatters: {
657
- formatMonthDropdown: (date) => date.toLocaleString("default", { month: "short" }),
658
- ...formatters
659
- },
660
- classNames: {
661
- root: cn("w-fit", defaultClassNames.root),
662
- months: cn(
663
- "flex gap-4 flex-col md:flex-row relative",
664
- defaultClassNames.months
665
- ),
666
- month: cn("flex flex-col w-full gap-4", defaultClassNames.month),
667
- nav: cn(
668
- "flex items-center gap-1 w-full absolute top-0 inset-x-0 justify-between",
669
- defaultClassNames.nav
670
- ),
671
- button_previous: cn(
672
- buttonVariants({ variant: buttonVariant }),
673
- "size-(--cell-size) aria-disabled:opacity-50 p-0 select-none",
674
- defaultClassNames.button_previous
675
- ),
676
- button_next: cn(
677
- buttonVariants({ variant: buttonVariant }),
678
- "size-(--cell-size) aria-disabled:opacity-50 p-0 select-none",
679
- defaultClassNames.button_next
680
- ),
681
- month_caption: cn(
682
- "flex items-center justify-center h-(--cell-size) w-full px-(--cell-size)",
683
- defaultClassNames.month_caption
684
- ),
685
- dropdowns: cn(
686
- "w-full flex items-center text-sm font-medium justify-center h-(--cell-size) gap-1.5",
687
- defaultClassNames.dropdowns
688
- ),
689
- dropdown_root: cn(
690
- "relative has-focus:border-ring border border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] rounded-md",
691
- defaultClassNames.dropdown_root
692
- ),
693
- dropdown: cn(
694
- "absolute bg-popover inset-0 opacity-0",
695
- defaultClassNames.dropdown
696
- ),
697
- caption_label: cn(
698
- "select-none font-medium",
699
- captionLayout === "label" ? "text-sm" : "rounded-md pl-2 pr-1 flex items-center gap-1 text-sm h-8 [&>svg]:text-muted-foreground [&>svg]:size-3.5",
700
- defaultClassNames.caption_label
701
- ),
702
- table: "w-full border-collapse",
703
- weekdays: cn("flex", defaultClassNames.weekdays),
704
- weekday: cn(
705
- "text-muted-foreground rounded-md flex-1 font-normal text-[0.8rem] select-none",
706
- defaultClassNames.weekday
707
- ),
708
- week: cn("flex w-full mt-2", defaultClassNames.week),
709
- week_number_header: cn(
710
- "select-none w-(--cell-size)",
711
- defaultClassNames.week_number_header
712
- ),
713
- week_number: cn(
714
- "text-[0.8rem] select-none text-muted-foreground",
715
- defaultClassNames.week_number
716
- ),
717
- day: cn(
718
- "relative w-full h-full p-0 text-center [&:last-child[data-selected=true]_button]:rounded-r-md group/day aspect-square select-none",
719
- props.showWeekNumber ? "[&:nth-child(2)[data-selected=true]_button]:rounded-l-md" : "[&:first-child[data-selected=true]_button]:rounded-l-md",
720
- defaultClassNames.day
721
- ),
722
- range_start: cn(
723
- "rounded-l-md bg-accent",
724
- defaultClassNames.range_start
725
- ),
726
- range_middle: cn("rounded-none", defaultClassNames.range_middle),
727
- range_end: cn("rounded-r-md bg-accent", defaultClassNames.range_end),
728
- today: cn(
729
- "bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none",
730
- defaultClassNames.today
731
- ),
732
- outside: cn(
733
- "text-muted-foreground aria-selected:text-muted-foreground",
734
- defaultClassNames.outside
735
- ),
736
- disabled: cn(
737
- "text-muted-foreground opacity-50",
738
- defaultClassNames.disabled
739
- ),
740
- hidden: cn("invisible", defaultClassNames.hidden),
741
- ...classNames
742
- },
743
- components: {
744
- Root: ({ className: className2, rootRef, ...props2 }) => {
745
- return /* @__PURE__ */ jsx(
746
- "div",
747
- {
748
- "data-slot": "calendar",
749
- ref: rootRef,
750
- className: cn(className2),
751
- ...props2
752
- }
753
- );
754
- },
755
- Chevron: ({ className: className2, orientation, ...props2 }) => {
756
- if (orientation === "left") {
757
- return /* @__PURE__ */ jsx(ChevronLeftIcon, { className: cn("size-4", className2), ...props2 });
758
- }
759
- if (orientation === "right") {
760
- return /* @__PURE__ */ jsx(
761
- ChevronRightIcon,
762
- {
763
- className: cn("size-4", className2),
764
- ...props2
765
- }
766
- );
767
- }
768
- return /* @__PURE__ */ jsx(ChevronDownIcon, { className: cn("size-4", className2), ...props2 });
769
- },
770
- DayButton: CalendarDayButton,
771
- WeekNumber: ({ children, ...props2 }) => {
772
- return /* @__PURE__ */ jsx("td", { ...props2, children: /* @__PURE__ */ jsx("div", { className: "flex size-(--cell-size) items-center justify-center text-center", children }) });
773
- },
774
- ...components
775
- },
776
- ...props
777
- }
778
- );
779
- }
780
- function CalendarDayButton({
781
- className,
782
- day,
783
- modifiers,
784
- ...props
785
- }) {
786
- const defaultClassNames = getDefaultClassNames();
787
- const ref = React2.useRef(null);
788
- React2.useEffect(() => {
789
- if (modifiers.focused) ref.current?.focus();
790
- }, [modifiers.focused]);
791
- return /* @__PURE__ */ jsx(
792
- Button,
793
- {
794
- ref,
795
- variant: "ghost",
796
- size: "icon",
797
- "data-day": day.date.toLocaleDateString(),
798
- "data-selected-single": modifiers.selected && !modifiers.range_start && !modifiers.range_end && !modifiers.range_middle,
799
- "data-range-start": modifiers.range_start,
800
- "data-range-end": modifiers.range_end,
801
- "data-range-middle": modifiers.range_middle,
802
- className: cn(
803
- "data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 dark:hover:text-accent-foreground flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md [&>span]:text-xs [&>span]:opacity-70",
804
- defaultClassNames.day,
805
- className
806
- ),
807
- ...props
808
- }
809
- );
810
- }
811
- var DateField = memo(function DateField2({
812
- name,
813
- label,
814
- placeholder = "Pick a date"
815
- }) {
816
- const { isEditing } = useFormCtx();
817
- return /* @__PURE__ */ jsx(field_default, { name, label, children: (field) => !isEditing ? /* @__PURE__ */ jsxs(
818
- Button,
819
- {
820
- type: "button",
821
- variant: "outline",
822
- className: cn(
823
- "w-full justify-start text-left font-normal bg-background/50",
824
- !field.value && "text-muted-foreground"
825
- ),
826
- disabled: true,
827
- children: [
828
- /* @__PURE__ */ jsx(CalendarIcon, { className: "mr-2 h-4 w-4" }),
829
- field.value ? format(new Date(field.value), "PPP") : /* @__PURE__ */ jsx("span", { children: placeholder })
830
- ]
831
- }
832
- ) : /* @__PURE__ */ jsxs(Popover, { children: [
833
- /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
834
- Button,
835
- {
836
- variant: "outline",
837
- className: cn(
838
- "w-full justify-start text-left font-normal",
839
- !field.value && "text-muted-foreground"
840
- ),
841
- children: [
842
- /* @__PURE__ */ jsx(CalendarIcon, { className: "mr-2 h-4 w-4" }),
843
- field.value ? format(new Date(field.value), "PPP") : /* @__PURE__ */ jsx("span", { children: placeholder })
844
- ]
845
- }
846
- ) }),
847
- /* @__PURE__ */ jsx(PopoverContent, { className: "w-auto p-0", align: "start", children: /* @__PURE__ */ jsx(
848
- Calendar,
849
- {
850
- mode: "single",
851
- selected: field.value ? new Date(field.value) : void 0,
852
- onSelect: field.onChange,
853
- initialFocus: true
854
- }
855
- ) })
856
- ] }) });
857
- });
858
- var date_field_default = DateField;
859
- var FileField = memo(function FileField2({
860
- name,
861
- label,
862
- accept,
863
- multiple
864
- }) {
865
- const { isEditing } = useFormCtx();
866
- return /* @__PURE__ */ jsx(field_default, { name, label, children: (field) => {
867
- const files = field.value;
868
- const filename = files && files.length ? multiple ? `${files.length} files` : files[0].name : "";
869
- if (!isEditing) {
870
- return /* @__PURE__ */ jsxs("div", { className: "relative flex items-center", children: [
871
- /* @__PURE__ */ jsx(Upload, { className: "absolute left-3 text-muted-foreground h-4 w-4 z-10" }),
872
- /* @__PURE__ */ jsx(
873
- Input,
874
- {
875
- id: `${String(name)}_display`,
876
- type: "text",
877
- value: filename,
878
- placeholder: accept ? `Accepts ${accept}` : "No file selected",
879
- readOnly: true,
880
- disabled: true,
881
- className: "bg-background/50 opacity-80 pl-10"
882
- }
883
- )
884
- ] });
885
- }
886
- return /* @__PURE__ */ jsxs("div", { className: "relative flex items-center", children: [
887
- /* @__PURE__ */ jsx(Upload, { className: "absolute left-3 text-muted-foreground h-4 w-4 z-10 pointer-events-none" }),
888
- /* @__PURE__ */ jsx(
889
- Input,
890
- {
891
- id: String(name),
892
- type: "file",
893
- accept,
894
- multiple,
895
- onChange: (e) => field.onChange(e.target.files),
896
- onBlur: field.onBlur,
897
- name: field.name,
898
- ref: field.ref,
899
- className: "pl-10"
900
- }
901
- )
902
- ] });
903
- } });
904
- });
905
- var file_field_default = FileField;
906
- function Avatar({
907
- className,
908
- ...props
909
- }) {
910
- return /* @__PURE__ */ jsx(
911
- AvatarPrimitive.Root,
912
- {
913
- "data-slot": "avatar",
914
- className: cn(
915
- "relative flex size-8 shrink-0 overflow-hidden rounded-full",
916
- className
917
- ),
918
- ...props
919
- }
920
- );
921
- }
922
- function AvatarImage({
923
- className,
924
- ...props
925
- }) {
926
- return /* @__PURE__ */ jsx(
927
- AvatarPrimitive.Image,
928
- {
929
- "data-slot": "avatar-image",
930
- className: cn("aspect-square size-full", className),
931
- ...props
932
- }
933
- );
934
- }
935
- function AvatarFallback({
936
- className,
937
- ...props
938
- }) {
939
- return /* @__PURE__ */ jsx(
940
- AvatarPrimitive.Fallback,
941
- {
942
- "data-slot": "avatar-fallback",
943
- className: cn(
944
- "bg-muted flex size-full items-center justify-center rounded-full",
945
- className
946
- ),
947
- ...props
948
- }
949
- );
950
- }
951
- var ProfilePictureField = memo(function ProfilePictureField2({
952
- name,
953
- label,
954
- className,
955
- avatarClassName,
956
- fallback = "User"
957
- }) {
958
- const { isEditing } = useFormCtx();
959
- const [preview, setPreview] = useState(null);
960
- return /* @__PURE__ */ jsx(field_default, { name, label, children: (field) => {
961
- const currentValue = field.value;
962
- const displayUrl = preview || (typeof currentValue === "string" ? currentValue : null);
963
- return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col items-center gap-4", className), children: [
964
- /* @__PURE__ */ jsxs(Avatar, { className: cn("h-24 w-24", avatarClassName), children: [
965
- /* @__PURE__ */ jsx(AvatarImage, { src: displayUrl || "", alt: "Profile picture" }),
966
- /* @__PURE__ */ jsx(AvatarFallback, { children: fallback })
967
- ] }),
968
- isEditing && /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2", children: [
969
- /* @__PURE__ */ jsxs(
970
- Label,
971
- {
972
- htmlFor: String(name),
973
- 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",
974
- children: [
975
- /* @__PURE__ */ jsx(Upload, { className: "h-4 w-4" }),
976
- "Upload Picture"
977
- ]
978
- }
979
- ),
980
- /* @__PURE__ */ jsx(
981
- Input,
982
- {
983
- id: String(name),
984
- type: "file",
985
- accept: "image/*",
986
- className: "hidden",
987
- onChange: (e) => {
988
- const file = e.target.files?.[0];
989
- if (file) {
990
- field.onChange(file);
991
- const reader = new FileReader();
992
- reader.onloadend = () => {
993
- setPreview(reader.result);
994
- };
995
- reader.readAsDataURL(file);
996
- }
997
- },
998
- onBlur: field.onBlur,
999
- name: field.name,
1000
- ref: field.ref
1001
- }
1002
- ),
1003
- displayUrl && /* @__PURE__ */ jsx(
1004
- Button,
1005
- {
1006
- variant: "ghost",
1007
- size: "sm",
1008
- type: "button",
1009
- onClick: () => {
1010
- field.onChange(null);
1011
- setPreview(null);
1012
- },
1013
- children: "Remove"
1014
- }
1015
- )
1016
- ] })
1017
- ] });
1018
- } });
1019
- });
1020
- var profile_picture_field_default = ProfilePictureField;
1021
- var Button2 = ({ children, ...props }) => /* @__PURE__ */ jsx(
1022
- "button",
1023
- {
1024
- 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",
1025
- ...props,
1026
- children
1027
- }
1028
- );
1029
- function Submit({ children, ...props }) {
1030
- const form = useFormCtx();
1031
- const isPending = form.isPending || form.formState.isSubmitting;
1032
- const { isEditing } = form;
1033
- if (!isEditing) return null;
1034
- return /* @__PURE__ */ jsx(Button2, { type: "submit", disabled: isPending || props.disabled, ...props, children: isPending ? "Submitting..." : children });
1035
- }
1036
- var submit_default = Submit;
1037
- function EditButton({ children, formId, ...props }) {
1038
- const ctx = useContext(FormContext);
1039
- if (ctx) {
1040
- const { isEditing, setIsEditing } = ctx;
1041
- if (isEditing) return null;
1042
- return /* @__PURE__ */ jsx(Button, { type: "button", onClick: () => setIsEditing?.(true), ...props, children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
1043
- /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4 mr-2" }),
1044
- "Edit Profile"
1045
- ] }) });
1046
- }
1047
- const handleClick = () => {
1048
- const key = formId ?? DEFAULT_FORM_KEY;
1049
- const immediate = formRegistry.get(key);
1050
- if (immediate) return immediate(true);
1051
- let attempts = 0;
1052
- const maxAttempts = 20;
1053
- const interval = setInterval(() => {
1054
- attempts += 1;
1055
- const setter = formRegistry.get(key);
1056
- if (setter) {
1057
- setter(true);
1058
- clearInterval(interval);
1059
- } else if (attempts >= maxAttempts) {
1060
- clearInterval(interval);
1061
- }
1062
- }, 100);
1063
- };
1064
- return /* @__PURE__ */ jsx(Button, { type: "button", onClick: handleClick, ...props, children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
1065
- /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4 mr-2" }),
1066
- "Edit Profile"
1067
- ] }) });
1068
- }
1069
- var edit_button_default = EditButton;
1070
- function CancelButton({ children, ...props }) {
1071
- const { isEditing, setIsEditing, reset } = useFormCtx();
1072
- if (!isEditing) return null;
1073
- return /* @__PURE__ */ jsx(
1074
- Button,
1075
- {
1076
- type: "button",
1077
- variant: "outline",
1078
- onClick: () => {
1079
- reset();
1080
- setIsEditing?.(false);
1081
- },
1082
- ...props,
1083
- children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
1084
- /* @__PURE__ */ jsx(X, { className: "h-4 w-4 mr-2" }),
1085
- "Cancel"
1086
- ] })
1087
- }
1088
- );
1089
- }
1090
- var cancel_button_default = CancelButton;
1091
- function LinkField({ label, link, LinkComponent, className }) {
1092
- const LinkTag = LinkComponent || "a";
1093
- const linkProps = { href: link };
1094
- return /* @__PURE__ */ jsx(
1095
- LinkTag,
1096
- {
1097
- ...linkProps,
1098
- className: cn("text-sm text-primary hover:underline", className),
1099
- children: label
1100
- }
1101
- );
1102
- }
1103
- var link_field_default = LinkField;
1104
- function FieldGroup({ children, className, title }) {
1105
- return /* @__PURE__ */ jsxs("div", { className: cn("space-y-4", className), children: [
1106
- title && /* @__PURE__ */ jsx("h3", { className: "text-lg font-medium", children: title }),
1107
- children
1108
- ] });
1109
- }
1110
- var field_group_default = FieldGroup;
1111
-
1112
- // src/components/form/index.ts
1113
- var Form = Object.assign(root_default, {
1114
- Root: root_default,
1115
- Field: field_default,
1116
- InputField: input_field_default,
1117
- PasswordField: password_field_default,
1118
- TextareaField: textarea_field_default,
1119
- SelectField: select_field_default,
1120
- CheckboxField: checkbox_field_default,
1121
- DateField: date_field_default,
1122
- FileField: file_field_default,
1123
- ProfilePictureField: profile_picture_field_default,
1124
- Submit: submit_default,
1125
- EditButton: edit_button_default,
1126
- CancelButton: cancel_button_default,
1127
- Group: field_group_default,
1128
- LinkField: link_field_default
1129
- });
1130
- var form_default = Form;
1131
- var DataTableContext = createContext(null);
1132
- function useDataTable() {
1133
- const context = useContext(DataTableContext);
1134
- if (!context) {
1135
- throw new Error("DataTable components must be used within DataTable.Root");
1136
- }
1137
- return context;
1138
- }
1139
- function Root7({
1140
- columns,
1141
- data,
1142
- filters = [],
1143
- defaultViewMode = "table",
1144
- viewMode: controlledViewMode,
1145
- onViewModeChange: controlledOnViewModeChange,
1146
- defaultPageSize = 10,
1147
- children
1148
- }) {
1149
- const [internalViewMode, setInternalViewMode] = useState(defaultViewMode);
1150
- const [sorting, setSorting] = useState([]);
1151
- const [columnFilters, setColumnFilters] = useState([]);
1152
- const [columnVisibility, setColumnVisibility] = useState({});
1153
- const [globalFilter, setGlobalFilter] = useState("");
1154
- const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: defaultPageSize });
1155
- const [activeFilters, setActiveFilters] = useState({});
1156
- const isControlled = controlledViewMode !== void 0 && controlledOnViewModeChange !== void 0;
1157
- const viewMode = isControlled ? controlledViewMode : internalViewMode;
1158
- const setViewMode = isControlled ? controlledOnViewModeChange : setInternalViewMode;
1159
- const filteredData = useMemo(() => {
1160
- if (Object.keys(activeFilters).length === 0) return data;
1161
- return data.filter((row) => {
1162
- return Object.entries(activeFilters).every(([filterId, filterValue]) => {
1163
- if (!filterValue || Array.isArray(filterValue) && filterValue.length === 0) {
1164
- return true;
1165
- }
1166
- const rowValue = row[filterId];
1167
- if (Array.isArray(filterValue)) {
1168
- return filterValue.includes(String(rowValue));
1169
- }
1170
- return String(rowValue) === String(filterValue);
1171
- });
1172
- });
1173
- }, [data, activeFilters]);
1174
- const table = useReactTable({
1175
- data: filteredData,
1176
- columns,
1177
- state: {
1178
- sorting,
1179
- columnFilters,
1180
- columnVisibility,
1181
- globalFilter,
1182
- pagination
1183
- },
1184
- onSortingChange: setSorting,
1185
- onColumnFiltersChange: setColumnFilters,
1186
- onColumnVisibilityChange: setColumnVisibility,
1187
- onGlobalFilterChange: setGlobalFilter,
1188
- onPaginationChange: setPagination,
1189
- getCoreRowModel: getCoreRowModel(),
1190
- getFilteredRowModel: getFilteredRowModel(),
1191
- getSortedRowModel: getSortedRowModel(),
1192
- getPaginationRowModel: getPaginationRowModel()
1193
- });
200
+ children: /* @__PURE__ */ jsx(ChevronUpIcon, { className: "size-4" })
201
+ }
202
+ );
203
+ }
204
+ function SelectScrollDownButton({
205
+ className,
206
+ ...props
207
+ }) {
1194
208
  return /* @__PURE__ */ jsx(
1195
- DataTableContext.Provider,
209
+ SelectPrimitive.ScrollDownButton,
1196
210
  {
1197
- value: {
1198
- table,
1199
- viewMode,
1200
- setViewMode,
1201
- filters,
1202
- activeFilters,
1203
- setActiveFilters
1204
- },
1205
- children: /* @__PURE__ */ jsx("div", { className: "space-y-4", children })
211
+ "data-slot": "select-scroll-down-button",
212
+ className: cn(
213
+ "flex cursor-default items-center justify-center py-1",
214
+ className
215
+ ),
216
+ ...props,
217
+ children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4" })
1206
218
  }
1207
219
  );
1208
220
  }
1209
- var root_default2 = Root7;
1210
- function ViewOptions({ viewMode: propViewMode, onViewModeChange: propOnViewModeChange }) {
1211
- let contextStr;
1212
- try {
1213
- contextStr = useDataTable();
1214
- } catch (e) {
1215
- }
1216
- const mode = propViewMode ?? contextStr?.viewMode ?? "table";
1217
- const setMode = propOnViewModeChange ?? contextStr?.setViewMode ?? (() => {
1218
- });
1219
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center border rounded-md bg-background", children: [
1220
- /* @__PURE__ */ jsx(
1221
- Button,
1222
- {
1223
- variant: mode === "table" ? "secondary" : "ghost",
1224
- size: "sm",
1225
- onClick: () => setMode("table"),
1226
- className: "rounded-r-none h-8 px-2 lg:px-3",
1227
- "aria-label": "Switch to table view",
1228
- children: /* @__PURE__ */ jsx(Table$1, { className: "h-4 w-4" })
1229
- }
1230
- ),
1231
- /* @__PURE__ */ jsx(
1232
- Button,
1233
- {
1234
- variant: mode === "grid" ? "secondary" : "ghost",
1235
- size: "sm",
1236
- onClick: () => setMode("grid"),
1237
- className: "rounded-l-none h-8 px-2 lg:px-3",
1238
- "aria-label": "Switch to grid view",
1239
- children: /* @__PURE__ */ jsx(LayoutGrid, { className: "h-4 w-4" })
1240
- }
1241
- )
1242
- ] });
1243
- }
1244
- var view_options_default = ViewOptions;
1245
- function Toolbar({ viewOptions } = {}) {
1246
- const { table, filters, activeFilters, setActiveFilters } = useDataTable();
221
+ function Toolbar() {
222
+ const { filters, showFilters, globalFilter, setGlobalFilter, table } = useDataTableContext();
223
+ const [activeFilters, setActiveFilters] = useState({});
1247
224
  const handleFilterChange = (filterId, value) => {
1248
- setActiveFilters((prev) => ({
1249
- ...prev,
1250
- [filterId]: value === "all" ? "" : value
1251
- }));
1252
- };
1253
- const handleMultiFilterToggle = (filterId, value) => {
1254
- setActiveFilters((prev) => {
1255
- const current = prev[filterId];
1256
- if (!current || !Array.isArray(current)) {
1257
- return { ...prev, [filterId]: [value] };
1258
- }
1259
- const newValues = current.includes(value) ? current.filter((v) => v !== value) : [...current, value];
1260
- return { ...prev, [filterId]: newValues };
1261
- });
225
+ setActiveFilters((prev) => ({ ...prev, [filterId]: value }));
226
+ if (value === "all" || value === "") {
227
+ table.getColumn(filterId)?.setFilterValue(void 0);
228
+ } else {
229
+ table.getColumn(filterId)?.setFilterValue(value);
230
+ }
1262
231
  };
1263
- return /* @__PURE__ */ jsxs("div", { className: "space-y-4 py-4", children: [
1264
- /* @__PURE__ */ jsx("div", { className: "w-full", children: /* @__PURE__ */ jsx(
1265
- Input,
1266
- {
1267
- placeholder: "Search...",
1268
- value: table.getState().globalFilter ?? "",
1269
- onChange: (e) => table.setGlobalFilter(e.target.value),
1270
- className: "w-full max-w-sm"
1271
- }
1272
- ) }),
1273
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4", children: [
1274
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-wrap flex-1", children: [
1275
- filters.map((filter) => /* @__PURE__ */ jsx("div", { children: filter.multiSelect ? /* @__PURE__ */ jsxs(Popover, { children: [
1276
- /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", className: "h-8 border-dashed", children: [
1277
- /* @__PURE__ */ jsx(SlidersHorizontal, { className: "h-4 w-4 mr-2" }),
1278
- filter.label,
1279
- activeFilters[filter.id] && (Array.isArray(activeFilters[filter.id]) ? activeFilters[filter.id].length > 0 : true) && /* @__PURE__ */ jsx("span", { className: "ml-1 rounded-sm bg-primary px-1 text-xs text-primary-foreground", children: Array.isArray(activeFilters[filter.id]) ? activeFilters[filter.id].length : 1 })
1280
- ] }) }),
1281
- /* @__PURE__ */ jsx(PopoverContent, { className: "w-[200px] p-0", align: "start", children: /* @__PURE__ */ jsxs("div", { className: "p-1", children: [
1282
- filter.options.map((option) => /* @__PURE__ */ jsxs(
1283
- "div",
1284
- {
1285
- className: "flex items-center space-x-2 rounded-sm px-2 py-1.5 hover:bg-accent cursor-pointer",
1286
- onClick: () => handleMultiFilterToggle(filter.id, option.value),
1287
- children: [
1288
- /* @__PURE__ */ jsx(
1289
- Checkbox,
1290
- {
1291
- id: `${filter.id}-${option.value}`,
1292
- checked: Array.isArray(activeFilters[filter.id]) && activeFilters[filter.id].includes(option.value)
1293
- }
1294
- ),
1295
- /* @__PURE__ */ jsx(
1296
- "label",
1297
- {
1298
- htmlFor: `${filter.id}-${option.value}`,
1299
- className: "text-sm cursor-pointer flex-1",
1300
- children: option.label
1301
- }
1302
- )
1303
- ]
1304
- },
1305
- option.value
1306
- )),
1307
- activeFilters[filter.id] && (Array.isArray(activeFilters[filter.id]) ? activeFilters[filter.id].length > 0 : false) && /* @__PURE__ */ jsxs(Fragment, { children: [
1308
- /* @__PURE__ */ jsx("div", { className: "h-px bg-border my-1" }),
1309
- /* @__PURE__ */ jsx(
1310
- "div",
1311
- {
1312
- className: "px-2 py-1.5 text-center text-sm cursor-pointer hover:bg-accent rounded-sm",
1313
- onClick: () => setActiveFilters((prev) => ({ ...prev, [filter.id]: [] })),
1314
- children: "Clear filters"
1315
- }
1316
- )
232
+ const hasFilters = filters && filters.length > 0;
233
+ return /* @__PURE__ */ jsxs("div", { className: "mb-4 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2", children: [
234
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-1 flex-wrap", children: [
235
+ /* @__PURE__ */ jsx("div", { className: "max-w-sm w-full sm:w-auto", children: /* @__PURE__ */ jsx(
236
+ Input,
237
+ {
238
+ placeholder: "Search...",
239
+ value: globalFilter ?? "",
240
+ onChange: (e) => setGlobalFilter(e.target.value),
241
+ className: "w-full"
242
+ }
243
+ ) }),
244
+ hasFilters && showFilters && filters.map((filter) => /* @__PURE__ */ jsxs(
245
+ Select,
246
+ {
247
+ onValueChange: (val) => handleFilterChange(filter.id, val),
248
+ children: [
249
+ /* @__PURE__ */ jsxs(SelectTrigger, { className: "h-9 cursor-pointer w-[140px] rounded-md border border-input bg-background px-2 text-sm", children: [
250
+ /* @__PURE__ */ jsx(Filter, { className: "h-4 w-4 mr-2 text-muted-foreground" }),
251
+ /* @__PURE__ */ jsx(SelectValue, { placeholder: filter.label })
252
+ ] }),
253
+ /* @__PURE__ */ jsxs(SelectContent, { children: [
254
+ /* @__PURE__ */ jsxs(SelectItem, { value: "all", children: [
255
+ "All ",
256
+ filter.label
257
+ ] }),
258
+ filter.options.map((opt) => /* @__PURE__ */ jsx(SelectItem, { value: opt.value, children: opt.label }, opt.value))
1317
259
  ] })
1318
- ] }) })
1319
- ] }) : /* @__PURE__ */ jsxs(
1320
- Select,
1321
- {
1322
- value: activeFilters[filter.id] || "all",
1323
- onValueChange: (value) => handleFilterChange(filter.id, value),
1324
- children: [
1325
- /* @__PURE__ */ jsx(SelectTrigger, { className: "h-8 w-[150px] border-dashed", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: filter.placeholder || filter.label }) }),
1326
- /* @__PURE__ */ jsxs(SelectContent, { children: [
1327
- /* @__PURE__ */ jsxs(SelectItem, { value: "all", children: [
1328
- "All ",
1329
- filter.label
1330
- ] }),
1331
- filter.options.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, children: option.label }, option.value))
1332
- ] })
1333
- ]
1334
- }
1335
- ) }, filter.id)),
1336
- /* @__PURE__ */ jsxs(Popover, { children: [
1337
- /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", className: "h-8 ml-auto sm:ml-0", children: [
1338
- /* @__PURE__ */ jsx(Eye, { className: "h-4 w-4 mr-2" }),
1339
- "Columns"
1340
- ] }) }),
1341
- /* @__PURE__ */ jsx(PopoverContent, { className: "w-56", align: "end", children: /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1342
- /* @__PURE__ */ jsx("h4", { className: "font-medium text-sm", children: "Toggle Columns" }),
1343
- table.getAllColumns().filter((column) => column.getCanHide()).map((column) => /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2", children: [
1344
- /* @__PURE__ */ jsx(
1345
- Checkbox,
1346
- {
1347
- id: column.id,
1348
- checked: column.getIsVisible(),
1349
- onCheckedChange: (value) => column.toggleVisibility(!!value)
1350
- }
1351
- ),
1352
- /* @__PURE__ */ jsx("label", { htmlFor: column.id, className: "text-sm cursor-pointer", children: column.id })
1353
- ] }, column.id))
1354
- ] }) })
1355
- ] })
1356
- ] }),
1357
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1358
- viewOptions ? viewOptions : /* @__PURE__ */ jsx(ViewOptions, {}),
1359
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1360
- /* @__PURE__ */ jsx("label", { className: "text-sm text-muted-foreground whitespace-nowrap hidden sm:inline-block", children: "Rows" }),
1361
- /* @__PURE__ */ jsxs(
1362
- Select,
1363
- {
1364
- value: String(table.getState().pagination.pageSize),
1365
- onValueChange: (value) => table.setPageSize(Number(value)),
1366
- children: [
1367
- /* @__PURE__ */ jsx(SelectTrigger, { className: "w-16 h-8", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
1368
- /* @__PURE__ */ jsx(SelectContent, { children: [10, 20, 30, 40, 50].map((size) => /* @__PURE__ */ jsx(SelectItem, { value: String(size), children: size }, size)) })
1369
- ]
1370
- }
1371
- )
1372
- ] })
1373
- ] })
260
+ ]
261
+ },
262
+ filter.id
263
+ ))
264
+ ] }),
265
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
266
+ /* @__PURE__ */ jsx("label", { className: "text-sm text-muted-foreground hidden sm:block", children: "Rows" }),
267
+ /* @__PURE__ */ jsxs(
268
+ Select,
269
+ {
270
+ value: String(table.getState().pagination.pageSize),
271
+ onValueChange: (val) => {
272
+ table.setPageSize(Number(val));
273
+ },
274
+ children: [
275
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "h-8 cursor-pointer rounded-md border border-input bg-background px-2 text-sm w-[70px]", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
276
+ /* @__PURE__ */ jsx(SelectContent, { children: [10, 20, 30, 40, 50].map((s) => /* @__PURE__ */ jsx(SelectItem, { value: String(s), children: s }, s)) })
277
+ ]
278
+ }
279
+ )
1374
280
  ] })
1375
281
  ] });
1376
282
  }
1377
- var toolbar_default = Toolbar;
1378
283
  function Table({ className, ...props }) {
1379
284
  return /* @__PURE__ */ jsx(
1380
285
  "div",
@@ -1451,8 +356,15 @@ function TableCell({ className, ...props }) {
1451
356
  }
1452
357
  );
1453
358
  }
1454
- function TableView() {
1455
- const { table } = useDataTable();
359
+ function Content2({ renderCard }) {
360
+ const { table, viewMode } = useDataTableContext();
361
+ const columns = table.getAllColumns();
362
+ if (viewMode === "grid") {
363
+ return /* @__PURE__ */ jsxs("div", { className: "grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4", children: [
364
+ table.getRowModel().rows.map((row, index) => /* @__PURE__ */ jsx("div", { children: renderCard ? renderCard(row.original, index) : JSON.stringify(row.original) }, row.id)),
365
+ table.getRowModel().rows.length === 0 && /* @__PURE__ */ jsx("div", { className: "col-span-full text-center py-8 text-muted-foreground", children: "No results." })
366
+ ] });
367
+ }
1456
368
  return /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-md border", children: /* @__PURE__ */ jsxs(Table, { children: [
1457
369
  /* @__PURE__ */ jsx(TableHeader, { children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx(TableRow, { children: headerGroup.headers.map((header) => {
1458
370
  const canSort = header.column.getCanSort();
@@ -1461,66 +373,207 @@ function TableView() {
1461
373
  "button",
1462
374
  {
1463
375
  className: "flex items-center gap-2",
1464
- onClick: () => canSort && header.column.toggleSorting(),
376
+ onClick: header.column.getToggleSortingHandler(),
377
+ disabled: !canSort,
1465
378
  children: [
1466
- flexRender(header.column.columnDef.header, header.getContext()),
379
+ flexRender(
380
+ header.column.columnDef.header,
381
+ header.getContext()
382
+ ),
1467
383
  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" }) })
1468
384
  ]
1469
385
  }
1470
386
  ) }, header.id);
1471
387
  }) }, headerGroup.id)) }),
1472
- /* @__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." }) }) })
388
+ /* @__PURE__ */ jsx(TableBody, { children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ jsx(
389
+ TableRow,
390
+ {
391
+ "data-state": row.getIsSelected() && "selected",
392
+ children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx(TableCell, { children: flexRender(
393
+ cell.column.columnDef.cell,
394
+ cell.getContext()
395
+ ) }, cell.id))
396
+ },
397
+ row.id
398
+ )) : /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(
399
+ TableCell,
400
+ {
401
+ colSpan: columns.length,
402
+ className: "h-24 text-center",
403
+ children: "No results."
404
+ }
405
+ ) }) })
1473
406
  ] }) });
1474
407
  }
1475
- var table_view_default = TableView;
1476
- function GridView({ renderCard, columns = 3, gap = 16 }) {
1477
- const { table } = useDataTable();
1478
- const rows = table.getRowModel().rows;
1479
- if (!rows.length) {
1480
- return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-64 text-muted-foreground", children: "No results." });
408
+ function setRef(ref, value) {
409
+ if (typeof ref === "function") {
410
+ return ref(value);
411
+ } else if (ref !== null && ref !== void 0) {
412
+ ref.current = value;
1481
413
  }
1482
- return /* @__PURE__ */ jsx(
1483
- "div",
1484
- {
1485
- className: "grid",
1486
- style: {
1487
- gridTemplateColumns: `repeat(${columns}, 1fr)`,
1488
- gap: `${gap}px`
1489
- },
1490
- children: rows.map((row, index) => {
1491
- const item = row.original;
1492
- 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);
1493
- })
414
+ }
415
+ function composeRefs(...refs) {
416
+ return (node) => {
417
+ let hasCleanup = false;
418
+ const cleanups = refs.map((ref) => {
419
+ const cleanup = setRef(ref, node);
420
+ if (!hasCleanup && typeof cleanup == "function") {
421
+ hasCleanup = true;
422
+ }
423
+ return cleanup;
424
+ });
425
+ if (hasCleanup) {
426
+ return () => {
427
+ for (let i = 0; i < cleanups.length; i++) {
428
+ const cleanup = cleanups[i];
429
+ if (typeof cleanup == "function") {
430
+ cleanup();
431
+ } else {
432
+ setRef(refs[i], null);
433
+ }
434
+ }
435
+ };
1494
436
  }
1495
- );
437
+ };
1496
438
  }
1497
- function DefaultCard({ item }) {
1498
- if (typeof item !== "object" || item === null) return null;
1499
- return /* @__PURE__ */ jsx("div", { className: "space-y-2", children: Object.entries(item).map(([key, value]) => /* @__PURE__ */ jsxs("div", { children: [
1500
- /* @__PURE__ */ jsxs("span", { className: "text-sm font-medium", children: [
1501
- key,
1502
- ": "
1503
- ] }),
1504
- /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: String(value) })
1505
- ] }, key)) });
439
+ // @__NO_SIDE_EFFECTS__
440
+ function createSlot(ownerName) {
441
+ const SlotClone = /* @__PURE__ */ createSlotClone(ownerName);
442
+ const Slot2 = React2.forwardRef((props, forwardedRef) => {
443
+ const { children, ...slotProps } = props;
444
+ const childrenArray = React2.Children.toArray(children);
445
+ const slottable = childrenArray.find(isSlottable);
446
+ if (slottable) {
447
+ const newElement = slottable.props.children;
448
+ const newChildren = childrenArray.map((child) => {
449
+ if (child === slottable) {
450
+ if (React2.Children.count(newElement) > 1) return React2.Children.only(null);
451
+ return React2.isValidElement(newElement) ? newElement.props.children : null;
452
+ } else {
453
+ return child;
454
+ }
455
+ });
456
+ return /* @__PURE__ */ jsx(SlotClone, { ...slotProps, ref: forwardedRef, children: React2.isValidElement(newElement) ? React2.cloneElement(newElement, void 0, newChildren) : null });
457
+ }
458
+ return /* @__PURE__ */ jsx(SlotClone, { ...slotProps, ref: forwardedRef, children });
459
+ });
460
+ Slot2.displayName = `${ownerName}.Slot`;
461
+ return Slot2;
1506
462
  }
1507
- var grid_view_default = GridView;
1508
- function Content3({ renderCard, gridColumns, gridGap }) {
1509
- const { viewMode } = useDataTable();
1510
- if (viewMode === "grid") {
1511
- return /* @__PURE__ */ jsx(grid_view_default, { renderCard, columns: gridColumns, gap: gridGap });
463
+ var Slot = /* @__PURE__ */ createSlot("Slot");
464
+ // @__NO_SIDE_EFFECTS__
465
+ function createSlotClone(ownerName) {
466
+ const SlotClone = React2.forwardRef((props, forwardedRef) => {
467
+ const { children, ...slotProps } = props;
468
+ if (React2.isValidElement(children)) {
469
+ const childrenRef = getElementRef(children);
470
+ const props2 = mergeProps(slotProps, children.props);
471
+ if (children.type !== React2.Fragment) {
472
+ props2.ref = forwardedRef ? composeRefs(forwardedRef, childrenRef) : childrenRef;
473
+ }
474
+ return React2.cloneElement(children, props2);
475
+ }
476
+ return React2.Children.count(children) > 1 ? React2.Children.only(null) : null;
477
+ });
478
+ SlotClone.displayName = `${ownerName}.SlotClone`;
479
+ return SlotClone;
480
+ }
481
+ var SLOTTABLE_IDENTIFIER = /* @__PURE__ */ Symbol("radix.slottable");
482
+ function isSlottable(child) {
483
+ return React2.isValidElement(child) && typeof child.type === "function" && "__radixId" in child.type && child.type.__radixId === SLOTTABLE_IDENTIFIER;
484
+ }
485
+ function mergeProps(slotProps, childProps) {
486
+ const overrideProps = { ...childProps };
487
+ for (const propName in childProps) {
488
+ const slotPropValue = slotProps[propName];
489
+ const childPropValue = childProps[propName];
490
+ const isHandler = /^on[A-Z]/.test(propName);
491
+ if (isHandler) {
492
+ if (slotPropValue && childPropValue) {
493
+ overrideProps[propName] = (...args) => {
494
+ const result = childPropValue(...args);
495
+ slotPropValue(...args);
496
+ return result;
497
+ };
498
+ } else if (slotPropValue) {
499
+ overrideProps[propName] = slotPropValue;
500
+ }
501
+ } else if (propName === "style") {
502
+ overrideProps[propName] = { ...slotPropValue, ...childPropValue };
503
+ } else if (propName === "className") {
504
+ overrideProps[propName] = [slotPropValue, childPropValue].filter(Boolean).join(" ");
505
+ }
506
+ }
507
+ return { ...slotProps, ...overrideProps };
508
+ }
509
+ function getElementRef(element) {
510
+ let getter = Object.getOwnPropertyDescriptor(element.props, "ref")?.get;
511
+ let mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
512
+ if (mayWarn) {
513
+ return element.ref;
514
+ }
515
+ getter = Object.getOwnPropertyDescriptor(element, "ref")?.get;
516
+ mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
517
+ if (mayWarn) {
518
+ return element.props.ref;
519
+ }
520
+ return element.props.ref || element.ref;
521
+ }
522
+ var buttonVariants = cva(
523
+ "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",
524
+ {
525
+ variants: {
526
+ variant: {
527
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
528
+ destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
529
+ 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",
530
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
531
+ ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
532
+ link: "text-primary underline-offset-4 hover:underline"
533
+ },
534
+ size: {
535
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
536
+ sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
537
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
538
+ icon: "size-9",
539
+ "icon-sm": "size-8",
540
+ "icon-lg": "size-10"
541
+ }
542
+ },
543
+ defaultVariants: {
544
+ variant: "default",
545
+ size: "default"
546
+ }
1512
547
  }
1513
- return /* @__PURE__ */ jsx(table_view_default, {});
548
+ );
549
+ function Button({
550
+ className,
551
+ variant = "default",
552
+ size = "default",
553
+ asChild = false,
554
+ ...props
555
+ }) {
556
+ const Comp = asChild ? Slot : "button";
557
+ return /* @__PURE__ */ jsx(
558
+ Comp,
559
+ {
560
+ "data-slot": "button",
561
+ "data-variant": variant,
562
+ "data-size": size,
563
+ className: cn(buttonVariants({ variant, size, className })),
564
+ ...props
565
+ }
566
+ );
1514
567
  }
1515
- var content_default = Content3;
1516
568
  function Pagination() {
1517
- const { table } = useDataTable();
569
+ const { table } = useDataTableContext();
1518
570
  return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between py-4", children: [
1519
571
  /* @__PURE__ */ jsxs("div", { className: "text-sm text-muted-foreground", children: [
1520
572
  "Showing",
1521
573
  " ",
1522
574
  table.getState().pagination.pageIndex * table.getState().pagination.pageSize + 1,
1523
- " -",
575
+ " ",
576
+ "-",
1524
577
  " ",
1525
578
  Math.min(
1526
579
  (table.getState().pagination.pageIndex + 1) * table.getState().pagination.pageSize,
@@ -1544,7 +597,8 @@ function Pagination() {
1544
597
  /* @__PURE__ */ jsxs("div", { className: "px-3 text-sm", children: [
1545
598
  "Page ",
1546
599
  table.getState().pagination.pageIndex + 1,
1547
- " of ",
600
+ " of",
601
+ " ",
1548
602
  table.getPageCount()
1549
603
  ] }),
1550
604
  /* @__PURE__ */ jsx(
@@ -1560,20 +614,38 @@ function Pagination() {
1560
614
  ] })
1561
615
  ] });
1562
616
  }
1563
- var pagination_default = Pagination;
1564
-
1565
- // src/components/data-table/index.tsx
1566
- var DataTable = Object.assign(root_default2, {
1567
- Root: root_default2,
1568
- Toolbar: toolbar_default,
1569
- Content: content_default,
1570
- TableView: table_view_default,
1571
- GridView: grid_view_default,
1572
- Pagination: pagination_default,
1573
- ViewOptions: view_options_default
1574
- });
1575
- var data_table_default = DataTable;
617
+ function ViewOptions({
618
+ viewMode: propViewMode,
619
+ onViewModeChange: propOnViewModeChange
620
+ }) {
621
+ const context = useDataTableContext();
622
+ const mode = propViewMode ?? context?.viewMode ?? "table";
623
+ const onChange = propOnViewModeChange ?? context?.setViewMode;
624
+ if (!onChange) return null;
625
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center border rounded-md", children: [
626
+ /* @__PURE__ */ jsx(
627
+ Button,
628
+ {
629
+ variant: mode === "table" ? "secondary" : "ghost",
630
+ size: "sm",
631
+ className: "rounded-r-none px-3",
632
+ onClick: () => onChange("table"),
633
+ children: /* @__PURE__ */ jsx(TableIcon, { className: "h-4 w-4" })
634
+ }
635
+ ),
636
+ /* @__PURE__ */ jsx(
637
+ Button,
638
+ {
639
+ variant: mode === "grid" ? "secondary" : "ghost",
640
+ size: "sm",
641
+ className: "rounded-l-none px-3",
642
+ onClick: () => onChange("grid"),
643
+ children: /* @__PURE__ */ jsx(LayoutGrid, { className: "h-4 w-4" })
644
+ }
645
+ )
646
+ ] });
647
+ }
1576
648
 
1577
- export { data_table_default as DataTable, form_default as Form, cn };
649
+ export { Content2 as Content, DataTableContext, Pagination, Root, Toolbar, ViewOptions, cn, useDataTableContext, useViewMode };
1578
650
  //# sourceMappingURL=index.mjs.map
1579
651
  //# sourceMappingURL=index.mjs.map