@page-speed/forms 0.4.2 → 0.4.3

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/inputs.js CHANGED
@@ -23,7 +23,7 @@ function TextInput({
23
23
  const handleBlur = () => {
24
24
  onBlur?.();
25
25
  };
26
- const baseClassName = "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm";
26
+ const baseClassName = "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm";
27
27
  const errorClassName = error ? "border-red-500 ring-1 ring-red-500" : "";
28
28
  const combinedClassName = `${baseClassName} ${errorClassName} ${className}`.trim();
29
29
  return /* @__PURE__ */ React7.createElement(
@@ -70,7 +70,7 @@ function TextArea({
70
70
  const handleBlur = () => {
71
71
  onBlur?.();
72
72
  };
73
- const baseClassName = "flex min-h-20 w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm";
73
+ const baseClassName = "flex min-h-20 w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm";
74
74
  const errorClassName = error ? "border-red-500 ring-1 ring-red-500" : "";
75
75
  const combinedClassName = `${baseClassName} ${errorClassName} ${className}`.trim();
76
76
  return /* @__PURE__ */ React7.createElement(
@@ -304,8 +304,8 @@ function CheckboxGroup({
304
304
  gridTemplateColumns: `repeat(${gridColumns}, 1fr)`
305
305
  } : void 0
306
306
  },
307
- label && /* @__PURE__ */ React7.createElement("div", { className: "text-sm font-medium" }, label),
308
- description && /* @__PURE__ */ React7.createElement("div", { className: "text-muted-foreground text-sm" }, description),
307
+ label ? /* @__PURE__ */ React7.createElement("div", { className: "text-sm font-medium" }, label) : null,
308
+ description ? /* @__PURE__ */ React7.createElement("div", { className: "text-xs opacity-70" }, description) : null,
309
309
  showSelectAll && enabledOptions.length > 0 && /* @__PURE__ */ React7.createElement(
310
310
  Checkbox,
311
311
  {
@@ -367,7 +367,6 @@ function Radio({
367
367
  error = false,
368
368
  className = "",
369
369
  layout = "stacked",
370
- radioVariant = "inline",
371
370
  label,
372
371
  options,
373
372
  ...props
@@ -403,12 +402,16 @@ function Radio({
403
402
  const handleBlur = () => {
404
403
  onBlur?.();
405
404
  };
406
- const containerClass = cn(
407
- "w-full gap-3",
408
- layout === "stacked" && "flex flex-col",
409
- layout === "inline" && "flex flex-row flex-wrap",
410
- className
411
- );
405
+ const useChoiceCard = React7.useMemo(() => {
406
+ return options.some((option) => option.description);
407
+ }, [options]);
408
+ const containerClass = React7.useMemo(() => {
409
+ return cn(
410
+ "w-full gap-3 grid grid-cols-1",
411
+ layout === "inline" && "md:grid-cols-2",
412
+ className
413
+ );
414
+ }, [layout, className]);
412
415
  return /* @__PURE__ */ React7.createElement(
413
416
  "div",
414
417
  {
@@ -455,29 +458,22 @@ function Radio({
455
458
  },
456
459
  isChecked && /* @__PURE__ */ React7.createElement("div", { className: "size-3 rounded-full bg-primary" })
457
460
  ));
458
- const labelContent = /* @__PURE__ */ React7.createElement("div", { className: "flex flex-col gap-0.5" }, /* @__PURE__ */ React7.createElement("div", { className: "text-sm font-medium" }, option.label), hasDescription && /* @__PURE__ */ React7.createElement(
459
- "p",
460
- {
461
- className: "text-xs opacity-75",
462
- id: `${radioId}-description`
463
- },
464
- option.description
465
- ));
461
+ const labelContent = /* @__PURE__ */ React7.createElement("div", { className: "flex flex-col gap-0.5" }, /* @__PURE__ */ React7.createElement("div", { className: "text-sm font-medium" }, option.label), hasDescription && /* @__PURE__ */ React7.createElement("p", { className: "text-xs opacity-75", id: `${radioId}-description` }, option.description));
466
462
  return /* @__PURE__ */ React7.createElement(
467
463
  "label",
468
464
  {
469
465
  key: option.value,
470
466
  className: cn(
471
467
  "w-full h-full flex gap-3 p-3 duration-200",
472
- radioVariant === "boxed" && "border rounded-lg hover:ring-2",
473
- radioVariant === "boxed" && isChecked && "ring-2",
468
+ useChoiceCard && "border rounded-lg hover:ring-2",
469
+ useChoiceCard && isChecked && "ring-2",
474
470
  isDisabled ? "opacity-50 cursor-not-allowed hover:ring-0" : "cursor-pointer"
475
471
  ),
476
472
  htmlFor: radioId,
477
473
  onKeyDown: (e) => handleKeyDown(e, index),
478
474
  tabIndex: isDisabled ? -1 : 0
479
475
  },
480
- /* @__PURE__ */ React7.createElement("div", { className: "flex w-full flex-row items-center gap-2" }, radioVariant === "inline" && radioIndicator, /* @__PURE__ */ React7.createElement("div", { className: "flex flex-1 flex-col gap-0.5" }, labelContent), radioVariant === "boxed" && radioIndicator)
476
+ /* @__PURE__ */ React7.createElement("div", { className: "flex w-full flex-row items-center gap-2" }, !useChoiceCard && radioIndicator, /* @__PURE__ */ React7.createElement("div", { className: "flex flex-1 flex-col gap-0.5" }, labelContent), useChoiceCard && radioIndicator)
481
477
  );
482
478
  })
483
479
  );
@@ -567,9 +563,7 @@ function Select({
567
563
  if (enabledOptions.length > 0) {
568
564
  const currentIndexInFiltered = focusedIndex;
569
565
  const nextIndex = (currentIndexInFiltered + 1) % enabledOptions.length;
570
- setFocusedIndex(
571
- filteredOptions.indexOf(enabledOptions[nextIndex])
572
- );
566
+ setFocusedIndex(filteredOptions.indexOf(enabledOptions[nextIndex]));
573
567
  }
574
568
  }
575
569
  break;
@@ -580,9 +574,7 @@ function Select({
580
574
  if (enabledOptions.length > 0) {
581
575
  const currentIndexInFiltered = focusedIndex;
582
576
  const prevIndex = (currentIndexInFiltered - 1 + enabledOptions.length) % enabledOptions.length;
583
- setFocusedIndex(
584
- filteredOptions.indexOf(enabledOptions[prevIndex])
585
- );
577
+ setFocusedIndex(filteredOptions.indexOf(enabledOptions[prevIndex]));
586
578
  }
587
579
  }
588
580
  break;
@@ -672,7 +664,7 @@ function Select({
672
664
  /* @__PURE__ */ React7.createElement(
673
665
  "div",
674
666
  {
675
- className: `flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm cursor-pointer transition-colors hover:bg-accent focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring ${disabled ? "cursor-not-allowed opacity-50 pointer-events-none" : ""} ${error ? "border-red-500 ring-1 ring-red-500" : ""}`,
667
+ className: `flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm cursor-pointer transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring ${disabled ? "cursor-not-allowed opacity-50 pointer-events-none" : ""} ${error ? "border-red-500 ring-1 ring-red-500" : ""}`,
676
668
  onClick: handleToggle,
677
669
  role: "combobox",
678
670
  "aria-expanded": isOpen,
@@ -683,48 +675,76 @@ function Select({
683
675
  "aria-disabled": disabled,
684
676
  tabIndex: disabled ? -1 : 0
685
677
  },
686
- /* @__PURE__ */ React7.createElement("span", { className: "flex items-center flex-1 overflow-hidden text-ellipsis" }, selectedOption ? renderOption ? renderOption(selectedOption) : selectedOption.label : /* @__PURE__ */ React7.createElement("span", { className: "text-muted-foreground" }, placeholder)),
678
+ /* @__PURE__ */ React7.createElement("span", { className: "flex items-center flex-1 overflow-hidden text-ellipsis" }, selectedOption ? renderOption ? renderOption(selectedOption) : selectedOption.label : /* @__PURE__ */ React7.createElement("span", { className: "relative" }, placeholder)),
687
679
  /* @__PURE__ */ React7.createElement("div", { className: "flex items-center gap-1 ml-2" }, loading && /* @__PURE__ */ React7.createElement("span", { className: "text-xs" }, "\u23F3"), clearable && value && !disabled && !loading && /* @__PURE__ */ React7.createElement(
688
680
  "button",
689
681
  {
690
682
  type: "button",
691
- className: "flex items-center justify-center h-4 w-4 rounded-sm border-none bg-transparent text-muted-foreground cursor-pointer text-xs p-0 transition-opacity hover:opacity-70",
683
+ className: "flex items-center justify-center h-4 w-4 rounded-sm border-none bg-transparent cursor-pointer text-xs p-0 transition-opacity hover:opacity-70",
692
684
  onClick: handleClear,
693
685
  "aria-label": "Clear selection",
694
686
  tabIndex: -1
695
687
  },
696
688
  "\u2715"
697
- ), /* @__PURE__ */ React7.createElement("span", { className: "text-muted-foreground text-xs leading-none", "aria-hidden": "true" }, isOpen ? "\u25B2" : "\u25BC"))
689
+ ), /* @__PURE__ */ React7.createElement("span", { className: "text-xs leading-none", "aria-hidden": "true" }, isOpen ? "\u25B2" : "\u25BC"))
698
690
  ),
699
- isOpen && /* @__PURE__ */ React7.createElement("div", { id: dropdownId, className: "absolute z-50 top-full mt-1 min-w-full overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md", role: "listbox" }, searchable && /* @__PURE__ */ React7.createElement("div", { className: "p-2 border-b border-border" }, /* @__PURE__ */ React7.createElement(
700
- "input",
691
+ isOpen && /* @__PURE__ */ React7.createElement(
692
+ "div",
701
693
  {
702
- ref: searchInputRef,
703
- type: "text",
704
- className: "w-full border border-input rounded px-2 py-1 text-sm bg-transparent outline-none focus:ring-1 focus:ring-ring",
705
- placeholder: "Search...",
706
- value: searchQuery,
707
- onChange: handleSearchChange,
708
- onClick: (e) => e.stopPropagation(),
709
- "aria-label": "Search options"
710
- }
711
- )), /* @__PURE__ */ React7.createElement("div", { className: "max-h-64 overflow-y-auto p-1" }, filteredOptions.length === 0 ? /* @__PURE__ */ React7.createElement("div", { className: "py-2 px-3 text-center text-sm text-muted-foreground" }, "No options found") : optionGroups.length > 0 ? (
712
- // Render grouped options
713
- optionGroups.map((group, groupIndex) => {
714
- const groupOptions = group.options.filter(
715
- (opt) => filteredOptions.includes(opt)
716
- );
717
- if (groupOptions.length === 0) return null;
718
- return /* @__PURE__ */ React7.createElement("div", { key: groupIndex, className: "py-1" }, /* @__PURE__ */ React7.createElement("div", { className: "py-1.5 px-2 text-xs font-semibold text-muted-foreground" }, group.label), groupOptions.map((option) => {
719
- const globalIndex = filteredOptions.indexOf(option);
694
+ id: dropdownId,
695
+ className: "absolute z-50 top-full mt-1 min-w-full overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md",
696
+ role: "listbox"
697
+ },
698
+ searchable && /* @__PURE__ */ React7.createElement("div", { className: "p-2 border-b border-border" }, /* @__PURE__ */ React7.createElement(
699
+ "input",
700
+ {
701
+ ref: searchInputRef,
702
+ type: "text",
703
+ className: "w-full border border-input rounded px-2 py-1 text-sm bg-transparent outline-none focus:ring-1 focus:ring-ring",
704
+ placeholder: "Search...",
705
+ value: searchQuery,
706
+ onChange: handleSearchChange,
707
+ onClick: (e) => e.stopPropagation(),
708
+ "aria-label": "Search options"
709
+ }
710
+ )),
711
+ /* @__PURE__ */ React7.createElement("div", { className: "max-h-64 overflow-y-auto p-1" }, filteredOptions.length === 0 ? /* @__PURE__ */ React7.createElement("div", { className: "py-2 px-3 text-center text-sm " }, "No options found") : optionGroups.length > 0 ? (
712
+ // Render grouped options
713
+ optionGroups.map((group, groupIndex) => {
714
+ const groupOptions = group.options.filter(
715
+ (opt) => filteredOptions.includes(opt)
716
+ );
717
+ if (groupOptions.length === 0) return null;
718
+ return /* @__PURE__ */ React7.createElement("div", { key: groupIndex, className: "py-1" }, /* @__PURE__ */ React7.createElement("div", { className: "py-1.5 px-2 text-xs font-semibold " }, group.label), groupOptions.map((option) => {
719
+ const globalIndex = filteredOptions.indexOf(option);
720
+ const isSelected = value === option.value;
721
+ const isFocused = globalIndex === focusedIndex;
722
+ const isDisabled = option.disabled;
723
+ return /* @__PURE__ */ React7.createElement(
724
+ "div",
725
+ {
726
+ key: option.value,
727
+ className: `relative flex w-full cursor-pointer items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors hover:bg-muted ${isFocused ? "bg-muted" : ""} ${isSelected ? "font-medium bg-muted" : ""} ${isDisabled ? "pointer-events-none opacity-50" : ""}`,
728
+ onClick: () => !isDisabled && handleSelect(option.value),
729
+ role: "option",
730
+ "aria-selected": isSelected,
731
+ "aria-disabled": isDisabled
732
+ },
733
+ renderOption ? renderOption(option) : option.label
734
+ );
735
+ }));
736
+ })
737
+ ) : (
738
+ // Render flat options
739
+ filteredOptions.map((option, index) => {
720
740
  const isSelected = value === option.value;
721
- const isFocused = globalIndex === focusedIndex;
741
+ const isFocused = index === focusedIndex;
722
742
  const isDisabled = option.disabled;
723
743
  return /* @__PURE__ */ React7.createElement(
724
744
  "div",
725
745
  {
726
746
  key: option.value,
727
- className: `relative flex w-full cursor-pointer items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground ${isFocused ? "bg-accent text-accent-foreground" : ""} ${isSelected ? "font-medium bg-accent" : ""} ${isDisabled ? "pointer-events-none opacity-50" : ""}`,
747
+ className: `relative flex w-full cursor-pointer items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors hover:bg-muted ${isFocused ? "bg-muted" : ""} ${isSelected ? "font-medium bg-muted" : ""} ${isDisabled ? "pointer-events-none opacity-50" : ""}`,
728
748
  onClick: () => !isDisabled && handleSelect(option.value),
729
749
  role: "option",
730
750
  "aria-selected": isSelected,
@@ -732,28 +752,9 @@ function Select({
732
752
  },
733
753
  renderOption ? renderOption(option) : option.label
734
754
  );
735
- }));
736
- })
737
- ) : (
738
- // Render flat options
739
- filteredOptions.map((option, index) => {
740
- const isSelected = value === option.value;
741
- const isFocused = index === focusedIndex;
742
- const isDisabled = option.disabled;
743
- return /* @__PURE__ */ React7.createElement(
744
- "div",
745
- {
746
- key: option.value,
747
- className: `relative flex w-full cursor-pointer items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground ${isFocused ? "bg-accent text-accent-foreground" : ""} ${isSelected ? "font-medium bg-accent" : ""} ${isDisabled ? "pointer-events-none opacity-50" : ""}`,
748
- onClick: () => !isDisabled && handleSelect(option.value),
749
- role: "option",
750
- "aria-selected": isSelected,
751
- "aria-disabled": isDisabled
752
- },
753
- renderOption ? renderOption(option) : option.label
754
- );
755
- })
756
- )))
755
+ })
756
+ ))
757
+ )
757
758
  );
758
759
  }
759
760
  Select.displayName = "Select";
@@ -762,7 +763,7 @@ function FileInput({
762
763
  value = [],
763
764
  onChange,
764
765
  onBlur,
765
- placeholder = "Choose file(s)...",
766
+ placeholder = "Choose file...",
766
767
  disabled = false,
767
768
  required = false,
768
769
  error = false,
@@ -865,7 +866,15 @@ function FileInput({
865
866
  inputRef.current.value = "";
866
867
  }
867
868
  },
868
- [value, onChange, validateFile, maxFiles, multiple, enableCropping, onValidationError]
869
+ [
870
+ value,
871
+ onChange,
872
+ validateFile,
873
+ maxFiles,
874
+ multiple,
875
+ enableCropping,
876
+ onValidationError
877
+ ]
869
878
  );
870
879
  const createCroppedImage = React7.useCallback(
871
880
  async (imageUrl, cropArea) => {
@@ -891,13 +900,17 @@ function FileInput({
891
900
  cropArea.width,
892
901
  cropArea.height
893
902
  );
894
- canvas.toBlob((blob) => {
895
- if (blob) {
896
- resolve(blob);
897
- } else {
898
- reject(new Error("Failed to create blob from canvas"));
899
- }
900
- }, "image/jpeg", 0.95);
903
+ canvas.toBlob(
904
+ (blob) => {
905
+ if (blob) {
906
+ resolve(blob);
907
+ } else {
908
+ reject(new Error("Failed to create blob from canvas"));
909
+ }
910
+ },
911
+ "image/jpeg",
912
+ 0.95
913
+ );
901
914
  };
902
915
  image.onerror = () => {
903
916
  reject(new Error("Failed to load image"));
@@ -917,11 +930,9 @@ function FileInput({
917
930
  if (onCropComplete) {
918
931
  onCropComplete(croppedBlob, imageToCrop.file);
919
932
  }
920
- const croppedFile = new File(
921
- [croppedBlob],
922
- imageToCrop.file.name,
923
- { type: "image/jpeg" }
924
- );
933
+ const croppedFile = new File([croppedBlob], imageToCrop.file.name, {
934
+ type: "image/jpeg"
935
+ });
925
936
  const updatedFiles = multiple ? [...value, croppedFile] : [croppedFile];
926
937
  onChange(updatedFiles);
927
938
  setCropperOpen(false);
@@ -933,7 +944,15 @@ function FileInput({
933
944
  } catch (error2) {
934
945
  console.error("Failed to crop image:", error2);
935
946
  }
936
- }, [imageToCrop, croppedAreaPixels, createCroppedImage, onCropComplete, value, onChange, multiple]);
947
+ }, [
948
+ imageToCrop,
949
+ croppedAreaPixels,
950
+ createCroppedImage,
951
+ onCropComplete,
952
+ value,
953
+ onChange,
954
+ multiple
955
+ ]);
937
956
  const handleCropCancel = React7.useCallback(() => {
938
957
  if (imageToCrop) {
939
958
  URL.revokeObjectURL(imageToCrop.url);
@@ -1045,7 +1064,7 @@ function FileInput({
1045
1064
  ), /* @__PURE__ */ React7.createElement(
1046
1065
  "div",
1047
1066
  {
1048
- className: `flex min-h-32 w-full cursor-pointer items-center justify-center rounded-md border-2 border-dashed border-input bg-transparent p-6 transition-colors hover:bg-accent/50 hover:border-ring ${dragActive ? "bg-accent border-ring" : ""} ${disabled ? "cursor-not-allowed opacity-50" : ""} ${error ? "border-red-500" : ""}`,
1067
+ className: `flex min-h-32 w-full cursor-pointer items-center justify-center rounded-md border-2 border-dashed border-input bg-transparent p-6 transition-colors hover:bg-primary/50 hover:border-ring ${dragActive ? "bg-primary text-primary-foreground border-ring" : ""} ${disabled ? "cursor-not-allowed opacity-50" : ""} ${error ? "border-red-500" : ""}`,
1049
1068
  onDragEnter: handleDrag,
1050
1069
  onDragLeave: handleDrag,
1051
1070
  onDragOver: handleDrag,
@@ -1060,7 +1079,6 @@ function FileInput({
1060
1079
  /* @__PURE__ */ React7.createElement("div", { className: "flex flex-col items-center gap-2 text-center" }, /* @__PURE__ */ React7.createElement(
1061
1080
  "svg",
1062
1081
  {
1063
- className: "text-muted-foreground",
1064
1082
  width: "48",
1065
1083
  height: "48",
1066
1084
  viewBox: "0 0 24 24",
@@ -1074,92 +1092,102 @@ function FileInput({
1074
1092
  /* @__PURE__ */ React7.createElement("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
1075
1093
  /* @__PURE__ */ React7.createElement("polyline", { points: "17 8 12 3 7 8" }),
1076
1094
  /* @__PURE__ */ React7.createElement("line", { x1: "12", y1: "3", x2: "12", y2: "15" })
1077
- ), /* @__PURE__ */ React7.createElement("p", { className: "text-sm font-medium" }, value.length > 0 ? `${value.length} file(s) selected` : placeholder), accept && /* @__PURE__ */ React7.createElement("p", { className: "text-xs text-muted-foreground" }, "Accepted: ", accept), maxSize && /* @__PURE__ */ React7.createElement("p", { className: "text-xs text-muted-foreground" }, "Max size: ", formatFileSize(maxSize)))
1095
+ ), /* @__PURE__ */ React7.createElement("p", { className: "text-sm font-medium" }, value.length > 0 ? `${value.length} file(s) selected` : placeholder), accept && /* @__PURE__ */ React7.createElement("p", { className: "text-xs" }, "Accepted: ", accept), maxSize && /* @__PURE__ */ React7.createElement("p", { className: "text-xs " }, "Max size: ", formatFileSize(maxSize)))
1078
1096
  ), value.length > 0 && /* @__PURE__ */ React7.createElement("ul", { className: "flex flex-col gap-2 mt-4", role: "list" }, value.map((file, index) => {
1079
1097
  const previewUrl = showPreview ? getPreviewUrl(file) : null;
1080
- return /* @__PURE__ */ React7.createElement("li", { key: `${file.name}-${index}`, className: "flex items-center gap-3 p-3 rounded-md border border-border bg-card hover:bg-accent/50 transition-colors" }, previewUrl && /* @__PURE__ */ React7.createElement(
1081
- "img",
1082
- {
1083
- src: previewUrl,
1084
- alt: file.name,
1085
- className: "w-12 h-12 rounded object-cover",
1086
- width: "48",
1087
- height: "48"
1088
- }
1089
- ), /* @__PURE__ */ React7.createElement("div", { className: "flex flex-col flex-1 min-w-0" }, /* @__PURE__ */ React7.createElement("span", { className: "text-sm font-medium truncate" }, file.name), /* @__PURE__ */ React7.createElement("span", { className: "text-xs text-muted-foreground" }, formatFileSize(file.size)), showProgress && uploadProgress[file.name] !== void 0 && /* @__PURE__ */ React7.createElement("div", { className: "flex items-center gap-2 mt-1" }, /* @__PURE__ */ React7.createElement(
1090
- "div",
1098
+ return /* @__PURE__ */ React7.createElement(
1099
+ "li",
1091
1100
  {
1092
- className: "h-1.5 bg-muted rounded-full overflow-hidden flex-1",
1093
- role: "progressbar",
1094
- "aria-valuenow": uploadProgress[file.name],
1095
- "aria-valuemin": 0,
1096
- "aria-valuemax": 100,
1097
- "aria-label": `Upload progress: ${uploadProgress[file.name]}%`
1101
+ key: `${file.name}-${index}`,
1102
+ className: "flex items-center gap-3 p-3 rounded-md border border-border bg-card text-card-foreground hover:bg-primary/50 transition-colors"
1098
1103
  },
1099
- /* @__PURE__ */ React7.createElement(
1100
- "div",
1104
+ previewUrl && /* @__PURE__ */ React7.createElement(
1105
+ "img",
1101
1106
  {
1102
- className: "h-full bg-primary transition-all",
1103
- style: { width: `${uploadProgress[file.name]}%` }
1107
+ src: previewUrl,
1108
+ alt: file.name,
1109
+ className: "w-12 h-12 rounded object-cover",
1110
+ width: "48",
1111
+ height: "48"
1104
1112
  }
1105
- )
1106
- ), /* @__PURE__ */ React7.createElement("span", { className: "text-xs text-muted-foreground" }, uploadProgress[file.name], "%"))), enableCropping && file.type.startsWith("image/") && /* @__PURE__ */ React7.createElement(
1107
- "button",
1108
- {
1109
- type: "button",
1110
- onClick: (e) => {
1111
- e.stopPropagation();
1112
- handleCrop(file);
1113
- },
1114
- disabled,
1115
- className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-accent text-muted-foreground hover:text-foreground transition-colors",
1116
- "aria-label": `Crop ${file.name}`
1117
- },
1118
- /* @__PURE__ */ React7.createElement(
1119
- "svg",
1113
+ ),
1114
+ /* @__PURE__ */ React7.createElement("div", { className: "flex flex-col flex-1 min-w-0" }, /* @__PURE__ */ React7.createElement("span", { className: "text-sm font-medium truncate" }, file.name), /* @__PURE__ */ React7.createElement("span", { className: "text-xs" }, formatFileSize(file.size)), showProgress && uploadProgress[file.name] !== void 0 && /* @__PURE__ */ React7.createElement("div", { className: "flex items-center gap-2 mt-1" }, /* @__PURE__ */ React7.createElement(
1115
+ "div",
1120
1116
  {
1121
- width: "20",
1122
- height: "20",
1123
- viewBox: "0 0 24 24",
1124
- fill: "none",
1125
- stroke: "currentColor",
1126
- strokeWidth: "2",
1127
- strokeLinecap: "round",
1128
- strokeLinejoin: "round",
1129
- "aria-hidden": "true"
1117
+ className: "h-1.5 bg-muted rounded-full overflow-hidden flex-1",
1118
+ role: "progressbar",
1119
+ "aria-valuenow": uploadProgress[file.name],
1120
+ "aria-valuemin": 0,
1121
+ "aria-valuemax": 100,
1122
+ "aria-label": `Upload progress: ${uploadProgress[file.name]}%`
1130
1123
  },
1131
- /* @__PURE__ */ React7.createElement("path", { d: "M6.13 1L6 16a2 2 0 0 0 2 2h15" }),
1132
- /* @__PURE__ */ React7.createElement("path", { d: "M1 6.13L16 6a2 2 0 0 1 2 2v15" })
1133
- )
1134
- ), /* @__PURE__ */ React7.createElement(
1135
- "button",
1136
- {
1137
- type: "button",
1138
- onClick: (e) => {
1139
- e.stopPropagation();
1140
- handleRemove(index);
1124
+ /* @__PURE__ */ React7.createElement(
1125
+ "div",
1126
+ {
1127
+ className: "h-full bg-primary transition-all",
1128
+ style: { width: `${uploadProgress[file.name]}%` }
1129
+ }
1130
+ )
1131
+ ), /* @__PURE__ */ React7.createElement("span", { className: "text-xs " }, uploadProgress[file.name], "%"))),
1132
+ enableCropping && file.type.startsWith("image/") && /* @__PURE__ */ React7.createElement(
1133
+ "button",
1134
+ {
1135
+ type: "button",
1136
+ onClick: (e) => {
1137
+ e.stopPropagation();
1138
+ handleCrop(file);
1139
+ },
1140
+ disabled,
1141
+ className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-primary hover:text-primary-foreground transition-colors",
1142
+ "aria-label": `Crop ${file.name}`
1141
1143
  },
1142
- disabled,
1143
- className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-accent text-muted-foreground hover:text-foreground transition-colors",
1144
- "aria-label": `Remove ${file.name}`
1145
- },
1144
+ /* @__PURE__ */ React7.createElement(
1145
+ "svg",
1146
+ {
1147
+ width: "20",
1148
+ height: "20",
1149
+ viewBox: "0 0 24 24",
1150
+ fill: "none",
1151
+ stroke: "currentColor",
1152
+ strokeWidth: "2",
1153
+ strokeLinecap: "round",
1154
+ strokeLinejoin: "round",
1155
+ "aria-hidden": "true"
1156
+ },
1157
+ /* @__PURE__ */ React7.createElement("path", { d: "M6.13 1L6 16a2 2 0 0 0 2 2h15" }),
1158
+ /* @__PURE__ */ React7.createElement("path", { d: "M1 6.13L16 6a2 2 0 0 1 2 2v15" })
1159
+ )
1160
+ ),
1146
1161
  /* @__PURE__ */ React7.createElement(
1147
- "svg",
1162
+ "button",
1148
1163
  {
1149
- width: "20",
1150
- height: "20",
1151
- viewBox: "0 0 24 24",
1152
- fill: "none",
1153
- stroke: "currentColor",
1154
- strokeWidth: "2",
1155
- strokeLinecap: "round",
1156
- strokeLinejoin: "round",
1157
- "aria-hidden": "true"
1164
+ type: "button",
1165
+ onClick: (e) => {
1166
+ e.stopPropagation();
1167
+ handleRemove(index);
1168
+ },
1169
+ disabled,
1170
+ className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-primary hover:text-primary-foreground transition-colors",
1171
+ "aria-label": `Remove ${file.name}`
1158
1172
  },
1159
- /* @__PURE__ */ React7.createElement("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1160
- /* @__PURE__ */ React7.createElement("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1173
+ /* @__PURE__ */ React7.createElement(
1174
+ "svg",
1175
+ {
1176
+ width: "20",
1177
+ height: "20",
1178
+ viewBox: "0 0 24 24",
1179
+ fill: "none",
1180
+ stroke: "currentColor",
1181
+ strokeWidth: "2",
1182
+ strokeLinecap: "round",
1183
+ strokeLinejoin: "round",
1184
+ "aria-hidden": "true"
1185
+ },
1186
+ /* @__PURE__ */ React7.createElement("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1187
+ /* @__PURE__ */ React7.createElement("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1188
+ )
1161
1189
  )
1162
- ));
1190
+ );
1163
1191
  })), cropperOpen && imageToCrop && /* @__PURE__ */ React7.createElement("div", { className: "fixed inset-0 z-50 flex items-center justify-center" }, /* @__PURE__ */ React7.createElement(
1164
1192
  "div",
1165
1193
  {
@@ -1171,7 +1199,7 @@ function FileInput({
1171
1199
  "button",
1172
1200
  {
1173
1201
  type: "button",
1174
- className: "flex items-center justify-center h-8 w-8 rounded hover:bg-accent text-muted-foreground hover:text-foreground transition-colors",
1202
+ className: "flex items-center justify-center h-8 w-8 rounded hover:bg-primary hover:text-primary-foreground transition-colors",
1175
1203
  onClick: handleCropCancel,
1176
1204
  "aria-label": "Close"
1177
1205
  },
@@ -1212,7 +1240,10 @@ function FileInput({
1212
1240
  const img = e.currentTarget;
1213
1241
  const containerWidth = 600;
1214
1242
  const containerHeight = 400;
1215
- const cropWidth = cropAspectRatio ? Math.min(containerWidth * 0.8, containerHeight * 0.8 * cropAspectRatio) : containerWidth * 0.8;
1243
+ const cropWidth = cropAspectRatio ? Math.min(
1244
+ containerWidth * 0.8,
1245
+ containerHeight * 0.8 * cropAspectRatio
1246
+ ) : containerWidth * 0.8;
1216
1247
  const cropHeight = cropAspectRatio ? cropWidth / cropAspectRatio : containerHeight * 0.8;
1217
1248
  const scale = zoom;
1218
1249
  const imgWidth = img.naturalWidth;
@@ -1241,7 +1272,16 @@ function FileInput({
1241
1272
  },
1242
1273
  /* @__PURE__ */ React7.createElement("div", { className: "absolute inset-0 grid grid-cols-3 grid-rows-3" }, /* @__PURE__ */ React7.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React7.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React7.createElement("div", { className: "border-b border-primary/30" }), /* @__PURE__ */ React7.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React7.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React7.createElement("div", { className: "border-b border-primary/30" }), /* @__PURE__ */ React7.createElement("div", { className: "border-r border-primary/30" }), /* @__PURE__ */ React7.createElement("div", { className: "border-r border-primary/30" }), /* @__PURE__ */ React7.createElement("div", null))
1243
1274
  )
1244
- ), /* @__PURE__ */ React7.createElement("div", { className: "flex items-center gap-3 mt-4" }, /* @__PURE__ */ React7.createElement("label", { htmlFor: "zoom-slider", className: "text-sm font-medium whitespace-nowrap" }, "Zoom: ", zoom.toFixed(1), "x"), /* @__PURE__ */ React7.createElement(
1275
+ ), /* @__PURE__ */ React7.createElement("div", { className: "flex items-center gap-3 mt-4" }, /* @__PURE__ */ React7.createElement(
1276
+ "label",
1277
+ {
1278
+ htmlFor: "zoom-slider",
1279
+ className: "text-sm font-medium whitespace-nowrap"
1280
+ },
1281
+ "Zoom: ",
1282
+ zoom.toFixed(1),
1283
+ "x"
1284
+ ), /* @__PURE__ */ React7.createElement(
1245
1285
  "input",
1246
1286
  {
1247
1287
  id: "zoom-slider",
@@ -1258,7 +1298,7 @@ function FileInput({
1258
1298
  "button",
1259
1299
  {
1260
1300
  type: "button",
1261
- className: "inline-flex items-center justify-center h-9 rounded-md px-4 text-sm font-medium border border-input bg-transparent hover:bg-accent hover:text-accent-foreground transition-colors",
1301
+ className: "inline-flex items-center justify-center h-9 rounded-md px-4 text-sm font-medium border border-input bg-transparent hover:bg-primary hover:text-primary-foreground transition-colors",
1262
1302
  onClick: handleCropCancel
1263
1303
  },
1264
1304
  "Cancel"
@@ -1652,36 +1692,43 @@ function TimePicker({
1652
1692
  }
1653
1693
  return mins;
1654
1694
  }, [minuteStep]);
1655
- const combinedClassName = `relative ${className}`.trim();
1695
+ const combinedClassName = cn("relative", className);
1656
1696
  const displayValue = formatTimeValue(timeValue, use24Hour);
1657
- return /* @__PURE__ */ React7.createElement("div", { ref: containerRef, className: combinedClassName }, /* @__PURE__ */ React7.createElement(
1658
- "input",
1659
- {
1660
- type: "hidden",
1661
- name,
1662
- value
1663
- }
1664
- ), /* @__PURE__ */ React7.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React7.createElement("span", { className: "absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground pointer-events-none", "aria-hidden": "true" }, /* @__PURE__ */ React7.createElement(
1665
- "svg",
1697
+ return /* @__PURE__ */ React7.createElement("div", { ref: containerRef, className: combinedClassName }, /* @__PURE__ */ React7.createElement("input", { type: "hidden", name, value }), /* @__PURE__ */ React7.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React7.createElement(
1698
+ "span",
1666
1699
  {
1667
- xmlns: "http://www.w3.org/2000/svg",
1668
- width: "18",
1669
- height: "18",
1670
- viewBox: "0 0 24 24",
1671
- fill: "none",
1672
- stroke: "currentColor",
1673
- strokeLinecap: "round",
1674
- strokeLinejoin: "round",
1675
- strokeWidth: "2"
1700
+ className: "absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none",
1701
+ "aria-hidden": "true"
1676
1702
  },
1677
- /* @__PURE__ */ React7.createElement("circle", { cx: "12", cy: "12", r: "10" }),
1678
- /* @__PURE__ */ React7.createElement("path", { d: "M12 6v6l4 2" })
1679
- )), /* @__PURE__ */ React7.createElement(
1703
+ /* @__PURE__ */ React7.createElement(
1704
+ "svg",
1705
+ {
1706
+ xmlns: "http://www.w3.org/2000/svg",
1707
+ width: "18",
1708
+ height: "18",
1709
+ viewBox: "0 0 24 24",
1710
+ fill: "none",
1711
+ stroke: "currentColor",
1712
+ strokeLinecap: "round",
1713
+ strokeLinejoin: "round",
1714
+ strokeWidth: "2"
1715
+ },
1716
+ /* @__PURE__ */ React7.createElement("circle", { cx: "12", cy: "12", r: "10" }),
1717
+ /* @__PURE__ */ React7.createElement("path", { d: "M12 6v6l4 2" })
1718
+ )
1719
+ ), /* @__PURE__ */ React7.createElement(
1680
1720
  "input",
1681
1721
  {
1682
1722
  ref: inputRef,
1683
1723
  type: "text",
1684
- className: `flex h-9 w-full rounded-md border border-input bg-transparent ${showIcon ? "pl-10" : "pl-3"} ${clearable && value ? "pr-10" : "pr-3"} py-1 text-base shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm ${error ? "border-red-500 ring-1 ring-red-500" : ""}`,
1724
+ className: cn(
1725
+ "flex h-9 w-full rounded-md border border-input bg-transparent py-1 text-base shadow-sm transition-colors",
1726
+ "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
1727
+ "disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
1728
+ showIcon ? "pl-10" : "pl-3",
1729
+ clearable && value ? "pr-10" : "pr-3",
1730
+ error && "border-red-500 ring-1 ring-red-500"
1731
+ ),
1685
1732
  value: displayValue,
1686
1733
  onClick: handleToggle,
1687
1734
  onBlur,
@@ -1697,13 +1744,13 @@ function TimePicker({
1697
1744
  "button",
1698
1745
  {
1699
1746
  type: "button",
1700
- className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors",
1747
+ className: "absolute right-3 top-1/2 -translate-y-1/2 transition-colors",
1701
1748
  onClick: handleClear,
1702
1749
  "aria-label": "Clear time",
1703
1750
  tabIndex: -1
1704
1751
  },
1705
1752
  "\u2715"
1706
- )), isOpen && !disabled && /* @__PURE__ */ React7.createElement("div", { className: "absolute z-50 top-full mt-1 min-w-full rounded-md border border-border bg-popover text-popover-foreground shadow-md p-3" }, /* @__PURE__ */ React7.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React7.createElement("div", { className: "flex flex-col flex-1" }, /* @__PURE__ */ React7.createElement("div", { className: "text-xs font-medium text-muted-foreground mb-2 text-center" }, use24Hour ? "Hour" : "Hour"), /* @__PURE__ */ React7.createElement("div", { className: "flex flex-col gap-1 max-h-48 overflow-y-auto" }, hours.map((hour) => {
1753
+ )), isOpen && !disabled && /* @__PURE__ */ React7.createElement("div", { className: "absolute z-50 top-full mt-1 min-w-full rounded-md border border-border bg-popover text-popover-foreground shadow-md p-3" }, /* @__PURE__ */ React7.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React7.createElement("div", { className: "flex flex-col flex-1" }, /* @__PURE__ */ React7.createElement("div", { className: "text-xs font-medium mb-2 text-center" }, use24Hour ? "Hour" : "Hour"), /* @__PURE__ */ React7.createElement("div", { className: "flex flex-col gap-1 max-h-48 overflow-y-auto" }, hours.map((hour) => {
1707
1754
  const displayHour = use24Hour ? hour : hour;
1708
1755
  const isSelected = use24Hour ? timeValue?.hour === (hour === 0 ? 12 : hour > 12 ? hour - 12 : hour) && timeValue?.period === (hour >= 12 ? "PM" : "AM") : timeValue?.hour === hour;
1709
1756
  return /* @__PURE__ */ React7.createElement(
@@ -1711,7 +1758,12 @@ function TimePicker({
1711
1758
  {
1712
1759
  key: hour,
1713
1760
  type: "button",
1714
- className: `flex items-center justify-center h-8 w-full rounded border-none bg-transparent cursor-pointer text-sm transition-colors hover:bg-accent hover:text-accent-foreground ${isSelected ? "bg-primary text-primary-foreground font-semibold" : ""}`,
1761
+ className: cn(
1762
+ "flex items-center justify-center h-8 w-full rounded",
1763
+ "border-none bg-transparent cursor-pointer text-sm transition-colors",
1764
+ "hover:bg-primary hover:text-primary-foreground",
1765
+ isSelected ? "bg-primary text-primary-foreground font-semibold" : ""
1766
+ ),
1715
1767
  onClick: () => {
1716
1768
  if (use24Hour) {
1717
1769
  const hour12 = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour;
@@ -1731,24 +1783,34 @@ function TimePicker({
1731
1783
  },
1732
1784
  String(displayHour).padStart(2, "0")
1733
1785
  );
1734
- }))), /* @__PURE__ */ React7.createElement("div", { className: "flex flex-col flex-1" }, /* @__PURE__ */ React7.createElement("div", { className: "text-xs font-medium text-muted-foreground mb-2 text-center" }, "Minute"), /* @__PURE__ */ React7.createElement("div", { className: "flex flex-col gap-1 max-h-48 overflow-y-auto" }, minutes.map((minute) => {
1786
+ }))), /* @__PURE__ */ React7.createElement("div", { className: "flex flex-col flex-1" }, /* @__PURE__ */ React7.createElement("div", { className: "text-xs font-medium mb-2 text-center" }, "Minute"), /* @__PURE__ */ React7.createElement("div", { className: "flex flex-col gap-1 max-h-48 overflow-y-auto" }, minutes.map((minute) => {
1735
1787
  const isSelected = timeValue?.minute === minute;
1736
1788
  return /* @__PURE__ */ React7.createElement(
1737
1789
  "button",
1738
1790
  {
1739
1791
  key: minute,
1740
1792
  type: "button",
1741
- className: `flex items-center justify-center h-8 w-full rounded border-none bg-transparent cursor-pointer text-sm transition-colors hover:bg-accent hover:text-accent-foreground ${isSelected ? "bg-primary text-primary-foreground font-semibold" : ""}`,
1793
+ className: cn(
1794
+ "flex items-center justify-center h-8 w-full",
1795
+ "rounded border-none bg-transparent cursor-pointer text-sm transition-colors",
1796
+ "hover:bg-primary hover:text-primary-foreground",
1797
+ isSelected ? "bg-primary text-primary-foreground font-semibold" : ""
1798
+ ),
1742
1799
  onClick: () => handleMinuteChange(minute),
1743
1800
  "aria-label": `${String(minute).padStart(2, "0")} minutes`
1744
1801
  },
1745
1802
  String(minute).padStart(2, "0")
1746
1803
  );
1747
- }))), !use24Hour && /* @__PURE__ */ React7.createElement("div", { className: "flex flex-col w-20" }, /* @__PURE__ */ React7.createElement("div", { className: "text-xs font-medium text-muted-foreground mb-2 text-center" }, "Period"), /* @__PURE__ */ React7.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React7.createElement(
1804
+ }))), !use24Hour && /* @__PURE__ */ React7.createElement("div", { className: "flex flex-col w-20" }, /* @__PURE__ */ React7.createElement("div", { className: "text-xs font-medium mb-2 text-center" }, "Period"), /* @__PURE__ */ React7.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React7.createElement(
1748
1805
  "button",
1749
1806
  {
1750
1807
  type: "button",
1751
- className: `flex items-center justify-center h-8 w-full rounded border-none bg-transparent cursor-pointer text-sm transition-colors hover:bg-accent hover:text-accent-foreground ${timeValue?.period === "AM" ? "bg-primary text-primary-foreground font-semibold" : ""}`,
1808
+ className: cn(
1809
+ "flex items-center justify-center h-8 w-full",
1810
+ "rounded border-none bg-transparent cursor-pointer text-sm",
1811
+ "transition-colors hover:bg-primary hover:text-primary-foreground",
1812
+ timeValue?.period === "AM" ? "bg-muted font-semibold" : ""
1813
+ ),
1752
1814
  onClick: () => handlePeriodChange("AM")
1753
1815
  },
1754
1816
  "AM"
@@ -1756,7 +1818,12 @@ function TimePicker({
1756
1818
  "button",
1757
1819
  {
1758
1820
  type: "button",
1759
- className: `flex items-center justify-center h-8 w-full rounded border-none bg-transparent cursor-pointer text-sm transition-colors hover:bg-accent hover:text-accent-foreground ${timeValue?.period === "PM" ? "bg-primary text-primary-foreground font-semibold" : ""}`,
1821
+ className: cn(
1822
+ "flex items-center justify-center h-8 w-full",
1823
+ "rounded border-none bg-transparent cursor-pointer text-sm",
1824
+ "transition-colors hover:bg-primary hover:text-primary-foreground",
1825
+ timeValue?.period === "PM" ? "bg-muted font-semibold" : ""
1826
+ ),
1760
1827
  onClick: () => handlePeriodChange("PM")
1761
1828
  },
1762
1829
  "PM"
@@ -1801,7 +1868,9 @@ function DateRangePicker({
1801
1868
  ...props
1802
1869
  }) {
1803
1870
  const [isOpen, setIsOpen] = React7.useState(false);
1804
- const [selectedMonth, setSelectedMonth] = React7.useState(value.start || /* @__PURE__ */ new Date());
1871
+ const [selectedMonth, setSelectedMonth] = React7.useState(
1872
+ value.start || /* @__PURE__ */ new Date()
1873
+ );
1805
1874
  const [rangeStart, setRangeStart] = React7.useState(value.start);
1806
1875
  const [rangeEnd, setRangeEnd] = React7.useState(value.end);
1807
1876
  const [hoverDate, setHoverDate] = React7.useState(null);
@@ -1899,7 +1968,7 @@ function DateRangePicker({
1899
1968
  "button",
1900
1969
  {
1901
1970
  type: "button",
1902
- className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-accent cursor-pointer",
1971
+ className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-primary hover:text-primary-foreground cursor-pointer",
1903
1972
  onClick: handlePrevMonth,
1904
1973
  "aria-label": "Previous month"
1905
1974
  },
@@ -1908,19 +1977,30 @@ function DateRangePicker({
1908
1977
  "button",
1909
1978
  {
1910
1979
  type: "button",
1911
- className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-accent cursor-pointer",
1980
+ className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-primary hover:text-primary-foreground cursor-pointer",
1912
1981
  onClick: handleNextMonth,
1913
1982
  "aria-label": "Next month"
1914
1983
  },
1915
1984
  "\u2192"
1916
- )), /* @__PURE__ */ React7.createElement("div", { className: "grid grid-cols-7 gap-1 mt-2" }, ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => /* @__PURE__ */ React7.createElement("div", { key: day, className: "flex items-center justify-center h-8 w-full text-xs text-muted-foreground font-medium" }, day))), /* @__PURE__ */ React7.createElement("div", { className: "grid grid-cols-7 gap-1" }, days.map((date, index) => {
1985
+ )), /* @__PURE__ */ React7.createElement("div", { className: "grid grid-cols-7 gap-1 mt-2" }, ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => /* @__PURE__ */ React7.createElement(
1986
+ "div",
1987
+ {
1988
+ key: day,
1989
+ className: "flex items-center justify-center h-8 w-full text-xs font-medium"
1990
+ },
1991
+ day
1992
+ ))), /* @__PURE__ */ React7.createElement("div", { className: "grid grid-cols-7 gap-1" }, days.map((date, index) => {
1917
1993
  if (!date) {
1918
1994
  return /* @__PURE__ */ React7.createElement("div", { key: `empty-${index}` });
1919
1995
  }
1920
1996
  const isStart = rangeStart && date.toDateString() === rangeStart.toDateString();
1921
1997
  const isEnd = rangeEnd && date.toDateString() === rangeEnd.toDateString();
1998
+ const isRangeEndpoint = Boolean(isStart || isEnd);
1922
1999
  const isInRange = rangeStart && rangeEnd && isDateInRange(date, rangeStart, rangeEnd);
1923
2000
  const isInHoverRange = rangeStart && !rangeEnd && hoverDate && (date >= rangeStart && date <= hoverDate || date <= rangeStart && date >= hoverDate);
2001
+ const isRangeHighlight = Boolean(
2002
+ (isInRange || isInHoverRange) && !isRangeEndpoint
2003
+ );
1924
2004
  const isToday = date.toDateString() === (/* @__PURE__ */ new Date()).toDateString();
1925
2005
  const disabled2 = isDisabled(date);
1926
2006
  return /* @__PURE__ */ React7.createElement(
@@ -1928,7 +2008,14 @@ function DateRangePicker({
1928
2008
  {
1929
2009
  key: date.toISOString(),
1930
2010
  type: "button",
1931
- className: `flex items-center justify-center h-8 w-full rounded border-none bg-transparent cursor-pointer text-sm transition-colors hover:bg-accent hover:text-accent-foreground ${isStart || isEnd ? "bg-primary text-primary-foreground font-semibold" : ""} ${isInRange || isInHoverRange ? "bg-accent/50" : ""} ${isToday ? "border border-primary" : ""} ${disabled2 ? "cursor-not-allowed opacity-50 pointer-events-none" : ""}`,
2011
+ className: cn(
2012
+ "flex items-center justify-center h-8 w-full rounded border-none bg-transparent",
2013
+ "cursor-pointer text-sm transition-colors hover:bg-muted",
2014
+ isRangeEndpoint && "bg-muted font-semibold",
2015
+ isRangeHighlight && "bg-muted/70",
2016
+ isToday && "border border-primary",
2017
+ disabled2 && "cursor-not-allowed opacity-50 pointer-events-none"
2018
+ ),
1932
2019
  onClick: () => !disabled2 && handleDateSelect(date),
1933
2020
  onMouseEnter: () => setHoverDate(date),
1934
2021
  onMouseLeave: () => setHoverDate(null),
@@ -1939,7 +2026,7 @@ function DateRangePicker({
1939
2026
  );
1940
2027
  })));
1941
2028
  };
1942
- const combinedClassName = `relative ${className}`.trim();
2029
+ const combinedClassName = cn("relative", className);
1943
2030
  const displayValue = rangeStart && rangeEnd ? `${formatDate2(rangeStart, format)}${separator}${formatDate2(rangeEnd, format)}` : rangeStart ? formatDate2(rangeStart, format) : "";
1944
2031
  return /* @__PURE__ */ React7.createElement("div", { ref: containerRef, className: combinedClassName }, /* @__PURE__ */ React7.createElement(
1945
2032
  "input",
@@ -1955,25 +2042,39 @@ function DateRangePicker({
1955
2042
  name: `${name}[end]`,
1956
2043
  value: rangeEnd ? rangeEnd.toISOString() : ""
1957
2044
  }
1958
- ), /* @__PURE__ */ React7.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React7.createElement("span", { className: "absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground pointer-events-none", "aria-hidden": "true" }, /* @__PURE__ */ React7.createElement(
1959
- "svg",
2045
+ ), /* @__PURE__ */ React7.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React7.createElement(
2046
+ "span",
1960
2047
  {
1961
- xmlns: "http://www.w3.org/2000/svg",
1962
- width: "18",
1963
- height: "18",
1964
- viewBox: "0 0 24 24",
1965
- fill: "none",
1966
- stroke: "currentColor",
1967
- strokeLinecap: "round",
1968
- strokeLinejoin: "round",
1969
- strokeWidth: "2"
2048
+ className: "absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none",
2049
+ "aria-hidden": "true"
1970
2050
  },
1971
- /* @__PURE__ */ React7.createElement("path", { d: "M8 2v4m8-4v4m5 8V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h8M3 10h18m-5 10l2 2l4-4" })
1972
- )), /* @__PURE__ */ React7.createElement(
2051
+ /* @__PURE__ */ React7.createElement(
2052
+ "svg",
2053
+ {
2054
+ xmlns: "http://www.w3.org/2000/svg",
2055
+ width: "18",
2056
+ height: "18",
2057
+ viewBox: "0 0 24 24",
2058
+ fill: "none",
2059
+ stroke: "currentColor",
2060
+ strokeLinecap: "round",
2061
+ strokeLinejoin: "round",
2062
+ strokeWidth: "2"
2063
+ },
2064
+ /* @__PURE__ */ React7.createElement("path", { d: "M8 2v4m8-4v4m5 8V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h8M3 10h18m-5 10l2 2l4-4" })
2065
+ )
2066
+ ), /* @__PURE__ */ React7.createElement(
1973
2067
  "input",
1974
2068
  {
1975
2069
  type: "text",
1976
- className: `flex h-9 w-full rounded-md border border-input bg-transparent ${showIcon ? "pl-10" : "pl-3"} ${clearable && (rangeStart || rangeEnd) ? "pr-10" : "pr-3"} py-1 text-base shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm ${error ? "border-red-500 ring-1 ring-red-500" : ""}`,
2070
+ className: cn(
2071
+ "flex h-9 w-full rounded-md border border-input bg-transparent py-1 text-base shadow-sm transition-colors",
2072
+ "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
2073
+ "disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
2074
+ showIcon ? "pl-10" : "pl-3",
2075
+ clearable && (rangeStart || rangeEnd) ? "pr-10" : "pr-3",
2076
+ error && "border-red-500 ring-1 ring-red-500"
2077
+ ),
1977
2078
  value: displayValue,
1978
2079
  onClick: handleToggle,
1979
2080
  onBlur,
@@ -1989,13 +2090,13 @@ function DateRangePicker({
1989
2090
  "button",
1990
2091
  {
1991
2092
  type: "button",
1992
- className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors",
2093
+ className: "absolute right-3 top-1/2 -translate-y-1/2 transition-colors",
1993
2094
  onClick: handleClear,
1994
2095
  "aria-label": "Clear date range",
1995
2096
  tabIndex: -1
1996
2097
  },
1997
2098
  "\u2715"
1998
- )), isOpen && !disabled && /* @__PURE__ */ React7.createElement("div", { className: "absolute z-50 top-full mt-1 min-w-full rounded-md border border-border bg-popover text-popover-foreground shadow-md p-3" }, renderCalendar(), rangeStart && !rangeEnd && /* @__PURE__ */ React7.createElement("div", { className: "text-xs text-muted-foreground text-center pt-2 border-t border-border mt-2" }, "Select end date")));
2099
+ )), isOpen && !disabled && /* @__PURE__ */ React7.createElement("div", { className: "absolute z-50 top-full mt-1 min-w-full rounded-md border border-border bg-popover text-popover-foreground shadow-md p-3" }, renderCalendar(), rangeStart && !rangeEnd && /* @__PURE__ */ React7.createElement("div", { className: "text-xs text-center pt-2 border-t border-border mt-2" }, "Select end date")));
1999
2100
  }
2000
2101
  DateRangePicker.displayName = "DateRangePicker";
2001
2102
  function htmlToMarkdown(html) {
@@ -2051,11 +2152,19 @@ function RichTextEditor({
2051
2152
  className = "",
2052
2153
  mode = "wysiwyg",
2053
2154
  allowModeSwitch = false,
2054
- placeholder = "Start typing...",
2155
+ placeholder = "Your message...",
2055
2156
  minHeight = "200px",
2056
2157
  maxHeight,
2057
2158
  showToolbar = true,
2058
- toolbarButtons = ["bold", "italic", "underline", "heading", "bulletList", "orderedList", "link"],
2159
+ toolbarButtons = [
2160
+ "bold",
2161
+ "italic",
2162
+ "underline",
2163
+ "heading",
2164
+ "bulletList",
2165
+ "orderedList",
2166
+ "link"
2167
+ ],
2059
2168
  ...props
2060
2169
  }) {
2061
2170
  const [currentMode, setCurrentMode] = React7.useState(mode);
@@ -2164,7 +2273,7 @@ function RichTextEditor({
2164
2273
  {
2165
2274
  key: buttonName,
2166
2275
  type: "button",
2167
- className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-accent text-muted-foreground hover:text-foreground cursor-pointer transition-colors disabled:cursor-not-allowed disabled:opacity-50",
2276
+ className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-muted cursor-pointer transition-colors disabled:cursor-not-allowed disabled:opacity-50",
2168
2277
  onClick: () => editorRef.current && button.action(editorRef.current),
2169
2278
  title: button.title,
2170
2279
  disabled: disabled || currentMode === "markdown",
@@ -2176,7 +2285,7 @@ function RichTextEditor({
2176
2285
  "button",
2177
2286
  {
2178
2287
  type: "button",
2179
- className: "flex items-center justify-center h-8 px-3 rounded border-none bg-transparent hover:bg-accent text-xs font-medium text-muted-foreground hover:text-foreground cursor-pointer transition-colors disabled:cursor-not-allowed disabled:opacity-50",
2288
+ className: "flex items-center justify-center h-8 px-3 rounded border-none bg-transparent hover:bg-muted text-xs font-medium cursor-pointer transition-colors disabled:cursor-not-allowed disabled:opacity-50",
2180
2289
  onClick: handleModeToggle,
2181
2290
  disabled,
2182
2291
  title: `Switch to ${currentMode === "wysiwyg" ? "Markdown" : "WYSIWYG"}`,
@@ -2187,7 +2296,7 @@ function RichTextEditor({
2187
2296
  "div",
2188
2297
  {
2189
2298
  ref: editorRef,
2190
- className: "w-full p-3 text-base md:text-sm outline-none bg-transparent focus-visible:outline-none [&:empty:before]:content-[attr(data-placeholder)] [&:empty:before]:text-muted-foreground",
2299
+ className: "w-full p-3 text-base md:text-sm outline-none bg-transparent focus-visible:outline-none [&:empty:before]:content-[attr(data-placeholder)]",
2191
2300
  role: "textbox",
2192
2301
  contentEditable: !disabled,
2193
2302
  onInput: handleWysiwygChange,
@@ -2202,7 +2311,7 @@ function RichTextEditor({
2202
2311
  "textarea",
2203
2312
  {
2204
2313
  ref: textareaRef,
2205
- className: "w-full p-3 text-base md:text-sm outline-none bg-transparent resize-none focus-visible:outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
2314
+ className: "w-full p-3 text-base md:text-sm outline-none bg-transparent resize-none focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50",
2206
2315
  value: content,
2207
2316
  onChange: handleMarkdownChange,
2208
2317
  onBlur,