sellmate-design-system-react 9.0.0-beta.93 → 9.0.0-beta.95

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.
Files changed (31) hide show
  1. package/AGENTS.md +1 -0
  2. package/dist/components/SButton/button.config.d.ts +2 -1
  3. package/dist/components/SChatAttachedFile/chatAttachedFile.config.d.ts +2 -2
  4. package/dist/components/SChatFile/chatFile.config.d.ts +2 -2
  5. package/dist/components/SChipFilter/README.md +2 -0
  6. package/dist/components/SGhostButton/README.md +2 -0
  7. package/dist/components/SGnb/gnb.config.d.ts +6 -0
  8. package/dist/components/SIcon/README.md +3 -1
  9. package/dist/components/SIcon/SIcon.d.ts +1 -1
  10. package/dist/components/SLauncherListBox/launcherListBox.config.d.ts +2 -7
  11. package/dist/components/SLoadingModal/README.md +2 -2
  12. package/dist/components/SRadioCard/README.md +3 -0
  13. package/dist/components/SRadioCard/SRadioCard.d.ts +7 -2
  14. package/dist/components/SRadioCard/SRadioCardGroup.d.ts +3 -1
  15. package/dist/components/SSelect/README.md +1 -1
  16. package/dist/components/SSelect/SSelect.d.ts +1 -1
  17. package/dist/components/SStepper/stepper.config.d.ts +9 -3
  18. package/dist/components/STabs/tabs.config.d.ts +3 -8
  19. package/dist/components/STag/tag.config.d.ts +10 -9
  20. package/dist/components/STimePicker/timepicker.config.d.ts +3 -0
  21. package/dist/components/STree/README.md +2 -0
  22. package/dist/index.cjs +1101 -854
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.js +1101 -854
  25. package/dist/index.js.map +1 -1
  26. package/dist/lib/list-box-item.d.ts +16 -0
  27. package/dist/lib/tree-row.d.ts +31 -2
  28. package/dist/llms-full.txt +12 -4
  29. package/dist/llms.txt +1 -0
  30. package/dist/styles.css +228 -80
  31. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3695,16 +3695,21 @@ var SIcon = /* @__PURE__ */ forwardRef(function SIcon2({ name, size = 24, color,
3695
3695
  const Svg = ICONS[name];
3696
3696
  if (!Svg) return null;
3697
3697
  const rotateClass = rotate ? { 90: "rotate-90", 180: "rotate-180", 270: "-rotate-90" }[rotate] : void 0;
3698
+ const cssSize = typeof size === "string" && /var\(|calc\(/.test(size);
3698
3699
  return /* @__PURE__ */ jsx(
3699
3700
  "span",
3700
3701
  {
3701
3702
  ref,
3702
3703
  className: cn("inline-flex items-center justify-center", rotateClass, className),
3703
- style: { color: resolveColor(color), ...style },
3704
+ style: {
3705
+ color: resolveColor(color),
3706
+ ...cssSize && { width: size, height: size },
3707
+ ...style
3708
+ },
3704
3709
  role: label ? "img" : void 0,
3705
3710
  "aria-label": label,
3706
3711
  "aria-hidden": label ? void 0 : true,
3707
- children: /* @__PURE__ */ jsx(Svg, { size })
3712
+ children: /* @__PURE__ */ jsx(Svg, { size: cssSize ? "100%" : size })
3708
3713
  }
3709
3714
  );
3710
3715
  });
@@ -4107,7 +4112,7 @@ var SBadge = /* @__PURE__ */ forwardRef(function SBadge2({ color = "blue", class
4107
4112
  return /* @__PURE__ */ jsx("span", { ref, className: cn("inline-flex items-center justify-center", className), ...rest, children: /* @__PURE__ */ jsx(
4108
4113
  "span",
4109
4114
  {
4110
- className: "rounded-full",
4115
+ className: "rounded-(--cmp-badge-radius)",
4111
4116
  style: {
4112
4117
  width: "var(--cmp-badge-size, 6px)",
4113
4118
  height: "var(--cmp-badge-size, 6px)",
@@ -4174,7 +4179,8 @@ var BUTTON_SIZE_CONFIG = {
4174
4179
  height: "var(--cmp-button-xs-height)",
4175
4180
  paddingX: "var(--cmp-button-xs-paddingX)",
4176
4181
  gap: "var(--cmp-button-xs-gap)",
4177
- iconSize: 12,
4182
+ iconSize: "var(--cmp-button-xs-icon)",
4183
+ iconOnlyWidth: "var(--cmp-button-iconOnly-xs-width)",
4178
4184
  fontSize: 12,
4179
4185
  fontWeight: 500,
4180
4186
  radius: "var(--cmp-button-radius-sm)",
@@ -4184,7 +4190,8 @@ var BUTTON_SIZE_CONFIG = {
4184
4190
  height: "var(--cmp-button-sm-height)",
4185
4191
  paddingX: "var(--cmp-button-sm-paddingX)",
4186
4192
  gap: "var(--cmp-button-sm-gap)",
4187
- iconSize: 16,
4193
+ iconSize: "var(--cmp-button-sm-icon)",
4194
+ iconOnlyWidth: "var(--cmp-button-iconOnly-sm-width)",
4188
4195
  fontSize: 12,
4189
4196
  fontWeight: 500,
4190
4197
  radius: "var(--cmp-button-radius-sm)",
@@ -4194,7 +4201,8 @@ var BUTTON_SIZE_CONFIG = {
4194
4201
  height: "var(--cmp-button-md-height)",
4195
4202
  paddingX: "var(--cmp-button-md-paddingX)",
4196
4203
  gap: "var(--cmp-button-md-gap)",
4197
- iconSize: 20,
4204
+ iconSize: "var(--cmp-button-md-icon)",
4205
+ iconOnlyWidth: "var(--cmp-button-iconOnly-md-width)",
4198
4206
  fontSize: 16,
4199
4207
  fontWeight: 500,
4200
4208
  radius: "var(--cmp-button-radius-md)",
@@ -4204,7 +4212,8 @@ var BUTTON_SIZE_CONFIG = {
4204
4212
  height: "var(--cmp-button-lg-height)",
4205
4213
  paddingX: "var(--cmp-button-lg-paddingX)",
4206
4214
  gap: "var(--cmp-button-lg-gap)",
4207
- iconSize: 24,
4215
+ iconSize: "var(--cmp-button-lg-icon)",
4216
+ iconOnlyWidth: "var(--cmp-button-iconOnly-lg-width)",
4208
4217
  fontSize: 18,
4209
4218
  fontWeight: 500,
4210
4219
  radius: "var(--cmp-button-radius-md)",
@@ -4251,7 +4260,7 @@ var SButton = /* @__PURE__ */ forwardRef(function SButton2({
4251
4260
  "--btn-border": disabled ? BUTTON_DISABLED_BORDER : preset.border,
4252
4261
  "--btn-ring": BUTTON_FOCUS_RING,
4253
4262
  "minHeight": s.height,
4254
- "minWidth": iconOnly ? s.height : hasLabel ? s.minWidth : void 0,
4263
+ "minWidth": iconOnly ? s.iconOnlyWidth : hasLabel ? s.minWidth : void 0,
4255
4264
  "padding": iconOnly ? 0 : `0 ${s.paddingX}`,
4256
4265
  "borderRadius": s.radius,
4257
4266
  "gap": s.gap,
@@ -4268,7 +4277,7 @@ var SButton = /* @__PURE__ */ forwardRef(function SButton2({
4268
4277
  disabled,
4269
4278
  "aria-label": ariaLabel,
4270
4279
  className: cn(
4271
- "inline-flex items-center justify-center whitespace-nowrap border border-solid leading-none transition-colors",
4280
+ "inline-flex items-center justify-center whitespace-nowrap border-[length:var(--cmp-button-border-width-default)] border-solid leading-none transition-colors",
4272
4281
  "border-[color:var(--btn-border)] bg-[var(--btn-bg)]",
4273
4282
  "outline-none focus-visible:shadow-[0_0_0_2px_var(--btn-ring)]",
4274
4283
  disabled ? "cursor-not-allowed" : "cursor-pointer hover:bg-[var(--btn-bg-hover)]",
@@ -4386,34 +4395,28 @@ var TAG_COLORS = [
4386
4395
  ];
4387
4396
  var TAG_SIZE_CONFIG = {
4388
4397
  xs: {
4389
- height: 20,
4390
- paddingX: 8,
4391
- gap: 4,
4392
- radius: 6,
4393
- iconSize: 12,
4394
- fontSize: 11,
4395
- fontWeight: 500,
4396
- lineHeight: 18
4398
+ height: "var(--cmp-tag-xs-height)",
4399
+ paddingX: "var(--cmp-tag-xs-paddingX)",
4400
+ gap: "var(--cmp-tag-xs-gap)",
4401
+ radius: "var(--cmp-tag-xs-radius)",
4402
+ iconSize: "var(--cmp-tag-xs-icon)",
4403
+ typography: "typo-feedback-xs"
4397
4404
  },
4398
4405
  sm: {
4399
- height: 24,
4400
- paddingX: 8,
4401
- gap: 4,
4402
- radius: 6,
4403
- iconSize: 16,
4404
- fontSize: 12,
4405
- fontWeight: 600,
4406
- lineHeight: 20
4406
+ height: "var(--cmp-tag-sm-height)",
4407
+ paddingX: "var(--cmp-tag-sm-paddingX)",
4408
+ gap: "var(--cmp-tag-sm-gap)",
4409
+ radius: "var(--cmp-tag-sm-radius)",
4410
+ iconSize: "var(--cmp-tag-sm-icon)",
4411
+ typography: "typo-feedback-sm-semibold"
4407
4412
  },
4408
4413
  md: {
4409
- height: 28,
4410
- paddingX: 12,
4411
- gap: 6,
4412
- radius: 8,
4413
- iconSize: 16,
4414
- fontSize: 14,
4415
- fontWeight: 700,
4416
- lineHeight: 24
4414
+ height: "var(--cmp-tag-md-height)",
4415
+ paddingX: "var(--cmp-tag-md-paddingX)",
4416
+ gap: "var(--cmp-tag-md-gap)",
4417
+ radius: "var(--cmp-tag-md-radius)",
4418
+ iconSize: "var(--cmp-tag-md-icon)",
4419
+ typography: "typo-feedback-md-bold"
4417
4420
  }
4418
4421
  };
4419
4422
  var STag = /* @__PURE__ */ forwardRef(function STag2({
@@ -4441,16 +4444,14 @@ var STag = /* @__PURE__ */ forwardRef(function STag2({
4441
4444
  "aria-label": label || "tag",
4442
4445
  className: cn(
4443
4446
  "box-border inline-flex w-fit select-none items-center justify-center whitespace-nowrap",
4447
+ s.typography,
4444
4448
  className
4445
4449
  ),
4446
4450
  style: {
4447
4451
  minHeight: s.height,
4448
- padding: `0 ${s.paddingX}px`,
4452
+ padding: `0 ${s.paddingX}`,
4449
4453
  gap: s.gap,
4450
4454
  borderRadius: shape === "pill" ? 999 : s.radius,
4451
- fontSize: s.fontSize,
4452
- fontWeight: s.fontWeight,
4453
- lineHeight: `${s.lineHeight}px`,
4454
4455
  background: bgColor,
4455
4456
  color: contentColor,
4456
4457
  ...resolvedWidth != null ? { width: resolvedWidth } : {},
@@ -4470,11 +4471,11 @@ var STag = /* @__PURE__ */ forwardRef(function STag2({
4470
4471
  );
4471
4472
  });
4472
4473
  var SIZE = {
4473
- xxs: { icon: 12, radius: "sm" },
4474
- xs: { icon: 16, radius: "sm" },
4475
- sm: { icon: 20, radius: "sm" },
4476
- md: { icon: 24, radius: "md" },
4477
- lg: { icon: 32, radius: "md" }
4474
+ xxs: { icon: "var(--cmp-ghostButton-xxs-icon)", radius: "sm" },
4475
+ xs: { icon: "var(--cmp-ghostButton-xs-icon)", radius: "sm" },
4476
+ sm: { icon: "var(--cmp-ghostButton-sm-icon)", radius: "sm" },
4477
+ md: { icon: "var(--cmp-ghostButton-md-icon)", radius: "md" },
4478
+ lg: { icon: "var(--cmp-ghostButton-lg-icon)", radius: "md" }
4478
4479
  };
4479
4480
  var TOOLTIP_HIDE_DELAY_MS = 100;
4480
4481
  var SGhostButton = /* @__PURE__ */ forwardRef(function SGhostButton2({
@@ -4549,7 +4550,7 @@ var SGhostButton = /* @__PURE__ */ forwardRef(function SGhostButton2({
4549
4550
  "span",
4550
4551
  {
4551
4552
  "aria-hidden": true,
4552
- className: "pointer-events-none absolute inset-0 rounded-[inherit] opacity-0 transition-opacity duration-200 group-hover/ghost-button:opacity-5",
4553
+ className: "pointer-events-none absolute inset-0 rounded-[inherit] opacity-0 transition-opacity duration-200 group-hover/ghost-button:opacity-(--cmp-ghostButton-hover-opacity)",
4553
4554
  style: { background: `var(--cmp-ghostButton-${intent}-hover-bg)` }
4554
4555
  }
4555
4556
  ),
@@ -4773,7 +4774,9 @@ var STooltipImpl = /* @__PURE__ */ forwardRef(function STooltip({
4773
4774
  ...restContentProps
4774
4775
  } = contentProps ?? {};
4775
4776
  const contentClass = cn(
4776
- "z-50 w-fit max-w-[var(--radix-popover-content-available-width)] rounded-[6px] px-[16px] py-[12px] text-[12px] leading-[20px] shadow-normal-sm",
4777
+ "z-50 w-fit max-w-[var(--radix-popover-content-available-width)] rounded-(--cmp-tooltip-radius) px-(--cmp-tooltip-paddingX) py-(--cmp-tooltip-paddingY) shadow-normal-sm",
4778
+ // default 500, danger/warning/accent 700 — tooltip.<type>.typography
4779
+ tooltipType === "default" ? "typo-feedback-sm-medium" : "typo-feedback-sm-bold",
4777
4780
  FLOATING_SLIDE_ANIM,
4778
4781
  className,
4779
4782
  contentPropsClassName
@@ -4781,7 +4784,6 @@ var STooltipImpl = /* @__PURE__ */ forwardRef(function STooltip({
4781
4784
  const contentStyle = {
4782
4785
  background: bg,
4783
4786
  color: fg,
4784
- fontWeight: tooltipType === "default" ? 500 : 700,
4785
4787
  ...style,
4786
4788
  ...contentPropsStyle
4787
4789
  };
@@ -4822,7 +4824,7 @@ var STooltipImpl = /* @__PURE__ */ forwardRef(function STooltip({
4822
4824
  onMouseLeave: isHover ? startHide : void 0,
4823
4825
  ...restContentProps,
4824
4826
  children: [
4825
- /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-[12px]", children: [
4827
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-(--cmp-tooltip-gap)", children: [
4826
4828
  /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: body }),
4827
4829
  showClose && !isNone && /* @__PURE__ */ jsx(
4828
4830
  SGhostButton,
@@ -4877,16 +4879,20 @@ var FIELD_SIZE = {
4877
4879
  height: 28,
4878
4880
  radius: 4,
4879
4881
  fieldGap: 12,
4880
- labelGap: 6,
4882
+ labelHeight: "var(--cmp-field-label-sm-height)",
4883
+ labelGap: "var(--cmp-field-label-sm-gap)",
4881
4884
  labelTypo: "typo-field-sm-bold",
4885
+ labelIcon: "var(--cmp-field-label-sm-icon)",
4882
4886
  icon: 16
4883
4887
  },
4884
4888
  md: {
4885
4889
  height: 36,
4886
4890
  radius: 6,
4887
4891
  fieldGap: 16,
4888
- labelGap: 8,
4892
+ labelHeight: "var(--cmp-field-label-md-height)",
4893
+ labelGap: "var(--cmp-field-label-md-gap)",
4889
4894
  labelTypo: "typo-field-md-bold",
4895
+ labelIcon: "var(--cmp-field-label-md-icon)",
4890
4896
  icon: 16
4891
4897
  }
4892
4898
  };
@@ -5013,7 +5019,7 @@ var SField = /* @__PURE__ */ forwardRef(function SField2({
5013
5019
  // 라벨과 컨트롤 사이가 간격 토큰보다 넓어진다. 줄 세우기용 labelWidth 도
5014
5020
  // 뜻이 없다(아래에 컨트롤이 제 폭으로 선다).
5015
5021
  ...labelOnTop ? {} : {
5016
- height: cssLen(labelHeight) ?? s.height,
5022
+ height: cssLen(labelHeight) ?? s.labelHeight,
5017
5023
  marginRight: s.fieldGap,
5018
5024
  width: cssLen(labelWidth)
5019
5025
  }
@@ -5023,7 +5029,7 @@ var SField = /* @__PURE__ */ forwardRef(function SField2({
5023
5029
  SIcon,
5024
5030
  {
5025
5031
  name: icon,
5026
- size: s.icon,
5032
+ size: s.labelIcon,
5027
5033
  color: iconColor,
5028
5034
  style: { marginRight: s.labelGap }
5029
5035
  }
@@ -5103,7 +5109,7 @@ var SField = /* @__PURE__ */ forwardRef(function SField2({
5103
5109
  effectiveAddonLabel !== "" && /* @__PURE__ */ jsxs(
5104
5110
  "div",
5105
5111
  {
5106
- className: "flex shrink-0 items-center gap-(--cmp-field-addonLabel-gap) whitespace-nowrap border-r border-solid px-(--cmp-field-addonLabel-paddingX) text-12 font-medium leading-sd-20",
5112
+ className: "flex shrink-0 items-center gap-(--cmp-field-addonLabel-gap) whitespace-nowrap border-r-(length:--cmp-field-addonLabel-border-width) border-solid px-(--cmp-field-addonLabel-paddingX) typo-field-sm-medium",
5107
5113
  style: {
5108
5114
  // 원본 sd-field: labelWidth가 addon 폭(--sd-field-addon-width)에도 적용됨
5109
5115
  width: cssLen(labelWidth),
@@ -5123,7 +5129,7 @@ var SField = /* @__PURE__ */ forwardRef(function SField2({
5123
5129
  ]
5124
5130
  }
5125
5131
  ),
5126
- showError ? /* @__PURE__ */ jsx("div", { className: "mt-(--cmp-field-contents-gap) px-(--cmp-field-message-paddingX) text-12 font-normal leading-sd-20 text-(--cmp-field-errorMessage-color)", children: errorMessage }) : hint !== "" ? /* @__PURE__ */ jsx("div", { className: "mt-(--cmp-field-contents-gap) px-(--cmp-field-message-paddingX) text-12 font-normal leading-sd-20 text-(--cmp-field-hint-color)", children: hint }) : null
5132
+ showError ? /* @__PURE__ */ jsx("div", { className: "mt-(--cmp-field-contents-gap) px-(--cmp-field-message-paddingX) typo-field-sm-default text-(--cmp-field-errorMessage-color)", children: errorMessage }) : hint !== "" ? /* @__PURE__ */ jsx("div", { className: "mt-(--cmp-field-contents-gap) px-(--cmp-field-message-paddingX) typo-field-sm-default text-(--cmp-field-hint-color)", children: hint }) : null
5127
5133
  ]
5128
5134
  }
5129
5135
  )
@@ -5450,8 +5456,8 @@ var CHAT_ATTACHED_FILE_CONFIG = {
5450
5456
  contentGap: "gap-(--cmp-chatAttachedFile-content-gap)",
5451
5457
  /** 클립 아이콘이 앉는 칩 — 내부 패딩·면·라운드 (높이는 아이콘+패딩이 정한다) */
5452
5458
  tile: "p-(--cmp-chatAttachedFile-icon-wrapper-padding) rounded-(--cmp-chatAttachedFile-icon-wrapper-radius) bg-(--cmp-chatAttachedFile-icon-wrapper-bg)",
5453
- /** 칩 안 클립 아이콘 크기(px). SVG width/height 는 속성값이라 CSS 변수를 못 받아 값으로 둔다 (토큰 값과 동일) */
5454
- iconSize: 16,
5459
+ /** 칩 안 클립 아이콘 크기 */
5460
+ iconSize: "var(--cmp-chatAttachedFile-icon-size)",
5455
5461
  /** 파일명 타이포 프리셋 */
5456
5462
  nameTypo: "typo-body-sm-default",
5457
5463
  /** 파일명 텍스트색 */
@@ -5529,8 +5535,8 @@ var CHAT_FILE_CONFIG = {
5529
5535
  * 디자인팀에 `icon.wrapper.bg.hover` 를 요청해 나오는 대로 갈아끼운다.
5530
5536
  */
5531
5537
  tile: "p-(--cmp-chatFile-icon-wrapper-padding) rounded-(--cmp-chatFile-icon-wrapper-radius) bg-(--cmp-chatFile-icon-wrapper-bg) group-hover/chat-file:bg-(--sys-color-bg-frame)",
5532
- /** 칩 안 클립 아이콘 크기(px). SVG width/height 는 속성값이라 CSS 변수를 못 받아 값으로 둔다 (토큰 값과 동일) */
5533
- iconSize: 20,
5538
+ /** 칩 안 클립 아이콘 크기 */
5539
+ iconSize: "var(--cmp-chatFile-icon-size)",
5534
5540
  /** 파일명 타이포 프리셋 */
5535
5541
  nameTypo: "typo-body-md-bold",
5536
5542
  /** 파일명·부가정보 텍스트색 */
@@ -5883,7 +5889,7 @@ var SDraggableItemView = /* @__PURE__ */ forwardRef(
5883
5889
  paddingYClass,
5884
5890
  // 항목 사이 구분선은 리스트가 그린다.
5885
5891
  bordered && cn(
5886
- "rounded-(--cmp-listDraggableItem-radius-bordered) border border-(--cmp-listDraggableItem-border-default)",
5892
+ "rounded-(--cmp-listDraggableItem-radius-bordered) border-(length:--cmp-listDraggableItem-border-width-default) border-(--cmp-listDraggableItem-border-default)",
5887
5893
  !disabled && !selected && !dragging && cn(
5888
5894
  "hover:border-(--cmp-listDraggableItem-bordered-border-hover)",
5889
5895
  "[[data-drag-active]_&]:hover:border-(--cmp-listDraggableItem-border-default)"
@@ -6755,7 +6761,7 @@ var SExpansionItem = /* @__PURE__ */ forwardRef(
6755
6761
  "gap-(--cmp-listExpansionItem-title-gap)",
6756
6762
  // 헤더 액션이 있으면 오른쪽 끝 여백은 액션 칸이 갖고, 버튼은 액션과의 간격만 남긴다
6757
6763
  hasHeaderAction ? "pr-(--cmp-listExpansionItem-title-gap)" : "pr-(--cmp-listExpansionItem-title-paddingX)",
6758
- depth === 2 ? "pl-[36px]" : depth === 3 ? "pl-[56px]" : "pl-[16px]",
6764
+ depth === 2 ? "pl-[36px]" : depth === 3 ? "pl-[56px]" : "pl-(--cmp-listExpansionItem-title-paddingX)",
6759
6765
  isExpanded && "text-(--cmp-listExpansionItem-title-text-expanded)"
6760
6766
  ),
6761
6767
  children: [
@@ -6766,7 +6772,14 @@ var SExpansionItem = /* @__PURE__ */ forwardRef(
6766
6772
  "flex transition-transform duration-200 ease-out motion-reduce:transition-none",
6767
6773
  isExpanded && "rotate-180"
6768
6774
  ),
6769
- children: /* @__PURE__ */ jsx(SIcon, { name: "caretDown", size: 12, color: "var(--sys-color-fg-quaternary)" })
6775
+ children: /* @__PURE__ */ jsx(
6776
+ SIcon,
6777
+ {
6778
+ name: "caretDown",
6779
+ size: "var(--cmp-listExpansionItem-title-icon)",
6780
+ color: "var(--sys-color-fg-quaternary)"
6781
+ }
6782
+ )
6770
6783
  }
6771
6784
  ),
6772
6785
  leadingNode,
@@ -6804,10 +6817,9 @@ var SExpansionItem = /* @__PURE__ */ forwardRef(
6804
6817
  className: cn(
6805
6818
  "group/expansion-item relative overflow-hidden bg-(--cmp-listExpansionItem-title-bg-default)",
6806
6819
  // 항목 사이 구분선은 리스트가 그린다.
6807
- // 보더 색은 시맨틱 토큰(border-default → hover strong → 펼침 accentLight)을 쓴다.
6808
- // TODO: expansionItem/bordered/radius 토큰 생성 후 rounded 고정값도 토큰으로 교체한다.
6809
- bordered && "rounded-[8px] border border-border-default hover:border-border-strong [&:has(>button:hover)]:border-border-strong",
6810
- bordered && isExpanded && "!border-border-accentLight",
6820
+ // 보더 색: 기본 → hover → 펼침 순으로 listExpansionItem.border 토큰을 쓴다.
6821
+ bordered && "rounded-(--cmp-listExpansionItem-bordered-radius) border border-(--cmp-listExpansionItem-border-default) hover:border-(--cmp-listExpansionItem-border-hover) [&:has(>button:hover)]:border-(--cmp-listExpansionItem-border-hover)",
6822
+ bordered && isExpanded && "!border-(--cmp-listExpansionItem-border-expanded)",
6811
6823
  className
6812
6824
  ),
6813
6825
  ...rest,
@@ -6816,7 +6828,7 @@ var SExpansionItem = /* @__PURE__ */ forwardRef(
6816
6828
  "span",
6817
6829
  {
6818
6830
  "aria-hidden": "true",
6819
- className: "pointer-events-none absolute bottom-[-1px] left-0 top-0 z-[1] w-(--cmp-listItem-accentStripe-width) bg-(--cmp-listItem-accentStripe-color)"
6831
+ className: "pointer-events-none absolute bottom-[-1px] left-0 top-0 z-[1] w-(--cmp-listExpansionItem-accentStripe-width) bg-(--cmp-listExpansionItem-accentStripe-color)"
6820
6832
  }
6821
6833
  ),
6822
6834
  hasHeaderAction ? (
@@ -6923,9 +6935,9 @@ var SListItemImpl = /* @__PURE__ */ forwardRef(function SListItem({
6923
6935
  dense ? "py-(--cmp-listItem-paddingY-dense)" : "py-(--cmp-listItem-paddingY-normal)",
6924
6936
  "gap-(--cmp-listItem-gap)",
6925
6937
  "pr-(--cmp-listItem-paddingX)",
6926
- depth === 2 ? "pl-[36px]" : depth === 3 ? "pl-[56px]" : "pl-[16px]",
6938
+ depth === 2 ? "pl-[36px]" : depth === 3 ? "pl-[56px]" : "pl-(--cmp-listItem-paddingX)",
6927
6939
  bordered && cn(
6928
- "overflow-hidden rounded-(--cmp-listItem-radius-bordered) border border-(--cmp-listItem-border-default)",
6940
+ "overflow-hidden rounded-(--cmp-listItem-radius-bordered) border-(length:--cmp-listItem-border-width-default) border-(--cmp-listItem-border-default)",
6929
6941
  isSelected ? "border-(--cmp-listItem-bordered-border-selected)" : isInteractive && "hover:border-(--cmp-listItem-bordered-border-hover)"
6930
6942
  ),
6931
6943
  className
@@ -7615,7 +7627,7 @@ function SCheckbox({
7615
7627
  };
7616
7628
  const boxBg = disabled ? "var(--cmp-checkbox-bg-disabled)" : inverse ? "transparent" : isChecked ? "var(--cmp-checkbox-checked-bg-default)" : "var(--cmp-checkbox-unchecked-bg-default)";
7617
7629
  const boxBorder = disabled ? "var(--cmp-checkbox-border-disabled)" : inverse ? "var(--cmp-checkbox-checked-border-inverse)" : isChecked ? "var(--cmp-checkbox-checked-bg-default)" : "var(--cmp-checkbox-unchecked-border-default)";
7618
- const iconColor = disabled ? "var(--cmp-checkbox-checked-icon-disabled)" : "var(--cmp-checkbox-checked-icon-default)";
7630
+ const iconColor = disabled ? "var(--cmp-checkbox-checked-icon-disabled)" : inverse ? "var(--cmp-checkbox-checked-icon-inverse)" : "var(--cmp-checkbox-checked-icon-default)";
7619
7631
  const labelColor = disabled ? "var(--cmp-checkbox-label-disabled)" : inverse ? "var(--cmp-checkbox-label-inverse)" : "var(--cmp-checkbox-label-default)";
7620
7632
  return /* @__PURE__ */ jsxs(
7621
7633
  "label",
@@ -7644,7 +7656,7 @@ function SCheckbox({
7644
7656
  SIcon,
7645
7657
  {
7646
7658
  name: state2 === "indeterminate" ? "checkboxIndeterminate" : "checkboxCheck",
7647
- size: 12,
7659
+ size: "var(--cmp-checkbox-icon)",
7648
7660
  color: iconColor
7649
7661
  }
7650
7662
  ) })
@@ -7656,11 +7668,19 @@ function SCheckbox({
7656
7668
  // 찌그러진다 — 띄어쓰기에서만 끊고, 끊을 자리가 없는 긴 토큰만 흘려보낸다
7657
7669
  // (SRadio·SSwitch 라벨과 같은 규칙). 두 사본에 함께 걸려야 하므로 바깥 grid 에 준다.
7658
7670
  /* @__PURE__ */ jsxs("span", { className: "grid break-keep wrap-break-word", style: { color: labelColor }, children: [
7659
- /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "typo-body-sm-medium invisible", style: { gridArea: "1 / 1" }, children: label }),
7660
7671
  /* @__PURE__ */ jsx(
7661
7672
  "span",
7662
7673
  {
7663
- className: isChecked ? "typo-body-sm-medium" : "typo-body-sm-default",
7674
+ "aria-hidden": true,
7675
+ className: "typo-field-sm-medium invisible",
7676
+ style: { gridArea: "1 / 1" },
7677
+ children: label
7678
+ }
7679
+ ),
7680
+ /* @__PURE__ */ jsx(
7681
+ "span",
7682
+ {
7683
+ className: isChecked ? "typo-field-sm-medium" : "typo-field-sm-default",
7664
7684
  style: { gridArea: "1 / 1" },
7665
7685
  children: label
7666
7686
  }
@@ -7672,18 +7692,25 @@ function SCheckbox({
7672
7692
  }
7673
7693
  var TREE_LABEL_TYPOGRAPHY = {
7674
7694
  sm: {
7675
- default: "typo-body-sm-medium",
7676
- selected: "typo-body-sm-bold",
7695
+ default: "typo-item-sm-default",
7696
+ selected: "typo-item-sm-selected",
7677
7697
  rowHeight: "h-[28px]"
7678
7698
  },
7679
7699
  md: {
7680
- default: "typo-body-md-medium",
7681
- selected: "typo-body-md-bold",
7700
+ default: "typo-item-md-default",
7701
+ selected: "typo-item-md-selected",
7682
7702
  rowHeight: "h-[32px]"
7683
7703
  }
7684
7704
  };
7705
+ var TREE_BRANCH_MOTION = { duration: 200, easing: "cubic-bezier(0, 0, 0.2, 1)" };
7706
+ function canAnimateTreeBranch() {
7707
+ if (typeof window === "undefined" || typeof HTMLElement.prototype.animate !== "function") {
7708
+ return false;
7709
+ }
7710
+ return !window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
7711
+ }
7685
7712
  var TREE_ROW_CLASS = "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 hover:bg-(--cmp-tree-item-bg-hover)";
7686
- var TREE_ROW_BORDER_CLASS = "border-b border-(--cmp-tree-item-border-default)";
7713
+ var TREE_ROW_BORDER_CLASS = "border-b-(length:--cmp-tree-item-border-width-default) border-(--cmp-tree-item-border-default)";
7687
7714
  var TREE_ROW_ACTIVE_CLASS = "bg-(--cmp-tree-item-bg-hover)";
7688
7715
  var TREE_CONTENT_CLASS = "box-border flex min-w-0 flex-1 items-center gap-(--cmp-tree-item-contentGap)";
7689
7716
  function treeLabelClass(size, {
@@ -7693,12 +7720,49 @@ function treeLabelClass(size, {
7693
7720
  }) {
7694
7721
  const typography = TREE_LABEL_TYPOGRAPHY[size];
7695
7722
  return cn(
7696
- "block min-w-0 flex-1 truncate py-(--cmp-tree-item-paddingY) text-(--cmp-tree-item-text-default)",
7723
+ "block min-w-0 truncate py-(--cmp-tree-item-paddingY) text-(--cmp-tree-item-text-default)",
7697
7724
  emphasized ? typography.selected : typography.default,
7698
7725
  disabled && "opacity-60",
7699
- disabled ? "cursor-not-allowed" : selectable ? "cursor-pointer" : void 0
7726
+ disabled ? "cursor-not-allowed" : selectable ? "cursor-pointer" : void 0,
7727
+ selectable && !disabled && "group-hover/tree-label:underline"
7728
+ );
7729
+ }
7730
+ function TreeSelectZone({
7731
+ selectable,
7732
+ disabled = false,
7733
+ control,
7734
+ children
7735
+ }) {
7736
+ return /* @__PURE__ */ jsxs(
7737
+ "span",
7738
+ {
7739
+ "data-tree-label": true,
7740
+ className: cn(
7741
+ "flex min-w-0 items-center gap-(--cmp-tree-item-contentGap)",
7742
+ selectable && (disabled ? "cursor-not-allowed" : "group/tree-label cursor-pointer")
7743
+ ),
7744
+ children: [
7745
+ control,
7746
+ /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-sd-8", children: [
7747
+ children,
7748
+ selectable && !disabled && /* @__PURE__ */ jsx(
7749
+ SIcon,
7750
+ {
7751
+ name: "chevronRight",
7752
+ size: 12,
7753
+ color: "var(--sys-color-fg-quaternary)",
7754
+ className: "hidden shrink-0 group-hover/tree-label:inline-flex"
7755
+ }
7756
+ )
7757
+ ] })
7758
+ ]
7759
+ }
7700
7760
  );
7701
7761
  }
7762
+ function isRowSelectClick(event) {
7763
+ const zone = event.target.closest("[data-tree-label]");
7764
+ return zone != null && event.currentTarget.contains(zone);
7765
+ }
7702
7766
  function isRowControlClick(event) {
7703
7767
  const control = event.target.closest("[data-tree-control]");
7704
7768
  return control != null && event.currentTarget.contains(control);
@@ -7932,7 +7996,7 @@ var STreeItemImpl = /* @__PURE__ */ forwardRef(function STreeItem({
7932
7996
  };
7933
7997
  const handleRowClick = (event) => {
7934
7998
  if (isRowControlClick(event)) return;
7935
- if (selectable && event.target.closest("[data-tree-label]")) {
7999
+ if (selectable && isRowSelectClick(event)) {
7936
8000
  handleSelect(event);
7937
8001
  return;
7938
8002
  }
@@ -7973,35 +8037,41 @@ var STreeItemImpl = /* @__PURE__ */ forwardRef(function STreeItem({
7973
8037
  /* @__PURE__ */ jsxs("div", { className: TREE_CONTENT_CLASS, children: [
7974
8038
  hasChildren ? /* @__PURE__ */ jsx(TreeCaret, { expanded, onToggle: (event) => onToggle?.(node, event) }) : /* @__PURE__ */ jsx(TreeCaretSpacer, {}),
7975
8039
  leadingNode,
7976
- selectable && /* @__PURE__ */ jsx(
7977
- "span",
8040
+ /* @__PURE__ */ jsx(
8041
+ TreeSelectZone,
7978
8042
  {
7979
- "data-tree-control": true,
7980
- className: "flex shrink-0",
7981
- "aria-hidden": node.disabled ? "true" : void 0,
8043
+ selectable,
8044
+ disabled: node.disabled,
8045
+ control: selectable && /* @__PURE__ */ jsx(
8046
+ "span",
8047
+ {
8048
+ "data-tree-control": true,
8049
+ className: "flex shrink-0",
8050
+ "aria-hidden": node.disabled ? "true" : void 0,
8051
+ children: /* @__PURE__ */ jsx(
8052
+ SCheckbox,
8053
+ {
8054
+ value: checkboxValue,
8055
+ disabled: node.disabled,
8056
+ onValueChange: () => handleSelect()
8057
+ }
8058
+ )
8059
+ }
8060
+ ),
7982
8061
  children: /* @__PURE__ */ jsx(
7983
- SCheckbox,
8062
+ "span",
7984
8063
  {
7985
- value: checkboxValue,
7986
- disabled: node.disabled,
7987
- onValueChange: () => handleSelect()
8064
+ className: treeLabelClass(size, {
8065
+ emphasized: selected || indeterminate,
8066
+ disabled: Boolean(node.disabled),
8067
+ selectable
8068
+ }),
8069
+ children: node.label
7988
8070
  }
7989
8071
  )
7990
8072
  }
7991
8073
  ),
7992
- /* @__PURE__ */ jsx(
7993
- "span",
7994
- {
7995
- "data-tree-label": true,
7996
- className: treeLabelClass(size, {
7997
- emphasized: selected || indeterminate,
7998
- disabled: Boolean(node.disabled),
7999
- selectable
8000
- }),
8001
- children: node.label
8002
- }
8003
- ),
8004
- trailingNode
8074
+ trailingNode != null && /* @__PURE__ */ jsx("span", { className: "ml-auto flex shrink-0", children: trailingNode })
8005
8075
  ] })
8006
8076
  ]
8007
8077
  }
@@ -8279,7 +8349,7 @@ var SSectionHeaderCardHeaderImpl = /* @__PURE__ */ forwardRef(
8279
8349
  "span",
8280
8350
  {
8281
8351
  className: cn(
8282
- "min-w-0 truncate text-(--sys-color-fg-brand)",
8352
+ "min-w-0 truncate text-(--cmp-sectionHeaderCard-title-color)",
8283
8353
  titleSizeClass[titleSize]
8284
8354
  ),
8285
8355
  children: title
@@ -8289,7 +8359,7 @@ var SSectionHeaderCardHeaderImpl = /* @__PURE__ */ forwardRef(
8289
8359
  SIcon,
8290
8360
  {
8291
8361
  name: "asterisk",
8292
- size: 16,
8362
+ size: "var(--cmp-sectionHeaderCard-required-icon)",
8293
8363
  color: "var(--sys-color-fg-accent)",
8294
8364
  className: "shrink-0"
8295
8365
  }
@@ -8306,7 +8376,7 @@ var SSectionHeaderCardHeaderImpl = /* @__PURE__ */ forwardRef(
8306
8376
  }
8307
8377
  )
8308
8378
  ] }),
8309
- subtitle && /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate text-[12px] font-normal leading-[20px] text-(--sys-color-fg-secondary)", children: subtitle }),
8379
+ subtitle && /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate typo-body-sm-default text-(--cmp-sectionHeaderCard-subtitle-color)", children: subtitle }),
8310
8380
  /* @__PURE__ */ jsx("div", { className: "ml-auto flex min-h-sd-6 min-w-0 flex-1 items-center justify-end", children: slot })
8311
8381
  ]
8312
8382
  }
@@ -8342,7 +8412,7 @@ var SSectionHeaderCardRootImpl = /* @__PURE__ */ forwardRef(
8342
8412
  {
8343
8413
  ref,
8344
8414
  className: cn(
8345
- "box-border flex w-full flex-col items-stretch overflow-hidden rounded-[8px] border border-(--sys-color-border-default) bg-(--sys-color-bg-frame)",
8415
+ "box-border flex w-full flex-col items-stretch overflow-hidden rounded-(--cmp-sectionHeaderCard-radius) border border-(--cmp-sectionHeaderCard-border) bg-(--cmp-sectionHeaderCard-body-bg)",
8346
8416
  className
8347
8417
  ),
8348
8418
  ...rest,
@@ -8894,18 +8964,25 @@ var SCallout = /* @__PURE__ */ forwardRef(function SCallout2({ type = "default",
8894
8964
  hasDangerTitle && /* @__PURE__ */ jsxs(
8895
8965
  "div",
8896
8966
  {
8897
- className: "flex shrink-0 flex-col items-center justify-center gap-[var(--cmp-callout-danger-title-gap)] px-[var(--cmp-callout-danger-title-paddingX)] py-[8px] text-[16px] font-bold leading-[26px]",
8967
+ className: "typo-heading-md flex shrink-0 flex-col items-center justify-center gap-[var(--cmp-callout-danger-title-gap)] px-[var(--cmp-callout-danger-title-paddingX)] py-[8px]",
8898
8968
  style: {
8899
8969
  background: "var(--cmp-callout-danger-title-bg)",
8900
8970
  color: "var(--cmp-callout-danger-title-color)"
8901
8971
  },
8902
8972
  children: [
8903
- /* @__PURE__ */ jsx(SIcon, { name: "warningFill", size: 24, color: "var(--cmp-callout-danger-title-color)" }),
8973
+ /* @__PURE__ */ jsx(
8974
+ SIcon,
8975
+ {
8976
+ name: "warningFill",
8977
+ size: "var(--cmp-callout-danger-title-icon)",
8978
+ color: "var(--cmp-callout-danger-title-color)"
8979
+ }
8980
+ ),
8904
8981
  /* @__PURE__ */ jsx("span", { className: "whitespace-nowrap", children: DANGER_TITLE_LABEL })
8905
8982
  ]
8906
8983
  }
8907
8984
  ),
8908
- /* @__PURE__ */ jsx("div", { className: "flex min-w-0 flex-1 flex-col justify-center gap-[var(--cmp-callout-body-gap)] px-[var(--cmp-callout-body-paddingX)] py-[var(--cmp-callout-body-paddingY)] text-[12px] font-normal leading-[20px]", children: children ?? /* @__PURE__ */ jsx("ul", { className: "m-0 flex list-none flex-col justify-center gap-[var(--cmp-callout-body-gap)] p-0", children: renderItems(message) }) })
8985
+ /* @__PURE__ */ jsx("div", { className: "flex min-w-0 flex-1 flex-col justify-center gap-[var(--cmp-callout-body-gap)] px-[var(--cmp-callout-body-paddingX)] py-[var(--cmp-callout-body-paddingY)] typo-feedback-sm-regular", children: children ?? /* @__PURE__ */ jsx("ul", { className: "m-0 flex list-none flex-col justify-center gap-[var(--cmp-callout-body-gap)] p-0", children: renderItems(message) }) })
8909
8986
  ]
8910
8987
  }
8911
8988
  );
@@ -8976,7 +9053,7 @@ var SContextAlert = /* @__PURE__ */ forwardRef(function SContextAlert2({ intent
8976
9053
  className: "shrink-0"
8977
9054
  }
8978
9055
  ),
8979
- /* @__PURE__ */ jsx("div", { className: "flex min-w-0 flex-1 flex-col text-[12px] font-normal leading-[20px] text-[color:var(--cmp-contextAlert-content)]", children: messages.map((m, i) => (
9056
+ /* @__PURE__ */ jsx("div", { className: "flex min-w-0 flex-1 flex-col typo-feedback-sm-regular text-[color:var(--cmp-contextAlert-content)]", children: messages.map((m, i) => (
8980
9057
  // 메시지는 HTML 문자열을 허용하되, sanitizeInlineHtml 로 살균 후 innerHTML 렌더 (XSS 방어)
8981
9058
  /* @__PURE__ */ jsx(
8982
9059
  "p",
@@ -9221,20 +9298,20 @@ var loading = {
9221
9298
  };
9222
9299
  var SIZE_CONFIG = {
9223
9300
  sm: {
9224
- gap: 4,
9225
- iconSize: 16,
9301
+ gap: "var(--cmp-textLink-sm-gap)",
9302
+ iconSize: "var(--cmp-textLink-sm-icon)",
9226
9303
  typo: "typo-control-xs-medium",
9227
9304
  underlineTypo: "typo-control-xs-underline"
9228
9305
  },
9229
9306
  md: {
9230
- gap: 8,
9231
- iconSize: 16,
9307
+ gap: "var(--cmp-textLink-md-gap)",
9308
+ iconSize: "var(--cmp-textLink-md-icon)",
9232
9309
  typo: "typo-control-sm-default",
9233
9310
  underlineTypo: "typo-control-sm-underline"
9234
9311
  },
9235
9312
  lg: {
9236
- gap: 8,
9237
- iconSize: 20,
9313
+ gap: "var(--cmp-textLink-lg-gap)",
9314
+ iconSize: "var(--cmp-textLink-lg-icon)",
9238
9315
  typo: "typo-control-md-default",
9239
9316
  underlineTypo: "typo-control-md-underline"
9240
9317
  }
@@ -9296,15 +9373,23 @@ var STextLink = /* @__PURE__ */ forwardRef(function STextLink2({
9296
9373
  children: label || children
9297
9374
  }
9298
9375
  ),
9299
- rightArrow !== "none" && /* @__PURE__ */ jsx("span", { className: "inline-flex h-[16px] w-[16px] items-center justify-center", children: /* @__PURE__ */ jsx(
9300
- SIcon,
9376
+ rightArrow !== "none" && // 화살표 칸은 좌측 아이콘과 같은 크기다(textLink.<size>.icon 이 leadingIcon·trailingArrow 공유)
9377
+ /* @__PURE__ */ jsx(
9378
+ "span",
9301
9379
  {
9302
- name: rightArrow === "chevron" ? "chevronRight" : "caretRight",
9303
- size: 12,
9304
- color: disabled ? "var(--cmp-textLink-icon-disabled)" : "var(--color-grey-65)",
9305
- rotate: rightArrowRotate
9380
+ className: "inline-flex items-center justify-center",
9381
+ style: { width: s.iconSize, height: s.iconSize },
9382
+ children: /* @__PURE__ */ jsx(
9383
+ SIcon,
9384
+ {
9385
+ name: rightArrow === "chevron" ? "chevronRight" : "caretRight",
9386
+ size: 12,
9387
+ color: disabled ? "var(--cmp-textLink-icon-disabled)" : "var(--color-grey-65)",
9388
+ rotate: rightArrowRotate
9389
+ }
9390
+ )
9306
9391
  }
9307
- ) })
9392
+ )
9308
9393
  ]
9309
9394
  }
9310
9395
  );
@@ -9377,24 +9462,38 @@ function DropdownMenuContent({
9377
9462
  ) });
9378
9463
  }
9379
9464
  var SIZE2 = {
9380
- xs: { height: 24, paddingX: 8, gap: 6, arrow: 12, fontSize: 12, minWidth: 64, splitMinWidth: 72 },
9465
+ xs: {
9466
+ height: "var(--cmp-button-xs-height)",
9467
+ paddingX: "var(--cmp-button-xs-paddingX)",
9468
+ gap: "var(--cmp-button-dropdown-xs-gap)",
9469
+ arrow: "var(--cmp-button-dropdown-xs-arrow)",
9470
+ toggleWidth: "var(--cmp-button-iconOnly-xs-width)",
9471
+ fontSize: 12,
9472
+ minWidth: 64,
9473
+ splitMinWidth: 72,
9474
+ radius: "var(--cmp-button-radius-sm)"
9475
+ },
9381
9476
  sm: {
9382
- height: 28,
9383
- paddingX: 12,
9384
- gap: 8,
9385
- arrow: 12,
9477
+ height: "var(--cmp-button-sm-height)",
9478
+ paddingX: "var(--cmp-button-sm-paddingX)",
9479
+ gap: "var(--cmp-button-dropdown-sm-gap)",
9480
+ arrow: "var(--cmp-button-dropdown-sm-arrow)",
9481
+ toggleWidth: "var(--cmp-button-iconOnly-sm-width)",
9386
9482
  fontSize: 12,
9387
9483
  minWidth: 72,
9388
- splitMinWidth: 88
9484
+ splitMinWidth: 88,
9485
+ radius: "var(--cmp-button-radius-sm)"
9389
9486
  },
9390
9487
  md: {
9391
- height: 36,
9392
- paddingX: 20,
9393
- gap: 16,
9394
- arrow: 16,
9488
+ height: "var(--cmp-button-md-height)",
9489
+ paddingX: "var(--cmp-button-md-paddingX)",
9490
+ gap: "var(--cmp-button-dropdown-md-gap)",
9491
+ arrow: "var(--cmp-button-dropdown-md-arrow)",
9492
+ toggleWidth: "var(--cmp-button-iconOnly-md-width)",
9395
9493
  fontSize: 16,
9396
9494
  minWidth: 100,
9397
- splitMinWidth: 106
9495
+ splitMinWidth: 106,
9496
+ radius: "var(--cmp-button-radius-md)"
9398
9497
  }
9399
9498
  };
9400
9499
  function splitDivider(color, outline) {
@@ -9476,7 +9575,7 @@ var SDropdownButtonImpl = /* @__PURE__ */ forwardRef(
9476
9575
  );
9477
9576
  const splitIcon = /* @__PURE__ */ jsx(SIcon, { name: "etc", size: s.arrow, color: "var(--dd-icon)" });
9478
9577
  const triggerBase = cn(
9479
- "box-border inline-flex items-center whitespace-nowrap border border-solid outline-none transition-colors",
9578
+ "box-border inline-flex items-center whitespace-nowrap border-[length:var(--cmp-button-border-width-default)] border-solid outline-none transition-colors",
9480
9579
  "border-[color:var(--dd-border)] bg-[var(--dd-bg)] text-[color:var(--dd-text)]",
9481
9580
  disabled ? "cursor-not-allowed" : "cursor-pointer hover:bg-[var(--dd-bg-hover)]"
9482
9581
  );
@@ -9515,10 +9614,12 @@ var SDropdownButtonImpl = /* @__PURE__ */ forwardRef(
9515
9614
  type: "button",
9516
9615
  disabled,
9517
9616
  onClick: onLabelClick,
9518
- className: cn(triggerBase, "flex-1 justify-center rounded-l-[4px] border-r-0"),
9617
+ className: cn(triggerBase, "flex-1 justify-center border-r-0"),
9519
9618
  style: {
9619
+ borderTopLeftRadius: s.radius,
9620
+ borderBottomLeftRadius: s.radius,
9520
9621
  minHeight: s.height,
9521
- padding: `0 ${s.paddingX}px`,
9622
+ padding: `0 ${s.paddingX}`,
9522
9623
  fontSize: s.fontSize,
9523
9624
  ...colorVars
9524
9625
  },
@@ -9532,10 +9633,15 @@ var SDropdownButtonImpl = /* @__PURE__ */ forwardRef(
9532
9633
  type: "button",
9533
9634
  disabled,
9534
9635
  "aria-label": "\uBA54\uB274 \uC5F4\uAE30",
9535
- className: cn(triggerBase, "justify-center rounded-r-[4px] border-l"),
9636
+ className: cn(
9637
+ triggerBase,
9638
+ "justify-center border-l-[length:var(--cmp-button-border-width-default)]"
9639
+ ),
9536
9640
  style: {
9641
+ borderTopRightRadius: s.radius,
9642
+ borderBottomRightRadius: s.radius,
9537
9643
  minHeight: s.height,
9538
- minWidth: s.height,
9644
+ minWidth: s.toggleWidth,
9539
9645
  borderLeftColor: disabled ? "var(--cmp-button-border-disabled)" : splitDivider(color, outline),
9540
9646
  ...colorVars
9541
9647
  },
@@ -9549,11 +9655,12 @@ var SDropdownButtonImpl = /* @__PURE__ */ forwardRef(
9549
9655
  {
9550
9656
  type: "button",
9551
9657
  disabled,
9552
- className: cn(triggerBase, "justify-between rounded-[4px]", className),
9658
+ className: cn(triggerBase, "justify-between rounded-(--dd-radius)", className),
9553
9659
  style: {
9660
+ ...{ "--dd-radius": s.radius },
9554
9661
  minWidth: s.minWidth,
9555
9662
  minHeight: s.height,
9556
- padding: `0 ${s.paddingX}px`,
9663
+ padding: `0 ${s.paddingX}`,
9557
9664
  gap: s.gap,
9558
9665
  fontSize: s.fontSize,
9559
9666
  ...colorVars,
@@ -9663,13 +9770,13 @@ function SSwitch({
9663
9770
  style
9664
9771
  }) {
9665
9772
  const right = rightLabel;
9666
- const renderLabel = (text) => text ? /* @__PURE__ */ jsx("span", { className: "typo-body-sm-medium break-keep wrap-break-word", children: text }) : null;
9773
+ const renderLabel = (text) => text ? /* @__PURE__ */ jsx("span", { className: "typo-field-sm-medium break-keep wrap-break-word", children: text }) : null;
9667
9774
  const trackBg = disabled ? value ? "var(--cmp-switch-bg-disabled-on)" : "var(--cmp-switch-bg-disabled-off)" : value ? "var(--cmp-switch-bg-on)" : "var(--cmp-switch-bg-off)";
9668
9775
  return /* @__PURE__ */ jsxs(
9669
9776
  "label",
9670
9777
  {
9671
9778
  className: cn(
9672
- "inline-flex items-center gap-[6px]",
9779
+ "inline-flex items-center gap-(--cmp-switch-gap)",
9673
9780
  disabled ? "cursor-not-allowed" : "cursor-pointer",
9674
9781
  className
9675
9782
  ),
@@ -9683,14 +9790,14 @@ function SSwitch({
9683
9790
  disabled,
9684
9791
  onCheckedChange: (v) => onValueChange?.(v),
9685
9792
  className: cn(
9686
- "relative h-[20px] w-[32px] flex-shrink-0 rounded-full p-[2px] outline-none transition-colors duration-200",
9793
+ "relative h-(--cmp-switch-height) w-(--cmp-switch-width) flex-shrink-0 rounded-(--cmp-switch-radius) p-(--cmp-switch-paddingXY) outline-none transition-colors duration-200",
9687
9794
  disabled ? "cursor-not-allowed" : "cursor-pointer"
9688
9795
  ),
9689
9796
  style: { background: trackBg },
9690
9797
  children: /* @__PURE__ */ jsx(
9691
9798
  RSwitch.Thumb,
9692
9799
  {
9693
- className: "block h-[16px] w-[16px] rounded-full shadow-[0_2px_4px_rgba(0,0,0,0.16)] transition-transform duration-200 data-[state=checked]:translate-x-[12px]",
9800
+ className: "block h-(--cmp-switch-knob-size) w-(--cmp-switch-knob-size) rounded-full shadow-[0_2px_4px_rgba(0,0,0,0.16)] transition-transform duration-200 data-[state=checked]:translate-x-[calc(var(--cmp-switch-width)_-_var(--cmp-switch-knob-size)_-_var(--cmp-switch-paddingXY)_*_2)]",
9694
9801
  style: {
9695
9802
  background: disabled ? "var(--cmp-switch-knob-disabled)" : "var(--cmp-switch-knob-default)"
9696
9803
  }
@@ -10418,8 +10525,8 @@ var SSystemActionButton = /* @__PURE__ */ forwardRef(
10418
10525
  }
10419
10526
  );
10420
10527
  var SIZE_CLASSES = {
10421
- xs: "h-[24px] px-[8px] text-[12px] font-normal leading-[20px]",
10422
- sm: "h-[28px] px-[12px] text-[14px] font-medium leading-[24px]"
10528
+ xs: "h-(--cmp-toggle-xs-height) px-(--cmp-toggle-xs-paddingX) typo-control-xs-default",
10529
+ sm: "h-(--cmp-toggle-sm-height) px-(--cmp-toggle-sm-paddingX) typo-control-sm-default"
10423
10530
  };
10424
10531
  function SToggle({
10425
10532
  value = false,
@@ -10441,7 +10548,7 @@ function SToggle({
10441
10548
  "aria-pressed": value,
10442
10549
  onClick: () => !disabled && onValueChange?.(!value),
10443
10550
  className: cn(
10444
- "box-border inline-flex items-center justify-center whitespace-nowrap rounded-full border border-solid transition-colors",
10551
+ "box-border inline-flex items-center justify-center whitespace-nowrap rounded-(--cmp-toggle-radius) border-(length:--cmp-toggle-border-width) border-solid transition-colors",
10445
10552
  SIZE_CLASSES[size],
10446
10553
  disabled ? "cursor-not-allowed" : "cursor-pointer",
10447
10554
  // 미선택(off) hover 시 파란 채움 + 흰 글자
@@ -10527,10 +10634,17 @@ function SPopover({
10527
10634
  menuTitle && /* @__PURE__ */ jsxs(
10528
10635
  "div",
10529
10636
  {
10530
- className: "flex items-center gap-[var(--cmp-popover-title-gap)] text-[14px] font-bold leading-[24px]",
10637
+ className: "typo-feedback-md-bold flex items-center gap-[var(--cmp-popover-title-gap)]",
10531
10638
  style: { color: titleColor },
10532
10639
  children: [
10533
- titleIcon && /* @__PURE__ */ jsx(SIcon, { name: titleIcon, size: 16, color: titleColor }),
10640
+ titleIcon && /* @__PURE__ */ jsx(
10641
+ SIcon,
10642
+ {
10643
+ name: titleIcon,
10644
+ size: "var(--cmp-popover-title-leadingIcon)",
10645
+ color: titleColor
10646
+ }
10647
+ ),
10534
10648
  /* @__PURE__ */ jsx("span", { className: "min-w-0", children: menuTitle })
10535
10649
  ]
10536
10650
  }
@@ -10667,14 +10781,14 @@ function SGuide({
10667
10781
  }
10668
10782
  setOpen((o) => !o);
10669
10783
  },
10670
- className: "inline-flex h-[var(--cmp-guide-button-height)] cursor-pointer items-center gap-[var(--cmp-guide-button-gap)] whitespace-nowrap rounded-[var(--cmp-guide-button-radius)] border-[length:var(--cmp-guide-button-border-width)] border-solid px-[var(--cmp-guide-button-paddingX)] text-[12px] font-medium leading-[20px] transition-colors",
10784
+ className: "inline-flex h-[var(--cmp-guide-button-height)] cursor-pointer items-center gap-[var(--cmp-guide-button-gap)] whitespace-nowrap rounded-[var(--cmp-guide-button-radius)] border-[length:var(--cmp-guide-button-border-width)] border-solid px-[var(--cmp-guide-button-paddingX)] typo-control-xs-medium transition-colors",
10671
10785
  style: {
10672
10786
  borderColor: active ? activeBg : "var(--cmp-guide-button-border-default)",
10673
10787
  background: active ? activeBg : "var(--cmp-guide-button-bg-default)",
10674
10788
  color: active ? "var(--cmp-guide-button-text-active)" : "var(--cmp-guide-button-text-default)"
10675
10789
  },
10676
10790
  children: [
10677
- /* @__PURE__ */ jsx(SIcon, { name: iconName, size: 16, color: iconColor }),
10791
+ /* @__PURE__ */ jsx(SIcon, { name: iconName, size: "var(--cmp-guide-button-icon-size)", color: iconColor }),
10678
10792
  label || defaultLabel
10679
10793
  ]
10680
10794
  }
@@ -10724,11 +10838,11 @@ function SGuide({
10724
10838
  color: isNotion ? "var(--sys-color-fg-primary)" : "var(--cmp-guide-contents-icon)"
10725
10839
  }
10726
10840
  ),
10727
- /* @__PURE__ */ jsx("h3", { className: "m-0 break-keep text-[16px] font-bold leading-[26px] text-[color:var(--cmp-guide-contents-typography-color)]", children: popupTitle || defaultLabel })
10841
+ /* @__PURE__ */ jsx("h3", { className: "typo-heading-md m-0 break-keep text-[color:var(--cmp-guide-contents-typography-color)]", children: popupTitle || defaultLabel })
10728
10842
  ]
10729
10843
  }
10730
10844
  ),
10731
- /* @__PURE__ */ jsx("ul", { className: "m-0 mt-[var(--cmp-guide-contents-gap)] flex w-full list-none flex-col gap-[var(--cmp-guide-contents-body-gap)] p-0 text-[12px] leading-[20px] text-[color:var(--cmp-guide-contents-typography-color)]", children: messages.map((m, i) => /* @__PURE__ */ jsx(
10845
+ /* @__PURE__ */ jsx("ul", { className: "m-0 mt-[var(--cmp-guide-contents-gap)] flex w-full list-none flex-col gap-[var(--cmp-guide-contents-body-gap)] p-0 typo-field-sm-default text-[color:var(--cmp-guide-contents-typography-color)]", children: messages.map((m, i) => /* @__PURE__ */ jsx(
10732
10846
  "li",
10733
10847
  {
10734
10848
  className: cn(
@@ -10999,15 +11113,22 @@ function SConfirmModal({
10999
11113
  showClose: true,
11000
11114
  onClose: () => settle(onClose),
11001
11115
  className: "w-fit min-w-[min(520px,calc(100dvw-48px))]",
11002
- children: /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-auto flex-col items-center gap-[40px] px-[32px] py-[40px]", children: [
11003
- /* @__PURE__ */ jsxs("div", { className: "flex w-full min-h-0 flex-col items-center gap-[20px] overflow-y-auto", children: [
11004
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-[12px]", children: [
11005
- iconName && /* @__PURE__ */ jsx(SIcon, { name: iconName, size: 32, color: TYPE_ICON_COLOR[type] }),
11116
+ children: /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-auto flex-col items-center gap-(--cmp-modal-confirm-gap) px-(--cmp-modal-confirm-paddingX) py-(--cmp-modal-confirm-paddingY)", children: [
11117
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full min-h-0 flex-col items-center gap-(--cmp-modal-confirm-body-gap) overflow-y-auto", children: [
11118
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-(--cmp-modal-confirm-title-gap)", children: [
11119
+ iconName && /* @__PURE__ */ jsx(
11120
+ SIcon,
11121
+ {
11122
+ name: iconName,
11123
+ size: "var(--cmp-modal-confirm-title-icon)",
11124
+ color: TYPE_ICON_COLOR[type]
11125
+ }
11126
+ ),
11006
11127
  /* @__PURE__ */ jsx(
11007
11128
  "h2",
11008
11129
  {
11009
11130
  className: cn(
11010
- "text-center text-[18px] font-bold leading-[30px] text-[color:var(--cmp-modal-confirm-title-color)]",
11131
+ "typo-heading-lg text-center text-[color:var(--cmp-modal-confirm-title-color)]",
11011
11132
  titleClassName
11012
11133
  ),
11013
11134
  children: modalTitle
@@ -11096,7 +11217,7 @@ function SOverlayHeader({
11096
11217
  {
11097
11218
  className: cn(
11098
11219
  "m-0 overflow-hidden text-ellipsis whitespace-nowrap",
11099
- "text-[16px] font-bold leading-[26px]",
11220
+ "typo-heading-md",
11100
11221
  titleClassName
11101
11222
  ),
11102
11223
  style: { color: "var(--cmp-overlay-header-title-color)" },
@@ -11191,8 +11312,8 @@ function SLoadingModal({
11191
11312
  showButton = false,
11192
11313
  buttonLabel,
11193
11314
  onButtonClick,
11194
- width = 520,
11195
- height = 320
11315
+ width = "var(--cmp-modal-loading-width)",
11316
+ height = "var(--cmp-modal-loading-height)"
11196
11317
  }) {
11197
11318
  const resolvedMessage = message ?? DEFAULT_MESSAGE[state2];
11198
11319
  const lines = Array.isArray(resolvedMessage) ? resolvedMessage : resolvedMessage ? [resolvedMessage] : [];
@@ -11208,8 +11329,15 @@ function SLoadingModal({
11208
11329
  ariaTitle: lines[0] || "\uB85C\uB529 \uC911",
11209
11330
  width,
11210
11331
  height,
11211
- children: /* @__PURE__ */ jsx("div", { className: "flex min-h-0 flex-auto flex-col overflow-y-auto px-[32px]", children: /* @__PURE__ */ jsxs("div", { className: "m-auto flex flex-col items-center gap-[20px]", children: [
11212
- state2 === "loading" ? progress !== void 0 ? /* @__PURE__ */ jsx(SCircleProgress, { value: progress }) : /* @__PURE__ */ jsx(SCircleProgress, { indeterminate: true }) : /* @__PURE__ */ jsx(SIcon, { name: "warningOutline", size: 80, color: "var(--cmp-modal-confirm-negative-icon)" }),
11332
+ children: /* @__PURE__ */ jsx("div", { className: "flex min-h-0 flex-auto flex-col overflow-y-auto px-[32px]", children: /* @__PURE__ */ jsxs("div", { className: "m-auto flex flex-col items-center gap-(--cmp-modal-loading-gap)", children: [
11333
+ state2 === "loading" ? progress !== void 0 ? /* @__PURE__ */ jsx(SCircleProgress, { value: progress }) : /* @__PURE__ */ jsx(SCircleProgress, { indeterminate: true }) : /* @__PURE__ */ jsx(
11334
+ SIcon,
11335
+ {
11336
+ name: "warningOutline",
11337
+ size: "var(--cmp-modal-loading-content)",
11338
+ color: "var(--cmp-modal-confirm-negative-icon)"
11339
+ }
11340
+ ),
11213
11341
  lines.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-[2px]", children: lines.map((m, i) => /* @__PURE__ */ jsx(
11214
11342
  "p",
11215
11343
  {
@@ -11997,13 +12125,8 @@ var LAUNCHER_LIST_BOX_LAYOUT = {
11997
12125
  radius: gnb("launcher-listBox-radius"),
11998
12126
  /** 패널 상하좌우 여백 */
11999
12127
  padding: gnb("launcher-listBox-paddingAll"),
12000
- /**
12001
- * 패널 그림자.
12002
- * 토큰(`component.gnb.launcher.listBox.shadow` = `{shadow.floating}`)은 값이 배열이라
12003
- * `--cmp-*` 로 나오지 않는다 — 생성기가 스칼라만 내보내기 때문이다. 그래서 그 별칭이
12004
- * 가리키는 스케일 토큰을 직접 쓴다(같은 값이다).
12005
- */
12006
- shadow: "var(--shadow-floating)",
12128
+ /** 패널 그림자 */
12129
+ shadow: gnb("launcher-listBox-shadow"),
12007
12130
  /** 줄 왼쪽 여백 */
12008
12131
  itemPaddingLeft: gnb("launcher-button-paddingLeft"),
12009
12132
  /** 줄 오른쪽 여백 — 왼쪽보다 좁다(오른쪽 끝은 hover 아이콘 자리다) */
@@ -12374,20 +12497,19 @@ var GNB_MENU = {
12374
12497
  depth3PaddingLeft: box2("item-depth3-paddingLeft"),
12375
12498
  depth1Icon: box2("item-depth1-icon"),
12376
12499
  // box 는 depth1 전용 타이포 토큰이 없어 depth1 도 selected 타이포를 따른다
12500
+ depth1Typo: "typo-navigation-lg-semibold",
12501
+ // token: gnb.box.item.typography.selected
12502
+ itemTypo: "typo-navigation-lg-medium",
12503
+ // token: gnb.box.item.typography.default
12504
+ itemTypoSelected: "typo-navigation-lg-semibold",
12505
+ // token: gnb.box.item.typography.selected
12377
12506
  depth1FontSize: 14,
12378
- // token: gnb.box.item.typography.selected.fontSize
12379
12507
  depth1LineHeight: 24,
12380
- // token: gnb.box.item.typography.selected.lineHeight
12381
12508
  depth1FontWeight: 600,
12382
- // token: gnb.box.item.typography.selected.fontWeight
12383
12509
  itemFontSize: 14,
12384
- // token: gnb.box.item.typography.default.fontSize
12385
12510
  itemLineHeight: 24,
12386
- // token: gnb.box.item.typography.default.lineHeight
12387
12511
  itemFontWeight: 500,
12388
- // token: gnb.box.item.typography.default.fontWeight
12389
12512
  itemFontWeightSelected: 600
12390
- // token: gnb.box.item.typography.selected.fontWeight
12391
12513
  },
12392
12514
  belt: {
12393
12515
  bodyPaddingY: gnb2("body-padding"),
@@ -12404,20 +12526,19 @@ var GNB_MENU = {
12404
12526
  depth3PaddingLeft: belt("item-depth3-paddingLeft"),
12405
12527
  depth1Icon: belt("item-depth1-icon"),
12406
12528
  // belt 전용 depth1 아이콘 토큰(16)
12529
+ depth1Typo: "typo-navigation-md-bold",
12530
+ // token: gnb.belt.item.depth1.typography
12531
+ itemTypo: "typo-navigation-sm-medium",
12532
+ // token: gnb.belt.item.typography.default
12533
+ itemTypoSelected: "typo-navigation-sm-bold",
12534
+ // token: gnb.belt.item.typography.selected
12407
12535
  depth1FontSize: 13,
12408
- // token: gnb.belt.item.depth1.typography.fontSize
12409
12536
  depth1LineHeight: 22,
12410
- // token: gnb.belt.item.depth1.typography.lineHeight
12411
12537
  depth1FontWeight: 700,
12412
- // token: gnb.belt.item.depth1.typography.fontWeight
12413
12538
  itemFontSize: 12,
12414
- // token: gnb.belt.item.typography.default.fontSize
12415
12539
  itemLineHeight: 20,
12416
- // token: gnb.belt.item.typography.default.lineHeight
12417
12540
  itemFontWeight: 500,
12418
- // token: gnb.belt.item.typography.default.fontWeight
12419
12541
  itemFontWeightSelected: 700
12420
- // token: gnb.belt.item.typography.selected.fontWeight
12421
12542
  }
12422
12543
  };
12423
12544
  var GNB_COLORS = {
@@ -12462,15 +12583,16 @@ var GNB_RAIL = {
12462
12583
  itemPaddingBottom: gnb2("rail-item-paddingBottom"),
12463
12584
  itemRadius: gnb2("rail-item-radius"),
12464
12585
  itemIcon: gnb2("rail-item-icon"),
12465
- // 타이포 (theme.css 에 gnb 타이포 변수 없음 → 토큰 값 직접 명시)
12586
+ // 타이포 — 토큰이 가리키는 typo-* 클래스
12587
+ itemTypo: "typo-navigation-xs-medium",
12588
+ // token: gnb.rail.item.typography.default
12589
+ itemTypoSelected: "typo-navigation-xs-bold",
12590
+ // token: gnb.rail.item.typography.selected
12591
+ // 아래 숫자는 공개 export 라 남겨 둔 같은 값이다 — 렌더에는 쓰지 않는다
12466
12592
  itemFontSize: 11,
12467
- // token: gnb.rail.item.typography.default.fontSize
12468
12593
  itemLineHeight: 18,
12469
- // token: gnb.rail.item.typography.default.lineHeight
12470
12594
  itemFontWeight: 500,
12471
- // token: gnb.rail.item.typography.default.fontWeight
12472
12595
  itemFontWeightSelected: 700
12473
- // token: gnb.rail.item.typography.selected.fontWeight
12474
12596
  };
12475
12597
  var GNB_RAIL_WIDTH = 68;
12476
12598
  var GNB_FOLD_MS = 200;
@@ -12704,7 +12826,10 @@ var SGnb = /* @__PURE__ */ forwardRef(function SGnb2({
12704
12826
  type: "button",
12705
12827
  disabled: item4.disabled,
12706
12828
  "aria-current": isActive ? "true" : void 0,
12707
- className: "box-border flex select-none flex-col items-center border-none bg-transparent transition-colors duration-150",
12829
+ className: cn(
12830
+ "box-border flex select-none flex-col items-center border-none bg-transparent transition-colors duration-150",
12831
+ isActive ? GNB_RAIL.itemTypoSelected : GNB_RAIL.itemTypo
12832
+ ),
12708
12833
  style: {
12709
12834
  width: GNB_RAIL.itemWidth,
12710
12835
  paddingTop: GNB_RAIL.itemPaddingTop,
@@ -12714,9 +12839,6 @@ var SGnb = /* @__PURE__ */ forwardRef(function SGnb2({
12714
12839
  color: isActive ? C.itemColorActive : C.railFgDefault,
12715
12840
  // <button> 의 UA 폰트를 끊고 앱 폰트를 잇는다 (메뉴 아이템과 같은 이유)
12716
12841
  fontFamily: "inherit",
12717
- fontSize: GNB_RAIL.itemFontSize,
12718
- lineHeight: `${GNB_RAIL.itemLineHeight}px`,
12719
- fontWeight: isActive ? GNB_RAIL.itemFontWeightSelected : GNB_RAIL.itemFontWeight,
12720
12842
  opacity: item4.disabled ? 0.4 : 1,
12721
12843
  cursor: item4.disabled ? "not-allowed" : "pointer"
12722
12844
  },
@@ -12755,9 +12877,6 @@ var SGnb = /* @__PURE__ */ forwardRef(function SGnb2({
12755
12877
  color: isSelected ? C.itemColorActive : isHovered ? C.itemColorHover : C.itemColorDefault,
12756
12878
  // <button> 의 UA 폰트(Arial 13.3px)를 끊고 앱 폰트를 잇는다
12757
12879
  fontFamily: "inherit",
12758
- fontSize: depth === 1 ? M.depth1FontSize : M.itemFontSize,
12759
- lineHeight: `${depth === 1 ? M.depth1LineHeight : M.itemLineHeight}px`,
12760
- fontWeight: depth === 1 ? M.depth1FontWeight : isSelected ? M.itemFontWeightSelected : M.itemFontWeight,
12761
12880
  opacity: item4.disabled ? 0.4 : 1,
12762
12881
  cursor: item4.disabled ? "not-allowed" : "pointer"
12763
12882
  };
@@ -12772,7 +12891,10 @@ var SGnb = /* @__PURE__ */ forwardRef(function SGnb2({
12772
12891
  disabled: item4.disabled,
12773
12892
  "aria-expanded": hasChildren ? isExpanded : void 0,
12774
12893
  "aria-current": isSelected ? "page" : void 0,
12775
- className: "box-border flex select-none items-center border-none bg-transparent text-left transition-colors duration-150",
12894
+ className: cn(
12895
+ "box-border flex select-none items-center border-none bg-transparent text-left transition-colors duration-150",
12896
+ depth === 1 ? M.depth1Typo : isSelected ? M.itemTypoSelected : M.itemTypo
12897
+ ),
12776
12898
  style: itemStyle,
12777
12899
  onClick: () => handleItemClick(item4),
12778
12900
  ...rowHoverProps(item4),
@@ -13958,8 +14080,10 @@ var SPageHeader = /* @__PURE__ */ withDisplayName(
13958
14080
  );
13959
14081
 
13960
14082
  // src/components/STabs/tabs.config.ts
13961
- var TAB_MAIN_SIZE = { height: 36, paddingX: 24 };
13962
- var TAB_TYPOGRAPHY = { fontSize: 12, lineHeight: 20 };
14083
+ var TAB_MAIN_SIZE = {
14084
+ height: "var(--cmp-tab-main-height)",
14085
+ paddingX: "var(--cmp-tab-main-paddingX)"
14086
+ };
13963
14087
  var TAB_MAIN_COLORS = {
13964
14088
  selected: {
13965
14089
  bg: "var(--cmp-tab-main-selected-bg)",
@@ -14004,7 +14128,7 @@ function STabs({
14004
14128
  // main(가로): baseline(하단 divider)이 100% 너비로 채워지도록 w-full
14005
14129
  sub ? "inline-flex w-fit" : "flex w-full",
14006
14130
  isVertical ? "flex-col items-stretch" : "flex-row",
14007
- sub ? isVertical ? "gap-[16px]" : "gap-[24px]" : "gap-[4px]",
14131
+ sub ? isVertical ? "gap-(--cmp-tab-sub-gap-vertical)" : "gap-(--cmp-tab-sub-gap-horizontal)" : "gap-(--cmp-tab-main-container-gap)",
14008
14132
  className
14009
14133
  ),
14010
14134
  style: containerStyle,
@@ -14014,30 +14138,26 @@ function STabs({
14014
14138
  let tabStyle;
14015
14139
  if (sub) {
14016
14140
  tabStyle = {
14017
- height: 20,
14018
- paddingBottom: 4,
14019
- fontSize: TAB_TYPOGRAPHY.fontSize,
14020
- lineHeight: `${TAB_TYPOGRAPHY.lineHeight}px`,
14141
+ height: "var(--cmp-tab-sub-item-height)",
14142
+ paddingBottom: "var(--cmp-tab-sub-content-gap)",
14021
14143
  color: selected ? TAB_SUB_COLORS.selected.text : TAB_SUB_COLORS.default.text,
14022
- borderBottom: `1px solid ${selected ? TAB_SUB_COLORS.selected.line : "transparent"}`
14144
+ borderBottom: `var(--cmp-tab-sub-border-width) solid ${selected ? TAB_SUB_COLORS.selected.line : "transparent"}`
14023
14145
  };
14024
14146
  } else {
14025
14147
  const border = selected ? TAB_MAIN_COLORS.selected.border : TAB_MAIN_COLORS.default.border;
14026
14148
  const selectedBg = TAB_MAIN_COLORS.selected.bg;
14027
14149
  tabStyle = {
14028
14150
  height: TAB_MAIN_SIZE.height,
14029
- padding: `0 ${TAB_MAIN_SIZE.paddingX}px`,
14030
- fontSize: TAB_TYPOGRAPHY.fontSize,
14031
- lineHeight: `${TAB_TYPOGRAPHY.lineHeight}px`,
14151
+ padding: `0 ${TAB_MAIN_SIZE.paddingX}`,
14032
14152
  background: selected ? TAB_MAIN_COLORS.selected.bg : TAB_MAIN_COLORS.default.bg,
14033
14153
  color: selected ? TAB_MAIN_COLORS.selected.text : TAB_MAIN_COLORS.default.text,
14034
- border: `1px solid ${border}`,
14154
+ border: `var(--cmp-tab-main-border-width) solid ${border}`,
14035
14155
  // 폴더형: 미선택 탭은 baseline 위에, 선택 탭은 baseline(파란선)을 1px 덮어 연결된 것처럼 보이게
14036
- borderTopLeftRadius: 6,
14037
- borderTopRightRadius: 6,
14156
+ borderTopLeftRadius: "var(--cmp-tab-main-radius)",
14157
+ borderTopRightRadius: "var(--cmp-tab-main-radius)",
14038
14158
  borderBottomLeftRadius: 0,
14039
14159
  borderBottomRightRadius: 0,
14040
- borderBottom: selected ? `1px solid ${selectedBg}` : "none",
14160
+ borderBottom: selected ? `var(--cmp-tab-main-border-width) solid ${selectedBg}` : "none",
14041
14161
  marginBottom: selected ? -1 : 0
14042
14162
  };
14043
14163
  }
@@ -14074,12 +14194,17 @@ function STabs({
14074
14194
  moveTo(tabs.length - 1);
14075
14195
  }
14076
14196
  },
14077
- className: "relative box-border inline-flex cursor-pointer select-none items-center justify-center gap-[8px] whitespace-nowrap outline-none transition-[color,background-color] duration-200",
14197
+ className: cn(
14198
+ "relative box-border inline-flex cursor-pointer select-none items-center justify-center whitespace-nowrap outline-none transition-[color,background-color] duration-200",
14199
+ sub ? "gap-[8px]" : "gap-(--cmp-tab-main-gap)",
14200
+ // 타이포 (token: tab.<main|sub>.<selected|default>.typography)
14201
+ selected ? "typo-navigation-sm-bold" : "typo-navigation-sm-default"
14202
+ ),
14078
14203
  style: tabStyle,
14079
14204
  children: [
14080
14205
  /* @__PURE__ */ jsxs("span", { className: "grid", children: [
14081
14206
  /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "invisible font-bold", style: { gridArea: "1 / 1" }, children: tab.label }),
14082
- /* @__PURE__ */ jsx("span", { style: { gridArea: "1 / 1", fontWeight: selected ? 700 : 400 }, children: tab.label })
14207
+ /* @__PURE__ */ jsx("span", { style: { gridArea: "1 / 1" }, children: tab.label })
14083
14208
  ] }),
14084
14209
  tab.badge !== void 0 && tab.badge !== null && tab.badge !== "" && /* @__PURE__ */ jsx(
14085
14210
  STag,
@@ -14130,7 +14255,7 @@ function SPagination({
14130
14255
  "aria-label": aria,
14131
14256
  onClick,
14132
14257
  className: "flex h-[var(--cmp-pagination-height)] w-[var(--cmp-pagination-height)] cursor-pointer items-center justify-center rounded-[var(--cmp-pagination-radius)] border-none bg-transparent hover:bg-[var(--cmp-pagination-item-bg-hover)]",
14133
- children: /* @__PURE__ */ jsx(SIcon, { name: icon, size: 12, color: "var(--color-grey-65)" })
14258
+ children: /* @__PURE__ */ jsx(SIcon, { name: icon, size: "var(--cmp-pagination-icon)", color: "var(--color-grey-65)" })
14134
14259
  }
14135
14260
  );
14136
14261
  const prevButtons = simple ? currentPage > 1 && /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -14154,8 +14279,8 @@ function SPagination({
14154
14279
  style,
14155
14280
  children: [
14156
14281
  /* @__PURE__ */ jsx("div", { className: "flex min-w-[calc(var(--cmp-pagination-height)*2+var(--cmp-pagination-move-gap))] items-center justify-end gap-[var(--cmp-pagination-move-gap)]", children: prevButtons }),
14157
- simple ? /* @__PURE__ */ jsxs("div", { className: "flex h-[var(--cmp-pagination-height)] items-center gap-[var(--cmp-pagination-simple-gap)] px-[var(--cmp-pagination-paddingX)] text-[12px] font-medium leading-[20px] text-[color:var(--cmp-pagination-item-content-default)]", children: [
14158
- /* @__PURE__ */ jsx("span", { className: "font-bold text-[color:var(--cmp-pagination-item-content-selected)]", children: currentPage }),
14282
+ simple ? /* @__PURE__ */ jsxs("div", { className: "flex h-[var(--cmp-pagination-height)] items-center gap-[var(--cmp-pagination-simple-gap)] px-[var(--cmp-pagination-paddingX)] typo-control-xs-medium text-[color:var(--cmp-pagination-item-content-default)]", children: [
14283
+ /* @__PURE__ */ jsx("span", { className: "typo-control-xs-bold text-[color:var(--cmp-pagination-item-content-selected)]", children: currentPage }),
14159
14284
  /* @__PURE__ */ jsx("span", { children: "/" }),
14160
14285
  /* @__PURE__ */ jsx("span", { children: lastPage })
14161
14286
  ] }) : /* @__PURE__ */ jsx("div", { className: "flex items-center gap-[var(--cmp-pagination-move-gap)]", children: pageNumbers.map((n) => {
@@ -14167,8 +14292,8 @@ function SPagination({
14167
14292
  "aria-current": selected ? "page" : void 0,
14168
14293
  onClick: () => go(n),
14169
14294
  className: cn(
14170
- "box-border flex h-[var(--cmp-pagination-height)] cursor-pointer items-center justify-center rounded-[var(--cmp-pagination-radius)] border-none px-[var(--cmp-pagination-paddingX)] text-[12px] leading-[20px]",
14171
- selected ? "bg-[var(--cmp-pagination-item-bg-selected)] font-bold text-[color:var(--cmp-pagination-item-content-selected)]" : "bg-transparent font-medium text-[color:var(--cmp-pagination-item-content-default)] hover:bg-[var(--cmp-pagination-item-bg-hover)] hover:text-[color:var(--cmp-pagination-item-content-hover)]"
14295
+ "box-border flex h-[var(--cmp-pagination-height)] cursor-pointer items-center justify-center rounded-[var(--cmp-pagination-radius)] border-none px-[var(--cmp-pagination-paddingX)]",
14296
+ selected ? "bg-[var(--cmp-pagination-item-bg-selected)] typo-control-xs-bold text-[color:var(--cmp-pagination-item-content-selected)]" : "bg-transparent typo-control-xs-medium text-[color:var(--cmp-pagination-item-content-default)] hover:bg-[var(--cmp-pagination-item-bg-hover)] hover:text-[color:var(--cmp-pagination-item-content-hover)]"
14172
14297
  ),
14173
14298
  style: { width: itemWidth },
14174
14299
  children: n
@@ -14191,15 +14316,18 @@ var STEPPER_SIZE_CONFIG = {
14191
14316
  sequenceSize: V2("sm-sequence-size"),
14192
14317
  fontSize: "12px",
14193
14318
  lineHeight: "20px",
14194
- fontWeightActive: 700,
14195
- fontWeightDefault: 500
14319
+ typoDefault: "typo-navigation-sm-medium",
14320
+ typoActive: "typo-navigation-sm-bold",
14321
+ fontWeightActive: 700
14196
14322
  },
14197
14323
  lg: {
14198
14324
  sequenceSize: V2("lg-sequence-size"),
14199
14325
  fontSize: "14px",
14200
14326
  lineHeight: "24px",
14201
- fontWeightActive: 700,
14202
- fontWeightDefault: 500
14327
+ typoDefault: "typo-navigation-lg-medium",
14328
+ // 토큰(navigation.lg.semibold)은 600 인데 지금 700 으로 그린다 — 값이 달라 토큰을 쓰지 않는다
14329
+ typoActive: null,
14330
+ fontWeightActive: 700
14203
14331
  }
14204
14332
  };
14205
14333
  var STEPPER_LAYOUT = {
@@ -14225,7 +14353,9 @@ var STEPPER_COLORS = {
14225
14353
  sequenceText: {
14226
14354
  active: V2("sequence-text-active"),
14227
14355
  default: V2("sequence-text-default"),
14228
- completed: VF("sequence-text-completed", "#0075FF")
14356
+ // 완료 시퀀스의 체크 아이콘 색은 전용 토큰이 없다(stepper.sequence.text 에 completed 가 없음).
14357
+ // 진행 중 시퀀스 숫자와 같은 accent 색을 시맨틱 토큰으로 직접 쓴다.
14358
+ completed: "var(--sys-color-fg-accent)"
14229
14359
  },
14230
14360
  text: {
14231
14361
  active: V2("text-active"),
@@ -14240,14 +14370,15 @@ var STEPPER_HORIZONTAL_COMPLETED_COLORS = {
14240
14370
  text: STEPPER_COLORS.text.completed
14241
14371
  };
14242
14372
  var STEPPER_VERTICAL_LAYOUT = {
14243
- width: VF("vertical-width", "240px"),
14373
+ /** 세로형 폭. 대응 토큰이 없어 디자인 값을 그대로 쓴다(stepper.vertical 에 width 가 없음). */
14374
+ width: "240px",
14244
14375
  itemGap: VF("vertical-item-gap", "12px"),
14245
14376
  itemPaddingX: VF("vertical-item-paddingX", "16px"),
14246
14377
  itemPaddingY: VF("vertical-item-paddingY", "8px"),
14247
14378
  titlePaddingTop: VF("vertical-title-paddingTop", "12px"),
14248
14379
  titlePaddingBottom: VF("vertical-title-paddingBottom", "4px"),
14249
- titleFontSize: VF("vertical-title-font-size", "11px"),
14250
- titleLineHeight: VF("vertical-title-line-height", "18px"),
14380
+ /** 구간 제목 타이포 — stepper.vertical.title.typography (= heading.xxs) */
14381
+ titleTypo: "typo-heading-xxs",
14251
14382
  accentStripeWidth: VF("vertical-item-accentStripe-width", "2px"),
14252
14383
  accentStripeColor: VF("vertical-item-accentStripe-color", "#64ABFF")
14253
14384
  };
@@ -14257,6 +14388,7 @@ var STEPPER_VERTICAL_COLORS = {
14257
14388
  hover: VF("vertical-item-bg-hover", "#F6F6F6"),
14258
14389
  selected: VF("vertical-item-bg-selected", "#EFF6FF")
14259
14390
  },
14391
+ titleBg: V2("vertical-title-bg"),
14260
14392
  titleText: VF("vertical-title-text", "#004290"),
14261
14393
  textDefault: STEPPER_COLORS.text.default,
14262
14394
  textCompleted: STEPPER_COLORS.text.completed,
@@ -14264,9 +14396,10 @@ var STEPPER_VERTICAL_COLORS = {
14264
14396
  sequenceBgActive: STEPPER_COLORS.sequenceBg.active,
14265
14397
  sequenceTextActive: STEPPER_COLORS.sequenceText.active,
14266
14398
  sequenceTextDefault: STEPPER_COLORS.sequenceText.default,
14267
- sequenceBorderCompleted: VF("vertical-sequence-border-completed", "#93C4FF"),
14268
- sequenceBgCompleted: VF("vertical-sequence-bg-completed", "#EFF6FF"),
14269
- sequenceIconCompleted: VF("vertical-sequence-icon-completed", "#0075FF"),
14399
+ // 세로형 전용 completed 토큰은 없다 — 가로형과 같은 sequence.*.completed 를 쓴다.
14400
+ sequenceBorderCompleted: STEPPER_COLORS.sequenceBorder.completed,
14401
+ sequenceBgCompleted: STEPPER_COLORS.sequenceBg.completed,
14402
+ sequenceIconCompleted: STEPPER_COLORS.sequenceText.completed,
14270
14403
  errorBadge: "#FB4444"
14271
14404
  };
14272
14405
  var ERROR_TOOLTIP_MESSAGE = "\uD655\uC778\uC774 \uD544\uC694\uD55C \uD56D\uBAA9\uC774 \uC788\uC2B5\uB2C8\uB2E4.";
@@ -14429,10 +14562,12 @@ var SStepper = /* @__PURE__ */ forwardRef(function SStepper2({
14429
14562
  if (isHorizontalCompleted) return STEPPER_HORIZONTAL_COMPLETED_COLORS.sequenceIcon;
14430
14563
  return STEPPER_COLORS.sequenceText[state2];
14431
14564
  })();
14565
+ const emphasized = state2 === "active" || isVertical && hovered;
14566
+ const itemTypo = emphasized ? config.typoActive : config.typoDefault;
14432
14567
  const itemStyle = {
14433
14568
  gap: STEPPER_LAYOUT.itemGap,
14434
14569
  color: itemColor,
14435
- fontWeight: state2 === "active" || isVertical && hovered ? config.fontWeightActive : config.fontWeightDefault
14570
+ fontWeight: itemTypo ? void 0 : config.fontWeightActive
14436
14571
  };
14437
14572
  const sequenceStyle = {
14438
14573
  width: config.sequenceSize,
@@ -14449,7 +14584,7 @@ var SStepper = /* @__PURE__ */ forwardRef(function SStepper2({
14449
14584
  {
14450
14585
  role: roleListItem ? "listitem" : void 0,
14451
14586
  "aria-current": roleListItem && state2 === "active" ? "step" : void 0,
14452
- className: "inline-flex items-center whitespace-nowrap",
14587
+ className: cn("inline-flex items-center whitespace-nowrap", itemTypo),
14453
14588
  style: itemStyle,
14454
14589
  children: [
14455
14590
  /* @__PURE__ */ jsx(
@@ -14495,7 +14630,7 @@ var SStepper = /* @__PURE__ */ forwardRef(function SStepper2({
14495
14630
  className: cn("relative inline-flex flex-col items-start", className),
14496
14631
  style: {
14497
14632
  width: STEPPER_VERTICAL_LAYOUT.width,
14498
- // 폭은 토큰이 정하되 부모보다 넓어지지 않는다 — 부모가 세로 스크롤바만큼 좁아지면 따라 줄어
14633
+ // 폭은 디자인 값(전용 토큰 없음)이되 부모보다 넓어지지 않는다 — 부모가 세로 스크롤바만큼 좁아지면 따라 줄어
14499
14634
  // 가로 넘침(가로 스크롤바)이 생기지 않는다
14500
14635
  maxWidth: "100%",
14501
14636
  fontSize: config.fontSize,
@@ -14527,18 +14662,18 @@ var SStepper = /* @__PURE__ */ forwardRef(function SStepper2({
14527
14662
  group.group && /* @__PURE__ */ jsx(
14528
14663
  "div",
14529
14664
  {
14530
- className: "flex w-full items-center overflow-hidden",
14665
+ className: cn(
14666
+ "flex w-full items-center overflow-hidden",
14667
+ STEPPER_VERTICAL_LAYOUT.titleTypo
14668
+ ),
14531
14669
  style: {
14532
14670
  gap: STEPPER_VERTICAL_LAYOUT.itemGap,
14533
14671
  paddingLeft: STEPPER_VERTICAL_LAYOUT.itemPaddingX,
14534
14672
  paddingRight: STEPPER_VERTICAL_LAYOUT.itemPaddingX,
14535
14673
  paddingTop: STEPPER_VERTICAL_LAYOUT.titlePaddingTop,
14536
14674
  paddingBottom: STEPPER_VERTICAL_LAYOUT.titlePaddingBottom,
14537
- background: STEPPER_VERTICAL_COLORS.itemBg.default,
14538
- color: STEPPER_VERTICAL_COLORS.titleText,
14539
- fontSize: STEPPER_VERTICAL_LAYOUT.titleFontSize,
14540
- lineHeight: STEPPER_VERTICAL_LAYOUT.titleLineHeight,
14541
- fontWeight: 700
14675
+ background: STEPPER_VERTICAL_COLORS.titleBg,
14676
+ color: STEPPER_VERTICAL_COLORS.titleText
14542
14677
  },
14543
14678
  children: /* @__PURE__ */ jsx("span", { className: "whitespace-nowrap", children: group.group })
14544
14679
  }
@@ -15117,8 +15252,8 @@ var CalendarDayCard = /* @__PURE__ */ forwardRef(function CalendarDayCard2({
15117
15252
  {
15118
15253
  className: cn(
15119
15254
  "inline-flex size-(--cmp-calendarBoard-daySequence-size) items-center justify-center rounded-(--cmp-calendarBoard-daySequence-radius)",
15120
- isToday ? "typo-body-md-bold bg-(--cmp-calendarBoard-daySequence-bg-today) text-(--cmp-calendarBoard-daySequence-text-today)" : cn(
15121
- "typo-body-md-medium",
15255
+ isToday ? "typo-item-md-selected bg-(--cmp-calendarBoard-daySequence-bg-today) text-(--cmp-calendarBoard-daySequence-text-today)" : cn(
15256
+ "typo-item-md-default",
15122
15257
  inCurrentMonth ? "text-(--cmp-calendarBoard-daySequence-text-default)" : "text-(--cmp-calendarBoard-daySequence-text-otherMonth)"
15123
15258
  ),
15124
15259
  // 오늘이 아니면서 선택된 날은 테두리 원으로 표시한다 (오늘은 이미 채운 원이라 겹치지 않는다).
@@ -15676,14 +15811,12 @@ function clampToAvailableHeight(value, availableHeight) {
15676
15811
  }
15677
15812
  var FONT = {
15678
15813
  sm: {
15679
- fontSize: 12,
15680
- lineHeight: 20,
15814
+ typo: "typo-field-sm-default",
15681
15815
  paddingX: "var(--cmp-textinput-sm-paddingX)",
15682
15816
  gap: "var(--cmp-textinput-sm-gap)"
15683
15817
  },
15684
15818
  md: {
15685
- fontSize: 14,
15686
- lineHeight: 24,
15819
+ typo: "typo-field-md-default",
15687
15820
  paddingX: "var(--cmp-textinput-md-paddingX)",
15688
15821
  gap: "var(--cmp-textinput-md-gap)"
15689
15822
  }
@@ -15722,12 +15855,10 @@ var SSearchInput = /* @__PURE__ */ forwardRef(function SSearchInput2({
15722
15855
  children: /* @__PURE__ */ jsxs(
15723
15856
  "div",
15724
15857
  {
15725
- className: "flex h-full w-full items-center",
15858
+ className: cn("flex h-full w-full items-center", f.typo),
15726
15859
  style: {
15727
15860
  gap: f.gap,
15728
- padding: `0 ${f.paddingX}`,
15729
- fontSize: f.fontSize,
15730
- lineHeight: `${f.lineHeight}px`
15861
+ padding: `0 ${f.paddingX}`
15731
15862
  },
15732
15863
  children: [
15733
15864
  /* @__PURE__ */ jsx(
@@ -15788,6 +15919,18 @@ var SSearchInput = /* @__PURE__ */ forwardRef(function SSearchInput2({
15788
15919
  );
15789
15920
  });
15790
15921
 
15922
+ // src/lib/list-box-item.ts
15923
+ var LIST_BOX_ITEM_PADDING_LEFT = {
15924
+ 1: "var(--cmp-listBoxItem-paddingLeft-depth1)",
15925
+ 2: "var(--cmp-listBoxItem-paddingLeft-depth2)",
15926
+ 3: "var(--cmp-listBoxItem-paddingLeft-depth3)"
15927
+ };
15928
+ var LIST_BOX_ITEM_PADDING_Y_RIGHT = {
15929
+ paddingTop: "var(--cmp-listBoxItem-paddingY)",
15930
+ paddingBottom: "var(--cmp-listBoxItem-paddingY)",
15931
+ paddingRight: "var(--cmp-listBoxItem-paddingRight)"
15932
+ };
15933
+
15791
15934
  // src/components/SSelect/select.config.ts
15792
15935
  function flattenOptions(options, depth = 1, inheritDisabled = true) {
15793
15936
  const out = [];
@@ -15962,6 +16105,21 @@ var SSelectImpl = /* @__PURE__ */ forwardRef(function SSelect({
15962
16105
  const [focusedIndex, setFocusedIndex] = useState(-1);
15963
16106
  const [expanded, setExpanded] = useState(() => /* @__PURE__ */ new Set());
15964
16107
  const [searchCollapsed, setSearchCollapsed] = useState(NO_SEARCH_COLLAPSED);
16108
+ const [treeMotion, setTreeMotion] = useState(null);
16109
+ const treeMotionTimerRef = useRef(null);
16110
+ const pendingCollapseRef = useRef(null);
16111
+ const cancelTreeMotion = () => {
16112
+ if (treeMotionTimerRef.current != null) clearTimeout(treeMotionTimerRef.current);
16113
+ treeMotionTimerRef.current = null;
16114
+ pendingCollapseRef.current = null;
16115
+ setTreeMotion(null);
16116
+ };
16117
+ useEffect(
16118
+ () => () => {
16119
+ if (treeMotionTimerRef.current != null) clearTimeout(treeMotionTimerRef.current);
16120
+ },
16121
+ []
16122
+ );
15965
16123
  const baseId = useId();
15966
16124
  const listboxId = `${baseId}-listbox`;
15967
16125
  const activeOptionId = `${baseId}-active-option`;
@@ -16029,6 +16187,7 @@ var SSelectImpl = /* @__PURE__ */ forwardRef(function SSelect({
16029
16187
  const commitOpen = (next, valueForRules) => {
16030
16188
  setOpen(next);
16031
16189
  onOpenChange?.(next);
16190
+ cancelTreeMotion();
16032
16191
  if (next) {
16033
16192
  dismissedByPointerRef.current = false;
16034
16193
  alignSelectedTopRef.current = true;
@@ -16061,6 +16220,14 @@ var SSelectImpl = /* @__PURE__ */ forwardRef(function SSelect({
16061
16220
  }, [insideModal, pendingOpen, portalContainer]);
16062
16221
  const requestOpenRef = useRef(requestOpen);
16063
16222
  requestOpenRef.current = requestOpen;
16223
+ useEffect(() => {
16224
+ if (!label || effectiveDisabled) return;
16225
+ const labelEl = document.getElementById(fieldLabelId(triggerId));
16226
+ if (!labelEl) return;
16227
+ const toggle = () => requestOpenRef.current(!open);
16228
+ labelEl.addEventListener("click", toggle);
16229
+ return () => labelEl.removeEventListener("click", toggle);
16230
+ }, [label, effectiveDisabled, triggerId, open]);
16064
16231
  useImperativeHandle(
16065
16232
  ref,
16066
16233
  () => ({
@@ -16091,6 +16258,10 @@ var SSelectImpl = /* @__PURE__ */ forwardRef(function SSelect({
16091
16258
  (groupValue) => treeSearching ? !searchCollapsed.has(groupValue) : expanded.has(groupValue),
16092
16259
  [expanded, searchCollapsed, treeSearching]
16093
16260
  );
16261
+ const isGroupShownExpanded = useCallback(
16262
+ (groupValue) => isGroupExpanded(groupValue) && !(treeMotion != null && !treeMotion.opening && treeMotion.group === groupValue),
16263
+ [isGroupExpanded, treeMotion]
16264
+ );
16094
16265
  const treeRows = useMemo(
16095
16266
  () => isTree ? visibleTreeRows(searched, (row) => isGroupExpanded(row.value)) : null,
16096
16267
  [isGroupExpanded, isTree, searched]
@@ -16342,6 +16513,7 @@ var SSelectImpl = /* @__PURE__ */ forwardRef(function SSelect({
16342
16513
  const handleClear = () => {
16343
16514
  emit3([]);
16344
16515
  if (rules && rules.length > 0) setRuleError(runRules(multi ? [] : "", rules));
16516
+ triggerRef.current?.focus();
16345
16517
  };
16346
16518
  const handleRemoveChip = (targets) => {
16347
16519
  const remove = new Set(targets);
@@ -16379,6 +16551,7 @@ var SSelectImpl = /* @__PURE__ */ forwardRef(function SSelect({
16379
16551
  const handleSearchChange = (next) => {
16380
16552
  setSearch(next);
16381
16553
  setSearchCollapsed(NO_SEARCH_COLLAPSED);
16554
+ cancelTreeMotion();
16382
16555
  };
16383
16556
  const handleToggleExpand = (groupValue) => {
16384
16557
  rangeAnchorRef.current = null;
@@ -16388,8 +16561,41 @@ var SSelectImpl = /* @__PURE__ */ forwardRef(function SSelect({
16388
16561
  else next.add(groupValue);
16389
16562
  return next;
16390
16563
  };
16391
- if (treeSearching) setSearchCollapsed(toggle);
16392
- else setExpanded(toggle);
16564
+ const applyToggle = treeSearching ? () => setSearchCollapsed(toggle) : () => setExpanded(toggle);
16565
+ if (treeMotionTimerRef.current != null) clearTimeout(treeMotionTimerRef.current);
16566
+ treeMotionTimerRef.current = null;
16567
+ const pendingCollapse = pendingCollapseRef.current;
16568
+ pendingCollapseRef.current = null;
16569
+ if (treeMotion?.group === groupValue && !treeMotion.opening) {
16570
+ setTreeMotion({ group: groupValue, opening: true });
16571
+ treeMotionTimerRef.current = setTimeout(
16572
+ () => setTreeMotion(null),
16573
+ TREE_BRANCH_MOTION.duration
16574
+ );
16575
+ return;
16576
+ }
16577
+ pendingCollapse?.();
16578
+ if (!canAnimateTreeBranch()) {
16579
+ setTreeMotion(null);
16580
+ applyToggle();
16581
+ return;
16582
+ }
16583
+ if (isGroupExpanded(groupValue)) {
16584
+ setTreeMotion({ group: groupValue, opening: false });
16585
+ pendingCollapseRef.current = applyToggle;
16586
+ treeMotionTimerRef.current = setTimeout(() => {
16587
+ pendingCollapseRef.current = null;
16588
+ setTreeMotion(null);
16589
+ applyToggle();
16590
+ }, TREE_BRANCH_MOTION.duration);
16591
+ } else {
16592
+ applyToggle();
16593
+ setTreeMotion({ group: groupValue, opening: true });
16594
+ treeMotionTimerRef.current = setTimeout(
16595
+ () => setTreeMotion(null),
16596
+ TREE_BRANCH_MOTION.duration
16597
+ );
16598
+ }
16393
16599
  };
16394
16600
  const handleToggleGroup = (leafValues) => {
16395
16601
  if (leafValues.length === 0) return;
@@ -16499,7 +16705,7 @@ var SSelectImpl = /* @__PURE__ */ forwardRef(function SSelect({
16499
16705
  const row = rowIndex != null ? filtered[rowIndex] : void 0;
16500
16706
  if (rowIndex == null || row == null) return;
16501
16707
  event.preventDefault();
16502
- const rowExpanded = row.isGroup && isGroupExpanded(row.value);
16708
+ const rowExpanded = row.isGroup && isGroupShownExpanded(row.value);
16503
16709
  if (event.key === "ArrowRight") {
16504
16710
  if (!row.isGroup) return;
16505
16711
  if (!rowExpanded) {
@@ -16537,6 +16743,15 @@ var SSelectImpl = /* @__PURE__ */ forwardRef(function SSelect({
16537
16743
  commitOpen(false);
16538
16744
  }
16539
16745
  };
16746
+ const handleTriggerKeyDown = (event) => {
16747
+ if (event.target !== event.currentTarget || effectiveDisabled) return;
16748
+ if (event.key === " " || !open && event.key === "Enter") {
16749
+ event.preventDefault();
16750
+ requestOpen(!open);
16751
+ return;
16752
+ }
16753
+ handleKeyDown(event);
16754
+ };
16540
16755
  return /* @__PURE__ */ jsxs(
16541
16756
  SField,
16542
16757
  {
@@ -16564,23 +16779,28 @@ var SSelectImpl = /* @__PURE__ */ forwardRef(function SSelect({
16564
16779
  children: [
16565
16780
  name && /* @__PURE__ */ jsx("input", { type: "hidden", name, value: selected.join(",") }),
16566
16781
  /* @__PURE__ */ jsxs(
16567
- "button",
16782
+ "div",
16568
16783
  {
16569
16784
  ref: triggerRef,
16570
16785
  id: triggerId,
16571
- type: "button",
16572
- disabled: effectiveDisabled,
16573
- "aria-labelledby": label ? `${fieldLabelId(triggerId)} ${triggerId}` : void 0,
16786
+ role: "combobox",
16787
+ tabIndex: effectiveDisabled ? -1 : 0,
16788
+ "aria-disabled": effectiveDisabled || void 0,
16789
+ "aria-labelledby": label ? `${fieldLabelId(triggerId)} ${triggerId}` : triggerId,
16574
16790
  "aria-haspopup": isTree ? "tree" : "listbox",
16575
16791
  "aria-expanded": open,
16576
16792
  "aria-controls": open ? listboxId : void 0,
16577
16793
  "aria-activedescendant": open && focusedIndex >= 0 ? activeOptionId : void 0,
16578
16794
  "aria-busy": showTriggerSpinner || void 0,
16579
- onClick: () => requestOpen(!open),
16580
- onKeyDown: handleKeyDown,
16795
+ onClick: () => {
16796
+ if (effectiveDisabled) return;
16797
+ requestOpen(!open);
16798
+ },
16799
+ onKeyDown: handleTriggerKeyDown,
16581
16800
  className: cn(
16582
- "flex h-full w-full cursor-pointer items-center justify-between bg-transparent text-left outline-none disabled:cursor-not-allowed",
16583
- size === "md" ? "typo-body-md-default gap-(--cmp-select-md-gap) px-(--cmp-select-md-paddingX)" : "typo-body-sm-default gap-(--cmp-select-sm-gap) px-(--cmp-select-sm-paddingX)"
16801
+ "flex h-full w-full items-center justify-between bg-transparent text-left outline-none",
16802
+ effectiveDisabled ? "cursor-not-allowed" : "cursor-pointer",
16803
+ size === "md" ? "typo-field-md-default gap-(--cmp-select-md-gap) px-(--cmp-select-md-paddingX)" : "typo-field-sm-default gap-(--cmp-select-sm-gap) px-(--cmp-select-sm-paddingX)"
16584
16804
  ),
16585
16805
  style: {
16586
16806
  // 칩 한 줄이 기본 높이 안에서 세로 가운데에 오는 여백. 줄이 늘면 같은 여백을 유지한 채 트리거가 커진다.
@@ -16702,7 +16922,7 @@ var SSelectImpl = /* @__PURE__ */ forwardRef(function SSelect({
16702
16922
  "div",
16703
16923
  {
16704
16924
  ref: searchBarRef,
16705
- className: "sticky top-0 z-[1] bg-[var(--cmp-listBox-bg)] px-(--cmp-listBoxItem-search-paddingX) py-(--cmp-listBoxItem-search-paddingY)",
16925
+ className: "sticky top-0 z-[1] border-b-(length:--border-width-1) border-solid border-[color:var(--sys-color-divider-default)] bg-[var(--cmp-listBox-bg)] px-(--cmp-listBoxItem-search-paddingX) py-(--cmp-listBoxItem-search-paddingY)",
16706
16926
  children: /* @__PURE__ */ jsx(
16707
16927
  SSearchInput,
16708
16928
  {
@@ -16730,14 +16950,14 @@ var SSelectImpl = /* @__PURE__ */ forwardRef(function SSelect({
16730
16950
  setSize: isDepth || isTree ? void 0 : rowCount,
16731
16951
  multi,
16732
16952
  tree: isTree,
16733
- isExpanded: isGroupExpanded,
16953
+ isExpanded: isGroupShownExpanded,
16734
16954
  onToggleExpand: handleToggleExpand,
16955
+ treeMotion,
16735
16956
  treeLines,
16736
16957
  selected,
16737
16958
  groupLeafValues,
16738
16959
  focusedValue: navigableItems[focusedIndex]?.key,
16739
16960
  showSelectAll: selectAllVisible,
16740
- searchVisible,
16741
16961
  selectAllLabel: allSelectedLabel,
16742
16962
  selectAllSelected: allSelected,
16743
16963
  onSelectAll: handleSelectAll,
@@ -16789,12 +17009,12 @@ function ItemList({
16789
17009
  tree,
16790
17010
  isExpanded,
16791
17011
  onToggleExpand,
17012
+ treeMotion,
16792
17013
  treeLines,
16793
17014
  selected,
16794
17015
  groupLeafValues,
16795
17016
  focusedValue,
16796
17017
  showSelectAll,
16797
- searchVisible,
16798
17018
  selectAllLabel,
16799
17019
  selectAllSelected,
16800
17020
  onSelectAll,
@@ -16805,281 +17025,327 @@ function ItemList({
16805
17025
  const selectedSet = useMemo(() => new Set(selected), [selected]);
16806
17026
  const checkboxShiftRef = useRef(false);
16807
17027
  const itemBase = cn(
16808
- "group/select-item flex w-full cursor-pointer select-none items-center gap-[8px] border-none bg-transparent text-left text-[12px] leading-[20px] outline-none",
17028
+ "group/select-item flex w-full cursor-pointer select-none items-center gap-(--cmp-listBoxItem-gap) border-none bg-transparent text-left typo-field-sm-default outline-none",
16809
17029
  "text-[color:var(--cmp-listBoxItem-content-default)]",
16810
17030
  "disabled:cursor-not-allowed disabled:text-[color:var(--cmp-listBoxItem-content-disabled)]"
16811
17031
  );
16812
17032
  const activeClass = "hover:bg-[var(--cmp-listBoxItem-bg-hover)] hover:text-[color:var(--cmp-listBoxItem-content-hover)] focus-visible:bg-[var(--cmp-listBoxItem-bg-hover)] focus-visible:text-[color:var(--cmp-listBoxItem-content-hover)]";
16813
- return /* @__PURE__ */ jsxs("div", { id: listboxId, role: tree ? "tree" : "listbox", "aria-multiselectable": multi || void 0, children: [
16814
- showSelectAll && (tree ? (
16815
- // 트리의 전체선택 줄은 STree 의 "전체" 줄 그대로다 (lib/tree-row).
16816
- /* @__PURE__ */ jsx(
16817
- TreeAllRow,
16818
- {
16819
- "data-select-all-row": true,
16820
- id: focusedValue === "__select_all__" ? activeOptionId : void 0,
16821
- "data-select-focused": focusedValue === "__select_all__" ? "true" : void 0,
16822
- "data-select-active": focusedValue === "__select_all__" ? "true" : void 0,
16823
- tabIndex: -1,
16824
- label: selectAllLabel,
16825
- selected: selectAllSelected,
16826
- active: focusedValue === "__select_all__",
16827
- className: "select-none",
16828
- onMouseEnter: () => onHoverValue("__select_all__"),
16829
- onMouseLeave: () => onHoverValue(null),
16830
- onToggle: onSelectAll
16831
- }
16832
- )
16833
- ) : /* @__PURE__ */ jsxs(
16834
- "button",
17033
+ const wrapTreeMotion = (nodes) => {
17034
+ if (!tree || treeMotion == null) return nodes;
17035
+ const start = items.findIndex((o) => o.isGroup && o.value === treeMotion.group);
17036
+ if (start < 0) return nodes;
17037
+ let end = start + 1;
17038
+ while (end < items.length && items[end].depth > items[start].depth) end++;
17039
+ if (end === start + 1) return nodes;
17040
+ return [
17041
+ ...nodes.slice(0, start + 1),
17042
+ /* @__PURE__ */ jsx(TreeRowsMotion, { opening: treeMotion.opening, children: nodes.slice(start + 1, end) }, `__motion_${treeMotion.group}__`),
17043
+ ...nodes.slice(end)
17044
+ ];
17045
+ };
17046
+ const selectAllRow = showSelectAll && (tree ? (
17047
+ // 트리의 전체선택 줄은 STree 의 "전체" 줄 그대로다 (lib/tree-row).
17048
+ /* @__PURE__ */ jsx(
17049
+ TreeAllRow,
16835
17050
  {
16836
- type: "button",
16837
17051
  "data-select-all-row": true,
16838
17052
  id: focusedValue === "__select_all__" ? activeOptionId : void 0,
16839
17053
  "data-select-focused": focusedValue === "__select_all__" ? "true" : void 0,
16840
17054
  "data-select-active": focusedValue === "__select_all__" ? "true" : void 0,
16841
- className: cn(
16842
- itemBase,
16843
- focusedValue === "__select_all__" && "bg-[var(--cmp-listBoxItem-bg-hover)] text-[color:var(--cmp-listBoxItem-content-hover)]"
16844
- ),
16845
- style: { paddingTop: 4, paddingBottom: 4, paddingRight: 12, paddingLeft: 12 },
17055
+ tabIndex: -1,
17056
+ label: selectAllLabel,
17057
+ selected: selectAllSelected,
17058
+ active: focusedValue === "__select_all__",
17059
+ className: "select-none",
16846
17060
  onMouseEnter: () => onHoverValue("__select_all__"),
16847
17061
  onMouseLeave: () => onHoverValue(null),
16848
- onClick: onSelectAll,
16849
- children: [
16850
- /* @__PURE__ */ jsx(CheckboxBox, { state: selectAllSelected, focused: focusedValue === "__select_all__" }),
16851
- /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: selectAllLabel })
16852
- ]
17062
+ onToggle: onSelectAll
16853
17063
  }
16854
- )),
16855
- topSpacer > 0 && /* @__PURE__ */ jsx("div", { "aria-hidden": true, style: { height: topSpacer } }),
16856
- items.map((o, windowIndex) => {
16857
- const idx = windowIndex + indexOffset;
16858
- const padLeft = o.depth === 1 ? 12 : o.depth === 2 ? 20 : 28;
16859
- const rowKey = `${o.value}-${idx}`;
16860
- if (tree) {
16861
- const togglesLeaves = multi && o.isGroup;
16862
- const leafValues = togglesLeaves ? groupLeafValues.get(idx) ?? [] : [];
16863
- const total = leafValues.length;
16864
- const selectedCount = leafValues.reduce((n, v) => selectedSet.has(v) ? n + 1 : n, 0);
16865
- const isSelected2 = selectedSet.has(o.value);
16866
- const checkState = togglesLeaves ? total === 0 || selectedCount === 0 ? false : selectedCount === total ? true : null : isSelected2;
16867
- const rowDisabled = o.disabled || togglesLeaves && total === 0;
16868
- const focusKey = togglesLeaves ? `__group_${idx}__` : o.value;
16869
- const focused = focusedValue === focusKey;
16870
- const expanded = o.isGroup && isExpanded(o.value);
16871
- const line = treeLines[idx];
16872
- const toggle = () => {
16873
- if (rowDisabled) return;
16874
- if (togglesLeaves) onToggleGroup(leafValues);
16875
- else onSelect(o.value, idx, checkboxShiftRef.current);
16876
- };
16877
- return (
16878
- // eslint-disable-next-line jsx-a11y/click-events-have-key-events -- 키보드는 트리거(또는 검색 입력)가 aria-activedescendant 로 맡는다. 줄로 포커스를 옮기지 않는다
16879
- /* @__PURE__ */ jsxs(
16880
- "div",
16881
- {
16882
- tabIndex: -1,
16883
- "data-select-row": true,
16884
- "data-index": idx,
16885
- id: focused ? activeOptionId : void 0,
16886
- role: "treeitem",
16887
- "aria-level": o.depth,
16888
- "aria-posinset": line?.posInSet,
16889
- "aria-setsize": line?.setSize,
16890
- "aria-expanded": o.isGroup ? expanded : void 0,
16891
- "aria-selected": checkState === true,
16892
- "aria-disabled": rowDisabled || void 0,
16893
- "data-select-focused": focused ? "true" : void 0,
16894
- "data-select-active": focused ? "true" : void 0,
16895
- className: cn(
16896
- TREE_ROW_CLASS,
16897
- TREE_LABEL_TYPOGRAPHY.sm.rowHeight,
16898
- TREE_ROW_BORDER_CLASS,
16899
- "select-none",
16900
- rowDisabled ? "cursor-not-allowed" : "cursor-pointer",
16901
- focused && TREE_ROW_ACTIVE_CLASS
16902
- ),
16903
- onMouseEnter: () => onHoverValue(focusKey),
16904
- onMouseLeave: () => onHoverValue(null),
16905
- onClick: (event) => {
16906
- if (isRowControlClick(event) || rowDisabled) return;
17064
+ )
17065
+ ) : /* @__PURE__ */ jsxs(
17066
+ "button",
17067
+ {
17068
+ type: "button",
17069
+ "data-select-all-row": true,
17070
+ id: focusedValue === "__select_all__" ? activeOptionId : void 0,
17071
+ "data-select-focused": focusedValue === "__select_all__" ? "true" : void 0,
17072
+ "data-select-active": focusedValue === "__select_all__" ? "true" : void 0,
17073
+ className: cn(
17074
+ itemBase,
17075
+ focusedValue === "__select_all__" && "bg-[var(--cmp-listBoxItem-bg-hover)] text-[color:var(--cmp-listBoxItem-content-hover)]"
17076
+ ),
17077
+ style: { ...LIST_BOX_ITEM_PADDING_Y_RIGHT, paddingLeft: LIST_BOX_ITEM_PADDING_LEFT[1] },
17078
+ onMouseEnter: () => onHoverValue("__select_all__"),
17079
+ onMouseLeave: () => onHoverValue(null),
17080
+ onClick: onSelectAll,
17081
+ children: [
17082
+ /* @__PURE__ */ jsx(CheckboxBox, { state: selectAllSelected, focused: focusedValue === "__select_all__" }),
17083
+ /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: selectAllLabel })
17084
+ ]
17085
+ }
17086
+ ));
17087
+ const rowNodes = items.map((o, windowIndex) => {
17088
+ const idx = windowIndex + indexOffset;
17089
+ const padLeft = LIST_BOX_ITEM_PADDING_LEFT[o.depth === 1 ? 1 : o.depth === 2 ? 2 : 3];
17090
+ const rowKey = `${o.value}-${idx}`;
17091
+ if (tree) {
17092
+ const togglesLeaves = multi && o.isGroup;
17093
+ const leafValues = togglesLeaves ? groupLeafValues.get(idx) ?? [] : [];
17094
+ const total = leafValues.length;
17095
+ const selectedCount = leafValues.reduce((n, v) => selectedSet.has(v) ? n + 1 : n, 0);
17096
+ const isSelected2 = selectedSet.has(o.value);
17097
+ const checkState = togglesLeaves ? total === 0 || selectedCount === 0 ? false : selectedCount === total ? true : null : isSelected2;
17098
+ const rowDisabled = o.disabled || togglesLeaves && total === 0;
17099
+ const focusKey = togglesLeaves ? `__group_${idx}__` : o.value;
17100
+ const focused = focusedValue === focusKey;
17101
+ const expanded = o.isGroup && isExpanded(o.value);
17102
+ const line = treeLines[idx];
17103
+ const toggle = () => {
17104
+ if (rowDisabled) return;
17105
+ if (togglesLeaves) onToggleGroup(leafValues);
17106
+ else onSelect(o.value, idx, checkboxShiftRef.current);
17107
+ };
17108
+ return (
17109
+ // eslint-disable-next-line jsx-a11y/click-events-have-key-events -- 키보드는 트리거(또는 검색 입력)가 aria-activedescendant 로 맡는다. 줄로 포커스를 옮기지 않는다
17110
+ /* @__PURE__ */ jsxs(
17111
+ "div",
17112
+ {
17113
+ tabIndex: -1,
17114
+ "data-select-row": true,
17115
+ "data-index": idx,
17116
+ id: focused ? activeOptionId : void 0,
17117
+ role: "treeitem",
17118
+ "aria-level": o.depth,
17119
+ "aria-posinset": line?.posInSet,
17120
+ "aria-setsize": line?.setSize,
17121
+ "aria-expanded": o.isGroup ? expanded : void 0,
17122
+ "aria-selected": checkState === true,
17123
+ "aria-disabled": rowDisabled || void 0,
17124
+ "data-select-focused": focused ? "true" : void 0,
17125
+ "data-select-active": focused ? "true" : void 0,
17126
+ className: cn(
17127
+ TREE_ROW_CLASS,
17128
+ TREE_LABEL_TYPOGRAPHY.sm.rowHeight,
17129
+ TREE_ROW_BORDER_CLASS,
17130
+ "select-none",
17131
+ o.isGroup && "cursor-pointer",
17132
+ focused && TREE_ROW_ACTIVE_CLASS
17133
+ ),
17134
+ onMouseEnter: () => onHoverValue(focusKey),
17135
+ onMouseLeave: () => onHoverValue(null),
17136
+ onClick: (event) => {
17137
+ if (isRowControlClick(event)) return;
17138
+ if (isRowSelectClick(event)) {
17139
+ if (rowDisabled) return;
16907
17140
  if (togglesLeaves) onToggleGroup(leafValues);
16908
17141
  else onSelect(o.value, idx, event.shiftKey);
16909
- },
16910
- children: [
16911
- /* @__PURE__ */ jsx(
16912
- TreeConnector,
16913
- {
16914
- guideline: true,
16915
- size: "sm",
16916
- depth: o.depth,
16917
- hasChildren: o.isGroup,
16918
- isLast: line?.isLast ?? true,
16919
- ancestorLast: line?.ancestorLast ?? []
16920
- }
16921
- ),
16922
- /* @__PURE__ */ jsxs("div", { className: TREE_CONTENT_CLASS, children: [
16923
- o.isGroup ? (
16924
- // 비활성 그룹도 접고 편다 — 그룹이 비활성이어도 아래에 고를 수 있는 자식이 있을 수 있다.
16925
- /* @__PURE__ */ jsx(TreeCaret, { expanded, onToggle: () => onToggleExpand(o.value) })
16926
- ) : /* @__PURE__ */ jsx(TreeCaretSpacer, {}),
16927
- multi && /* @__PURE__ */ jsx(
16928
- "span",
16929
- {
16930
- "data-tree-control": true,
16931
- className: "flex shrink-0",
16932
- onPointerDownCapture: (event) => {
16933
- checkboxShiftRef.current = event.shiftKey;
16934
- },
16935
- children: /* @__PURE__ */ jsx(SCheckbox, { value: checkState, disabled: rowDisabled, onValueChange: toggle })
16936
- }
16937
- ),
16938
- /* @__PURE__ */ jsx(
16939
- OptionLabel,
16940
- {
16941
- label: o.label,
16942
- className: treeLabelClass("sm", {
16943
- // 고른 줄은 굵게 — multi_tree 는 일부만 고른 그룹도 굵다 (STree 와 같다)
16944
- emphasized: checkState !== false,
16945
- disabled: rowDisabled,
16946
- selectable: true
16947
- })
16948
- }
16949
- )
16950
- ] })
16951
- ]
17142
+ return;
17143
+ }
17144
+ if (o.isGroup) onToggleExpand(o.value);
16952
17145
  },
16953
- rowKey
16954
- )
16955
- );
16956
- }
16957
- if (o.isGroup) {
16958
- const isDepth1 = o.depth === 1;
16959
- const isFirstRow = idx === 0 && !showSelectAll && !searchVisible;
16960
- const groupTone = cn(
16961
- isDepth1 ? "bg-[var(--cmp-listBoxItem-depth1-bg-default)] font-bold" : "bg-[var(--cmp-listBoxItem-depth2-middle-bg)] font-medium",
16962
- isDepth1 && !isFirstRow && "border-t border-solid border-[color:var(--cmp-listBoxItem-depth1-border-color)]"
16963
- );
16964
- if (multi) {
16965
- const leafValues = groupLeafValues.get(idx) ?? [];
16966
- const total = leafValues.length;
16967
- const selectedCount = leafValues.reduce((n, v) => selectedSet.has(v) ? n + 1 : n, 0);
16968
- const groupState = total === 0 || selectedCount === 0 ? false : selectedCount === total ? true : null;
16969
- const groupDisabled = o.disabled || total === 0;
16970
- const groupFocused = focusedValue === `__group_${idx}__`;
16971
- return /* @__PURE__ */ jsxs(
16972
- "button",
16973
- {
16974
- type: "button",
16975
- "data-select-row": true,
16976
- "data-index": idx,
16977
- id: groupFocused ? activeOptionId : void 0,
16978
- role: "option",
16979
- "aria-selected": groupState === true,
16980
- disabled: groupDisabled,
16981
- "data-select-focused": groupFocused ? "true" : void 0,
16982
- "data-select-active": groupFocused ? "true" : void 0,
16983
- className: cn(
16984
- "flex w-full select-none items-center gap-[8px] border-none py-[4px] pr-[12px] text-left text-[12px] leading-[20px] text-[color:var(--cmp-listBoxItem-content-default)]",
16985
- groupTone,
16986
- groupDisabled ? "cursor-not-allowed text-[color:var(--cmp-listBoxItem-content-disabled)]" : "cursor-pointer",
16987
- groupDisabled && isDepth1 && "bg-[var(--cmp-listBoxItem-depth1-bg-disabled)]",
16988
- // 포커스 하이라이트는 depth 배경보다 뒤에 둬 tailwind-merge 로 이기게 한다.
16989
- groupFocused && !groupDisabled && "bg-[var(--cmp-listBoxItem-bg-hover)] text-[color:var(--cmp-listBoxItem-content-hover)]"
17146
+ children: [
17147
+ /* @__PURE__ */ jsx(
17148
+ TreeConnector,
17149
+ {
17150
+ guideline: true,
17151
+ size: "sm",
17152
+ depth: o.depth,
17153
+ hasChildren: o.isGroup,
17154
+ isLast: line?.isLast ?? true,
17155
+ ancestorLast: line?.ancestorLast ?? []
17156
+ }
16990
17157
  ),
16991
- style: { paddingLeft: padLeft },
16992
- onMouseEnter: () => onHoverValue(`__group_${idx}__`),
16993
- onMouseLeave: () => onHoverValue(null),
16994
- onClick: () => onToggleGroup(leafValues),
16995
- children: [
16996
- /* @__PURE__ */ jsx(CheckboxBox, { state: groupState, disabled: groupDisabled, focused: groupFocused }),
16997
- /* @__PURE__ */ jsx(OptionLabel, { label: o.label, className: "min-w-0 truncate" }),
16998
- total > 0 && /* @__PURE__ */ jsxs(
16999
- "span",
17158
+ /* @__PURE__ */ jsxs("div", { className: TREE_CONTENT_CLASS, children: [
17159
+ o.isGroup ? (
17160
+ // 비활성 그룹도 접고 편다 — 그룹이 비활성이어도 아래에 고를 수 있는 자식이 있을 수 있다.
17161
+ /* @__PURE__ */ jsx(TreeCaret, { expanded, onToggle: () => onToggleExpand(o.value) })
17162
+ ) : /* @__PURE__ */ jsx(TreeCaretSpacer, {}),
17163
+ /* @__PURE__ */ jsx(
17164
+ TreeSelectZone,
17000
17165
  {
17001
- className: cn(
17002
- "shrink-0 font-medium",
17003
- groupFocused ? "text-white" : "text-[color:var(--cmp-listBoxItem-content-disabled)]"
17166
+ selectable: true,
17167
+ disabled: rowDisabled,
17168
+ control: multi && /* @__PURE__ */ jsx(
17169
+ "span",
17170
+ {
17171
+ "data-tree-control": true,
17172
+ className: "flex shrink-0",
17173
+ onPointerDownCapture: (event) => {
17174
+ checkboxShiftRef.current = event.shiftKey;
17175
+ },
17176
+ children: /* @__PURE__ */ jsx(SCheckbox, { value: checkState, disabled: rowDisabled, onValueChange: toggle })
17177
+ }
17004
17178
  ),
17005
- children: [
17006
- "(",
17007
- selectedCount,
17008
- "/",
17009
- total,
17010
- ")"
17011
- ]
17179
+ children: /* @__PURE__ */ jsx(
17180
+ OptionLabel,
17181
+ {
17182
+ label: o.label,
17183
+ className: treeLabelClass("sm", {
17184
+ // 고른 줄은 굵게 — multi_tree 는 일부만 고른 그룹도 굵다 (STree 와 같다)
17185
+ emphasized: checkState !== false,
17186
+ disabled: rowDisabled,
17187
+ selectable: true
17188
+ })
17189
+ }
17190
+ )
17012
17191
  }
17013
17192
  )
17014
- ]
17015
- },
17016
- rowKey
17017
- );
17018
- }
17019
- return /* @__PURE__ */ jsx(
17020
- "div",
17193
+ ] })
17194
+ ]
17195
+ },
17196
+ rowKey
17197
+ )
17198
+ );
17199
+ }
17200
+ if (o.isGroup) {
17201
+ const isDepth1 = o.depth === 1;
17202
+ const isFirstRow = idx === 0 && !showSelectAll;
17203
+ const groupTone = cn(
17204
+ isDepth1 ? "bg-[var(--cmp-listBoxItem-depth1-bg-default)] font-bold" : "bg-[var(--cmp-listBoxItem-depth2-middle-bg)] font-medium",
17205
+ isDepth1 && !isFirstRow && "border-t border-solid border-[color:var(--cmp-listBoxItem-depth1-border-color)]"
17206
+ );
17207
+ if (multi) {
17208
+ const leafValues = groupLeafValues.get(idx) ?? [];
17209
+ const total = leafValues.length;
17210
+ const selectedCount = leafValues.reduce((n, v) => selectedSet.has(v) ? n + 1 : n, 0);
17211
+ const groupState = total === 0 || selectedCount === 0 ? false : selectedCount === total ? true : null;
17212
+ const groupDisabled = o.disabled || total === 0;
17213
+ const groupFocused = focusedValue === `__group_${idx}__`;
17214
+ return /* @__PURE__ */ jsxs(
17215
+ "button",
17021
17216
  {
17217
+ type: "button",
17022
17218
  "data-select-row": true,
17023
17219
  "data-index": idx,
17220
+ id: groupFocused ? activeOptionId : void 0,
17221
+ role: "option",
17222
+ "aria-selected": groupState === true,
17223
+ disabled: groupDisabled,
17224
+ "data-select-focused": groupFocused ? "true" : void 0,
17225
+ "data-select-active": groupFocused ? "true" : void 0,
17024
17226
  className: cn(
17025
- "select-none py-[4px] pr-[12px] text-[12px] leading-[20px] text-[color:var(--cmp-listBoxItem-content-default)]",
17227
+ "flex w-full select-none items-center gap-(--cmp-listBoxItem-gap) border-none py-(--cmp-listBoxItem-paddingY) pr-(--cmp-listBoxItem-paddingRight) text-left typo-field-sm-default text-[color:var(--cmp-listBoxItem-content-default)]",
17026
17228
  groupTone,
17027
- // 하위가 전부 비활성이면(select.config 에서 bubble-up) 어미 그룹도 비활성 처리:
17028
- // 텍스트는 회색(#888), depth1 그룹은 파란 배경 대신 회색(#EEE)으로 (depth2 는 #F6F6F6 유지)
17029
- o.disabled && "cursor-not-allowed text-[color:var(--cmp-listBoxItem-content-disabled)]",
17030
- o.disabled && isDepth1 && "bg-[var(--cmp-listBoxItem-depth1-bg-disabled)]"
17229
+ groupDisabled ? "cursor-not-allowed text-[color:var(--cmp-listBoxItem-content-disabled)]" : "cursor-pointer",
17230
+ groupDisabled && isDepth1 && "bg-[var(--cmp-listBoxItem-depth1-bg-disabled)]",
17231
+ // 포커스 하이라이트는 depth 배경보다 뒤에 둬 tailwind-merge 로 이기게 한다.
17232
+ groupFocused && !groupDisabled && "bg-[var(--cmp-listBoxItem-bg-hover)] text-[color:var(--cmp-listBoxItem-content-hover)]"
17031
17233
  ),
17032
17234
  style: { paddingLeft: padLeft },
17033
- children: o.label
17235
+ onMouseEnter: () => onHoverValue(`__group_${idx}__`),
17236
+ onMouseLeave: () => onHoverValue(null),
17237
+ onClick: () => onToggleGroup(leafValues),
17238
+ children: [
17239
+ /* @__PURE__ */ jsx(CheckboxBox, { state: groupState, disabled: groupDisabled, focused: groupFocused }),
17240
+ /* @__PURE__ */ jsx(OptionLabel, { label: o.label, className: "min-w-0 truncate" }),
17241
+ total > 0 && /* @__PURE__ */ jsxs(
17242
+ "span",
17243
+ {
17244
+ className: cn(
17245
+ "shrink-0 font-medium",
17246
+ groupFocused ? "text-white" : "text-[color:var(--cmp-listBoxItem-content-disabled)]"
17247
+ ),
17248
+ children: [
17249
+ "(",
17250
+ selectedCount,
17251
+ "/",
17252
+ total,
17253
+ ")"
17254
+ ]
17255
+ }
17256
+ )
17257
+ ]
17034
17258
  },
17035
17259
  rowKey
17036
17260
  );
17037
17261
  }
17038
- const isSelected = selected.includes(o.value);
17039
- return /* @__PURE__ */ jsxs(
17040
- "button",
17262
+ return /* @__PURE__ */ jsx(
17263
+ "div",
17041
17264
  {
17042
- type: "button",
17043
17265
  "data-select-row": true,
17044
17266
  "data-index": idx,
17045
- id: focusedValue === o.value ? activeOptionId : void 0,
17046
- disabled: o.disabled,
17047
- role: "option",
17048
- "aria-selected": isSelected,
17049
- "aria-setsize": setSize,
17050
- "aria-posinset": setSize != null ? idx + 1 : void 0,
17051
- "data-select-focused": focusedValue === o.value ? "true" : void 0,
17052
- "data-select-active": focusedValue === o.value ? "true" : void 0,
17053
17267
  className: cn(
17054
- itemBase,
17055
- isSelected && !multi && "font-bold text-[color:var(--cmp-listBoxItem-content-selected)]",
17056
- focusedValue === o.value && "bg-[var(--cmp-listBoxItem-bg-hover)] text-[color:var(--cmp-listBoxItem-content-hover)]",
17057
- // 비활성 항목은 hover/focus 스타일 대상에서 제외한다.
17058
- // (:hover 는 disabled 버튼에도 매칭되므로 클래스 자체를 붙이지 않아야 한다)
17059
- !o.disabled && activeClass
17268
+ "select-none py-(--cmp-listBoxItem-paddingY) pr-(--cmp-listBoxItem-paddingRight) typo-field-sm-default text-[color:var(--cmp-listBoxItem-content-default)]",
17269
+ groupTone,
17270
+ // 하위가 전부 비활성이면(select.config 에서 bubble-up) 어미 그룹도 비활성 처리:
17271
+ // 텍스트는 회색(#888), depth1 그룹은 파란 배경 대신 회색(#EEE)으로 (depth2 는 #F6F6F6 유지)
17272
+ o.disabled && "cursor-not-allowed text-[color:var(--cmp-listBoxItem-content-disabled)]",
17273
+ o.disabled && isDepth1 && "bg-[var(--cmp-listBoxItem-depth1-bg-disabled)]"
17060
17274
  ),
17061
- style: { paddingTop: 4, paddingBottom: 4, paddingRight: 12, paddingLeft: padLeft },
17062
- onMouseEnter: () => onHoverValue(o.value),
17063
- onMouseLeave: () => onHoverValue(null),
17064
- onClick: (event) => onSelect(o.value, idx, event.shiftKey),
17065
- children: [
17066
- multi && /* @__PURE__ */ jsx(
17067
- CheckboxBox,
17068
- {
17069
- state: isSelected,
17070
- disabled: o.disabled,
17071
- focused: focusedValue === o.value
17072
- }
17073
- ),
17074
- /* @__PURE__ */ jsx(OptionLabel, { label: o.label, className: "flex-1 truncate" })
17075
- ]
17275
+ style: { paddingLeft: padLeft },
17276
+ children: o.label
17076
17277
  },
17077
17278
  rowKey
17078
17279
  );
17079
- }),
17280
+ }
17281
+ const isSelected = selected.includes(o.value);
17282
+ return /* @__PURE__ */ jsxs(
17283
+ "button",
17284
+ {
17285
+ type: "button",
17286
+ "data-select-row": true,
17287
+ "data-index": idx,
17288
+ id: focusedValue === o.value ? activeOptionId : void 0,
17289
+ disabled: o.disabled,
17290
+ role: "option",
17291
+ "aria-selected": isSelected,
17292
+ "aria-setsize": setSize,
17293
+ "aria-posinset": setSize != null ? idx + 1 : void 0,
17294
+ "data-select-focused": focusedValue === o.value ? "true" : void 0,
17295
+ "data-select-active": focusedValue === o.value ? "true" : void 0,
17296
+ className: cn(
17297
+ itemBase,
17298
+ isSelected && !multi && "font-bold text-[color:var(--cmp-listBoxItem-content-selected)]",
17299
+ focusedValue === o.value && "bg-[var(--cmp-listBoxItem-bg-hover)] text-[color:var(--cmp-listBoxItem-content-hover)]",
17300
+ // 비활성 항목은 hover/focus 스타일 대상에서 제외한다.
17301
+ // (:hover 는 disabled 버튼에도 매칭되므로 클래스 자체를 붙이지 않아야 한다)
17302
+ !o.disabled && activeClass
17303
+ ),
17304
+ style: { ...LIST_BOX_ITEM_PADDING_Y_RIGHT, paddingLeft: padLeft },
17305
+ onMouseEnter: () => onHoverValue(o.value),
17306
+ onMouseLeave: () => onHoverValue(null),
17307
+ onClick: (event) => onSelect(o.value, idx, event.shiftKey),
17308
+ children: [
17309
+ multi && /* @__PURE__ */ jsx(
17310
+ CheckboxBox,
17311
+ {
17312
+ state: isSelected,
17313
+ disabled: o.disabled,
17314
+ focused: focusedValue === o.value
17315
+ }
17316
+ ),
17317
+ /* @__PURE__ */ jsx(OptionLabel, { label: o.label, className: "flex-1 truncate" })
17318
+ ]
17319
+ },
17320
+ rowKey
17321
+ );
17322
+ });
17323
+ return /* @__PURE__ */ jsxs("div", { id: listboxId, role: tree ? "tree" : "listbox", "aria-multiselectable": multi || void 0, children: [
17324
+ selectAllRow,
17325
+ topSpacer > 0 && /* @__PURE__ */ jsx("div", { "aria-hidden": true, style: { height: topSpacer } }),
17326
+ wrapTreeMotion(rowNodes),
17080
17327
  bottomSpacer > 0 && /* @__PURE__ */ jsx("div", { "aria-hidden": true, style: { height: bottomSpacer } })
17081
17328
  ] });
17082
17329
  }
17330
+ function TreeRowsMotion({ opening, children }) {
17331
+ const ref = useRef(null);
17332
+ const animationRef = useRef(null);
17333
+ const mountedRef = useRef(false);
17334
+ useLayoutEffect(() => {
17335
+ const el = ref.current;
17336
+ if (el == null || typeof el.animate !== "function") return;
17337
+ const from = !mountedRef.current && opening ? 0 : el.getBoundingClientRect().height;
17338
+ mountedRef.current = true;
17339
+ animationRef.current?.cancel();
17340
+ animationRef.current = el.animate(
17341
+ [{ height: `${from}px` }, { height: opening ? `${el.scrollHeight}px` : "0px" }],
17342
+ // 접힌 뒤 줄이 목록에서 빠질 때까지 0 으로 붙잡아 둔다. 편 뒤에는 제 높이(auto)로 돌아간다
17343
+ { ...TREE_BRANCH_MOTION, fill: opening ? "none" : "forwards" }
17344
+ );
17345
+ }, [opening]);
17346
+ useEffect(() => () => animationRef.current?.cancel(), []);
17347
+ return /* @__PURE__ */ jsx("div", { ref, className: "overflow-hidden", "aria-hidden": opening ? void 0 : true, children });
17348
+ }
17083
17349
  function OptionLabel({ label, className }) {
17084
17350
  return isHtmlLabel(label) ? /* @__PURE__ */ jsx("span", { className, dangerouslySetInnerHTML: { __html: sanitizeInlineHtml(label) } }) : /* @__PURE__ */ jsx("span", { className, children: label });
17085
17351
  }
@@ -17087,40 +17353,17 @@ function TriggerLabel({ label }) {
17087
17353
  return /* @__PURE__ */ jsx(OptionLabel, { label, className: "truncate" });
17088
17354
  }
17089
17355
  function TriggerRemoveButton({ ariaLabel, onRemove }) {
17090
- return /* @__PURE__ */ jsxs(
17091
- "span",
17356
+ return /* @__PURE__ */ jsx(
17357
+ SGhostButton,
17092
17358
  {
17093
- role: "button",
17094
- tabIndex: 0,
17095
- "aria-label": ariaLabel,
17096
- className: "group/select-remove relative inline-flex shrink-0 cursor-pointer items-center justify-center",
17097
- style: {
17098
- width: "var(--cmp-ghostButton-xxs-size)",
17099
- height: "var(--cmp-ghostButton-xxs-size)",
17100
- borderRadius: "var(--cmp-ghostButton-radius-sm)"
17101
- },
17359
+ icon: "close",
17360
+ size: "xxs",
17361
+ ariaLabel,
17362
+ className: "shrink-0",
17102
17363
  onClick: (event) => {
17103
- event.preventDefault();
17104
17364
  event.stopPropagation();
17105
17365
  onRemove();
17106
- },
17107
- onKeyDown: (event) => {
17108
- if (event.key !== "Enter" && event.key !== " ") return;
17109
- event.preventDefault();
17110
- event.stopPropagation();
17111
- onRemove();
17112
- },
17113
- children: [
17114
- /* @__PURE__ */ jsx(
17115
- "span",
17116
- {
17117
- "aria-hidden": true,
17118
- className: "pointer-events-none absolute inset-0 rounded-[inherit] opacity-0 transition-opacity duration-200 group-hover/select-remove:opacity-5",
17119
- style: { background: "var(--cmp-ghostButton-default-hover-bg)" }
17120
- }
17121
- ),
17122
- /* @__PURE__ */ jsx(SIcon, { name: "close", size: 12, color: "var(--cmp-ghostButton-default-content)" })
17123
- ]
17366
+ }
17124
17367
  }
17125
17368
  );
17126
17369
  }
@@ -17134,7 +17377,7 @@ function CheckboxBox({
17134
17377
  "span",
17135
17378
  {
17136
17379
  className: cn(
17137
- "flex h-[16px] w-[16px] flex-shrink-0 items-center justify-center rounded-[2px] border border-solid",
17380
+ "flex size-(--cmp-checkbox-size) flex-shrink-0 items-center justify-center rounded-(--cmp-checkbox-radius) border-(length:--cmp-checkbox-borderWidth) border-solid",
17138
17381
  disabled ? (
17139
17382
  // 비활성: 회색 채움(#E1E1E1) + 회색 테두리(#CCCCCC)
17140
17383
  "cursor-not-allowed border-[color:var(--cmp-checkbox-border-disabled)] bg-[var(--cmp-checkbox-bg-disabled)]"
@@ -17144,7 +17387,7 @@ function CheckboxBox({
17144
17387
  SIcon,
17145
17388
  {
17146
17389
  name: state2 === null ? "checkboxIndeterminate" : "checkboxCheck",
17147
- size: 12,
17390
+ size: "var(--cmp-checkbox-icon)",
17148
17391
  color: disabled ? "var(--cmp-checkbox-checked-icon-disabled)" : "var(--cmp-checkbox-checked-icon-default)"
17149
17392
  }
17150
17393
  )
@@ -17777,7 +18020,7 @@ var STableImpl = /* @__PURE__ */ forwardRef(function STable({
17777
18020
  "span",
17778
18021
  {
17779
18022
  onMouseDown: (e) => startResize(i, e),
17780
- className: "absolute right-0 top-1/2 z-[5] flex h-[16px] w-[9px] -translate-y-1/2 cursor-col-resize items-center justify-end",
18023
+ className: "absolute right-0 top-1/2 z-[5] flex h-[var(--cmp-table-header-resizingBar-height)] w-[9px] -translate-y-1/2 cursor-col-resize items-center justify-end",
17781
18024
  "aria-hidden": true,
17782
18025
  children: /* @__PURE__ */ jsx("span", { className: "h-full w-[4px] border-x border-solid border-[color:var(--cmp-table-header-resizingBar-color)]" })
17783
18026
  },
@@ -17840,7 +18083,7 @@ var STableImpl = /* @__PURE__ */ forwardRef(function STable({
17840
18083
  colSpan: group.colSpan,
17841
18084
  rowSpan: group.rowSpan,
17842
18085
  className: cn(
17843
- "relative border-b border-r border-solid border-[color:var(--cmp-table-border-color)] bg-[var(--cmp-table-header-bg)] px-[16px] text-[12px] font-medium leading-[20px] text-[color:var(--sys-color-fg-primary)]",
18086
+ "relative border-b border-r border-solid border-[color:var(--cmp-table-border-color)] bg-[var(--cmp-table-header-bg)] px-[var(--cmp-table-header-paddingX)] typo-table-header text-[color:var(--sys-color-fg-primary)]",
17844
18087
  group.firstIndex + group.colSpan === visibleCols.length && "border-r-0",
17845
18088
  group.rowSpan === 2 && "border-b-0",
17846
18089
  group.className
@@ -17882,7 +18125,7 @@ var STableImpl = /* @__PURE__ */ forwardRef(function STable({
17882
18125
  "span",
17883
18126
  {
17884
18127
  "aria-hidden": true,
17885
- className: "pointer-events-none absolute right-0 top-1/2 h-[16px] w-px -translate-y-1/2 bg-[var(--cmp-table-header-resizingBar-color)]"
18128
+ className: "pointer-events-none absolute right-0 top-1/2 h-[var(--cmp-table-header-resizingBar-height)] w-px -translate-y-1/2 bg-[var(--cmp-table-header-resizingBar-color)]"
17886
18129
  }
17887
18130
  )
17888
18131
  ]
@@ -17903,7 +18146,7 @@ var STableImpl = /* @__PURE__ */ forwardRef(function STable({
17903
18146
  // 세로 가운데도 어긋난다. 글자 줄높이는 아래 th__content 가 다시 준다.
17904
18147
  headerGroupInfo && "border-r border-solid border-[color:var(--cmp-table-border-color)]",
17905
18148
  headerGroupInfo && i === visibleCols.length - 1 && "border-r-0",
17906
- "relative bg-[var(--cmp-table-header-bg)] px-[16px] text-[12px] font-medium leading-[0] text-[color:var(--sys-color-fg-primary)]",
18149
+ "relative bg-[var(--cmp-table-header-bg)] px-[var(--cmp-table-header-paddingX)] typo-table-header leading-[0] text-[color:var(--sys-color-fg-primary)]",
17907
18150
  stickyInfo(i).isSticky && "z-[6]",
17908
18151
  col.thClass
17909
18152
  ),
@@ -17922,7 +18165,7 @@ var STableImpl = /* @__PURE__ */ forwardRef(function STable({
17922
18165
  // 원본 th__content: align에 따라 justify-content 적용 (th도 정렬 반영)
17923
18166
  // th 가 leading-[0] 이므로 글자 줄높이는 여기서 준다 (truncate 가
17924
18167
  // overflow-hidden 이라 줄높이가 0이면 라벨이 잘려 사라진다).
17925
- "inline-flex w-full min-w-0 items-center gap-[4px] leading-[20px]",
18168
+ "inline-flex w-full min-w-0 items-center gap-[var(--cmp-table-header-gap)] leading-[20px]",
17926
18169
  col.align === "center" && "justify-center",
17927
18170
  col.align === "right" && "justify-end"
17928
18171
  ),
@@ -18820,8 +19063,8 @@ function useTruncatedValueTooltip({
18820
19063
  };
18821
19064
  }
18822
19065
  var FONT2 = {
18823
- sm: { fontSize: 12, lineHeight: 20, paddingX: "var(--cmp-textinput-sm-paddingX)" },
18824
- md: { fontSize: 14, lineHeight: 24, paddingX: "var(--cmp-textinput-md-paddingX)" }
19066
+ sm: { typo: "typo-field-sm-default", paddingX: "var(--cmp-textinput-sm-paddingX)" },
19067
+ md: { typo: "typo-field-md-default", paddingX: "var(--cmp-textinput-md-paddingX)" }
18825
19068
  };
18826
19069
  var SInput = /* @__PURE__ */ forwardRef(function SInput2({
18827
19070
  value,
@@ -18914,12 +19157,11 @@ var SInput = /* @__PURE__ */ forwardRef(function SInput2({
18914
19157
  {
18915
19158
  className: cn(
18916
19159
  "flex h-full w-full items-center",
19160
+ f.typo,
18917
19161
  size === "md" ? "gap-[var(--cmp-textinput-md-gap)]" : "gap-[var(--cmp-textinput-sm-gap)]"
18918
19162
  ),
18919
19163
  style: {
18920
- padding: `0 ${f.paddingX}`,
18921
- fontSize: f.fontSize,
18922
- lineHeight: `${f.lineHeight}px`
19164
+ padding: `0 ${f.paddingX}`
18923
19165
  },
18924
19166
  children: [
18925
19167
  prefix != null && /* @__PURE__ */ jsx("span", { className: "flex flex-shrink-0 items-center", children: prefix }),
@@ -18993,8 +19235,8 @@ var SInput = /* @__PURE__ */ forwardRef(function SInput2({
18993
19235
  );
18994
19236
  });
18995
19237
  var PAD2 = {
18996
- sm: { fontSize: 12, lineHeight: 20, stepper: 20, icon: 12 },
18997
- md: { fontSize: 14, lineHeight: 24, stepper: 24, icon: 14 }
19238
+ sm: { typo: "typo-field-sm-default", icon: 12 },
19239
+ md: { typo: "typo-field-md-default", icon: 14 }
18998
19240
  };
18999
19241
  var toNumber = (val) => {
19000
19242
  if (val === null || val === void 0 || val === "") return null;
@@ -19229,7 +19471,7 @@ var SNumberInput = /* @__PURE__ */ forwardRef(function SNumberInput2({
19229
19471
  onClick: dir === "inc" ? increment : decrement,
19230
19472
  className: cn(
19231
19473
  "flex flex-shrink-0 items-center justify-center border border-solid border-transparent transition-colors",
19232
- off ? "cursor-not-allowed" : "cursor-pointer hover:border-[var(--color-border-accentLight)]"
19474
+ off ? "cursor-not-allowed" : "cursor-pointer hover:border-[var(--cmp-numberInput-stepper-border-default)]"
19233
19475
  ),
19234
19476
  style: {
19235
19477
  width: `var(--cmp-numberInput-stepper-${size}-size)`,
@@ -19278,13 +19520,11 @@ var SNumberInput = /* @__PURE__ */ forwardRef(function SNumberInput2({
19278
19520
  children: /* @__PURE__ */ jsxs(
19279
19521
  "div",
19280
19522
  {
19281
- className: "flex h-full w-full items-center",
19523
+ className: cn("flex h-full w-full items-center", p.typo),
19282
19524
  style: {
19283
19525
  // 원본 sd-number-input: content gap = padding-x 토큰 (gap 토큰 아님)
19284
19526
  gap: `var(--cmp-numberInput-${size}-paddingX)`,
19285
- padding: `0 ${showButton ? padX : `calc(${padX} * 2)`}`,
19286
- fontSize: p.fontSize,
19287
- lineHeight: `${p.lineHeight}px`
19527
+ padding: `0 ${showButton ? padX : `calc(${padX} * 2)`}`
19288
19528
  },
19289
19529
  children: [
19290
19530
  showButton && stepper("dec"),
@@ -19570,7 +19810,7 @@ function SCalendar({
19570
19810
  onClick: () => view(y - 1, m)
19571
19811
  }
19572
19812
  ),
19573
- /* @__PURE__ */ jsx("span", { className: "inline-flex min-w-[40px] items-center justify-center text-center text-[14px] font-medium leading-[24px]", children: y }),
19813
+ /* @__PURE__ */ jsx("span", { className: "inline-flex min-w-[40px] items-center justify-center text-center typo-field-md-medium", children: y }),
19574
19814
  /* @__PURE__ */ jsx(
19575
19815
  SGhostButton,
19576
19816
  {
@@ -19595,7 +19835,7 @@ function SCalendar({
19595
19835
  }
19596
19836
  }
19597
19837
  ),
19598
- /* @__PURE__ */ jsxs("span", { className: "inline-flex w-full min-w-[40px] items-center justify-center text-center text-[14px] font-medium leading-[24px]", children: [
19838
+ /* @__PURE__ */ jsxs("span", { className: "inline-flex w-full min-w-[40px] items-center justify-center text-center typo-field-md-medium", children: [
19599
19839
  m,
19600
19840
  "\uC6D4"
19601
19841
  ] }),
@@ -19672,7 +19912,7 @@ function SCalendar({
19672
19912
  }) }),
19673
19913
  legend.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
19674
19914
  /* @__PURE__ */ jsx(SDivider, {}),
19675
- /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center justify-center gap-x-[var(--cmp-datepicker-calendar-legend-group-gap)] gap-y-[4px] text-[11px] leading-[18px]", children: legend.map((item4) => /* @__PURE__ */ jsxs(
19915
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center justify-center gap-x-[var(--cmp-datepicker-calendar-legend-group-gap)] gap-y-[4px] typo-field-xs-default", children: legend.map((item4) => /* @__PURE__ */ jsxs(
19676
19916
  "span",
19677
19917
  {
19678
19918
  className: "inline-flex items-center gap-[var(--cmp-datepicker-calendar-legend-gap)]",
@@ -19700,10 +19940,10 @@ function SCalendar({
19700
19940
  var MODE_LIST_HEIGHT = 240;
19701
19941
  var MODE_ITEM_HEIGHT = 28;
19702
19942
  var modeListItemClass = (selected, disabled) => cn(
19703
- "flex w-full items-center justify-center gap-[var(--cmp-datepicker-mode-item-gap)] border-0 px-[var(--cmp-datepicker-mode-item-paddingX)] py-[var(--cmp-datepicker-mode-item-paddingY)] text-center font-base text-12 leading-[20px]",
19704
- disabled && "cursor-not-allowed bg-[var(--cmp-datepicker-mode-item-bg-default)] font-medium text-[color:var(--cmp-datepicker-mode-item-content-disabled)]",
19705
- !disabled && !selected && "cursor-pointer bg-[var(--cmp-datepicker-mode-item-bg-default)] font-medium text-[color:var(--cmp-datepicker-mode-item-content-default)] hover:bg-[var(--cmp-datepicker-mode-item-bg-hover)] hover:text-[color:var(--cmp-datepicker-mode-item-content-hover)]",
19706
- !disabled && selected && "cursor-pointer bg-[var(--cmp-datepicker-mode-item-bg-default)] font-bold text-[color:var(--cmp-datepicker-mode-item-content-selected)]"
19943
+ "flex w-full items-center justify-center gap-[var(--cmp-datepicker-mode-item-gap)] border-0 px-[var(--cmp-datepicker-mode-item-paddingX)] py-[var(--cmp-datepicker-mode-item-paddingY)] text-center",
19944
+ disabled && "typo-field-sm-medium cursor-not-allowed bg-[var(--cmp-datepicker-mode-item-bg-default)] text-[color:var(--cmp-datepicker-mode-item-content-disabled)]",
19945
+ !disabled && !selected && "typo-field-sm-medium cursor-pointer bg-[var(--cmp-datepicker-mode-item-bg-default)] text-[color:var(--cmp-datepicker-mode-item-content-default)] hover:bg-[var(--cmp-datepicker-mode-item-bg-hover)] hover:text-[color:var(--cmp-datepicker-mode-item-content-hover)]",
19946
+ !disabled && selected && "typo-field-sm-bold cursor-pointer bg-[var(--cmp-datepicker-mode-item-bg-default)] text-[color:var(--cmp-datepicker-mode-item-content-selected)]"
19707
19947
  );
19708
19948
  var MODE_NOUN = {
19709
19949
  date: "\uB0A0\uC9DC",
@@ -20013,9 +20253,9 @@ function SDatePicker({
20013
20253
  const resolvedError = error || ruleError !== "";
20014
20254
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
20015
20255
  const baseDims = size === "md" ? {
20016
- padX: 16,
20017
- gap: 12,
20018
- icon: 20,
20256
+ padX: "var(--cmp-datepicker-md-paddingX)",
20257
+ gap: "var(--cmp-datepicker-md-gap)",
20258
+ icon: "var(--cmp-datepicker-md-icon)",
20019
20259
  minW: 104,
20020
20260
  fieldMinW: 168,
20021
20261
  // 값 길이가 YYYY-MM-DD 로 정해져 있어, width="100%" 를 받아도 행 전체로
@@ -20023,19 +20263,20 @@ function SDatePicker({
20023
20263
  // px 가 아니라 등급이라 --cmp-field-width-* 가 바뀌면 함께 따라간다.
20024
20264
  // 이 기본 상한이 걸리적거리는 자리(폭이 이미 좁게 정해진 팝오버 등)는 maxWidth prop 으로 덮는다
20025
20265
  fieldMaxW: "lg",
20266
+ // 요일 폭 계산에 숫자가 필요해 남긴다. 렌더 타이포는 typo 가 맡는다
20026
20267
  fontSize: 14,
20027
- lineHeight: 24,
20028
- radius: 6
20268
+ typo: "typo-field-md-default",
20269
+ radius: "var(--cmp-datepicker-md-radius)"
20029
20270
  } : {
20030
- padX: 12,
20031
- gap: 8,
20032
- icon: 16,
20271
+ padX: "var(--cmp-datepicker-sm-paddingX)",
20272
+ gap: "var(--cmp-datepicker-sm-gap)",
20273
+ icon: "var(--cmp-datepicker-sm-icon)",
20033
20274
  minW: 80,
20034
20275
  fieldMinW: 128,
20035
20276
  fieldMaxW: "md",
20036
20277
  fontSize: 12,
20037
- lineHeight: 20,
20038
- radius: 4
20278
+ typo: "typo-field-sm-default",
20279
+ radius: "var(--cmp-datepicker-sm-radius)"
20039
20280
  };
20040
20281
  const weekdayW = weekday ? weekdaySuffixWidth(baseDims.fontSize) : 0;
20041
20282
  const dims = {
@@ -20106,7 +20347,7 @@ function SDatePicker({
20106
20347
  "flex h-full w-full items-center overflow-hidden bg-transparent outline-none",
20107
20348
  disabled ? "cursor-not-allowed" : "cursor-pointer"
20108
20349
  ),
20109
- style: { padding: `0 ${dims.padX}px`, gap: dims.gap, borderRadius: dims.radius },
20350
+ style: { padding: `0 ${dims.padX}`, gap: dims.gap, borderRadius: dims.radius },
20110
20351
  children: [
20111
20352
  /* @__PURE__ */ jsx(
20112
20353
  SIcon,
@@ -20121,11 +20362,9 @@ function SDatePicker({
20121
20362
  "span",
20122
20363
  {
20123
20364
  id: triggerTextId,
20124
- className: "flex-1 truncate text-center",
20365
+ className: cn("flex-1 truncate text-center", dims.typo),
20125
20366
  style: {
20126
20367
  minWidth: dims.minW,
20127
- fontSize: dims.fontSize,
20128
- lineHeight: `${dims.lineHeight}px`,
20129
20368
  color: disabled ? "var(--cmp-datepicker-text-disabled)" : hasValue ? "var(--cmp-datepicker-text-default)" : "var(--cmp-field-hint-color)"
20130
20369
  },
20131
20370
  children: hasValue ? weekday ? withWeekday(value) : value : resolvedPlaceholder
@@ -20336,7 +20575,7 @@ function RangeCalendar({
20336
20575
  className: cn(!isLeft && "invisible pointer-events-none")
20337
20576
  }
20338
20577
  ),
20339
- /* @__PURE__ */ jsxs("span", { className: "inline-flex min-w-[40px] flex-1 items-center justify-center text-center text-[14px] font-medium leading-[24px]", children: [
20578
+ /* @__PURE__ */ jsxs("span", { className: "inline-flex min-w-[40px] flex-1 items-center justify-center text-center typo-field-md-medium", children: [
20340
20579
  gy,
20341
20580
  ".",
20342
20581
  String(gm).padStart(2, "0")
@@ -20404,14 +20643,14 @@ function RangeCalendar({
20404
20643
  const hour = which === "start" ? sH : eH;
20405
20644
  const minute = which === "start" ? sM : eM;
20406
20645
  const num = (n, strip) => active && n !== "" ? strip ? String(Number(n)) : n : "-";
20407
- const INPUT_CLS = "h-[var(--cmp-datepicker-sm-height)] w-[40px] rounded-[var(--cmp-datepicker-sm-radius)] border border-solid border-[color:var(--cmp-datepicker-border-default)] bg-[var(--cmp-datepicker-bg-default)] text-center text-[12px] font-medium leading-[20px] text-[color:var(--cmp-datepicker-text-default)] outline-none placeholder:text-[color:var(--cmp-datepicker-text-disabled)] focus:border-[color:var(--cmp-datepicker-border-focus)] disabled:cursor-not-allowed";
20646
+ const INPUT_CLS = "h-[var(--cmp-datepicker-sm-height)] w-[40px] rounded-[var(--cmp-datepicker-sm-radius)] border-[length:var(--cmp-datepicker-border-width)] border-solid border-[color:var(--cmp-datepicker-border-default)] bg-[var(--cmp-datepicker-bg-default)] text-center typo-field-sm-medium text-[color:var(--cmp-datepicker-text-default)] outline-none placeholder:text-[color:var(--cmp-datepicker-text-disabled)] focus:border-[color:var(--cmp-datepicker-border-focus)] disabled:cursor-not-allowed";
20408
20647
  const LABEL = "text-[color:var(--cmp-datepicker-calendar-time-date-label)]";
20409
20648
  const UNIT = "text-[color:var(--cmp-datepicker-calendar-time-date-unit)]";
20410
20649
  return /* @__PURE__ */ jsxs(
20411
20650
  "div",
20412
20651
  {
20413
20652
  className: cn(
20414
- "flex flex-1 items-center justify-center gap-[var(--cmp-datepicker-calendar-time-section-gap)] rounded-[var(--cmp-datepicker-calendar-time-radius)] px-[var(--cmp-datepicker-calendar-time-paddingX)] py-[var(--cmp-datepicker-calendar-time-paddingY)] text-[12px] font-medium leading-[20px]",
20653
+ "flex flex-1 items-center justify-center gap-[var(--cmp-datepicker-calendar-time-section-gap)] rounded-[var(--cmp-datepicker-calendar-time-radius)] px-[var(--cmp-datepicker-calendar-time-paddingX)] py-[var(--cmp-datepicker-calendar-time-paddingY)] typo-field-sm-medium",
20415
20654
  active ? "bg-[var(--cmp-datepicker-calendar-time-bg-selected)]" : "bg-[var(--cmp-datepicker-calendar-time-bg-default)]"
20416
20655
  ),
20417
20656
  children: [
@@ -20473,7 +20712,7 @@ function RangeCalendar({
20473
20712
  ),
20474
20713
  children: [
20475
20714
  /* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center", children: [
20476
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-[var(--cmp-datepicker-calendar-gap)] text-[14px] font-medium leading-[24px]", children: [
20715
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-[var(--cmp-datepicker-calendar-gap)] typo-field-md-medium", children: [
20477
20716
  /* @__PURE__ */ jsx(SGhostButton, { icon: "chevronLeft", size: "xxs", ariaLabel: "prevYear", onClick: goPrevYear }),
20478
20717
  /* @__PURE__ */ jsx("span", { className: "inline-flex min-w-[40px] items-center justify-center text-center", children: y }),
20479
20718
  /* @__PURE__ */ jsx(SGhostButton, { icon: "chevronRight", size: "xxs", ariaLabel: "nextYear", onClick: goNextYear })
@@ -20570,28 +20809,29 @@ function SDateRangePicker({
20570
20809
  const resolvedError = error || ruleError !== "";
20571
20810
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
20572
20811
  const baseDims = size === "md" ? {
20573
- padX: 16,
20574
- gap: 12,
20575
- icon: 20,
20812
+ padX: "var(--cmp-datepicker-md-paddingX)",
20813
+ gap: "var(--cmp-datepicker-md-gap)",
20814
+ icon: "var(--cmp-datepicker-md-icon)",
20576
20815
  minW: 104,
20577
20816
  fieldMinW: 260,
20578
20817
  // xl — 값이 `YYYY-MM-DD ~ YYYY-MM-DD` 라 단일 날짜의 두 배가 넘는다.
20579
20818
  // 최소너비(260)가 이미 lg 를 넘으므로 상한도 한 등급 위여야 한다
20580
20819
  fieldMaxW: "xl",
20820
+ // 요일 폭 계산에 숫자가 필요해 남긴다. 렌더 타이포는 typo 가 맡는다
20581
20821
  fontSize: 14,
20582
- lineHeight: 24,
20583
- radius: 6
20822
+ typo: "typo-field-md-default",
20823
+ radius: "var(--cmp-datepicker-md-radius)"
20584
20824
  } : {
20585
- padX: 12,
20586
- gap: 8,
20587
- icon: 16,
20825
+ padX: "var(--cmp-datepicker-sm-paddingX)",
20826
+ gap: "var(--cmp-datepicker-sm-gap)",
20827
+ icon: "var(--cmp-datepicker-sm-icon)",
20588
20828
  minW: 80,
20589
20829
  fieldMinW: 216,
20590
20830
  // lg — 최소너비 216 이 md 를 넘어 md 로는 담기지 않는다
20591
20831
  fieldMaxW: "lg",
20592
20832
  fontSize: 12,
20593
- lineHeight: 20,
20594
- radius: 4
20833
+ typo: "typo-field-sm-default",
20834
+ radius: "var(--cmp-datepicker-sm-radius)"
20595
20835
  };
20596
20836
  const weekdayW = showWeekday ? weekdaySuffixWidth(baseDims.fontSize) * 2 : 0;
20597
20837
  const dims = {
@@ -20668,7 +20908,7 @@ function SDateRangePicker({
20668
20908
  "flex h-full w-full items-center overflow-hidden bg-transparent outline-none",
20669
20909
  disabled ? "cursor-not-allowed" : "cursor-pointer"
20670
20910
  ),
20671
- style: { padding: `0 ${dims.padX}px`, gap: dims.gap, borderRadius: dims.radius },
20911
+ style: { padding: `0 ${dims.padX}`, gap: dims.gap, borderRadius: dims.radius },
20672
20912
  children: [
20673
20913
  /* @__PURE__ */ jsx(
20674
20914
  SIcon,
@@ -20685,12 +20925,11 @@ function SDateRangePicker({
20685
20925
  id: triggerTextId,
20686
20926
  className: cn(
20687
20927
  "flex-1 items-center",
20928
+ dims.typo,
20688
20929
  hasDisplay ? "flex" : "block truncate text-center"
20689
20930
  ),
20690
20931
  style: {
20691
20932
  minWidth: dims.minW,
20692
- fontSize: dims.fontSize,
20693
- lineHeight: `${dims.lineHeight}px`,
20694
20933
  color: disabled ? "var(--cmp-datepicker-text-disabled)" : hasDisplay ? "var(--cmp-datepicker-text-default)" : "var(--cmp-field-hint-color)"
20695
20934
  },
20696
20935
  children: hasDisplay ? /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -20845,8 +21084,9 @@ var SChipImpl = /* @__PURE__ */ forwardRef(function SChip({
20845
21084
  {
20846
21085
  "aria-disabled": disabled ? "true" : void 0,
20847
21086
  className: cn(
20848
- "box-border inline-flex h-[var(--cmp-chip-height)] max-w-full items-center justify-center gap-[var(--cmp-chip-gap)] overflow-hidden whitespace-nowrap border-[length:var(--cmp-chip-border-width)] border-solid px-[var(--cmp-chip-paddingX)] text-[12px] leading-[20px] select-none",
20849
- editing ? "font-normal" : "font-medium",
21087
+ "box-border inline-flex h-[var(--cmp-chip-height)] max-w-full items-center justify-center gap-[var(--cmp-chip-gap)] overflow-hidden whitespace-nowrap border-[length:var(--cmp-chip-border-width)] border-solid px-[var(--cmp-chip-paddingX)] select-none",
21088
+ // chip.typography.focus / .default
21089
+ editing ? "typo-control-xs-default" : "typo-control-xs-medium",
20850
21090
  disabled ? "cursor-not-allowed" : "",
20851
21091
  className
20852
21092
  ),
@@ -21018,7 +21258,7 @@ function SFilePicker({
21018
21258
  const resolvedError = error || ruleError !== "";
21019
21259
  const resolvedStatus = status ?? (rules?.length ? ruleError !== "" ? "error" : void 0 : void 0);
21020
21260
  const padX = size === "md" ? "var(--cmp-filepicker-md-paddingX)" : "var(--cmp-filepicker-sm-paddingX)";
21021
- const iconSize = size === "md" ? 20 : 16;
21261
+ const iconSize = size === "md" ? "var(--cmp-filepicker-md-icon)" : "var(--cmp-filepicker-sm-icon)";
21022
21262
  const gapCls = size === "md" ? "gap-[var(--cmp-filepicker-md-gap)]" : "gap-[var(--cmp-filepicker-sm-gap)]";
21023
21263
  const inlinePlaceholder = inline && !disabled && !hasFiles;
21024
21264
  const showListbox = multiple && showMultipleListBox;
@@ -21072,7 +21312,8 @@ function SFilePicker({
21072
21312
  {
21073
21313
  id: displayTextId,
21074
21314
  className: cn(
21075
- "min-w-0 flex-1 truncate text-[12px]",
21315
+ "min-w-0 flex-1 truncate",
21316
+ size === "md" ? "typo-field-md-default" : "typo-field-sm-default",
21076
21317
  inlinePlaceholder && "text-[color:var(--cmp-filepicker-text-placeholder)] transition-colors group-hover/filepicker:text-[color:var(--cmp-filepicker-text-default)]"
21077
21318
  ),
21078
21319
  style: inlinePlaceholder ? void 0 : {
@@ -21246,10 +21487,10 @@ function SKeyValueTable({
21246
21487
  skipOccupied();
21247
21488
  maxCols = Math.max(maxCols, col, occupied.length);
21248
21489
  });
21249
- const radiusClass = radius === "full" ? "rounded-none" : radius === "useTop" ? "rounded-b-[8px] rounded-t-none" : "rounded-[8px]";
21490
+ const radiusClass = radius === "full" ? "rounded-none" : radius === "useTop" ? "rounded-b-[var(--cmp-table-radius)] rounded-t-none" : "rounded-[var(--cmp-table-radius)]";
21250
21491
  const frameClass = cn(
21251
21492
  "overflow-hidden",
21252
- bordered && "border border-solid border-[color:var(--cmp-table-border-color)]",
21493
+ bordered && "border-[length:var(--cmp-table-border-width)] border-solid border-[color:var(--cmp-table-border-color)]",
21253
21494
  radiusClass
21254
21495
  );
21255
21496
  const table = /* @__PURE__ */ jsxs(
@@ -21285,7 +21526,7 @@ function SKeyValueTable({
21285
21526
  paddingBottom: cellPadY
21286
21527
  },
21287
21528
  children: /* @__PURE__ */ jsxs("div", { className: "flex h-full w-full items-center justify-between gap-[var(--cmp-table-header-gap)]", children: [
21288
- /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-[8px]", children: [
21529
+ /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-[var(--cmp-table-content-gap)]", children: [
21289
21530
  /* @__PURE__ */ jsx("span", { className: "text-[12px] font-bold leading-[20px] text-[color:var(--sys-color-fg-primary)]", children: f.label }),
21290
21531
  f.required && /* @__PURE__ */ jsx(SIcon, { name: "asterisk", size: 12, color: "var(--sys-color-fg-accent)" })
21291
21532
  ] }),
@@ -23393,22 +23634,15 @@ function SToast({
23393
23634
  ...style
23394
23635
  },
23395
23636
  children: [
23396
- icon && /* @__PURE__ */ jsx(SIcon, { name: icon, size: 16, color: iconColor }),
23397
- /* @__PURE__ */ jsx(
23398
- "span",
23399
- {
23400
- className: "text-[14px] font-medium leading-[24px] text-nowrap",
23401
- style: { color: content },
23402
- children: message
23403
- }
23404
- ),
23637
+ icon && /* @__PURE__ */ jsx(SIcon, { name: icon, size: "var(--cmp-toast-icon)", color: iconColor }),
23638
+ /* @__PURE__ */ jsx("span", { className: "typo-feedback-md-medium text-nowrap", style: { color: content }, children: message }),
23405
23639
  link && /* @__PURE__ */ jsx(
23406
23640
  "a",
23407
23641
  {
23408
23642
  href: link,
23409
23643
  target: "_blank",
23410
23644
  rel: "noopener noreferrer",
23411
- className: "text-[14px] font-bold leading-[24px] underline text-nowrap",
23645
+ className: "typo-feedback-md-underline text-nowrap",
23412
23646
  style: { color: linkColor },
23413
23647
  children: linkLabel || link
23414
23648
  }
@@ -23951,9 +24185,9 @@ var SForm = /* @__PURE__ */ forwardRef(function SForm2({ formClassName, onSubmit
23951
24185
  ) });
23952
24186
  });
23953
24187
  var SIZE_CONFIG2 = {
23954
- xs: { fontSize: 12, lineHeight: 20, radius: "var(--cmp-radioButton-radius-sm)" },
23955
- sm: { fontSize: 12, lineHeight: 20, radius: "var(--cmp-radioButton-radius-sm)" },
23956
- md: { fontSize: 14, lineHeight: 24, radius: "var(--cmp-radioButton-radius-md)" }
24188
+ xs: { typo: "typo-control-xs-medium", radius: "var(--cmp-radioButton-radius-sm)" },
24189
+ sm: { typo: "typo-control-xs-medium", radius: "var(--cmp-radioButton-radius-sm)" },
24190
+ md: { typo: "typo-control-sm-default", radius: "var(--cmp-radioButton-radius-md)" }
23957
24191
  };
23958
24192
  function SRadioButton({
23959
24193
  options = [],
@@ -24002,8 +24236,9 @@ function SRadioButton({
24002
24236
  onFocus: tooltip ? () => setHoveredValue(o.value) : void 0,
24003
24237
  onBlur: tooltip ? () => setHoveredValue(null) : void 0,
24004
24238
  className: cn(
24005
- "relative box-border grow inline-flex items-center justify-center whitespace-nowrap border border-solid font-medium transition-colors",
24006
- first ? "" : "-ml-px",
24239
+ "relative box-border grow inline-flex items-center justify-center whitespace-nowrap border-(length:--cmp-radioButton-border-width) border-solid transition-colors",
24240
+ s.typo,
24241
+ first ? "" : "ml-(--cmp-radioButton-group-gap)",
24007
24242
  selected ? "z-10" : "",
24008
24243
  !od && !ro && !selected && "hover:!bg-[var(--cmp-radioButton-bg-hover)] hover:!text-[color:var(--cmp-radioButton-content-hover)] hover:!border-[color:var(--cmp-radioButton-bg-hover)] hover:z-10",
24009
24244
  od ? "cursor-not-allowed" : ro ? "cursor-default" : "cursor-pointer"
@@ -24011,8 +24246,6 @@ function SRadioButton({
24011
24246
  style: {
24012
24247
  height: `var(--cmp-radioButton-${size}-height)`,
24013
24248
  padding: `0 var(--cmp-radioButton-${size}-paddingX)`,
24014
- fontSize: `${s.fontSize}px`,
24015
- lineHeight: `${s.lineHeight}px`,
24016
24249
  borderRadius: [
24017
24250
  first ? s.radius : "0",
24018
24251
  last ? s.radius : "0",
@@ -24049,6 +24282,7 @@ function SRadioCard({
24049
24282
  value,
24050
24283
  label,
24051
24284
  subtitle,
24285
+ children,
24052
24286
  tag,
24053
24287
  disabled = false,
24054
24288
  name,
@@ -24076,72 +24310,85 @@ function SRadioCard({
24076
24310
  };
24077
24311
  const textColor = disabled ? "text-(--sys-color-disabled-text)" : null;
24078
24312
  return /* @__PURE__ */ jsxs(
24079
- "label",
24313
+ "div",
24080
24314
  {
24081
- ...cardInteractiveProps,
24082
- "aria-disabled": disabled || void 0,
24083
24315
  className: cn(
24084
- "box-border flex w-full flex-col rounded-(--cmp-radioCard-radius) border-(length:--cmp-radioCard-border-width) border-solid px-(--cmp-radioCard-paddingX) py-(--cmp-radioCard-paddingY) transition-colors",
24085
- disabled ? "cursor-not-allowed border-(--cmp-radioCard-border-default) bg-(--cmp-radioCard-bg-disabled)" : checked ? "cursor-pointer border-(--cmp-radioCard-border-selected) bg-(--cmp-radioCard-bg-selected)" : "cursor-pointer border-(--cmp-radioCard-border-default) bg-(--cmp-radioCard-bg-default) hover:border-(--cmp-radioCard-border-hover) hover:bg-(--cmp-radioCard-bg-hover)",
24316
+ "box-border flex w-full flex-col rounded-(--cmp-radioCard-radius) border-(length:--cmp-radioCard-border-width) border-solid transition-colors",
24317
+ disabled ? "border-(--cmp-radioCard-border-default) bg-(--cmp-radioCard-bg-disabled)" : checked ? "border-(--cmp-radioCard-border-selected) bg-(--cmp-radioCard-bg-selected)" : "border-(--cmp-radioCard-border-default) bg-(--cmp-radioCard-bg-default) hover:border-(--cmp-radioCard-border-hover) hover:bg-(--cmp-radioCard-bg-hover)",
24086
24318
  className
24087
24319
  ),
24088
24320
  style,
24089
24321
  children: [
24090
- /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-(--cmp-radioCard-gap)", children: [
24091
- native && /* @__PURE__ */ jsx(
24092
- "input",
24093
- {
24094
- type: "radio",
24095
- name,
24096
- value: valStr,
24097
- checked,
24098
- disabled,
24099
- onChange: () => onValueChange?.(val),
24100
- className: "sr-only"
24101
- }
24102
- ),
24103
- /* @__PURE__ */ jsx(
24104
- "span",
24105
- {
24106
- className: "flex h-(--cmp-radio-size) w-(--cmp-radio-size) shrink-0 items-center justify-center rounded-(--cmp-radio-radius) border-(length:--cmp-radio-borderWidth) border-solid border-(--rc-dot-border) bg-(--rc-dot-bg)",
24107
- style: {
24108
- "--rc-dot-bg": disabled ? "var(--cmp-radio-bg-disabled)" : "var(--cmp-radio-bg-default)",
24109
- "--rc-dot-border": disabled ? "var(--cmp-radio-border-disabled)" : checked ? "var(--cmp-radio-border-active)" : "var(--cmp-radio-border-default)"
24110
- },
24111
- children: checked && /* @__PURE__ */ jsx(
24322
+ /* @__PURE__ */ jsxs(
24323
+ "label",
24324
+ {
24325
+ ...cardInteractiveProps,
24326
+ "aria-disabled": disabled || void 0,
24327
+ className: cn(
24328
+ "box-border flex w-full flex-col px-(--cmp-radioCard-paddingX) py-(--cmp-radioCard-paddingY)",
24329
+ disabled ? "cursor-not-allowed" : "cursor-pointer"
24330
+ ),
24331
+ children: [
24332
+ /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-(--cmp-radioCard-gap)", children: [
24333
+ native && /* @__PURE__ */ jsx(
24334
+ "input",
24335
+ {
24336
+ type: "radio",
24337
+ name,
24338
+ value: valStr,
24339
+ checked,
24340
+ disabled,
24341
+ onChange: () => onValueChange?.(val),
24342
+ className: "sr-only"
24343
+ }
24344
+ ),
24345
+ /* @__PURE__ */ jsx(
24346
+ "span",
24347
+ {
24348
+ className: "flex h-(--cmp-radio-size) w-(--cmp-radio-size) shrink-0 items-center justify-center rounded-(--cmp-radio-radius) border-(length:--cmp-radio-borderWidth) border-solid border-(--rc-dot-border) bg-(--rc-dot-bg)",
24349
+ style: {
24350
+ "--rc-dot-bg": disabled ? "var(--cmp-radio-bg-disabled)" : "var(--cmp-radio-bg-default)",
24351
+ "--rc-dot-border": disabled ? "var(--cmp-radio-border-disabled)" : checked ? "var(--cmp-radio-border-active)" : "var(--cmp-radio-border-default)"
24352
+ },
24353
+ children: checked && /* @__PURE__ */ jsx(
24354
+ "span",
24355
+ {
24356
+ className: "h-(--cmp-radio-dot-size) w-(--cmp-radio-dot-size) rounded-(--cmp-radio-radius) bg-(--rc-dot-fill)",
24357
+ style: {
24358
+ "--rc-dot-fill": disabled ? "var(--cmp-radio-dot-disabled)" : "var(--cmp-radio-dot-default)"
24359
+ }
24360
+ }
24361
+ )
24362
+ }
24363
+ ),
24364
+ /* @__PURE__ */ jsxs("span", { className: cn("grid min-w-0", textColor ?? "text-(--cmp-radioCard-label-color)"), children: [
24365
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "typo-body-md-bold invisible", style: { gridArea: "1 / 1" }, children: label }),
24366
+ /* @__PURE__ */ jsx(
24367
+ "span",
24368
+ {
24369
+ className: checked ? "typo-body-md-bold" : "typo-body-md-semibold",
24370
+ style: { gridArea: "1 / 1" },
24371
+ children: label
24372
+ }
24373
+ )
24374
+ ] }),
24375
+ tag && /* @__PURE__ */ jsx(STag, { ...tag, size: "xs", className: "ml-auto" })
24376
+ ] }),
24377
+ subtitle && /* @__PURE__ */ jsx(
24112
24378
  "span",
24113
24379
  {
24114
- className: "h-(--cmp-radio-dot-size) w-(--cmp-radio-dot-size) rounded-(--cmp-radio-radius) bg-(--rc-dot-fill)",
24115
- style: {
24116
- "--rc-dot-fill": disabled ? "var(--cmp-radio-dot-disabled)" : "var(--cmp-radio-dot-default)"
24117
- }
24380
+ className: cn(
24381
+ "typo-body-sm-default pl-(--cmp-radioCard-subtitle-paddingLeft)",
24382
+ textColor ?? "text-(--cmp-radioCard-subtitle-color)"
24383
+ ),
24384
+ children: subtitle
24118
24385
  }
24119
24386
  )
24120
- }
24121
- ),
24122
- /* @__PURE__ */ jsxs("span", { className: cn("grid min-w-0", textColor ?? "text-(--cmp-radioCard-label-color)"), children: [
24123
- /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "typo-body-md-bold invisible", style: { gridArea: "1 / 1" }, children: label }),
24124
- /* @__PURE__ */ jsx(
24125
- "span",
24126
- {
24127
- className: checked ? "typo-body-md-bold" : "typo-body-md-semibold",
24128
- style: { gridArea: "1 / 1" },
24129
- children: label
24130
- }
24131
- )
24132
- ] }),
24133
- tag && /* @__PURE__ */ jsx(STag, { ...tag, size: "xs", className: "ml-auto" })
24134
- ] }),
24135
- subtitle && /* @__PURE__ */ jsx(
24136
- "span",
24137
- {
24138
- className: cn(
24139
- "typo-body-sm-default pl-(--cmp-radioCard-subtitle-paddingLeft)",
24140
- textColor ?? "text-(--cmp-radioCard-subtitle-color)"
24141
- ),
24142
- children: subtitle
24387
+ ]
24143
24388
  }
24144
- )
24389
+ ),
24390
+ children != null && children !== false && // 라벨 왼쪽 끝(카드 여백 + 서브타이틀 들여쓰기)에 맞춘다. 서브타이틀과의 간격은 label 의 아래 여백이다
24391
+ /* @__PURE__ */ jsx("div", { className: "box-border w-full pr-(--cmp-radioCard-paddingX) pb-(--cmp-radioCard-paddingY) pl-[calc(var(--cmp-radioCard-paddingX)+var(--cmp-radioCard-subtitle-paddingLeft))]", children })
24145
24392
  ]
24146
24393
  }
24147
24394
  );
@@ -24176,7 +24423,8 @@ function SRadioCardGroup({
24176
24423
  tag: o.tag,
24177
24424
  name: groupName,
24178
24425
  disabled: disabled || o.disabled,
24179
- onValueChange
24426
+ onValueChange,
24427
+ children: o.content
24180
24428
  },
24181
24429
  String(o.value)
24182
24430
  ))
@@ -26515,6 +26763,7 @@ var CHIPFILTER = {
26515
26763
  dividerHeight: "var(--cmp-chipFilter-divider-height)",
26516
26764
  chipHeight: "var(--cmp-chipFilter-chip-height)",
26517
26765
  chipRadius: "var(--cmp-chipFilter-chip-radius)",
26766
+ chipPaddingX: "var(--cmp-chipFilter-chip-paddingX)",
26518
26767
  chipGap: "var(--cmp-chipFilter-chip-gap)",
26519
26768
  chipDefaultBg: "var(--cmp-chipFilter-chip-default-bg)",
26520
26769
  chipDefaultBorder: "var(--cmp-chipFilter-chip-default-border)",
@@ -26525,7 +26774,7 @@ var CHIPFILTER = {
26525
26774
  chipAppliedBg: "var(--cmp-chipFilter-chip-applied-bg)",
26526
26775
  chipAppliedBorder: "var(--cmp-chipFilter-chip-applied-border)",
26527
26776
  chipAppliedLabel: "var(--cmp-chipFilter-chip-applied-text-label)",
26528
- chipAppliedValue: "var(--color-brilliantblue-80)",
26777
+ chipAppliedValue: "var(--cmp-chipFilter-chip-applied-text-data)",
26529
26778
  chipDisabledBg: "var(--cmp-chipFilter-chip-disabled-bg)",
26530
26779
  chipDisabledBorder: "var(--cmp-chipFilter-chip-disabled-border)",
26531
26780
  chipDisabledText: "var(--cmp-chipFilter-chip-disabled-text)",
@@ -27160,20 +27409,13 @@ var SChipFilter = /* @__PURE__ */ forwardRef(function SChipFilter2({
27160
27409
  onValueChange: (next) => emitValueAndSearch(field.key, next)
27161
27410
  }),
27162
27411
  addable && !disabled && !field.disabled && showClear && /* @__PURE__ */ jsx(
27163
- "button",
27412
+ SGhostButton,
27164
27413
  {
27165
- type: "button",
27166
- "aria-label": `${field.label} \uD544\uD130 \uC81C\uAC70`,
27167
- className: "inline-flex size-[16px] shrink-0 items-center justify-center rounded-[var(--cmp-ghostButton-radius-sm)] border-none bg-transparent p-0",
27168
- onClick: handleClear,
27169
- children: /* @__PURE__ */ jsx(
27170
- SIcon,
27171
- {
27172
- name: "close",
27173
- size: 12,
27174
- color: "var(--cmp-ghostButton-default-content)"
27175
- }
27176
- )
27414
+ icon: "close",
27415
+ size: "xxs",
27416
+ ariaLabel: `${field.label} \uD544\uD130 \uC81C\uAC70`,
27417
+ className: "shrink-0",
27418
+ onClick: handleClear
27177
27419
  }
27178
27420
  )
27179
27421
  ] }, field.key) : /* @__PURE__ */ jsx(
@@ -27216,7 +27458,7 @@ var SChipFilter = /* @__PURE__ */ forwardRef(function SChipFilter2({
27216
27458
  {
27217
27459
  type: "button",
27218
27460
  disabled: disabled || inactiveFields.length === 0,
27219
- className: "inline-flex shrink-0 cursor-pointer items-center justify-center gap-[var(--cmp-chipFilter-addButton-gap)] whitespace-nowrap border border-solid bg-[var(--cmp-chipFilter-addButton-bg)] px-[var(--cmp-chipFilter-addButton-paddingX)] text-[12px] font-medium leading-[20px] outline-none disabled:cursor-not-allowed",
27461
+ className: "inline-flex shrink-0 cursor-pointer items-center justify-center gap-[var(--cmp-chipFilter-addButton-gap)] whitespace-nowrap border border-solid bg-[var(--cmp-chipFilter-addButton-bg)] px-[var(--cmp-chipFilter-addButton-paddingX)] typo-control-xs-medium outline-none disabled:cursor-not-allowed",
27220
27462
  style: {
27221
27463
  minHeight: "var(--cmp-chipFilter-addButton-height)" ,
27222
27464
  borderRadius: "var(--cmp-chipFilter-addButton-radius)" ,
@@ -27228,7 +27470,7 @@ var SChipFilter = /* @__PURE__ */ forwardRef(function SChipFilter2({
27228
27470
  SIcon,
27229
27471
  {
27230
27472
  name: "add",
27231
- size: 12,
27473
+ size: "var(--cmp-chipFilter-addButton-icon)",
27232
27474
  color: disabled || inactiveFields.length === 0 ? CHIPFILTER.addTextDisabled : CHIPFILTER.addText
27233
27475
  }
27234
27476
  ),
@@ -27264,9 +27506,9 @@ var SChipFilter = /* @__PURE__ */ forwardRef(function SChipFilter2({
27264
27506
  onClick: reset,
27265
27507
  className: cn(
27266
27508
  "shrink-0",
27267
- // 부모 flex gap(6px)은 칩 사이 간격 기준이라, 필터 추가 버튼과의 12px 간격을 맞추려면
27268
- // 부족한 만큼(12px - gap)을 추가로 띄운다. 필터 추가가 없을 땐 divider와 이미 12px이라 불필요.
27269
- hasAddButton && "ml-[calc(12px-var(--cmp-chipFilter-chip-group))]"
27509
+ // 부모 flex gap(chip-group)은 칩 사이 간격 기준이라, 필터 추가 버튼과의 bar-gap 간격을 맞추려면
27510
+ // 부족한 만큼(bar-gap - chip-group)을 추가로 띄운다. 필터 추가가 없을 땐 divider와 이미 bar-gap이라 불필요.
27511
+ hasAddButton && "ml-[calc(var(--cmp-chipFilter-bar-gap)_-_var(--cmp-chipFilter-chip-group))]"
27270
27512
  )
27271
27513
  }
27272
27514
  )
@@ -27320,7 +27562,7 @@ function Divider({ inset, top } = {}) {
27320
27562
  className: cn(
27321
27563
  "inline-flex w-px shrink-0 bg-[var(--chipfilter-bar-border)]",
27322
27564
  top ? "mt-[2px] self-start" : "my-auto",
27323
- inset && "mx-[calc(12px-var(--cmp-chipFilter-chip-group))]"
27565
+ inset && "mx-[calc(var(--cmp-chipFilter-bar-gap)_-_var(--cmp-chipFilter-chip-group))]"
27324
27566
  ),
27325
27567
  style: { height: "var(--chipfilter-divider-height)" }
27326
27568
  }
@@ -27360,87 +27602,97 @@ function FilterChip({
27360
27602
  const border = disabled ? CHIPFILTER.chipDisabledBorder : warning ? CHIPFILTER.chipWarningBorder : applied ? active ? "var(--color-blue-strong)" : CHIPFILTER.chipAppliedBorder : active ? CHIPFILTER.chipActiveBorder : CHIPFILTER.chipDefaultBorder;
27361
27603
  const background = disabled ? CHIPFILTER.chipDisabledBg : applied ? CHIPFILTER.chipAppliedBg : CHIPFILTER.chipDefaultBg;
27362
27604
  const textColor = disabled ? CHIPFILTER.chipDisabledText : CHIPFILTER.chipDefaultText;
27605
+ const hasClear = !disabled && showClear && (applied || showClearWhenEmpty);
27363
27606
  return /* @__PURE__ */ jsxs(
27364
- "button",
27607
+ "div",
27365
27608
  {
27366
- ref: refCallback,
27367
- type: "button",
27368
- disabled,
27369
- "aria-expanded": active,
27370
27609
  onPointerDown: (event) => event.stopPropagation(),
27371
- onClick: onOpen,
27372
- className: "group/chip-filter inline-flex max-w-full shrink-0 cursor-pointer items-center justify-center whitespace-nowrap border border-solid px-[var(--cmp-chipFilter-chip-paddingX)] text-[12px] leading-[20px] outline-none disabled:cursor-not-allowed",
27610
+ className: "inline-flex max-w-full shrink-0 items-stretch whitespace-nowrap border border-solid",
27373
27611
  style: {
27374
27612
  minHeight: CHIPFILTER.chipHeight,
27375
27613
  gap: CHIPFILTER.chipGap,
27376
27614
  borderRadius: CHIPFILTER.chipRadius,
27377
27615
  borderColor: border,
27378
27616
  background,
27379
- color: textColor
27617
+ paddingRight: hasClear ? CHIPFILTER.chipPaddingX : void 0
27380
27618
  },
27381
27619
  children: [
27382
- field.required && /* @__PURE__ */ jsx(
27383
- SIcon,
27620
+ /* @__PURE__ */ jsxs(
27621
+ "button",
27384
27622
  {
27385
- name: "asterisk",
27386
- size: 12,
27387
- color: disabled ? CHIPFILTER.chipDisabledText : "var(--cmp-tag-darkblue-content)"
27623
+ ref: refCallback,
27624
+ type: "button",
27625
+ disabled,
27626
+ "aria-expanded": active,
27627
+ onClick: onOpen,
27628
+ className: "inline-flex min-w-0 cursor-pointer items-center justify-center border-none bg-transparent p-0 typo-body-sm-default outline-none disabled:cursor-not-allowed",
27629
+ style: {
27630
+ gap: CHIPFILTER.chipGap,
27631
+ paddingLeft: CHIPFILTER.chipPaddingX,
27632
+ paddingRight: hasClear ? void 0 : CHIPFILTER.chipPaddingX,
27633
+ color: textColor
27634
+ },
27635
+ children: [
27636
+ field.required && /* @__PURE__ */ jsx(
27637
+ SIcon,
27638
+ {
27639
+ name: "asterisk",
27640
+ size: "var(--cmp-chipFilter-chip-icon-essential)",
27641
+ color: disabled ? CHIPFILTER.chipDisabledText : "var(--cmp-tag-darkblue-content)"
27642
+ }
27643
+ ),
27644
+ applied ? /* @__PURE__ */ jsxs("span", { className: "inline-flex min-w-0 items-center gap-[4px] truncate", children: [
27645
+ /* @__PURE__ */ jsx(
27646
+ "span",
27647
+ {
27648
+ className: "typo-body-sm-bold",
27649
+ style: {
27650
+ color: disabled ? CHIPFILTER.chipDisabledText : CHIPFILTER.chipAppliedLabel
27651
+ },
27652
+ children: field.label
27653
+ }
27654
+ ),
27655
+ /* @__PURE__ */ jsx(
27656
+ "span",
27657
+ {
27658
+ style: {
27659
+ color: disabled ? CHIPFILTER.chipDisabledText : CHIPFILTER.chipAppliedLabel
27660
+ },
27661
+ children: ":"
27662
+ }
27663
+ ),
27664
+ /* @__PURE__ */ jsx(
27665
+ "span",
27666
+ {
27667
+ className: "min-w-0 truncate typo-body-sm-bold",
27668
+ style: {
27669
+ color: disabled ? CHIPFILTER.chipDisabledText : CHIPFILTER.chipAppliedValue
27670
+ },
27671
+ children: valueText
27672
+ }
27673
+ )
27674
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
27675
+ /* @__PURE__ */ jsx("span", { className: cn("min-w-0 truncate", active && "typo-body-sm-bold"), children: field.label }),
27676
+ /* @__PURE__ */ jsx(
27677
+ SIcon,
27678
+ {
27679
+ name: "caretDown",
27680
+ size: "var(--cmp-chipFilter-chip-icon-caret)",
27681
+ color: disabled ? CHIPFILTER.chipDisabledText : CHIPFILTER.chipCaret
27682
+ }
27683
+ )
27684
+ ] })
27685
+ ]
27388
27686
  }
27389
27687
  ),
27390
- applied ? /* @__PURE__ */ jsxs("span", { className: "inline-flex min-w-0 items-center gap-[4px] truncate", children: [
27391
- /* @__PURE__ */ jsx(
27392
- "span",
27393
- {
27394
- className: "font-bold",
27395
- style: { color: disabled ? CHIPFILTER.chipDisabledText : CHIPFILTER.chipAppliedLabel },
27396
- children: field.label
27397
- }
27398
- ),
27399
- /* @__PURE__ */ jsx(
27400
- "span",
27401
- {
27402
- style: { color: disabled ? CHIPFILTER.chipDisabledText : CHIPFILTER.chipAppliedLabel },
27403
- children: ":"
27404
- }
27405
- ),
27406
- /* @__PURE__ */ jsx(
27407
- "span",
27408
- {
27409
- className: "min-w-0 truncate font-bold",
27410
- style: { color: disabled ? CHIPFILTER.chipDisabledText : CHIPFILTER.chipAppliedValue },
27411
- children: valueText
27412
- }
27413
- )
27414
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
27415
- /* @__PURE__ */ jsx("span", { className: cn("min-w-0 truncate", active && "font-bold"), children: field.label }),
27416
- /* @__PURE__ */ jsx(
27417
- SIcon,
27418
- {
27419
- name: "caretDown",
27420
- size: 12,
27421
- color: disabled ? CHIPFILTER.chipDisabledText : CHIPFILTER.chipCaret
27422
- }
27423
- )
27424
- ] }),
27425
- !disabled && showClear && (applied || showClearWhenEmpty) && /* @__PURE__ */ jsx(
27426
- "span",
27688
+ hasClear && /* @__PURE__ */ jsx(
27689
+ SGhostButton,
27427
27690
  {
27428
- role: "button",
27429
- tabIndex: 0,
27430
- "aria-label": `${field.label} \uD544\uD130 \uC9C0\uC6B0\uAE30`,
27431
- className: "inline-flex size-[16px] items-center justify-center rounded-[var(--cmp-ghostButton-radius-sm)]",
27432
- onClick: (event) => {
27433
- event.preventDefault();
27434
- event.stopPropagation();
27435
- onClear();
27436
- },
27437
- onKeyDown: (event) => {
27438
- if (event.key !== "Enter" && event.key !== " ") return;
27439
- event.preventDefault();
27440
- event.stopPropagation();
27441
- onClear();
27442
- },
27443
- children: /* @__PURE__ */ jsx(SIcon, { name: "close", size: 12, color: "var(--cmp-ghostButton-default-content)" })
27691
+ icon: "close",
27692
+ size: "xxs",
27693
+ ariaLabel: `${field.label} \uD544\uD130 \uC9C0\uC6B0\uAE30`,
27694
+ className: "shrink-0 self-center",
27695
+ onClick: onClear
27444
27696
  }
27445
27697
  )
27446
27698
  ]
@@ -27820,47 +28072,18 @@ function InlineDatePresetFilter({
27820
28072
  const badgeBackground = disabled ? CHIPFILTER.chipDisabledBg : CHIPFILTER.chipAppliedBg;
27821
28073
  const badgeLabelColor = disabled ? CHIPFILTER.chipDisabledText : CHIPFILTER.chipAppliedLabel;
27822
28074
  const badgeValueColor = disabled ? CHIPFILTER.chipDisabledText : CHIPFILTER.chipAppliedValue;
27823
- const badge = applied && /* @__PURE__ */ jsxs(
27824
- "span",
27825
- {
27826
- className: "inline-flex shrink-0 items-center gap-[4px] whitespace-nowrap border border-solid px-[var(--cmp-chipFilter-chip-paddingX)] text-[12px] leading-[20px]",
27827
- style: {
27828
- minHeight: CHIPFILTER.chipHeight,
27829
- borderRadius: CHIPFILTER.chipRadius,
27830
- borderColor: badgeBorder,
27831
- background: badgeBackground,
27832
- color: badgeLabelColor,
27833
- cursor: rangeValue && !disabled ? "pointer" : void 0
27834
- },
27835
- children: [
27836
- /* @__PURE__ */ jsxs("span", { className: "font-bold", children: [
27837
- field.label,
27838
- ":"
27839
- ] }),
27840
- /* @__PURE__ */ jsx("span", { className: "font-bold", style: { color: badgeValueColor }, children: displayValue(field, value) }),
27841
- !disabled && showClear && /* @__PURE__ */ jsx(
27842
- "span",
27843
- {
27844
- role: "button",
27845
- tabIndex: 0,
27846
- "aria-label": `${field.label} \uD544\uD130 \uC9C0\uC6B0\uAE30`,
27847
- className: "inline-flex size-[16px] items-center justify-center rounded-[var(--cmp-ghostButton-radius-sm)]",
27848
- onClick: (event) => {
27849
- event.stopPropagation();
27850
- onClear();
27851
- },
27852
- onKeyDown: (event) => {
27853
- if (event.key !== "Enter" && event.key !== " ") return;
27854
- event.preventDefault();
27855
- event.stopPropagation();
27856
- onClear();
27857
- },
27858
- children: /* @__PURE__ */ jsx(SIcon, { name: "close", size: 12, color: "var(--cmp-ghostButton-default-content)" })
27859
- }
27860
- )
27861
- ]
27862
- }
27863
- );
28075
+ const hasClear = !disabled && showClear;
28076
+ const badgeTextStyle = {
28077
+ paddingLeft: CHIPFILTER.chipPaddingX,
28078
+ paddingRight: hasClear ? void 0 : CHIPFILTER.chipPaddingX
28079
+ };
28080
+ const badgeText = /* @__PURE__ */ jsxs(Fragment, { children: [
28081
+ /* @__PURE__ */ jsxs("span", { className: "typo-body-sm-bold", children: [
28082
+ field.label,
28083
+ ":"
28084
+ ] }),
28085
+ /* @__PURE__ */ jsx("span", { className: "typo-body-sm-bold", style: { color: badgeValueColor }, children: displayValue(field, value) })
28086
+ ] });
27864
28087
  return /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-[8px]", children: [
27865
28088
  /* @__PURE__ */ jsx(
27866
28089
  SRadioButton,
@@ -27872,43 +28095,71 @@ function InlineDatePresetFilter({
27872
28095
  onValueChange: (next) => selectPreset(String(next))
27873
28096
  }
27874
28097
  ),
27875
- applied && (rangeValue ? (
27876
- // 뱃지 모양은 그대로 두고, 눌렀을 때 캘린더가 열려 기간을 직접 다시 고를 수 있게 한다.
27877
- // 직접 고르면 프리셋 선택은 해제된다.
27878
- /* @__PURE__ */ jsxs(RPopover13.Root, { open: pickerOpen, onOpenChange: setPickerOpen, children: [
27879
- /* @__PURE__ */ jsx(RPopover13.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(
27880
- "button",
27881
- {
27882
- type: "button",
27883
- disabled,
27884
- className: "border-none bg-transparent p-0 outline-none disabled:cursor-not-allowed",
27885
- children: badge
27886
- }
27887
- ) }),
27888
- /* @__PURE__ */ jsx(RPopover13.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
27889
- RPopover13.Content,
27890
- {
27891
- side: "bottom",
27892
- align: "start",
27893
- sideOffset: 4,
27894
- className: cn("z-50", FLOATING_SLIDE_ANIM),
27895
- children: /* @__PURE__ */ jsx(
27896
- RangeCalendar,
27897
- {
27898
- value: rangeValue,
27899
- selectable: field.selectable,
27900
- maxRange: field.maxRange,
27901
- onSelect: (range) => {
27902
- setSelectedId(null);
27903
- onValueChange(range);
27904
- setPickerOpen(false);
28098
+ applied && // 뱃지 모양(테두리·배경)은 바깥이 맡고, 라벨·값 칸과 지우기 × 를 형제로 둔다 — FilterChip 과
28099
+ // 같은 이유로, 캘린더를 여는 버튼 안에 × 를 넣지 않는다.
28100
+ /* @__PURE__ */ jsxs(
28101
+ "span",
28102
+ {
28103
+ className: "inline-flex shrink-0 items-stretch gap-[4px] whitespace-nowrap border border-solid typo-body-sm-default",
28104
+ style: {
28105
+ minHeight: CHIPFILTER.chipHeight,
28106
+ borderRadius: CHIPFILTER.chipRadius,
28107
+ borderColor: badgeBorder,
28108
+ background: badgeBackground,
28109
+ color: badgeLabelColor,
28110
+ paddingRight: hasClear ? CHIPFILTER.chipPaddingX : void 0
28111
+ },
28112
+ children: [
28113
+ rangeValue ? (
28114
+ // 눌렀을 때 캘린더가 열려 기간을 직접 다시 고를 수 있게 한다. 직접 고르면 프리셋 선택은 해제된다.
28115
+ /* @__PURE__ */ jsxs(RPopover13.Root, { open: pickerOpen, onOpenChange: setPickerOpen, children: [
28116
+ /* @__PURE__ */ jsx(RPopover13.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(
28117
+ "button",
28118
+ {
28119
+ type: "button",
28120
+ disabled,
28121
+ className: "inline-flex cursor-pointer items-center gap-[4px] border-none bg-transparent p-0 outline-none disabled:cursor-not-allowed",
28122
+ style: badgeTextStyle,
28123
+ children: badgeText
27905
28124
  }
27906
- }
27907
- )
27908
- }
27909
- ) })
27910
- ] })
27911
- ) : badge)
28125
+ ) }),
28126
+ /* @__PURE__ */ jsx(RPopover13.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
28127
+ RPopover13.Content,
28128
+ {
28129
+ side: "bottom",
28130
+ align: "start",
28131
+ sideOffset: 4,
28132
+ className: cn("z-50", FLOATING_SLIDE_ANIM),
28133
+ children: /* @__PURE__ */ jsx(
28134
+ RangeCalendar,
28135
+ {
28136
+ value: rangeValue,
28137
+ selectable: field.selectable,
28138
+ maxRange: field.maxRange,
28139
+ onSelect: (range) => {
28140
+ setSelectedId(null);
28141
+ onValueChange(range);
28142
+ setPickerOpen(false);
28143
+ }
28144
+ }
28145
+ )
28146
+ }
28147
+ ) })
28148
+ ] })
28149
+ ) : /* @__PURE__ */ jsx("span", { className: "inline-flex items-center gap-[4px]", style: badgeTextStyle, children: badgeText }),
28150
+ hasClear && /* @__PURE__ */ jsx(
28151
+ SGhostButton,
28152
+ {
28153
+ icon: "close",
28154
+ size: "xxs",
28155
+ ariaLabel: `${field.label} \uD544\uD130 \uC9C0\uC6B0\uAE30`,
28156
+ className: "shrink-0 self-center",
28157
+ onClick: onClear
28158
+ }
28159
+ )
28160
+ ]
28161
+ }
28162
+ )
27912
28163
  ] });
27913
28164
  }
27914
28165
  var MATCH_MODE_OPTIONS = [
@@ -27997,7 +28248,7 @@ function KeywordEditor({
27997
28248
  /* @__PURE__ */ jsx(
27998
28249
  "span",
27999
28250
  {
28000
- className: "shrink-0 whitespace-nowrap text-[12px] font-medium leading-[20px]",
28251
+ className: "shrink-0 whitespace-nowrap typo-body-sm-medium",
28001
28252
  style: { color: CHIPFILTER.listboxLabel },
28002
28253
  children: "\uAC80\uC0C9 \uC870\uAC74 :"
28003
28254
  }
@@ -28057,7 +28308,7 @@ function KeywordEntryRow({
28057
28308
  return /* @__PURE__ */ jsxs(
28058
28309
  "div",
28059
28310
  {
28060
- className: "group flex w-full items-center justify-between gap-[8px] text-[12px] leading-[20px]",
28311
+ className: "group flex w-full items-center justify-between gap-[8px] typo-body-sm-default",
28061
28312
  style: {
28062
28313
  paddingTop: CHIPFILTER.itemPaddingY,
28063
28314
  paddingBottom: CHIPFILTER.itemPaddingY,
@@ -28068,13 +28319,13 @@ function KeywordEntryRow({
28068
28319
  children: [
28069
28320
  /* @__PURE__ */ jsx("span", { className: cn("min-w-0 truncate", !disabled && "group-hover:font-bold"), children: label }),
28070
28321
  !disabled && /* @__PURE__ */ jsx(
28071
- "button",
28322
+ SGhostButton,
28072
28323
  {
28073
- type: "button",
28074
- "aria-label": `${label} \uC0AD\uC81C`,
28075
- className: "invisible inline-flex size-[16px] shrink-0 cursor-pointer items-center justify-center group-hover:visible",
28076
- onClick: onRemove,
28077
- children: /* @__PURE__ */ jsx(SIcon, { name: "close", size: 12, color: "var(--cmp-ghostButton-default-content)" })
28324
+ icon: "close",
28325
+ size: "xxs",
28326
+ ariaLabel: `${label} \uC0AD\uC81C`,
28327
+ className: "invisible shrink-0 group-hover:visible",
28328
+ onClick: onRemove
28078
28329
  }
28079
28330
  )
28080
28331
  ]
@@ -28083,7 +28334,7 @@ function KeywordEntryRow({
28083
28334
  }
28084
28335
  var OPTION_SEARCH_THRESHOLD = 11;
28085
28336
  var filterFlatOptions = (flat, query) => filterDepthRows(flat, (option) => option.label.toLowerCase().includes(query));
28086
- var depthPaddingLeft = (depth) => depth === 1 ? 12 : depth === 2 ? 20 : 28;
28337
+ var depthPaddingLeft = (depth) => LIST_BOX_ITEM_PADDING_LEFT[depth === 1 ? 1 : depth === 2 ? 2 : 3];
28087
28338
  function OptionList({
28088
28339
  field,
28089
28340
  value,
@@ -28299,14 +28550,14 @@ function OptionCheckbox({ checked, disabled }) {
28299
28550
  "span",
28300
28551
  {
28301
28552
  className: cn(
28302
- "inline-flex size-[16px] shrink-0 items-center justify-center rounded-[2px] border border-solid",
28553
+ "inline-flex size-(--cmp-checkbox-size) shrink-0 items-center justify-center rounded-(--cmp-checkbox-radius) border-(length:--cmp-checkbox-borderWidth) border-solid",
28303
28554
  disabled ? "border-[color:var(--cmp-checkbox-border-disabled)] bg-[var(--cmp-checkbox-bg-disabled)]" : filled ? "border-[color:var(--cmp-checkbox-checked-bg-default)] bg-[var(--cmp-checkbox-checked-bg-default)]" : "border-[color:var(--cmp-checkbox-unchecked-border-default)] bg-[var(--cmp-checkbox-unchecked-bg-default)]"
28304
28555
  ),
28305
28556
  children: filled && /* @__PURE__ */ jsx(
28306
28557
  SIcon,
28307
28558
  {
28308
28559
  name: checked === null ? "checkboxIndeterminate" : "checkboxCheck",
28309
- size: 12,
28560
+ size: "var(--cmp-checkbox-icon)",
28310
28561
  color: disabled ? "var(--cmp-checkbox-checked-icon-disabled)" : "var(--cmp-checkbox-checked-icon-default)"
28311
28562
  }
28312
28563
  )
@@ -28351,8 +28602,8 @@ function MenuItem({
28351
28602
  onMouseEnter,
28352
28603
  onClick,
28353
28604
  className: cn(
28354
- "flex w-full min-w-0 cursor-pointer items-center gap-[8px] border-none bg-transparent text-left text-[12px] leading-[20px] outline-none disabled:cursor-not-allowed",
28355
- selected ? "font-bold" : "font-normal",
28605
+ "flex w-full min-w-0 cursor-pointer items-center gap-[8px] border-none bg-transparent text-left outline-none disabled:cursor-not-allowed",
28606
+ selected ? "typo-body-sm-bold" : "typo-body-sm-default",
28356
28607
  !disabled && "hover:font-bold"
28357
28608
  ),
28358
28609
  style: {
@@ -28589,7 +28840,7 @@ var SChipInput = /* @__PURE__ */ forwardRef(function SChipInput2({
28589
28840
  labelPosition,
28590
28841
  subLabel,
28591
28842
  labelWidth,
28592
- labelHeight: `calc(var(--cmp-chipInput-${size}-minHeight) + 2px)`,
28843
+ labelHeight: `calc(var(--cmp-chipInput-${size}-minHeight) + var(--cmp-chipInput-borderWidth) * 2)`,
28593
28844
  icon,
28594
28845
  iconColor,
28595
28846
  labelTooltip,
@@ -28674,8 +28925,8 @@ var SChipInput = /* @__PURE__ */ forwardRef(function SChipInput2({
28674
28925
  {
28675
28926
  "aria-hidden": true,
28676
28927
  className: cn(
28677
- "invisible col-start-1 row-start-1 whitespace-pre font-normal",
28678
- size === "md" ? "text-14 leading-sd-24" : "text-12 leading-sd-20"
28928
+ "invisible col-start-1 row-start-1 whitespace-pre",
28929
+ size === "md" ? "typo-field-md-default" : "typo-field-sm-default"
28679
28930
  ),
28680
28931
  children: inputValue !== "" ? inputValue : values.length === 0 ? placeholder : ""
28681
28932
  }
@@ -28694,9 +28945,9 @@ var SChipInput = /* @__PURE__ */ forwardRef(function SChipInput2({
28694
28945
  "aria-activedescendant": showDropdown && activeIndex >= 0 ? activeOptionId : void 0,
28695
28946
  "aria-autocomplete": "list",
28696
28947
  className: cn(
28697
- "s-chip-input__input col-start-1 row-start-1 w-full border-0 bg-transparent p-0 font-normal text-(--cmp-chip-content-focus) outline-none placeholder:text-(--cmp-chipInput-text-placeholder) disabled:cursor-not-allowed",
28948
+ "s-chip-input__input col-start-1 row-start-1 w-full border-0 bg-transparent p-0 text-(--cmp-chip-content-focus) outline-none placeholder:text-(--cmp-chipInput-text-placeholder) disabled:cursor-not-allowed",
28698
28949
  AUTOFILL_RESET_CLASS,
28699
- size === "md" ? "text-14 leading-sd-24" : "text-12 leading-sd-20"
28950
+ size === "md" ? "typo-field-md-default" : "typo-field-sm-default"
28700
28951
  ),
28701
28952
  style: {
28702
28953
  minWidth: "1ch",
@@ -28866,7 +29117,7 @@ var SChipInput = /* @__PURE__ */ forwardRef(function SChipInput2({
28866
29117
  "aria-selected": selected || active,
28867
29118
  tabIndex: -1,
28868
29119
  className: cn(
28869
- "s-chip-input__suggestion-item flex shrink-0 cursor-pointer items-center gap-sd-8 overflow-hidden text-ellipsis whitespace-nowrap px-sd-12 py-sd-4 text-12 leading-sd-20",
29120
+ "s-chip-input__suggestion-item flex shrink-0 cursor-pointer items-center gap-(--cmp-listBoxItem-gap) overflow-hidden text-ellipsis whitespace-nowrap py-(--cmp-listBoxItem-paddingY) pl-(--cmp-listBoxItem-paddingLeft-depth1) pr-(--cmp-listBoxItem-paddingRight) typo-field-sm-default",
28870
29121
  selected ? "cursor-default overflow-visible font-bold text-(--cmp-listBoxItem-content-selected)" : active ? "bg-(--cmp-listBoxItem-bg-hover) font-medium text-(--cmp-listBoxItem-content-hover)" : "text-(--cmp-listBoxItem-content-default)"
28871
29122
  ),
28872
29123
  onMouseDown: (e) => {
@@ -29075,7 +29326,7 @@ var TIMEPICKER_SIZE_CONFIG = {
29075
29326
  gap: V4("sm-gap"),
29076
29327
  icon: V4("sm-icon"),
29077
29328
  radius: V4("sm-radius"),
29078
- // TODO: component.timepicker 토큰에 typography가 추가되면 CSS 변수로 교체한다.
29329
+ typography: "typo-field-sm-default",
29079
29330
  fontSize: 12,
29080
29331
  lineHeight: 20,
29081
29332
  minWidth: 80,
@@ -29088,7 +29339,7 @@ var TIMEPICKER_SIZE_CONFIG = {
29088
29339
  gap: V4("md-gap"),
29089
29340
  icon: V4("md-icon"),
29090
29341
  radius: V4("md-radius"),
29091
- // TODO: component.timepicker 토큰에 typography가 추가되면 CSS 변수로 교체한다.
29342
+ typography: "typo-field-md-default",
29092
29343
  fontSize: 14,
29093
29344
  lineHeight: 24,
29094
29345
  minWidth: 96,
@@ -29419,11 +29670,9 @@ function STimePicker({
29419
29670
  "span",
29420
29671
  {
29421
29672
  id: triggerTextId,
29422
- className: "flex-1 truncate text-center",
29673
+ className: cn("flex-1 truncate text-center", dims.typography),
29423
29674
  style: {
29424
29675
  minWidth: dims.minWidth,
29425
- fontSize: dims.fontSize,
29426
- lineHeight: `${dims.lineHeight}px`,
29427
29676
  color: disabled ? "var(--cmp-timepicker-text-disabled)" : hasValue ? "var(--cmp-timepicker-text-default)" : "var(--cmp-field-hint-color)"
29428
29677
  },
29429
29678
  children: hasValue ? displayText : placeholder
@@ -29527,7 +29776,7 @@ function RangeTimeSelector({
29527
29776
  className: "flex flex-col items-center",
29528
29777
  style: { gap: "var(--cmp-timepicker-selector-range-heading-gap)" },
29529
29778
  children: [
29530
- /* @__PURE__ */ jsx("div", { className: "whitespace-nowrap text-center text-[12px] font-bold leading-[20px] text-[var(--cmp-timepicker-selector-range-heading-color)]", children: title }),
29779
+ /* @__PURE__ */ jsx("div", { className: "whitespace-nowrap text-center typo-field-sm-bold text-[var(--cmp-timepicker-selector-range-heading-color)]", children: title }),
29531
29780
  /* @__PURE__ */ jsx(
29532
29781
  TimeListbox,
29533
29782
  {
@@ -29694,11 +29943,9 @@ function STimeRangePicker({
29694
29943
  "span",
29695
29944
  {
29696
29945
  id: triggerTextId,
29697
- className: "flex-1 truncate text-center",
29946
+ className: cn("flex-1 truncate text-center", dims.typography),
29698
29947
  style: {
29699
29948
  minWidth: dims.minWidth,
29700
- fontSize: dims.fontSize,
29701
- lineHeight: `${dims.lineHeight}px`,
29702
29949
  color: disabled ? "var(--cmp-timepicker-text-disabled)" : hasValue ? "var(--cmp-timepicker-text-default)" : "var(--cmp-field-hint-color)"
29703
29950
  },
29704
29951
  children: hasValue ? displayText : placeholder