@farmzone/fz-react-ui 1.0.7 → 1.0.9

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
@@ -499,12 +499,10 @@ function Input2(props) {
499
499
  const actualType = type === "password" && showPassword ? "text" : type;
500
500
  const handlePasswordToggle = () => setShowPassword((prev) => !prev);
501
501
  const finalRightIcon = rightIcon || (shouldShowPasswordToggle ? /* @__PURE__ */ jsxRuntime.jsx(
502
- "button",
502
+ "div",
503
503
  {
504
- type: "button",
505
504
  onClick: handlePasswordToggle,
506
505
  className: "text-muted-foreground hover:text-foreground cursor-pointer transition-colors",
507
- disabled,
508
506
  children: showPassword ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.EyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Eye, { className: "h-4 w-4" })
509
507
  }
510
508
  ) : null);
@@ -3480,36 +3478,100 @@ var MODAL_ICONS = {
3480
3478
  delete: lucideReact.Trash2,
3481
3479
  warning: lucideReact.TriangleAlert
3482
3480
  };
3481
+ var VARIANT_CONFIG = {
3482
+ default: {
3483
+ container: "bg-gradient-to-r from-blue-50 to-indigo-50 border-blue-100",
3484
+ iconBg: "bg-blue-100 rounded-full",
3485
+ iconColor: "text-main",
3486
+ titleColor: "text-gray-900",
3487
+ descColor: "text-gray-500",
3488
+ closeBtn: "text-gray-400 group-hover:text-gray-600"
3489
+ },
3490
+ "system-light": {
3491
+ container: "bg-gray-50 border-gray-200",
3492
+ iconBg: "bg-white border border-gray-200 shadow-sm rounded-lg",
3493
+ iconColor: "text-slate-600",
3494
+ titleColor: "text-gray-900",
3495
+ descColor: "text-gray-500",
3496
+ closeBtn: "text-gray-400 group-hover:text-gray-600"
3497
+ },
3498
+ "system-dark": {
3499
+ container: "bg-slate-800 border-slate-700",
3500
+ iconBg: "bg-slate-700 border border-slate-600 shadow-sm rounded-lg",
3501
+ iconColor: "text-slate-300",
3502
+ titleColor: "text-slate-100",
3503
+ descColor: "text-slate-400",
3504
+ closeBtn: "text-slate-500 group-hover:text-slate-300"
3505
+ }
3506
+ };
3507
+ var SIZE_CONFIG = {
3508
+ md: {
3509
+ padding: "px-6 py-5",
3510
+ iconBox: "w-10 h-10",
3511
+ iconSize: 20,
3512
+ gap: "gap-3",
3513
+ titleSize: "text-xl font-bold",
3514
+ descSize: "text-sm mt-0.5",
3515
+ closeBtnBox: "w-10 h-10",
3516
+ closeIconSize: 20
3517
+ },
3518
+ sm: {
3519
+ padding: "px-4 py-4",
3520
+ iconBox: "w-8 h-8",
3521
+ iconSize: 16,
3522
+ gap: "gap-2.5",
3523
+ titleSize: "text-lg font-bold",
3524
+ descSize: "text-sm mt-0.5",
3525
+ closeBtnBox: "w-8 h-8",
3526
+ closeIconSize: 16
3527
+ }
3528
+ };
3483
3529
  function ModalIconHeader(props) {
3484
- const { type, title, description, onClose, className } = props;
3530
+ const {
3531
+ type,
3532
+ title,
3533
+ description,
3534
+ onClose,
3535
+ action,
3536
+ variant = "default",
3537
+ size: size2 = "md",
3538
+ primaryColor,
3539
+ className
3540
+ } = props;
3485
3541
  const Icon2 = MODAL_ICONS[type];
3486
- return /* @__PURE__ */ jsxRuntime.jsx(
3487
- ModalHeader,
3488
- {
3489
- className: cn(
3490
- "bg-gradient-to-r from-blue-50 to-indigo-50 border-blue-100 p-0 text-left space-y-0",
3491
- className
3492
- ),
3493
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-6 py-5", children: [
3494
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
3495
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center w-10 h-10 bg-blue-100 rounded-full shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(Icon2, { size: 20, className: "text-main" }) }),
3496
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3497
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl font-bold text-gray-900", children: title }),
3498
- description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-600 mt-0.5", children: description })
3499
- ] })
3500
- ] }),
3501
- /* @__PURE__ */ jsxRuntime.jsx(
3502
- "button",
3503
- {
3504
- type: "button",
3505
- onClick: onClose,
3506
- className: "flex items-center justify-center w-10 h-10 rounded-full transition-colors group cursor-pointer hover:bg-black/5 shrink-0",
3507
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: 20, className: "text-gray-400 group-hover:text-gray-600 transition-colors" })
3508
- }
3509
- )
3542
+ const v = VARIANT_CONFIG[variant];
3543
+ const s = SIZE_CONFIG[size2];
3544
+ const hasColor = !!primaryColor;
3545
+ const isDark = variant === "system-dark";
3546
+ const containerStyle = hasColor && variant === "default" ? {
3547
+ background: `linear-gradient(to right, color-mix(in srgb, ${primaryColor} 6%, white), color-mix(in srgb, ${primaryColor} 12%, white))`,
3548
+ borderColor: `color-mix(in srgb, ${primaryColor} 25%, transparent)`
3549
+ } : void 0;
3550
+ const iconBgStyle = hasColor ? {
3551
+ backgroundColor: isDark ? `color-mix(in srgb, ${primaryColor} 20%, #334155)` : `color-mix(in srgb, ${primaryColor} 15%, white)`
3552
+ } : void 0;
3553
+ const iconColorStyle = hasColor && !isDark ? { color: primaryColor } : void 0;
3554
+ return /* @__PURE__ */ jsxRuntime.jsx(ModalHeader, { className: cn("p-0 text-left space-y-0", v.container, className), style: containerStyle, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center justify-between", s.padding), children: [
3555
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center", s.gap), children: [
3556
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex items-center justify-center shrink-0", s.iconBox, v.iconBg), style: iconBgStyle, children: /* @__PURE__ */ jsxRuntime.jsx(Icon2, { size: s.iconSize, className: hasColor && !isDark ? void 0 : v.iconColor, style: iconColorStyle }) }),
3557
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3558
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: cn(s.titleSize, v.titleColor), children: title }),
3559
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn(s.descSize, v.descColor), children: description })
3510
3560
  ] })
3511
- }
3512
- );
3561
+ ] }),
3562
+ action ?? /* @__PURE__ */ jsxRuntime.jsx(
3563
+ "button",
3564
+ {
3565
+ type: "button",
3566
+ onClick: onClose,
3567
+ className: cn(
3568
+ "flex items-center justify-center rounded-full transition-colors group cursor-pointer hover:bg-black/5 shrink-0",
3569
+ s.closeBtnBox
3570
+ ),
3571
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: s.closeIconSize, className: cn("transition-colors", v.closeBtn) })
3572
+ }
3573
+ )
3574
+ ] }) });
3513
3575
  }
3514
3576
  function Modal(props) {
3515
3577
  const {
@@ -3963,8 +4025,6 @@ function ArrowIcon(props) {
3963
4025
  }
3964
4026
  );
3965
4027
  }
3966
- var DEFAULT_SORT_KEY = "";
3967
- var DEFAULT_SORT_ORDER = "asc";
3968
4028
  var DEFAULT_SORT_OPTIONS = {
3969
4029
  visibleType: "always",
3970
4030
  sortKey: "",
@@ -4013,27 +4073,18 @@ function TableHeader(props) {
4013
4073
  if (onSortChange) {
4014
4074
  const isActive = sortOption?.sortKey === columnKey;
4015
4075
  const currentOrder = sortOption?.sortOrder;
4016
- if (isActive) {
4017
- if (currentOrder === "desc") {
4018
- onSortChange(columnKey, "asc");
4019
- } else if (currentOrder === "asc") {
4020
- onSortChange(DEFAULT_SORT_KEY, DEFAULT_SORT_ORDER);
4021
- } else {
4022
- onSortChange(columnKey, "desc");
4023
- }
4076
+ if (isActive && currentOrder === "desc") {
4077
+ onSortChange(columnKey, "asc");
4024
4078
  } else {
4025
4079
  onSortChange(columnKey, "desc");
4026
4080
  }
4027
4081
  return;
4028
4082
  }
4029
4083
  setInternalSortState((prev) => {
4030
- if (prev.columnKey !== columnKey) {
4031
- return { columnKey, order: "desc" };
4032
- }
4033
- if (prev.order === "desc") {
4084
+ if (prev.columnKey === columnKey && prev.order === "desc") {
4034
4085
  return { columnKey, order: "asc" };
4035
4086
  }
4036
- return { columnKey: null, order: null };
4087
+ return { columnKey, order: "desc" };
4037
4088
  });
4038
4089
  };
4039
4090
  const renderSortIcon = (columnKey) => {
@@ -4669,9 +4720,11 @@ function Table(props) {
4669
4720
  paginationInfo,
4670
4721
  renderFooter,
4671
4722
  tooltipConfig = "overflow",
4672
- isDynamicHeight = true
4723
+ isDynamicHeight = true,
4724
+ showHorizontalDivider = true,
4725
+ showVerticalDivider = true
4673
4726
  } = props;
4674
- const { fixed = false, onSelectionChange, selectedKeys = [] } = checkboxInfo ?? {};
4727
+ const { fixed = false, onSelectionChange, selectedKeys = [], disabledKeys = [], disabledTooltip } = checkboxInfo ?? {};
4675
4728
  const scrollRef = React6.useRef(null);
4676
4729
  const footerRef = React6.useRef(null);
4677
4730
  const [tableHeight, setTableHeight] = React6.useState(500);
@@ -4713,11 +4766,14 @@ function Table(props) {
4713
4766
  const footerH = footerRef.current?.getBoundingClientRect().height ?? 0;
4714
4767
  setTableHeight(window.innerHeight - top - footerH - 24);
4715
4768
  }, [showSkeleton, showEmpty]);
4716
- const isAllSelected = data.length > 0 && selectedKeys.length === data.length;
4717
4769
  const selectedKeysRef = React6.useRef(selectedKeys);
4718
4770
  selectedKeysRef.current = selectedKeys;
4719
4771
  const onSelectionChangeRef = React6.useRef(onSelectionChange);
4720
4772
  onSelectionChangeRef.current = onSelectionChange;
4773
+ const disabledKeysRef = React6.useRef(disabledKeys);
4774
+ disabledKeysRef.current = disabledKeys;
4775
+ const disabledTooltipRef = React6.useRef(disabledTooltip);
4776
+ disabledTooltipRef.current = disabledTooltip;
4721
4777
  const dataRef = React6.useRef(data);
4722
4778
  dataRef.current = data;
4723
4779
  const onRowClickRef = React6.useRef(onRowClick);
@@ -4732,6 +4788,8 @@ function Table(props) {
4732
4788
  },
4733
4789
  [rowKey]
4734
4790
  );
4791
+ const selectableKeys = data.map((record, index) => getRowKey(record, index)).filter((key) => !disabledKeys.includes(key));
4792
+ const isAllSelected = selectableKeys.length > 0 && selectableKeys.every((key) => selectedKeys.includes(key));
4735
4793
  const allColumns = React6.useMemo(() => {
4736
4794
  const checkboxCol = {
4737
4795
  key: "__checkbox__",
@@ -4746,19 +4804,24 @@ function Table(props) {
4746
4804
  checked: isAllSelected,
4747
4805
  onChange: () => {
4748
4806
  if (!onSelectionChangeRef.current) return;
4749
- const allKeys = dataRef.current.map((record, index) => getRowKey(record, index));
4807
+ const allKeys = dataRef.current.map((record, index) => getRowKey(record, index)).filter((key) => !disabledKeysRef.current.includes(key));
4750
4808
  onSelectionChangeRef.current(isAllSelected ? [] : allKeys);
4751
4809
  }
4752
4810
  }
4753
4811
  ),
4754
4812
  render: (_value, record, rowIdx) => {
4755
4813
  const key = getRowKey(record, rowIdx);
4814
+ const isDisabled = disabledKeysRef.current.includes(key);
4815
+ const tooltip = disabledTooltipRef.current;
4816
+ const tooltipContent = isDisabled && tooltip ? typeof tooltip === "function" ? tooltip(key) : tooltip : void 0;
4756
4817
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full w-full items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
4757
4818
  Checkbox,
4758
4819
  {
4759
4820
  checked: selectedKeysRef.current.includes(key),
4821
+ disabled: isDisabled,
4822
+ tooltipConfig: tooltipContent ? { content: tooltipContent, position: "bottom" } : void 0,
4760
4823
  onChange: () => {
4761
- if (!onSelectionChangeRef.current) return;
4824
+ if (!onSelectionChangeRef.current || isDisabled) return;
4762
4825
  const cur = selectedKeysRef.current;
4763
4826
  const next = cur.includes(key) ? cur.filter((k) => k !== key) : [...cur, key];
4764
4827
  onSelectionChangeRef.current(next);
@@ -5019,7 +5082,7 @@ function Table(props) {
5019
5082
  id: `${col.key}-body`,
5020
5083
  "data-row-cell": "true",
5021
5084
  "data-col-key": col.key,
5022
- className: `${isCheckbox ? "p-0" : "p-3"} whitespace-nowrap text-sm text-gray-900 border-r border-b border-gray-300/70 last:border-r-0 bg-inherit group-hover:bg-gray-100 transition-all`,
5085
+ className: `${isCheckbox ? "p-0" : "p-3"} whitespace-nowrap text-sm text-gray-900 border-gray-300/70 last:border-r-0 bg-inherit group-hover:bg-gray-100 transition-all ${showVerticalDivider ? "border-r" : ""} ${showHorizontalDivider ? "border-b" : ""}`,
5023
5086
  style: {
5024
5087
  width,
5025
5088
  minWidth: minWidth || width,
@@ -7728,7 +7791,7 @@ function PageFilter(props) {
7728
7791
  onChange: handleSelectChange(optionKey),
7729
7792
  options: option.options,
7730
7793
  placeholder: "\uC120\uD0DD",
7731
- canReset: true,
7794
+ canReset: option.canReset ?? true,
7732
7795
  containerClassName: option.containerClassName ?? "w-30"
7733
7796
  }
7734
7797
  ) }, String(optionKey));
@@ -7879,16 +7942,24 @@ function easedFade(dir, opacity) {
7879
7942
  return `linear-gradient(${dir}, ${c(1)} 0%, ${c(0.72)} 20%, ${c(0.38)} 45%, ${c(0.1)} 70%, transparent 100%)`;
7880
7943
  }
7881
7944
  function MultiTabBar(props) {
7882
- const { tabs, activeTabId, onTabClick, onTabClose, onTabAdd, variant = "light", primaryColor } = props;
7945
+ const {
7946
+ tabs,
7947
+ activeTabId,
7948
+ onTabClick,
7949
+ onTabClose,
7950
+ onTabAdd,
7951
+ onTabsReorder,
7952
+ variant = "light",
7953
+ primaryColor
7954
+ } = props;
7883
7955
  const s = VARIANT_STYLES[variant];
7884
7956
  const scrollRef = React6.useRef(null);
7885
7957
  const tabRefs = React6.useRef(/* @__PURE__ */ new Map());
7886
7958
  const [showLeftFade, setShowLeftFade] = React6.useState(false);
7887
7959
  const [showRightFade, setShowRightFade] = React6.useState(false);
7888
- const isDragging = React6.useRef(false);
7889
- const hasDragged = React6.useRef(false);
7890
- const dragStartX = React6.useRef(0);
7891
- const dragScrollLeft = React6.useRef(0);
7960
+ const [draggingId, setDraggingId] = React6.useState(null);
7961
+ const [dropTargetId, setDropTargetId] = React6.useState(null);
7962
+ const [dropSide, setDropSide] = React6.useState("before");
7892
7963
  React6.useEffect(() => {
7893
7964
  if (!activeTabId || !scrollRef.current) return;
7894
7965
  const el = tabRefs.current.get(activeTabId);
@@ -7916,23 +7987,6 @@ function MultiTabBar(props) {
7916
7987
  if (scrollRef.current) obs.observe(scrollRef.current);
7917
7988
  return () => obs.disconnect();
7918
7989
  }, [tabs]);
7919
- const handleMouseDown = (e) => {
7920
- if (!scrollRef.current) return;
7921
- isDragging.current = true;
7922
- hasDragged.current = false;
7923
- dragStartX.current = e.pageX - scrollRef.current.getBoundingClientRect().left;
7924
- dragScrollLeft.current = scrollRef.current.scrollLeft;
7925
- };
7926
- const handleMouseMove = (e) => {
7927
- if (!isDragging.current || !scrollRef.current) return;
7928
- const x = e.pageX - scrollRef.current.getBoundingClientRect().left;
7929
- const walk = x - dragStartX.current;
7930
- if (Math.abs(walk) > 4) hasDragged.current = true;
7931
- scrollRef.current.scrollLeft = dragScrollLeft.current - walk;
7932
- };
7933
- const handleStopDrag = () => {
7934
- isDragging.current = false;
7935
- };
7936
7990
  React6.useEffect(() => {
7937
7991
  const el = scrollRef.current;
7938
7992
  if (!el) return;
@@ -7943,6 +7997,46 @@ function MultiTabBar(props) {
7943
7997
  el.addEventListener("wheel", onWheel, { passive: false });
7944
7998
  return () => el.removeEventListener("wheel", onWheel);
7945
7999
  }, []);
8000
+ const handleDragStart = (e, tabId) => {
8001
+ setDraggingId(tabId);
8002
+ e.dataTransfer.effectAllowed = "move";
8003
+ };
8004
+ const handleDragOver = (e, tabId) => {
8005
+ e.preventDefault();
8006
+ if (tabId === draggingId) return;
8007
+ e.dataTransfer.dropEffect = "move";
8008
+ const rect = e.currentTarget.getBoundingClientRect();
8009
+ setDropSide(e.clientX < rect.left + rect.width / 2 ? "before" : "after");
8010
+ setDropTargetId(tabId);
8011
+ };
8012
+ const handleDrop = (e, targetTabId) => {
8013
+ e.preventDefault();
8014
+ if (!draggingId || draggingId === targetTabId) {
8015
+ setDraggingId(null);
8016
+ setDropTargetId(null);
8017
+ return;
8018
+ }
8019
+ if (onTabsReorder) {
8020
+ const fromIdx = tabs.findIndex((t) => t.id === draggingId);
8021
+ if (fromIdx !== -1) {
8022
+ const newTabs = [...tabs];
8023
+ const moved = newTabs.splice(fromIdx, 1)[0];
8024
+ let insertIdx = newTabs.findIndex((t) => t.id === targetTabId);
8025
+ if (insertIdx !== -1) {
8026
+ if (dropSide === "after") insertIdx += 1;
8027
+ newTabs.splice(insertIdx, 0, moved);
8028
+ onTabsReorder(newTabs);
8029
+ }
8030
+ }
8031
+ }
8032
+ setDraggingId(null);
8033
+ setDropTargetId(null);
8034
+ };
8035
+ const handleDragEnd = () => {
8036
+ setDraggingId(null);
8037
+ setDropTargetId(null);
8038
+ };
8039
+ const showPlus = !!onTabAdd;
7946
8040
  if (tabs.length === 0) return null;
7947
8041
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex-shrink-0 w-full overflow-hidden ${s.container}`, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex items-stretch", children: [
7948
8042
  showLeftFade && /* @__PURE__ */ jsxRuntime.jsx(
@@ -7957,7 +8051,7 @@ function MultiTabBar(props) {
7957
8051
  {
7958
8052
  className: "absolute top-0 bottom-0 w-10 pointer-events-none z-10",
7959
8053
  style: {
7960
- right: PLUS_BTN_WIDTH,
8054
+ right: showPlus ? PLUS_BTN_WIDTH : 0,
7961
8055
  background: easedFade("to left", s.fadeOpacity)
7962
8056
  }
7963
8057
  }
@@ -7969,12 +8063,10 @@ function MultiTabBar(props) {
7969
8063
  className: `flex-1 min-w-0 flex items-end gap-0.5 ${s.scrollPadding} overflow-x-auto [&::-webkit-scrollbar]:hidden`,
7970
8064
  style: { scrollbarWidth: "none" },
7971
8065
  onScroll: updateFades,
7972
- onMouseDown: handleMouseDown,
7973
- onMouseMove: handleMouseMove,
7974
- onMouseUp: handleStopDrag,
7975
- onMouseLeave: handleStopDrag,
7976
8066
  children: tabs.map((tab) => {
7977
8067
  const isActive = tab.id === activeTabId;
8068
+ const isDraggingThis = tab.id === draggingId;
8069
+ const isDropTarget = dropTargetId === tab.id;
7978
8070
  return /* @__PURE__ */ jsxRuntime.jsxs(
7979
8071
  "div",
7980
8072
  {
@@ -7982,15 +8074,23 @@ function MultiTabBar(props) {
7982
8074
  if (el) tabRefs.current.set(tab.id, el);
7983
8075
  else tabRefs.current.delete(tab.id);
7984
8076
  },
8077
+ draggable: !!onTabsReorder,
7985
8078
  onClick: () => {
7986
- if (hasDragged.current) return;
7987
8079
  if (!isActive) onTabClick(tab.id);
7988
8080
  },
8081
+ onDragStart: (e) => handleDragStart(e, tab.id),
8082
+ onDragOver: (e) => handleDragOver(e, tab.id),
8083
+ onDrop: (e) => handleDrop(e, tab.id),
8084
+ onDragEnd: handleDragEnd,
7989
8085
  className: `
7990
8086
  group relative flex items-center gap-1.5 ${s.tabPx} ${s.tabPy} flex-shrink-0
7991
- ${s.rounded} border border-b-0 cursor-pointer select-none
8087
+ ${s.rounded} border border-b-0 select-none
7992
8088
  transition-colors duration-100
7993
8089
  ${isActive ? s.activeTab : s.inactiveTab}
8090
+ ${onTabsReorder ? "cursor-grab" : "cursor-pointer"}
8091
+ ${isDraggingThis ? "opacity-40" : ""}
8092
+ ${isDropTarget && dropSide === "before" ? "[box-shadow:inset_2px_0_0_0_#3b82f6]" : ""}
8093
+ ${isDropTarget && dropSide === "after" ? "[box-shadow:inset_-2px_0_0_0_#3b82f6]" : ""}
7994
8094
  `,
7995
8095
  children: [
7996
8096
  isActive && /* @__PURE__ */ jsxRuntime.jsx(
@@ -8030,7 +8130,7 @@ function MultiTabBar(props) {
8030
8130
  })
8031
8131
  }
8032
8132
  ),
8033
- onTabAdd && /* @__PURE__ */ jsxRuntime.jsx(
8133
+ showPlus && /* @__PURE__ */ jsxRuntime.jsx(
8034
8134
  "div",
8035
8135
  {
8036
8136
  className: `flex-shrink-0 flex items-center justify-center ${s.plusBtnArea}`,
@@ -9027,6 +9127,7 @@ function Sidebar(props) {
9027
9127
  footer,
9028
9128
  className,
9029
9129
  showCollapseButton = false,
9130
+ collapseButtonPlacement = "right",
9030
9131
  variant = "light",
9031
9132
  primaryColor
9032
9133
  } = props;
@@ -9113,7 +9214,7 @@ function Sidebar(props) {
9113
9214
  "button",
9114
9215
  {
9115
9216
  onClick: () => setIsCollapsed((prev) => !prev),
9116
- className: `absolute top-4 right-2 z-20 w-6.5 h-6.5 rounded-full flex items-center justify-center transition-colors cursor-pointer ${s.collapseBtn}`,
9217
+ className: `absolute top-4 z-20 w-6.5 h-6.5 rounded-full flex items-center justify-center transition-colors cursor-pointer ${s.collapseBtn} ${collapseButtonPlacement === "left" ? "left-2" : "right-2"}`,
9117
9218
  children: isCollapsed ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PanelRightClose, { size: 18, color: primaryColor ?? s.collapseIcon }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PanelLeftClose, { size: 18, color: primaryColor ?? s.collapseIcon })
9118
9219
  }
9119
9220
  ),
@@ -9533,7 +9634,9 @@ function DetailModalFrame(props) {
9533
9634
  renderExtraContent,
9534
9635
  renderFooterExtra,
9535
9636
  onDirtyChange,
9536
- headerType
9637
+ headerType,
9638
+ headerIconVariant,
9639
+ headerIconSize
9537
9640
  } = props;
9538
9641
  const controller = useDetailController({ mode, onModeChange });
9539
9642
  React6.useEffect(() => {
@@ -9577,7 +9680,9 @@ function DetailModalFrame(props) {
9577
9680
  {
9578
9681
  type: isEditMode ? "edit" : headerType,
9579
9682
  title,
9580
- onClose: handleClose
9683
+ onClose: handleClose,
9684
+ variant: headerIconVariant,
9685
+ size: headerIconSize
9581
9686
  }
9582
9687
  ) : /* @__PURE__ */ jsxRuntime.jsx(ModalHeader, { className: "flex flex-row items-center justify-between", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-base font-semibold text-gray-900", children: title }) }),
9583
9688
  /* @__PURE__ */ jsxRuntime.jsxs(ModalBody, { className: "flex-1 min-h-0 overflow-hidden p-0 flex flex-col", children: [