@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/core.cjs +1 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/inputs.cjs +338 -229
- package/dist/inputs.cjs.map +1 -1
- package/dist/inputs.d.cts +1 -8
- package/dist/inputs.d.ts +1 -8
- package/dist/inputs.js +338 -229
- package/dist/inputs.js.map +1 -1
- package/package.json +1 -1
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
|
|
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
|
|
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
|
|
330
|
-
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
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
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
|
-
|
|
495
|
-
|
|
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" },
|
|
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-
|
|
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: "
|
|
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
|
|
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-
|
|
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(
|
|
722
|
-
"
|
|
713
|
+
isOpen && /* @__PURE__ */ React7__namespace.createElement(
|
|
714
|
+
"div",
|
|
723
715
|
{
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
(
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
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 =
|
|
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-
|
|
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
|
|
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
|
-
[
|
|
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(
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
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
|
-
|
|
944
|
-
|
|
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
|
-
}, [
|
|
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-
|
|
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
|
|
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(
|
|
1103
|
-
"
|
|
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
|
-
|
|
1115
|
-
|
|
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
|
-
"
|
|
1126
|
+
previewUrl && /* @__PURE__ */ React7__namespace.createElement(
|
|
1127
|
+
"img",
|
|
1123
1128
|
{
|
|
1124
|
-
|
|
1125
|
-
|
|
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
|
-
|
|
1129
|
-
|
|
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
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
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(
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
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
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
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
|
-
"
|
|
1184
|
+
"button",
|
|
1170
1185
|
{
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
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(
|
|
1182
|
-
|
|
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-
|
|
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(
|
|
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(
|
|
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-
|
|
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 =
|
|
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
|
-
"
|
|
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
|
-
|
|
1690
|
-
|
|
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(
|
|
1700
|
-
|
|
1701
|
-
|
|
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:
|
|
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
|
|
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
|
|
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:
|
|
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
|
|
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:
|
|
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
|
|
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:
|
|
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:
|
|
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(
|
|
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-
|
|
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-
|
|
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(
|
|
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:
|
|
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 =
|
|
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(
|
|
1981
|
-
"
|
|
2067
|
+
), /* @__PURE__ */ React7__namespace.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React7__namespace.createElement(
|
|
2068
|
+
"span",
|
|
1982
2069
|
{
|
|
1983
|
-
|
|
1984
|
-
|
|
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(
|
|
1994
|
-
|
|
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:
|
|
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
|
|
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-
|
|
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 = "
|
|
2177
|
+
placeholder = "Your message...",
|
|
2077
2178
|
minHeight = "200px",
|
|
2078
2179
|
maxHeight,
|
|
2079
2180
|
showToolbar = true,
|
|
2080
|
-
toolbarButtons = [
|
|
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-
|
|
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-
|
|
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)]
|
|
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
|
|
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,
|