@farmzone/fz-react-ui 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -44,9 +44,10 @@ var buttonVariants = cva(
44
44
  delete: "bg-white border border-sub-red text-main-red hover:bg-red-50 disabled:bg-light-gray disabled:border-sub-lightgray-2 disabled:text-sub-lightgray-2 font-bold min-w-22",
45
45
  reset: "bg-white border border-sub-lightgray-2 text-sub-darkgray hover:bg-gray-100 hover:text-black",
46
46
  search: "bg-main-blue border-none text-white hover:bg-main-blue/90",
47
- file: "bg-sub-darkgray text-white hover:bg-sub-darkgray/80",
47
+ file: "bg-btn-file text-white hover:bg-btn-file/90",
48
48
  carousel: "bg-white border border-gray-300 hover:bg-gray-100 hover:text-black rounded-full",
49
49
  accent: "btn-grad text-white rounded-full",
50
+ metal: "btn-metal text-white min-w-22",
50
51
  ghost: "p-1 h-auto rounded-sm bg-transparent hover:bg-sub-lightgray text-sub-darkgray hover:bg-inherit",
51
52
  link: "bg-transparent border-none text-main-blue underline-offset-4 hover:underline h-auto p-0"
52
53
  },
@@ -3362,8 +3363,7 @@ function ModalContent(props) {
3362
3363
  {
3363
3364
  ref,
3364
3365
  className: cn(
3365
- "fixed left-[50%] top-[50%] max-h-[85vh] z-55 flex flex-col w-full max-w-lg translate-x-[-50%] translate-y-[-50%] bg-white rounded-lg overflow-hidden shadow-xl duration-200",
3366
- "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]",
3366
+ "fixed left-[50%] top-[50%] max-h-[85vh] z-55 flex flex-col w-full max-w-lg translate-x-[-50%] translate-y-[-50%] bg-white rounded-lg overflow-hidden shadow-xl",
3367
3367
  className
3368
3368
  ),
3369
3369
  style: zIndex !== void 0 ? { zIndex } : void 0,
@@ -3374,7 +3374,7 @@ function ModalContent(props) {
3374
3374
  );
3375
3375
  }
3376
3376
  function ModalOverlay(props) {
3377
- const { isOpen: isOpen2, onClose, className, closeOnOverlayClick = true, zIndex } = props;
3377
+ const { ref, isOpen: isOpen2, onClose, className, closeOnOverlayClick = true, zIndex } = props;
3378
3378
  if (!isOpen2) return null;
3379
3379
  const handleOverlayClick = (e) => {
3380
3380
  if (closeOnOverlayClick && e.target === e.currentTarget) {
@@ -3384,9 +3384,10 @@ function ModalOverlay(props) {
3384
3384
  return /* @__PURE__ */ jsx(
3385
3385
  "div",
3386
3386
  {
3387
+ ref,
3387
3388
  className: cn(
3388
3389
  "fixed inset-0 z-54 bg-black/50",
3389
- "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
3390
+ "animate-in fade-in-0 duration-150",
3390
3391
  className
3391
3392
  ),
3392
3393
  style: zIndex !== void 0 ? { zIndex } : void 0,
@@ -3488,7 +3489,7 @@ function Modal(props) {
3488
3489
  } = props;
3489
3490
  const idRef = useRef(/* @__PURE__ */ Symbol("modal"));
3490
3491
  const [depth, setDepth] = useState(0);
3491
- useEffect(() => {
3492
+ useLayoutEffect(() => {
3492
3493
  if (!isOpen2) return;
3493
3494
  const id = idRef.current;
3494
3495
  const d = modalStack.push(id);
@@ -3525,12 +3526,22 @@ function Modal(props) {
3525
3526
  {
3526
3527
  isOpen: isOpen2,
3527
3528
  onClose,
3528
- className: overlayClassName,
3529
+ className: cn(overlayClassName, depth > 1 && "bg-black/20"),
3529
3530
  closeOnOverlayClick,
3530
3531
  zIndex: overlayZ
3531
3532
  }
3532
3533
  ),
3533
- /* @__PURE__ */ jsx(ModalContent, { className: contentClassName, zIndex: contentZ, children })
3534
+ /* @__PURE__ */ jsx(
3535
+ ModalContent,
3536
+ {
3537
+ className: cn(
3538
+ contentClassName,
3539
+ depth > 1 && "shadow-[0_0_0_1px_rgba(255,255,255,0.12),0_20px_50px_-5px_rgba(0,0,0,0.4)]"
3540
+ ),
3541
+ zIndex: contentZ,
3542
+ children
3543
+ }
3544
+ )
3534
3545
  ] });
3535
3546
  }
3536
3547
  function ConfirmModal(props) {
@@ -4031,7 +4042,7 @@ function TableHeader(props) {
4031
4042
  const subTitleClasses = column.key === "subTitle" ? "inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-blue-100 text-blue-800" : "";
4032
4043
  if (column.align === "left") {
4033
4044
  return /* @__PURE__ */ jsxs("div", { className: "flex item-center w-full", children: [
4034
- /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx("span", { className: `pl-2 truncate ${baseClasses} ${isClickableHead} ${subTitleClasses}`, children: column.title }) }),
4045
+ /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx("span", { className: `pl-3 truncate ${baseClasses} ${isClickableHead} ${subTitleClasses}`, children: column.title }) }),
4035
4046
  column.sortable && /* @__PURE__ */ jsx(
4036
4047
  "div",
4037
4048
  {
@@ -4062,7 +4073,7 @@ function TableHeader(props) {
4062
4073
  children: renderSortIcon(column.key)
4063
4074
  }
4064
4075
  ),
4065
- /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx("span", { className: `pr-2 truncate ${baseClasses} ${isClickableHead} ${subTitleClasses}`, children: column.title }) })
4076
+ /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx("span", { className: `pr-3 truncate ${baseClasses} ${isClickableHead} ${subTitleClasses}`, children: column.title }) })
4066
4077
  ] });
4067
4078
  }
4068
4079
  return /* @__PURE__ */ jsx("span", { className: `px-1.5 truncate ${baseClasses} ${isClickableHead} ${subTitleClasses}`, children: column.title });
@@ -4433,7 +4444,7 @@ function SkeletonTd(props) {
4433
4444
  return /* @__PURE__ */ jsx(
4434
4445
  "td",
4435
4446
  {
4436
- className: `${col.key === "__checkbox__" ? "p-0" : "px-2 py-[6.8px]"} whitespace-nowrap text-sm border-r border-b border-gray-200/70 last:border-r-0`,
4447
+ className: `${col.key === "__checkbox__" ? "p-0" : "px-2 py-4"} whitespace-nowrap text-sm border-r border-b border-gray-200/70 last:border-r-0`,
4437
4448
  style: {
4438
4449
  width: col.width,
4439
4450
  minWidth: col.minWidth || col.width,
@@ -4505,7 +4516,7 @@ function TableCellContent(props) {
4505
4516
  "div",
4506
4517
  {
4507
4518
  ref: textRef,
4508
- className: "ellipsis-1-line table-item hover:text-main cursor-pointer w-full min-w-0",
4519
+ className: `ellipsis-1-line table-item w-full min-w-0 ${onCellClick ? "hover:text-main cursor-pointer" : "cursor-default"}`,
4509
4520
  style: { textAlign },
4510
4521
  onClick: onCellClick,
4511
4522
  children: shouldShowTooltip ? /* @__PURE__ */ jsx(Tooltip2, { content: tooltipText, position: "bottom", asChild: true, children: /* @__PURE__ */ jsx("span", { children: cellContent }) }) : cellContent
@@ -4974,7 +4985,7 @@ function Table(props) {
4974
4985
  id: `${col.key}-body`,
4975
4986
  "data-row-cell": "true",
4976
4987
  "data-col-key": col.key,
4977
- className: `${isCheckbox ? "p-0" : "px-2 py-[6.8px]"} whitespace-nowrap text-sm text-gray-900 border-r border-b border-gray-200 last:border-r-0 bg-inherit group-hover:bg-gray-100 transition-all`,
4988
+ className: `${isCheckbox ? "p-0" : "px-2 py-3"} whitespace-nowrap text-sm text-gray-900 border-r border-b border-gray-200 last:border-r-0 bg-inherit group-hover:bg-gray-100 transition-all`,
4978
4989
  style: {
4979
4990
  width,
4980
4991
  minWidth: minWidth || width,
@@ -4991,7 +5002,7 @@ function Table(props) {
4991
5002
  tooltipText: String(record[col.key] ?? ""),
4992
5003
  align: align ?? "",
4993
5004
  tooltipConfig: col.key === "__checkbox__" ? false : tooltipConfig,
4994
- onCellClick: col.key !== "__checkbox__" ? () => onRowClickRef.current?.(record, rowIdx) : void 0
5005
+ onCellClick: col.key !== "__checkbox__" && onRowClickRef.current ? () => onRowClickRef.current?.(record, rowIdx) : void 0
4995
5006
  }
4996
5007
  ) })
4997
5008
  },
@@ -5066,7 +5077,7 @@ function Table(props) {
5066
5077
  const rest = baseRows.filter((row) => !effectiveRowOrder.includes(String(getRowKey(row.original, row.index))));
5067
5078
  return [...ordered, ...rest];
5068
5079
  }, [baseRows, effectiveRowOrder, getRowKey]);
5069
- return /* @__PURE__ */ jsxs("div", { className: "bg-white rounded table-shadow", children: [
5080
+ return /* @__PURE__ */ jsxs("div", { className: "bg-white rounded shadow-panel", children: [
5070
5081
  /* @__PURE__ */ jsx(
5071
5082
  "div",
5072
5083
  {
@@ -5090,7 +5101,7 @@ function Table(props) {
5090
5101
  isColumnDraggable
5091
5102
  }
5092
5103
  ),
5093
- /* @__PURE__ */ jsx("tbody", { className: "w-full h-full", children: showSkeleton ? Array.from({ length: 15 }).map((_, rowIdx) => /* @__PURE__ */ jsxs("tr", { className: "hover:bg-gray-50", children: [
5104
+ /* @__PURE__ */ jsx("tbody", { className: "w-full h-full", children: showSkeleton ? Array.from({ length: 3 }).map((_, rowIdx) => /* @__PURE__ */ jsxs("tr", { className: "hover:bg-gray-50", children: [
5094
5105
  leadingPinnedCols.map((col, idx) => /* @__PURE__ */ jsx(SkeletonTd, { col, showSquare: idx === 0 && !!checkboxInfo }, `leading-${idx}`)),
5095
5106
  leftColspan > 0 && /* @__PURE__ */ jsx("td", { colSpan: leftColspan, style: { padding: 0, border: "none" } }),
5096
5107
  virtualItems.map((vc) => /* @__PURE__ */ jsx(SkeletonTd, { col: groupCols[vc.index] }, `group-${vc.index}`)),
@@ -6102,14 +6113,53 @@ function resolveValueColSpan(colspan) {
6102
6113
  const span = colspan ?? 10;
6103
6114
  return COL_SPAN_CLASS[span] ?? COL_SPAN_CLASS[10];
6104
6115
  }
6116
+ var THREE_DIGIT_AREA_CODES = /* @__PURE__ */ new Set([
6117
+ "031",
6118
+ "032",
6119
+ "033",
6120
+ "041",
6121
+ "042",
6122
+ "043",
6123
+ "051",
6124
+ "052",
6125
+ "053",
6126
+ "054",
6127
+ "055",
6128
+ "061",
6129
+ "062",
6130
+ "063"
6131
+ ]);
6105
6132
  function formatPhoneNumber(value) {
6106
- const numbers = value.replace(/\D/g, "");
6107
- if (numbers.length <= 3) return numbers;
6108
- if (numbers.length <= 7) return `${numbers.slice(0, 3)}-${numbers.slice(3)}`;
6109
- if (numbers.length <= 11) {
6110
- return `${numbers.slice(0, 3)}-${numbers.slice(3, 7)}-${numbers.slice(7)}`;
6133
+ let digits = value.replace(/\D/g, "");
6134
+ if (digits.startsWith("02")) {
6135
+ if (digits.length > 2 && digits.length <= 6) {
6136
+ return `${digits.slice(0, 2)}-${digits.slice(2)}`;
6137
+ }
6138
+ if (digits.length > 6) {
6139
+ return `${digits.slice(0, 2)}-${digits.slice(2, 6)}-${digits.slice(6)}`;
6140
+ }
6141
+ } else if (THREE_DIGIT_AREA_CODES.has(digits.slice(0, 3))) {
6142
+ if (digits.length > 3 && digits.length <= 6) {
6143
+ return `${digits.slice(0, 3)}-${digits.slice(3)}`;
6144
+ }
6145
+ if (digits.length > 6) {
6146
+ return `${digits.slice(0, 3)}-${digits.slice(3, 6)}-${digits.slice(6)}`;
6147
+ }
6148
+ } else {
6149
+ if (digits.length > 3 && digits.length <= 7) {
6150
+ return `${digits.slice(0, 3)}-${digits.slice(3)}`;
6151
+ }
6152
+ if (digits.length > 7) {
6153
+ return `${digits.slice(0, 3)}-${digits.slice(3, 7)}-${digits.slice(7)}`;
6154
+ }
6155
+ }
6156
+ return digits;
6157
+ }
6158
+ function resolvePhoneMaxLength(formattedValue) {
6159
+ if (formattedValue.startsWith("02") || THREE_DIGIT_AREA_CODES.has(formattedValue.slice(0, 3))) {
6160
+ return 12;
6111
6161
  }
6112
- return `${numbers.slice(0, 3)}-${numbers.slice(3, 7)}-${numbers.slice(7, 11)}`;
6162
+ return 13;
6113
6163
  }
6114
6164
  function formatNumberWithCommas(value) {
6115
6165
  const numStr = String(value).replace(/,/g, "");
@@ -6804,7 +6854,8 @@ function InputField(props) {
6804
6854
  maxLength,
6805
6855
  className = "",
6806
6856
  type = "input",
6807
- numbersOnly = false
6857
+ numbersOnly = false,
6858
+ autoComplete
6808
6859
  } = config;
6809
6860
  const inputType = type === "email" ? "email" : type === "password" ? "password" : "text";
6810
6861
  if (readOnly) {
@@ -6829,6 +6880,7 @@ function InputField(props) {
6829
6880
  maxLength,
6830
6881
  status: "default",
6831
6882
  className: formControlClass(hasError),
6883
+ autoComplete,
6832
6884
  bare: true,
6833
6885
  onChange: handleChange
6834
6886
  }
@@ -6931,11 +6983,13 @@ function PhoneField(props) {
6931
6983
  hasError = false
6932
6984
  } = props;
6933
6985
  const { placeholder = "010-0000-0000", disabled = false, readOnly = false, className = "" } = config;
6986
+ const phoneValue = String(value ?? "");
6987
+ const phoneMaxLength = resolvePhoneMaxLength(phoneValue);
6934
6988
  const handleChange = (e) => {
6935
6989
  onChange(formatPhoneNumber(e.target.value));
6936
6990
  };
6937
6991
  if (readOnly) {
6938
- return /* @__PURE__ */ jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: String(value ?? "") || "\u2014" }) });
6992
+ return /* @__PURE__ */ jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: phoneValue || "\u2014" }) });
6939
6993
  }
6940
6994
  return /* @__PURE__ */ jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsx(
6941
6995
  Input2,
@@ -6943,12 +6997,12 @@ function PhoneField(props) {
6943
6997
  name,
6944
6998
  ref,
6945
6999
  onBlur,
6946
- value: String(value ?? ""),
7000
+ value: phoneValue,
6947
7001
  type: "text",
6948
7002
  placeholder,
6949
7003
  disabled,
6950
7004
  readOnly,
6951
- maxLength: 13,
7005
+ maxLength: phoneMaxLength,
6952
7006
  status: "default",
6953
7007
  className: formControlClass(hasError),
6954
7008
  bare: true,
@@ -7534,7 +7588,8 @@ function SubmitFormRoot(props) {
7534
7588
  className = "",
7535
7589
  formClassName,
7536
7590
  gridClassName = "grid-cols-12",
7537
- mode = "onSubmit"
7591
+ mode = "onSubmit",
7592
+ autoComplete
7538
7593
  } = props;
7539
7594
  const methods = useForm({
7540
7595
  resolver: zodResolver(schema),
@@ -7557,6 +7612,7 @@ function SubmitFormRoot(props) {
7557
7612
  id: formId,
7558
7613
  onSubmit: handleSubmit,
7559
7614
  className: cn2(SUBMIT_FORM_CLASS, formClassName, className),
7615
+ autoComplete,
7560
7616
  noValidate: true,
7561
7617
  children: /* @__PURE__ */ jsx("div", { className: `grid ${gridClassName} items-stretch gap-0`, children })
7562
7618
  }
@@ -7584,7 +7640,8 @@ function PageFilter(props) {
7584
7640
  colGap = 0,
7585
7641
  submitButtonText = "\uAC80\uC0C9",
7586
7642
  resetButtonText = "\uCD08\uAE30\uD654",
7587
- values
7643
+ values,
7644
+ primaryColor
7588
7645
  } = props;
7589
7646
  const [localValues, setLocalValues] = useState(values);
7590
7647
  const initialValuesRef = useRef(values);
@@ -7642,6 +7699,7 @@ function PageFilter(props) {
7642
7699
  onChange: handleSelectChange(optionKey),
7643
7700
  options: option.options,
7644
7701
  placeholder: "\uC120\uD0DD",
7702
+ canReset: true,
7645
7703
  containerClassName: option.containerClassName ?? "w-30"
7646
7704
  }
7647
7705
  ) }, String(optionKey));
@@ -7694,16 +7752,20 @@ function PageFilter(props) {
7694
7752
  "div",
7695
7753
  {
7696
7754
  className: cn(
7697
- "flex flex-col gap-3 bg-white py-3 px-5 border-t-main border-t-1 shadow-page-filter",
7755
+ "flex flex-col gap-3 bg-white py-3 px-5 border-t-main border-t-1 shadow-panel",
7698
7756
  containerClassName
7699
7757
  ),
7700
- children: /* @__PURE__ */ jsxs("div", { className: "relative flex flex-col", style: { gap: `${colGap}px` }, children: [
7701
- rows.map((row) => /* @__PURE__ */ jsx("div", { className: "flex flex-row min-h-12", children: row.options.map((option, index) => renderFilterOption(option, rowGap, index)) }, row.options.map((opt) => String(opt.key)).join("_"))),
7702
- /* @__PURE__ */ jsxs("div", { className: "absolute right-2 bottom-2 flex justify-end gap-2 pt-2", children: [
7703
- /* @__PURE__ */ jsx(Button, { variant: "search", onClick: handleSubmit, children: submitButtonText }),
7704
- onReset && /* @__PURE__ */ jsx(Button, { variant: "reset", onClick: handleReset, children: resetButtonText })
7705
- ] })
7706
- ] })
7758
+ style: primaryColor ? { borderTopColor: primaryColor } : void 0,
7759
+ children: /* @__PURE__ */ jsx("div", { className: "relative flex flex-col", style: { gap: `${colGap}px` }, children: rows.map((row, ix) => {
7760
+ const isLastRow = rows.length - 1 === ix;
7761
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-row min-h-12", children: [
7762
+ row.options.map((option, index) => renderFilterOption(option, rowGap, index)),
7763
+ isLastRow && /* @__PURE__ */ jsxs("div", { className: "ml-4 flex flex-row items-center gap-2", children: [
7764
+ /* @__PURE__ */ jsx(Button, { variant: "search", onClick: handleSubmit, children: submitButtonText }),
7765
+ onReset && /* @__PURE__ */ jsx(Button, { variant: "reset", onClick: handleReset, children: resetButtonText })
7766
+ ] })
7767
+ ] }, row.options.map((opt) => String(opt.key)).join("_"));
7768
+ }) })
7707
7769
  }
7708
7770
  );
7709
7771
  }
@@ -7715,7 +7777,9 @@ var VARIANT_STYLES = {
7715
7777
  activeText: "font-semibold text-gray-800",
7716
7778
  inactiveText: "font-normal",
7717
7779
  indicator: "bg-blue-500",
7718
- closeBtn: "hover:bg-gray-300/60",
7780
+ closeBtn: "rounded hover:bg-gray-300/60",
7781
+ closeBtnWH: "w-3.5 h-3.5",
7782
+ closeBtnSize: 10,
7719
7783
  plusBtnArea: "border-l border-gray-100 bg-white",
7720
7784
  plusBtn: "text-gray-400 hover:text-gray-600 hover:bg-gray-100",
7721
7785
  fadeOpacity: 0.12,
@@ -7732,7 +7796,9 @@ var VARIANT_STYLES = {
7732
7796
  activeText: "font-semibold text-white",
7733
7797
  inactiveText: "font-normal",
7734
7798
  indicator: "bg-indigo-400",
7735
- closeBtn: "hover:bg-gray-600/60",
7799
+ closeBtn: "rounded hover:bg-gray-600/60",
7800
+ closeBtnWH: "w-3.5 h-3.5",
7801
+ closeBtnSize: 10,
7736
7802
  plusBtnArea: "border-l border-gray-700 bg-gray-900",
7737
7803
  plusBtn: "text-gray-500 hover:text-gray-300 hover:bg-gray-700",
7738
7804
  fadeOpacity: 0.4,
@@ -7745,11 +7811,13 @@ var VARIANT_STYLES = {
7745
7811
  "system-light": {
7746
7812
  container: "bg-gray-200 border-b border-gray-300",
7747
7813
  activeTab: "bg-white border-gray-300 text-slate-800 shadow-sm",
7748
- inactiveTab: "bg-transparent border-gray-300/80 text-slate-500 hover:text-slate-700 hover:bg-gray-200 hover:border-gray-300",
7814
+ inactiveTab: "bg-transparent border-gray-300/80 text-slate-500 hover:text-slate-700 hover:bg-[#efefef] hover:border-gray-300",
7749
7815
  activeText: "font-semibold text-slate-800",
7750
7816
  inactiveText: "font-medium",
7751
7817
  indicator: "bg-[#2b2b2b]",
7752
- closeBtn: "hover:bg-gray-300",
7818
+ closeBtn: "ml-auto text-slate-400 hover:text-slate-700",
7819
+ closeBtnWH: "w-4 h-4",
7820
+ closeBtnSize: 13,
7753
7821
  plusBtnArea: "border-l border-gray-300 bg-gray-200",
7754
7822
  plusBtn: "text-slate-400 hover:text-slate-600 hover:bg-gray-300",
7755
7823
  fadeOpacity: 0.15,
@@ -7766,7 +7834,9 @@ var VARIANT_STYLES = {
7766
7834
  activeText: "font-semibold text-slate-100",
7767
7835
  inactiveText: "font-medium",
7768
7836
  indicator: "bg-indigo-400",
7769
- closeBtn: "hover:bg-slate-600/60",
7837
+ closeBtn: "ml-auto text-slate-500 hover:text-slate-200",
7838
+ closeBtnWH: "w-4 h-4",
7839
+ closeBtnSize: 13,
7770
7840
  plusBtnArea: "border-l border-slate-700 bg-slate-900",
7771
7841
  plusBtn: "text-slate-400 hover:text-slate-200 hover:bg-slate-700",
7772
7842
  fadeOpacity: 0.45,
@@ -7919,12 +7989,12 @@ function MultiTabBar(props) {
7919
7989
  onTabClose(tab.id);
7920
7990
  },
7921
7991
  className: `
7922
- flex-shrink-0 w-3.5 h-3.5 flex items-center justify-center
7923
- rounded transition-all duration-100 cursor-pointer
7992
+ flex-shrink-0 ${s.closeBtnWH} flex items-center justify-center
7993
+ transition-all duration-100 cursor-pointer
7924
7994
  ${s.closeBtn}
7925
7995
  ${isActive ? "opacity-100" : "opacity-40 group-hover:opacity-60"}
7926
7996
  `,
7927
- children: /* @__PURE__ */ jsx(X, { size: 10, strokeWidth: 2.5 })
7997
+ children: /* @__PURE__ */ jsx(X, { size: s.closeBtnSize, strokeWidth: 2.5 })
7928
7998
  }
7929
7999
  )
7930
8000
  ]
@@ -8754,7 +8824,8 @@ var VARIANT_STYLES2 = {
8754
8824
  iconClass: "w-4 h-4 flex-shrink-0",
8755
8825
  activeItemStyle: {},
8756
8826
  activeChildStyle: {},
8757
- activeGrandchildStyle: {}
8827
+ activeGrandchildStyle: {},
8828
+ footerBorder: "border-t border-gray-200"
8758
8829
  },
8759
8830
  dark: {
8760
8831
  aside: "bg-gray-900 border-r border-gray-700",
@@ -8780,7 +8851,8 @@ var VARIANT_STYLES2 = {
8780
8851
  iconClass: "w-4 h-4 flex-shrink-0",
8781
8852
  activeItemStyle: {},
8782
8853
  activeChildStyle: {},
8783
- activeGrandchildStyle: {}
8854
+ activeGrandchildStyle: {},
8855
+ footerBorder: "border-t border-gray-700"
8784
8856
  },
8785
8857
  "system-dark": {
8786
8858
  aside: "bg-slate-900 border-r border-slate-700",
@@ -8806,7 +8878,8 @@ var VARIANT_STYLES2 = {
8806
8878
  iconClass: "w-4.5 h-4.5 flex-shrink-0",
8807
8879
  activeItemStyle: { borderLeft: "3px solid #818cf8", paddingLeft: "9px" },
8808
8880
  activeChildStyle: { borderLeft: "2px solid #818cf8", paddingLeft: "14px" },
8809
- activeGrandchildStyle: { borderLeft: "2px solid #818cf8", paddingLeft: "10px" }
8881
+ activeGrandchildStyle: { borderLeft: "2px solid #818cf8", paddingLeft: "10px" },
8882
+ footerBorder: "border-t border-slate-700"
8810
8883
  },
8811
8884
  "system-light": {
8812
8885
  aside: "bg-gray-50 border-r border-gray-200",
@@ -8847,7 +8920,8 @@ var VARIANT_STYLES2 = {
8847
8920
  backgroundColor: "color-mix(in srgb, #2b2b2b 10%, transparent)",
8848
8921
  borderLeft: "2px solid #2b2b2b",
8849
8922
  paddingLeft: "10px"
8850
- }
8923
+ },
8924
+ footerBorder: "border-t border-gray-200"
8851
8925
  }
8852
8926
  };
8853
8927
  function tintedStyle(color) {
@@ -8924,6 +8998,7 @@ function Sidebar(props) {
8924
8998
  onClose,
8925
8999
  menuSections,
8926
9000
  header,
9001
+ footer,
8927
9002
  className,
8928
9003
  showCollapseButton = false,
8929
9004
  variant = "light",
@@ -8931,8 +9006,17 @@ function Sidebar(props) {
8931
9006
  } = props;
8932
9007
  const { pathname } = useLocation();
8933
9008
  const [isCollapsed, setIsCollapsed] = useState(false);
9009
+ const [overflowVisible, setOverflowVisible] = useState(true);
8934
9010
  const [expandedItems, setExpandedItems] = useState(/* @__PURE__ */ new Set());
8935
9011
  const [expandedSubItems, setExpandedSubItems] = useState(/* @__PURE__ */ new Set());
9012
+ useEffect(() => {
9013
+ if (isCollapsed) {
9014
+ setOverflowVisible(false);
9015
+ return;
9016
+ }
9017
+ const timer = setTimeout(() => setOverflowVisible(true), 300);
9018
+ return () => clearTimeout(timer);
9019
+ }, [isCollapsed]);
8936
9020
  const s = VARIANT_STYLES2[variant];
8937
9021
  const applier = ACCENT_APPLIERS[variant];
8938
9022
  useEffect(() => {
@@ -8994,7 +9078,7 @@ function Sidebar(props) {
8994
9078
  className: `
8995
9079
  ${isCollapsed ? "w-11 min-w-11" : "min-w-60 w-62"}
8996
9080
  transition-[width,min-width] duration-300 ease-in-out
8997
- hide-scrollbar relative h-screen shrink-0 overflow-y-auto overflow-x-hidden
9081
+ relative h-screen shrink-0 overflow-x-hidden flex flex-col
8998
9082
  ${s.aside}
8999
9083
  ${className ?? ""}
9000
9084
  `,
@@ -9007,14 +9091,14 @@ function Sidebar(props) {
9007
9091
  children: isCollapsed ? /* @__PURE__ */ jsx(PanelRightClose, { size: 18, color: primaryColor ?? s.collapseIcon }) : /* @__PURE__ */ jsx(PanelLeftClose, { size: 18, color: primaryColor ?? s.collapseIcon })
9008
9092
  }
9009
9093
  ),
9010
- /* @__PURE__ */ jsxs(
9094
+ /* @__PURE__ */ jsx("div", { className: `flex-1 min-h-0 hide-scrollbar ${overflowVisible ? "overflow-y-auto" : "overflow-hidden"}`, children: /* @__PURE__ */ jsxs(
9011
9095
  "div",
9012
9096
  {
9013
- className: `transition-opacity duration-200 ease-in-out ${isCollapsed ? "opacity-0 pointer-events-none select-none" : "opacity-100"} ${variant === "system-dark" || variant === "system-light" ? "px-1 py-6" : "px-4 py-6"}`,
9097
+ className: `transition-opacity duration-200 ease-in-out ${isCollapsed ? "opacity-0 pointer-events-none select-none" : "opacity-100"} ${variant === "system-dark" || variant === "system-light" ? "pb-6" : "px-4 pb-6"}`,
9014
9098
  style: { transitionDelay: isCollapsed ? "0ms" : "150ms" },
9015
9099
  children: [
9016
- header && /* @__PURE__ */ jsx("div", { className: "mb-6 mt-2", children: header }),
9017
- /* @__PURE__ */ jsx("nav", { className: "space-y-6", children: menuSections.map((section, sectionIndex) => /* @__PURE__ */ jsxs("div", { children: [
9100
+ header && header,
9101
+ /* @__PURE__ */ jsx("nav", { className: `space-y-6 ${variant === "system-dark" || variant === "system-light" ? "px-1" : ""}`, children: menuSections.map((section, sectionIndex) => /* @__PURE__ */ jsxs("div", { children: [
9018
9102
  section.title && /* @__PURE__ */ jsx("div", { className: s.sectionTitle, children: section.title }),
9019
9103
  /* @__PURE__ */ jsx("div", { className: "space-y-0.5", children: section.items.map((item) => {
9020
9104
  const isActive = !item.children && pathname === item.path;
@@ -9153,6 +9237,14 @@ function Sidebar(props) {
9153
9237
  ] }, section.title ?? sectionIndex)) })
9154
9238
  ]
9155
9239
  }
9240
+ ) }),
9241
+ footer && /* @__PURE__ */ jsx(
9242
+ "div",
9243
+ {
9244
+ className: `flex-shrink-0 transition-opacity duration-200 ease-in-out ${isCollapsed ? "opacity-0 pointer-events-none select-none" : "opacity-100"} ${s.footerBorder}`,
9245
+ style: { transitionDelay: isCollapsed ? "0ms" : "150ms" },
9246
+ children: footer
9247
+ }
9156
9248
  )
9157
9249
  ]
9158
9250
  }
@@ -9471,7 +9563,7 @@ function DetailModalFrame(props) {
9471
9563
  ) }),
9472
9564
  renderExtraContent?.({ isEditMode })
9473
9565
  ] }),
9474
- /* @__PURE__ */ jsx(ModalFooter, { className: "flex justify-end gap-2", children: isEditMode ? /* @__PURE__ */ jsxs(Fragment, { children: [
9566
+ /* @__PURE__ */ jsx(ModalFooter, { className: "flex justify-end", children: isEditMode ? /* @__PURE__ */ jsxs(Fragment, { children: [
9475
9567
  /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: handleCancelEdit, disabled: controller.isSaving, children: "\uCDE8\uC18C" }),
9476
9568
  /* @__PURE__ */ jsx(Button, { type: "submit", form: controller.formId, variant: "save", disabled: controller.isSaving, children: "\uC800\uC7A5" })
9477
9569
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -9756,6 +9848,144 @@ function useScrollToTop(containerId) {
9756
9848
  return scrollToTop;
9757
9849
  }
9758
9850
 
9759
- export { ArrowIcon, Badge, BaseUploader, BreadCrumb, Button, Carousel_default as Carousel, Checkbox, DatePicker, DebouncedButton, DetailContent, DetailModalFrame, DetailPageFrame, Empty, ExcelUploader, FilePreviewViewer, FileUploader, Input2 as Input, Loading, LoadingOverlay, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, ModalIconHeader, ModalOverlay, MultiTabBar as MultiTab, PageFilter, Pagination, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverDescription, PopoverFooter, PopoverHeader, PopoverTitle, PopoverTrigger, Radio, RadioGroup, ScrollArea_default as ScrollArea, ScrollBar, SearchAddress, SearchBar, Select2 as Select, Select as SelectBase, SelectContent, SelectGroup2 as SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Sidebar, SimplePopover, Skeleton, Slider, Spinner, SubmitForm, Switch, Tab, Table, Textarea, ToastProvider, ToggleSwitch, Tooltip2 as Tooltip, Z_INDEX, buildBreadCrumbItems, buttonVariants, cn, confirmModal, findParentMenuItem, findParentMenuName, formatDate, getFileLabel, getPreviewFileType, isCalendarDayAfterMax, isDateInRange, switchTrackSizes, textVariants, toast, useBlockModalConfirm, useBreadCrumbItems, useCustomBlocker, useDetailController, useFilePreviewViewer, useModal, useMultiTabStore, useScrollToTop, useStableImageSrc, useToast, validateAndFormatInput };
9851
+ // src/hooks/useParams/config/utils.ts
9852
+ function paramsToSearchParams(params) {
9853
+ const searchParams = new URLSearchParams();
9854
+ Object.entries(params).forEach(([key, value]) => {
9855
+ if (value === null || value === void 0) {
9856
+ return;
9857
+ }
9858
+ if (Array.isArray(value)) {
9859
+ value.forEach((item) => searchParams.append(key, String(item)));
9860
+ } else if (value !== "") {
9861
+ searchParams.set(key, String(value));
9862
+ }
9863
+ });
9864
+ return searchParams;
9865
+ }
9866
+ function useParams(initialParams) {
9867
+ if (!initialParams) {
9868
+ throw new Error("initialParams is required");
9869
+ }
9870
+ const [params, setParams] = useState(initialParams);
9871
+ const [localParams, setLocalParams] = useState(initialParams);
9872
+ const [searchParams, setSearchParams] = useSearchParams();
9873
+ const isInitializedRef = useRef(false);
9874
+ const getInitialState = useCallback(() => {
9875
+ const result = { ...initialParams };
9876
+ Object.keys(initialParams).forEach((key) => {
9877
+ const initialValue = initialParams[key];
9878
+ if (Array.isArray(initialValue)) {
9879
+ const urlValue = searchParams.getAll(key);
9880
+ if (urlValue.length > 0) {
9881
+ result[key] = urlValue;
9882
+ }
9883
+ } else {
9884
+ const urlValue = searchParams.get(key);
9885
+ if (urlValue !== null) {
9886
+ if (urlValue === "null") {
9887
+ result[key] = null;
9888
+ } else if (urlValue === "undefined") {
9889
+ result[key] = void 0;
9890
+ } else {
9891
+ result[key] = urlValue;
9892
+ }
9893
+ }
9894
+ }
9895
+ });
9896
+ return result;
9897
+ }, [initialParams, searchParams]);
9898
+ useEffect(() => {
9899
+ if (!isInitializedRef.current) {
9900
+ const initialState = getInitialState();
9901
+ setLocalParams(initialState);
9902
+ setParams(initialState);
9903
+ if (!searchParams.toString()) {
9904
+ const newSearchParams = paramsToSearchParams(initialParams);
9905
+ setSearchParams(newSearchParams, { replace: true });
9906
+ }
9907
+ isInitializedRef.current = true;
9908
+ }
9909
+ }, [getInitialState, initialParams, searchParams, setSearchParams]);
9910
+ const updateLocalParam = useCallback(
9911
+ (key, value) => {
9912
+ setLocalParams((prev) => ({
9913
+ ...prev,
9914
+ [key]: value
9915
+ }));
9916
+ },
9917
+ [setLocalParams]
9918
+ );
9919
+ const updateParams = useCallback(
9920
+ (updatedParams) => {
9921
+ const newParams = {
9922
+ ...params,
9923
+ ...updatedParams
9924
+ };
9925
+ setParams(newParams);
9926
+ setLocalParams(newParams);
9927
+ setSearchParams(paramsToSearchParams(newParams));
9928
+ },
9929
+ [params, setSearchParams]
9930
+ );
9931
+ const updateParam = useCallback(
9932
+ (key, value) => {
9933
+ const newParams = {
9934
+ ...params,
9935
+ [key]: value
9936
+ };
9937
+ setParams(newParams);
9938
+ setLocalParams(newParams);
9939
+ setSearchParams(paramsToSearchParams(newParams));
9940
+ },
9941
+ [params, setSearchParams]
9942
+ );
9943
+ const update = useCallback(() => {
9944
+ const paramsWithResetPage = {
9945
+ ...localParams,
9946
+ page: 0
9947
+ };
9948
+ const newSearchParams = paramsToSearchParams(paramsWithResetPage);
9949
+ setSearchParams(newSearchParams);
9950
+ setParams(paramsWithResetPage);
9951
+ setLocalParams(paramsWithResetPage);
9952
+ }, [localParams, setSearchParams]);
9953
+ const reset = useCallback(() => {
9954
+ setLocalParams(initialParams);
9955
+ setParams(initialParams);
9956
+ const newSearchParams = paramsToSearchParams(initialParams);
9957
+ setSearchParams(newSearchParams);
9958
+ }, [initialParams, setSearchParams]);
9959
+ const handleSortChange = useCallback(
9960
+ (sortKey, sortOrder) => {
9961
+ const newParams = {
9962
+ ...params,
9963
+ sortBy: sortKey,
9964
+ sortOrder
9965
+ };
9966
+ updateParams(newParams);
9967
+ },
9968
+ [updateParams, params]
9969
+ );
9970
+ const sortOption = useMemo(() => {
9971
+ if (!params.sortBy || !params.sortOrder) return void 0;
9972
+ return {
9973
+ sortKey: params.sortBy,
9974
+ sortOrder: params.sortOrder
9975
+ };
9976
+ }, [params.sortBy, params.sortOrder]);
9977
+ return {
9978
+ localParams,
9979
+ params,
9980
+ updateParam,
9981
+ updateLocalParam,
9982
+ update,
9983
+ reset,
9984
+ handleSortChange,
9985
+ sortOption
9986
+ };
9987
+ }
9988
+
9989
+ export { ArrowIcon, Badge, BaseUploader, BreadCrumb, Button, Carousel_default as Carousel, Checkbox, DatePicker, DebouncedButton, DetailContent, DetailModalFrame, DetailPageFrame, Empty, ExcelUploader, FilePreviewViewer, FileUploader, Input2 as Input, Loading, LoadingOverlay, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, ModalIconHeader, ModalOverlay, MultiTabBar as MultiTab, PageFilter, Pagination, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverDescription, PopoverFooter, PopoverHeader, PopoverTitle, PopoverTrigger, Radio, RadioGroup, ScrollArea_default as ScrollArea, ScrollBar, SearchAddress, SearchBar, Select2 as Select, Select as SelectBase, SelectContent, SelectGroup2 as SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Sidebar, SimplePopover, Skeleton, Slider, Spinner, SubmitForm, Switch, Tab, Table, Textarea, ToastProvider, ToggleSwitch, Tooltip2 as Tooltip, Z_INDEX, buildBreadCrumbItems, buttonVariants, cn, confirmModal, findParentMenuItem, findParentMenuName, formatDate, getFileLabel, getPreviewFileType, isCalendarDayAfterMax, isDateInRange, switchTrackSizes, textVariants, toast, useBlockModalConfirm, useBreadCrumbItems, useCustomBlocker, useDetailController, useFilePreviewViewer, useModal, useMultiTabStore, useParams, useScrollToTop, useStableImageSrc, useToast, validateAndFormatInput };
9760
9990
  //# sourceMappingURL=index.js.map
9761
9991
  //# sourceMappingURL=index.js.map