@farmzone/fz-react-ui 1.0.19 → 1.0.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -2463,6 +2463,8 @@ function DatePickerRange(props) {
2463
2463
  endValue = "",
2464
2464
  onRangeChange,
2465
2465
  className = "",
2466
+ width,
2467
+ height,
2466
2468
  editDateSelect = true,
2467
2469
  onKeyDownEnter,
2468
2470
  datePosition = "bottom",
@@ -2573,7 +2575,7 @@ function DatePickerRange(props) {
2573
2575
  }
2574
2576
  };
2575
2577
  const inputClassName = cn(
2576
- "w-full px-2 py-1.25 border border-gray-300 shadow-xs outline-none text-sm rounded-sm pr-7 transition-colors",
2578
+ "w-full h-full px-2 py-1.25 border border-gray-300 shadow-xs outline-none text-sm rounded-sm pr-7 transition-colors",
2577
2579
  disabled ? DATE_PICKER_FIELD_DISABLED_CLASS : "bg-white text-gray-900 focus:border-blue-600"
2578
2580
  );
2579
2581
  const iconWrapperClassName = cn(
@@ -2616,72 +2618,84 @@ function DatePickerRange(props) {
2616
2618
  )
2617
2619
  }
2618
2620
  );
2619
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className: cn("relative w-64 h-8", className), "aria-disabled": disabled, children: [
2620
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-1", children: [
2621
- /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: startAnchorRef, className: "relative flex-1", children: [
2622
- /* @__PURE__ */ jsxRuntime.jsx(
2623
- "input",
2624
- {
2625
- type: "text",
2626
- value: startInputValue,
2627
- onChange: (e) => handleRangeInputChange(e, true),
2628
- placeholder: "\uC2DC\uC791 \uB0A0\uC9DC",
2629
- disabled,
2630
- className: inputClassName,
2631
- maxLength: 10,
2632
- onKeyDown: (e) => {
2633
- if (e.key === "Enter") {
2634
- e.preventDefault();
2635
- handleFieldEnter(startInputValue);
2621
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2622
+ "div",
2623
+ {
2624
+ ref: containerRef,
2625
+ className: cn("relative w-64 h-8", className),
2626
+ style: {
2627
+ width: typeof width === "number" ? `${width}px` : width,
2628
+ height: typeof height === "number" ? `${height}px` : height
2629
+ },
2630
+ "aria-disabled": disabled,
2631
+ children: [
2632
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-1 h-full", children: [
2633
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: startAnchorRef, className: "relative flex-1 h-full", children: [
2634
+ /* @__PURE__ */ jsxRuntime.jsx(
2635
+ "input",
2636
+ {
2637
+ type: "text",
2638
+ value: startInputValue,
2639
+ onChange: (e) => handleRangeInputChange(e, true),
2640
+ placeholder: "\uC2DC\uC791 \uB0A0\uC9DC",
2641
+ disabled,
2642
+ className: inputClassName,
2643
+ maxLength: 10,
2644
+ onKeyDown: (e) => {
2645
+ if (e.key === "Enter") {
2646
+ e.preventDefault();
2647
+ handleFieldEnter(startInputValue);
2648
+ }
2649
+ }
2636
2650
  }
2637
- }
2638
- }
2639
- ),
2640
- /* @__PURE__ */ jsxRuntime.jsx(
2641
- "div",
2642
- {
2643
- onClick: () => {
2644
- if (!disabled) handleCalendarIconClick("start");
2645
- },
2646
- className: iconWrapperClassName,
2647
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Calendar, { size: 15, className: iconClassName })
2648
- }
2649
- )
2650
- ] }),
2651
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("text-sm w-2 text-center", disabled && "text-neutral-400 opacity-50"), children: "~" }),
2652
- /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: endAnchorRef, className: "relative flex-1", children: [
2653
- /* @__PURE__ */ jsxRuntime.jsx(
2654
- "input",
2655
- {
2656
- type: "text",
2657
- value: endInputValue,
2658
- onChange: (e) => handleRangeInputChange(e, false),
2659
- placeholder: "\uC885\uB8CC \uB0A0\uC9DC",
2660
- disabled,
2661
- className: inputClassName,
2662
- maxLength: 10,
2663
- onKeyDown: (e) => {
2664
- if (e.key === "Enter") {
2665
- e.preventDefault();
2666
- handleFieldEnter(endInputValue);
2651
+ ),
2652
+ /* @__PURE__ */ jsxRuntime.jsx(
2653
+ "div",
2654
+ {
2655
+ onClick: () => {
2656
+ if (!disabled) handleCalendarIconClick("start");
2657
+ },
2658
+ className: iconWrapperClassName,
2659
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Calendar, { size: 15, className: iconClassName })
2667
2660
  }
2668
- }
2669
- }
2670
- ),
2671
- /* @__PURE__ */ jsxRuntime.jsx(
2672
- "div",
2673
- {
2674
- onClick: () => {
2675
- if (!disabled) handleCalendarIconClick("end");
2676
- },
2677
- className: iconWrapperClassName,
2678
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Calendar, { size: 15, className: iconClassName })
2679
- }
2680
- )
2681
- ] })
2682
- ] }),
2683
- calendarNode
2684
- ] });
2661
+ )
2662
+ ] }),
2663
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("text-sm w-2 text-center", disabled && "text-neutral-400 opacity-50"), children: "~" }),
2664
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: endAnchorRef, className: "relative flex-1 h-full", children: [
2665
+ /* @__PURE__ */ jsxRuntime.jsx(
2666
+ "input",
2667
+ {
2668
+ type: "text",
2669
+ value: endInputValue,
2670
+ onChange: (e) => handleRangeInputChange(e, false),
2671
+ placeholder: "\uC885\uB8CC \uB0A0\uC9DC",
2672
+ disabled,
2673
+ className: inputClassName,
2674
+ maxLength: 10,
2675
+ onKeyDown: (e) => {
2676
+ if (e.key === "Enter") {
2677
+ e.preventDefault();
2678
+ handleFieldEnter(endInputValue);
2679
+ }
2680
+ }
2681
+ }
2682
+ ),
2683
+ /* @__PURE__ */ jsxRuntime.jsx(
2684
+ "div",
2685
+ {
2686
+ onClick: () => {
2687
+ if (!disabled) handleCalendarIconClick("end");
2688
+ },
2689
+ className: iconWrapperClassName,
2690
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Calendar, { size: 15, className: iconClassName })
2691
+ }
2692
+ )
2693
+ ] })
2694
+ ] }),
2695
+ calendarNode
2696
+ ]
2697
+ }
2698
+ );
2685
2699
  }
2686
2700
  function DatePickerSingle(props) {
2687
2701
  const {
@@ -2689,6 +2703,8 @@ function DatePickerSingle(props) {
2689
2703
  onChange,
2690
2704
  placeholder = "\uB0A0\uC9DC \uC120\uD0DD",
2691
2705
  className = "",
2706
+ width,
2707
+ height,
2692
2708
  editDateSelect = true,
2693
2709
  onKeyDownEnter,
2694
2710
  datePosition = "bottom",
@@ -2799,56 +2815,70 @@ function DatePickerSingle(props) {
2799
2815
  )
2800
2816
  }
2801
2817
  );
2802
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className: cn("relative w-30 h-8", className), "aria-disabled": disabled, children: [
2803
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
2804
- /* @__PURE__ */ jsxRuntime.jsx(
2805
- "input",
2806
- {
2807
- type: "text",
2808
- value: inputValue,
2809
- onChange: handleInputChange,
2810
- onBlur: () => onBlur && handleInputBlur(),
2811
- placeholder,
2812
- disabled,
2813
- className: cn(
2814
- "w-full px-2 py-1.25 border text-sm rounded-sm outline-none shadow-xs transition-colors",
2815
- validation ? "border-red-600 focus:border-blue-600 focus-visible:border-blue-600 focus-visible:ring-1 focus-visible:ring-blue-600/30 focus-visible:outline-none" : "border-gray-300 focus:border-blue-600 focus-visible:border-blue-600 focus-visible:ring-1 focus-visible:ring-blue-600/30 focus-visible:outline-none",
2816
- disabled ? DATE_PICKER_FIELD_DISABLED_CLASS : "bg-white text-gray-900"
2817
- ),
2818
- maxLength: 10,
2819
- onKeyDown: (e) => {
2820
- if (e.key === "Enter") {
2821
- e.preventDefault();
2822
- handleFieldEnter(inputValue);
2818
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2819
+ "div",
2820
+ {
2821
+ ref: containerRef,
2822
+ className: cn("relative w-30 h-8", className),
2823
+ style: {
2824
+ width: typeof width === "number" ? `${width}px` : width,
2825
+ height: typeof height === "number" ? `${height}px` : height
2826
+ },
2827
+ "aria-disabled": disabled,
2828
+ children: [
2829
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative h-full", children: [
2830
+ /* @__PURE__ */ jsxRuntime.jsx(
2831
+ "input",
2832
+ {
2833
+ type: "text",
2834
+ value: inputValue,
2835
+ onChange: handleInputChange,
2836
+ onBlur: () => onBlur && handleInputBlur(),
2837
+ placeholder,
2838
+ disabled,
2839
+ className: cn(
2840
+ "w-full h-full px-2 py-1.25 border text-sm rounded-sm outline-none shadow-xs transition-colors",
2841
+ validation ? "border-red-600 focus:border-blue-600 focus-visible:border-blue-600 focus-visible:ring-1 focus-visible:ring-blue-600/30 focus-visible:outline-none" : "border-gray-300 focus:border-blue-600 focus-visible:border-blue-600 focus-visible:ring-1 focus-visible:ring-blue-600/30 focus-visible:outline-none",
2842
+ disabled ? DATE_PICKER_FIELD_DISABLED_CLASS : "bg-white text-gray-900"
2843
+ ),
2844
+ maxLength: 10,
2845
+ onKeyDown: (e) => {
2846
+ if (e.key === "Enter") {
2847
+ e.preventDefault();
2848
+ handleFieldEnter(inputValue);
2849
+ }
2850
+ },
2851
+ "data-date-input": "true"
2823
2852
  }
2824
- },
2825
- "data-date-input": "true"
2826
- }
2827
- ),
2828
- /* @__PURE__ */ jsxRuntime.jsx(
2829
- "div",
2830
- {
2831
- role: "button",
2832
- tabIndex: -1,
2833
- "aria-hidden": disabled,
2834
- onClick: () => {
2835
- if (!disabled) toggleCalendar(inputValue);
2836
- },
2837
- className: cn(
2838
- "absolute right-1 top-1/2 -translate-y-1/2 rounded-full p-1",
2839
- disabled ? DATE_PICKER_ICON_DISABLED_CLASS : DATE_PICKER_ICON_ENABLED_CLASS
2840
2853
  ),
2841
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Calendar, { size: 15, className: cn(disabled ? "text-neutral-400 opacity-50" : "text-gray-600") })
2842
- }
2843
- )
2844
- ] }),
2845
- calendarNode
2846
- ] });
2854
+ /* @__PURE__ */ jsxRuntime.jsx(
2855
+ "div",
2856
+ {
2857
+ role: "button",
2858
+ tabIndex: -1,
2859
+ "aria-hidden": disabled,
2860
+ onClick: () => {
2861
+ if (!disabled) toggleCalendar(inputValue);
2862
+ },
2863
+ className: cn(
2864
+ "absolute right-1 top-1/2 -translate-y-1/2 rounded-full p-1",
2865
+ disabled ? DATE_PICKER_ICON_DISABLED_CLASS : DATE_PICKER_ICON_ENABLED_CLASS
2866
+ ),
2867
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Calendar, { size: 15, className: cn(disabled ? "text-neutral-400 opacity-50" : "text-gray-600") })
2868
+ }
2869
+ )
2870
+ ] }),
2871
+ calendarNode
2872
+ ]
2873
+ }
2874
+ );
2847
2875
  }
2848
2876
  function DatePicker(props) {
2849
2877
  const {
2850
2878
  isRange,
2851
2879
  className,
2880
+ width,
2881
+ height,
2852
2882
  editDateSelect,
2853
2883
  onKeyDownEnter,
2854
2884
  datePosition,
@@ -2867,6 +2897,8 @@ function DatePicker(props) {
2867
2897
  endValue,
2868
2898
  onRangeChange,
2869
2899
  className,
2900
+ width,
2901
+ height,
2870
2902
  editDateSelect,
2871
2903
  onKeyDownEnter,
2872
2904
  datePosition,
@@ -2886,6 +2918,8 @@ function DatePicker(props) {
2886
2918
  onChange,
2887
2919
  placeholder,
2888
2920
  className,
2921
+ width,
2922
+ height,
2889
2923
  editDateSelect,
2890
2924
  onKeyDownEnter,
2891
2925
  datePosition,
@@ -8623,7 +8657,9 @@ function BaseUploader(props) {
8623
8657
  maxSize,
8624
8658
  disabled = false,
8625
8659
  placeholder,
8626
- className
8660
+ className,
8661
+ width,
8662
+ height
8627
8663
  } = props;
8628
8664
  const inputRef = React6.useRef(null);
8629
8665
  const inputId = React6.useId();
@@ -8666,7 +8702,7 @@ function BaseUploader(props) {
8666
8702
  };
8667
8703
  const showZone = multiple || files.length === 0;
8668
8704
  const acceptLabel = accept ? accept.split(",").map((s) => s.trim().toUpperCase()).join(", ") : "\uBAA8\uB4E0 \uD615\uC2DD";
8669
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-3", className), children: [
8705
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-3", className), style: { width: typeof width === "number" ? `${width}px` : width }, children: [
8670
8706
  /* @__PURE__ */ jsxRuntime.jsx(
8671
8707
  "input",
8672
8708
  {
@@ -8700,6 +8736,7 @@ function BaseUploader(props) {
8700
8736
  setIsDragging(false);
8701
8737
  },
8702
8738
  onDrop: handleDrop,
8739
+ style: { minHeight: typeof height === "number" ? `${height}px` : height ?? "7rem" },
8703
8740
  className: cn(
8704
8741
  "flex flex-col items-center justify-center gap-2 min-h-28 w-full rounded-lg bg-gray-50/50 border-[1.5px] border-dashed",
8705
8742
  disabled ? "cursor-not-allowed border-gray-200 bg-gray-100 opacity-60" : "cursor-pointer hover:bg-gray-50",
@@ -8745,7 +8782,7 @@ function BaseUploader(props) {
8745
8782
  var EXCEL_ACCEPT = ".xlsx,.xls,.csv";
8746
8783
  var MAX_EXCEL_BYTES = 10 * 1024 * 1024;
8747
8784
  function ExcelUploader(props) {
8748
- const { files, onChange, disabled, className } = props;
8785
+ const { files, onChange, disabled, className, width, height } = props;
8749
8786
  return /* @__PURE__ */ jsxRuntime.jsx(
8750
8787
  BaseUploader,
8751
8788
  {
@@ -8756,7 +8793,9 @@ function ExcelUploader(props) {
8756
8793
  maxSize: MAX_EXCEL_BYTES,
8757
8794
  disabled,
8758
8795
  placeholder: "\uC5D1\uC140 \uD30C\uC77C\uC744 \uD074\uB9AD\uD558\uAC70\uB098 \uB4DC\uB798\uADF8\uD558\uC138\uC694",
8759
- className
8796
+ className,
8797
+ width,
8798
+ height
8760
8799
  }
8761
8800
  );
8762
8801
  }
@@ -8853,7 +8892,7 @@ var compressImage = (file) => {
8853
8892
  }).catch(() => file);
8854
8893
  };
8855
8894
  function FileUploader(props) {
8856
- const { files, onChange, multiple = true, disabled = false, className } = props;
8895
+ const { files, onChange, multiple = true, disabled = false, className, width, height } = props;
8857
8896
  const inputRef = React6.useRef(null);
8858
8897
  const containerRef = React6.useRef(null);
8859
8898
  const [isDragging, setIsDragging] = React6.useState(false);
@@ -8960,121 +8999,129 @@ function FileUploader(props) {
8960
8999
  setError("");
8961
9000
  };
8962
9001
  const isProcessing = processingCount > 0;
8963
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-3", className), children: [
8964
- /* @__PURE__ */ jsxRuntime.jsx(
8965
- "input",
8966
- {
8967
- ref: inputRef,
8968
- type: "file",
8969
- multiple,
8970
- accept: "image/jpeg,image/png,image/webp,image/heic,image/heif,application/pdf,.heic,.heif",
8971
- disabled,
8972
- className: "hidden",
8973
- onChange: (e) => {
8974
- handleFiles(e.target.files);
8975
- if (inputRef.current) inputRef.current.value = "";
8976
- }
8977
- }
8978
- ),
8979
- /* @__PURE__ */ jsxRuntime.jsxs(
8980
- "div",
8981
- {
8982
- ref: containerRef,
8983
- onClick: isProcessing || disabled ? void 0 : () => inputRef.current?.click(),
8984
- onDragOver: handleDragOver,
8985
- onDragEnter: handleDragOver,
8986
- onDragLeave: handleDragLeave,
8987
- onDrop: handleDrop,
8988
- className: cn(
8989
- "relative w-full rounded-lg bg-gray-50/50 border-[1.5px] border-dashed",
8990
- disabled ? "cursor-not-allowed border-gray-200 bg-gray-100 opacity-60" : isProcessing ? "cursor-default border-gray-300" : "cursor-pointer hover:bg-gray-50",
8991
- isDragging ? "border-blue-500 bg-blue-50" : "border-gray-300",
8992
- error && !isDragging ? "border-red-300 bg-red-50" : "",
8993
- files.length > 0 ? "p-3" : "flex flex-col items-center justify-center gap-1 min-h-32"
9002
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9003
+ "div",
9004
+ {
9005
+ className: cn("space-y-3", className),
9006
+ style: { width: typeof width === "number" ? `${width}px` : width },
9007
+ children: [
9008
+ /* @__PURE__ */ jsxRuntime.jsx(
9009
+ "input",
9010
+ {
9011
+ ref: inputRef,
9012
+ type: "file",
9013
+ multiple,
9014
+ accept: "image/jpeg,image/png,image/webp,image/heic,image/heif,application/pdf,.heic,.heif",
9015
+ disabled,
9016
+ className: "hidden",
9017
+ onChange: (e) => {
9018
+ handleFiles(e.target.files);
9019
+ if (inputRef.current) inputRef.current.value = "";
9020
+ }
9021
+ }
8994
9022
  ),
8995
- children: [
8996
- isProcessing && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-0 z-10 flex flex-col items-center justify-center gap-2 rounded-lg bg-white/80", children: [
8997
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-8 w-8 animate-spin rounded-full border-4 border-blue-400 border-t-transparent" }),
8998
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-600", children: "\uCC98\uB9AC \uC911..." })
8999
- ] }),
9000
- files.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9001
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-3", children: files.map((file, idx) => {
9002
- const url = previewUrls[idx];
9003
- const isImage = file.type.startsWith("image/");
9004
- return /* @__PURE__ */ jsxRuntime.jsxs(
9005
- "div",
9006
- {
9007
- className: "group relative overflow-hidden rounded-lg border border-gray-200 bg-white shadow-sm transition-shadow hover:shadow-md",
9008
- children: [
9009
- /* @__PURE__ */ jsxRuntime.jsx(
9010
- "button",
9011
- {
9012
- type: "button",
9013
- onClick: (e) => {
9014
- e.stopPropagation();
9015
- viewer.open(idx);
9016
- },
9017
- className: "block w-full aspect-square cursor-pointer",
9018
- "aria-label": `${file.name} \uBBF8\uB9AC\uBCF4\uAE30`,
9019
- children: isImage && url ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: url, alt: file.name, className: "h-full w-full object-cover" }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full w-full flex-col items-center justify-center bg-gray-50 text-gray-400", children: [
9020
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "w-8 h-8" }),
9021
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-1 max-w-full truncate px-1 text-center text-[10px]", children: file.name })
9022
- ] })
9023
- }
9024
- ),
9025
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-1 border-t border-gray-100 px-1.5 py-1", children: [
9026
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate text-[10px] text-gray-600", title: file.name, children: file.name }),
9027
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 text-[10px] text-gray-400", children: formatFileSize(file.size) })
9028
- ] }),
9029
- !disabled && /* @__PURE__ */ jsxRuntime.jsx(
9030
- "button",
9031
- {
9032
- type: "button",
9033
- onClick: (e) => {
9034
- e.stopPropagation();
9035
- removeFile(idx);
9036
- },
9037
- className: "absolute right-1 top-1 flex h-5 w-5 items-center justify-center rounded-full bg-black/60 text-white opacity-0 transition-opacity group-hover:opacity-100 cursor-pointer",
9038
- "aria-label": "\uD30C\uC77C \uC81C\uAC70",
9039
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-3 h-3" })
9040
- }
9041
- )
9042
- ]
9043
- },
9044
- `${file.name}-${idx}`
9045
- );
9046
- }) }),
9047
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 flex items-center justify-between text-xs text-gray-500", children: [
9048
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
9049
- files.length,
9050
- "\uAC1C \uD30C\uC77C \uC120\uD0DD\uB428",
9051
- !disabled && " \xB7 \uD074\uB9AD\uD558\uC5EC \uCD94\uAC00"
9023
+ /* @__PURE__ */ jsxRuntime.jsxs(
9024
+ "div",
9025
+ {
9026
+ ref: containerRef,
9027
+ onClick: isProcessing || disabled ? void 0 : () => inputRef.current?.click(),
9028
+ onDragOver: handleDragOver,
9029
+ onDragEnter: handleDragOver,
9030
+ onDragLeave: handleDragLeave,
9031
+ onDrop: handleDrop,
9032
+ className: cn(
9033
+ "relative w-full rounded-lg bg-gray-50/50 border-[1.5px] border-dashed",
9034
+ disabled ? "cursor-not-allowed border-gray-200 bg-gray-100 opacity-60" : isProcessing ? "cursor-default border-gray-300" : "cursor-pointer hover:bg-gray-50",
9035
+ isDragging ? "border-blue-500 bg-blue-50" : "border-gray-300",
9036
+ error && !isDragging ? "border-red-300 bg-red-50" : "",
9037
+ files.length > 0 ? "p-3" : "flex flex-col items-center justify-center gap-1"
9038
+ ),
9039
+ style: files.length === 0 ? { minHeight: typeof height === "number" ? `${height}px` : height ?? "8rem" } : void 0,
9040
+ children: [
9041
+ isProcessing && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-0 z-10 flex flex-col items-center justify-center gap-2 rounded-lg bg-white/80", children: [
9042
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-8 w-8 animate-spin rounded-full border-4 border-blue-400 border-t-transparent" }),
9043
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-600", children: "\uCC98\uB9AC \uC911..." })
9052
9044
  ] }),
9053
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
9054
- "\uCD1D ",
9055
- formatFileSize(files.reduce((sum, f) => sum + f.size, 0))
9045
+ files.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9046
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-3", children: files.map((file, idx) => {
9047
+ const url = previewUrls[idx];
9048
+ const isImage = file.type.startsWith("image/");
9049
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9050
+ "div",
9051
+ {
9052
+ className: "group relative overflow-hidden rounded-lg border border-gray-200 bg-white shadow-sm transition-shadow hover:shadow-md",
9053
+ children: [
9054
+ /* @__PURE__ */ jsxRuntime.jsx(
9055
+ "button",
9056
+ {
9057
+ type: "button",
9058
+ onClick: (e) => {
9059
+ e.stopPropagation();
9060
+ viewer.open(idx);
9061
+ },
9062
+ className: "block w-full aspect-square cursor-pointer",
9063
+ "aria-label": `${file.name} \uBBF8\uB9AC\uBCF4\uAE30`,
9064
+ children: isImage && url ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: url, alt: file.name, className: "h-full w-full object-cover" }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full w-full flex-col items-center justify-center bg-gray-50 text-gray-400", children: [
9065
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "w-8 h-8" }),
9066
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-1 max-w-full truncate px-1 text-center text-[10px]", children: file.name })
9067
+ ] })
9068
+ }
9069
+ ),
9070
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-1 border-t border-gray-100 px-1.5 py-1", children: [
9071
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate text-[10px] text-gray-600", title: file.name, children: file.name }),
9072
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 text-[10px] text-gray-400", children: formatFileSize(file.size) })
9073
+ ] }),
9074
+ !disabled && /* @__PURE__ */ jsxRuntime.jsx(
9075
+ "button",
9076
+ {
9077
+ type: "button",
9078
+ onClick: (e) => {
9079
+ e.stopPropagation();
9080
+ removeFile(idx);
9081
+ },
9082
+ className: "absolute right-1 top-1 flex h-5 w-5 items-center justify-center rounded-full bg-black/60 text-white opacity-0 transition-opacity group-hover:opacity-100 cursor-pointer",
9083
+ "aria-label": "\uD30C\uC77C \uC81C\uAC70",
9084
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-3 h-3" })
9085
+ }
9086
+ )
9087
+ ]
9088
+ },
9089
+ `${file.name}-${idx}`
9090
+ );
9091
+ }) }),
9092
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 flex items-center justify-between text-xs text-gray-500", children: [
9093
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
9094
+ files.length,
9095
+ "\uAC1C \uD30C\uC77C \uC120\uD0DD\uB428",
9096
+ !disabled && " \xB7 \uD074\uB9AD\uD558\uC5EC \uCD94\uAC00"
9097
+ ] }),
9098
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
9099
+ "\uCD1D ",
9100
+ formatFileSize(files.reduce((sum, f) => sum + f.size, 0))
9101
+ ] })
9102
+ ] })
9103
+ ] }) : isDragging ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center gap-1 text-blue-500", children: [
9104
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm font-semibold flex gap-1", children: [
9105
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileUp, { size: 15, className: "mt-[1px]" }),
9106
+ "\uD30C\uC77C\uC744 \uC5EC\uAE30\uC5D0 \uB193\uC544\uC8FC\uC138\uC694"
9107
+ ] }),
9108
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium", children: "\uB4DC\uB86D\uD558\uBA74 \uC790\uB3D9\uC73C\uB85C \uC5C5\uB85C\uB4DC\uB429\uB2C8\uB2E4." })
9109
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9110
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-gray-600 flex gap-1", children: [
9111
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileUp, { size: 15, className: "text-gray-400 mt-[1px]" }),
9112
+ " \uD074\uB9AD\uD558\uC5EC \uD30C\uC77C\uC744 \uC120\uD0DD\uD558\uAC70\uB098 \uB4DC\uB798\uADF8\uD558\uC138\uC694"
9113
+ ] }),
9114
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-400", children: "\uC774\uBBF8\uC9C0(JPG \xB7 PNG \xB7 WEBP \xB7 HEIC, \uCD5C\uB300 50MB) \xB7 PDF(\uCD5C\uB300 10MB)" }),
9115
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-400", children: multiple ? `\uCD5C\uB300 ${MAX_FILES}\uAC1C \xB7 \uC804\uCCB4 20MB \uC774\uD558` : "\uB2E8\uC77C \uD30C\uC77C" })
9056
9116
  ] })
9057
- ] })
9058
- ] }) : isDragging ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center gap-1 text-blue-500", children: [
9059
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm font-semibold flex gap-1", children: [
9060
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileUp, { size: 15, className: "mt-[1px]" }),
9061
- "\uD30C\uC77C\uC744 \uC5EC\uAE30\uC5D0 \uB193\uC544\uC8FC\uC138\uC694"
9062
- ] }),
9063
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium", children: "\uB4DC\uB86D\uD558\uBA74 \uC790\uB3D9\uC73C\uB85C \uC5C5\uB85C\uB4DC\uB429\uB2C8\uB2E4." })
9064
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9065
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-gray-600 flex gap-1", children: [
9066
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileUp, { size: 15, className: "text-gray-400 mt-[1px]" }),
9067
- " \uD074\uB9AD\uD558\uC5EC \uD30C\uC77C\uC744 \uC120\uD0DD\uD558\uAC70\uB098 \uB4DC\uB798\uADF8\uD558\uC138\uC694"
9068
- ] }),
9069
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-400", children: "\uC774\uBBF8\uC9C0(JPG \xB7 PNG \xB7 WEBP \xB7 HEIC, \uCD5C\uB300 50MB) \xB7 PDF(\uCD5C\uB300 10MB)" }),
9070
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-400", children: multiple ? `\uCD5C\uB300 ${MAX_FILES}\uAC1C \xB7 \uC804\uCCB4 20MB \uC774\uD558` : "\uB2E8\uC77C \uD30C\uC77C" })
9071
- ] })
9072
- ]
9073
- }
9074
- ),
9075
- error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "whitespace-pre-line text-xs text-red-500 bg-red-50 border border-red-200 rounded px-3 py-2", children: error }),
9076
- /* @__PURE__ */ jsxRuntime.jsx(FilePreviewViewer, { ...viewer.viewerProps, fileTypes, fileNames: files.map((f) => f.name) })
9077
- ] });
9117
+ ]
9118
+ }
9119
+ ),
9120
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "whitespace-pre-line text-xs text-red-500 bg-red-50 border border-red-200 rounded px-3 py-2", children: error }),
9121
+ /* @__PURE__ */ jsxRuntime.jsx(FilePreviewViewer, { ...viewer.viewerProps, fileTypes, fileNames: files.map((f) => f.name) })
9122
+ ]
9123
+ }
9124
+ );
9078
9125
  }
9079
9126
  var VARIANT_STYLES2 = {
9080
9127
  light: {