@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.cjs CHANGED
@@ -45,7 +45,7 @@ function TextInput({
45
45
  const handleBlur = () => {
46
46
  onBlur?.();
47
47
  };
48
- 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";
48
+ 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";
49
49
  const errorClassName = error ? "border-red-500 ring-1 ring-red-500" : "";
50
50
  const combinedClassName = `${baseClassName} ${errorClassName} ${className}`.trim();
51
51
  return /* @__PURE__ */ React7__namespace.createElement(
@@ -92,7 +92,7 @@ function TextArea({
92
92
  const handleBlur = () => {
93
93
  onBlur?.();
94
94
  };
95
- 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";
95
+ 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";
96
96
  const errorClassName = error ? "border-red-500 ring-1 ring-red-500" : "";
97
97
  const combinedClassName = `${baseClassName} ${errorClassName} ${className}`.trim();
98
98
  return /* @__PURE__ */ React7__namespace.createElement(
@@ -326,8 +326,8 @@ function CheckboxGroup({
326
326
  gridTemplateColumns: `repeat(${gridColumns}, 1fr)`
327
327
  } : void 0
328
328
  },
329
- label && /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-sm font-medium" }, label),
330
- description && /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-muted-foreground text-sm" }, description),
329
+ label ? /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-sm font-medium" }, label) : null,
330
+ description ? /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-xs opacity-70" }, description) : null,
331
331
  showSelectAll && enabledOptions.length > 0 && /* @__PURE__ */ React7__namespace.createElement(
332
332
  Checkbox,
333
333
  {
@@ -389,7 +389,6 @@ function Radio({
389
389
  error = false,
390
390
  className = "",
391
391
  layout = "stacked",
392
- radioVariant = "inline",
393
392
  label,
394
393
  options,
395
394
  ...props
@@ -425,12 +424,16 @@ function Radio({
425
424
  const handleBlur = () => {
426
425
  onBlur?.();
427
426
  };
428
- const containerClass = cn(
429
- "w-full gap-3",
430
- layout === "stacked" && "flex flex-col",
431
- layout === "inline" && "flex flex-row flex-wrap",
432
- className
433
- );
427
+ const useChoiceCard = React7__namespace.useMemo(() => {
428
+ return options.some((option) => option.description);
429
+ }, [options]);
430
+ const containerClass = React7__namespace.useMemo(() => {
431
+ return cn(
432
+ "w-full gap-3 grid grid-cols-1",
433
+ layout === "inline" && "md:grid-cols-2",
434
+ className
435
+ );
436
+ }, [layout, className]);
434
437
  return /* @__PURE__ */ React7__namespace.createElement(
435
438
  "div",
436
439
  {
@@ -477,29 +480,22 @@ function Radio({
477
480
  },
478
481
  isChecked && /* @__PURE__ */ React7__namespace.createElement("div", { className: "size-3 rounded-full bg-primary" })
479
482
  ));
480
- const labelContent = /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col gap-0.5" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-sm font-medium" }, option.label), hasDescription && /* @__PURE__ */ React7__namespace.createElement(
481
- "p",
482
- {
483
- className: "text-xs opacity-75",
484
- id: `${radioId}-description`
485
- },
486
- option.description
487
- ));
483
+ const labelContent = /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col gap-0.5" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-sm font-medium" }, option.label), hasDescription && /* @__PURE__ */ React7__namespace.createElement("p", { className: "text-xs opacity-75", id: `${radioId}-description` }, option.description));
488
484
  return /* @__PURE__ */ React7__namespace.createElement(
489
485
  "label",
490
486
  {
491
487
  key: option.value,
492
488
  className: cn(
493
489
  "w-full h-full flex gap-3 p-3 duration-200",
494
- radioVariant === "boxed" && "border rounded-lg hover:ring-2",
495
- radioVariant === "boxed" && isChecked && "ring-2",
490
+ useChoiceCard && "border rounded-lg hover:ring-2",
491
+ useChoiceCard && isChecked && "ring-2",
496
492
  isDisabled ? "opacity-50 cursor-not-allowed hover:ring-0" : "cursor-pointer"
497
493
  ),
498
494
  htmlFor: radioId,
499
495
  onKeyDown: (e) => handleKeyDown(e, index),
500
496
  tabIndex: isDisabled ? -1 : 0
501
497
  },
502
- /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex w-full flex-row items-center gap-2" }, radioVariant === "inline" && radioIndicator, /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-1 flex-col gap-0.5" }, labelContent), radioVariant === "boxed" && radioIndicator)
498
+ /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex w-full flex-row items-center gap-2" }, !useChoiceCard && radioIndicator, /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-1 flex-col gap-0.5" }, labelContent), useChoiceCard && radioIndicator)
503
499
  );
504
500
  })
505
501
  );
@@ -589,9 +585,7 @@ function Select({
589
585
  if (enabledOptions.length > 0) {
590
586
  const currentIndexInFiltered = focusedIndex;
591
587
  const nextIndex = (currentIndexInFiltered + 1) % enabledOptions.length;
592
- setFocusedIndex(
593
- filteredOptions.indexOf(enabledOptions[nextIndex])
594
- );
588
+ setFocusedIndex(filteredOptions.indexOf(enabledOptions[nextIndex]));
595
589
  }
596
590
  }
597
591
  break;
@@ -602,9 +596,7 @@ function Select({
602
596
  if (enabledOptions.length > 0) {
603
597
  const currentIndexInFiltered = focusedIndex;
604
598
  const prevIndex = (currentIndexInFiltered - 1 + enabledOptions.length) % enabledOptions.length;
605
- setFocusedIndex(
606
- filteredOptions.indexOf(enabledOptions[prevIndex])
607
- );
599
+ setFocusedIndex(filteredOptions.indexOf(enabledOptions[prevIndex]));
608
600
  }
609
601
  }
610
602
  break;
@@ -694,7 +686,7 @@ function Select({
694
686
  /* @__PURE__ */ React7__namespace.createElement(
695
687
  "div",
696
688
  {
697
- 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" : ""}`,
689
+ 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" : ""}`,
698
690
  onClick: handleToggle,
699
691
  role: "combobox",
700
692
  "aria-expanded": isOpen,
@@ -705,48 +697,76 @@ function Select({
705
697
  "aria-disabled": disabled,
706
698
  tabIndex: disabled ? -1 : 0
707
699
  },
708
- /* @__PURE__ */ React7__namespace.createElement("span", { className: "flex items-center flex-1 overflow-hidden text-ellipsis" }, selectedOption ? renderOption ? renderOption(selectedOption) : selectedOption.label : /* @__PURE__ */ React7__namespace.createElement("span", { className: "text-muted-foreground" }, placeholder)),
700
+ /* @__PURE__ */ React7__namespace.createElement("span", { className: "flex items-center flex-1 overflow-hidden text-ellipsis" }, selectedOption ? renderOption ? renderOption(selectedOption) : selectedOption.label : /* @__PURE__ */ React7__namespace.createElement("span", { className: "relative" }, placeholder)),
709
701
  /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex items-center gap-1 ml-2" }, loading && /* @__PURE__ */ React7__namespace.createElement("span", { className: "text-xs" }, "\u23F3"), clearable && value && !disabled && !loading && /* @__PURE__ */ React7__namespace.createElement(
710
702
  "button",
711
703
  {
712
704
  type: "button",
713
- 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",
705
+ 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",
714
706
  onClick: handleClear,
715
707
  "aria-label": "Clear selection",
716
708
  tabIndex: -1
717
709
  },
718
710
  "\u2715"
719
- ), /* @__PURE__ */ React7__namespace.createElement("span", { className: "text-muted-foreground text-xs leading-none", "aria-hidden": "true" }, isOpen ? "\u25B2" : "\u25BC"))
711
+ ), /* @__PURE__ */ React7__namespace.createElement("span", { className: "text-xs leading-none", "aria-hidden": "true" }, isOpen ? "\u25B2" : "\u25BC"))
720
712
  ),
721
- isOpen && /* @__PURE__ */ React7__namespace.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__namespace.createElement("div", { className: "p-2 border-b border-border" }, /* @__PURE__ */ React7__namespace.createElement(
722
- "input",
713
+ isOpen && /* @__PURE__ */ React7__namespace.createElement(
714
+ "div",
723
715
  {
724
- ref: searchInputRef,
725
- type: "text",
726
- className: "w-full border border-input rounded px-2 py-1 text-sm bg-transparent outline-none focus:ring-1 focus:ring-ring",
727
- placeholder: "Search...",
728
- value: searchQuery,
729
- onChange: handleSearchChange,
730
- onClick: (e) => e.stopPropagation(),
731
- "aria-label": "Search options"
732
- }
733
- )), /* @__PURE__ */ React7__namespace.createElement("div", { className: "max-h-64 overflow-y-auto p-1" }, filteredOptions.length === 0 ? /* @__PURE__ */ React7__namespace.createElement("div", { className: "py-2 px-3 text-center text-sm text-muted-foreground" }, "No options found") : optionGroups.length > 0 ? (
734
- // Render grouped options
735
- optionGroups.map((group, groupIndex) => {
736
- const groupOptions = group.options.filter(
737
- (opt) => filteredOptions.includes(opt)
738
- );
739
- if (groupOptions.length === 0) return null;
740
- return /* @__PURE__ */ React7__namespace.createElement("div", { key: groupIndex, className: "py-1" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "py-1.5 px-2 text-xs font-semibold text-muted-foreground" }, group.label), groupOptions.map((option) => {
741
- const globalIndex = filteredOptions.indexOf(option);
716
+ id: dropdownId,
717
+ 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",
718
+ role: "listbox"
719
+ },
720
+ searchable && /* @__PURE__ */ React7__namespace.createElement("div", { className: "p-2 border-b border-border" }, /* @__PURE__ */ React7__namespace.createElement(
721
+ "input",
722
+ {
723
+ ref: searchInputRef,
724
+ type: "text",
725
+ className: "w-full border border-input rounded px-2 py-1 text-sm bg-transparent outline-none focus:ring-1 focus:ring-ring",
726
+ placeholder: "Search...",
727
+ value: searchQuery,
728
+ onChange: handleSearchChange,
729
+ onClick: (e) => e.stopPropagation(),
730
+ "aria-label": "Search options"
731
+ }
732
+ )),
733
+ /* @__PURE__ */ React7__namespace.createElement("div", { className: "max-h-64 overflow-y-auto p-1" }, filteredOptions.length === 0 ? /* @__PURE__ */ React7__namespace.createElement("div", { className: "py-2 px-3 text-center text-sm " }, "No options found") : optionGroups.length > 0 ? (
734
+ // Render grouped options
735
+ optionGroups.map((group, groupIndex) => {
736
+ const groupOptions = group.options.filter(
737
+ (opt) => filteredOptions.includes(opt)
738
+ );
739
+ if (groupOptions.length === 0) return null;
740
+ return /* @__PURE__ */ React7__namespace.createElement("div", { key: groupIndex, className: "py-1" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "py-1.5 px-2 text-xs font-semibold " }, group.label), groupOptions.map((option) => {
741
+ const globalIndex = filteredOptions.indexOf(option);
742
+ const isSelected = value === option.value;
743
+ const isFocused = globalIndex === focusedIndex;
744
+ const isDisabled = option.disabled;
745
+ return /* @__PURE__ */ React7__namespace.createElement(
746
+ "div",
747
+ {
748
+ key: option.value,
749
+ 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" : ""}`,
750
+ onClick: () => !isDisabled && handleSelect(option.value),
751
+ role: "option",
752
+ "aria-selected": isSelected,
753
+ "aria-disabled": isDisabled
754
+ },
755
+ renderOption ? renderOption(option) : option.label
756
+ );
757
+ }));
758
+ })
759
+ ) : (
760
+ // Render flat options
761
+ filteredOptions.map((option, index) => {
742
762
  const isSelected = value === option.value;
743
- const isFocused = globalIndex === focusedIndex;
763
+ const isFocused = index === focusedIndex;
744
764
  const isDisabled = option.disabled;
745
765
  return /* @__PURE__ */ React7__namespace.createElement(
746
766
  "div",
747
767
  {
748
768
  key: option.value,
749
- 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" : ""}`,
769
+ 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" : ""}`,
750
770
  onClick: () => !isDisabled && handleSelect(option.value),
751
771
  role: "option",
752
772
  "aria-selected": isSelected,
@@ -754,28 +774,9 @@ function Select({
754
774
  },
755
775
  renderOption ? renderOption(option) : option.label
756
776
  );
757
- }));
758
- })
759
- ) : (
760
- // Render flat options
761
- filteredOptions.map((option, index) => {
762
- const isSelected = value === option.value;
763
- const isFocused = index === focusedIndex;
764
- const isDisabled = option.disabled;
765
- return /* @__PURE__ */ React7__namespace.createElement(
766
- "div",
767
- {
768
- key: option.value,
769
- 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" : ""}`,
770
- onClick: () => !isDisabled && handleSelect(option.value),
771
- role: "option",
772
- "aria-selected": isSelected,
773
- "aria-disabled": isDisabled
774
- },
775
- renderOption ? renderOption(option) : option.label
776
- );
777
- })
778
- )))
777
+ })
778
+ ))
779
+ )
779
780
  );
780
781
  }
781
782
  Select.displayName = "Select";
@@ -784,7 +785,7 @@ function FileInput({
784
785
  value = [],
785
786
  onChange,
786
787
  onBlur,
787
- placeholder = "Choose file(s)...",
788
+ placeholder = "Choose file...",
788
789
  disabled = false,
789
790
  required = false,
790
791
  error = false,
@@ -887,7 +888,15 @@ function FileInput({
887
888
  inputRef.current.value = "";
888
889
  }
889
890
  },
890
- [value, onChange, validateFile, maxFiles, multiple, enableCropping, onValidationError]
891
+ [
892
+ value,
893
+ onChange,
894
+ validateFile,
895
+ maxFiles,
896
+ multiple,
897
+ enableCropping,
898
+ onValidationError
899
+ ]
891
900
  );
892
901
  const createCroppedImage = React7__namespace.useCallback(
893
902
  async (imageUrl, cropArea) => {
@@ -913,13 +922,17 @@ function FileInput({
913
922
  cropArea.width,
914
923
  cropArea.height
915
924
  );
916
- canvas.toBlob((blob) => {
917
- if (blob) {
918
- resolve(blob);
919
- } else {
920
- reject(new Error("Failed to create blob from canvas"));
921
- }
922
- }, "image/jpeg", 0.95);
925
+ canvas.toBlob(
926
+ (blob) => {
927
+ if (blob) {
928
+ resolve(blob);
929
+ } else {
930
+ reject(new Error("Failed to create blob from canvas"));
931
+ }
932
+ },
933
+ "image/jpeg",
934
+ 0.95
935
+ );
923
936
  };
924
937
  image.onerror = () => {
925
938
  reject(new Error("Failed to load image"));
@@ -939,11 +952,9 @@ function FileInput({
939
952
  if (onCropComplete) {
940
953
  onCropComplete(croppedBlob, imageToCrop.file);
941
954
  }
942
- const croppedFile = new File(
943
- [croppedBlob],
944
- imageToCrop.file.name,
945
- { type: "image/jpeg" }
946
- );
955
+ const croppedFile = new File([croppedBlob], imageToCrop.file.name, {
956
+ type: "image/jpeg"
957
+ });
947
958
  const updatedFiles = multiple ? [...value, croppedFile] : [croppedFile];
948
959
  onChange(updatedFiles);
949
960
  setCropperOpen(false);
@@ -955,7 +966,15 @@ function FileInput({
955
966
  } catch (error2) {
956
967
  console.error("Failed to crop image:", error2);
957
968
  }
958
- }, [imageToCrop, croppedAreaPixels, createCroppedImage, onCropComplete, value, onChange, multiple]);
969
+ }, [
970
+ imageToCrop,
971
+ croppedAreaPixels,
972
+ createCroppedImage,
973
+ onCropComplete,
974
+ value,
975
+ onChange,
976
+ multiple
977
+ ]);
959
978
  const handleCropCancel = React7__namespace.useCallback(() => {
960
979
  if (imageToCrop) {
961
980
  URL.revokeObjectURL(imageToCrop.url);
@@ -1067,7 +1086,7 @@ function FileInput({
1067
1086
  ), /* @__PURE__ */ React7__namespace.createElement(
1068
1087
  "div",
1069
1088
  {
1070
- 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" : ""}`,
1089
+ 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" : ""}`,
1071
1090
  onDragEnter: handleDrag,
1072
1091
  onDragLeave: handleDrag,
1073
1092
  onDragOver: handleDrag,
@@ -1082,7 +1101,6 @@ function FileInput({
1082
1101
  /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col items-center gap-2 text-center" }, /* @__PURE__ */ React7__namespace.createElement(
1083
1102
  "svg",
1084
1103
  {
1085
- className: "text-muted-foreground",
1086
1104
  width: "48",
1087
1105
  height: "48",
1088
1106
  viewBox: "0 0 24 24",
@@ -1096,92 +1114,102 @@ function FileInput({
1096
1114
  /* @__PURE__ */ React7__namespace.createElement("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
1097
1115
  /* @__PURE__ */ React7__namespace.createElement("polyline", { points: "17 8 12 3 7 8" }),
1098
1116
  /* @__PURE__ */ React7__namespace.createElement("line", { x1: "12", y1: "3", x2: "12", y2: "15" })
1099
- ), /* @__PURE__ */ React7__namespace.createElement("p", { className: "text-sm font-medium" }, value.length > 0 ? `${value.length} file(s) selected` : placeholder), accept && /* @__PURE__ */ React7__namespace.createElement("p", { className: "text-xs text-muted-foreground" }, "Accepted: ", accept), maxSize && /* @__PURE__ */ React7__namespace.createElement("p", { className: "text-xs text-muted-foreground" }, "Max size: ", formatFileSize(maxSize)))
1117
+ ), /* @__PURE__ */ React7__namespace.createElement("p", { className: "text-sm font-medium" }, value.length > 0 ? `${value.length} file(s) selected` : placeholder), accept && /* @__PURE__ */ React7__namespace.createElement("p", { className: "text-xs" }, "Accepted: ", accept), maxSize && /* @__PURE__ */ React7__namespace.createElement("p", { className: "text-xs " }, "Max size: ", formatFileSize(maxSize)))
1100
1118
  ), value.length > 0 && /* @__PURE__ */ React7__namespace.createElement("ul", { className: "flex flex-col gap-2 mt-4", role: "list" }, value.map((file, index) => {
1101
1119
  const previewUrl = showPreview ? getPreviewUrl(file) : null;
1102
- return /* @__PURE__ */ React7__namespace.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__namespace.createElement(
1103
- "img",
1104
- {
1105
- src: previewUrl,
1106
- alt: file.name,
1107
- className: "w-12 h-12 rounded object-cover",
1108
- width: "48",
1109
- height: "48"
1110
- }
1111
- ), /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col flex-1 min-w-0" }, /* @__PURE__ */ React7__namespace.createElement("span", { className: "text-sm font-medium truncate" }, file.name), /* @__PURE__ */ React7__namespace.createElement("span", { className: "text-xs text-muted-foreground" }, formatFileSize(file.size)), showProgress && uploadProgress[file.name] !== void 0 && /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex items-center gap-2 mt-1" }, /* @__PURE__ */ React7__namespace.createElement(
1112
- "div",
1120
+ return /* @__PURE__ */ React7__namespace.createElement(
1121
+ "li",
1113
1122
  {
1114
- className: "h-1.5 bg-muted rounded-full overflow-hidden flex-1",
1115
- role: "progressbar",
1116
- "aria-valuenow": uploadProgress[file.name],
1117
- "aria-valuemin": 0,
1118
- "aria-valuemax": 100,
1119
- "aria-label": `Upload progress: ${uploadProgress[file.name]}%`
1123
+ key: `${file.name}-${index}`,
1124
+ className: "flex items-center gap-3 p-3 rounded-md border border-border bg-card text-card-foreground hover:bg-primary/50 transition-colors"
1120
1125
  },
1121
- /* @__PURE__ */ React7__namespace.createElement(
1122
- "div",
1126
+ previewUrl && /* @__PURE__ */ React7__namespace.createElement(
1127
+ "img",
1123
1128
  {
1124
- className: "h-full bg-primary transition-all",
1125
- style: { width: `${uploadProgress[file.name]}%` }
1129
+ src: previewUrl,
1130
+ alt: file.name,
1131
+ className: "w-12 h-12 rounded object-cover",
1132
+ width: "48",
1133
+ height: "48"
1126
1134
  }
1127
- )
1128
- ), /* @__PURE__ */ React7__namespace.createElement("span", { className: "text-xs text-muted-foreground" }, uploadProgress[file.name], "%"))), enableCropping && file.type.startsWith("image/") && /* @__PURE__ */ React7__namespace.createElement(
1129
- "button",
1130
- {
1131
- type: "button",
1132
- onClick: (e) => {
1133
- e.stopPropagation();
1134
- handleCrop(file);
1135
- },
1136
- disabled,
1137
- 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",
1138
- "aria-label": `Crop ${file.name}`
1139
- },
1140
- /* @__PURE__ */ React7__namespace.createElement(
1141
- "svg",
1135
+ ),
1136
+ /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col flex-1 min-w-0" }, /* @__PURE__ */ React7__namespace.createElement("span", { className: "text-sm font-medium truncate" }, file.name), /* @__PURE__ */ React7__namespace.createElement("span", { className: "text-xs" }, formatFileSize(file.size)), showProgress && uploadProgress[file.name] !== void 0 && /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex items-center gap-2 mt-1" }, /* @__PURE__ */ React7__namespace.createElement(
1137
+ "div",
1142
1138
  {
1143
- width: "20",
1144
- height: "20",
1145
- viewBox: "0 0 24 24",
1146
- fill: "none",
1147
- stroke: "currentColor",
1148
- strokeWidth: "2",
1149
- strokeLinecap: "round",
1150
- strokeLinejoin: "round",
1151
- "aria-hidden": "true"
1139
+ className: "h-1.5 bg-muted rounded-full overflow-hidden flex-1",
1140
+ role: "progressbar",
1141
+ "aria-valuenow": uploadProgress[file.name],
1142
+ "aria-valuemin": 0,
1143
+ "aria-valuemax": 100,
1144
+ "aria-label": `Upload progress: ${uploadProgress[file.name]}%`
1152
1145
  },
1153
- /* @__PURE__ */ React7__namespace.createElement("path", { d: "M6.13 1L6 16a2 2 0 0 0 2 2h15" }),
1154
- /* @__PURE__ */ React7__namespace.createElement("path", { d: "M1 6.13L16 6a2 2 0 0 1 2 2v15" })
1155
- )
1156
- ), /* @__PURE__ */ React7__namespace.createElement(
1157
- "button",
1158
- {
1159
- type: "button",
1160
- onClick: (e) => {
1161
- e.stopPropagation();
1162
- handleRemove(index);
1146
+ /* @__PURE__ */ React7__namespace.createElement(
1147
+ "div",
1148
+ {
1149
+ className: "h-full bg-primary transition-all",
1150
+ style: { width: `${uploadProgress[file.name]}%` }
1151
+ }
1152
+ )
1153
+ ), /* @__PURE__ */ React7__namespace.createElement("span", { className: "text-xs " }, uploadProgress[file.name], "%"))),
1154
+ enableCropping && file.type.startsWith("image/") && /* @__PURE__ */ React7__namespace.createElement(
1155
+ "button",
1156
+ {
1157
+ type: "button",
1158
+ onClick: (e) => {
1159
+ e.stopPropagation();
1160
+ handleCrop(file);
1161
+ },
1162
+ disabled,
1163
+ className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-primary hover:text-primary-foreground transition-colors",
1164
+ "aria-label": `Crop ${file.name}`
1163
1165
  },
1164
- disabled,
1165
- 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",
1166
- "aria-label": `Remove ${file.name}`
1167
- },
1166
+ /* @__PURE__ */ React7__namespace.createElement(
1167
+ "svg",
1168
+ {
1169
+ width: "20",
1170
+ height: "20",
1171
+ viewBox: "0 0 24 24",
1172
+ fill: "none",
1173
+ stroke: "currentColor",
1174
+ strokeWidth: "2",
1175
+ strokeLinecap: "round",
1176
+ strokeLinejoin: "round",
1177
+ "aria-hidden": "true"
1178
+ },
1179
+ /* @__PURE__ */ React7__namespace.createElement("path", { d: "M6.13 1L6 16a2 2 0 0 0 2 2h15" }),
1180
+ /* @__PURE__ */ React7__namespace.createElement("path", { d: "M1 6.13L16 6a2 2 0 0 1 2 2v15" })
1181
+ )
1182
+ ),
1168
1183
  /* @__PURE__ */ React7__namespace.createElement(
1169
- "svg",
1184
+ "button",
1170
1185
  {
1171
- width: "20",
1172
- height: "20",
1173
- viewBox: "0 0 24 24",
1174
- fill: "none",
1175
- stroke: "currentColor",
1176
- strokeWidth: "2",
1177
- strokeLinecap: "round",
1178
- strokeLinejoin: "round",
1179
- "aria-hidden": "true"
1186
+ type: "button",
1187
+ onClick: (e) => {
1188
+ e.stopPropagation();
1189
+ handleRemove(index);
1190
+ },
1191
+ disabled,
1192
+ className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-primary hover:text-primary-foreground transition-colors",
1193
+ "aria-label": `Remove ${file.name}`
1180
1194
  },
1181
- /* @__PURE__ */ React7__namespace.createElement("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1182
- /* @__PURE__ */ React7__namespace.createElement("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1195
+ /* @__PURE__ */ React7__namespace.createElement(
1196
+ "svg",
1197
+ {
1198
+ width: "20",
1199
+ height: "20",
1200
+ viewBox: "0 0 24 24",
1201
+ fill: "none",
1202
+ stroke: "currentColor",
1203
+ strokeWidth: "2",
1204
+ strokeLinecap: "round",
1205
+ strokeLinejoin: "round",
1206
+ "aria-hidden": "true"
1207
+ },
1208
+ /* @__PURE__ */ React7__namespace.createElement("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1209
+ /* @__PURE__ */ React7__namespace.createElement("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1210
+ )
1183
1211
  )
1184
- ));
1212
+ );
1185
1213
  })), cropperOpen && imageToCrop && /* @__PURE__ */ React7__namespace.createElement("div", { className: "fixed inset-0 z-50 flex items-center justify-center" }, /* @__PURE__ */ React7__namespace.createElement(
1186
1214
  "div",
1187
1215
  {
@@ -1193,7 +1221,7 @@ function FileInput({
1193
1221
  "button",
1194
1222
  {
1195
1223
  type: "button",
1196
- className: "flex items-center justify-center h-8 w-8 rounded hover:bg-accent text-muted-foreground hover:text-foreground transition-colors",
1224
+ className: "flex items-center justify-center h-8 w-8 rounded hover:bg-primary hover:text-primary-foreground transition-colors",
1197
1225
  onClick: handleCropCancel,
1198
1226
  "aria-label": "Close"
1199
1227
  },
@@ -1234,7 +1262,10 @@ function FileInput({
1234
1262
  const img = e.currentTarget;
1235
1263
  const containerWidth = 600;
1236
1264
  const containerHeight = 400;
1237
- const cropWidth = cropAspectRatio ? Math.min(containerWidth * 0.8, containerHeight * 0.8 * cropAspectRatio) : containerWidth * 0.8;
1265
+ const cropWidth = cropAspectRatio ? Math.min(
1266
+ containerWidth * 0.8,
1267
+ containerHeight * 0.8 * cropAspectRatio
1268
+ ) : containerWidth * 0.8;
1238
1269
  const cropHeight = cropAspectRatio ? cropWidth / cropAspectRatio : containerHeight * 0.8;
1239
1270
  const scale = zoom;
1240
1271
  const imgWidth = img.naturalWidth;
@@ -1263,7 +1294,16 @@ function FileInput({
1263
1294
  },
1264
1295
  /* @__PURE__ */ React7__namespace.createElement("div", { className: "absolute inset-0 grid grid-cols-3 grid-rows-3" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React7__namespace.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React7__namespace.createElement("div", { className: "border-b border-primary/30" }), /* @__PURE__ */ React7__namespace.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React7__namespace.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React7__namespace.createElement("div", { className: "border-b border-primary/30" }), /* @__PURE__ */ React7__namespace.createElement("div", { className: "border-r border-primary/30" }), /* @__PURE__ */ React7__namespace.createElement("div", { className: "border-r border-primary/30" }), /* @__PURE__ */ React7__namespace.createElement("div", null))
1265
1296
  )
1266
- ), /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex items-center gap-3 mt-4" }, /* @__PURE__ */ React7__namespace.createElement("label", { htmlFor: "zoom-slider", className: "text-sm font-medium whitespace-nowrap" }, "Zoom: ", zoom.toFixed(1), "x"), /* @__PURE__ */ React7__namespace.createElement(
1297
+ ), /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex items-center gap-3 mt-4" }, /* @__PURE__ */ React7__namespace.createElement(
1298
+ "label",
1299
+ {
1300
+ htmlFor: "zoom-slider",
1301
+ className: "text-sm font-medium whitespace-nowrap"
1302
+ },
1303
+ "Zoom: ",
1304
+ zoom.toFixed(1),
1305
+ "x"
1306
+ ), /* @__PURE__ */ React7__namespace.createElement(
1267
1307
  "input",
1268
1308
  {
1269
1309
  id: "zoom-slider",
@@ -1280,7 +1320,7 @@ function FileInput({
1280
1320
  "button",
1281
1321
  {
1282
1322
  type: "button",
1283
- 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",
1323
+ 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",
1284
1324
  onClick: handleCropCancel
1285
1325
  },
1286
1326
  "Cancel"
@@ -1674,36 +1714,43 @@ function TimePicker({
1674
1714
  }
1675
1715
  return mins;
1676
1716
  }, [minuteStep]);
1677
- const combinedClassName = `relative ${className}`.trim();
1717
+ const combinedClassName = cn("relative", className);
1678
1718
  const displayValue = formatTimeValue(timeValue, use24Hour);
1679
- return /* @__PURE__ */ React7__namespace.createElement("div", { ref: containerRef, className: combinedClassName }, /* @__PURE__ */ React7__namespace.createElement(
1680
- "input",
1681
- {
1682
- type: "hidden",
1683
- name,
1684
- value
1685
- }
1686
- ), /* @__PURE__ */ React7__namespace.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React7__namespace.createElement("span", { className: "absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground pointer-events-none", "aria-hidden": "true" }, /* @__PURE__ */ React7__namespace.createElement(
1687
- "svg",
1719
+ return /* @__PURE__ */ React7__namespace.createElement("div", { ref: containerRef, className: combinedClassName }, /* @__PURE__ */ React7__namespace.createElement("input", { type: "hidden", name, value }), /* @__PURE__ */ React7__namespace.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React7__namespace.createElement(
1720
+ "span",
1688
1721
  {
1689
- xmlns: "http://www.w3.org/2000/svg",
1690
- width: "18",
1691
- height: "18",
1692
- viewBox: "0 0 24 24",
1693
- fill: "none",
1694
- stroke: "currentColor",
1695
- strokeLinecap: "round",
1696
- strokeLinejoin: "round",
1697
- strokeWidth: "2"
1722
+ className: "absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none",
1723
+ "aria-hidden": "true"
1698
1724
  },
1699
- /* @__PURE__ */ React7__namespace.createElement("circle", { cx: "12", cy: "12", r: "10" }),
1700
- /* @__PURE__ */ React7__namespace.createElement("path", { d: "M12 6v6l4 2" })
1701
- )), /* @__PURE__ */ React7__namespace.createElement(
1725
+ /* @__PURE__ */ React7__namespace.createElement(
1726
+ "svg",
1727
+ {
1728
+ xmlns: "http://www.w3.org/2000/svg",
1729
+ width: "18",
1730
+ height: "18",
1731
+ viewBox: "0 0 24 24",
1732
+ fill: "none",
1733
+ stroke: "currentColor",
1734
+ strokeLinecap: "round",
1735
+ strokeLinejoin: "round",
1736
+ strokeWidth: "2"
1737
+ },
1738
+ /* @__PURE__ */ React7__namespace.createElement("circle", { cx: "12", cy: "12", r: "10" }),
1739
+ /* @__PURE__ */ React7__namespace.createElement("path", { d: "M12 6v6l4 2" })
1740
+ )
1741
+ ), /* @__PURE__ */ React7__namespace.createElement(
1702
1742
  "input",
1703
1743
  {
1704
1744
  ref: inputRef,
1705
1745
  type: "text",
1706
- 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" : ""}`,
1746
+ className: cn(
1747
+ "flex h-9 w-full rounded-md border border-input bg-transparent py-1 text-base shadow-sm transition-colors",
1748
+ "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
1749
+ "disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
1750
+ showIcon ? "pl-10" : "pl-3",
1751
+ clearable && value ? "pr-10" : "pr-3",
1752
+ error && "border-red-500 ring-1 ring-red-500"
1753
+ ),
1707
1754
  value: displayValue,
1708
1755
  onClick: handleToggle,
1709
1756
  onBlur,
@@ -1719,13 +1766,13 @@ function TimePicker({
1719
1766
  "button",
1720
1767
  {
1721
1768
  type: "button",
1722
- className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors",
1769
+ className: "absolute right-3 top-1/2 -translate-y-1/2 transition-colors",
1723
1770
  onClick: handleClear,
1724
1771
  "aria-label": "Clear time",
1725
1772
  tabIndex: -1
1726
1773
  },
1727
1774
  "\u2715"
1728
- )), isOpen && !disabled && /* @__PURE__ */ React7__namespace.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__namespace.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col flex-1" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-xs font-medium text-muted-foreground mb-2 text-center" }, use24Hour ? "Hour" : "Hour"), /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col gap-1 max-h-48 overflow-y-auto" }, hours.map((hour) => {
1775
+ )), isOpen && !disabled && /* @__PURE__ */ React7__namespace.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__namespace.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col flex-1" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-xs font-medium mb-2 text-center" }, use24Hour ? "Hour" : "Hour"), /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col gap-1 max-h-48 overflow-y-auto" }, hours.map((hour) => {
1729
1776
  const displayHour = use24Hour ? hour : hour;
1730
1777
  const isSelected = use24Hour ? timeValue?.hour === (hour === 0 ? 12 : hour > 12 ? hour - 12 : hour) && timeValue?.period === (hour >= 12 ? "PM" : "AM") : timeValue?.hour === hour;
1731
1778
  return /* @__PURE__ */ React7__namespace.createElement(
@@ -1733,7 +1780,12 @@ function TimePicker({
1733
1780
  {
1734
1781
  key: hour,
1735
1782
  type: "button",
1736
- 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" : ""}`,
1783
+ className: cn(
1784
+ "flex items-center justify-center h-8 w-full rounded",
1785
+ "border-none bg-transparent cursor-pointer text-sm transition-colors",
1786
+ "hover:bg-primary hover:text-primary-foreground",
1787
+ isSelected ? "bg-primary text-primary-foreground font-semibold" : ""
1788
+ ),
1737
1789
  onClick: () => {
1738
1790
  if (use24Hour) {
1739
1791
  const hour12 = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour;
@@ -1753,24 +1805,34 @@ function TimePicker({
1753
1805
  },
1754
1806
  String(displayHour).padStart(2, "0")
1755
1807
  );
1756
- }))), /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col flex-1" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-xs font-medium text-muted-foreground mb-2 text-center" }, "Minute"), /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col gap-1 max-h-48 overflow-y-auto" }, minutes.map((minute) => {
1808
+ }))), /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col flex-1" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-xs font-medium mb-2 text-center" }, "Minute"), /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col gap-1 max-h-48 overflow-y-auto" }, minutes.map((minute) => {
1757
1809
  const isSelected = timeValue?.minute === minute;
1758
1810
  return /* @__PURE__ */ React7__namespace.createElement(
1759
1811
  "button",
1760
1812
  {
1761
1813
  key: minute,
1762
1814
  type: "button",
1763
- 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" : ""}`,
1815
+ className: cn(
1816
+ "flex items-center justify-center h-8 w-full",
1817
+ "rounded border-none bg-transparent cursor-pointer text-sm transition-colors",
1818
+ "hover:bg-primary hover:text-primary-foreground",
1819
+ isSelected ? "bg-primary text-primary-foreground font-semibold" : ""
1820
+ ),
1764
1821
  onClick: () => handleMinuteChange(minute),
1765
1822
  "aria-label": `${String(minute).padStart(2, "0")} minutes`
1766
1823
  },
1767
1824
  String(minute).padStart(2, "0")
1768
1825
  );
1769
- }))), !use24Hour && /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col w-20" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-xs font-medium text-muted-foreground mb-2 text-center" }, "Period"), /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React7__namespace.createElement(
1826
+ }))), !use24Hour && /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col w-20" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-xs font-medium mb-2 text-center" }, "Period"), /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React7__namespace.createElement(
1770
1827
  "button",
1771
1828
  {
1772
1829
  type: "button",
1773
- 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" : ""}`,
1830
+ className: cn(
1831
+ "flex items-center justify-center h-8 w-full",
1832
+ "rounded border-none bg-transparent cursor-pointer text-sm",
1833
+ "transition-colors hover:bg-primary hover:text-primary-foreground",
1834
+ timeValue?.period === "AM" ? "bg-muted font-semibold" : ""
1835
+ ),
1774
1836
  onClick: () => handlePeriodChange("AM")
1775
1837
  },
1776
1838
  "AM"
@@ -1778,7 +1840,12 @@ function TimePicker({
1778
1840
  "button",
1779
1841
  {
1780
1842
  type: "button",
1781
- 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" : ""}`,
1843
+ className: cn(
1844
+ "flex items-center justify-center h-8 w-full",
1845
+ "rounded border-none bg-transparent cursor-pointer text-sm",
1846
+ "transition-colors hover:bg-primary hover:text-primary-foreground",
1847
+ timeValue?.period === "PM" ? "bg-muted font-semibold" : ""
1848
+ ),
1782
1849
  onClick: () => handlePeriodChange("PM")
1783
1850
  },
1784
1851
  "PM"
@@ -1823,7 +1890,9 @@ function DateRangePicker({
1823
1890
  ...props
1824
1891
  }) {
1825
1892
  const [isOpen, setIsOpen] = React7__namespace.useState(false);
1826
- const [selectedMonth, setSelectedMonth] = React7__namespace.useState(value.start || /* @__PURE__ */ new Date());
1893
+ const [selectedMonth, setSelectedMonth] = React7__namespace.useState(
1894
+ value.start || /* @__PURE__ */ new Date()
1895
+ );
1827
1896
  const [rangeStart, setRangeStart] = React7__namespace.useState(value.start);
1828
1897
  const [rangeEnd, setRangeEnd] = React7__namespace.useState(value.end);
1829
1898
  const [hoverDate, setHoverDate] = React7__namespace.useState(null);
@@ -1921,7 +1990,7 @@ function DateRangePicker({
1921
1990
  "button",
1922
1991
  {
1923
1992
  type: "button",
1924
- className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-accent cursor-pointer",
1993
+ className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-primary hover:text-primary-foreground cursor-pointer",
1925
1994
  onClick: handlePrevMonth,
1926
1995
  "aria-label": "Previous month"
1927
1996
  },
@@ -1930,19 +1999,30 @@ function DateRangePicker({
1930
1999
  "button",
1931
2000
  {
1932
2001
  type: "button",
1933
- className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-accent cursor-pointer",
2002
+ className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-primary hover:text-primary-foreground cursor-pointer",
1934
2003
  onClick: handleNextMonth,
1935
2004
  "aria-label": "Next month"
1936
2005
  },
1937
2006
  "\u2192"
1938
- )), /* @__PURE__ */ React7__namespace.createElement("div", { className: "grid grid-cols-7 gap-1 mt-2" }, ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => /* @__PURE__ */ React7__namespace.createElement("div", { key: day, className: "flex items-center justify-center h-8 w-full text-xs text-muted-foreground font-medium" }, day))), /* @__PURE__ */ React7__namespace.createElement("div", { className: "grid grid-cols-7 gap-1" }, days.map((date, index) => {
2007
+ )), /* @__PURE__ */ React7__namespace.createElement("div", { className: "grid grid-cols-7 gap-1 mt-2" }, ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => /* @__PURE__ */ React7__namespace.createElement(
2008
+ "div",
2009
+ {
2010
+ key: day,
2011
+ className: "flex items-center justify-center h-8 w-full text-xs font-medium"
2012
+ },
2013
+ day
2014
+ ))), /* @__PURE__ */ React7__namespace.createElement("div", { className: "grid grid-cols-7 gap-1" }, days.map((date, index) => {
1939
2015
  if (!date) {
1940
2016
  return /* @__PURE__ */ React7__namespace.createElement("div", { key: `empty-${index}` });
1941
2017
  }
1942
2018
  const isStart = rangeStart && date.toDateString() === rangeStart.toDateString();
1943
2019
  const isEnd = rangeEnd && date.toDateString() === rangeEnd.toDateString();
2020
+ const isRangeEndpoint = Boolean(isStart || isEnd);
1944
2021
  const isInRange = rangeStart && rangeEnd && isDateInRange(date, rangeStart, rangeEnd);
1945
2022
  const isInHoverRange = rangeStart && !rangeEnd && hoverDate && (date >= rangeStart && date <= hoverDate || date <= rangeStart && date >= hoverDate);
2023
+ const isRangeHighlight = Boolean(
2024
+ (isInRange || isInHoverRange) && !isRangeEndpoint
2025
+ );
1946
2026
  const isToday = date.toDateString() === (/* @__PURE__ */ new Date()).toDateString();
1947
2027
  const disabled2 = isDisabled(date);
1948
2028
  return /* @__PURE__ */ React7__namespace.createElement(
@@ -1950,7 +2030,14 @@ function DateRangePicker({
1950
2030
  {
1951
2031
  key: date.toISOString(),
1952
2032
  type: "button",
1953
- 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" : ""}`,
2033
+ className: cn(
2034
+ "flex items-center justify-center h-8 w-full rounded border-none bg-transparent",
2035
+ "cursor-pointer text-sm transition-colors hover:bg-muted",
2036
+ isRangeEndpoint && "bg-muted font-semibold",
2037
+ isRangeHighlight && "bg-muted/70",
2038
+ isToday && "border border-primary",
2039
+ disabled2 && "cursor-not-allowed opacity-50 pointer-events-none"
2040
+ ),
1954
2041
  onClick: () => !disabled2 && handleDateSelect(date),
1955
2042
  onMouseEnter: () => setHoverDate(date),
1956
2043
  onMouseLeave: () => setHoverDate(null),
@@ -1961,7 +2048,7 @@ function DateRangePicker({
1961
2048
  );
1962
2049
  })));
1963
2050
  };
1964
- const combinedClassName = `relative ${className}`.trim();
2051
+ const combinedClassName = cn("relative", className);
1965
2052
  const displayValue = rangeStart && rangeEnd ? `${formatDate2(rangeStart, format)}${separator}${formatDate2(rangeEnd, format)}` : rangeStart ? formatDate2(rangeStart, format) : "";
1966
2053
  return /* @__PURE__ */ React7__namespace.createElement("div", { ref: containerRef, className: combinedClassName }, /* @__PURE__ */ React7__namespace.createElement(
1967
2054
  "input",
@@ -1977,25 +2064,39 @@ function DateRangePicker({
1977
2064
  name: `${name}[end]`,
1978
2065
  value: rangeEnd ? rangeEnd.toISOString() : ""
1979
2066
  }
1980
- ), /* @__PURE__ */ React7__namespace.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React7__namespace.createElement("span", { className: "absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground pointer-events-none", "aria-hidden": "true" }, /* @__PURE__ */ React7__namespace.createElement(
1981
- "svg",
2067
+ ), /* @__PURE__ */ React7__namespace.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React7__namespace.createElement(
2068
+ "span",
1982
2069
  {
1983
- xmlns: "http://www.w3.org/2000/svg",
1984
- width: "18",
1985
- height: "18",
1986
- viewBox: "0 0 24 24",
1987
- fill: "none",
1988
- stroke: "currentColor",
1989
- strokeLinecap: "round",
1990
- strokeLinejoin: "round",
1991
- strokeWidth: "2"
2070
+ className: "absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none",
2071
+ "aria-hidden": "true"
1992
2072
  },
1993
- /* @__PURE__ */ React7__namespace.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" })
1994
- )), /* @__PURE__ */ React7__namespace.createElement(
2073
+ /* @__PURE__ */ React7__namespace.createElement(
2074
+ "svg",
2075
+ {
2076
+ xmlns: "http://www.w3.org/2000/svg",
2077
+ width: "18",
2078
+ height: "18",
2079
+ viewBox: "0 0 24 24",
2080
+ fill: "none",
2081
+ stroke: "currentColor",
2082
+ strokeLinecap: "round",
2083
+ strokeLinejoin: "round",
2084
+ strokeWidth: "2"
2085
+ },
2086
+ /* @__PURE__ */ React7__namespace.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" })
2087
+ )
2088
+ ), /* @__PURE__ */ React7__namespace.createElement(
1995
2089
  "input",
1996
2090
  {
1997
2091
  type: "text",
1998
- 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" : ""}`,
2092
+ className: cn(
2093
+ "flex h-9 w-full rounded-md border border-input bg-transparent py-1 text-base shadow-sm transition-colors",
2094
+ "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
2095
+ "disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
2096
+ showIcon ? "pl-10" : "pl-3",
2097
+ clearable && (rangeStart || rangeEnd) ? "pr-10" : "pr-3",
2098
+ error && "border-red-500 ring-1 ring-red-500"
2099
+ ),
1999
2100
  value: displayValue,
2000
2101
  onClick: handleToggle,
2001
2102
  onBlur,
@@ -2011,13 +2112,13 @@ function DateRangePicker({
2011
2112
  "button",
2012
2113
  {
2013
2114
  type: "button",
2014
- className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors",
2115
+ className: "absolute right-3 top-1/2 -translate-y-1/2 transition-colors",
2015
2116
  onClick: handleClear,
2016
2117
  "aria-label": "Clear date range",
2017
2118
  tabIndex: -1
2018
2119
  },
2019
2120
  "\u2715"
2020
- )), isOpen && !disabled && /* @__PURE__ */ React7__namespace.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__namespace.createElement("div", { className: "text-xs text-muted-foreground text-center pt-2 border-t border-border mt-2" }, "Select end date")));
2121
+ )), isOpen && !disabled && /* @__PURE__ */ React7__namespace.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__namespace.createElement("div", { className: "text-xs text-center pt-2 border-t border-border mt-2" }, "Select end date")));
2021
2122
  }
2022
2123
  DateRangePicker.displayName = "DateRangePicker";
2023
2124
  function htmlToMarkdown(html) {
@@ -2073,11 +2174,19 @@ function RichTextEditor({
2073
2174
  className = "",
2074
2175
  mode = "wysiwyg",
2075
2176
  allowModeSwitch = false,
2076
- placeholder = "Start typing...",
2177
+ placeholder = "Your message...",
2077
2178
  minHeight = "200px",
2078
2179
  maxHeight,
2079
2180
  showToolbar = true,
2080
- toolbarButtons = ["bold", "italic", "underline", "heading", "bulletList", "orderedList", "link"],
2181
+ toolbarButtons = [
2182
+ "bold",
2183
+ "italic",
2184
+ "underline",
2185
+ "heading",
2186
+ "bulletList",
2187
+ "orderedList",
2188
+ "link"
2189
+ ],
2081
2190
  ...props
2082
2191
  }) {
2083
2192
  const [currentMode, setCurrentMode] = React7__namespace.useState(mode);
@@ -2186,7 +2295,7 @@ function RichTextEditor({
2186
2295
  {
2187
2296
  key: buttonName,
2188
2297
  type: "button",
2189
- 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",
2298
+ 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",
2190
2299
  onClick: () => editorRef.current && button.action(editorRef.current),
2191
2300
  title: button.title,
2192
2301
  disabled: disabled || currentMode === "markdown",
@@ -2198,7 +2307,7 @@ function RichTextEditor({
2198
2307
  "button",
2199
2308
  {
2200
2309
  type: "button",
2201
- 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",
2310
+ 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",
2202
2311
  onClick: handleModeToggle,
2203
2312
  disabled,
2204
2313
  title: `Switch to ${currentMode === "wysiwyg" ? "Markdown" : "WYSIWYG"}`,
@@ -2209,7 +2318,7 @@ function RichTextEditor({
2209
2318
  "div",
2210
2319
  {
2211
2320
  ref: editorRef,
2212
- 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",
2321
+ className: "w-full p-3 text-base md:text-sm outline-none bg-transparent focus-visible:outline-none [&:empty:before]:content-[attr(data-placeholder)]",
2213
2322
  role: "textbox",
2214
2323
  contentEditable: !disabled,
2215
2324
  onInput: handleWysiwygChange,
@@ -2224,7 +2333,7 @@ function RichTextEditor({
2224
2333
  "textarea",
2225
2334
  {
2226
2335
  ref: textareaRef,
2227
- 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",
2336
+ 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",
2228
2337
  value: content,
2229
2338
  onChange: handleMarkdownChange,
2230
2339
  onBlur,