sellmate-design-system-react 9.0.0-beta.6 → 9.0.0-beta.8

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
@@ -5,7 +5,7 @@ import { forwardRef, useState, useRef, useEffect, createContext, useContext, use
5
5
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
6
  import { createPortal } from 'react-dom';
7
7
  import * as RCheckbox from '@radix-ui/react-checkbox';
8
- import * as RPopover9 from '@radix-ui/react-popover';
8
+ import * as RPopover10 from '@radix-ui/react-popover';
9
9
  import { createRoot } from 'react-dom/client';
10
10
  import * as RTooltip from '@radix-ui/react-tooltip';
11
11
  import * as RDropdown from '@radix-ui/react-dropdown-menu';
@@ -3417,7 +3417,7 @@ var SDraggableItemView = /* @__PURE__ */ forwardRef(
3417
3417
  !disabled && !selected && !dragging && "hover:bg-(--cmp-listDraggableItem-bg-hover)",
3418
3418
  hasSupportingText && supportingTextPosition === "bottom" ? dense ? "min-h-[52px]" : "min-h-[60px]" : dense ? "h-[32px]" : "h-[40px]",
3419
3419
  paddingYClass,
3420
- // 항목 사이 구분선은 리스트가 그린다 — SDraggableList 의 separator (SList.tsx)
3420
+ // 항목 사이 구분선은 리스트가 그린다.
3421
3421
  bordered && cn(
3422
3422
  "rounded-(--cmp-listDraggableItem-radius-bordered) border border-(--cmp-listDraggableItem-border-default)",
3423
3423
  !disabled && !selected && !dragging && "hover:border-(--cmp-listDraggableItem-bordered-border-hover)",
@@ -3625,7 +3625,7 @@ var SDraggableItemImpl = /* @__PURE__ */ forwardRef(function SDraggableItem({
3625
3625
  ] });
3626
3626
  });
3627
3627
  var SDraggableItem2 = /* @__PURE__ */ withDisplayName(SDraggableItemImpl, "SDraggableItem");
3628
- var SListImpl = /* @__PURE__ */ forwardRef(function SList({ className, children, useGap = false, usePadding = false, separator = false, ...rest }, ref) {
3628
+ var SListImpl = /* @__PURE__ */ forwardRef(function SList({ className, children, useGap = false, usePadding = false, ...rest }, ref) {
3629
3629
  return /* @__PURE__ */ jsx(
3630
3630
  "div",
3631
3631
  {
@@ -3633,7 +3633,7 @@ var SListImpl = /* @__PURE__ */ forwardRef(function SList({ className, children,
3633
3633
  className: cn(
3634
3634
  useGap && "flex flex-col gap-(--cmp-list-group-gap)",
3635
3635
  usePadding && "p-(--cmp-list-group-padding)",
3636
- separator && "[&>*]:border-b [&>*]:border-(--cmp-listItem-border-default)",
3636
+ "[&>*]:border-b [&>*]:border-(--cmp-listItem-border-default)",
3637
3637
  className
3638
3638
  ),
3639
3639
  ...rest,
@@ -4005,7 +4005,7 @@ var SExpansionItem = /* @__PURE__ */ forwardRef(
4005
4005
  ref,
4006
4006
  className: cn(
4007
4007
  "group/expansion-item relative overflow-hidden bg-(--cmp-listExpansionItem-title-bg-default)",
4008
- // 항목 사이 구분선은 리스트가 그린다 — SList/SExpansionList 의 separator (SList.tsx)
4008
+ // 항목 사이 구분선은 리스트가 그린다.
4009
4009
  // 보더 색은 시맨틱 토큰(border-default → hover strong → 펼침 accentLight)을 쓴다.
4010
4010
  // TODO: expansionItem/bordered/radius 토큰 생성 후 rounded 고정값도 토큰으로 교체한다.
4011
4011
  bordered && "rounded-[8px] border border-border-default hover:border-border-strong [&:has(>button:hover)]:border-border-strong",
@@ -4557,8 +4557,8 @@ function SGhostButton({
4557
4557
  }
4558
4558
  );
4559
4559
  if (!hasTooltip) return btn;
4560
- return /* @__PURE__ */ jsxs(RPopover9.Root, { open, onOpenChange: setOpen, children: [
4561
- /* @__PURE__ */ jsx(RPopover9.Anchor, { asChild: true, children: /* @__PURE__ */ jsx(
4560
+ return /* @__PURE__ */ jsxs(RPopover10.Root, { open, onOpenChange: setOpen, children: [
4561
+ /* @__PURE__ */ jsx(RPopover10.Anchor, { asChild: true, children: /* @__PURE__ */ jsx(
4562
4562
  "span",
4563
4563
  {
4564
4564
  className: cn("inline-flex", anchorClassName),
@@ -4570,8 +4570,8 @@ function SGhostButton({
4570
4570
  children: btn
4571
4571
  }
4572
4572
  ) }),
4573
- /* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
4574
- RPopover9.Content,
4573
+ /* @__PURE__ */ jsx(RPopover10.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
4574
+ RPopover10.Content,
4575
4575
  {
4576
4576
  side: "top",
4577
4577
  sideOffset: 4,
@@ -4585,6 +4585,18 @@ function SGhostButton({
4585
4585
  ) })
4586
4586
  ] });
4587
4587
  }
4588
+ var TREE_LABEL_TYPOGRAPHY = {
4589
+ sm: {
4590
+ default: "typo-body-sm-medium",
4591
+ selected: "typo-body-sm-bold",
4592
+ rowHeight: "h-[28px]"
4593
+ },
4594
+ md: {
4595
+ default: "typo-body-md-medium",
4596
+ selected: "typo-body-md-bold",
4597
+ rowHeight: "h-[32px]"
4598
+ }
4599
+ };
4588
4600
  function collectIds(nodes) {
4589
4601
  return nodes.flatMap((node) => [node.id, ...collectIds(node.children ?? [])]);
4590
4602
  }
@@ -4617,6 +4629,7 @@ function getSelectionState(node, selectedSet, cascadeSelection) {
4617
4629
  }
4618
4630
  function TreeConnector({
4619
4631
  guideline,
4632
+ size,
4620
4633
  depth,
4621
4634
  hasChildren,
4622
4635
  isLast,
@@ -4624,6 +4637,8 @@ function TreeConnector({
4624
4637
  }) {
4625
4638
  if (depth <= 1) return null;
4626
4639
  const ancestorConnectors = ancestorLast.slice(0, -1);
4640
+ const branchTop = size === "sm" ? "top-[13px]" : "top-[15px]";
4641
+ const nodeHeight = size === "sm" ? "h-[15px]" : "h-[17px]";
4627
4642
  return /* @__PURE__ */ jsxs("span", { "aria-hidden": "true", className: "flex self-stretch", children: [
4628
4643
  ancestorConnectors.map((last, index) => /* @__PURE__ */ jsx(
4629
4644
  "span",
@@ -4637,13 +4652,22 @@ function TreeConnector({
4637
4652
  /* @__PURE__ */ jsxs("span", { className: "relative block w-[20px] shrink-0", children: [
4638
4653
  guideline && !isLast && /* @__PURE__ */ jsx("span", { className: "absolute bottom-0 left-[6px] top-[-1px] w-px bg-(--cmp-tree-connector-line-color)" }),
4639
4654
  guideline && /* @__PURE__ */ jsxs(Fragment, { children: [
4640
- /* @__PURE__ */ jsx("span", { className: "absolute left-[6px] top-[-1px] h-[17px] w-px bg-(--cmp-tree-connector-line-color)" }),
4655
+ /* @__PURE__ */ jsx(
4656
+ "span",
4657
+ {
4658
+ className: cn(
4659
+ "absolute left-[6px] top-[-1px] w-px bg-(--cmp-tree-connector-line-color)",
4660
+ nodeHeight
4661
+ )
4662
+ }
4663
+ ),
4641
4664
  /* @__PURE__ */ jsx(
4642
4665
  "span",
4643
4666
  {
4644
4667
  "data-tree-connector-branch": hasChildren ? "parent" : "leaf",
4645
4668
  className: cn(
4646
- "absolute left-[6px] top-[15px] h-px bg-(--cmp-tree-connector-line-color)",
4669
+ "absolute left-[6px] h-px bg-(--cmp-tree-connector-line-color)",
4670
+ branchTop,
4647
4671
  hasChildren ? "w-[14px]" : "w-[calc(14px+var(--cmp-tree-item-arrow-icon))]"
4648
4672
  )
4649
4673
  }
@@ -4656,9 +4680,12 @@ function STreeAllItem({
4656
4680
  selected,
4657
4681
  indeterminate,
4658
4682
  border,
4683
+ size,
4659
4684
  onSelect
4660
4685
  }) {
4661
4686
  const checkboxValue = indeterminate ? null : selected;
4687
+ const typography = TREE_LABEL_TYPOGRAPHY[size];
4688
+ const labelTypo = selected || indeterminate ? typography.selected : typography.default;
4662
4689
  return /* @__PURE__ */ jsx(
4663
4690
  "div",
4664
4691
  {
@@ -4667,17 +4694,18 @@ function STreeAllItem({
4667
4694
  "aria-selected": selected,
4668
4695
  onClick: onSelect,
4669
4696
  className: cn(
4670
- "group/tree-item box-border flex h-[32px] w-full cursor-pointer items-center overflow-hidden bg-(--cmp-tree-item-bg-default) px-(--cmp-tree-item-paddingX) text-left hover:bg-(--cmp-tree-item-bg-hover)",
4697
+ "group/tree-item box-border flex w-full cursor-pointer items-center overflow-hidden bg-(--cmp-tree-item-bg-default) px-(--cmp-tree-item-paddingX) text-left hover:bg-(--cmp-tree-item-bg-hover)",
4698
+ typography.rowHeight,
4671
4699
  border && "border-b border-(--cmp-tree-item-border-default)"
4672
4700
  ),
4673
- children: /* @__PURE__ */ jsxs("div", { className: "box-border flex h-full min-w-0 flex-1 items-center gap-(--cmp-tree-item-contentGap) py-(--cmp-tree-item-paddingY)", children: [
4701
+ children: /* @__PURE__ */ jsxs("div", { className: "box-border flex min-w-0 flex-1 items-center gap-(--cmp-tree-item-contentGap)", children: [
4674
4702
  /* @__PURE__ */ jsx("span", { onClick: (event) => event.stopPropagation(), className: "flex shrink-0", children: /* @__PURE__ */ jsx(SCheckbox, { value: checkboxValue, onValueChange: () => onSelect() }) }),
4675
4703
  /* @__PURE__ */ jsx(
4676
4704
  "span",
4677
4705
  {
4678
4706
  className: cn(
4679
- "block min-w-0 flex-1 truncate text-[14px] leading-[24px]",
4680
- selected || indeterminate ? "font-bold text-(--cmp-tree-item-text-selected)" : "font-medium text-(--cmp-tree-item-text-default)"
4707
+ "block min-w-0 flex-1 truncate py-(--cmp-tree-item-paddingY) text-(--cmp-tree-item-text-default)",
4708
+ labelTypo
4681
4709
  ),
4682
4710
  children: "\uC804\uCCB4"
4683
4711
  }
@@ -4697,6 +4725,7 @@ var STreeItemImpl = /* @__PURE__ */ forwardRef(function STreeItem({
4697
4725
  border = true,
4698
4726
  indeterminate = false,
4699
4727
  selectable = true,
4728
+ size = "sm",
4700
4729
  leading,
4701
4730
  trailing,
4702
4731
  onToggle,
@@ -4708,6 +4737,7 @@ var STreeItemImpl = /* @__PURE__ */ forwardRef(function STreeItem({
4708
4737
  const renderState = {
4709
4738
  node,
4710
4739
  depth,
4740
+ size,
4711
4741
  expanded,
4712
4742
  selected,
4713
4743
  indeterminate,
@@ -4717,6 +4747,8 @@ var STreeItemImpl = /* @__PURE__ */ forwardRef(function STreeItem({
4717
4747
  const leadingNode = typeof leading === "function" ? leading(renderState) : leading;
4718
4748
  const trailingNode = typeof trailing === "function" ? trailing(renderState) : trailing;
4719
4749
  const checkboxValue = indeterminate ? null : selected;
4750
+ const typography = TREE_LABEL_TYPOGRAPHY[size];
4751
+ const labelTypo = selected || indeterminate ? typography.selected : typography.default;
4720
4752
  const handleSelect = (event) => {
4721
4753
  if (node.disabled) return;
4722
4754
  onTreeSelect?.(node, event);
@@ -4736,7 +4768,8 @@ var STreeItemImpl = /* @__PURE__ */ forwardRef(function STreeItem({
4736
4768
  "aria-disabled": node.disabled || void 0,
4737
4769
  onClick: handleRowClick,
4738
4770
  className: cn(
4739
- "group/tree-item box-border flex h-[32px] w-full items-center gap-(--cmp-tree-item-rowGap) overflow-hidden bg-(--cmp-tree-item-bg-default) px-(--cmp-tree-item-paddingX) text-left",
4771
+ "group/tree-item box-border flex w-full items-center gap-(--cmp-tree-item-rowGap) overflow-hidden bg-(--cmp-tree-item-bg-default) px-(--cmp-tree-item-paddingX) text-left",
4772
+ typography.rowHeight,
4740
4773
  border && "border-b border-(--cmp-tree-item-border-default)",
4741
4774
  !node.disabled && "hover:bg-(--cmp-tree-item-bg-hover)",
4742
4775
  node.disabled && "cursor-not-allowed opacity-60",
@@ -4749,13 +4782,14 @@ var STreeItemImpl = /* @__PURE__ */ forwardRef(function STreeItem({
4749
4782
  TreeConnector,
4750
4783
  {
4751
4784
  guideline,
4785
+ size,
4752
4786
  depth,
4753
4787
  hasChildren,
4754
4788
  isLast,
4755
4789
  ancestorLast
4756
4790
  }
4757
4791
  ),
4758
- /* @__PURE__ */ jsxs("div", { className: "box-border flex h-full min-w-0 flex-1 items-center gap-(--cmp-tree-item-contentGap) py-(--cmp-tree-item-paddingY)", children: [
4792
+ /* @__PURE__ */ jsxs("div", { className: "box-border flex min-w-0 flex-1 items-center gap-(--cmp-tree-item-contentGap)", children: [
4759
4793
  hasChildren ? /* @__PURE__ */ jsx(
4760
4794
  SGhostButton,
4761
4795
  {
@@ -4797,8 +4831,8 @@ var STreeItemImpl = /* @__PURE__ */ forwardRef(function STreeItem({
4797
4831
  if (!node.disabled && selectable) onTreeSelect?.(node, event);
4798
4832
  },
4799
4833
  className: cn(
4800
- "block min-w-0 flex-1 truncate text-[14px] leading-[24px]",
4801
- selected || indeterminate ? "font-bold text-(--cmp-tree-item-text-selected)" : "font-medium text-(--cmp-tree-item-text-default)",
4834
+ "block min-w-0 flex-1 truncate py-(--cmp-tree-item-paddingY) text-(--cmp-tree-item-text-default)",
4835
+ labelTypo,
4802
4836
  node.disabled ? "cursor-not-allowed" : selectable ? "cursor-pointer" : void 0
4803
4837
  ),
4804
4838
  children: node.label
@@ -4818,6 +4852,7 @@ var STreeImpl = /* @__PURE__ */ forwardRef(function STree({
4818
4852
  expandedIds,
4819
4853
  defaultExpandedIds,
4820
4854
  selectable = true,
4855
+ size = "sm",
4821
4856
  useAll = false,
4822
4857
  cascadeSelection = true,
4823
4858
  guideline = true,
@@ -4891,6 +4926,7 @@ var STreeImpl = /* @__PURE__ */ forwardRef(function STree({
4891
4926
  selected,
4892
4927
  indeterminate,
4893
4928
  selectable,
4929
+ size,
4894
4930
  guideline,
4895
4931
  border,
4896
4932
  leading,
@@ -4926,6 +4962,7 @@ var STreeImpl = /* @__PURE__ */ forwardRef(function STree({
4926
4962
  selected: allSelected,
4927
4963
  indeterminate: allIndeterminate,
4928
4964
  border,
4965
+ size,
4929
4966
  onSelect: updateAllSelected
4930
4967
  }
4931
4968
  ),
@@ -5110,14 +5147,14 @@ var STooltipImpl = /* @__PURE__ */ forwardRef(function STooltip({
5110
5147
  ...style,
5111
5148
  ...contentPropsStyle
5112
5149
  };
5113
- return /* @__PURE__ */ jsxs(RPopover9.Root, { open, onOpenChange: setOpenState, children: [
5150
+ return /* @__PURE__ */ jsxs(RPopover10.Root, { open, onOpenChange: setOpenState, children: [
5114
5151
  isNone ? (
5115
5152
  // 트리거 없음: children 을 래퍼 없이 그대로 앵커로 쓴다 (소비자 레이아웃 보존).
5116
5153
  // mouse/focus 핸들러가 없으므로 useClose 없이도 자동 닫힘이 발생하지 않는다.
5117
- /* @__PURE__ */ jsx(RPopover9.Anchor, { asChild: true, children: triggerNode })
5154
+ /* @__PURE__ */ jsx(RPopover10.Anchor, { asChild: true, children: triggerNode })
5118
5155
  ) : isHover ? (
5119
5156
  // hover: Anchor(위치 기준) + 직접 mouse 핸들러 — 클릭으로 토글되지 않도록 Trigger 미사용
5120
- /* @__PURE__ */ jsx(RPopover9.Anchor, { asChild: true, children: /* @__PURE__ */ jsx(
5157
+ /* @__PURE__ */ jsx(RPopover10.Anchor, { asChild: true, children: /* @__PURE__ */ jsx(
5121
5158
  "span",
5122
5159
  {
5123
5160
  className: "inline-flex",
@@ -5128,9 +5165,9 @@ var STooltipImpl = /* @__PURE__ */ forwardRef(function STooltip({
5128
5165
  children: triggerNode
5129
5166
  }
5130
5167
  ) })
5131
- ) : /* @__PURE__ */ jsx(RPopover9.Trigger, { asChild: true, children: triggerNode }),
5132
- /* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxs(
5133
- RPopover9.Content,
5168
+ ) : /* @__PURE__ */ jsx(RPopover10.Trigger, { asChild: true, children: triggerNode }),
5169
+ /* @__PURE__ */ jsx(RPopover10.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxs(
5170
+ RPopover10.Content,
5134
5171
  {
5135
5172
  side: placement,
5136
5173
  sideOffset,
@@ -5164,7 +5201,7 @@ var STooltipImpl = /* @__PURE__ */ forwardRef(function STooltip({
5164
5201
  }
5165
5202
  )
5166
5203
  ] }),
5167
- /* @__PURE__ */ jsx(RPopover9.Arrow, { width: 16, height: 12, style: { fill: bg } })
5204
+ /* @__PURE__ */ jsx(RPopover10.Arrow, { width: 16, height: 12, style: { fill: bg } })
5168
5205
  ]
5169
5206
  }
5170
5207
  ) })
@@ -6451,10 +6488,10 @@ function SPopover({
6451
6488
  const descColor = type === "default" ? "var(--cmp-popover-default-description)" : "var(--cmp-popover-light-description)";
6452
6489
  const leftLinkLabelClass = type === "default" ? "text-[color:var(--cmp-popover-default-subAction)]" : "text-[color:var(--cmp-popover-light-subAction)]";
6453
6490
  const triggerNode = trigger ?? /* @__PURE__ */ jsx("span", { className: "inline-flex cursor-pointer", "aria-label": ariaLabel, children: /* @__PURE__ */ jsx(SIcon, { name: icon, size: iconSize, color }) });
6454
- return /* @__PURE__ */ jsxs(RPopover9.Root, { open: actualOpen, onOpenChange: setOpen, children: [
6455
- /* @__PURE__ */ jsx(RPopover9.Trigger, { asChild: true, children: triggerNode }),
6456
- /* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxs(
6457
- RPopover9.Content,
6491
+ return /* @__PURE__ */ jsxs(RPopover10.Root, { open: actualOpen, onOpenChange: setOpen, children: [
6492
+ /* @__PURE__ */ jsx(RPopover10.Trigger, { asChild: true, children: triggerNode }),
6493
+ /* @__PURE__ */ jsx(RPopover10.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxs(
6494
+ RPopover10.Content,
6458
6495
  {
6459
6496
  side: placement,
6460
6497
  sideOffset: 8,
@@ -6520,7 +6557,7 @@ function SPopover({
6520
6557
  ]
6521
6558
  }
6522
6559
  ),
6523
- /* @__PURE__ */ jsx(RPopover9.Arrow, { width: 16, height: 12, style: { fill: bg } })
6560
+ /* @__PURE__ */ jsx(RPopover10.Arrow, { width: 16, height: 12, style: { fill: bg } })
6524
6561
  ]
6525
6562
  }
6526
6563
  ) })
@@ -6551,7 +6588,7 @@ function SPortal({
6551
6588
  const portalContainer = usePortalContainer();
6552
6589
  const { minWidth: styleMinWidth, maxWidth: styleMaxWidth, ...restStyle } = style ?? {};
6553
6590
  return /* @__PURE__ */ jsxs(
6554
- RPopover9.Root,
6591
+ RPopover10.Root,
6555
6592
  {
6556
6593
  open,
6557
6594
  onOpenChange: (next) => {
@@ -6559,9 +6596,9 @@ function SPortal({
6559
6596
  if (!next) onClose?.();
6560
6597
  },
6561
6598
  children: [
6562
- /* @__PURE__ */ jsx(RPopover9.Anchor, { virtualRef: anchorRef }),
6563
- /* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
6564
- RPopover9.Content,
6599
+ /* @__PURE__ */ jsx(RPopover10.Anchor, { virtualRef: anchorRef }),
6600
+ /* @__PURE__ */ jsx(RPopover10.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
6601
+ RPopover10.Content,
6565
6602
  {
6566
6603
  side: placement,
6567
6604
  align,
@@ -6759,10 +6796,10 @@ function SGuide({
6759
6796
  );
6760
6797
  if (isNotion)
6761
6798
  return /* @__PURE__ */ jsx("span", { className, style, children: trigger });
6762
- return /* @__PURE__ */ jsxs(RPopover9.Root, { open, onOpenChange: setOpen, children: [
6763
- /* @__PURE__ */ jsx(RPopover9.Trigger, { asChild: true, children: trigger }),
6764
- /* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxs(
6765
- RPopover9.Content,
6799
+ return /* @__PURE__ */ jsxs(RPopover10.Root, { open, onOpenChange: setOpen, children: [
6800
+ /* @__PURE__ */ jsx(RPopover10.Trigger, { asChild: true, children: trigger }),
6801
+ /* @__PURE__ */ jsx(RPopover10.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxs(
6802
+ RPopover10.Content,
6766
6803
  {
6767
6804
  side: "bottom",
6768
6805
  align: "start",
@@ -8843,10 +8880,10 @@ var SGnb = /* @__PURE__ */ forwardRef(function SGnb2({
8843
8880
  }
8844
8881
  ),
8845
8882
  header === "fix" && menuResizeHandle,
8846
- /* @__PURE__ */ jsxs(RPopover9.Root, { open: labelTip !== null, onOpenChange: (open) => !open && setLabelTip(null), children: [
8847
- /* @__PURE__ */ jsx(RPopover9.Anchor, { virtualRef: labelTipAnchorRef }),
8848
- /* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
8849
- RPopover9.Content,
8883
+ /* @__PURE__ */ jsxs(RPopover10.Root, { open: labelTip !== null, onOpenChange: (open) => !open && setLabelTip(null), children: [
8884
+ /* @__PURE__ */ jsx(RPopover10.Anchor, { virtualRef: labelTipAnchorRef }),
8885
+ /* @__PURE__ */ jsx(RPopover10.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
8886
+ RPopover10.Content,
8850
8887
  {
8851
8888
  side: "right",
8852
8889
  sideOffset: 4,
@@ -8917,13 +8954,155 @@ var SPageHeader = /* @__PURE__ */ withDisplayName(
8917
8954
  );
8918
8955
  var MIN_CONTENT_WIDTH = `calc(var(${SLAYOUT_MIN_WIDTH_VAR}, 0px) - 100cqw + 100%)`;
8919
8956
  var BACKGROUND_CLASS = {
8920
- frame: `bg-[var(--sys-color-bg-frame)] ${SCROLLBAR_TRACK_BORDER_CLASS} ${SCROLLBAR_TRACK_BG_CLASS}`,
8921
- neutral: `bg-[var(--sys-color-bg-neutralLight)] ${SCROLLBAR_TRACK_BORDER_CLASS} ${SCROLLBAR_TRACK_BG_WHITE_CLASS}`,
8922
- screen: `bg-[var(--sys-color-bg-screen)] ${SCROLLBAR_TRACK_BORDER_CLASS} ${SCROLLBAR_TRACK_BG_CLASS}`
8957
+ frame: "bg-[var(--sys-color-bg-frame)]",
8958
+ neutral: "bg-[var(--sys-color-bg-neutralLight)]",
8959
+ screen: "bg-[var(--sys-color-bg-screen)]"
8960
+ };
8961
+ var NATIVE_SCROLLBAR_BACKGROUND_CLASS = {
8962
+ frame: `${SCROLLBAR_TRACK_BORDER_CLASS} ${SCROLLBAR_TRACK_BG_CLASS}`,
8963
+ neutral: `${SCROLLBAR_TRACK_BORDER_CLASS} ${SCROLLBAR_TRACK_BG_WHITE_CLASS}`,
8964
+ screen: `${SCROLLBAR_TRACK_BORDER_CLASS} ${SCROLLBAR_TRACK_BG_CLASS}`
8923
8965
  };
8966
+ var SCROLLBAR_SIZE = 12;
8967
+ var SCROLLBAR_MIN_THUMB_SIZE = 32;
8968
+ var getMetrics = (viewportSize, contentSize, scrollOffset) => {
8969
+ if (contentSize <= viewportSize) {
8970
+ return { visible: false, thumbSize: 0, thumbOffset: 0 };
8971
+ }
8972
+ const trackSize = viewportSize;
8973
+ const maxScrollOffset = contentSize - viewportSize;
8974
+ const thumbSize = Math.min(
8975
+ trackSize,
8976
+ Math.max(SCROLLBAR_MIN_THUMB_SIZE, viewportSize / contentSize * trackSize)
8977
+ );
8978
+ const maxThumbOffset = trackSize - thumbSize;
8979
+ const thumbOffset = maxScrollOffset > 0 ? scrollOffset / maxScrollOffset * maxThumbOffset : 0;
8980
+ return { visible: true, thumbSize, thumbOffset };
8981
+ };
8982
+ var setForwardedRef = (ref, node) => {
8983
+ if (typeof ref === "function") {
8984
+ ref(node);
8985
+ return;
8986
+ }
8987
+ if (ref) ref.current = node;
8988
+ };
8989
+ function SPageOverlayScrollbars({ scrollRef }) {
8990
+ const [vertical, setVertical] = useState({
8991
+ visible: false,
8992
+ thumbSize: 0,
8993
+ thumbOffset: 0
8994
+ });
8995
+ const [horizontal, setHorizontal] = useState({
8996
+ visible: false,
8997
+ thumbSize: 0,
8998
+ thumbOffset: 0
8999
+ });
9000
+ const update = useCallback(() => {
9001
+ const el = scrollRef.current;
9002
+ if (!el) return;
9003
+ setVertical(getMetrics(el.clientHeight, el.scrollHeight, el.scrollTop));
9004
+ setHorizontal(getMetrics(el.clientWidth, el.scrollWidth, el.scrollLeft));
9005
+ }, [scrollRef]);
9006
+ useEffect(() => {
9007
+ const el = scrollRef.current;
9008
+ if (!el) return;
9009
+ update();
9010
+ el.addEventListener("scroll", update, { passive: true });
9011
+ const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(update);
9012
+ observer?.observe(el);
9013
+ if (el.firstElementChild) observer?.observe(el.firstElementChild);
9014
+ return () => {
9015
+ el.removeEventListener("scroll", update);
9016
+ observer?.disconnect();
9017
+ };
9018
+ }, [scrollRef, update]);
9019
+ const dragVertical = (startEvent) => {
9020
+ const el = scrollRef.current;
9021
+ if (!el || !vertical.visible) return;
9022
+ startEvent.preventDefault();
9023
+ startEvent.currentTarget.setPointerCapture(startEvent.pointerId);
9024
+ const startPointer = startEvent.clientY;
9025
+ const startScrollTop = el.scrollTop;
9026
+ const maxThumbOffset = el.clientHeight - vertical.thumbSize;
9027
+ const maxScrollTop = el.scrollHeight - el.clientHeight;
9028
+ if (maxThumbOffset <= 0 || maxScrollTop <= 0) return;
9029
+ const onPointerMove = (moveEvent) => {
9030
+ const delta = moveEvent.clientY - startPointer;
9031
+ el.scrollTop = startScrollTop + delta / maxThumbOffset * maxScrollTop;
9032
+ };
9033
+ const onPointerUp = () => {
9034
+ window.removeEventListener("pointermove", onPointerMove);
9035
+ window.removeEventListener("pointerup", onPointerUp);
9036
+ };
9037
+ window.addEventListener("pointermove", onPointerMove);
9038
+ window.addEventListener("pointerup", onPointerUp, { once: true });
9039
+ };
9040
+ const dragHorizontal = (startEvent) => {
9041
+ const el = scrollRef.current;
9042
+ if (!el || !horizontal.visible) return;
9043
+ startEvent.preventDefault();
9044
+ startEvent.currentTarget.setPointerCapture(startEvent.pointerId);
9045
+ const startPointer = startEvent.clientX;
9046
+ const startScrollLeft = el.scrollLeft;
9047
+ const maxThumbOffset = el.clientWidth - horizontal.thumbSize;
9048
+ const maxScrollLeft = el.scrollWidth - el.clientWidth;
9049
+ if (maxThumbOffset <= 0 || maxScrollLeft <= 0) return;
9050
+ const onPointerMove = (moveEvent) => {
9051
+ const delta = moveEvent.clientX - startPointer;
9052
+ el.scrollLeft = startScrollLeft + delta / maxThumbOffset * maxScrollLeft;
9053
+ };
9054
+ const onPointerUp = () => {
9055
+ window.removeEventListener("pointermove", onPointerMove);
9056
+ window.removeEventListener("pointerup", onPointerUp);
9057
+ };
9058
+ window.addEventListener("pointermove", onPointerMove);
9059
+ window.addEventListener("pointerup", onPointerUp, { once: true });
9060
+ };
9061
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
9062
+ vertical.visible && /* @__PURE__ */ jsx(
9063
+ "div",
9064
+ {
9065
+ "aria-hidden": "true",
9066
+ className: "pointer-events-none absolute bottom-0 right-0 top-0 z-[1] w-[12px]",
9067
+ style: { bottom: horizontal.visible ? SCROLLBAR_SIZE : 0 },
9068
+ children: /* @__PURE__ */ jsx(
9069
+ "div",
9070
+ {
9071
+ className: "pointer-events-auto absolute right-[2px] w-[8px] cursor-default touch-none rounded-full bg-[var(--color-grey-45)]",
9072
+ style: {
9073
+ height: vertical.thumbSize,
9074
+ transform: `translateY(${vertical.thumbOffset}px)`
9075
+ },
9076
+ onPointerDown: dragVertical
9077
+ }
9078
+ )
9079
+ }
9080
+ ),
9081
+ horizontal.visible && /* @__PURE__ */ jsx(
9082
+ "div",
9083
+ {
9084
+ "aria-hidden": "true",
9085
+ className: "pointer-events-none absolute bottom-0 left-0 right-0 z-[1] h-[12px]",
9086
+ style: { right: vertical.visible ? SCROLLBAR_SIZE : 0 },
9087
+ children: /* @__PURE__ */ jsx(
9088
+ "div",
9089
+ {
9090
+ className: "pointer-events-auto absolute bottom-[2px] h-[8px] cursor-default touch-none rounded-full bg-[var(--color-grey-45)]",
9091
+ style: {
9092
+ width: horizontal.thumbSize,
9093
+ transform: `translateX(${horizontal.thumbOffset}px)`
9094
+ },
9095
+ onPointerDown: dragHorizontal
9096
+ }
9097
+ )
9098
+ }
9099
+ )
9100
+ ] });
9101
+ }
8924
9102
  var SPage = /* @__PURE__ */ forwardRef(function SPage2({
8925
9103
  background = "frame",
8926
9104
  scrollEndSpacing = true,
9105
+ overlayScrollbar = false,
8927
9106
  contentHeight = "auto",
8928
9107
  header,
8929
9108
  className,
@@ -8934,6 +9113,14 @@ var SPage = /* @__PURE__ */ forwardRef(function SPage2({
8934
9113
  }, ref) {
8935
9114
  const layout = useContext(SLayoutContext);
8936
9115
  const gridStyle = layout?.header === "full" ? { gridArea: "page" } : void 0;
9116
+ const scrollRef = useRef(null);
9117
+ const setMainRef = useCallback(
9118
+ (node) => {
9119
+ scrollRef.current = node;
9120
+ setForwardedRef(ref, node);
9121
+ },
9122
+ [ref]
9123
+ );
8937
9124
  const [scrolled, setScrolled] = useState(false);
8938
9125
  const handleScroll = (e) => {
8939
9126
  onScroll?.(e);
@@ -8943,21 +9130,54 @@ var SPage = /* @__PURE__ */ forwardRef(function SPage2({
8943
9130
  const main = /* @__PURE__ */ jsx(
8944
9131
  "main",
8945
9132
  {
8946
- ref,
9133
+ ref: setMainRef,
8947
9134
  className: cn(
8948
9135
  "box-border min-h-0 min-w-0 flex-1 overflow-auto p-[var(--cmp-pageBody-padding-default)]",
9136
+ overlayScrollbar && "h-full",
8949
9137
  !fill && scrollEndSpacing && "pb-[var(--cmp-pageBody-padding-scrollEnd)]",
8950
- SCROLLBAR_CLASS,
9138
+ overlayScrollbar ? SCROLLBAR_HIDDEN_CLASS : `${SCROLLBAR_CLASS} ${NATIVE_SCROLLBAR_BACKGROUND_CLASS[background]}`,
8951
9139
  BACKGROUND_CLASS[background],
8952
9140
  className
8953
9141
  ),
8954
- style: header == null ? { ...gridStyle, ...style } : style,
9142
+ style: header == null && !overlayScrollbar ? { ...gridStyle, ...style } : style,
8955
9143
  onScroll: handleScroll,
8956
9144
  ...rest,
8957
9145
  children: /* @__PURE__ */ jsx("div", { className: cn(fill && "h-full"), style: { minWidth: MIN_CONTENT_WIDTH }, children })
8958
9146
  }
8959
9147
  );
8960
- if (header == null) return main;
9148
+ if (!overlayScrollbar) {
9149
+ if (header == null) return main;
9150
+ return (
9151
+ // fix 가 아닌 헤더는 자기 배경이 투명이라(SPageHeader.tsx) 이 배경이 그대로 비친다.
9152
+ /* @__PURE__ */ jsxs(
9153
+ "div",
9154
+ {
9155
+ className: cn("flex min-h-0 min-w-0 flex-1 flex-col", BACKGROUND_CLASS[background]),
9156
+ style: gridStyle,
9157
+ children: [
9158
+ /* @__PURE__ */ jsx(SPageHeader, { ...header, scrolled }),
9159
+ main
9160
+ ]
9161
+ }
9162
+ )
9163
+ );
9164
+ }
9165
+ if (header == null) {
9166
+ return /* @__PURE__ */ jsxs(
9167
+ "div",
9168
+ {
9169
+ className: cn(
9170
+ "relative min-h-0 min-w-0 flex-1 overflow-hidden",
9171
+ BACKGROUND_CLASS[background]
9172
+ ),
9173
+ style: gridStyle,
9174
+ children: [
9175
+ main,
9176
+ /* @__PURE__ */ jsx(SPageOverlayScrollbars, { scrollRef })
9177
+ ]
9178
+ }
9179
+ );
9180
+ }
8961
9181
  return (
8962
9182
  // fix 가 아닌 헤더는 자기 배경이 투명이라(SPageHeader.tsx) 이 배경이 그대로 비친다 —
8963
9183
  // 그래서 SPage 의 background 를 main 뿐 아니라 여기에도 칠한다(스크롤바 관련 클래스는
@@ -8969,7 +9189,10 @@ var SPage = /* @__PURE__ */ forwardRef(function SPage2({
8969
9189
  style: gridStyle,
8970
9190
  children: [
8971
9191
  /* @__PURE__ */ jsx(SPageHeader, { ...header, scrolled }),
8972
- main
9192
+ /* @__PURE__ */ jsxs("div", { className: "relative min-h-0 min-w-0 flex-1 overflow-hidden", children: [
9193
+ main,
9194
+ /* @__PURE__ */ jsx(SPageOverlayScrollbars, { scrollRef })
9195
+ ] })
8973
9196
  ]
8974
9197
  }
8975
9198
  )
@@ -8981,10 +9204,7 @@ var PAGE_BACKGROUNDS = ["frame", "neutral", "screen"];
8981
9204
  var PAGE_CONTENT_HEIGHTS = ["auto", "fill"];
8982
9205
 
8983
9206
  // src/components/STabs/tabs.config.ts
8984
- var TAB_MAIN_SIZE = {
8985
- md: { height: 36, paddingX: 24 },
8986
- lg: { height: 44, paddingX: 32 }
8987
- };
9207
+ var TAB_MAIN_SIZE = { height: 36, paddingX: 24 };
8988
9208
  var TAB_TYPOGRAPHY = { fontSize: 12, lineHeight: 20 };
8989
9209
  var TAB_MAIN_COLORS = {
8990
9210
  selected: {
@@ -9006,13 +9226,11 @@ function STabs({
9006
9226
  value,
9007
9227
  tabs,
9008
9228
  onValueChange,
9009
- size = "md",
9010
9229
  isSub = false,
9011
9230
  vertical = false,
9012
9231
  className,
9013
9232
  style
9014
9233
  }) {
9015
- const s = TAB_MAIN_SIZE[size];
9016
9234
  const blue = TAB_MAIN_COLORS.selected.border;
9017
9235
  const isVertical = isSub && vertical;
9018
9236
  const tabRefs = useRef([]);
@@ -9053,8 +9271,8 @@ function STabs({
9053
9271
  const border = selected ? TAB_MAIN_COLORS.selected.border : TAB_MAIN_COLORS.default.border;
9054
9272
  const selectedBg = TAB_MAIN_COLORS.selected.bg;
9055
9273
  tabStyle = {
9056
- height: s.height,
9057
- padding: `0 ${s.paddingX}px`,
9274
+ height: TAB_MAIN_SIZE.height,
9275
+ padding: `0 ${TAB_MAIN_SIZE.paddingX}px`,
9058
9276
  fontSize: TAB_TYPOGRAPHY.fontSize,
9059
9277
  lineHeight: `${TAB_TYPOGRAPHY.lineHeight}px`,
9060
9278
  background: selected ? TAB_MAIN_COLORS.selected.bg : TAB_MAIN_COLORS.default.bg,
@@ -11276,6 +11494,67 @@ var STableBar = /* @__PURE__ */ forwardRef(function STableBar2({ total, selected
11276
11494
 
11277
11495
  // src/lib/autofill.ts
11278
11496
  var AUTOFILL_RESET_CLASS = "autofill:[-webkit-text-fill-color:currentColor] autofill:[box-shadow:0_0_0_1000px_var(--sys-color-field-bg-default)_inset] autofill:[transition:background-color_5000s_ease-in-out_0s] [&:-webkit-autofill]:[-webkit-text-fill-color:currentColor] [&:-webkit-autofill]:[box-shadow:0_0_0_1000px_var(--sys-color-field-bg-default)_inset] [&:-webkit-autofill]:[transition:background-color_5000s_ease-in-out_0s]";
11497
+ var HIDE_DELAY_MS2 = 100;
11498
+ function mergeRefs(...refs) {
11499
+ return (node) => {
11500
+ for (const ref of refs) {
11501
+ if (!ref) continue;
11502
+ if (typeof ref === "function") ref(node);
11503
+ else ref.current = node;
11504
+ }
11505
+ };
11506
+ }
11507
+ function useTruncatedValueTooltip({
11508
+ enabled,
11509
+ text
11510
+ }) {
11511
+ const portalContainer = usePortalContainer();
11512
+ const elRef = useRef(null);
11513
+ const [open, setOpen] = useState(false);
11514
+ const hideTimer = useRef(void 0);
11515
+ const cancelHide = useCallback(() => {
11516
+ if (hideTimer.current) {
11517
+ clearTimeout(hideTimer.current);
11518
+ hideTimer.current = void 0;
11519
+ }
11520
+ }, []);
11521
+ const startHide = useCallback(() => {
11522
+ cancelHide();
11523
+ hideTimer.current = setTimeout(() => setOpen(false), HIDE_DELAY_MS2);
11524
+ }, [cancelHide]);
11525
+ const onMouseEnter = useCallback(() => {
11526
+ cancelHide();
11527
+ const el = elRef.current;
11528
+ if (!el) return;
11529
+ if (el.scrollWidth - el.clientWidth > 1) setOpen(true);
11530
+ }, [cancelHide]);
11531
+ useEffect(() => {
11532
+ if (!enabled || text === "") setOpen(false);
11533
+ }, [enabled, text]);
11534
+ useEffect(() => cancelHide, [cancelHide]);
11535
+ const active = enabled && text !== "";
11536
+ return {
11537
+ valueRef: elRef,
11538
+ onMouseEnter: active ? onMouseEnter : cancelHide,
11539
+ onMouseLeave: active ? startHide : cancelHide,
11540
+ tooltip: active ? /* @__PURE__ */ jsxs(RPopover10.Root, { open, onOpenChange: setOpen, children: [
11541
+ /* @__PURE__ */ jsx(RPopover10.Anchor, { virtualRef: elRef }),
11542
+ /* @__PURE__ */ jsx(RPopover10.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
11543
+ RPopover10.Content,
11544
+ {
11545
+ side: "top",
11546
+ sideOffset: 4,
11547
+ "aria-hidden": true,
11548
+ className: cn("z-50", FLOATING_SLIDE_ANIM),
11549
+ onOpenAutoFocus: (e) => e.preventDefault(),
11550
+ onMouseEnter: cancelHide,
11551
+ onMouseLeave: startHide,
11552
+ children: /* @__PURE__ */ jsx(STag, { shape: "square", size: "xs", color: "grey", label: text })
11553
+ }
11554
+ ) })
11555
+ ] }) : null
11556
+ };
11557
+ }
11279
11558
  var FONT = {
11280
11559
  sm: { fontSize: 12, lineHeight: 20, paddingX: "var(--cmp-textinput-sm-paddingX)" },
11281
11560
  md: { fontSize: 14, lineHeight: 24, paddingX: "var(--cmp-textinput-md-paddingX)" }
@@ -11333,6 +11612,10 @@ var SInput = /* @__PURE__ */ forwardRef(function SInput2({
11333
11612
  const resolvedError = error || ruleError !== "";
11334
11613
  const resolvedErrorMessage = ruleError !== "" ? ruleError : errorMessage;
11335
11614
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
11615
+ const valueTooltip = useTruncatedValueTooltip({
11616
+ enabled: readOnly && !disabled,
11617
+ text: String(value ?? "")
11618
+ });
11336
11619
  return /* @__PURE__ */ jsx(
11337
11620
  SField,
11338
11621
  {
@@ -11373,7 +11656,7 @@ var SInput = /* @__PURE__ */ forwardRef(function SInput2({
11373
11656
  /* @__PURE__ */ jsx(
11374
11657
  "input",
11375
11658
  {
11376
- ref,
11659
+ ref: mergeRefs(ref, valueTooltip.valueRef),
11377
11660
  type: inputType,
11378
11661
  value: value ?? "",
11379
11662
  disabled,
@@ -11398,9 +11681,18 @@ var SInput = /* @__PURE__ */ forwardRef(function SInput2({
11398
11681
  color: disabled ? "var(--cmp-textinput-text-disabled)" : "var(--sys-color-field-text-default)",
11399
11682
  ...inputStyle
11400
11683
  },
11401
- ...rest
11684
+ ...rest,
11685
+ onMouseEnter: (e) => {
11686
+ rest.onMouseEnter?.(e);
11687
+ valueTooltip.onMouseEnter();
11688
+ },
11689
+ onMouseLeave: (e) => {
11690
+ rest.onMouseLeave?.(e);
11691
+ valueTooltip.onMouseLeave();
11692
+ }
11402
11693
  }
11403
11694
  ),
11695
+ valueTooltip.tooltip,
11404
11696
  suffix != null && /* @__PURE__ */ jsx("span", { className: "flex flex-shrink-0 items-center", children: suffix }),
11405
11697
  clearable && hasValue && !disabled && !readOnly && /* @__PURE__ */ jsx(
11406
11698
  SGhostButton,
@@ -11634,8 +11926,10 @@ var SNumberInput = /* @__PURE__ */ forwardRef(function SNumberInput2({
11634
11926
  const [display, setDisplay] = useState(() => formatWithCommas(numValue));
11635
11927
  const [ruleError, setRuleError] = useState("");
11636
11928
  const innerRef = useRef(null);
11929
+ const valueTooltip = useTruncatedValueTooltip({ enabled: readOnly && !disabled, text: display });
11637
11930
  const setRefs2 = (el) => {
11638
11931
  innerRef.current = el;
11932
+ valueTooltip.valueRef.current = el;
11639
11933
  if (typeof ref === "function") ref(el);
11640
11934
  else if (ref) ref.current = el;
11641
11935
  };
@@ -11849,9 +12143,12 @@ var SNumberInput = /* @__PURE__ */ forwardRef(function SNumberInput2({
11849
12143
  textAlign: useButton ? "center" : "right",
11850
12144
  color: disabled ? "var(--cmp-numberInput-text-disabled)" : "var(--cmp-numberInput-text-default)",
11851
12145
  ...inputStyle
11852
- }
12146
+ },
12147
+ onMouseEnter: valueTooltip.onMouseEnter,
12148
+ onMouseLeave: valueTooltip.onMouseLeave
11853
12149
  }
11854
12150
  ),
12151
+ valueTooltip.tooltip,
11855
12152
  inputSuffix !== "" && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", style: { color: affixColor }, children: inputSuffix }),
11856
12153
  useButton && stepper("inc")
11857
12154
  ]
@@ -12592,8 +12889,8 @@ function SDatePicker({
12592
12889
  disabled,
12593
12890
  className,
12594
12891
  style,
12595
- children: /* @__PURE__ */ jsxs(RPopover9.Root, { open, onOpenChange: (o) => !disabled && setOpen(o), children: [
12596
- /* @__PURE__ */ jsx(RPopover9.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
12892
+ children: /* @__PURE__ */ jsxs(RPopover10.Root, { open, onOpenChange: (o) => !disabled && setOpen(o), children: [
12893
+ /* @__PURE__ */ jsx(RPopover10.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
12597
12894
  "button",
12598
12895
  {
12599
12896
  type: "button",
@@ -12629,8 +12926,8 @@ function SDatePicker({
12629
12926
  ]
12630
12927
  }
12631
12928
  ) }),
12632
- /* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
12633
- RPopover9.Content,
12929
+ /* @__PURE__ */ jsx(RPopover10.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
12930
+ RPopover10.Content,
12634
12931
  {
12635
12932
  side: "bottom",
12636
12933
  align: mode === "date" ? "start" : "center",
@@ -13096,7 +13393,7 @@ function SDateRangePicker({
13096
13393
  className,
13097
13394
  style,
13098
13395
  children: /* @__PURE__ */ jsxs(
13099
- RPopover9.Root,
13396
+ RPopover10.Root,
13100
13397
  {
13101
13398
  open,
13102
13399
  onOpenChange: (o) => {
@@ -13105,7 +13402,7 @@ function SDateRangePicker({
13105
13402
  if (!o) setPendingStart(null);
13106
13403
  },
13107
13404
  children: [
13108
- /* @__PURE__ */ jsx(RPopover9.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
13405
+ /* @__PURE__ */ jsx(RPopover10.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
13109
13406
  "button",
13110
13407
  {
13111
13408
  type: "button",
@@ -13146,8 +13443,8 @@ function SDateRangePicker({
13146
13443
  ]
13147
13444
  }
13148
13445
  ) }),
13149
- /* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
13150
- RPopover9.Content,
13446
+ /* @__PURE__ */ jsx(RPopover10.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
13447
+ RPopover10.Content,
13151
13448
  {
13152
13449
  side: "bottom",
13153
13450
  align: "start",
@@ -14673,8 +14970,8 @@ var SChipFilter = /* @__PURE__ */ forwardRef(function SChipFilter2({
14673
14970
  })(),
14674
14971
  hasRightActions && /* @__PURE__ */ jsxs(Fragment, { children: [
14675
14972
  /* @__PURE__ */ jsx(Divider, { inset: true }),
14676
- hasAddButton && /* @__PURE__ */ jsxs(RPopover9.Root, { open: addOpen, onOpenChange: setAddOpen, children: [
14677
- /* @__PURE__ */ jsx(RPopover9.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
14973
+ hasAddButton && /* @__PURE__ */ jsxs(RPopover10.Root, { open: addOpen, onOpenChange: setAddOpen, children: [
14974
+ /* @__PURE__ */ jsx(RPopover10.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
14678
14975
  "button",
14679
14976
  {
14680
14977
  type: "button",
@@ -14699,8 +14996,8 @@ var SChipFilter = /* @__PURE__ */ forwardRef(function SChipFilter2({
14699
14996
  ]
14700
14997
  }
14701
14998
  ) }),
14702
- /* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
14703
- RPopover9.Content,
14999
+ /* @__PURE__ */ jsx(RPopover10.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
15000
+ RPopover10.Content,
14704
15001
  {
14705
15002
  side: "bottom",
14706
15003
  align: "start",
@@ -14740,17 +15037,17 @@ var SChipFilter = /* @__PURE__ */ forwardRef(function SChipFilter2({
14740
15037
  )
14741
15038
  ] })
14742
15039
  ] }),
14743
- /* @__PURE__ */ jsxs(RPopover9.Root, { open: openKey != null, onOpenChange: (next) => !next && setOpenKey(null), children: [
15040
+ /* @__PURE__ */ jsxs(RPopover10.Root, { open: openKey != null, onOpenChange: (next) => !next && setOpenKey(null), children: [
14744
15041
  /* @__PURE__ */ jsx(
14745
- RPopover9.Anchor,
15042
+ RPopover10.Anchor,
14746
15043
  {
14747
15044
  virtualRef: {
14748
15045
  current: openKey ? triggerRefs.current.get(openKey) : null
14749
15046
  }
14750
15047
  }
14751
15048
  ),
14752
- /* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
14753
- RPopover9.Content,
15049
+ /* @__PURE__ */ jsx(RPopover10.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
15050
+ RPopover10.Content,
14754
15051
  {
14755
15052
  side: "bottom",
14756
15053
  align: "start",
@@ -15290,8 +15587,8 @@ function InlineDatePresetFilter({
15290
15587
  applied && (rangeValue ? (
15291
15588
  // 뱃지 모양은 그대로 두고, 눌렀을 때 캘린더가 열려 기간을 직접 다시 고를 수 있게 한다.
15292
15589
  // 직접 고르면 프리셋 선택은 해제된다.
15293
- /* @__PURE__ */ jsxs(RPopover9.Root, { open: pickerOpen, onOpenChange: setPickerOpen, children: [
15294
- /* @__PURE__ */ jsx(RPopover9.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(
15590
+ /* @__PURE__ */ jsxs(RPopover10.Root, { open: pickerOpen, onOpenChange: setPickerOpen, children: [
15591
+ /* @__PURE__ */ jsx(RPopover10.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(
15295
15592
  "button",
15296
15593
  {
15297
15594
  type: "button",
@@ -15300,8 +15597,8 @@ function InlineDatePresetFilter({
15300
15597
  children: badge
15301
15598
  }
15302
15599
  ) }),
15303
- /* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
15304
- RPopover9.Content,
15600
+ /* @__PURE__ */ jsx(RPopover10.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
15601
+ RPopover10.Content,
15305
15602
  {
15306
15603
  side: "bottom",
15307
15604
  align: "start",
@@ -16112,6 +16409,10 @@ var SBarcodeInput = /* @__PURE__ */ forwardRef(
16112
16409
  });
16113
16410
  const resolvedError = error || ruleError !== "";
16114
16411
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
16412
+ const valueTooltip = useTruncatedValueTooltip({
16413
+ enabled: readOnly && !disabled,
16414
+ text: String(value ?? "")
16415
+ });
16115
16416
  return /* @__PURE__ */ jsx(
16116
16417
  SField,
16117
16418
  {
@@ -16148,7 +16449,7 @@ var SBarcodeInput = /* @__PURE__ */ forwardRef(
16148
16449
  /* @__PURE__ */ jsx(
16149
16450
  "input",
16150
16451
  {
16151
- ref,
16452
+ ref: mergeRefs(ref, valueTooltip.valueRef),
16152
16453
  name,
16153
16454
  type: "text",
16154
16455
  value: value ?? "",
@@ -16174,9 +16475,12 @@ var SBarcodeInput = /* @__PURE__ */ forwardRef(
16174
16475
  fontSize: f.fontSize,
16175
16476
  color: disabled ? "var(--cmp-textinput-text-disabled)" : "var(--cmp-textinput-text-default)",
16176
16477
  ...inputStyle
16177
- }
16478
+ },
16479
+ onMouseEnter: valueTooltip.onMouseEnter,
16480
+ onMouseLeave: valueTooltip.onMouseLeave
16178
16481
  }
16179
16482
  ),
16483
+ valueTooltip.tooltip,
16180
16484
  suffix,
16181
16485
  clearable && hasValue && !disabled && /* @__PURE__ */ jsx(
16182
16486
  SGhostButton,
@@ -16556,8 +16860,8 @@ function STimePicker({
16556
16860
  disabled,
16557
16861
  className,
16558
16862
  style,
16559
- children: /* @__PURE__ */ jsxs(RPopover9.Root, { open, onOpenChange: commitOpen, children: [
16560
- /* @__PURE__ */ jsx(RPopover9.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
16863
+ children: /* @__PURE__ */ jsxs(RPopover10.Root, { open, onOpenChange: commitOpen, children: [
16864
+ /* @__PURE__ */ jsx(RPopover10.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
16561
16865
  "div",
16562
16866
  {
16563
16867
  ref: triggerRef,
@@ -16617,8 +16921,8 @@ function STimePicker({
16617
16921
  ]
16618
16922
  }
16619
16923
  ) }),
16620
- /* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
16621
- RPopover9.Content,
16924
+ /* @__PURE__ */ jsx(RPopover10.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
16925
+ RPopover10.Content,
16622
16926
  {
16623
16927
  side: "bottom",
16624
16928
  align: "start",
@@ -17023,8 +17327,8 @@ function STimeRangePicker({
17023
17327
  disabled,
17024
17328
  className,
17025
17329
  style,
17026
- children: /* @__PURE__ */ jsxs(RPopover9.Root, { open, onOpenChange: commitOpen, children: [
17027
- /* @__PURE__ */ jsx(RPopover9.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
17330
+ children: /* @__PURE__ */ jsxs(RPopover10.Root, { open, onOpenChange: commitOpen, children: [
17331
+ /* @__PURE__ */ jsx(RPopover10.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
17028
17332
  "div",
17029
17333
  {
17030
17334
  ref: triggerRef,
@@ -17084,8 +17388,8 @@ function STimeRangePicker({
17084
17388
  ]
17085
17389
  }
17086
17390
  ) }),
17087
- /* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
17088
- RPopover9.Content,
17391
+ /* @__PURE__ */ jsx(RPopover10.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
17392
+ RPopover10.Content,
17089
17393
  {
17090
17394
  side: "bottom",
17091
17395
  align: "start",