hazo_ui 2.9.0 → 2.16.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.js CHANGED
@@ -1,20 +1,19 @@
1
1
  "use client";
2
- import * as React27 from 'react';
3
- import React27__default, { useRef, useState, useCallback, useEffect, useMemo, Fragment } from 'react';
2
+ import * as React25 from 'react';
3
+ import React25__default, { useRef, useState, useCallback, useEffect, useMemo, Fragment } from 'react';
4
4
  import { Slot } from '@radix-ui/react-slot';
5
5
  import { cva } from 'class-variance-authority';
6
6
  import { clsx } from 'clsx';
7
7
  import { twMerge } from 'tailwind-merge';
8
8
  import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
9
9
  import * as DialogPrimitive from '@radix-ui/react-dialog';
10
- import { X, ChevronDown, ChevronUp, Check, Circle, ChevronRight, ChevronLeft, Filter, Plus, ChevronsUpDown, ArrowUpDown, Trash2, Loader2, GripVertical, Calendar as Calendar$1 } from 'lucide-react';
10
+ import { X, ChevronDown, ChevronUp, Check, Circle, ChevronRight, ChevronLeft, Filter, Plus, ArrowUpDown, Loader2, AlertTriangle, OctagonAlert, CheckCircle2, ChevronsUpDown, GripVertical, ArrowUp, ArrowDown, Pencil, Calendar as Calendar$1 } from 'lucide-react';
11
11
  import * as PopoverPrimitive from '@radix-ui/react-popover';
12
12
  import * as SelectPrimitive from '@radix-ui/react-select';
13
13
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
14
14
  import { DayPicker } from 'react-day-picker';
15
15
  import { format } from 'date-fns';
16
- import * as SwitchPrimitives from '@radix-ui/react-switch';
17
- import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, closestCenter } from '@dnd-kit/core';
16
+ import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, closestCenter, closestCorners, DragOverlay, useDroppable } from '@dnd-kit/core';
18
17
  import { sortableKeyboardCoordinates, SortableContext, verticalListSortingStrategy, arrayMove, useSortable } from '@dnd-kit/sortable';
19
18
  import { CSS } from '@dnd-kit/utilities';
20
19
  import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
@@ -61,12 +60,15 @@ import * as AccordionPrimitive from '@radix-ui/react-accordion';
61
60
  import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
62
61
  import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
63
62
  import * as HoverCardPrimitive from '@radix-ui/react-hover-card';
63
+ import * as SwitchPrimitives from '@radix-ui/react-switch';
64
64
  import * as SeparatorPrimitive from '@radix-ui/react-separator';
65
65
  import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
66
66
  import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
67
67
  import * as TogglePrimitive from '@radix-ui/react-toggle';
68
68
  import * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group';
69
69
  import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
70
+ import { Toaster, toast } from 'sonner';
71
+ export { toast as rawToast } from 'sonner';
70
72
 
71
73
  var __create = Object.create;
72
74
  var __defProp = Object.defineProperty;
@@ -186,26 +188,26 @@ var buttonVariants = cva(
186
188
  );
187
189
  var variant_styles = {
188
190
  default: {
189
- backgroundColor: "var(--primary)",
190
- color: "var(--primary-foreground)",
191
- border: "1px solid var(--primary)"
191
+ backgroundColor: "hsl(var(--primary))",
192
+ color: "hsl(var(--primary-foreground))",
193
+ border: "1px solid hsl(var(--primary))"
192
194
  },
193
195
  destructive: {
194
- backgroundColor: "var(--destructive)",
195
- color: "white",
196
- border: "1px solid var(--destructive)"
196
+ backgroundColor: "hsl(var(--destructive))",
197
+ color: "hsl(var(--destructive-foreground))",
198
+ border: "1px solid hsl(var(--destructive))"
197
199
  },
198
200
  outline: {
199
- backgroundColor: "var(--background)",
200
- color: "var(--foreground)",
201
- border: "1px solid var(--border)"
201
+ backgroundColor: "hsl(var(--background))",
202
+ color: "hsl(var(--foreground))",
203
+ border: "1px solid hsl(var(--border))"
202
204
  },
203
205
  secondary: {
204
- backgroundColor: "var(--secondary)",
205
- color: "var(--secondary-foreground)"
206
+ backgroundColor: "hsl(var(--secondary))",
207
+ color: "hsl(var(--secondary-foreground))"
206
208
  }
207
209
  };
208
- var Button = React27.forwardRef(
210
+ var Button = React25.forwardRef(
209
211
  ({ className, variant, size, asChild = false, style, ...props }, ref) => {
210
212
  const Comp = asChild ? Slot : "button";
211
213
  const fallback_styles = variant_styles[variant ?? "default"] ?? {};
@@ -225,7 +227,7 @@ var Dialog = DialogPrimitive.Root;
225
227
  var DialogTrigger = DialogPrimitive.Trigger;
226
228
  var DialogPortal = DialogPrimitive.Portal;
227
229
  var DialogClose = DialogPrimitive.Close;
228
- var DialogOverlay = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
230
+ var DialogOverlay = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
229
231
  DialogPrimitive.Overlay,
230
232
  {
231
233
  ref,
@@ -237,14 +239,14 @@ var DialogOverlay = React27.forwardRef(({ className, ...props }, ref) => /* @__P
237
239
  }
238
240
  ));
239
241
  DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
240
- var DialogContent = React27.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(DialogPortal, { children: [
242
+ var DialogContent = React25.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(DialogPortal, { children: [
241
243
  /* @__PURE__ */ jsx(DialogOverlay, {}),
242
244
  /* @__PURE__ */ jsxs(
243
245
  DialogPrimitive.Content,
244
246
  {
245
247
  ref,
246
248
  className: cn(
247
- "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
249
+ "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 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 sm:rounded-lg",
248
250
  className
249
251
  ),
250
252
  ...props,
@@ -287,7 +289,7 @@ var DialogFooter = ({
287
289
  }
288
290
  );
289
291
  DialogFooter.displayName = "DialogFooter";
290
- var DialogTitle = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
292
+ var DialogTitle = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
291
293
  DialogPrimitive.Title,
292
294
  {
293
295
  ref,
@@ -300,7 +302,7 @@ var DialogTitle = React27.forwardRef(({ className, ...props }, ref) => /* @__PUR
300
302
  }
301
303
  ));
302
304
  DialogTitle.displayName = DialogPrimitive.Title.displayName;
303
- var DialogDescription = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
305
+ var DialogDescription = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
304
306
  DialogPrimitive.Description,
305
307
  {
306
308
  ref,
@@ -309,7 +311,7 @@ var DialogDescription = React27.forwardRef(({ className, ...props }, ref) => /*
309
311
  }
310
312
  ));
311
313
  DialogDescription.displayName = DialogPrimitive.Description.displayName;
312
- var Command = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
314
+ var Command = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
313
315
  "div",
314
316
  {
315
317
  ref,
@@ -321,7 +323,7 @@ var Command = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__
321
323
  }
322
324
  ));
323
325
  Command.displayName = "Command";
324
- var CommandInput = React27.forwardRef(({ className, onValueChange, onChange, ...props }, ref) => /* @__PURE__ */ jsx(
326
+ var CommandInput = React25.forwardRef(({ className, onValueChange, onChange, ...props }, ref) => /* @__PURE__ */ jsx(
325
327
  "input",
326
328
  {
327
329
  ref,
@@ -337,7 +339,7 @@ var CommandInput = React27.forwardRef(({ className, onValueChange, onChange, ...
337
339
  }
338
340
  ));
339
341
  CommandInput.displayName = "CommandInput";
340
- var CommandList = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
342
+ var CommandList = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
341
343
  "div",
342
344
  {
343
345
  ref,
@@ -346,7 +348,7 @@ var CommandList = React27.forwardRef(({ className, ...props }, ref) => /* @__PUR
346
348
  }
347
349
  ));
348
350
  CommandList.displayName = "CommandList";
349
- var CommandEmpty = React27.forwardRef((props, ref) => /* @__PURE__ */ jsx(
351
+ var CommandEmpty = React25.forwardRef((props, ref) => /* @__PURE__ */ jsx(
350
352
  "div",
351
353
  {
352
354
  ref,
@@ -355,7 +357,7 @@ var CommandEmpty = React27.forwardRef((props, ref) => /* @__PURE__ */ jsx(
355
357
  }
356
358
  ));
357
359
  CommandEmpty.displayName = "CommandEmpty";
358
- var CommandGroup = React27.forwardRef(({ className, heading, children, ...props }, ref) => /* @__PURE__ */ jsxs(
360
+ var CommandGroup = React25.forwardRef(({ className, heading, children, ...props }, ref) => /* @__PURE__ */ jsxs(
359
361
  "div",
360
362
  {
361
363
  ref,
@@ -371,7 +373,7 @@ var CommandGroup = React27.forwardRef(({ className, heading, children, ...props
371
373
  }
372
374
  ));
373
375
  CommandGroup.displayName = "CommandGroup";
374
- var CommandItem = React27.forwardRef(({ className, onSelect, value, selected, style, ...props }, ref) => {
376
+ var CommandItem = React25.forwardRef(({ className, onSelect, value, selected, style, ...props }, ref) => {
375
377
  const handleClick = () => {
376
378
  if (onSelect && value) {
377
379
  onSelect(value);
@@ -402,7 +404,7 @@ var CommandItem = React27.forwardRef(({ className, onSelect, value, selected, st
402
404
  CommandItem.displayName = "CommandItem";
403
405
  var Popover = PopoverPrimitive.Root;
404
406
  var PopoverTrigger = PopoverPrimitive.Trigger;
405
- var PopoverContent = React27.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
407
+ var PopoverContent = React25.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
406
408
  PopoverPrimitive.Content,
407
409
  {
408
410
  ref,
@@ -416,7 +418,7 @@ var PopoverContent = React27.forwardRef(({ className, align = "center", sideOffs
416
418
  }
417
419
  ) }));
418
420
  PopoverContent.displayName = PopoverPrimitive.Content.displayName;
419
- var Input = React27.forwardRef(
421
+ var Input = React25.forwardRef(
420
422
  ({ className, type, ...props }, ref) => {
421
423
  return /* @__PURE__ */ jsx(
422
424
  "input",
@@ -436,7 +438,7 @@ Input.displayName = "Input";
436
438
  var Select = SelectPrimitive.Root;
437
439
  var SelectGroup = SelectPrimitive.Group;
438
440
  var SelectValue = SelectPrimitive.Value;
439
- var SelectTrigger = React27.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
441
+ var SelectTrigger = React25.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
440
442
  SelectPrimitive.Trigger,
441
443
  {
442
444
  ref,
@@ -452,7 +454,7 @@ var SelectTrigger = React27.forwardRef(({ className, children, ...props }, ref)
452
454
  }
453
455
  ));
454
456
  SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
455
- var SelectScrollUpButton = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
457
+ var SelectScrollUpButton = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
456
458
  SelectPrimitive.ScrollUpButton,
457
459
  {
458
460
  ref,
@@ -465,7 +467,7 @@ var SelectScrollUpButton = React27.forwardRef(({ className, ...props }, ref) =>
465
467
  }
466
468
  ));
467
469
  SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
468
- var SelectScrollDownButton = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
470
+ var SelectScrollDownButton = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
469
471
  SelectPrimitive.ScrollDownButton,
470
472
  {
471
473
  ref,
@@ -478,7 +480,7 @@ var SelectScrollDownButton = React27.forwardRef(({ className, ...props }, ref) =
478
480
  }
479
481
  ));
480
482
  SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
481
- var SelectContent = React27.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
483
+ var SelectContent = React25.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
482
484
  SelectPrimitive.Content,
483
485
  {
484
486
  ref,
@@ -506,7 +508,7 @@ var SelectContent = React27.forwardRef(({ className, children, position = "poppe
506
508
  }
507
509
  ) }));
508
510
  SelectContent.displayName = SelectPrimitive.Content.displayName;
509
- var SelectLabel = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
511
+ var SelectLabel = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
510
512
  SelectPrimitive.Label,
511
513
  {
512
514
  ref,
@@ -515,7 +517,7 @@ var SelectLabel = React27.forwardRef(({ className, ...props }, ref) => /* @__PUR
515
517
  }
516
518
  ));
517
519
  SelectLabel.displayName = SelectPrimitive.Label.displayName;
518
- var SelectItem = React27.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
520
+ var SelectItem = React25.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
519
521
  SelectPrimitive.Item,
520
522
  {
521
523
  ref,
@@ -531,7 +533,7 @@ var SelectItem = React27.forwardRef(({ className, children, ...props }, ref) =>
531
533
  }
532
534
  ));
533
535
  SelectItem.displayName = SelectPrimitive.Item.displayName;
534
- var SelectSeparator = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
536
+ var SelectSeparator = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
535
537
  SelectPrimitive.Separator,
536
538
  {
537
539
  ref,
@@ -543,7 +545,7 @@ SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
543
545
  var TooltipProvider = TooltipPrimitive.Provider;
544
546
  var Tooltip = TooltipPrimitive.Root;
545
547
  var TooltipTrigger = TooltipPrimitive.Trigger;
546
- var TooltipContent = React27.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(
548
+ var TooltipContent = React25.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(
547
549
  TooltipPrimitive.Content,
548
550
  {
549
551
  ref,
@@ -630,27 +632,27 @@ function FilterFieldItem({
630
632
  placeholder: "Enter text...",
631
633
  minLength: fieldConfig.textConfig?.minLength,
632
634
  maxLength: fieldConfig.textConfig?.maxLength,
633
- className: "cls_filter_text_input w-full min-w-0"
635
+ className: "cls_filter_text_input h-8 w-full min-w-0 text-sm"
634
636
  }
635
637
  );
636
- case "number":
638
+ case "number": {
637
639
  const numberOperators = [
638
- { value: "equals", label: "Equals" },
639
- { value: "not_equals", label: "Not Equals" },
640
- { value: "greater_than", label: "Greater Than" },
641
- { value: "less_than", label: "Less Than" },
642
- { value: "greater_equal", label: "Greater or Equal" },
643
- { value: "less_equal", label: "Less or Equal" }
640
+ { value: "equals", label: "=" },
641
+ { value: "not_equals", label: "\u2260" },
642
+ { value: "greater_than", label: ">" },
643
+ { value: "less_than", label: "<" },
644
+ { value: "greater_equal", label: "\u2265" },
645
+ { value: "less_equal", label: "\u2264" }
644
646
  ];
645
- return /* @__PURE__ */ jsxs("div", { className: "cls_number_filter_container flex flex-col sm:flex-row items-stretch sm:items-center gap-2 w-full", children: [
647
+ return /* @__PURE__ */ jsxs("div", { className: "cls_number_filter_container flex w-full items-center gap-1.5", children: [
646
648
  /* @__PURE__ */ jsxs(
647
649
  Select,
648
650
  {
649
651
  value: filterConfig.operator || "equals",
650
652
  onValueChange: (value) => onOperatorChange?.(value),
651
653
  children: [
652
- /* @__PURE__ */ jsx(SelectTrigger, { className: "cls_operator_select w-full sm:w-[140px] shrink-0", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
653
- /* @__PURE__ */ jsx(SelectContent, { children: numberOperators.map((op) => /* @__PURE__ */ jsx(SelectItem, { value: op.value, children: op.label }, op.value)) })
654
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "cls_operator_select h-8 w-[60px] shrink-0 text-sm", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
655
+ /* @__PURE__ */ jsx(SelectContent, { children: numberOperators.map((op) => /* @__PURE__ */ jsx(SelectItem, { value: op.value, children: /* @__PURE__ */ jsx("span", { className: "font-mono", children: op.label }) }, op.value)) })
654
656
  ]
655
657
  }
656
658
  ),
@@ -666,14 +668,10 @@ function FilterFieldItem({
666
668
  return;
667
669
  }
668
670
  let numValue = fieldConfig.numberConfig?.allowDecimal ? parseFloat(value) : parseInt(value, 10);
669
- if (isNaN(numValue)) {
670
- return;
671
- }
671
+ if (isNaN(numValue)) return;
672
672
  if (fieldConfig.numberConfig?.allowDecimal && fieldConfig.numberConfig?.decimalLength) {
673
673
  const decimalPlaces = value.split(".")[1]?.length || 0;
674
- if (decimalPlaces > fieldConfig.numberConfig.decimalLength) {
675
- return;
676
- }
674
+ if (decimalPlaces > fieldConfig.numberConfig.decimalLength) return;
677
675
  }
678
676
  if (fieldConfig.numberConfig?.min !== void 0 && numValue < fieldConfig.numberConfig.min) {
679
677
  numValue = fieldConfig.numberConfig.min;
@@ -683,14 +681,15 @@ function FilterFieldItem({
683
681
  }
684
682
  onValueChange(numValue);
685
683
  },
686
- placeholder: "Enter number...",
684
+ placeholder: "Value",
687
685
  min: fieldConfig.numberConfig?.min,
688
686
  max: fieldConfig.numberConfig?.max,
689
687
  step: fieldConfig.numberConfig?.allowDecimal ? 0.01 : 1,
690
- className: "cls_filter_number_input flex-1 min-w-0"
688
+ className: "cls_filter_number_input h-8 flex-1 min-w-0 text-sm tabular-nums"
691
689
  }
692
690
  )
693
691
  ] });
692
+ }
694
693
  case "combobox":
695
694
  return /* @__PURE__ */ jsxs(
696
695
  Select,
@@ -698,12 +697,12 @@ function FilterFieldItem({
698
697
  value: filterConfig.value || "",
699
698
  onValueChange: (value) => onValueChange(value),
700
699
  children: [
701
- /* @__PURE__ */ jsx(SelectTrigger, { className: "cls_filter_combobox_select w-full min-w-0", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select option..." }) }),
700
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "cls_filter_combobox_select h-8 w-full min-w-0 text-sm", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select option..." }) }),
702
701
  /* @__PURE__ */ jsx(SelectContent, { children: fieldConfig.comboboxOptions?.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
703
702
  ]
704
703
  }
705
704
  );
706
- case "boolean":
705
+ case "boolean": {
707
706
  const trueLabel = fieldConfig.booleanLabels?.trueLabel || "On";
708
707
  const falseLabel = fieldConfig.booleanLabels?.falseLabel || "Off";
709
708
  return /* @__PURE__ */ jsxs(
@@ -712,7 +711,7 @@ function FilterFieldItem({
712
711
  value: filterConfig.value !== void 0 && filterConfig.value !== null ? String(filterConfig.value) : "",
713
712
  onValueChange: (value) => onValueChange(value === "true"),
714
713
  children: [
715
- /* @__PURE__ */ jsx(SelectTrigger, { className: "cls_filter_boolean_select w-full min-w-0", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select..." }) }),
714
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "cls_filter_boolean_select h-8 w-full min-w-0 text-sm", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select..." }) }),
716
715
  /* @__PURE__ */ jsxs(SelectContent, { children: [
717
716
  /* @__PURE__ */ jsx(SelectItem, { value: "true", children: trueLabel }),
718
717
  /* @__PURE__ */ jsx(SelectItem, { value: "false", children: falseLabel })
@@ -720,25 +719,26 @@ function FilterFieldItem({
720
719
  ]
721
720
  }
722
721
  );
723
- case "date":
722
+ }
723
+ case "date": {
724
724
  const dateOperators = [
725
- { value: "equals", label: "Equals" },
726
- { value: "not_equals", label: "Not Equals" },
727
- { value: "greater_than", label: "Greater Than" },
728
- { value: "less_than", label: "Less Than" },
729
- { value: "greater_equal", label: "Greater or Equal" },
730
- { value: "less_equal", label: "Less or Equal" }
725
+ { value: "equals", label: "=" },
726
+ { value: "not_equals", label: "\u2260" },
727
+ { value: "greater_than", label: ">" },
728
+ { value: "less_than", label: "<" },
729
+ { value: "greater_equal", label: "\u2265" },
730
+ { value: "less_equal", label: "\u2264" }
731
731
  ];
732
732
  const selectedDate = filterConfig.value ? typeof filterConfig.value === "string" ? new Date(filterConfig.value) : filterConfig.value : void 0;
733
- return /* @__PURE__ */ jsxs("div", { className: "cls_date_filter_container flex flex-col sm:flex-row items-stretch sm:items-center gap-2 w-full", children: [
733
+ return /* @__PURE__ */ jsxs("div", { className: "cls_date_filter_container flex w-full items-center gap-1.5", children: [
734
734
  /* @__PURE__ */ jsxs(
735
735
  Select,
736
736
  {
737
737
  value: filterConfig.operator || "equals",
738
738
  onValueChange: (value) => onOperatorChange?.(value),
739
739
  children: [
740
- /* @__PURE__ */ jsx(SelectTrigger, { className: "cls_operator_select w-full sm:w-[140px] shrink-0", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
741
- /* @__PURE__ */ jsx(SelectContent, { children: dateOperators.map((op) => /* @__PURE__ */ jsx(SelectItem, { value: op.value, children: op.label }, op.value)) })
740
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "cls_operator_select h-8 w-[60px] shrink-0 text-sm", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
741
+ /* @__PURE__ */ jsx(SelectContent, { children: dateOperators.map((op) => /* @__PURE__ */ jsx(SelectItem, { value: op.value, children: /* @__PURE__ */ jsx("span", { className: "font-mono", children: op.label }) }, op.value)) })
742
742
  ]
743
743
  }
744
744
  ),
@@ -748,11 +748,11 @@ function FilterFieldItem({
748
748
  {
749
749
  variant: "outline",
750
750
  className: cn(
751
- "cls_date_picker_trigger w-full justify-start text-left font-normal min-w-0",
751
+ "cls_date_picker_trigger h-8 flex-1 justify-start gap-2 px-2.5 text-left text-sm font-normal min-w-0",
752
752
  !selectedDate && "text-muted-foreground"
753
753
  ),
754
754
  children: [
755
- /* @__PURE__ */ jsx(Calendar$1, { className: "cls_calendar_icon mr-2 h-4 w-4 shrink-0" }),
755
+ /* @__PURE__ */ jsx(Calendar$1, { className: "cls_calendar_icon h-3.5 w-3.5 shrink-0" }),
756
756
  /* @__PURE__ */ jsx("span", { className: "cls_date_text truncate", children: selectedDate ? format(selectedDate, "MMM d, yyyy") : "Pick a date" })
757
757
  ]
758
758
  }
@@ -771,24 +771,27 @@ function FilterFieldItem({
771
771
  ) })
772
772
  ] })
773
773
  ] });
774
+ }
774
775
  default:
775
776
  return null;
776
777
  }
777
778
  };
778
- return /* @__PURE__ */ jsxs("div", { className: "cls_filter_field_item flex flex-col sm:flex-row items-start sm:items-center gap-3 p-3 border rounded-md bg-card", children: [
779
- /* @__PURE__ */ jsx("span", { className: "cls_field_label text-sm font-medium min-w-[120px] sm:min-w-[100px] truncate", children: fieldConfig.label }),
780
- /* @__PURE__ */ jsx("div", { className: "cls_field_input_container flex-1 min-w-0 w-full sm:w-auto", children: renderInput() }),
781
- /* @__PURE__ */ jsx(
782
- Button,
783
- {
784
- variant: "ghost",
785
- size: "sm",
786
- onClick: onDelete,
787
- className: "cls_delete_btn h-8 w-8 p-0 text-destructive hover:text-destructive shrink-0",
788
- "aria-label": `Remove ${fieldConfig.label} filter`,
789
- children: /* @__PURE__ */ jsx(Trash2, { className: "cls_delete_icon h-4 w-4" })
790
- }
791
- )
779
+ return /* @__PURE__ */ jsxs("div", { className: "cls_filter_field_item group flex flex-col gap-2 rounded-lg border border-border/70 bg-card px-3 py-2.5 transition-colors hover:border-border sm:flex-row sm:items-center sm:gap-3", children: [
780
+ /* @__PURE__ */ jsx("span", { className: "cls_field_label w-full shrink-0 truncate text-xs font-semibold uppercase tracking-wide text-muted-foreground sm:w-[110px] sm:text-sm sm:normal-case sm:font-medium sm:text-foreground sm:tracking-normal", children: fieldConfig.label }),
781
+ /* @__PURE__ */ jsxs("div", { className: "cls_field_input_container flex min-w-0 flex-1 items-center gap-2", children: [
782
+ /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: renderInput() }),
783
+ /* @__PURE__ */ jsx(
784
+ Button,
785
+ {
786
+ variant: "ghost",
787
+ size: "sm",
788
+ onClick: onDelete,
789
+ className: "cls_delete_btn h-7 w-7 shrink-0 p-0 text-muted-foreground/60 hover:bg-destructive/10 hover:text-destructive",
790
+ "aria-label": `Remove ${fieldConfig.label} filter`,
791
+ children: /* @__PURE__ */ jsx(X, { className: "cls_delete_icon h-3.5 w-3.5" })
792
+ }
793
+ )
794
+ ] })
792
795
  ] });
793
796
  }
794
797
  function HazoUiMultiFilterDialog({
@@ -796,7 +799,7 @@ function HazoUiMultiFilterDialog({
796
799
  onFilterChange,
797
800
  initialFilters = [],
798
801
  title = "Filter",
799
- description = "Add multiple fields to filter by. Select a field and set its filter value.",
802
+ description = "Add fields to filter by. Select a field and set its value.",
800
803
  headerBackgroundColor,
801
804
  headerTextColor,
802
805
  submitButtonBackgroundColor,
@@ -846,13 +849,9 @@ function HazoUiMultiFilterDialog({
846
849
  }
847
850
  }, [isOpen, initialFilters]);
848
851
  const handleAddField = (fieldValue) => {
849
- if (filterFields.some((ff) => ff.field === fieldValue)) {
850
- return;
851
- }
852
+ if (filterFields.some((ff) => ff.field === fieldValue)) return;
852
853
  const fieldConfig = availableFields.find((af) => af.value === fieldValue);
853
- if (!fieldConfig) {
854
- return;
855
- }
854
+ if (!fieldConfig) return;
856
855
  let defaultValue = "";
857
856
  if (fieldConfig.type === "boolean") {
858
857
  defaultValue = false;
@@ -905,7 +904,7 @@ function HazoUiMultiFilterDialog({
905
904
  };
906
905
  const hasActiveFilters = initialFilters.length > 0;
907
906
  const tooltipContent = hasActiveFilters ? /* @__PURE__ */ jsxs("div", { className: "cls_filter_tooltip_content space-y-1", children: [
908
- /* @__PURE__ */ jsx("div", { className: "cls_tooltip_title text-xs font-semibold mb-1", children: "Active Filters:" }),
907
+ /* @__PURE__ */ jsx("div", { className: "cls_tooltip_title text-xs font-semibold mb-1", children: "Active filters" }),
909
908
  initialFilters.map((filterConfig) => {
910
909
  const fieldConfig = getFieldConfig(filterConfig.field);
911
910
  if (!fieldConfig) return null;
@@ -949,152 +948,114 @@ function HazoUiMultiFilterDialog({
949
948
  )
950
949
  }
951
950
  ),
952
- "Filter"
951
+ "Filter",
952
+ hasActiveFilters && /* @__PURE__ */ jsx("span", { className: "cls_filter_count ml-2 inline-flex h-4 min-w-4 items-center justify-center rounded-full bg-blue-600 px-1 text-[10px] font-semibold text-white", children: initialFilters.length })
953
953
  ]
954
954
  }
955
955
  ) }) }),
956
956
  /* @__PURE__ */ jsx(TooltipContent, { children: tooltipContent })
957
957
  ] }) }),
958
- /* @__PURE__ */ jsxs(DialogContent, { className: "cls_filter_dialog_content max-w-lg w-full max-h-[90vh] overflow-y-auto", children: [
959
- /* @__PURE__ */ jsxs(DialogHeader, { style: headerStyles, children: [
960
- /* @__PURE__ */ jsx(DialogTitle, { children: title }),
961
- /* @__PURE__ */ jsx(DialogDescription, { children: description })
962
- ] }),
963
- /* @__PURE__ */ jsxs("div", { className: "cls_filter_dialog_body space-y-4 py-4", children: [
958
+ /* @__PURE__ */ jsxs(DialogContent, { className: "cls_filter_dialog_content max-w-lg gap-0 p-0 sm:rounded-xl max-h-[90vh]", children: [
959
+ /* @__PURE__ */ jsxs(
960
+ DialogHeader,
961
+ {
962
+ className: "cls_filter_dialog_header space-y-1 border-b px-5 py-4 text-left",
963
+ style: headerStyles,
964
+ children: [
965
+ /* @__PURE__ */ jsx(DialogTitle, { className: "text-base font-semibold", children: title }),
966
+ /* @__PURE__ */ jsx(DialogDescription, { className: "text-xs leading-relaxed text-muted-foreground", children: description })
967
+ ]
968
+ }
969
+ ),
970
+ /* @__PURE__ */ jsxs("div", { className: "cls_filter_dialog_body space-y-3 overflow-y-auto px-5 py-4", children: [
971
+ filterFields.length > 0 ? /* @__PURE__ */ jsx("div", { className: "cls_filter_fields_list space-y-1.5", children: filterFields.map((filterConfig) => {
972
+ const fieldConfig = getFieldConfig(filterConfig.field);
973
+ if (!fieldConfig) return null;
974
+ return /* @__PURE__ */ jsx(
975
+ FilterFieldItem,
976
+ {
977
+ filterConfig,
978
+ fieldConfig,
979
+ onValueChange: (value) => handleValueChange(filterConfig.field, value),
980
+ onOperatorChange: (operator) => handleOperatorChange(filterConfig.field, operator),
981
+ onDelete: () => handleDeleteField(filterConfig.field)
982
+ },
983
+ filterConfig.field
984
+ );
985
+ }) }) : /* @__PURE__ */ jsx("div", { className: "cls_empty_filter_fields rounded-lg border border-dashed border-border/70 bg-muted/20 px-4 py-6 text-center text-xs text-muted-foreground", children: "No filters yet. Add one below to narrow down the results." }),
964
986
  /* @__PURE__ */ jsx("div", { className: "cls_add_field_section", children: /* @__PURE__ */ jsxs(Popover, { open: isComboboxOpen, onOpenChange: setIsComboboxOpen, children: [
965
987
  /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
966
988
  Button,
967
989
  {
968
- variant: "outline",
990
+ variant: "ghost",
969
991
  role: "combobox",
970
992
  "aria-expanded": isComboboxOpen,
971
- className: "cls_add_field_combobox w-full justify-between",
993
+ disabled: availableFieldsToAdd.length === 0,
994
+ className: "cls_add_field_combobox w-full justify-start gap-2 border border-dashed border-border/70 text-sm font-medium text-muted-foreground hover:border-border hover:bg-muted/40 hover:text-foreground",
972
995
  children: [
973
- /* @__PURE__ */ jsxs("div", { className: "cls_combobox_content flex items-center", children: [
974
- /* @__PURE__ */ jsx(Plus, { className: "cls_plus_icon h-4 w-4 mr-2" }),
975
- /* @__PURE__ */ jsx("span", { children: "Add field" })
976
- ] }),
977
- /* @__PURE__ */ jsx(ChevronsUpDown, { className: "cls_chevron_icon ml-2 h-4 w-4 shrink-0 opacity-50" })
996
+ /* @__PURE__ */ jsx(Plus, { className: "cls_plus_icon h-4 w-4" }),
997
+ /* @__PURE__ */ jsx("span", { children: availableFieldsToAdd.length === 0 ? "All fields added" : "Add filter field" })
978
998
  ]
979
999
  }
980
1000
  ) }),
981
- /* @__PURE__ */ jsx(PopoverContent, { className: "cls_combobox_popover w-full p-0", children: /* @__PURE__ */ jsxs(Command, { children: [
1001
+ /* @__PURE__ */ jsx(PopoverContent, { className: "cls_combobox_popover w-[var(--radix-popover-trigger-width)] p-0", align: "start", children: /* @__PURE__ */ jsxs(Command, { children: [
982
1002
  /* @__PURE__ */ jsx(CommandInput, { placeholder: "Search fields...", className: "cls_command_input" }),
983
- /* @__PURE__ */ jsx(CommandList, { children: availableFieldsToAdd.length === 0 ? /* @__PURE__ */ jsx(CommandEmpty, { children: "No fields found." }) : /* @__PURE__ */ jsx(CommandGroup, { children: availableFieldsToAdd.map((field) => /* @__PURE__ */ jsxs(
1003
+ /* @__PURE__ */ jsx(CommandList, { children: availableFieldsToAdd.length === 0 ? /* @__PURE__ */ jsx(CommandEmpty, { children: "No fields available." }) : /* @__PURE__ */ jsx(CommandGroup, { children: availableFieldsToAdd.map((field) => /* @__PURE__ */ jsx(
984
1004
  CommandItem,
985
1005
  {
986
1006
  value: field.label,
987
1007
  onSelect: () => handleAddField(field.value),
988
1008
  className: "cls_command_item",
989
- children: [
990
- /* @__PURE__ */ jsx(
991
- Check,
992
- {
993
- className: cn(
994
- "cls_check_icon mr-2 h-4 w-4",
995
- "opacity-0"
996
- )
997
- }
998
- ),
999
- field.label
1000
- ]
1009
+ children: field.label
1001
1010
  },
1002
1011
  field.value
1003
1012
  )) }) })
1004
1013
  ] }) })
1005
- ] }) }),
1006
- filterFields.length > 0 ? /* @__PURE__ */ jsx("div", { className: "cls_filter_fields_list space-y-2", children: filterFields.map((filterConfig) => {
1007
- const fieldConfig = getFieldConfig(filterConfig.field);
1008
- if (!fieldConfig) return null;
1009
- return /* @__PURE__ */ jsx(
1010
- FilterFieldItem,
1011
- {
1012
- filterConfig,
1013
- fieldConfig,
1014
- onValueChange: (value) => handleValueChange(filterConfig.field, value),
1015
- onOperatorChange: (operator) => handleOperatorChange(filterConfig.field, operator),
1016
- onDelete: () => handleDeleteField(filterConfig.field)
1017
- },
1018
- filterConfig.field
1019
- );
1020
- }) }) : /* @__PURE__ */ jsx("div", { className: "cls_empty_filter_fields text-center py-8 text-sm text-muted-foreground", children: 'No filter fields added. Click "Add field" to add filtering criteria.' })
1014
+ ] }) })
1021
1015
  ] }),
1022
- /* @__PURE__ */ jsxs(DialogFooter, { children: [
1023
- filterFields.length > 0 && /* @__PURE__ */ jsxs(
1016
+ /* @__PURE__ */ jsxs(DialogFooter, { className: "cls_filter_dialog_footer flex flex-row items-center justify-between gap-2 border-t bg-muted/20 px-5 py-3 sm:justify-between sm:space-x-0", children: [
1017
+ /* @__PURE__ */ jsx("div", { className: "cls_footer_left", children: filterFields.length > 0 && /* @__PURE__ */ jsx(
1024
1018
  Button,
1025
1019
  {
1026
- variant: "outline",
1020
+ variant: "ghost",
1021
+ size: "sm",
1027
1022
  onClick: handleClearAll,
1028
- className: "cls_clear_all_btn",
1023
+ className: "cls_clear_all_btn text-muted-foreground hover:text-foreground",
1029
1024
  style: clearButtonStyles,
1030
- children: [
1031
- /* @__PURE__ */ jsx(X, { className: "cls_clear_all_icon h-4 w-4 mr-2" }),
1032
- "Clear All"
1033
- ]
1034
- }
1035
- ),
1036
- /* @__PURE__ */ jsx(
1037
- Button,
1038
- {
1039
- onClick: handleApply,
1040
- className: "cls_apply_btn",
1041
- style: submitButtonStyles,
1042
- children: "Apply"
1043
- }
1044
- ),
1045
- /* @__PURE__ */ jsx(
1046
- Button,
1047
- {
1048
- variant: "outline",
1049
- onClick: handleCancel,
1050
- className: "cls_cancel_btn",
1051
- style: cancelButtonStyles,
1052
- children: "Cancel"
1025
+ children: "Clear all"
1053
1026
  }
1054
- )
1027
+ ) }),
1028
+ /* @__PURE__ */ jsxs("div", { className: "cls_footer_right flex items-center gap-2", children: [
1029
+ /* @__PURE__ */ jsx(
1030
+ Button,
1031
+ {
1032
+ variant: "outline",
1033
+ size: "sm",
1034
+ onClick: handleCancel,
1035
+ className: "cls_cancel_btn",
1036
+ style: cancelButtonStyles,
1037
+ children: "Cancel"
1038
+ }
1039
+ ),
1040
+ /* @__PURE__ */ jsx(
1041
+ Button,
1042
+ {
1043
+ size: "sm",
1044
+ onClick: handleApply,
1045
+ className: "cls_apply_btn",
1046
+ style: submitButtonStyles,
1047
+ children: "Apply"
1048
+ }
1049
+ )
1050
+ ] })
1055
1051
  ] })
1056
1052
  ] })
1057
1053
  ] });
1058
1054
  }
1059
- var Switch = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1060
- SwitchPrimitives.Root,
1061
- {
1062
- className: cn(
1063
- "peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
1064
- className
1065
- ),
1066
- ...props,
1067
- ref,
1068
- children: /* @__PURE__ */ jsx(
1069
- SwitchPrimitives.Thumb,
1070
- {
1071
- className: cn(
1072
- "pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0"
1073
- )
1074
- }
1075
- )
1076
- }
1077
- ));
1078
- Switch.displayName = SwitchPrimitives.Root.displayName;
1079
- var Label2 = React27.forwardRef(
1080
- ({ className, ...props }, ref) => {
1081
- return /* @__PURE__ */ jsx(
1082
- "label",
1083
- {
1084
- ref,
1085
- className: cn(
1086
- "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
1087
- className
1088
- ),
1089
- ...props
1090
- }
1091
- );
1092
- }
1093
- );
1094
- Label2.displayName = "Label";
1095
1055
  function SortableSortFieldItem({
1096
1056
  sortConfig,
1097
1057
  fieldLabel,
1058
+ priority,
1098
1059
  onDirectionChange,
1099
1060
  onDelete
1100
1061
  }) {
@@ -1109,46 +1070,88 @@ function SortableSortFieldItem({
1109
1070
  const style = {
1110
1071
  transform: CSS.Transform.toString(transform),
1111
1072
  transition,
1112
- opacity: isDragging ? 0.5 : 1
1073
+ opacity: isDragging ? 0.6 : 1,
1074
+ zIndex: isDragging ? 10 : void 0
1113
1075
  };
1114
1076
  return /* @__PURE__ */ jsxs(
1115
1077
  "div",
1116
1078
  {
1117
1079
  ref: setNodeRef,
1118
1080
  style,
1119
- className: "cls_sortable_sort_field_item flex items-center gap-3 p-3 border rounded-md bg-card",
1081
+ className: cn(
1082
+ "cls_sortable_sort_field_item group flex items-center gap-2.5 rounded-lg border border-border/70 bg-card pl-1.5 pr-2 py-2 transition-shadow",
1083
+ isDragging ? "shadow-md" : "hover:border-border"
1084
+ ),
1120
1085
  children: [
1121
1086
  /* @__PURE__ */ jsx(
1122
- "div",
1087
+ "button",
1123
1088
  {
1089
+ type: "button",
1124
1090
  ...attributes,
1125
1091
  ...listeners,
1126
- className: "cls_drag_handle cursor-grab active:cursor-grabbing text-muted-foreground hover:text-foreground",
1092
+ className: "cls_drag_handle flex h-7 w-5 shrink-0 cursor-grab items-center justify-center rounded text-muted-foreground/60 hover:text-foreground active:cursor-grabbing",
1093
+ "aria-label": `Reorder ${fieldLabel}`,
1127
1094
  children: /* @__PURE__ */ jsx(GripVertical, { className: "cls_drag_icon h-4 w-4" })
1128
1095
  }
1129
1096
  ),
1130
- /* @__PURE__ */ jsx("span", { className: "cls_field_label flex-1 text-sm font-medium", children: fieldLabel }),
1131
- /* @__PURE__ */ jsxs("div", { className: "cls_direction_control flex items-center gap-2", children: [
1132
- /* @__PURE__ */ jsx(Label2, { htmlFor: `switch-${sortConfig.field}`, className: "cls_direction_label text-xs text-muted-foreground", children: sortConfig.direction === "asc" ? "Ascending" : "Descending" }),
1133
- /* @__PURE__ */ jsx(
1134
- Switch,
1135
- {
1136
- id: `switch-${sortConfig.field}`,
1137
- checked: sortConfig.direction === "desc",
1138
- onCheckedChange: (checked) => onDirectionChange(checked ? "desc" : "asc"),
1139
- "aria-label": `Toggle sort direction for ${fieldLabel}`
1140
- }
1141
- )
1142
- ] }),
1097
+ /* @__PURE__ */ jsx(
1098
+ "span",
1099
+ {
1100
+ className: "cls_priority_badge inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-muted text-[10px] font-semibold tabular-nums text-muted-foreground",
1101
+ "aria-label": `Sort priority ${priority}`,
1102
+ children: priority
1103
+ }
1104
+ ),
1105
+ /* @__PURE__ */ jsx("span", { className: "cls_field_label flex-1 truncate text-sm font-medium text-foreground", children: fieldLabel }),
1106
+ /* @__PURE__ */ jsxs(
1107
+ "div",
1108
+ {
1109
+ role: "radiogroup",
1110
+ "aria-label": `Sort direction for ${fieldLabel}`,
1111
+ className: "cls_direction_control inline-flex shrink-0 items-center rounded-md border border-border/70 bg-muted/40 p-0.5",
1112
+ children: [
1113
+ /* @__PURE__ */ jsxs(
1114
+ "button",
1115
+ {
1116
+ type: "button",
1117
+ role: "radio",
1118
+ "aria-checked": sortConfig.direction === "asc",
1119
+ "data-active": sortConfig.direction === "asc",
1120
+ onClick: () => onDirectionChange("asc"),
1121
+ className: "cls_dir_asc inline-flex items-center gap-1 rounded px-2 py-1 text-xs font-medium text-muted-foreground transition-colors data-[active=true]:bg-background data-[active=true]:text-foreground data-[active=true]:shadow-sm hover:text-foreground",
1122
+ children: [
1123
+ /* @__PURE__ */ jsx(ArrowUp, { className: "h-3 w-3" }),
1124
+ "Asc"
1125
+ ]
1126
+ }
1127
+ ),
1128
+ /* @__PURE__ */ jsxs(
1129
+ "button",
1130
+ {
1131
+ type: "button",
1132
+ role: "radio",
1133
+ "aria-checked": sortConfig.direction === "desc",
1134
+ "data-active": sortConfig.direction === "desc",
1135
+ onClick: () => onDirectionChange("desc"),
1136
+ className: "cls_dir_desc inline-flex items-center gap-1 rounded px-2 py-1 text-xs font-medium text-muted-foreground transition-colors data-[active=true]:bg-background data-[active=true]:text-foreground data-[active=true]:shadow-sm hover:text-foreground",
1137
+ children: [
1138
+ /* @__PURE__ */ jsx(ArrowDown, { className: "h-3 w-3" }),
1139
+ "Desc"
1140
+ ]
1141
+ }
1142
+ )
1143
+ ]
1144
+ }
1145
+ ),
1143
1146
  /* @__PURE__ */ jsx(
1144
1147
  Button,
1145
1148
  {
1146
1149
  variant: "ghost",
1147
1150
  size: "sm",
1148
1151
  onClick: onDelete,
1149
- className: "cls_delete_btn h-8 w-8 p-0 text-destructive hover:text-destructive",
1152
+ className: "cls_delete_btn h-7 w-7 shrink-0 p-0 text-muted-foreground/60 hover:bg-destructive/10 hover:text-destructive",
1150
1153
  "aria-label": `Remove ${fieldLabel} from sort`,
1151
- children: /* @__PURE__ */ jsx(Trash2, { className: "cls_delete_icon h-4 w-4" })
1154
+ children: /* @__PURE__ */ jsx(X, { className: "cls_delete_icon h-3.5 w-3.5" })
1152
1155
  }
1153
1156
  )
1154
1157
  ]
@@ -1160,7 +1163,7 @@ function HazoUiMultiSortDialog({
1160
1163
  onSortChange,
1161
1164
  initialSortFields = [],
1162
1165
  title = "Sort",
1163
- description = "Add multiple fields to sort by and reorder them. Use the switch to toggle between ascending and descending.",
1166
+ description = "Add fields to sort by, drag to reorder, toggle ascending or descending.",
1164
1167
  headerBackgroundColor,
1165
1168
  headerTextColor,
1166
1169
  submitButtonBackgroundColor,
@@ -1205,7 +1208,7 @@ function HazoUiMultiSortDialog({
1205
1208
  const [sortFields, setSortFields] = useState(initialSortFields);
1206
1209
  const [isComboboxOpen, setIsComboboxOpen] = useState(false);
1207
1210
  const sensors = useSensors(
1208
- useSensor(PointerSensor),
1211
+ useSensor(PointerSensor, { activationConstraint: { distance: 4 } }),
1209
1212
  useSensor(KeyboardSensor, {
1210
1213
  coordinateGetter: sortableKeyboardCoordinates
1211
1214
  })
@@ -1219,11 +1222,7 @@ function HazoUiMultiSortDialog({
1219
1222
  if (sortFields.some((sf) => sf.field === fieldValue)) {
1220
1223
  return;
1221
1224
  }
1222
- const newField = {
1223
- field: fieldValue,
1224
- direction: "asc"
1225
- };
1226
- setSortFields([...sortFields, newField]);
1225
+ setSortFields([...sortFields, { field: fieldValue, direction: "asc" }]);
1227
1226
  setIsComboboxOpen(false);
1228
1227
  };
1229
1228
  const handleDeleteField = (fieldValue) => {
@@ -1238,9 +1237,7 @@ function HazoUiMultiSortDialog({
1238
1237
  };
1239
1238
  const handleDragEnd = (event) => {
1240
1239
  const { active, over } = event;
1241
- if (!over || active.id === over.id) {
1242
- return;
1243
- }
1240
+ if (!over || active.id === over.id) return;
1244
1241
  const oldIndex = sortFields.findIndex((sf) => sf.field === active.id);
1245
1242
  const newIndex = sortFields.findIndex((sf) => sf.field === over.id);
1246
1243
  if (oldIndex !== -1 && newIndex !== -1) {
@@ -1266,7 +1263,7 @@ function HazoUiMultiSortDialog({
1266
1263
  };
1267
1264
  const hasActiveSorts = initialSortFields.length > 0;
1268
1265
  const tooltipContent = hasActiveSorts ? /* @__PURE__ */ jsxs("div", { className: "cls_sort_tooltip_content space-y-1", children: [
1269
- /* @__PURE__ */ jsx("div", { className: "cls_tooltip_title text-xs font-semibold mb-1", children: "Active Sorts:" }),
1266
+ /* @__PURE__ */ jsx("div", { className: "cls_tooltip_title text-xs font-semibold mb-1", children: "Active sorts" }),
1270
1267
  initialSortFields.map((sortConfig, index) => /* @__PURE__ */ jsxs("div", { className: "cls_tooltip_item text-xs", children: [
1271
1268
  index + 1,
1272
1269
  ". ",
@@ -1295,61 +1292,27 @@ function HazoUiMultiSortDialog({
1295
1292
  )
1296
1293
  }
1297
1294
  ),
1298
- "Sort"
1295
+ "Sort",
1296
+ hasActiveSorts && /* @__PURE__ */ jsx("span", { className: "cls_sort_count ml-2 inline-flex h-4 min-w-4 items-center justify-center rounded-full bg-blue-600 px-1 text-[10px] font-semibold text-white", children: initialSortFields.length })
1299
1297
  ]
1300
1298
  }
1301
1299
  ) }) }),
1302
1300
  /* @__PURE__ */ jsx(TooltipContent, { children: tooltipContent })
1303
1301
  ] }) }),
1304
- /* @__PURE__ */ jsxs(DialogContent, { className: "cls_sort_dialog_content max-w-lg", children: [
1305
- /* @__PURE__ */ jsxs(DialogHeader, { style: headerStyles, children: [
1306
- /* @__PURE__ */ jsx(DialogTitle, { children: title }),
1307
- /* @__PURE__ */ jsx(DialogDescription, { children: description })
1308
- ] }),
1309
- /* @__PURE__ */ jsxs("div", { className: "cls_sort_dialog_body space-y-4 py-4", children: [
1310
- /* @__PURE__ */ jsx("div", { className: "cls_add_field_section", children: /* @__PURE__ */ jsxs(Popover, { open: isComboboxOpen, onOpenChange: setIsComboboxOpen, children: [
1311
- /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
1312
- Button,
1313
- {
1314
- variant: "outline",
1315
- role: "combobox",
1316
- "aria-expanded": isComboboxOpen,
1317
- className: "cls_add_field_combobox w-full justify-between",
1318
- children: [
1319
- /* @__PURE__ */ jsxs("div", { className: "cls_combobox_content flex items-center", children: [
1320
- /* @__PURE__ */ jsx(Plus, { className: "cls_plus_icon h-4 w-4 mr-2" }),
1321
- /* @__PURE__ */ jsx("span", { children: "Add field" })
1322
- ] }),
1323
- /* @__PURE__ */ jsx(ChevronsUpDown, { className: "cls_chevron_icon ml-2 h-4 w-4 shrink-0 opacity-50" })
1324
- ]
1325
- }
1326
- ) }),
1327
- /* @__PURE__ */ jsx(PopoverContent, { className: "cls_combobox_popover w-full p-0", children: /* @__PURE__ */ jsxs(Command, { children: [
1328
- /* @__PURE__ */ jsx(CommandInput, { placeholder: "Search fields...", className: "cls_command_input" }),
1329
- /* @__PURE__ */ jsx(CommandList, { children: availableFieldsToAdd.length === 0 ? /* @__PURE__ */ jsx(CommandEmpty, { children: "No fields found." }) : /* @__PURE__ */ jsx(CommandGroup, { children: availableFieldsToAdd.map((field) => /* @__PURE__ */ jsxs(
1330
- CommandItem,
1331
- {
1332
- value: field.label,
1333
- onSelect: () => handleAddField(field.value),
1334
- className: "cls_command_item",
1335
- children: [
1336
- /* @__PURE__ */ jsx(
1337
- Check,
1338
- {
1339
- className: cn(
1340
- "cls_check_icon mr-2 h-4 w-4",
1341
- "opacity-0"
1342
- )
1343
- }
1344
- ),
1345
- field.label
1346
- ]
1347
- },
1348
- field.value
1349
- )) }) })
1350
- ] }) })
1351
- ] }) }),
1352
- sortFields.length > 0 ? /* @__PURE__ */ jsx("div", { className: "cls_sort_fields_list space-y-2", children: /* @__PURE__ */ jsx(
1302
+ /* @__PURE__ */ jsxs(DialogContent, { className: "cls_sort_dialog_content max-w-lg gap-0 p-0 sm:rounded-xl", children: [
1303
+ /* @__PURE__ */ jsxs(
1304
+ DialogHeader,
1305
+ {
1306
+ className: "cls_sort_dialog_header space-y-1 border-b px-5 py-4 text-left",
1307
+ style: headerStyles,
1308
+ children: [
1309
+ /* @__PURE__ */ jsx(DialogTitle, { className: "text-base font-semibold", children: title }),
1310
+ /* @__PURE__ */ jsx(DialogDescription, { className: "text-xs leading-relaxed text-muted-foreground", children: description })
1311
+ ]
1312
+ }
1313
+ ),
1314
+ /* @__PURE__ */ jsxs("div", { className: "cls_sort_dialog_body space-y-3 px-5 py-4", children: [
1315
+ sortFields.length > 0 ? /* @__PURE__ */ jsx("div", { className: "cls_sort_fields_list space-y-1.5", children: /* @__PURE__ */ jsx(
1353
1316
  DndContext,
1354
1317
  {
1355
1318
  sensors,
@@ -1360,11 +1323,12 @@ function HazoUiMultiSortDialog({
1360
1323
  {
1361
1324
  items: sortFields.map((sf) => sf.field),
1362
1325
  strategy: verticalListSortingStrategy,
1363
- children: sortFields.map((sortConfig) => /* @__PURE__ */ jsx(
1326
+ children: sortFields.map((sortConfig, idx) => /* @__PURE__ */ jsx(
1364
1327
  SortableSortFieldItem,
1365
1328
  {
1366
1329
  sortConfig,
1367
1330
  fieldLabel: getFieldLabel(sortConfig.field),
1331
+ priority: idx + 1,
1368
1332
  onDirectionChange: (direction) => handleDirectionChange(sortConfig.field, direction),
1369
1333
  onDelete: () => handleDeleteField(sortConfig.field)
1370
1334
  },
@@ -1373,46 +1337,77 @@ function HazoUiMultiSortDialog({
1373
1337
  }
1374
1338
  )
1375
1339
  }
1376
- ) }) : /* @__PURE__ */ jsx("div", { className: "cls_empty_sort_fields text-center py-8 text-sm text-muted-foreground", children: 'No sort fields added. Click "Add field" to add sorting criteria.' })
1340
+ ) }) : /* @__PURE__ */ jsx("div", { className: "cls_empty_sort_fields rounded-lg border border-dashed border-border/70 bg-muted/20 px-4 py-6 text-center text-xs text-muted-foreground", children: "No sort fields yet. Add one below to start ordering rows." }),
1341
+ /* @__PURE__ */ jsx("div", { className: "cls_add_field_section", children: /* @__PURE__ */ jsxs(Popover, { open: isComboboxOpen, onOpenChange: setIsComboboxOpen, children: [
1342
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
1343
+ Button,
1344
+ {
1345
+ variant: "ghost",
1346
+ role: "combobox",
1347
+ "aria-expanded": isComboboxOpen,
1348
+ disabled: availableFieldsToAdd.length === 0,
1349
+ className: "cls_add_field_combobox w-full justify-start gap-2 border border-dashed border-border/70 text-sm font-medium text-muted-foreground hover:border-border hover:bg-muted/40 hover:text-foreground",
1350
+ children: [
1351
+ /* @__PURE__ */ jsx(Plus, { className: "cls_plus_icon h-4 w-4" }),
1352
+ /* @__PURE__ */ jsx("span", { children: availableFieldsToAdd.length === 0 ? "All fields added" : "Add sort field" })
1353
+ ]
1354
+ }
1355
+ ) }),
1356
+ /* @__PURE__ */ jsx(PopoverContent, { className: "cls_combobox_popover w-[var(--radix-popover-trigger-width)] p-0", align: "start", children: /* @__PURE__ */ jsxs(Command, { children: [
1357
+ /* @__PURE__ */ jsx(CommandInput, { placeholder: "Search fields...", className: "cls_command_input" }),
1358
+ /* @__PURE__ */ jsx(CommandList, { children: availableFieldsToAdd.length === 0 ? /* @__PURE__ */ jsx(CommandEmpty, { children: "No fields available." }) : /* @__PURE__ */ jsx(CommandGroup, { children: availableFieldsToAdd.map((field) => /* @__PURE__ */ jsx(
1359
+ CommandItem,
1360
+ {
1361
+ value: field.label,
1362
+ onSelect: () => handleAddField(field.value),
1363
+ className: "cls_command_item",
1364
+ children: field.label
1365
+ },
1366
+ field.value
1367
+ )) }) })
1368
+ ] }) })
1369
+ ] }) })
1377
1370
  ] }),
1378
- /* @__PURE__ */ jsxs(DialogFooter, { children: [
1379
- sortFields.length > 0 && /* @__PURE__ */ jsxs(
1371
+ /* @__PURE__ */ jsxs(DialogFooter, { className: "cls_sort_dialog_footer flex flex-row items-center justify-between gap-2 border-t bg-muted/20 px-5 py-3 sm:justify-between sm:space-x-0", children: [
1372
+ /* @__PURE__ */ jsx("div", { className: "cls_footer_left", children: sortFields.length > 0 && /* @__PURE__ */ jsx(
1380
1373
  Button,
1381
1374
  {
1382
- variant: "outline",
1375
+ variant: "ghost",
1376
+ size: "sm",
1383
1377
  onClick: handleClearAll,
1384
- className: "cls_clear_all_btn",
1378
+ className: "cls_clear_all_btn text-muted-foreground hover:text-foreground",
1385
1379
  style: clearButtonStyles,
1386
- children: [
1387
- /* @__PURE__ */ jsx(Trash2, { className: "cls_clear_all_icon h-4 w-4 mr-2" }),
1388
- "Clear All"
1389
- ]
1390
- }
1391
- ),
1392
- /* @__PURE__ */ jsx(
1393
- Button,
1394
- {
1395
- onClick: handleApply,
1396
- className: "cls_apply_btn",
1397
- style: submitButtonStyles,
1398
- children: "Apply"
1399
- }
1400
- ),
1401
- /* @__PURE__ */ jsx(
1402
- Button,
1403
- {
1404
- variant: "outline",
1405
- onClick: handleCancel,
1406
- className: "cls_cancel_btn",
1407
- style: cancelButtonStyles,
1408
- children: "Cancel"
1380
+ children: "Clear all"
1409
1381
  }
1410
- )
1382
+ ) }),
1383
+ /* @__PURE__ */ jsxs("div", { className: "cls_footer_right flex items-center gap-2", children: [
1384
+ /* @__PURE__ */ jsx(
1385
+ Button,
1386
+ {
1387
+ variant: "outline",
1388
+ size: "sm",
1389
+ onClick: handleCancel,
1390
+ className: "cls_cancel_btn",
1391
+ style: cancelButtonStyles,
1392
+ children: "Cancel"
1393
+ }
1394
+ ),
1395
+ /* @__PURE__ */ jsx(
1396
+ Button,
1397
+ {
1398
+ size: "sm",
1399
+ onClick: handleApply,
1400
+ className: "cls_apply_btn",
1401
+ style: submitButtonStyles,
1402
+ children: "Apply"
1403
+ }
1404
+ )
1405
+ ] })
1411
1406
  ] })
1412
1407
  ] })
1413
1408
  ] });
1414
1409
  }
1415
- var RadioGroup = React27.forwardRef(({ className, ...props }, ref) => {
1410
+ var RadioGroup = React25.forwardRef(({ className, ...props }, ref) => {
1416
1411
  return /* @__PURE__ */ jsx(
1417
1412
  RadioGroupPrimitive.Root,
1418
1413
  {
@@ -1423,7 +1418,7 @@ var RadioGroup = React27.forwardRef(({ className, ...props }, ref) => {
1423
1418
  );
1424
1419
  });
1425
1420
  RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
1426
- var RadioGroupItem = React27.forwardRef(({ className, ...props }, ref) => {
1421
+ var RadioGroupItem = React25.forwardRef(({ className, ...props }, ref) => {
1427
1422
  return /* @__PURE__ */ jsx(
1428
1423
  RadioGroupPrimitive.Item,
1429
1424
  {
@@ -1880,7 +1875,7 @@ function filterInputValue(value, input_type, num_decimals) {
1880
1875
  }
1881
1876
  }
1882
1877
  }
1883
- var HazoUiFlexInput = React27.forwardRef(
1878
+ var HazoUiFlexInput = React25.forwardRef(
1884
1879
  ({
1885
1880
  className,
1886
1881
  input_type = "mixed",
@@ -1897,13 +1892,13 @@ var HazoUiFlexInput = React27.forwardRef(
1897
1892
  onBlur,
1898
1893
  ...props
1899
1894
  }, ref) => {
1900
- const [internalValue, setInternalValue] = React27.useState(
1895
+ const [internalValue, setInternalValue] = React25.useState(
1901
1896
  typeof controlledValue === "string" ? controlledValue : typeof controlledValue === "number" ? String(controlledValue) : ""
1902
1897
  );
1903
- const [errorMessage, setErrorMessage] = React27.useState();
1898
+ const [errorMessage, setErrorMessage] = React25.useState();
1904
1899
  const isControlled = controlledValue !== void 0;
1905
1900
  const currentValue = isControlled ? typeof controlledValue === "string" ? controlledValue : String(controlledValue || "") : internalValue;
1906
- React27.useEffect(() => {
1901
+ React25.useEffect(() => {
1907
1902
  if (isControlled) {
1908
1903
  const newValue = typeof controlledValue === "string" ? controlledValue : String(controlledValue || "");
1909
1904
  if (newValue !== internalValue) {
@@ -1983,7 +1978,7 @@ var HazoUiFlexInput = React27.forwardRef(
1983
1978
  }
1984
1979
  );
1985
1980
  HazoUiFlexInput.displayName = "HazoUiFlexInput";
1986
- var ToolbarButton = React27.forwardRef(
1981
+ var ToolbarButton = React25.forwardRef(
1987
1982
  ({ onClick, is_active = false, disabled = false, tooltip, className, children }, ref) => {
1988
1983
  const button = /* @__PURE__ */ jsx(
1989
1984
  "button",
@@ -2302,7 +2297,7 @@ var getRelativePosition = (node, event) => {
2302
2297
  };
2303
2298
  };
2304
2299
  var _excluded = ["prefixCls", "className", "onMove", "onDown"];
2305
- var Interactive = /* @__PURE__ */ React27__default.forwardRef((props, ref) => {
2300
+ var Interactive = /* @__PURE__ */ React25__default.forwardRef((props, ref) => {
2306
2301
  var {
2307
2302
  prefixCls = "w-color-interactive",
2308
2303
  className,
@@ -2401,7 +2396,7 @@ var Pointer = (_ref) => {
2401
2396
  }), [top, left, color2, className, prefixCls]);
2402
2397
  };
2403
2398
  var _excluded2 = ["prefixCls", "radius", "pointer", "className", "hue", "style", "hsva", "onChange"];
2404
- var Saturation = /* @__PURE__ */ React27__default.forwardRef((props, ref) => {
2399
+ var Saturation = /* @__PURE__ */ React25__default.forwardRef((props, ref) => {
2405
2400
  var _hsva$h;
2406
2401
  var {
2407
2402
  prefixCls = "w-color-saturation",
@@ -2553,7 +2548,7 @@ var Pointer2 = (_ref) => {
2553
2548
  };
2554
2549
  var _excluded4 = ["prefixCls", "className", "hsva", "background", "bgProps", "innerProps", "pointerProps", "radius", "width", "height", "direction", "style", "onChange", "pointer"];
2555
2550
  var BACKGROUND_IMG = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAMUlEQVQ4T2NkYGAQYcAP3uCTZhw1gGGYhAGBZIA/nYDCgBDAm9BGDWAAJyRCgLaBCAAgXwixzAS0pgAAAABJRU5ErkJggg==";
2556
- var Alpha = /* @__PURE__ */ React27__default.forwardRef((props, ref) => {
2551
+ var Alpha = /* @__PURE__ */ React25__default.forwardRef((props, ref) => {
2557
2552
  var {
2558
2553
  prefixCls = "w-color-alpha",
2559
2554
  className,
@@ -2687,7 +2682,7 @@ var import_objectWithoutPropertiesLoose5 = __toESM(require_objectWithoutProperti
2687
2682
  var _excluded5 = ["prefixCls", "placement", "label", "value", "className", "style", "labelStyle", "inputStyle", "onChange", "onBlur", "renderInput"];
2688
2683
  var validHex2 = (hex) => /^#?([A-Fa-f0-9]{3,4}){1,2}$/.test(hex);
2689
2684
  var getNumberValue = (value) => Number(String(value).replace(/%/g, ""));
2690
- var EditableInput = /* @__PURE__ */ React27__default.forwardRef((props, ref) => {
2685
+ var EditableInput = /* @__PURE__ */ React25__default.forwardRef((props, ref) => {
2691
2686
  var {
2692
2687
  prefixCls = "w-color-editable-input",
2693
2688
  placement = "bottom",
@@ -2792,7 +2787,7 @@ var esm_default4 = EditableInput;
2792
2787
  var import_extends7 = __toESM(require_extends());
2793
2788
  var import_objectWithoutPropertiesLoose6 = __toESM(require_objectWithoutPropertiesLoose());
2794
2789
  var _excluded6 = ["prefixCls", "hsva", "placement", "rProps", "gProps", "bProps", "aProps", "className", "style", "onChange"];
2795
- var EditableInputRGBA = /* @__PURE__ */ React27__default.forwardRef((props, ref) => {
2790
+ var EditableInputRGBA = /* @__PURE__ */ React25__default.forwardRef((props, ref) => {
2796
2791
  var {
2797
2792
  prefixCls = "w-color-editable-input-rgba",
2798
2793
  hsva,
@@ -2915,7 +2910,7 @@ var esm_default5 = EditableInputRGBA;
2915
2910
  var import_extends8 = __toESM(require_extends());
2916
2911
  var import_objectWithoutPropertiesLoose7 = __toESM(require_objectWithoutPropertiesLoose());
2917
2912
  var _excluded7 = ["prefixCls", "className", "hue", "onChange", "direction"];
2918
- var Hue = /* @__PURE__ */ React27__default.forwardRef((props, ref) => {
2913
+ var Hue = /* @__PURE__ */ React25__default.forwardRef((props, ref) => {
2919
2914
  var {
2920
2915
  prefixCls = "w-color-hue",
2921
2916
  className,
@@ -2949,7 +2944,7 @@ var esm_default6 = Hue;
2949
2944
  var import_extends9 = __toESM(require_extends());
2950
2945
  var import_objectWithoutPropertiesLoose8 = __toESM(require_objectWithoutPropertiesLoose());
2951
2946
  var _excluded8 = ["prefixCls", "className", "color", "colors", "style", "rectProps", "onChange", "addonAfter", "addonBefore", "rectRender"];
2952
- var Swatch = /* @__PURE__ */ React27__default.forwardRef((props, ref) => {
2947
+ var Swatch = /* @__PURE__ */ React25__default.forwardRef((props, ref) => {
2953
2948
  var {
2954
2949
  prefixCls = "w-color-swatch",
2955
2950
  className,
@@ -2986,7 +2981,7 @@ var Swatch = /* @__PURE__ */ React27__default.forwardRef((props, ref) => {
2986
2981
  flexWrap: "wrap",
2987
2982
  position: "relative"
2988
2983
  }, style),
2989
- children: [addonBefore && /* @__PURE__ */ React27__default.isValidElement(addonBefore) && addonBefore, colors && Array.isArray(colors) && colors.map((item, idx) => {
2984
+ children: [addonBefore && /* @__PURE__ */ React25__default.isValidElement(addonBefore) && addonBefore, colors && Array.isArray(colors) && colors.map((item, idx) => {
2990
2985
  var title = "";
2991
2986
  var background = "";
2992
2987
  if (typeof item === "string") {
@@ -3012,7 +3007,7 @@ var Swatch = /* @__PURE__ */ React27__default.forwardRef((props, ref) => {
3012
3007
  children: render
3013
3008
  }, idx);
3014
3009
  }
3015
- var child = rectProps.children && /* @__PURE__ */ React27__default.isValidElement(rectProps.children) ? /* @__PURE__ */ React27__default.cloneElement(rectProps.children, {
3010
+ var child = rectProps.children && /* @__PURE__ */ React25__default.isValidElement(rectProps.children) ? /* @__PURE__ */ React25__default.cloneElement(rectProps.children, {
3016
3011
  color: background,
3017
3012
  checked
3018
3013
  }) : null;
@@ -3026,7 +3021,7 @@ var Swatch = /* @__PURE__ */ React27__default.forwardRef((props, ref) => {
3026
3021
  background
3027
3022
  })
3028
3023
  }), idx);
3029
- }), addonAfter && /* @__PURE__ */ React27__default.isValidElement(addonAfter) && addonAfter]
3024
+ }), addonAfter && /* @__PURE__ */ React25__default.isValidElement(addonAfter) && addonAfter]
3030
3025
  }));
3031
3026
  });
3032
3027
  Swatch.displayName = "Swatch";
@@ -3045,7 +3040,7 @@ var Bar = (props) => /* @__PURE__ */ jsx("div", {
3045
3040
  backgroundColor: "#fff"
3046
3041
  }
3047
3042
  });
3048
- var Sketch = /* @__PURE__ */ React27__default.forwardRef((props, ref) => {
3043
+ var Sketch = /* @__PURE__ */ React25__default.forwardRef((props, ref) => {
3049
3044
  var {
3050
3045
  prefixCls = "w-color-sketch",
3051
3046
  className,
@@ -3296,19 +3291,19 @@ var Toolbar = ({
3296
3291
  on_attachments_change,
3297
3292
  disabled = false
3298
3293
  }) => {
3299
- const [link_url, set_link_url] = React27.useState("https://");
3300
- const [link_popover_open, set_link_popover_open] = React27.useState(false);
3301
- const [text_color_open, set_text_color_open] = React27.useState(false);
3302
- const [highlight_color_open, set_highlight_color_open] = React27.useState(false);
3303
- const [variables_menu_open, set_variables_menu_open] = React27.useState(false);
3304
- const [table_menu_open, set_table_menu_open] = React27.useState(false);
3305
- const [text_color, set_text_color] = React27.useState("#000000");
3306
- const [highlight_color, set_highlight_color] = React27.useState("#ffff00");
3307
- const [table_rows, set_table_rows] = React27.useState(3);
3308
- const [table_cols, set_table_cols] = React27.useState(3);
3309
- const [hovered_cell, set_hovered_cell] = React27.useState(null);
3310
- const file_input_ref = React27.useRef(null);
3311
- const image_input_ref = React27.useRef(null);
3294
+ const [link_url, set_link_url] = React25.useState("https://");
3295
+ const [link_popover_open, set_link_popover_open] = React25.useState(false);
3296
+ const [text_color_open, set_text_color_open] = React25.useState(false);
3297
+ const [highlight_color_open, set_highlight_color_open] = React25.useState(false);
3298
+ const [variables_menu_open, set_variables_menu_open] = React25.useState(false);
3299
+ const [table_menu_open, set_table_menu_open] = React25.useState(false);
3300
+ const [text_color, set_text_color] = React25.useState("#000000");
3301
+ const [highlight_color, set_highlight_color] = React25.useState("#ffff00");
3302
+ const [table_rows, set_table_rows] = React25.useState(3);
3303
+ const [table_cols, set_table_cols] = React25.useState(3);
3304
+ const [hovered_cell, set_hovered_cell] = React25.useState(null);
3305
+ const file_input_ref = React25.useRef(null);
3306
+ const image_input_ref = React25.useRef(null);
3312
3307
  if (!editor) {
3313
3308
  return null;
3314
3309
  }
@@ -4241,7 +4236,7 @@ var VariableExtension = Node.create({
4241
4236
  }
4242
4237
  });
4243
4238
  var Tabs = TabsPrimitive.Root;
4244
- var TabsList = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4239
+ var TabsList = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4245
4240
  TabsPrimitive.List,
4246
4241
  {
4247
4242
  ref,
@@ -4253,7 +4248,7 @@ var TabsList = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__
4253
4248
  }
4254
4249
  ));
4255
4250
  TabsList.displayName = TabsPrimitive.List.displayName;
4256
- var TabsTrigger = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4251
+ var TabsTrigger = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4257
4252
  TabsPrimitive.Trigger,
4258
4253
  {
4259
4254
  ref,
@@ -4265,7 +4260,7 @@ var TabsTrigger = React27.forwardRef(({ className, ...props }, ref) => /* @__PUR
4265
4260
  }
4266
4261
  ));
4267
4262
  TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
4268
- var TabsContent = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4263
+ var TabsContent = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4269
4264
  TabsPrimitive.Content,
4270
4265
  {
4271
4266
  ref,
@@ -4300,14 +4295,14 @@ var HazoUiRte = ({
4300
4295
  className,
4301
4296
  show_output_viewer = false
4302
4297
  }) => {
4303
- const [attachments, set_attachments] = React27.useState(
4298
+ const [attachments, set_attachments] = React25.useState(
4304
4299
  initial_attachments
4305
4300
  );
4306
- const [active_tab, set_active_tab] = React27.useState("html");
4301
+ const [active_tab, set_active_tab] = React25.useState("html");
4307
4302
  const is_view_only = active_tab !== "html";
4308
- const attachments_ref = React27.useRef(attachments);
4303
+ const attachments_ref = React25.useRef(attachments);
4309
4304
  attachments_ref.current = attachments;
4310
- const debounced_on_change = React27.useMemo(
4305
+ const debounced_on_change = React25.useMemo(
4311
4306
  () => debounce_fn((output) => {
4312
4307
  if (on_change) {
4313
4308
  on_change(output);
@@ -4406,7 +4401,7 @@ var HazoUiRte = ({
4406
4401
  debounced_on_change(output);
4407
4402
  }
4408
4403
  });
4409
- React27.useEffect(() => {
4404
+ React25.useEffect(() => {
4410
4405
  if (editor && html !== void 0) {
4411
4406
  const current_html = editor.getHTML();
4412
4407
  if (html !== current_html && !editor.isFocused) {
@@ -4414,21 +4409,21 @@ var HazoUiRte = ({
4414
4409
  }
4415
4410
  }
4416
4411
  }, [html, editor]);
4417
- React27.useEffect(() => {
4412
+ React25.useEffect(() => {
4418
4413
  if (editor) {
4419
4414
  editor.setEditable(!disabled);
4420
4415
  }
4421
4416
  }, [disabled, editor]);
4422
- const attachments_from_props_ref = React27.useRef(false);
4423
- const prev_initial_attachments_ref = React27.useRef(initial_attachments);
4424
- React27.useEffect(() => {
4417
+ const attachments_from_props_ref = React25.useRef(false);
4418
+ const prev_initial_attachments_ref = React25.useRef(initial_attachments);
4419
+ React25.useEffect(() => {
4425
4420
  if (JSON.stringify(initial_attachments) !== JSON.stringify(prev_initial_attachments_ref.current)) {
4426
4421
  prev_initial_attachments_ref.current = initial_attachments;
4427
4422
  attachments_from_props_ref.current = true;
4428
4423
  set_attachments(initial_attachments);
4429
4424
  }
4430
4425
  }, [initial_attachments]);
4431
- React27.useEffect(() => {
4426
+ React25.useEffect(() => {
4432
4427
  if (attachments_from_props_ref.current) {
4433
4428
  attachments_from_props_ref.current = false;
4434
4429
  return;
@@ -4930,12 +4925,12 @@ var CommandPopover = ({
4930
4925
  on_selection_change: _on_selection_change,
4931
4926
  prefix_color
4932
4927
  }) => {
4933
- const container_ref = React27.useRef(null);
4934
- const grouped_commands = React27.useMemo(
4928
+ const container_ref = React25.useRef(null);
4929
+ const grouped_commands = React25.useMemo(
4935
4930
  () => group_commands(commands),
4936
4931
  [commands]
4937
4932
  );
4938
- React27.useEffect(() => {
4933
+ React25.useEffect(() => {
4939
4934
  const handle_click_outside = (e) => {
4940
4935
  if (container_ref.current && !container_ref.current.contains(e.target)) {
4941
4936
  on_close();
@@ -4948,8 +4943,8 @@ var CommandPopover = ({
4948
4943
  };
4949
4944
  }
4950
4945
  }, [is_open, on_close]);
4951
- const [mounted, set_mounted] = React27.useState(false);
4952
- React27.useEffect(() => {
4946
+ const [mounted, set_mounted] = React25.useState(false);
4947
+ React25.useEffect(() => {
4953
4948
  set_mounted(true);
4954
4949
  }, []);
4955
4950
  if (!is_open || !mounted) return null;
@@ -5259,21 +5254,21 @@ var HazoUiTextbox = ({
5259
5254
  on_command_change,
5260
5255
  on_command_remove
5261
5256
  }) => {
5262
- const generated_instance_id = React27.useId();
5257
+ const generated_instance_id = React25.useId();
5263
5258
  const instance_id = provided_instance_id || generated_instance_id;
5264
- const [suggestion_state, set_suggestion_state] = React27.useState(null);
5265
- const [selected_index, set_selected_index] = React27.useState(0);
5266
- const [popover_position, set_popover_position] = React27.useState({ top: 0, left: 0 });
5267
- const [edit_context, set_edit_context] = React27.useState(null);
5268
- const [edit_selected_index, set_edit_selected_index] = React27.useState(0);
5259
+ const [suggestion_state, set_suggestion_state] = React25.useState(null);
5260
+ const [selected_index, set_selected_index] = React25.useState(0);
5261
+ const [popover_position, set_popover_position] = React25.useState({ top: 0, left: 0 });
5262
+ const [edit_context, set_edit_context] = React25.useState(null);
5263
+ const [edit_selected_index, set_edit_selected_index] = React25.useState(0);
5269
5264
  const is_controlled = value !== void 0;
5270
- const editor_container_ref = React27.useRef(null);
5271
- const edit_popover_ref = React27.useRef(null);
5272
- const [mounted, set_mounted] = React27.useState(false);
5273
- React27.useEffect(() => {
5265
+ const editor_container_ref = React25.useRef(null);
5266
+ const edit_popover_ref = React25.useRef(null);
5267
+ const [mounted, set_mounted] = React25.useState(false);
5268
+ React25.useEffect(() => {
5274
5269
  set_mounted(true);
5275
5270
  }, []);
5276
- const suggestion_extensions = React27.useMemo(() => {
5271
+ const suggestion_extensions = React25.useMemo(() => {
5277
5272
  return create_command_suggestion_extension({
5278
5273
  prefixes,
5279
5274
  instance_id,
@@ -5324,7 +5319,7 @@ var HazoUiTextbox = ({
5324
5319
  }
5325
5320
  }
5326
5321
  });
5327
- React27.useEffect(() => {
5322
+ React25.useEffect(() => {
5328
5323
  if (suggestion_state?.is_active && editor) {
5329
5324
  requestAnimationFrame(() => {
5330
5325
  const { from } = suggestion_state.range;
@@ -5348,7 +5343,7 @@ var HazoUiTextbox = ({
5348
5343
  });
5349
5344
  }
5350
5345
  }, [suggestion_state, editor]);
5351
- React27.useEffect(() => {
5346
+ React25.useEffect(() => {
5352
5347
  if (is_controlled && editor && !editor.isFocused) {
5353
5348
  const current_text = editor.getText();
5354
5349
  if (value !== current_text) {
@@ -5357,12 +5352,12 @@ var HazoUiTextbox = ({
5357
5352
  }
5358
5353
  }
5359
5354
  }, [value, editor, is_controlled, prefixes, pill_variant]);
5360
- React27.useEffect(() => {
5355
+ React25.useEffect(() => {
5361
5356
  if (editor) {
5362
5357
  editor.setEditable(!disabled);
5363
5358
  }
5364
5359
  }, [disabled, editor]);
5365
- const handle_command_select = React27.useCallback(
5360
+ const handle_command_select = React25.useCallback(
5366
5361
  (command) => {
5367
5362
  if (!editor || !suggestion_state) return;
5368
5363
  const prefix_config = prefixes.find((p) => p.char === suggestion_state.prefix);
@@ -5382,15 +5377,15 @@ var HazoUiTextbox = ({
5382
5377
  },
5383
5378
  [editor, suggestion_state, pill_variant, on_command_insert, prefixes]
5384
5379
  );
5385
- const handle_popover_close = React27.useCallback(() => {
5380
+ const handle_popover_close = React25.useCallback(() => {
5386
5381
  set_suggestion_state(null);
5387
5382
  editor?.commands.focus();
5388
5383
  }, [editor]);
5389
- const handle_edit_close = React27.useCallback(() => {
5384
+ const handle_edit_close = React25.useCallback(() => {
5390
5385
  set_edit_context(null);
5391
5386
  editor?.commands.focus();
5392
5387
  }, [editor]);
5393
- const handle_command_update = React27.useCallback(
5388
+ const handle_command_update = React25.useCallback(
5394
5389
  (new_command) => {
5395
5390
  if (!editor || !edit_context) return;
5396
5391
  const old_command = edit_context.command;
@@ -5406,7 +5401,7 @@ var HazoUiTextbox = ({
5406
5401
  },
5407
5402
  [editor, edit_context, on_command_change]
5408
5403
  );
5409
- const handle_command_remove = React27.useCallback(() => {
5404
+ const handle_command_remove = React25.useCallback(() => {
5410
5405
  if (!editor || !edit_context) return;
5411
5406
  const command = edit_context.command;
5412
5407
  editor.state.doc.descendants((node, pos) => {
@@ -5420,7 +5415,7 @@ var HazoUiTextbox = ({
5420
5415
  }
5421
5416
  set_edit_context(null);
5422
5417
  }, [editor, edit_context, on_command_remove]);
5423
- const filtered_commands = React27.useMemo(() => {
5418
+ const filtered_commands = React25.useMemo(() => {
5424
5419
  if (!suggestion_state) return [];
5425
5420
  const query = suggestion_state.query.toLowerCase();
5426
5421
  if (!query) return suggestion_state.commands;
@@ -5428,7 +5423,7 @@ var HazoUiTextbox = ({
5428
5423
  (cmd) => cmd.action_label.toLowerCase().includes(query) || cmd.action.toLowerCase().includes(query) || cmd.action_description?.toLowerCase().includes(query)
5429
5424
  );
5430
5425
  }, [suggestion_state]);
5431
- React27.useEffect(() => {
5426
+ React25.useEffect(() => {
5432
5427
  if (!suggestion_state?.is_active) return;
5433
5428
  const handle_keydown = (e) => {
5434
5429
  switch (e.key) {
@@ -5463,7 +5458,7 @@ var HazoUiTextbox = ({
5463
5458
  handle_command_select,
5464
5459
  handle_popover_close
5465
5460
  ]);
5466
- React27.useEffect(() => {
5461
+ React25.useEffect(() => {
5467
5462
  if (!edit_context) return;
5468
5463
  const handle_click_outside = (e) => {
5469
5464
  if (edit_popover_ref.current && !edit_popover_ref.current.contains(e.target)) {
@@ -5478,12 +5473,12 @@ var HazoUiTextbox = ({
5478
5473
  document.removeEventListener("mousedown", handle_click_outside);
5479
5474
  };
5480
5475
  }, [edit_context]);
5481
- const edit_commands = React27.useMemo(() => {
5476
+ const edit_commands = React25.useMemo(() => {
5482
5477
  if (!edit_context) return [];
5483
5478
  const prefix_config = prefixes.find((p) => p.char === edit_context.command.prefix);
5484
5479
  return prefix_config?.commands || [];
5485
5480
  }, [edit_context, prefixes]);
5486
- React27.useEffect(() => {
5481
+ React25.useEffect(() => {
5487
5482
  if (!edit_context) return;
5488
5483
  const handle_keydown = (e) => {
5489
5484
  switch (e.key) {
@@ -5521,7 +5516,7 @@ var HazoUiTextbox = ({
5521
5516
  handle_command_remove,
5522
5517
  handle_edit_close
5523
5518
  ]);
5524
- React27.useEffect(() => {
5519
+ React25.useEffect(() => {
5525
5520
  const handle_pill_click = (e) => {
5526
5521
  const detail = e.detail;
5527
5522
  const { id, prefix, action, action_label, node_pos } = detail;
@@ -5804,22 +5799,22 @@ var HazoUiTextarea = ({
5804
5799
  on_command_change,
5805
5800
  on_command_remove
5806
5801
  }) => {
5807
- const generated_instance_id = React27.useId();
5802
+ const generated_instance_id = React25.useId();
5808
5803
  const instance_id = provided_instance_id || generated_instance_id;
5809
- const [suggestion_state, set_suggestion_state] = React27.useState(null);
5810
- const [selected_index, set_selected_index] = React27.useState(0);
5811
- const [popover_position, set_popover_position] = React27.useState({ top: 0, left: 0 });
5812
- const [edit_context, set_edit_context] = React27.useState(null);
5813
- const [edit_selected_index, set_edit_selected_index] = React27.useState(0);
5804
+ const [suggestion_state, set_suggestion_state] = React25.useState(null);
5805
+ const [selected_index, set_selected_index] = React25.useState(0);
5806
+ const [popover_position, set_popover_position] = React25.useState({ top: 0, left: 0 });
5807
+ const [edit_context, set_edit_context] = React25.useState(null);
5808
+ const [edit_selected_index, set_edit_selected_index] = React25.useState(0);
5814
5809
  const is_controlled = value !== void 0;
5815
- const editor_container_ref = React27.useRef(null);
5816
- const edit_popover_ref = React27.useRef(null);
5817
- const [mounted, set_mounted] = React27.useState(false);
5818
- React27.useEffect(() => {
5810
+ const editor_container_ref = React25.useRef(null);
5811
+ const edit_popover_ref = React25.useRef(null);
5812
+ const [mounted, set_mounted] = React25.useState(false);
5813
+ React25.useEffect(() => {
5819
5814
  set_mounted(true);
5820
5815
  }, []);
5821
5816
  const calculated_min_height = rows ? `${rows * 1.5}em` : min_height;
5822
- const suggestion_extensions = React27.useMemo(() => {
5817
+ const suggestion_extensions = React25.useMemo(() => {
5823
5818
  return create_command_suggestion_extension({
5824
5819
  prefixes,
5825
5820
  instance_id,
@@ -5868,7 +5863,7 @@ var HazoUiTextarea = ({
5868
5863
  }
5869
5864
  }
5870
5865
  });
5871
- React27.useEffect(() => {
5866
+ React25.useEffect(() => {
5872
5867
  if (suggestion_state?.is_active && editor) {
5873
5868
  requestAnimationFrame(() => {
5874
5869
  const { from } = suggestion_state.range;
@@ -5892,7 +5887,7 @@ var HazoUiTextarea = ({
5892
5887
  });
5893
5888
  }
5894
5889
  }, [suggestion_state, editor]);
5895
- React27.useEffect(() => {
5890
+ React25.useEffect(() => {
5896
5891
  if (is_controlled && editor && !editor.isFocused) {
5897
5892
  const current_text = editor.getText();
5898
5893
  if (value !== current_text) {
@@ -5905,12 +5900,12 @@ var HazoUiTextarea = ({
5905
5900
  }
5906
5901
  }
5907
5902
  }, [value, editor, is_controlled, prefixes, pill_variant]);
5908
- React27.useEffect(() => {
5903
+ React25.useEffect(() => {
5909
5904
  if (editor) {
5910
5905
  editor.setEditable(!disabled);
5911
5906
  }
5912
5907
  }, [disabled, editor]);
5913
- const handle_command_select = React27.useCallback(
5908
+ const handle_command_select = React25.useCallback(
5914
5909
  (command) => {
5915
5910
  if (!editor || !suggestion_state) return;
5916
5911
  const prefix_config = prefixes.find((p) => p.char === suggestion_state.prefix);
@@ -5930,15 +5925,15 @@ var HazoUiTextarea = ({
5930
5925
  },
5931
5926
  [editor, suggestion_state, pill_variant, on_command_insert, prefixes]
5932
5927
  );
5933
- const handle_popover_close = React27.useCallback(() => {
5928
+ const handle_popover_close = React25.useCallback(() => {
5934
5929
  set_suggestion_state(null);
5935
5930
  editor?.commands.focus();
5936
5931
  }, [editor]);
5937
- const handle_edit_close = React27.useCallback(() => {
5932
+ const handle_edit_close = React25.useCallback(() => {
5938
5933
  set_edit_context(null);
5939
5934
  editor?.commands.focus();
5940
5935
  }, [editor]);
5941
- const handle_command_update = React27.useCallback(
5936
+ const handle_command_update = React25.useCallback(
5942
5937
  (new_command) => {
5943
5938
  if (!editor || !edit_context) return;
5944
5939
  const old_command = edit_context.command;
@@ -5954,7 +5949,7 @@ var HazoUiTextarea = ({
5954
5949
  },
5955
5950
  [editor, edit_context, on_command_change]
5956
5951
  );
5957
- const handle_command_remove = React27.useCallback(() => {
5952
+ const handle_command_remove = React25.useCallback(() => {
5958
5953
  if (!editor || !edit_context) return;
5959
5954
  const command = edit_context.command;
5960
5955
  editor.state.doc.descendants((node, pos) => {
@@ -5968,7 +5963,7 @@ var HazoUiTextarea = ({
5968
5963
  }
5969
5964
  set_edit_context(null);
5970
5965
  }, [editor, edit_context, on_command_remove]);
5971
- const filtered_commands = React27.useMemo(() => {
5966
+ const filtered_commands = React25.useMemo(() => {
5972
5967
  if (!suggestion_state) return [];
5973
5968
  const query = suggestion_state.query.toLowerCase();
5974
5969
  if (!query) return suggestion_state.commands;
@@ -5976,7 +5971,7 @@ var HazoUiTextarea = ({
5976
5971
  (cmd) => cmd.action_label.toLowerCase().includes(query) || cmd.action.toLowerCase().includes(query) || cmd.action_description?.toLowerCase().includes(query)
5977
5972
  );
5978
5973
  }, [suggestion_state]);
5979
- React27.useEffect(() => {
5974
+ React25.useEffect(() => {
5980
5975
  if (!suggestion_state?.is_active) return;
5981
5976
  const handle_keydown = (e) => {
5982
5977
  switch (e.key) {
@@ -6011,7 +6006,7 @@ var HazoUiTextarea = ({
6011
6006
  handle_command_select,
6012
6007
  handle_popover_close
6013
6008
  ]);
6014
- React27.useEffect(() => {
6009
+ React25.useEffect(() => {
6015
6010
  if (!edit_context) return;
6016
6011
  const handle_click_outside = (e) => {
6017
6012
  if (edit_popover_ref.current && !edit_popover_ref.current.contains(e.target)) {
@@ -6026,12 +6021,12 @@ var HazoUiTextarea = ({
6026
6021
  document.removeEventListener("mousedown", handle_click_outside);
6027
6022
  };
6028
6023
  }, [edit_context]);
6029
- const edit_commands = React27.useMemo(() => {
6024
+ const edit_commands = React25.useMemo(() => {
6030
6025
  if (!edit_context) return [];
6031
6026
  const prefix_config = prefixes.find((p) => p.char === edit_context.command.prefix);
6032
6027
  return prefix_config?.commands || [];
6033
6028
  }, [edit_context, prefixes]);
6034
- React27.useEffect(() => {
6029
+ React25.useEffect(() => {
6035
6030
  if (!edit_context) return;
6036
6031
  const handle_keydown = (e) => {
6037
6032
  switch (e.key) {
@@ -6069,7 +6064,7 @@ var HazoUiTextarea = ({
6069
6064
  handle_command_remove,
6070
6065
  handle_edit_close
6071
6066
  ]);
6072
- React27.useEffect(() => {
6067
+ React25.useEffect(() => {
6073
6068
  const handle_pill_click = (e) => {
6074
6069
  const detail = e.detail;
6075
6070
  const { id, prefix, action, action_label, node_pos } = detail;
@@ -6616,7 +6611,7 @@ function HazoUiConfirmDialog({
6616
6611
  openAnimation = "zoom",
6617
6612
  closeAnimation = "zoom"
6618
6613
  }) {
6619
- const [internal_loading, set_internal_loading] = React27.useState(false);
6614
+ const [internal_loading, set_internal_loading] = React25.useState(false);
6620
6615
  const config = get_hazo_ui_config();
6621
6616
  const variant_preset = variant !== "default" ? CONFIRM_VARIANT_PRESETS[variant] : void 0;
6622
6617
  const is_loading = external_loading ?? internal_loading;
@@ -6653,7 +6648,7 @@ function HazoUiConfirmDialog({
6653
6648
  onCancel?.();
6654
6649
  onOpenChange(false);
6655
6650
  };
6656
- const cancel_ref = React27.useRef(null);
6651
+ const cancel_ref = React25.useRef(null);
6657
6652
  return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(DialogPortal, { children: [
6658
6653
  /* @__PURE__ */ jsx(
6659
6654
  DialogOverlay,
@@ -6738,7 +6733,7 @@ Drawer.displayName = "Drawer";
6738
6733
  var DrawerTrigger = Drawer$1.Trigger;
6739
6734
  var DrawerPortal = Drawer$1.Portal;
6740
6735
  var DrawerClose = Drawer$1.Close;
6741
- var DrawerOverlay = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
6736
+ var DrawerOverlay = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
6742
6737
  Drawer$1.Overlay,
6743
6738
  {
6744
6739
  ref,
@@ -6750,7 +6745,7 @@ var DrawerOverlay = React27.forwardRef(({ className, ...props }, ref) => /* @__P
6750
6745
  }
6751
6746
  ));
6752
6747
  DrawerOverlay.displayName = "DrawerOverlay";
6753
- var DrawerContent = React27.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(DrawerPortal, { children: [
6748
+ var DrawerContent = React25.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(DrawerPortal, { children: [
6754
6749
  /* @__PURE__ */ jsx(DrawerOverlay, {}),
6755
6750
  /* @__PURE__ */ jsxs(
6756
6751
  Drawer$1.Content,
@@ -6791,7 +6786,7 @@ var DrawerFooter = ({
6791
6786
  }
6792
6787
  );
6793
6788
  DrawerFooter.displayName = "DrawerFooter";
6794
- var DrawerTitle = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
6789
+ var DrawerTitle = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
6795
6790
  Drawer$1.Title,
6796
6791
  {
6797
6792
  ref,
@@ -6803,7 +6798,7 @@ var DrawerTitle = React27.forwardRef(({ className, ...props }, ref) => /* @__PUR
6803
6798
  }
6804
6799
  ));
6805
6800
  DrawerTitle.displayName = "DrawerTitle";
6806
- var DrawerDescription = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
6801
+ var DrawerDescription = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
6807
6802
  Drawer$1.Description,
6808
6803
  {
6809
6804
  ref,
@@ -6813,14 +6808,14 @@ var DrawerDescription = React27.forwardRef(({ className, ...props }, ref) => /*
6813
6808
  ));
6814
6809
  DrawerDescription.displayName = "DrawerDescription";
6815
6810
  function useMediaQuery(query) {
6816
- const get_match = React27.useCallback(() => {
6811
+ const get_match = React25.useCallback(() => {
6817
6812
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
6818
6813
  return false;
6819
6814
  }
6820
6815
  return window.matchMedia(query).matches;
6821
6816
  }, [query]);
6822
- const [matches, set_matches] = React27.useState(false);
6823
- React27.useEffect(() => {
6817
+ const [matches, set_matches] = React25.useState(false);
6818
+ React25.useEffect(() => {
6824
6819
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
6825
6820
  return;
6826
6821
  }
@@ -6837,7 +6832,7 @@ function useMediaQuery(query) {
6837
6832
  return matches;
6838
6833
  }
6839
6834
  var Accordion = AccordionPrimitive.Root;
6840
- var AccordionItem = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
6835
+ var AccordionItem = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
6841
6836
  AccordionPrimitive.Item,
6842
6837
  {
6843
6838
  ref,
@@ -6846,7 +6841,7 @@ var AccordionItem = React27.forwardRef(({ className, ...props }, ref) => /* @__P
6846
6841
  }
6847
6842
  ));
6848
6843
  AccordionItem.displayName = "AccordionItem";
6849
- var AccordionTrigger = React27.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(AccordionPrimitive.Header, { className: "flex", children: /* @__PURE__ */ jsxs(
6844
+ var AccordionTrigger = React25.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(AccordionPrimitive.Header, { className: "flex", children: /* @__PURE__ */ jsxs(
6850
6845
  AccordionPrimitive.Trigger,
6851
6846
  {
6852
6847
  ref,
@@ -6862,7 +6857,7 @@ var AccordionTrigger = React27.forwardRef(({ className, children, ...props }, re
6862
6857
  }
6863
6858
  ) }));
6864
6859
  AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;
6865
- var AccordionContent = React27.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(
6860
+ var AccordionContent = React25.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(
6866
6861
  AccordionPrimitive.Content,
6867
6862
  {
6868
6863
  ref,
@@ -6872,7 +6867,7 @@ var AccordionContent = React27.forwardRef(({ className, children, ...props }, re
6872
6867
  }
6873
6868
  ));
6874
6869
  AccordionContent.displayName = AccordionPrimitive.Content.displayName;
6875
- var Checkbox = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
6870
+ var Checkbox = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
6876
6871
  CheckboxPrimitive.Root,
6877
6872
  {
6878
6873
  ref,
@@ -6897,7 +6892,7 @@ var DropdownMenuGroup = DropdownMenuPrimitive.Group;
6897
6892
  var DropdownMenuPortal = DropdownMenuPrimitive.Portal;
6898
6893
  var DropdownMenuSub = DropdownMenuPrimitive.Sub;
6899
6894
  var DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
6900
- var DropdownMenuSubTrigger = React27.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(
6895
+ var DropdownMenuSubTrigger = React25.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(
6901
6896
  DropdownMenuPrimitive.SubTrigger,
6902
6897
  {
6903
6898
  ref,
@@ -6914,7 +6909,7 @@ var DropdownMenuSubTrigger = React27.forwardRef(({ className, inset, children, .
6914
6909
  }
6915
6910
  ));
6916
6911
  DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
6917
- var DropdownMenuSubContent = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
6912
+ var DropdownMenuSubContent = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
6918
6913
  DropdownMenuPrimitive.SubContent,
6919
6914
  {
6920
6915
  ref,
@@ -6926,7 +6921,7 @@ var DropdownMenuSubContent = React27.forwardRef(({ className, ...props }, ref) =
6926
6921
  }
6927
6922
  ));
6928
6923
  DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
6929
- var DropdownMenuContent = React27.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
6924
+ var DropdownMenuContent = React25.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
6930
6925
  DropdownMenuPrimitive.Content,
6931
6926
  {
6932
6927
  ref,
@@ -6939,7 +6934,7 @@ var DropdownMenuContent = React27.forwardRef(({ className, sideOffset = 4, ...pr
6939
6934
  }
6940
6935
  ) }));
6941
6936
  DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
6942
- var DropdownMenuItem = React27.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
6937
+ var DropdownMenuItem = React25.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
6943
6938
  DropdownMenuPrimitive.Item,
6944
6939
  {
6945
6940
  ref,
@@ -6952,7 +6947,7 @@ var DropdownMenuItem = React27.forwardRef(({ className, inset, ...props }, ref)
6952
6947
  }
6953
6948
  ));
6954
6949
  DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
6955
- var DropdownMenuCheckboxItem = React27.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs(
6950
+ var DropdownMenuCheckboxItem = React25.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs(
6956
6951
  DropdownMenuPrimitive.CheckboxItem,
6957
6952
  {
6958
6953
  ref,
@@ -6969,7 +6964,7 @@ var DropdownMenuCheckboxItem = React27.forwardRef(({ className, children, checke
6969
6964
  }
6970
6965
  ));
6971
6966
  DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
6972
- var DropdownMenuRadioItem = React27.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
6967
+ var DropdownMenuRadioItem = React25.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
6973
6968
  DropdownMenuPrimitive.RadioItem,
6974
6969
  {
6975
6970
  ref,
@@ -6985,7 +6980,7 @@ var DropdownMenuRadioItem = React27.forwardRef(({ className, children, ...props
6985
6980
  }
6986
6981
  ));
6987
6982
  DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
6988
- var DropdownMenuLabel = React27.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
6983
+ var DropdownMenuLabel = React25.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
6989
6984
  DropdownMenuPrimitive.Label,
6990
6985
  {
6991
6986
  ref,
@@ -6998,7 +6993,7 @@ var DropdownMenuLabel = React27.forwardRef(({ className, inset, ...props }, ref)
6998
6993
  }
6999
6994
  ));
7000
6995
  DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
7001
- var DropdownMenuSeparator = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
6996
+ var DropdownMenuSeparator = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7002
6997
  DropdownMenuPrimitive.Separator,
7003
6998
  {
7004
6999
  ref,
@@ -7022,7 +7017,7 @@ var DropdownMenuShortcut = ({
7022
7017
  DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
7023
7018
  var HoverCard = HoverCardPrimitive.Root;
7024
7019
  var HoverCardTrigger = HoverCardPrimitive.Trigger;
7025
- var HoverCardContent = React27.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(
7020
+ var HoverCardContent = React25.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(
7026
7021
  HoverCardPrimitive.Content,
7027
7022
  {
7028
7023
  ref,
@@ -7036,34 +7031,70 @@ var HoverCardContent = React27.forwardRef(({ className, align = "center", sideOf
7036
7031
  }
7037
7032
  ));
7038
7033
  HoverCardContent.displayName = HoverCardPrimitive.Content.displayName;
7039
- var Textarea = React27.forwardRef(
7034
+ var Label3 = React25.forwardRef(
7040
7035
  ({ className, ...props }, ref) => {
7041
7036
  return /* @__PURE__ */ jsx(
7042
- "textarea",
7037
+ "label",
7043
7038
  {
7039
+ ref,
7044
7040
  className: cn(
7045
- "flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2",
7046
- "text-sm ring-offset-background",
7047
- "placeholder:text-muted-foreground",
7048
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
7049
- "disabled:cursor-not-allowed disabled:opacity-50",
7041
+ "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
7050
7042
  className
7051
7043
  ),
7052
- ref,
7053
7044
  ...props
7054
7045
  }
7055
7046
  );
7056
7047
  }
7057
7048
  );
7058
- Textarea.displayName = "Textarea";
7059
- var Separator3 = React27.forwardRef(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx(
7060
- SeparatorPrimitive.Root,
7049
+ Label3.displayName = "Label";
7050
+ var Switch = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7051
+ SwitchPrimitives.Root,
7061
7052
  {
7062
- ref,
7063
- decorative,
7064
- orientation,
7065
7053
  className: cn(
7066
- "shrink-0 bg-border",
7054
+ "peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
7055
+ className
7056
+ ),
7057
+ ...props,
7058
+ ref,
7059
+ children: /* @__PURE__ */ jsx(
7060
+ SwitchPrimitives.Thumb,
7061
+ {
7062
+ className: cn(
7063
+ "pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0"
7064
+ )
7065
+ }
7066
+ )
7067
+ }
7068
+ ));
7069
+ Switch.displayName = SwitchPrimitives.Root.displayName;
7070
+ var Textarea = React25.forwardRef(
7071
+ ({ className, ...props }, ref) => {
7072
+ return /* @__PURE__ */ jsx(
7073
+ "textarea",
7074
+ {
7075
+ className: cn(
7076
+ "flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2",
7077
+ "text-sm ring-offset-background",
7078
+ "placeholder:text-muted-foreground",
7079
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
7080
+ "disabled:cursor-not-allowed disabled:opacity-50",
7081
+ className
7082
+ ),
7083
+ ref,
7084
+ ...props
7085
+ }
7086
+ );
7087
+ }
7088
+ );
7089
+ Textarea.displayName = "Textarea";
7090
+ var Separator3 = React25.forwardRef(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx(
7091
+ SeparatorPrimitive.Root,
7092
+ {
7093
+ ref,
7094
+ decorative,
7095
+ orientation,
7096
+ className: cn(
7097
+ "shrink-0 bg-border",
7067
7098
  orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
7068
7099
  className
7069
7100
  ),
@@ -7074,7 +7105,7 @@ Separator3.displayName = SeparatorPrimitive.Root.displayName;
7074
7105
  var Collapsible = CollapsiblePrimitive.Root;
7075
7106
  var CollapsibleTrigger2 = CollapsiblePrimitive.CollapsibleTrigger;
7076
7107
  var CollapsibleContent2 = CollapsiblePrimitive.CollapsibleContent;
7077
- var ScrollArea = React27.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
7108
+ var ScrollArea = React25.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
7078
7109
  ScrollAreaPrimitive.Root,
7079
7110
  {
7080
7111
  ref,
@@ -7088,7 +7119,7 @@ var ScrollArea = React27.forwardRef(({ className, children, ...props }, ref) =>
7088
7119
  }
7089
7120
  ));
7090
7121
  ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
7091
- var ScrollBar = React27.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ jsx(
7122
+ var ScrollBar = React25.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ jsx(
7092
7123
  ScrollAreaPrimitive.ScrollAreaScrollbar,
7093
7124
  {
7094
7125
  ref,
@@ -7104,27 +7135,27 @@ var ScrollBar = React27.forwardRef(({ className, orientation = "vertical", ...pr
7104
7135
  }
7105
7136
  ));
7106
7137
  ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
7107
- var Card = React27.forwardRef(
7138
+ var Card = React25.forwardRef(
7108
7139
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("rounded-lg border bg-card text-card-foreground shadow-sm", className), ...props })
7109
7140
  );
7110
7141
  Card.displayName = "Card";
7111
- var CardHeader = React27.forwardRef(
7142
+ var CardHeader = React25.forwardRef(
7112
7143
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("flex flex-col space-y-1.5 p-6", className), ...props })
7113
7144
  );
7114
7145
  CardHeader.displayName = "CardHeader";
7115
- var CardTitle = React27.forwardRef(
7146
+ var CardTitle = React25.forwardRef(
7116
7147
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx("h3", { ref, className: cn("text-2xl font-semibold leading-none tracking-tight", className), ...props })
7117
7148
  );
7118
7149
  CardTitle.displayName = "CardTitle";
7119
- var CardDescription = React27.forwardRef(
7150
+ var CardDescription = React25.forwardRef(
7120
7151
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props })
7121
7152
  );
7122
7153
  CardDescription.displayName = "CardDescription";
7123
- var CardContent = React27.forwardRef(
7154
+ var CardContent = React25.forwardRef(
7124
7155
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props })
7125
7156
  );
7126
7157
  CardContent.displayName = "CardContent";
7127
- var CardFooter = React27.forwardRef(
7158
+ var CardFooter = React25.forwardRef(
7128
7159
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("flex items-center p-6 pt-0", className), ...props })
7129
7160
  );
7130
7161
  CardFooter.displayName = "CardFooter";
@@ -7157,16 +7188,16 @@ var toggleVariants = cva(
7157
7188
  defaultVariants: { variant: "default", size: "default" }
7158
7189
  }
7159
7190
  );
7160
- var Toggle = React27.forwardRef(({ className, variant, size, ...props }, ref) => /* @__PURE__ */ jsx(TogglePrimitive.Root, { ref, className: cn(toggleVariants({ variant, size, className })), ...props }));
7191
+ var Toggle = React25.forwardRef(({ className, variant, size, ...props }, ref) => /* @__PURE__ */ jsx(TogglePrimitive.Root, { ref, className: cn(toggleVariants({ variant, size, className })), ...props }));
7161
7192
  Toggle.displayName = TogglePrimitive.Root.displayName;
7162
- var ToggleGroupContext = React27.createContext({
7193
+ var ToggleGroupContext = React25.createContext({
7163
7194
  size: "default",
7164
7195
  variant: "default"
7165
7196
  });
7166
- var ToggleGroup = React27.forwardRef(({ className, variant, size, children, ...props }, ref) => /* @__PURE__ */ jsx(ToggleGroupPrimitive.Root, { ref, className: cn("flex items-center justify-center gap-1", className), ...props, children: /* @__PURE__ */ jsx(ToggleGroupContext.Provider, { value: { variant, size }, children }) }));
7197
+ var ToggleGroup = React25.forwardRef(({ className, variant, size, children, ...props }, ref) => /* @__PURE__ */ jsx(ToggleGroupPrimitive.Root, { ref, className: cn("flex items-center justify-center gap-1", className), ...props, children: /* @__PURE__ */ jsx(ToggleGroupContext.Provider, { value: { variant, size }, children }) }));
7167
7198
  ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName;
7168
- var ToggleGroupItem = React27.forwardRef(({ className, children, variant, size, ...props }, ref) => {
7169
- const context = React27.useContext(ToggleGroupContext);
7199
+ var ToggleGroupItem = React25.forwardRef(({ className, children, variant, size, ...props }, ref) => {
7200
+ const context = React25.useContext(ToggleGroupContext);
7170
7201
  return /* @__PURE__ */ jsx(
7171
7202
  ToggleGroupPrimitive.Item,
7172
7203
  {
@@ -7181,7 +7212,7 @@ ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;
7181
7212
  var AlertDialog = AlertDialogPrimitive.Root;
7182
7213
  var AlertDialogTrigger = AlertDialogPrimitive.Trigger;
7183
7214
  var AlertDialogPortal = AlertDialogPrimitive.Portal;
7184
- var AlertDialogOverlay = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7215
+ var AlertDialogOverlay = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7185
7216
  AlertDialogPrimitive.Overlay,
7186
7217
  {
7187
7218
  ref,
@@ -7190,7 +7221,7 @@ var AlertDialogOverlay = React27.forwardRef(({ className, ...props }, ref) => /*
7190
7221
  }
7191
7222
  ));
7192
7223
  AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
7193
- var AlertDialogContent = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs(AlertDialogPortal, { children: [
7224
+ var AlertDialogContent = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs(AlertDialogPortal, { children: [
7194
7225
  /* @__PURE__ */ jsx(AlertDialogOverlay, {}),
7195
7226
  /* @__PURE__ */ jsx(
7196
7227
  AlertDialogPrimitive.Content,
@@ -7206,13 +7237,13 @@ var AlertDialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsx("div",
7206
7237
  AlertDialogHeader.displayName = "AlertDialogHeader";
7207
7238
  var AlertDialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx("div", { className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className), ...props });
7208
7239
  AlertDialogFooter.displayName = "AlertDialogFooter";
7209
- var AlertDialogTitle = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(AlertDialogPrimitive.Title, { ref, className: cn("text-lg font-semibold", className), ...props }));
7240
+ var AlertDialogTitle = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(AlertDialogPrimitive.Title, { ref, className: cn("text-lg font-semibold", className), ...props }));
7210
7241
  AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
7211
- var AlertDialogDescription = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(AlertDialogPrimitive.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
7242
+ var AlertDialogDescription = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(AlertDialogPrimitive.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
7212
7243
  AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName;
7213
- var AlertDialogAction = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(AlertDialogPrimitive.Action, { ref, className: cn(buttonVariants(), className), ...props }));
7244
+ var AlertDialogAction = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(AlertDialogPrimitive.Action, { ref, className: cn(buttonVariants(), className), ...props }));
7214
7245
  AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
7215
- var AlertDialogCancel = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(AlertDialogPrimitive.Cancel, { ref, className: cn(buttonVariants({ variant: "outline" }), "mt-2 sm:mt-0", className), ...props }));
7246
+ var AlertDialogCancel = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(AlertDialogPrimitive.Cancel, { ref, className: cn(buttonVariants({ variant: "outline" }), "mt-2 sm:mt-0", className), ...props }));
7216
7247
  AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
7217
7248
  var buttonGroupVariants = cva(
7218
7249
  "flex w-fit items-stretch [&>*]:focus-visible:relative [&>*]:focus-visible:z-10",
@@ -7240,7 +7271,1969 @@ function ButtonGroupText({ className, asChild = false, ...props }) {
7240
7271
  function ButtonGroupSeparator({ className, orientation = "vertical", ...props }) {
7241
7272
  return /* @__PURE__ */ jsx(Separator3, { orientation, className: cn("bg-input relative !m-0 self-stretch data-[orientation=vertical]:h-auto", className), ...props });
7242
7273
  }
7274
+ var SkeletonBase = React25.forwardRef(
7275
+ ({ className, ...rest }, ref) => /* @__PURE__ */ jsx(
7276
+ "div",
7277
+ {
7278
+ ref,
7279
+ "data-hazo-skeleton": "",
7280
+ "aria-hidden": "true",
7281
+ className: cn("hazo-shimmer rounded-md", className),
7282
+ ...rest
7283
+ }
7284
+ )
7285
+ );
7286
+ SkeletonBase.displayName = "Skeleton";
7287
+ var Skeleton = SkeletonBase;
7288
+ function SkeletonCircle({ size = 40, className }) {
7289
+ return /* @__PURE__ */ jsx(
7290
+ SkeletonBase,
7291
+ {
7292
+ className: cn("rounded-full", className),
7293
+ style: { width: size, height: size }
7294
+ }
7295
+ );
7296
+ }
7297
+ function SkeletonBar({ width = "100%", height = 12, className }) {
7298
+ return /* @__PURE__ */ jsx(
7299
+ SkeletonBase,
7300
+ {
7301
+ className,
7302
+ style: { width, height }
7303
+ }
7304
+ );
7305
+ }
7306
+ function SkeletonRect({ width = "100%", height = 96, radius = 6, className }) {
7307
+ return /* @__PURE__ */ jsx(
7308
+ SkeletonBase,
7309
+ {
7310
+ className,
7311
+ style: { width, height, borderRadius: radius }
7312
+ }
7313
+ );
7314
+ }
7315
+ function SkeletonGroup({ label = "Loading content", children, className, ...rest }) {
7316
+ return /* @__PURE__ */ jsxs(
7317
+ "div",
7318
+ {
7319
+ role: "status",
7320
+ "aria-busy": "true",
7321
+ "aria-label": label,
7322
+ className: cn("space-y-2", className),
7323
+ ...rest,
7324
+ children: [
7325
+ children,
7326
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: label })
7327
+ ]
7328
+ }
7329
+ );
7330
+ }
7331
+ function EmptyState({
7332
+ icon,
7333
+ title,
7334
+ description,
7335
+ action,
7336
+ size = "md",
7337
+ className
7338
+ }) {
7339
+ const sizing = {
7340
+ sm: { wrap: "py-6 gap-2", icon: "w-8 h-8 mb-1", title: "text-sm font-medium", desc: "text-xs" },
7341
+ md: { wrap: "py-10 gap-3", icon: "w-12 h-12 mb-2", title: "text-base font-semibold", desc: "text-sm" },
7342
+ lg: { wrap: "py-16 gap-4", icon: "w-16 h-16 mb-3", title: "text-lg font-semibold", desc: "text-base" }
7343
+ }[size];
7344
+ return /* @__PURE__ */ jsxs(
7345
+ "div",
7346
+ {
7347
+ className: cn(
7348
+ "flex flex-col items-center justify-center text-center text-muted-foreground",
7349
+ sizing.wrap,
7350
+ className
7351
+ ),
7352
+ children: [
7353
+ icon ? /* @__PURE__ */ jsx("div", { className: cn("text-muted-foreground/60", sizing.icon), children: icon }) : null,
7354
+ /* @__PURE__ */ jsx("div", { className: cn("text-foreground", sizing.title), children: title }),
7355
+ description ? /* @__PURE__ */ jsx("div", { className: cn("max-w-md text-muted-foreground", sizing.desc), children: description }) : null,
7356
+ action ? /* @__PURE__ */ jsx("div", { className: "mt-2 flex items-center gap-2", children: action }) : null
7357
+ ]
7358
+ }
7359
+ );
7360
+ }
7361
+ function ErrorBanner({
7362
+ severity = "error",
7363
+ title,
7364
+ message,
7365
+ icon,
7366
+ action,
7367
+ onDismiss,
7368
+ className
7369
+ }) {
7370
+ const palette = severity === "warning" ? "border-amber-300 bg-amber-50 text-amber-900 dark:border-amber-700 dark:bg-amber-950 dark:text-amber-100" : "border-destructive/40 bg-destructive/10 text-destructive-foreground";
7371
+ const iconColor = severity === "warning" ? "text-amber-600" : "text-destructive";
7372
+ const resolvedIcon = icon ?? (severity === "warning" ? /* @__PURE__ */ jsx(AlertTriangle, { className: cn("h-5 w-5", iconColor), "aria-hidden": "true" }) : /* @__PURE__ */ jsx(OctagonAlert, { className: cn("h-5 w-5", iconColor), "aria-hidden": "true" }));
7373
+ return /* @__PURE__ */ jsxs(
7374
+ "div",
7375
+ {
7376
+ role: "alert",
7377
+ "aria-live": severity === "error" ? "assertive" : "polite",
7378
+ className: cn(
7379
+ "flex items-start gap-3 rounded-md border px-4 py-3 text-sm",
7380
+ palette,
7381
+ className
7382
+ ),
7383
+ children: [
7384
+ /* @__PURE__ */ jsx("div", { className: "flex-shrink-0 mt-0.5", children: resolvedIcon }),
7385
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
7386
+ title ? /* @__PURE__ */ jsx("div", { className: "font-semibold leading-tight", children: title }) : null,
7387
+ /* @__PURE__ */ jsx("div", { className: cn("leading-snug", title ? "mt-1" : ""), children: message }),
7388
+ action ? /* @__PURE__ */ jsx("div", { className: "mt-2 flex items-center gap-2", children: action }) : null
7389
+ ] }),
7390
+ onDismiss ? /* @__PURE__ */ jsx(
7391
+ "button",
7392
+ {
7393
+ type: "button",
7394
+ onClick: onDismiss,
7395
+ "aria-label": "Dismiss",
7396
+ className: "flex-shrink-0 rounded p-1 hover:bg-black/5 focus:outline-none focus:ring-2 focus:ring-offset-2 dark:hover:bg-white/5",
7397
+ children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4", "aria-hidden": "true" })
7398
+ }
7399
+ ) : null
7400
+ ]
7401
+ }
7402
+ );
7403
+ }
7404
+ function ErrorPage({
7405
+ title = "Something went wrong",
7406
+ description,
7407
+ errorCode,
7408
+ correlationId,
7409
+ actions,
7410
+ illustration,
7411
+ className
7412
+ }) {
7413
+ return /* @__PURE__ */ jsxs(
7414
+ "div",
7415
+ {
7416
+ role: "alert",
7417
+ "aria-live": "assertive",
7418
+ className: cn(
7419
+ "mx-auto flex max-w-md flex-col items-center justify-center gap-4 px-6 py-16 text-center",
7420
+ className
7421
+ ),
7422
+ children: [
7423
+ /* @__PURE__ */ jsx("div", { className: "text-destructive", children: illustration ?? /* @__PURE__ */ jsx(OctagonAlert, { className: "h-16 w-16", "aria-hidden": "true" }) }),
7424
+ errorCode ? /* @__PURE__ */ jsx("div", { className: "rounded-full bg-muted px-3 py-1 text-xs font-mono uppercase tracking-wider text-muted-foreground", children: errorCode }) : null,
7425
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold text-foreground", children: title }),
7426
+ description ? /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: description }) : null,
7427
+ correlationId ? /* @__PURE__ */ jsxs("div", { className: "w-full rounded-md border bg-muted/40 px-3 py-2 text-left", children: [
7428
+ /* @__PURE__ */ jsx("div", { className: "text-[10px] uppercase tracking-wider text-muted-foreground", children: "Correlation ID" }),
7429
+ /* @__PURE__ */ jsx("code", { className: "break-all text-xs", children: correlationId })
7430
+ ] }) : null,
7431
+ actions ? /* @__PURE__ */ jsx("div", { className: "mt-2 flex flex-wrap items-center justify-center gap-2", children: actions }) : null
7432
+ ]
7433
+ }
7434
+ );
7435
+ }
7436
+ function LoadingTimeout({
7437
+ active,
7438
+ children,
7439
+ skeleton,
7440
+ onRetry,
7441
+ thresholds,
7442
+ label = "content",
7443
+ className
7444
+ }) {
7445
+ const t = {
7446
+ gentle: thresholds?.gentle ?? 5e3,
7447
+ firm: thresholds?.firm ?? 15e3,
7448
+ expired: thresholds?.expired ?? 3e4
7449
+ };
7450
+ const [phase, setPhase] = React25.useState(active ? "silent" : "idle");
7451
+ React25.useEffect(() => {
7452
+ if (!active) {
7453
+ setPhase("idle");
7454
+ return;
7455
+ }
7456
+ setPhase("silent");
7457
+ const gentleTimer = window.setTimeout(() => setPhase("gentle"), t.gentle);
7458
+ const firmTimer = window.setTimeout(() => setPhase("firm"), t.firm);
7459
+ const expiredTimer = window.setTimeout(() => setPhase("expired"), t.expired);
7460
+ return () => {
7461
+ window.clearTimeout(gentleTimer);
7462
+ window.clearTimeout(firmTimer);
7463
+ window.clearTimeout(expiredTimer);
7464
+ };
7465
+ }, [active, t.gentle, t.firm, t.expired]);
7466
+ if (!active) {
7467
+ return /* @__PURE__ */ jsx(Fragment$1, { children });
7468
+ }
7469
+ if (phase === "expired") {
7470
+ return /* @__PURE__ */ jsx("div", { className, role: "alert", "aria-busy": "false", children: /* @__PURE__ */ jsx(
7471
+ ErrorBanner,
7472
+ {
7473
+ severity: "error",
7474
+ title: "This is taking longer than expected",
7475
+ message: `We're still trying to load the ${label}. The connection may be slow.`,
7476
+ action: onRetry ? /* @__PURE__ */ jsx(
7477
+ "button",
7478
+ {
7479
+ type: "button",
7480
+ onClick: onRetry,
7481
+ className: "rounded bg-foreground/10 px-3 py-1.5 text-sm font-medium hover:bg-foreground/15",
7482
+ children: "Try again"
7483
+ }
7484
+ ) : null
7485
+ }
7486
+ ) });
7487
+ }
7488
+ return /* @__PURE__ */ jsxs("div", { className, role: "status", "aria-busy": "true", "aria-live": "polite", children: [
7489
+ skeleton,
7490
+ phase === "gentle" ? /* @__PURE__ */ jsxs("div", { className: "mt-3 text-center text-sm text-muted-foreground", children: [
7491
+ "Loading ",
7492
+ label,
7493
+ "\u2026"
7494
+ ] }) : null,
7495
+ phase === "firm" ? /* @__PURE__ */ jsx("div", { className: "mt-3 text-center text-sm text-muted-foreground", children: "Still working on it \u2014 almost there." }) : null
7496
+ ] });
7497
+ }
7498
+ function ProgressiveImage({
7499
+ src,
7500
+ alt,
7501
+ lqip,
7502
+ width,
7503
+ height,
7504
+ loading = "lazy",
7505
+ fit = "cover",
7506
+ className,
7507
+ onLoad,
7508
+ onError
7509
+ }) {
7510
+ const [loaded, setLoaded] = React25.useState(false);
7511
+ return /* @__PURE__ */ jsxs(
7512
+ "div",
7513
+ {
7514
+ className: cn("relative overflow-hidden bg-muted", className),
7515
+ style: { width, height },
7516
+ children: [
7517
+ lqip ? /* @__PURE__ */ jsx(
7518
+ "img",
7519
+ {
7520
+ src: lqip,
7521
+ alt: "",
7522
+ "aria-hidden": "true",
7523
+ className: cn(
7524
+ "absolute inset-0 h-full w-full object-cover blur-md scale-110 transition-opacity duration-300",
7525
+ loaded ? "opacity-0" : "opacity-100"
7526
+ )
7527
+ }
7528
+ ) : null,
7529
+ /* @__PURE__ */ jsx(
7530
+ "img",
7531
+ {
7532
+ src,
7533
+ alt,
7534
+ loading,
7535
+ onLoad: () => {
7536
+ setLoaded(true);
7537
+ onLoad?.();
7538
+ },
7539
+ onError,
7540
+ className: cn(
7541
+ "absolute inset-0 h-full w-full transition-opacity duration-300",
7542
+ `object-${fit}`,
7543
+ loaded ? "opacity-100" : "opacity-0"
7544
+ )
7545
+ }
7546
+ )
7547
+ ]
7548
+ }
7549
+ );
7550
+ }
7551
+ function HazoUiToaster({
7552
+ position = "bottom-right",
7553
+ closeButton = true,
7554
+ visibleToasts = 5
7555
+ } = {}) {
7556
+ return /* @__PURE__ */ jsx(
7557
+ Toaster,
7558
+ {
7559
+ position,
7560
+ closeButton,
7561
+ visibleToasts,
7562
+ theme: "system",
7563
+ richColors: true,
7564
+ toastOptions: {
7565
+ classNames: {
7566
+ toast: "group rounded-md border bg-background text-foreground shadow-lg",
7567
+ title: "font-medium",
7568
+ description: "text-muted-foreground text-sm"
7569
+ }
7570
+ }
7571
+ }
7572
+ );
7573
+ }
7574
+ function successToast({ title, description, duration = 3e3, action }) {
7575
+ return toast.success(title, {
7576
+ description,
7577
+ duration,
7578
+ icon: /* @__PURE__ */ jsx(CheckCircle2, { className: "h-4 w-4 text-emerald-600" }),
7579
+ action: action ? { label: action.label, onClick: action.onClick } : void 0
7580
+ });
7581
+ }
7582
+ function errorToast({ title, description, duration = 5e3, action }) {
7583
+ return toast.error(title, {
7584
+ description,
7585
+ duration,
7586
+ icon: /* @__PURE__ */ jsx(OctagonAlert, { className: "h-4 w-4 text-destructive" }),
7587
+ action: action ? { label: action.label, onClick: action.onClick } : void 0
7588
+ });
7589
+ }
7590
+ function useLoadingState(initial = false) {
7591
+ const [isLoading, setLoading] = useState(initial);
7592
+ const withLoading = useCallback(async (fn) => {
7593
+ setLoading(true);
7594
+ try {
7595
+ return await fn();
7596
+ } finally {
7597
+ setLoading(false);
7598
+ }
7599
+ }, []);
7600
+ return { isLoading, setLoading, withLoading };
7601
+ }
7602
+ function useErrorDisplay() {
7603
+ const [error, setRaw] = useState(null);
7604
+ const setError = useCallback((value) => {
7605
+ if (value == null) {
7606
+ setRaw(null);
7607
+ return;
7608
+ }
7609
+ if (typeof value === "string") {
7610
+ setRaw(value);
7611
+ return;
7612
+ }
7613
+ if (value instanceof Error) {
7614
+ setRaw(value.message);
7615
+ return;
7616
+ }
7617
+ setRaw(String(value));
7618
+ }, []);
7619
+ const clearError = useCallback(() => setRaw(null), []);
7620
+ return { error, setError, clearError };
7621
+ }
7622
+ function KanbanCard({
7623
+ item,
7624
+ renderCard,
7625
+ dragging = false,
7626
+ cardClassName,
7627
+ showEdit = false,
7628
+ onEditRequest
7629
+ }) {
7630
+ const {
7631
+ attributes,
7632
+ listeners,
7633
+ setNodeRef,
7634
+ transform,
7635
+ transition,
7636
+ isDragging
7637
+ } = useSortable({ id: item.id, data: { columnKey: item.columnKey } });
7638
+ const priority_var = item.priority ? `--hazo-kanban-priority-${String(item.priority).toLowerCase()}` : null;
7639
+ const style = {
7640
+ transform: CSS.Transform.toString(transform),
7641
+ transition,
7642
+ backgroundColor: "hsl(var(--hazo-kanban-card-bg))",
7643
+ border: `1px solid hsl(var(--hazo-kanban-card-border))`,
7644
+ borderLeft: priority_var ? `4px solid hsl(var(${priority_var}))` : `1px solid hsl(var(--hazo-kanban-card-border))`,
7645
+ opacity: isDragging && !dragging ? 0.4 : 1,
7646
+ cursor: "grab"
7647
+ };
7648
+ return /* @__PURE__ */ jsxs(
7649
+ "div",
7650
+ {
7651
+ ref: setNodeRef,
7652
+ style,
7653
+ className: cn(
7654
+ "cls_hazo_kanban_card group relative rounded-md p-3 mb-2 select-none",
7655
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
7656
+ dragging && "cls_hazo_kanban_card_overlay shadow-lg",
7657
+ cardClassName
7658
+ ),
7659
+ ...attributes,
7660
+ ...listeners,
7661
+ role: "button",
7662
+ tabIndex: 0,
7663
+ "aria-roledescription": "draggable card",
7664
+ "aria-grabbed": isDragging,
7665
+ children: [
7666
+ showEdit && onEditRequest && !dragging && /* @__PURE__ */ jsx(
7667
+ "button",
7668
+ {
7669
+ type: "button",
7670
+ onPointerDown: (e) => e.stopPropagation(),
7671
+ onMouseDown: (e) => e.stopPropagation(),
7672
+ onKeyDown: (e) => e.stopPropagation(),
7673
+ onClick: (e) => {
7674
+ e.stopPropagation();
7675
+ onEditRequest(item);
7676
+ },
7677
+ "aria-label": `Edit ${item.id}`,
7678
+ className: cn(
7679
+ "cls_hazo_kanban_card_edit absolute top-1.5 right-1.5",
7680
+ "p-1 rounded-md text-muted-foreground hover:text-foreground hover:bg-accent",
7681
+ "opacity-0 group-hover:opacity-100 group-focus-within:opacity-100",
7682
+ "focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
7683
+ "transition-opacity duration-150"
7684
+ ),
7685
+ tabIndex: 0,
7686
+ children: /* @__PURE__ */ jsx(Pencil, { className: "h-3.5 w-3.5" })
7687
+ }
7688
+ ),
7689
+ renderCard(item)
7690
+ ]
7691
+ }
7692
+ );
7693
+ }
7694
+ function KanbanColumn({
7695
+ column,
7696
+ items,
7697
+ renderCard,
7698
+ emptyColumn,
7699
+ cardClassName,
7700
+ showEdit,
7701
+ onEditRequest
7702
+ }) {
7703
+ const { setNodeRef, isOver } = useDroppable({
7704
+ id: `column:${column.key}`,
7705
+ data: { columnKey: column.key, isColumn: true }
7706
+ });
7707
+ return /* @__PURE__ */ jsxs(
7708
+ "div",
7709
+ {
7710
+ ref: setNodeRef,
7711
+ className: cn(
7712
+ "cls_hazo_kanban_column flex flex-col rounded-md p-2",
7713
+ isOver && "cls_hazo_kanban_column_over bg-accent/30 ring-2 ring-ring/40"
7714
+ ),
7715
+ children: [
7716
+ /* @__PURE__ */ jsxs("div", { className: "cls_hazo_kanban_column_head flex items-center justify-between mb-2 px-1 text-xs uppercase tracking-wider text-muted-foreground", children: [
7717
+ /* @__PURE__ */ jsx("span", { className: "cls_hazo_kanban_column_title", children: column.title }),
7718
+ /* @__PURE__ */ jsx("span", { className: "cls_hazo_kanban_column_count rounded-full bg-muted px-2 py-0.5 text-foreground", children: items.length })
7719
+ ] }),
7720
+ /* @__PURE__ */ jsx(
7721
+ SortableContext,
7722
+ {
7723
+ items: items.map((i) => i.id),
7724
+ strategy: verticalListSortingStrategy,
7725
+ children: /* @__PURE__ */ jsx("div", { className: "cls_hazo_kanban_column_body flex-1 min-h-[40px]", children: items.length === 0 ? /* @__PURE__ */ jsx("div", { className: "cls_hazo_kanban_column_empty text-xs text-muted-foreground py-2 px-1", children: emptyColumn }) : items.map((item) => /* @__PURE__ */ jsx(
7726
+ KanbanCard,
7727
+ {
7728
+ item,
7729
+ renderCard,
7730
+ cardClassName,
7731
+ showEdit,
7732
+ onEditRequest
7733
+ },
7734
+ item.id
7735
+ )) })
7736
+ }
7737
+ )
7738
+ ]
7739
+ }
7740
+ );
7741
+ }
7742
+ var DEFAULT_PRIORITIES = ["P0", "P1", "P2", "P3"];
7743
+ function humanize(key) {
7744
+ return key.replace(/[_\-]+/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\s+/g, " ").trim().split(" ").map((w) => w ? w[0].toUpperCase() + w.slice(1) : w).join(" ");
7745
+ }
7746
+ function auto_detect_fields(item, columns) {
7747
+ const skip = /* @__PURE__ */ new Set(["id", "columnKey", "priority"]);
7748
+ const out = [];
7749
+ for (const [key, value] of Object.entries(item)) {
7750
+ if (skip.has(key)) continue;
7751
+ if (typeof value === "string") {
7752
+ out.push({ key, type: "text" });
7753
+ }
7754
+ }
7755
+ if (columns.length > 0) {
7756
+ out.push({ key: "columnKey", type: "status", label: "Status" });
7757
+ }
7758
+ return out;
7759
+ }
7760
+ function KanbanEditor({
7761
+ item,
7762
+ columns,
7763
+ fields,
7764
+ priorities,
7765
+ titleFn,
7766
+ renderBody,
7767
+ hideFooter = false,
7768
+ onSave,
7769
+ onClose
7770
+ }) {
7771
+ const [draft, set_draft] = React25.useState(item);
7772
+ const [saving, set_saving] = React25.useState(false);
7773
+ const [error, set_error] = React25.useState(null);
7774
+ const item_id = item?.id ?? null;
7775
+ React25.useEffect(() => {
7776
+ set_draft(item);
7777
+ set_error(null);
7778
+ set_saving(false);
7779
+ }, [item_id]);
7780
+ const resolved_columns = columns ?? [];
7781
+ const resolved_priorities = priorities ?? DEFAULT_PRIORITIES;
7782
+ const resolved_fields = React25.useMemo(() => {
7783
+ if (fields) return fields;
7784
+ if (!item) return [];
7785
+ return auto_detect_fields(item, resolved_columns);
7786
+ }, [fields, item, resolved_columns]);
7787
+ const required_keys = React25.useMemo(
7788
+ () => resolved_fields.filter(
7789
+ (f) => f.required && (f.type === "text" || f.type === "textarea" || f.type === "number")
7790
+ ).map((f) => f.key),
7791
+ [resolved_fields]
7792
+ );
7793
+ const all_required_filled = React25.useMemo(() => {
7794
+ if (!draft) return false;
7795
+ for (const key of required_keys) {
7796
+ const v = draft[key];
7797
+ if (v === void 0 || v === null || v === "") return false;
7798
+ if (typeof v === "string" && v.trim() === "") return false;
7799
+ }
7800
+ return true;
7801
+ }, [draft, required_keys]);
7802
+ const is_dirty = React25.useMemo(() => {
7803
+ if (!draft || !item) return false;
7804
+ try {
7805
+ return JSON.stringify(draft) !== JSON.stringify(item);
7806
+ } catch {
7807
+ return draft !== item;
7808
+ }
7809
+ }, [draft, item]);
7810
+ const handle_save = React25.useCallback(async () => {
7811
+ if (!draft || !item) return;
7812
+ if (saving) return;
7813
+ set_error(null);
7814
+ if (!onSave) {
7815
+ onClose();
7816
+ return;
7817
+ }
7818
+ const result = onSave({ itemId: item.id, item, next: draft });
7819
+ if (result && typeof result.then === "function") {
7820
+ set_saving(true);
7821
+ try {
7822
+ await result;
7823
+ set_saving(false);
7824
+ onClose();
7825
+ } catch (err) {
7826
+ set_saving(false);
7827
+ const message = err instanceof Error ? err.message : String(err);
7828
+ set_error(message);
7829
+ }
7830
+ } else {
7831
+ onClose();
7832
+ }
7833
+ }, [draft, item, onSave, onClose, saving]);
7834
+ const ctx = {
7835
+ draft: draft ?? item,
7836
+ setDraft: (next) => {
7837
+ set_draft((prev) => {
7838
+ const base = prev ?? item;
7839
+ if (!base) return prev;
7840
+ if (typeof next === "function") {
7841
+ return next(base);
7842
+ }
7843
+ return next;
7844
+ });
7845
+ },
7846
+ save: handle_save,
7847
+ close: onClose,
7848
+ saving,
7849
+ error,
7850
+ isDirty: is_dirty
7851
+ };
7852
+ const open = item !== null;
7853
+ const title = item && titleFn ? titleFn(item) : item ? `Edit ${item.id}` : "";
7854
+ const priority_var = item?.priority ? `--hazo-kanban-priority-${String(item.priority).toLowerCase()}` : null;
7855
+ const header_bar_color = priority_var ? `hsl(var(${priority_var}))` : void 0;
7856
+ const use_default_footer = !(renderBody && hideFooter);
7857
+ return /* @__PURE__ */ jsx(
7858
+ HazoUiDialog,
7859
+ {
7860
+ open,
7861
+ onOpenChange: (o) => {
7862
+ if (!o && !saving) onClose();
7863
+ },
7864
+ title,
7865
+ description: "Update card details below.",
7866
+ sizeWidth: "min(90vw, 480px)",
7867
+ openAnimation: "none",
7868
+ closeAnimation: "none",
7869
+ headerBar: !!priority_var,
7870
+ headerBarColor: header_bar_color,
7871
+ contentClassName: cn("cls_hazo_kanban_editor", priority_var && "pt-0"),
7872
+ actionButtonText: saving ? "Saving\u2026" : "Save",
7873
+ actionButtonIcon: saving ? void 0 : /* @__PURE__ */ jsx(Check, { className: "h-4 w-4 mr-2" }),
7874
+ actionButtonLoading: saving,
7875
+ actionButtonDisabled: !is_dirty || !all_required_filled || saving,
7876
+ cancelButtonText: "Cancel",
7877
+ showCancelButton: true,
7878
+ onConfirm: handle_save,
7879
+ onCancel: onClose,
7880
+ footerContent: use_default_footer ? void 0 : /* @__PURE__ */ jsx("span", {}),
7881
+ children: /* @__PURE__ */ jsxs("div", { className: "cls_hazo_kanban_editor_body flex flex-col gap-4", children: [
7882
+ item && draft && renderBody ? renderBody(item, ctx) : draft ? resolved_fields.map((field) => /* @__PURE__ */ jsx(
7883
+ KanbanEditorFieldRow,
7884
+ {
7885
+ field,
7886
+ draft,
7887
+ setDraft: (updater) => set_draft(
7888
+ (prev) => prev ? updater(prev) : prev
7889
+ ),
7890
+ priorities: resolved_priorities,
7891
+ columns: resolved_columns
7892
+ },
7893
+ field.key
7894
+ )) : null,
7895
+ error && /* @__PURE__ */ jsx(
7896
+ "div",
7897
+ {
7898
+ className: "cls_hazo_kanban_editor_error mt-1 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-sm text-destructive",
7899
+ role: "alert",
7900
+ children: error
7901
+ }
7902
+ )
7903
+ ] })
7904
+ }
7905
+ );
7906
+ }
7907
+ function KanbanEditorFieldRow({
7908
+ field,
7909
+ draft,
7910
+ setDraft,
7911
+ priorities,
7912
+ columns
7913
+ }) {
7914
+ const id = `kanban-editor-${field.key}`;
7915
+ const label = field.label ?? humanize(field.key);
7916
+ const value = draft[field.key];
7917
+ const set_value = (next_value) => {
7918
+ setDraft((prev) => ({ ...prev, [field.key]: next_value }));
7919
+ };
7920
+ const required_marker_shown = field.required && (field.type === "text" || field.type === "textarea" || field.type === "number");
7921
+ return /* @__PURE__ */ jsxs("div", { className: cn("cls_hazo_kanban_editor_field flex flex-col gap-1.5"), children: [
7922
+ /* @__PURE__ */ jsxs(Label3, { htmlFor: id, className: "text-xs font-medium text-muted-foreground", children: [
7923
+ label,
7924
+ required_marker_shown && /* @__PURE__ */ jsx("span", { className: "text-destructive ml-0.5", children: "*" })
7925
+ ] }),
7926
+ field.type === "text" && /* @__PURE__ */ jsx(
7927
+ Input,
7928
+ {
7929
+ id,
7930
+ value: typeof value === "string" ? value : "",
7931
+ placeholder: field.placeholder,
7932
+ onChange: (e) => set_value(e.target.value)
7933
+ }
7934
+ ),
7935
+ field.type === "textarea" && /* @__PURE__ */ jsx(
7936
+ Textarea,
7937
+ {
7938
+ id,
7939
+ value: typeof value === "string" ? value : "",
7940
+ placeholder: field.placeholder,
7941
+ rows: 3,
7942
+ onChange: (e) => set_value(e.target.value)
7943
+ }
7944
+ ),
7945
+ field.type === "number" && /* @__PURE__ */ jsx(
7946
+ Input,
7947
+ {
7948
+ id,
7949
+ type: "number",
7950
+ value: typeof value === "number" ? value : value === "" || value == null ? "" : Number(value) || 0,
7951
+ placeholder: field.placeholder,
7952
+ onChange: (e) => set_value(e.target.value === "" ? void 0 : Number(e.target.value))
7953
+ }
7954
+ ),
7955
+ field.type === "checkbox" && /* @__PURE__ */ jsx(
7956
+ Checkbox,
7957
+ {
7958
+ id,
7959
+ checked: !!value,
7960
+ onCheckedChange: (checked) => set_value(checked === true)
7961
+ }
7962
+ ),
7963
+ field.type === "select" && /* @__PURE__ */ jsxs(
7964
+ Select,
7965
+ {
7966
+ value: typeof value === "string" ? value : "",
7967
+ onValueChange: set_value,
7968
+ children: [
7969
+ /* @__PURE__ */ jsx(SelectTrigger, { id, children: /* @__PURE__ */ jsx(
7970
+ SelectValue,
7971
+ {
7972
+ placeholder: field.placeholder ?? `Select ${label}\u2026`
7973
+ }
7974
+ ) }),
7975
+ /* @__PURE__ */ jsx(SelectContent, { children: (field.options ?? []).map((opt) => /* @__PURE__ */ jsx(SelectItem, { value: opt, children: opt }, opt)) })
7976
+ ]
7977
+ }
7978
+ ),
7979
+ field.type === "priority" && /* @__PURE__ */ jsxs(
7980
+ Select,
7981
+ {
7982
+ value: typeof value === "string" ? value : "",
7983
+ onValueChange: set_value,
7984
+ children: [
7985
+ /* @__PURE__ */ jsx(SelectTrigger, { id, children: /* @__PURE__ */ jsx(
7986
+ SelectValue,
7987
+ {
7988
+ placeholder: field.placeholder ?? "Select priority\u2026"
7989
+ }
7990
+ ) }),
7991
+ /* @__PURE__ */ jsx(SelectContent, { children: priorities.map((p) => /* @__PURE__ */ jsx(SelectItem, { value: p, children: p }, p)) })
7992
+ ]
7993
+ }
7994
+ ),
7995
+ field.type === "status" && /* @__PURE__ */ jsxs(
7996
+ Select,
7997
+ {
7998
+ value: typeof value === "string" ? value : "",
7999
+ onValueChange: set_value,
8000
+ children: [
8001
+ /* @__PURE__ */ jsx(SelectTrigger, { id, children: /* @__PURE__ */ jsx(
8002
+ SelectValue,
8003
+ {
8004
+ placeholder: field.placeholder ?? "Select status\u2026"
8005
+ }
8006
+ ) }),
8007
+ /* @__PURE__ */ jsx(SelectContent, { children: columns.map((col) => /* @__PURE__ */ jsx(SelectItem, { value: col.key, children: col.title }, col.key)) })
8008
+ ]
8009
+ }
8010
+ )
8011
+ ] });
8012
+ }
8013
+ var EMPTY_FILTER = {
8014
+ search: "",
8015
+ categories: [],
8016
+ priority: null
8017
+ };
8018
+ function HazoUiKanbanFilter({
8019
+ search = true,
8020
+ searchPlaceholder = "Search...",
8021
+ categories,
8022
+ priorities,
8023
+ value,
8024
+ defaultValue,
8025
+ onChange,
8026
+ className
8027
+ }) {
8028
+ const is_controlled = value !== void 0;
8029
+ const [internal, set_internal] = React25.useState(
8030
+ defaultValue ?? EMPTY_FILTER
8031
+ );
8032
+ const current = is_controlled ? value : internal;
8033
+ const update = React25.useCallback(
8034
+ (next) => {
8035
+ if (!is_controlled) set_internal(next);
8036
+ onChange?.(next);
8037
+ },
8038
+ [is_controlled, onChange]
8039
+ );
8040
+ const has_active = current.search.length > 0 || current.categories.length > 0 || current.priority !== null;
8041
+ return /* @__PURE__ */ jsxs(
8042
+ "div",
8043
+ {
8044
+ className: cn(
8045
+ "cls_hazo_kanban_filter flex flex-wrap items-center gap-3 p-2",
8046
+ className
8047
+ ),
8048
+ children: [
8049
+ search && /* @__PURE__ */ jsx(
8050
+ Input,
8051
+ {
8052
+ value: current.search,
8053
+ onChange: (e) => update({ ...current, search: e.target.value }),
8054
+ placeholder: searchPlaceholder,
8055
+ className: "cls_hazo_kanban_filter_search w-full sm:w-64"
8056
+ }
8057
+ ),
8058
+ categories && categories.length > 0 && /* @__PURE__ */ jsx(
8059
+ ToggleGroup,
8060
+ {
8061
+ type: "multiple",
8062
+ value: current.categories,
8063
+ onValueChange: (cats) => update({ ...current, categories: cats }),
8064
+ className: "cls_hazo_kanban_filter_categories flex flex-wrap gap-1",
8065
+ children: categories.map((cat) => /* @__PURE__ */ jsx(
8066
+ ToggleGroupItem,
8067
+ {
8068
+ value: cat,
8069
+ size: "sm",
8070
+ className: "cls_hazo_kanban_filter_category_chip",
8071
+ children: cat
8072
+ },
8073
+ cat
8074
+ ))
8075
+ }
8076
+ ),
8077
+ priorities && priorities.length > 0 && /* @__PURE__ */ jsx(
8078
+ ToggleGroup,
8079
+ {
8080
+ type: "single",
8081
+ value: current.priority ?? "",
8082
+ onValueChange: (p) => update({
8083
+ ...current,
8084
+ priority: p ? p : null
8085
+ }),
8086
+ className: "cls_hazo_kanban_filter_priority flex gap-1",
8087
+ children: priorities.map((p) => /* @__PURE__ */ jsx(
8088
+ ToggleGroupItem,
8089
+ {
8090
+ value: p,
8091
+ size: "sm",
8092
+ className: "cls_hazo_kanban_filter_priority_chip",
8093
+ children: p
8094
+ },
8095
+ p
8096
+ ))
8097
+ }
8098
+ ),
8099
+ has_active && /* @__PURE__ */ jsxs(
8100
+ Button,
8101
+ {
8102
+ variant: "ghost",
8103
+ size: "sm",
8104
+ onClick: () => update(EMPTY_FILTER),
8105
+ className: "cls_hazo_kanban_filter_clear",
8106
+ children: [
8107
+ /* @__PURE__ */ jsx(X, { className: "h-4 w-4 mr-1" }),
8108
+ "Clear"
8109
+ ]
8110
+ }
8111
+ )
8112
+ ]
8113
+ }
8114
+ );
8115
+ }
8116
+
8117
+ // src/components/hazo_ui_kanban/apply_kanban_filter.ts
8118
+ function applyKanbanFilter(items, filter) {
8119
+ const search = filter.search.trim().toLowerCase();
8120
+ return items.filter((item) => {
8121
+ if (filter.priority && item.priority !== filter.priority) {
8122
+ return false;
8123
+ }
8124
+ if (filter.categories.length > 0) {
8125
+ const cat = item.category;
8126
+ if (typeof cat !== "string" || !filter.categories.includes(cat)) {
8127
+ return false;
8128
+ }
8129
+ }
8130
+ if (search) {
8131
+ const haystack = Object.values(item).filter((v) => typeof v === "string").join(" ").toLowerCase();
8132
+ if (!haystack.includes(search)) {
8133
+ return false;
8134
+ }
8135
+ }
8136
+ return true;
8137
+ });
8138
+ }
8139
+ function default_announcements(itemLabel) {
8140
+ return {
8141
+ onDragStart: ({ item, fromColumn }) => `Picked up ${itemLabel(item)}. Currently in ${fromColumn}. Use arrow keys to choose a different column. Press space to drop, escape to cancel.`,
8142
+ onDragOver: ({ item, overColumn }) => overColumn ? `${itemLabel(item)} over ${overColumn}.` : "",
8143
+ onDragEnd: ({ item, fromColumn, toColumn, newIndex }) => fromColumn === toColumn ? `${itemLabel(item)} reordered to position ${newIndex + 1} in ${toColumn}.` : `${itemLabel(item)} dropped in ${toColumn}, position ${newIndex + 1}.`,
8144
+ onDragCancel: ({ item, fromColumn }) => `Movement cancelled. ${itemLabel(item)} returned to ${fromColumn}.`
8145
+ };
8146
+ }
8147
+ function group_items_by_column(items, overlay, columns) {
8148
+ const out = /* @__PURE__ */ new Map();
8149
+ for (const col of columns) out.set(col.key, []);
8150
+ const overlay_inserts = /* @__PURE__ */ new Map();
8151
+ for (const col of columns) overlay_inserts.set(col.key, []);
8152
+ for (const item of items) {
8153
+ const ov = overlay.get(item.id);
8154
+ if (ov) {
8155
+ const bucket = overlay_inserts.get(ov.columnKey);
8156
+ if (bucket) {
8157
+ bucket.push({ item, index: ov.index });
8158
+ }
8159
+ } else {
8160
+ const bucket = out.get(item.columnKey);
8161
+ if (bucket) bucket.push(item);
8162
+ }
8163
+ }
8164
+ for (const col of columns) {
8165
+ const inserts = overlay_inserts.get(col.key) ?? [];
8166
+ inserts.sort((a, b) => a.index - b.index);
8167
+ const arr = out.get(col.key) ?? [];
8168
+ for (const { item, index } of inserts) {
8169
+ const at = Math.max(0, Math.min(index, arr.length));
8170
+ arr.splice(at, 0, item);
8171
+ }
8172
+ out.set(col.key, arr);
8173
+ }
8174
+ return out;
8175
+ }
8176
+ function HazoUiKanban({
8177
+ columns,
8178
+ items,
8179
+ renderCard,
8180
+ onMove,
8181
+ onReorder,
8182
+ mobileBreakpoint = 640,
8183
+ announcements,
8184
+ emptyColumn = "\u2014",
8185
+ className,
8186
+ cardClassName,
8187
+ itemLabel,
8188
+ editorFields,
8189
+ editorPriorities,
8190
+ editorTitle,
8191
+ renderCardEditor,
8192
+ hideEditorFooter,
8193
+ onCardSave,
8194
+ disableEdit = false
8195
+ }) {
8196
+ const label_fn = React25.useCallback(
8197
+ (item) => itemLabel ? itemLabel(item) : item.id,
8198
+ [itemLabel]
8199
+ );
8200
+ const dnd_context_id = React25.useId();
8201
+ const [overlay, set_overlay] = React25.useState(
8202
+ /* @__PURE__ */ new Map()
8203
+ );
8204
+ const [active_id, set_active_id] = React25.useState(null);
8205
+ const [active_tab, set_active_tab] = React25.useState(columns[0]?.key ?? "");
8206
+ const [editing_item, set_editing_item] = React25.useState(null);
8207
+ const show_edit = !disableEdit && typeof onCardSave === "function";
8208
+ const handle_edit_request = React25.useCallback(
8209
+ (it) => {
8210
+ const typed = items.find((x) => x.id === it.id);
8211
+ if (typed) set_editing_item(typed);
8212
+ },
8213
+ [items]
8214
+ );
8215
+ const handle_editor_close = React25.useCallback(() => {
8216
+ set_editing_item(null);
8217
+ }, []);
8218
+ React25.useEffect(() => {
8219
+ if (overlay.size === 0) return;
8220
+ set_overlay((prev) => {
8221
+ let changed = false;
8222
+ const next = new Map(prev);
8223
+ for (const [item_id, pos] of prev.entries()) {
8224
+ const item = items.find((i) => i.id === item_id);
8225
+ if (item && item.columnKey === pos.columnKey) {
8226
+ next.delete(item_id);
8227
+ changed = true;
8228
+ }
8229
+ }
8230
+ return changed ? next : prev;
8231
+ });
8232
+ }, [items, overlay]);
8233
+ const grouped = React25.useMemo(
8234
+ () => group_items_by_column(items, overlay, columns),
8235
+ [items, overlay, columns]
8236
+ );
8237
+ const find_item = React25.useCallback(
8238
+ (id) => items.find((i) => i.id === id),
8239
+ [items]
8240
+ );
8241
+ const sensors = useSensors(
8242
+ useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
8243
+ useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })
8244
+ );
8245
+ const merged_announcements = React25.useMemo(() => {
8246
+ const defaults = default_announcements(label_fn);
8247
+ return {
8248
+ onDragStart: announcements?.onDragStart ?? defaults.onDragStart,
8249
+ onDragOver: announcements?.onDragOver ?? defaults.onDragOver,
8250
+ onDragEnd: announcements?.onDragEnd ?? defaults.onDragEnd,
8251
+ onDragCancel: announcements?.onDragCancel ?? defaults.onDragCancel
8252
+ };
8253
+ }, [announcements, label_fn]);
8254
+ const dnd_announcements = React25.useMemo(
8255
+ () => ({
8256
+ onDragStart({ active }) {
8257
+ const id = String(active.id);
8258
+ const item = find_item(id);
8259
+ if (!item) return "";
8260
+ const col = columns.find((c) => c.key === item.columnKey);
8261
+ return merged_announcements.onDragStart({
8262
+ item,
8263
+ fromColumn: col?.title ?? item.columnKey
8264
+ });
8265
+ },
8266
+ onDragOver({
8267
+ active,
8268
+ over
8269
+ }) {
8270
+ const id = String(active.id);
8271
+ const item = find_item(id);
8272
+ if (!item) return "";
8273
+ const over_col_key = over ? over.data?.current?.columnKey ?? String(over.id).replace(/^column:/, "") : null;
8274
+ const col = over_col_key ? columns.find((c) => c.key === over_col_key) : null;
8275
+ return merged_announcements.onDragOver({
8276
+ item,
8277
+ overColumn: col?.title ?? null
8278
+ });
8279
+ },
8280
+ onDragEnd({
8281
+ active,
8282
+ over
8283
+ }) {
8284
+ const id = String(active.id);
8285
+ const item = find_item(id);
8286
+ if (!item) return "";
8287
+ const from_col = columns.find((c) => c.key === item.columnKey);
8288
+ const over_col_key = over ? over.data?.current?.columnKey ?? String(over.id).replace(/^column:/, "") : null;
8289
+ const to_col = over_col_key ? columns.find((c) => c.key === over_col_key) ?? from_col : from_col;
8290
+ const target = over_col_key ? grouped.get(over_col_key) ?? [] : grouped.get(item.columnKey) ?? [];
8291
+ const new_index = over && String(over.id) !== `column:${over_col_key}` ? target.findIndex((it) => it.id === String(over.id)) : target.length;
8292
+ return merged_announcements.onDragEnd({
8293
+ item,
8294
+ fromColumn: from_col?.title ?? item.columnKey,
8295
+ toColumn: to_col?.title ?? item.columnKey,
8296
+ newIndex: Math.max(0, new_index)
8297
+ });
8298
+ },
8299
+ onDragCancel({ active }) {
8300
+ const id = String(active.id);
8301
+ const item = find_item(id);
8302
+ if (!item) return "";
8303
+ const col = columns.find((c) => c.key === item.columnKey);
8304
+ return merged_announcements.onDragCancel({
8305
+ item,
8306
+ fromColumn: col?.title ?? item.columnKey
8307
+ });
8308
+ }
8309
+ }),
8310
+ [find_item, columns, grouped, merged_announcements]
8311
+ );
8312
+ const handle_drag_start = React25.useCallback((event) => {
8313
+ set_active_id(String(event.active.id));
8314
+ }, []);
8315
+ const make_revert_handle = React25.useCallback(
8316
+ (item_id) => ({
8317
+ revert: () => {
8318
+ set_overlay((prev) => {
8319
+ if (!prev.has(item_id)) return prev;
8320
+ const next = new Map(prev);
8321
+ next.delete(item_id);
8322
+ return next;
8323
+ });
8324
+ }
8325
+ }),
8326
+ []
8327
+ );
8328
+ const handle_drag_end = React25.useCallback(
8329
+ (event) => {
8330
+ const active_id_str = String(event.active.id);
8331
+ set_active_id(null);
8332
+ const item = find_item(active_id_str);
8333
+ if (!item) return;
8334
+ if (!event.over) return;
8335
+ const over_id = String(event.over.id);
8336
+ const over_data = event.over.data?.current;
8337
+ const dest_column_key = over_data?.columnKey ?? over_id.replace(/^column:/, "");
8338
+ const dest_column = columns.find((c) => c.key === dest_column_key);
8339
+ if (!dest_column) return;
8340
+ if (dest_column.accepts && !dest_column.accepts(item)) return;
8341
+ const dest_items_pre_overlay = grouped.get(dest_column_key) ?? [];
8342
+ let new_index;
8343
+ if (over_data?.isColumn) {
8344
+ new_index = dest_items_pre_overlay.length;
8345
+ } else {
8346
+ const idx = dest_items_pre_overlay.findIndex((i) => i.id === over_id);
8347
+ new_index = idx === -1 ? dest_items_pre_overlay.length : idx;
8348
+ }
8349
+ const handle = make_revert_handle(active_id_str);
8350
+ if (item.columnKey === dest_column_key) {
8351
+ if (active_id_str === over_id) return;
8352
+ set_overlay((prev) => {
8353
+ const next = new Map(prev);
8354
+ next.set(active_id_str, {
8355
+ columnKey: dest_column_key,
8356
+ index: new_index
8357
+ });
8358
+ return next;
8359
+ });
8360
+ const reorder_event = {
8361
+ itemId: active_id_str,
8362
+ item,
8363
+ columnKey: dest_column_key,
8364
+ newIndex: new_index,
8365
+ revert: handle.revert
8366
+ };
8367
+ onReorder?.(reorder_event);
8368
+ return;
8369
+ }
8370
+ set_overlay((prev) => {
8371
+ const next = new Map(prev);
8372
+ next.set(active_id_str, {
8373
+ columnKey: dest_column_key,
8374
+ index: new_index
8375
+ });
8376
+ return next;
8377
+ });
8378
+ const move_event = {
8379
+ itemId: active_id_str,
8380
+ item,
8381
+ fromColumn: item.columnKey,
8382
+ toColumn: dest_column_key,
8383
+ newIndex: new_index,
8384
+ revert: handle.revert
8385
+ };
8386
+ onMove?.(move_event);
8387
+ },
8388
+ [find_item, columns, grouped, onMove, onReorder, make_revert_handle]
8389
+ );
8390
+ const handle_drag_cancel = React25.useCallback(() => {
8391
+ set_active_id(null);
8392
+ }, []);
8393
+ const active_item = active_id ? find_item(active_id) : null;
8394
+ const is_custom_breakpoint = mobileBreakpoint !== 640;
8395
+ const is_mobile_via_query = useMediaQuery(
8396
+ `(max-width: ${Math.max(0, mobileBreakpoint - 1)}px)`
8397
+ );
8398
+ const mobile_classes = is_custom_breakpoint ? is_mobile_via_query ? "block" : "hidden" : "sm:hidden";
8399
+ const desktop_classes = is_custom_breakpoint ? is_mobile_via_query ? "hidden" : "grid" : "hidden sm:grid";
8400
+ return /* @__PURE__ */ jsxs(
8401
+ DndContext,
8402
+ {
8403
+ id: dnd_context_id,
8404
+ sensors,
8405
+ collisionDetection: closestCorners,
8406
+ onDragStart: handle_drag_start,
8407
+ onDragEnd: handle_drag_end,
8408
+ onDragCancel: handle_drag_cancel,
8409
+ accessibility: { announcements: dnd_announcements },
8410
+ children: [
8411
+ /* @__PURE__ */ jsxs("div", { className: cn("cls_hazo_kanban w-full", className), children: [
8412
+ /* @__PURE__ */ jsx("div", { className: cn("cls_hazo_kanban_mobile", mobile_classes), children: /* @__PURE__ */ jsxs(Tabs, { value: active_tab, onValueChange: set_active_tab, children: [
8413
+ /* @__PURE__ */ jsx(TabsList, { className: "grid w-full", style: { gridTemplateColumns: `repeat(${columns.length}, 1fr)` }, children: columns.map((col) => {
8414
+ const count = (grouped.get(col.key) ?? []).length;
8415
+ return /* @__PURE__ */ jsxs(TabsTrigger, { value: col.key, className: "flex flex-col gap-0.5", children: [
8416
+ /* @__PURE__ */ jsx("span", { className: "text-xs", children: col.title }),
8417
+ /* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground", children: count })
8418
+ ] }, col.key);
8419
+ }) }),
8420
+ columns.map((col) => /* @__PURE__ */ jsx(TabsContent, { value: col.key, className: "mt-3", children: /* @__PURE__ */ jsx(
8421
+ KanbanColumn,
8422
+ {
8423
+ column: col,
8424
+ items: grouped.get(col.key) ?? [],
8425
+ renderCard,
8426
+ emptyColumn,
8427
+ cardClassName,
8428
+ showEdit: show_edit,
8429
+ onEditRequest: handle_edit_request
8430
+ }
8431
+ ) }, col.key))
8432
+ ] }) }),
8433
+ /* @__PURE__ */ jsx(
8434
+ "div",
8435
+ {
8436
+ className: cn("cls_hazo_kanban_desktop gap-3", desktop_classes),
8437
+ style: { gridTemplateColumns: `repeat(${columns.length}, minmax(0, 1fr))` },
8438
+ children: columns.map((col) => /* @__PURE__ */ jsx(
8439
+ KanbanColumn,
8440
+ {
8441
+ column: col,
8442
+ items: grouped.get(col.key) ?? [],
8443
+ renderCard,
8444
+ emptyColumn,
8445
+ cardClassName,
8446
+ showEdit: show_edit,
8447
+ onEditRequest: handle_edit_request
8448
+ },
8449
+ col.key
8450
+ ))
8451
+ }
8452
+ ),
8453
+ /* @__PURE__ */ jsx(DragOverlay, { children: active_item ? /* @__PURE__ */ jsx(
8454
+ KanbanCard,
8455
+ {
8456
+ item: active_item,
8457
+ renderCard,
8458
+ dragging: true,
8459
+ cardClassName
8460
+ }
8461
+ ) : null })
8462
+ ] }),
8463
+ /* @__PURE__ */ jsx(
8464
+ KanbanEditor,
8465
+ {
8466
+ item: editing_item,
8467
+ columns,
8468
+ fields: editorFields,
8469
+ priorities: editorPriorities,
8470
+ titleFn: editorTitle,
8471
+ renderBody: renderCardEditor,
8472
+ hideFooter: hideEditorFooter,
8473
+ onSave: onCardSave,
8474
+ onClose: handle_editor_close
8475
+ }
8476
+ )
8477
+ ]
8478
+ }
8479
+ );
8480
+ }
8481
+ var Table2 = React25.forwardRef(
8482
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { className: "cls_table_wrap relative w-full overflow-auto", children: /* @__PURE__ */ jsx(
8483
+ "table",
8484
+ {
8485
+ ref,
8486
+ className: cn("w-full caption-bottom text-sm", className),
8487
+ ...props
8488
+ }
8489
+ ) })
8490
+ );
8491
+ Table2.displayName = "Table";
8492
+ var TableHeader2 = React25.forwardRef(
8493
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx("thead", { ref, className: cn("[&_tr]:border-b", className), ...props })
8494
+ );
8495
+ TableHeader2.displayName = "TableHeader";
8496
+ var TableBody = React25.forwardRef(
8497
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
8498
+ "tbody",
8499
+ {
8500
+ ref,
8501
+ className: cn("[&_tr:last-child]:border-0", className),
8502
+ ...props
8503
+ }
8504
+ )
8505
+ );
8506
+ TableBody.displayName = "TableBody";
8507
+ var TableFooter = React25.forwardRef(
8508
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
8509
+ "tfoot",
8510
+ {
8511
+ ref,
8512
+ className: cn("bg-muted/50 font-medium [&>tr]:last:border-b-0", className),
8513
+ ...props
8514
+ }
8515
+ )
8516
+ );
8517
+ TableFooter.displayName = "TableFooter";
8518
+ var TableRow2 = React25.forwardRef(
8519
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
8520
+ "tr",
8521
+ {
8522
+ ref,
8523
+ className: cn(
8524
+ "border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
8525
+ className
8526
+ ),
8527
+ ...props
8528
+ }
8529
+ )
8530
+ );
8531
+ TableRow2.displayName = "TableRow";
8532
+ var TableHead = React25.forwardRef(
8533
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
8534
+ "th",
8535
+ {
8536
+ ref,
8537
+ className: cn(
8538
+ "h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
8539
+ className
8540
+ ),
8541
+ ...props
8542
+ }
8543
+ )
8544
+ );
8545
+ TableHead.displayName = "TableHead";
8546
+ var TableCell2 = React25.forwardRef(
8547
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
8548
+ "td",
8549
+ {
8550
+ ref,
8551
+ className: cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className),
8552
+ ...props
8553
+ }
8554
+ )
8555
+ );
8556
+ TableCell2.displayName = "TableCell";
8557
+ var TableCaption = React25.forwardRef(
8558
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
8559
+ "caption",
8560
+ {
8561
+ ref,
8562
+ className: cn("mt-4 text-sm text-muted-foreground", className),
8563
+ ...props
8564
+ }
8565
+ )
8566
+ );
8567
+ TableCaption.displayName = "TableCaption";
8568
+ function TableMobileCards(props) {
8569
+ const { columns, rows, getRowKey, onRowClick, renderCell: renderCell2 } = props;
8570
+ const [titleCol, ...restCols] = columns;
8571
+ if (!titleCol) return null;
8572
+ return /* @__PURE__ */ jsx("div", { className: "cls_hazo_ui_table_mobile_cards flex flex-col gap-3", children: rows.map((row, i) => {
8573
+ const interactionProps = onRowClick ? {
8574
+ role: "button",
8575
+ tabIndex: 0,
8576
+ className: "cls_hazo_ui_table_mobile_card_clickable cursor-pointer",
8577
+ onClick: () => onRowClick(row, i),
8578
+ onKeyDown: (e) => {
8579
+ if (e.key === "Enter" || e.key === " ") {
8580
+ e.preventDefault();
8581
+ onRowClick(row, i);
8582
+ }
8583
+ }
8584
+ } : {};
8585
+ return /* @__PURE__ */ jsxs(
8586
+ Card,
8587
+ {
8588
+ ...interactionProps,
8589
+ children: [
8590
+ /* @__PURE__ */ jsx(CardHeader, { className: "pb-2", children: /* @__PURE__ */ jsx(CardTitle, { className: "text-base", children: renderCell2(titleCol, row, i) }) }),
8591
+ /* @__PURE__ */ jsx(CardContent, { className: "pt-0 space-y-1.5", children: restCols.map((c) => /* @__PURE__ */ jsxs(
8592
+ "div",
8593
+ {
8594
+ className: cn(
8595
+ "cls_hazo_ui_table_mobile_row flex items-center justify-between gap-3 text-sm"
8596
+ ),
8597
+ children: [
8598
+ /* @__PURE__ */ jsx("span", { className: "cls_hazo_ui_table_mobile_label text-muted-foreground", children: c.label }),
8599
+ /* @__PURE__ */ jsx("span", { className: cn("cls_hazo_ui_table_mobile_value", c.className), children: renderCell2(c, row, i) })
8600
+ ]
8601
+ },
8602
+ c.key
8603
+ )) })
8604
+ ]
8605
+ },
8606
+ getRowKey ? getRowKey(row, i) : i
8607
+ );
8608
+ }) });
8609
+ }
8610
+ var DEFAULT_DEBOUNCE_MS = 200;
8611
+ function useTableState(props) {
8612
+ const [sortInternal, setSortInternal] = useState(
8613
+ () => normalizeSortProp(props.defaultSort)
8614
+ );
8615
+ const isSortControlled = props.sort !== void 0;
8616
+ const sort = isSortControlled ? normalizeSortProp(props.sort) : sortInternal;
8617
+ const setSort = useCallback(
8618
+ (next) => {
8619
+ if (!isSortControlled) setSortInternal(next);
8620
+ props.onSortChange?.(next);
8621
+ },
8622
+ [isSortControlled, props.onSortChange]
8623
+ );
8624
+ const cycleHeaderSort = useCallback(
8625
+ (key, append) => {
8626
+ const next = append ? cycleAppendColumn(sort, key) : cycleSingleColumn(sort, key);
8627
+ setSort(next);
8628
+ },
8629
+ [sort, setSort]
8630
+ );
8631
+ const [filterInternal, setFilterInternal] = useState(
8632
+ () => props.defaultFilter ?? {}
8633
+ );
8634
+ const isFilterControlled = props.filter !== void 0;
8635
+ const filter = isFilterControlled ? props.filter : filterInternal;
8636
+ const setFilter = useCallback(
8637
+ (next) => {
8638
+ if (!isFilterControlled) setFilterInternal(next);
8639
+ props.onFilterChange?.(next);
8640
+ },
8641
+ [isFilterControlled, props.onFilterChange]
8642
+ );
8643
+ const [searchDraft, setSearchDraft] = useState(
8644
+ filter.search ?? ""
8645
+ );
8646
+ const debounceMs = props.searchDebounceMs ?? DEFAULT_DEBOUNCE_MS;
8647
+ useEffect(() => {
8648
+ const handle = setTimeout(() => {
8649
+ if (searchDraft === (filter.search ?? "")) return;
8650
+ setFilter({ ...filter, search: searchDraft || void 0 });
8651
+ }, debounceMs);
8652
+ return () => clearTimeout(handle);
8653
+ }, [searchDraft, debounceMs]);
8654
+ const setSearch = useCallback((s) => setSearchDraft(s), []);
8655
+ const [pageInternal, setPageInternal] = useState(
8656
+ () => props.defaultPage ?? 0
8657
+ );
8658
+ const isPageControlled = props.page !== void 0;
8659
+ const page = isPageControlled ? props.page : pageInternal;
8660
+ const setPage = useCallback(
8661
+ (next) => {
8662
+ if (!isPageControlled) setPageInternal(next);
8663
+ props.onPageChange?.(next);
8664
+ },
8665
+ [isPageControlled, props.onPageChange]
8666
+ );
8667
+ const prevSortKey = useRef(serializeSort(sort));
8668
+ const prevFilterKey = useRef(serializeFilter(filter));
8669
+ useEffect(() => {
8670
+ const sk = serializeSort(sort);
8671
+ const fk = serializeFilter(filter);
8672
+ if (sk !== prevSortKey.current || fk !== prevFilterKey.current) {
8673
+ if (!isPageControlled) setPageInternal(0);
8674
+ prevSortKey.current = sk;
8675
+ prevFilterKey.current = fk;
8676
+ }
8677
+ }, [sort, filter, isPageControlled]);
8678
+ const pageSize = props.pagination && typeof props.pagination === "object" ? props.pagination.pageSize : 0;
8679
+ const isServerMode = typeof props.onLoad === "function";
8680
+ const filtered = useMemo(
8681
+ () => isServerMode ? props.rows : applyFilter(props.rows, filter, props.columns),
8682
+ [props.rows, filter, props.columns, isServerMode]
8683
+ );
8684
+ const sorted = useMemo(
8685
+ () => isServerMode ? filtered : applySort(filtered, sort),
8686
+ [filtered, sort, isServerMode]
8687
+ );
8688
+ const pagedInMemory = useMemo(() => {
8689
+ if (isServerMode || pageSize <= 0) return sorted;
8690
+ const start = page * pageSize;
8691
+ return sorted.slice(start, start + pageSize);
8692
+ }, [sorted, page, pageSize, isServerMode]);
8693
+ const [serverRows, setServerRows] = useState([]);
8694
+ const [serverTotal, setServerTotal] = useState(0);
8695
+ const [serverError, setServerError] = useState(null);
8696
+ const reqIdRef = useRef(0);
8697
+ useEffect(() => {
8698
+ if (!isServerMode) return;
8699
+ const myId = ++reqIdRef.current;
8700
+ let cancelled = false;
8701
+ setServerError(null);
8702
+ Promise.resolve(
8703
+ props.onLoad({ page, sort, filter })
8704
+ ).then((res) => {
8705
+ if (cancelled || myId !== reqIdRef.current) return;
8706
+ setServerRows(res.rows);
8707
+ setServerTotal(res.total);
8708
+ }).catch((err) => {
8709
+ if (cancelled || myId !== reqIdRef.current) return;
8710
+ console.warn("[HazoUiTable] onLoad rejected:", err);
8711
+ setServerRows([]);
8712
+ setServerTotal(0);
8713
+ setServerError(err ?? new Error("onLoad rejected"));
8714
+ });
8715
+ return () => {
8716
+ cancelled = true;
8717
+ };
8718
+ }, [isServerMode, page, sort, filter, props.onLoad]);
8719
+ const displayed = isServerMode ? serverRows : pagedInMemory;
8720
+ const totalAfterFilter = isServerMode ? serverTotal : filtered.length;
8721
+ return {
8722
+ sort,
8723
+ setSort,
8724
+ cycleHeaderSort,
8725
+ filter,
8726
+ setFilter,
8727
+ setSearch,
8728
+ page,
8729
+ setPage,
8730
+ displayed,
8731
+ totalAfterFilter,
8732
+ pageSize,
8733
+ serverError: isServerMode ? serverError : null
8734
+ };
8735
+ }
8736
+ function normalizeSortProp(p) {
8737
+ if (!p) return [];
8738
+ if (Array.isArray(p)) return p;
8739
+ return [p];
8740
+ }
8741
+ function cycleSingleColumn(current, key) {
8742
+ if (current.length !== 1) return [{ key, dir: "asc" }];
8743
+ const only = current[0];
8744
+ if (only.key !== key) return [{ key, dir: "asc" }];
8745
+ if (only.dir === "asc") return [{ key, dir: "desc" }];
8746
+ return [];
8747
+ }
8748
+ function cycleAppendColumn(current, key) {
8749
+ const idx = current.findIndex((s) => s.key === key);
8750
+ if (idx === -1) return [...current, { key, dir: "asc" }];
8751
+ const entry = current[idx];
8752
+ if (entry.dir === "asc") {
8753
+ const next = current.slice();
8754
+ next[idx] = { key, dir: "desc" };
8755
+ return next;
8756
+ }
8757
+ return current.filter((_, i) => i !== idx);
8758
+ }
8759
+ function applyFilter(rows, filter, columns) {
8760
+ let result = rows;
8761
+ if (filter.fields && filter.fields.length > 0) {
8762
+ result = result.filter(
8763
+ (row) => filter.fields.every((f) => matchesFieldFilter(row, f, columns))
8764
+ );
8765
+ }
8766
+ const needle = (filter.search ?? "").trim().toLowerCase();
8767
+ if (needle.length > 0) {
8768
+ const searchKeys = columns.filter(isSearchable).map((c) => c.key);
8769
+ if (searchKeys.length > 0) {
8770
+ result = result.filter(
8771
+ (row) => searchKeys.some(
8772
+ (k) => String(row[k] ?? "").toLowerCase().includes(needle)
8773
+ )
8774
+ );
8775
+ }
8776
+ }
8777
+ return result;
8778
+ }
8779
+ function isSearchable(c) {
8780
+ if (c.searchable !== void 0) return c.searchable;
8781
+ switch (c.formatter) {
8782
+ case "number":
8783
+ case "currency":
8784
+ case "percent":
8785
+ case "date":
8786
+ return false;
8787
+ default:
8788
+ return true;
8789
+ }
8790
+ }
8791
+ function matchesFieldFilter(row, f, columns) {
8792
+ const col = columns.find((c) => c.key === f.field);
8793
+ if (!col || !col.filterType) return true;
8794
+ const value = row[f.field];
8795
+ const op = f.operator || "equals";
8796
+ switch (col.filterType) {
8797
+ case "text": {
8798
+ if (f.value === void 0 || f.value === "") return true;
8799
+ return String(value ?? "").toLowerCase().includes(String(f.value).toLowerCase());
8800
+ }
8801
+ case "number": {
8802
+ const v = Number(value);
8803
+ const fv = Number(f.value);
8804
+ if (Number.isNaN(v) || Number.isNaN(fv)) return false;
8805
+ return numberOp(v, fv, op);
8806
+ }
8807
+ case "date": {
8808
+ const v = value instanceof Date ? value : new Date(value);
8809
+ const fv = f.value instanceof Date ? f.value : new Date(f.value);
8810
+ if (Number.isNaN(v.getTime()) || Number.isNaN(fv.getTime())) return false;
8811
+ const ta = new Date(v).setHours(0, 0, 0, 0);
8812
+ const tb = new Date(fv).setHours(0, 0, 0, 0);
8813
+ return numberOp(ta, tb, op);
8814
+ }
8815
+ case "combobox":
8816
+ return String(value) === String(f.value);
8817
+ case "boolean":
8818
+ return Boolean(value) === Boolean(f.value);
8819
+ default:
8820
+ return true;
8821
+ }
8822
+ }
8823
+ function numberOp(a, b, op) {
8824
+ switch (op) {
8825
+ case "equals":
8826
+ return a === b;
8827
+ case "not_equals":
8828
+ return a !== b;
8829
+ case "greater_than":
8830
+ return a > b;
8831
+ case "less_than":
8832
+ return a < b;
8833
+ case "greater_equal":
8834
+ return a >= b;
8835
+ case "less_equal":
8836
+ return a <= b;
8837
+ default:
8838
+ return true;
8839
+ }
8840
+ }
8841
+ function applySort(rows, sort) {
8842
+ if (sort.length === 0) return rows;
8843
+ return [...rows].map((row, idx) => ({ row, idx })).sort((a, b) => {
8844
+ for (const entry of sort) {
8845
+ const va = a.row[entry.key];
8846
+ const vb = b.row[entry.key];
8847
+ const cmp = compareValues(va, vb);
8848
+ if (cmp !== 0) return entry.dir === "asc" ? cmp : -cmp;
8849
+ }
8850
+ return a.idx - b.idx;
8851
+ }).map((x) => x.row);
8852
+ }
8853
+ function compareValues(a, b) {
8854
+ if (a == null && b == null) return 0;
8855
+ if (a == null) return 1;
8856
+ if (b == null) return -1;
8857
+ if (a instanceof Date && b instanceof Date)
8858
+ return a.getTime() - b.getTime();
8859
+ if (typeof a === "number" && typeof b === "number") return a - b;
8860
+ return String(a).localeCompare(String(b));
8861
+ }
8862
+ function serializeSort(sort) {
8863
+ return sort.map((s) => `${s.key}:${s.dir}`).join(",");
8864
+ }
8865
+ function serializeFilter(filter) {
8866
+ const fields = (filter.fields ?? []).map((f) => `${f.field}:${f.operator ?? ""}:${String(f.value)}`).join(",");
8867
+ return `${filter.search ?? ""}|${fields}`;
8868
+ }
8869
+ function HazoUiTable(props) {
8870
+ const state = useTableState(props);
8871
+ const { columns, rows, getRowKey, className, caption } = props;
8872
+ const mobileBreakpoint = props.mobileBreakpoint ?? 768;
8873
+ const mobileEnabled = props.mobileCardFallback !== false;
8874
+ const isNarrow = useMediaQuery(`(max-width: ${mobileBreakpoint - 1}px)`);
8875
+ const renderAsCards = mobileEnabled && isNarrow;
8876
+ return /* @__PURE__ */ jsxs("div", { className: cn("cls_hazo_ui_table_root space-y-3", className), children: [
8877
+ (props.enableSearch || props.enableSortDialog || props.enableFilterDialog) && /* @__PURE__ */ jsx(
8878
+ Toolbar2,
8879
+ {
8880
+ columns,
8881
+ sort: state.sort,
8882
+ onSortChange: state.setSort,
8883
+ filter: state.filter,
8884
+ onSearchChange: state.setSearch,
8885
+ onFilterFieldsChange: (fields) => state.setFilter({ ...state.filter, fields }),
8886
+ enableSearch: props.enableSearch,
8887
+ enableSortDialog: props.enableSortDialog,
8888
+ enableFilterDialog: props.enableFilterDialog,
8889
+ searchPlaceholder: props.searchPlaceholder
8890
+ }
8891
+ ),
8892
+ renderAsCards ? props.loading ? /* @__PURE__ */ jsx("div", { className: "cls_hazo_ui_table_mobile_loading flex flex-col gap-3", children: Array.from({ length: Math.max(state.pageSize || 5, 3) }).map(
8893
+ (_, i) => /* @__PURE__ */ jsxs(Card, { children: [
8894
+ /* @__PURE__ */ jsx(CardHeader, { className: "pb-2", children: /* @__PURE__ */ jsx(SkeletonBar, { className: "w-2/3" }) }),
8895
+ /* @__PURE__ */ jsxs(CardContent, { className: "pt-0 space-y-2", children: [
8896
+ /* @__PURE__ */ jsx(SkeletonBar, { className: "w-full" }),
8897
+ /* @__PURE__ */ jsx(SkeletonBar, { className: "w-1/2" })
8898
+ ] })
8899
+ ] }, `mloader-${i}`)
8900
+ ) }) : state.serverError != null ? /* @__PURE__ */ jsx("div", { className: "cls_hazo_ui_table_mobile_error py-6", children: renderErrorState(props.error, state.serverError) }) : state.displayed.length === 0 ? /* @__PURE__ */ jsx("div", { className: "cls_hazo_ui_table_mobile_empty py-6", children: noActiveFilters(state.filter) && rows.length === 0 ? typeof props.empty === "string" || props.empty === void 0 ? /* @__PURE__ */ jsx(
8901
+ EmptyState,
8902
+ {
8903
+ title: typeof props.empty === "string" && props.empty || "No items"
8904
+ }
8905
+ ) : props.empty : typeof props.noResults === "string" || props.noResults === void 0 ? /* @__PURE__ */ jsx(
8906
+ EmptyState,
8907
+ {
8908
+ title: typeof props.noResults === "string" && props.noResults || "No matches \u2014 adjust your filters"
8909
+ }
8910
+ ) : props.noResults }) : /* @__PURE__ */ jsx(
8911
+ TableMobileCards,
8912
+ {
8913
+ columns,
8914
+ rows: state.displayed,
8915
+ getRowKey,
8916
+ onRowClick: props.onRowClick,
8917
+ renderCell
8918
+ }
8919
+ ) : /* @__PURE__ */ jsxs(Table2, { children: [
8920
+ caption && /* @__PURE__ */ jsx(TableCaption, { children: caption }),
8921
+ /* @__PURE__ */ jsx(TableHeader2, { children: /* @__PURE__ */ jsx(TableRow2, { children: columns.map((c) => /* @__PURE__ */ jsx(
8922
+ TableHead,
8923
+ {
8924
+ className: cn(headerAlignClass(c), c.headerClassName),
8925
+ "aria-sort": ariaSortFor(state.sort, c.key),
8926
+ children: c.sortable ? /* @__PURE__ */ jsxs(
8927
+ "button",
8928
+ {
8929
+ type: "button",
8930
+ onClick: (e) => state.cycleHeaderSort(c.key, e.shiftKey),
8931
+ title: "Click to sort; shift-click to append a secondary sort",
8932
+ className: "cls_hazo_ui_table_sort_btn inline-flex items-center gap-1 hover:text-foreground",
8933
+ children: [
8934
+ /* @__PURE__ */ jsx("span", { children: c.label }),
8935
+ /* @__PURE__ */ jsx(SortIndicator, { sort: state.sort, columnKey: c.key })
8936
+ ]
8937
+ }
8938
+ ) : c.label
8939
+ },
8940
+ c.key
8941
+ )) }) }),
8942
+ /* @__PURE__ */ jsx(TableBody, { children: props.loading ? /* @__PURE__ */ jsx(
8943
+ LoadingRows,
8944
+ {
8945
+ columns,
8946
+ count: Math.max(state.pageSize || 5, 3)
8947
+ }
8948
+ ) : state.serverError != null ? /* @__PURE__ */ jsx(TableRow2, { children: /* @__PURE__ */ jsx(
8949
+ TableCell2,
8950
+ {
8951
+ colSpan: columns.length,
8952
+ className: "cls_hazo_ui_table_error_cell p-0",
8953
+ children: /* @__PURE__ */ jsx("div", { className: "cls_hazo_ui_table_error_wrap py-6", children: renderErrorState(props.error, state.serverError) })
8954
+ }
8955
+ ) }) : state.displayed.length === 0 ? /* @__PURE__ */ jsx(TableRow2, { children: /* @__PURE__ */ jsx(
8956
+ TableCell2,
8957
+ {
8958
+ colSpan: columns.length,
8959
+ className: "cls_hazo_ui_table_empty_cell p-0",
8960
+ children: noActiveFilters(state.filter) && rows.length === 0 ? /* @__PURE__ */ jsx("div", { className: "cls_hazo_ui_table_empty_wrap py-6", children: typeof props.empty === "string" || props.empty === void 0 ? /* @__PURE__ */ jsx(
8961
+ EmptyState,
8962
+ {
8963
+ title: typeof props.empty === "string" && props.empty || "No items"
8964
+ }
8965
+ ) : props.empty }) : /* @__PURE__ */ jsx("div", { className: "cls_hazo_ui_table_no_results_wrap py-6", children: typeof props.noResults === "string" || props.noResults === void 0 ? /* @__PURE__ */ jsx(
8966
+ EmptyState,
8967
+ {
8968
+ title: typeof props.noResults === "string" && props.noResults || "No matches \u2014 adjust your filters"
8969
+ }
8970
+ ) : props.noResults })
8971
+ }
8972
+ ) }) : state.displayed.map((row, i) => /* @__PURE__ */ jsx(
8973
+ TableRow2,
8974
+ {
8975
+ ...buildRowProps(row, i, props.onRowClick),
8976
+ children: columns.map((c) => /* @__PURE__ */ jsx(
8977
+ TableCell2,
8978
+ {
8979
+ className: cn(cellAlignClass(c), c.className),
8980
+ children: renderCell(c, row, i)
8981
+ },
8982
+ c.key
8983
+ ))
8984
+ },
8985
+ getRowKey ? getRowKey(row, i) : i
8986
+ )) })
8987
+ ] }),
8988
+ state.pageSize > 0 && /* @__PURE__ */ jsx(
8989
+ PaginationFooter,
8990
+ {
8991
+ page: state.page,
8992
+ pageSize: state.pageSize,
8993
+ total: state.totalAfterFilter,
8994
+ onPageChange: state.setPage
8995
+ }
8996
+ )
8997
+ ] });
8998
+ }
8999
+ function renderCell(c, row, i) {
9000
+ if (c.cell) return c.cell(row, i);
9001
+ const raw = row[c.key];
9002
+ return formatValue(raw, c.formatter, c.currency, c.locale);
9003
+ }
9004
+ var DEFAULT_NUMBER_LOCALE = "en-US";
9005
+ function formatValue(value, formatter, currency, locale) {
9006
+ if (value === null || value === void 0 || value === "") return "\u2014";
9007
+ const lc = locale ?? DEFAULT_NUMBER_LOCALE;
9008
+ switch (formatter) {
9009
+ case "date": {
9010
+ const d = value instanceof Date ? value : new Date(value);
9011
+ if (Number.isNaN(d.getTime())) return String(value);
9012
+ return format(d, "MMM d, yyyy");
9013
+ }
9014
+ case "number":
9015
+ return new Intl.NumberFormat(lc).format(Number(value));
9016
+ case "currency":
9017
+ return new Intl.NumberFormat(lc, {
9018
+ style: "currency",
9019
+ currency: currency ?? "USD"
9020
+ }).format(Number(value));
9021
+ case "percent":
9022
+ return new Intl.NumberFormat(lc, {
9023
+ style: "percent",
9024
+ maximumFractionDigits: 2
9025
+ }).format(Number(value));
9026
+ default:
9027
+ return String(value);
9028
+ }
9029
+ }
9030
+ function headerAlignClass(c) {
9031
+ switch (c.align) {
9032
+ case "right":
9033
+ return "text-right";
9034
+ case "center":
9035
+ return "text-center";
9036
+ default:
9037
+ return "text-left";
9038
+ }
9039
+ }
9040
+ function cellAlignClass(c) {
9041
+ switch (c.align) {
9042
+ case "right":
9043
+ return "text-right";
9044
+ case "center":
9045
+ return "text-center";
9046
+ default:
9047
+ return "";
9048
+ }
9049
+ }
9050
+ function ariaSortFor(sort, key) {
9051
+ const entry = sort.find((s) => s.key === key);
9052
+ if (!entry) return "none";
9053
+ return entry.dir === "asc" ? "ascending" : "descending";
9054
+ }
9055
+ function deriveSortFields(columns) {
9056
+ return columns.filter((c) => c.sortable).map((c) => ({ value: c.key, label: c.label }));
9057
+ }
9058
+ function deriveFilterFields(columns) {
9059
+ return columns.filter((c) => c.filterType).map((c) => ({
9060
+ value: c.key,
9061
+ label: c.label,
9062
+ type: c.filterType,
9063
+ ...c.filterConfig ?? {}
9064
+ }));
9065
+ }
9066
+ function sortToDialogConfig(sort) {
9067
+ return sort.map((s) => ({ field: s.key, direction: s.dir }));
9068
+ }
9069
+ function dialogConfigToSort(configs) {
9070
+ return configs.map((c) => ({ key: c.field, dir: c.direction }));
9071
+ }
9072
+ function PaginationFooter({
9073
+ page,
9074
+ pageSize,
9075
+ total,
9076
+ onPageChange
9077
+ }) {
9078
+ const start = total === 0 ? 0 : page * pageSize + 1;
9079
+ const end = Math.min((page + 1) * pageSize, total);
9080
+ const lastPage = Math.max(0, Math.ceil(total / pageSize) - 1);
9081
+ return /* @__PURE__ */ jsxs("div", { className: "cls_hazo_ui_table_pagination flex items-center justify-between gap-3 pt-2 text-sm", children: [
9082
+ /* @__PURE__ */ jsxs("span", { className: "cls_hazo_ui_table_page_counter text-muted-foreground", children: [
9083
+ "Showing ",
9084
+ start,
9085
+ "\u2013",
9086
+ end,
9087
+ " of ",
9088
+ total
9089
+ ] }),
9090
+ /* @__PURE__ */ jsxs("div", { className: "cls_hazo_ui_table_page_buttons flex items-center gap-2", children: [
9091
+ /* @__PURE__ */ jsx(
9092
+ Button,
9093
+ {
9094
+ variant: "outline",
9095
+ size: "sm",
9096
+ onClick: () => onPageChange(Math.max(0, page - 1)),
9097
+ disabled: page === 0,
9098
+ "aria-label": "Previous page",
9099
+ children: "\u2039 Prev"
9100
+ }
9101
+ ),
9102
+ /* @__PURE__ */ jsx(
9103
+ Button,
9104
+ {
9105
+ variant: "outline",
9106
+ size: "sm",
9107
+ onClick: () => onPageChange(Math.min(lastPage, page + 1)),
9108
+ disabled: page >= lastPage,
9109
+ "aria-label": "Next page",
9110
+ children: "Next \u203A"
9111
+ }
9112
+ )
9113
+ ] })
9114
+ ] });
9115
+ }
9116
+ function Toolbar2(props) {
9117
+ const {
9118
+ columns,
9119
+ sort,
9120
+ onSortChange,
9121
+ filter,
9122
+ onSearchChange,
9123
+ onFilterFieldsChange,
9124
+ enableSearch,
9125
+ enableSortDialog,
9126
+ enableFilterDialog,
9127
+ searchPlaceholder
9128
+ } = props;
9129
+ const sortFields = React25.useMemo(
9130
+ () => deriveSortFields(columns),
9131
+ [columns]
9132
+ );
9133
+ const filterFields = React25.useMemo(
9134
+ () => deriveFilterFields(columns),
9135
+ [columns]
9136
+ );
9137
+ const [searchValue, setSearchValue] = React25.useState(
9138
+ filter.search ?? ""
9139
+ );
9140
+ React25.useEffect(() => {
9141
+ setSearchValue(filter.search ?? "");
9142
+ }, [filter.search]);
9143
+ return /* @__PURE__ */ jsxs("div", { className: "cls_hazo_ui_table_toolbar flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between", children: [
9144
+ enableSearch ? /* @__PURE__ */ jsx(
9145
+ Input,
9146
+ {
9147
+ type: "text",
9148
+ value: searchValue,
9149
+ onChange: (e) => {
9150
+ const v = e.target.value;
9151
+ setSearchValue(v);
9152
+ onSearchChange(v);
9153
+ },
9154
+ placeholder: searchPlaceholder ?? "Search...",
9155
+ className: "cls_hazo_ui_table_search w-full sm:max-w-xs"
9156
+ }
9157
+ ) : /* @__PURE__ */ jsx("div", {}),
9158
+ /* @__PURE__ */ jsxs("div", { className: "cls_hazo_ui_table_toolbar_right flex items-center gap-2", children: [
9159
+ enableFilterDialog && filterFields.length > 0 && /* @__PURE__ */ jsx(
9160
+ HazoUiMultiFilterDialog,
9161
+ {
9162
+ availableFields: filterFields,
9163
+ initialFilters: filter.fields ?? [],
9164
+ onFilterChange: onFilterFieldsChange
9165
+ }
9166
+ ),
9167
+ enableSortDialog && sortFields.length > 0 && /* @__PURE__ */ jsx(
9168
+ HazoUiMultiSortDialog,
9169
+ {
9170
+ availableFields: sortFields,
9171
+ initialSortFields: sortToDialogConfig(sort),
9172
+ onSortChange: (configs) => onSortChange(dialogConfigToSort(configs))
9173
+ }
9174
+ )
9175
+ ] })
9176
+ ] });
9177
+ }
9178
+ function LoadingRows({
9179
+ columns,
9180
+ count
9181
+ }) {
9182
+ return /* @__PURE__ */ jsx(Fragment$1, { children: Array.from({ length: count }).map((_, rowIdx) => /* @__PURE__ */ jsx(TableRow2, { children: columns.map((c) => /* @__PURE__ */ jsx(TableCell2, { className: cellAlignClass(c), children: /* @__PURE__ */ jsx(
9183
+ SkeletonBar,
9184
+ {
9185
+ className: cn(
9186
+ "cls_hazo_ui_table_skeleton",
9187
+ c.align === "right" ? "w-16 ml-auto" : "w-full"
9188
+ )
9189
+ }
9190
+ ) }, c.key)) }, `skeleton-${rowIdx}`)) });
9191
+ }
9192
+ function noActiveFilters(filter) {
9193
+ return !filter.search && (!filter.fields || filter.fields.length === 0);
9194
+ }
9195
+ function renderErrorState(error, serverError) {
9196
+ if (typeof error === "function") return error(serverError);
9197
+ if (error !== void 0 && error !== null) return error;
9198
+ const msg = serverError instanceof Error ? serverError.message : String(serverError);
9199
+ return /* @__PURE__ */ jsx(
9200
+ EmptyState,
9201
+ {
9202
+ title: "Couldn't load data",
9203
+ description: msg || "The data source rejected the request."
9204
+ }
9205
+ );
9206
+ }
9207
+ function buildRowProps(row, index, onRowClick) {
9208
+ if (!onRowClick) return {};
9209
+ return {
9210
+ role: "button",
9211
+ tabIndex: 0,
9212
+ className: "cls_hazo_ui_table_row_clickable cursor-pointer",
9213
+ onClick: () => onRowClick(row, index),
9214
+ onKeyDown: (e) => {
9215
+ if (e.key === "Enter" || e.key === " ") {
9216
+ e.preventDefault();
9217
+ onRowClick(row, index);
9218
+ }
9219
+ }
9220
+ };
9221
+ }
9222
+ function SortIndicator({
9223
+ sort,
9224
+ columnKey
9225
+ }) {
9226
+ const idx = sort.findIndex((s) => s.key === columnKey);
9227
+ if (idx === -1) {
9228
+ return /* @__PURE__ */ jsx(ChevronsUpDown, { className: "cls_hazo_ui_table_sort_idle h-3.5 w-3.5 opacity-30" });
9229
+ }
9230
+ const entry = sort[idx];
9231
+ return /* @__PURE__ */ jsxs("span", { className: "cls_hazo_ui_table_sort_active inline-flex items-center gap-0.5", children: [
9232
+ entry.dir === "asc" ? /* @__PURE__ */ jsx(ChevronUp, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(ChevronDown, { className: "h-3.5 w-3.5" }),
9233
+ sort.length > 1 && /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium", children: idx + 1 })
9234
+ ] });
9235
+ }
7243
9236
 
7244
- export { ANIMATION_PRESETS, Accordion, AccordionContent, AccordionItem, AccordionTrigger, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, CommandNodeExtension, CommandPill, CommandPopover, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, HazoUiConfirmDialog, HazoUiDialog, DialogClose as HazoUiDialogClose, DialogContent as HazoUiDialogContent, DialogDescription as HazoUiDialogDescription, DialogFooter as HazoUiDialogFooter, DialogHeader as HazoUiDialogHeader, DialogOverlay as HazoUiDialogOverlay, DialogPortal as HazoUiDialogPortal, Dialog as HazoUiDialogRoot, DialogTitle as HazoUiDialogTitle, DialogTrigger as HazoUiDialogTrigger, HazoUiFlexInput, HazoUiFlexRadio, HazoUiMultiFilterDialog, HazoUiMultiSortDialog, HazoUiPillRadio, HazoUiRte, HazoUiTextarea, HazoUiTextbox, HoverCard, HoverCardContent, HoverCardTrigger, Input, Label2 as Label, Popover, PopoverContent, PopoverTrigger, RadioGroup, RadioGroupItem, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator3 as Separator, Command as ShadcnCommand, CommandEmpty as ShadcnCommandEmpty, CommandGroup as ShadcnCommandGroup, CommandInput as ShadcnCommandInput, CommandItem as ShadcnCommandItem, CommandList as ShadcnCommandList, Spinner, Switch, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, buttonGroupVariants, create_command_suggestion_extension, get_hazo_ui_config, parse_commands_from_text, reset_hazo_ui_config, resolve_animation_classes, set_hazo_ui_config, text_to_tiptap_content, toggleVariants, useMediaQuery };
9237
+ export { ANIMATION_PRESETS, Accordion, AccordionContent, AccordionItem, AccordionTrigger, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, CommandNodeExtension, CommandPill, CommandPopover, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, ErrorBanner, ErrorPage, HazoUiConfirmDialog, HazoUiDialog, DialogClose as HazoUiDialogClose, DialogContent as HazoUiDialogContent, DialogDescription as HazoUiDialogDescription, DialogFooter as HazoUiDialogFooter, DialogHeader as HazoUiDialogHeader, DialogOverlay as HazoUiDialogOverlay, DialogPortal as HazoUiDialogPortal, Dialog as HazoUiDialogRoot, DialogTitle as HazoUiDialogTitle, DialogTrigger as HazoUiDialogTrigger, HazoUiFlexInput, HazoUiFlexRadio, HazoUiKanban, HazoUiKanbanFilter, HazoUiMultiFilterDialog, HazoUiMultiSortDialog, HazoUiPillRadio, HazoUiRte, HazoUiTable, HazoUiTextarea, HazoUiTextbox, HazoUiToaster, HoverCard, HoverCardContent, HoverCardTrigger, Input, Label3 as Label, LoadingTimeout, Popover, PopoverContent, PopoverTrigger, ProgressiveImage, RadioGroup, RadioGroupItem, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator3 as Separator, Command as ShadcnCommand, CommandEmpty as ShadcnCommandEmpty, CommandGroup as ShadcnCommandGroup, CommandInput as ShadcnCommandInput, CommandItem as ShadcnCommandItem, CommandList as ShadcnCommandList, Skeleton, SkeletonBar, SkeletonCircle, SkeletonGroup, SkeletonRect, Spinner, Switch, Table2 as Table, TableBody, TableCaption, TableCell2 as TableCell, TableFooter, TableHead, TableHeader2 as TableHeader, TableRow2 as TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, applyKanbanFilter, buttonGroupVariants, create_command_suggestion_extension, errorToast, get_hazo_ui_config, parse_commands_from_text, reset_hazo_ui_config, resolve_animation_classes, set_hazo_ui_config, successToast, text_to_tiptap_content, toggleVariants, useErrorDisplay, useLoadingState, useMediaQuery };
7245
9238
  //# sourceMappingURL=index.js.map
7246
9239
  //# sourceMappingURL=index.js.map