sellmate-design-system-react 9.0.0-beta.32 → 9.0.0-beta.34

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 (32) hide show
  1. package/AGENTS.md +21 -6
  2. package/dist/components/SBadge/README.md +2 -0
  3. package/dist/components/SButton/README.md +2 -0
  4. package/dist/components/SCalendarBoard/CalendarDayCard.d.ts +38 -0
  5. package/dist/components/SCalendarBoard/CalendarDayEventListBox.d.ts +26 -0
  6. package/dist/components/SCalendarBoard/CalendarEventButton.d.ts +13 -0
  7. package/dist/components/SCalendarBoard/CalendarMoreButton.d.ts +12 -0
  8. package/dist/components/SCalendarBoard/README.md +137 -0
  9. package/dist/components/SCalendarBoard/SCalendarBoard.d.ts +68 -0
  10. package/dist/components/SCalendarBoard/calendarBoard.config.d.ts +33 -0
  11. package/dist/components/SCalendarBoard/index.d.ts +3 -0
  12. package/dist/components/SCalendarBoard/types.d.ts +31 -0
  13. package/dist/components/SDivider/README.md +2 -0
  14. package/dist/components/SGhostButton/README.md +2 -0
  15. package/dist/components/SGnb/SGnb.d.ts +6 -0
  16. package/dist/components/SGnb/gnb.config.d.ts +3 -3
  17. package/dist/components/SGnbSystem/README.md +43 -1
  18. package/dist/components/SGnbSystem/SGnbSystem.d.ts +48 -2
  19. package/dist/components/SPortal/README.md +2 -0
  20. package/dist/components/SScrollArea/README.md +13 -0
  21. package/dist/components/SSystemActionButton/systemActionButton.config.d.ts +8 -2
  22. package/dist/components/STooltip/README.md +2 -0
  23. package/dist/index.cjs +823 -129
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.ts +1 -0
  26. package/dist/index.js +817 -129
  27. package/dist/index.js.map +1 -1
  28. package/dist/llms-full.txt +206 -7
  29. package/dist/llms.txt +23 -8
  30. package/dist/styles.css +290 -9
  31. package/dist/theme.css +74 -8
  32. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -7,7 +7,7 @@ var react = require('react');
7
7
  var jsxRuntime = require('react/jsx-runtime');
8
8
  var reactDom = require('react-dom');
9
9
  var RCheckbox = require('@radix-ui/react-checkbox');
10
- var RPopover11 = require('@radix-ui/react-popover');
10
+ var RPopover12 = require('@radix-ui/react-popover');
11
11
  var client = require('react-dom/client');
12
12
  var RTooltip = require('@radix-ui/react-tooltip');
13
13
  var RDropdown2 = require('@radix-ui/react-dropdown-menu');
@@ -34,7 +34,7 @@ function _interopNamespace(e) {
34
34
  }
35
35
 
36
36
  var RCheckbox__namespace = /*#__PURE__*/_interopNamespace(RCheckbox);
37
- var RPopover11__namespace = /*#__PURE__*/_interopNamespace(RPopover11);
37
+ var RPopover12__namespace = /*#__PURE__*/_interopNamespace(RPopover12);
38
38
  var RTooltip__namespace = /*#__PURE__*/_interopNamespace(RTooltip);
39
39
  var RDropdown2__namespace = /*#__PURE__*/_interopNamespace(RDropdown2);
40
40
  var RSwitch__namespace = /*#__PURE__*/_interopNamespace(RSwitch);
@@ -5192,8 +5192,8 @@ function SGhostButton({
5192
5192
  }
5193
5193
  );
5194
5194
  if (!hasTooltip) return btn2;
5195
- return /* @__PURE__ */ jsxRuntime.jsxs(RPopover11__namespace.Root, { open, onOpenChange: setOpen, children: [
5196
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Anchor, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
5195
+ return /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open, onOpenChange: setOpen, children: [
5196
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Anchor, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
5197
5197
  "span",
5198
5198
  {
5199
5199
  className: cn("inline-flex", anchorClassName),
@@ -5205,8 +5205,8 @@ function SGhostButton({
5205
5205
  children: btn2
5206
5206
  }
5207
5207
  ) }),
5208
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
5209
- RPopover11__namespace.Content,
5208
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
5209
+ RPopover12__namespace.Content,
5210
5210
  {
5211
5211
  side: "top",
5212
5212
  sideOffset: 4,
@@ -5782,14 +5782,14 @@ var STooltipImpl = /* @__PURE__ */ react.forwardRef(function STooltip({
5782
5782
  ...style,
5783
5783
  ...contentPropsStyle
5784
5784
  };
5785
- return /* @__PURE__ */ jsxRuntime.jsxs(RPopover11__namespace.Root, { open, onOpenChange: setOpenState, children: [
5785
+ return /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open, onOpenChange: setOpenState, children: [
5786
5786
  isNone ? (
5787
5787
  // 트리거 없음: children 을 래퍼 없이 그대로 앵커로 쓴다 (소비자 레이아웃 보존).
5788
5788
  // mouse/focus 핸들러가 없으므로 useClose 없이도 자동 닫힘이 발생하지 않는다.
5789
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Anchor, { asChild: true, children: triggerNode })
5789
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Anchor, { asChild: true, children: triggerNode })
5790
5790
  ) : isHover ? (
5791
5791
  // hover: Anchor(위치 기준) + 직접 mouse 핸들러 — 클릭으로 토글되지 않도록 Trigger 미사용
5792
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Anchor, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
5792
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Anchor, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
5793
5793
  "span",
5794
5794
  {
5795
5795
  className: "inline-flex",
@@ -5800,9 +5800,9 @@ var STooltipImpl = /* @__PURE__ */ react.forwardRef(function STooltip({
5800
5800
  children: triggerNode
5801
5801
  }
5802
5802
  ) })
5803
- ) : /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Trigger, { asChild: true, children: triggerNode }),
5804
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(
5805
- RPopover11__namespace.Content,
5803
+ ) : /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Trigger, { asChild: true, children: triggerNode }),
5804
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(
5805
+ RPopover12__namespace.Content,
5806
5806
  {
5807
5807
  side: placement,
5808
5808
  sideOffset,
@@ -5836,7 +5836,7 @@ var STooltipImpl = /* @__PURE__ */ react.forwardRef(function STooltip({
5836
5836
  }
5837
5837
  )
5838
5838
  ] }),
5839
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Arrow, { width: 16, height: 12, style: { fill: bg } })
5839
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Arrow, { width: 16, height: 12, style: { fill: bg } })
5840
5840
  ]
5841
5841
  }
5842
5842
  ) })
@@ -6914,7 +6914,7 @@ function SPortal({
6914
6914
  const portalContainer = usePortalContainer();
6915
6915
  const { minWidth: styleMinWidth, maxWidth: styleMaxWidth, ...restStyle } = style ?? {};
6916
6916
  return /* @__PURE__ */ jsxRuntime.jsxs(
6917
- RPopover11__namespace.Root,
6917
+ RPopover12__namespace.Root,
6918
6918
  {
6919
6919
  open,
6920
6920
  onOpenChange: (next) => {
@@ -6922,9 +6922,9 @@ function SPortal({
6922
6922
  if (!next) onClose?.();
6923
6923
  },
6924
6924
  children: [
6925
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Anchor, { virtualRef: anchorRef }),
6926
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
6927
- RPopover11__namespace.Content,
6925
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Anchor, { virtualRef: anchorRef }),
6926
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
6927
+ RPopover12__namespace.Content,
6928
6928
  {
6929
6929
  side: placement,
6930
6930
  align,
@@ -7368,12 +7368,15 @@ var SYSTEM_ACTION_BUTTON_COLOR_CONFIG = {
7368
7368
  dark: {
7369
7369
  bg: item2("dark-bg-default"),
7370
7370
  bgHover: item2("dark-bg-hover"),
7371
+ // 프레임은 hover 에서도 행의 기본 표면색을 지킨다 — 표면만 한 단계 밝아지고 프레임은
7372
+ // 제자리에 남아, 밝아진 면에 뚫린 구멍처럼 읽힌다. `dark-icon-bg-hover`(흰색) 토큰은
7373
+ // 이 시안과 어긋나 쓰지 않는다.
7371
7374
  iconBg: item2("dark-icon-bg-default"),
7372
- iconBgHover: item2("dark-icon-bg-hover"),
7373
- // 어두운 면에는 글리프색 토큰이 없다. 기본은 프레임이 배경과 블렌딩되므로 라벨색(흰색),
7374
- // hover 는 프레임이 흰색이 되므로 그 위에 표면색을 그대로 얹는다.
7375
+ iconBgHover: item2("dark-icon-bg-default"),
7376
+ // 어두운 면에는 글리프색 토큰이 없다. 프레임이 배경과 블렌딩되므로 라벨색(흰색)을 쓰고,
7377
+ // 프레임이 hover 에서 그대로이므로 글리프도 그대로 둔다.
7375
7378
  iconGlyph: item2("dark-text"),
7376
- iconGlyphHover: item2("dark-bg-hover"),
7379
+ iconGlyphHover: item2("dark-text"),
7377
7380
  text: item2("dark-text"),
7378
7381
  actionText: {
7379
7382
  switch: action("switch-text-dark"),
@@ -7385,10 +7388,11 @@ var SYSTEM_ACTION_BUTTON_COLOR_CONFIG = {
7385
7388
  darker: {
7386
7389
  bg: item2("darker-bg-default"),
7387
7390
  bgHover: item2("darker-bg-hover"),
7391
+ // dark 와 같은 규칙 — 프레임은 hover 에서도 행의 기본 표면색을 지킨다.
7388
7392
  iconBg: item2("darker-icon-bg-default"),
7389
- iconBgHover: item2("darker-icon-bg-hover"),
7393
+ iconBgHover: item2("darker-icon-bg-default"),
7390
7394
  iconGlyph: item2("darker-text"),
7391
- iconGlyphHover: item2("darker-bg-hover"),
7395
+ iconGlyphHover: item2("darker-text"),
7392
7396
  text: item2("darker-text"),
7393
7397
  actionText: {
7394
7398
  switch: action("switch-text-dark"),
@@ -7433,7 +7437,13 @@ var SYSTEM_ACTION_BUTTON_LAYOUT = {
7433
7437
  /** 우측 여백 */
7434
7438
  paddingRight: action("paddingRight"),
7435
7439
  /** 액션 텍스트 ↔ 액션 아이콘 간격 */
7436
- actionGap: action("selectData-gap")
7440
+ actionGap: action("selectData-gap"),
7441
+ /**
7442
+ * 액션 아이콘 글리프 한 변. 프레임 한 변은 타입별 토큰(`actionButton.*-icon`)이 정하고
7443
+ * 그 안에 글리프가 이 크기로 놓인다 — 선행 아이콘의 프레임(24)/글리프(20) 과 같은 구조다.
7444
+ * 대응 토큰이 없어 디자인 값을 그대로 쓴다.
7445
+ */
7446
+ actionIconGlyph: "12px"
7437
7447
  };
7438
7448
  function TokenIcon2({ name, size }) {
7439
7449
  return /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name, size: "100%", style: { width: size, height: size } });
@@ -7536,7 +7546,15 @@ var SSystemActionButton = /* @__PURE__ */ react.forwardRef(
7536
7546
  children: actionText
7537
7547
  }
7538
7548
  ),
7539
- spec.actionIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex shrink-0 items-center text-(--sab-action-icon)", children: /* @__PURE__ */ jsxRuntime.jsx(TokenIcon2, { name: spec.actionIcon.name, size: spec.actionIcon.size }) })
7549
+ spec.actionIcon && // 토큰이 정하는 크기는 글리프가 아니라 프레임이다 — 그 안에 글리프를 가운데로 놓는다.
7550
+ /* @__PURE__ */ jsxRuntime.jsx(
7551
+ "span",
7552
+ {
7553
+ className: "inline-flex shrink-0 items-center justify-center text-(--sab-action-icon)",
7554
+ style: { width: spec.actionIcon.size, height: spec.actionIcon.size },
7555
+ children: /* @__PURE__ */ jsxRuntime.jsx(TokenIcon2, { name: spec.actionIcon.name, size: SYSTEM_ACTION_BUTTON_LAYOUT.actionIconGlyph })
7556
+ }
7557
+ )
7540
7558
  ] })
7541
7559
  ]
7542
7560
  }
@@ -7657,10 +7675,10 @@ function SPopover({
7657
7675
  const descColor = type === "default" ? "var(--cmp-popover-default-description)" : "var(--cmp-popover-light-description)";
7658
7676
  const leftLinkLabelClass = type === "default" ? "text-[color:var(--cmp-popover-default-subAction)]" : "text-[color:var(--cmp-popover-light-subAction)]";
7659
7677
  const triggerNode = trigger ?? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex cursor-pointer", "aria-label": ariaLabel, children: /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: icon, size: iconSize, color }) });
7660
- return /* @__PURE__ */ jsxRuntime.jsxs(RPopover11__namespace.Root, { open: actualOpen, onOpenChange: setOpen, children: [
7661
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Trigger, { asChild: true, children: triggerNode }),
7662
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(
7663
- RPopover11__namespace.Content,
7678
+ return /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open: actualOpen, onOpenChange: setOpen, children: [
7679
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Trigger, { asChild: true, children: triggerNode }),
7680
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(
7681
+ RPopover12__namespace.Content,
7664
7682
  {
7665
7683
  side: placement,
7666
7684
  sideOffset: 8,
@@ -7726,7 +7744,7 @@ function SPopover({
7726
7744
  ]
7727
7745
  }
7728
7746
  ),
7729
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Arrow, { width: 16, height: 12, style: { fill: bg } })
7747
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Arrow, { width: 16, height: 12, style: { fill: bg } })
7730
7748
  ]
7731
7749
  }
7732
7750
  ) })
@@ -7837,10 +7855,10 @@ function SGuide({
7837
7855
  );
7838
7856
  if (isNotion)
7839
7857
  return /* @__PURE__ */ jsxRuntime.jsx("span", { className, style, children: trigger });
7840
- return /* @__PURE__ */ jsxRuntime.jsxs(RPopover11__namespace.Root, { open, onOpenChange: setOpen, children: [
7841
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Trigger, { asChild: true, children: trigger }),
7842
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(
7843
- RPopover11__namespace.Content,
7858
+ return /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open, onOpenChange: setOpen, children: [
7859
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Trigger, { asChild: true, children: trigger }),
7860
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(
7861
+ RPopover12__namespace.Content,
7844
7862
  {
7845
7863
  side: "bottom",
7846
7864
  align: "start",
@@ -9270,9 +9288,9 @@ var GNB_RAIL = {
9270
9288
  var GNB_RAIL_WIDTH = 68;
9271
9289
  var GNB_FOLD_MS = 200;
9272
9290
  var GNB_EXPAND_MS = 200;
9273
- var GNB_MENU_WIDTH = 240;
9291
+ var GNB_MENU_WIDTH = 214;
9274
9292
  var GNB_MENU_MIN_WIDTH = 200;
9275
- var GNB_MENU_MAX_WIDTH = 300;
9293
+ var GNB_MENU_MAX_WIDTH = 240;
9276
9294
  var GNB_MENU_RESIZE_KEY_STEP = { normal: 10, large: 50 };
9277
9295
  var clampGnbMenuWidth = (width) => Math.min(GNB_MENU_MAX_WIDTH, Math.max(GNB_MENU_MIN_WIDTH, Math.round(width)));
9278
9296
  var GNB_FULL_LOGO_WIDTH = 140;
@@ -9830,8 +9848,15 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
9830
9848
  "topContent"
9831
9849
  ) : null;
9832
9850
  const systemMenuContext = react.useMemo(
9833
- () => ({ color, folded: false, placement: "panel", active: !railFolded }),
9834
- [color, railFolded]
9851
+ // 기본 폭보다 줄여 놓은 메뉴 컬럼이면 판에 알린다 — 알림 개수가 점 배지로 줄어든다.
9852
+ () => ({
9853
+ color,
9854
+ folded: false,
9855
+ placement: "panel",
9856
+ active: !railFolded,
9857
+ narrow: menuWidth < GNB_MENU_WIDTH
9858
+ }),
9859
+ [color, railFolded, menuWidth]
9835
9860
  );
9836
9861
  const systemFoldedContext = react.useMemo(
9837
9862
  () => ({ color, folded: true, placement: "panel", active: true }),
@@ -9984,10 +10009,10 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
9984
10009
  }
9985
10010
  ),
9986
10011
  header === "fix" && menuResizeHandle,
9987
- /* @__PURE__ */ jsxRuntime.jsxs(RPopover11__namespace.Root, { open: labelTip !== null, onOpenChange: (open) => !open && setLabelTip(null), children: [
9988
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Anchor, { virtualRef: labelTipAnchorRef }),
9989
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
9990
- RPopover11__namespace.Content,
10012
+ /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open: labelTip !== null, onOpenChange: (open) => !open && setLabelTip(null), children: [
10013
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Anchor, { virtualRef: labelTipAnchorRef }),
10014
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
10015
+ RPopover12__namespace.Content,
9991
10016
  {
9992
10017
  side: "right",
9993
10018
  sideOffset: 4,
@@ -10098,7 +10123,7 @@ var GNB_SYSTEM_SETTING_LABEL = "\uC124\uC815";
10098
10123
  function TokenIcon3({ name, size }) {
10099
10124
  return /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name, size: "100%", style: { width: size, height: size } });
10100
10125
  }
10101
- function SystemButton({
10126
+ var SystemButton = /* @__PURE__ */ react.forwardRef(function SystemButton2({
10102
10127
  color,
10103
10128
  icon,
10104
10129
  label,
@@ -10110,21 +10135,22 @@ function SystemButton({
10110
10135
  dot,
10111
10136
  accentColor,
10112
10137
  stretch,
10113
- buttonRef,
10114
10138
  hasPopup,
10115
10139
  expanded,
10116
- onClick
10117
- }) {
10140
+ onClick,
10141
+ onMouseLeave
10142
+ }, ref) {
10118
10143
  const c = SYSTEM_ACTION_BUTTON_COLOR_CONFIG[color];
10119
10144
  return /* @__PURE__ */ jsxRuntime.jsxs(
10120
10145
  "button",
10121
10146
  {
10122
- ref: buttonRef,
10147
+ ref,
10123
10148
  type: "button",
10124
10149
  "aria-label": label ? void 0 : ariaLabel,
10125
10150
  "aria-haspopup": hasPopup ? "dialog" : void 0,
10126
10151
  "aria-expanded": hasPopup ? expanded : void 0,
10127
10152
  onClick,
10153
+ onMouseLeave,
10128
10154
  className: cn(
10129
10155
  "group box-border flex cursor-pointer items-center border-none bg-(--gsb-bg) text-(--gsb-text) transition-colors hover:bg-(--gsb-bg-hover)",
10130
10156
  stretch ? "min-w-0 flex-1" : "shrink-0",
@@ -10170,12 +10196,14 @@ function SystemButton({
10170
10196
  ]
10171
10197
  }
10172
10198
  ),
10173
- label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typo-body-sm-semibold min-w-0 flex-1 truncate", children: label }),
10174
- count != null && count > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typo-body-md-bold shrink-0", style: { color: accentColor }, children: count.toLocaleString() })
10199
+ label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typo-body-sm-semibold min-w-0 truncate", children: label }),
10200
+ count != null && count > 0 && // 개수 오른쪽은 버튼 여백(alertButton.paddingX)만으로는 좁다 — 시안이 4px 을 더 준다.
10201
+ // 대응 토큰이 없어 디자인 값을 그대로 쓴다.
10202
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typo-body-md-bold me-[4px] shrink-0", style: { color: accentColor }, children: count.toLocaleString() })
10175
10203
  ]
10176
10204
  }
10177
10205
  );
10178
- }
10206
+ });
10179
10207
  var SGnbSystem = /* @__PURE__ */ react.forwardRef(function SGnbSystem2({
10180
10208
  color: colorProp,
10181
10209
  folded: foldedProp,
@@ -10194,6 +10222,7 @@ var SGnbSystem = /* @__PURE__ */ react.forwardRef(function SGnbSystem2({
10194
10222
  const isTop = placement === "top";
10195
10223
  const folded = !isTop && (foldedProp ?? gnb2?.folded ?? false);
10196
10224
  const active = gnb2?.active ?? true;
10225
+ const narrow = !isTop && !folded && (gnb2?.narrow ?? false);
10197
10226
  const c = GNB_SYSTEM_COLOR_CONFIG[color];
10198
10227
  const t = GNB_SYSTEM_TOP_COLOR_CONFIG[color];
10199
10228
  const itemColor = isTop ? t.item : color;
@@ -10212,13 +10241,39 @@ var SGnbSystem = /* @__PURE__ */ react.forwardRef(function SGnbSystem2({
10212
10241
  setAccountOpen(next);
10213
10242
  account?.onOpenChange?.(next);
10214
10243
  };
10244
+ const alertButtonRef = react.useRef(null);
10245
+ const [alertListOpen, setAlertListOpen] = react.useState(false);
10246
+ const hasAlertList = alert2?.listBox != null;
10247
+ const commitAlertListOpen = (next) => {
10248
+ setAlertListOpen(next);
10249
+ alert2?.onOpenChange?.(next);
10250
+ };
10215
10251
  react.useEffect(() => {
10216
10252
  if (active || !accountOpen) return;
10217
10253
  setAccountOpen(false);
10218
10254
  account?.onOpenChange?.(false);
10219
10255
  }, [active, accountOpen, account]);
10256
+ react.useEffect(() => {
10257
+ if (active || !alertListOpen) return;
10258
+ setAlertListOpen(false);
10259
+ alert2?.onOpenChange?.(false);
10260
+ }, [active, alertListOpen, alert2]);
10220
10261
  const alertCount = alert2?.count ?? 0;
10221
10262
  const notified = alertCount > 0;
10263
+ const alertTooltip = (alert2?.tooltip ?? []).filter((line) => line.trim() !== "");
10264
+ const hasAlertTooltip = alertTooltip.length > 0;
10265
+ const [alertTooltipDismissed, setAlertTooltipDismissed] = react.useState(false);
10266
+ const hadAlertTooltip = react.useRef(hasAlertTooltip);
10267
+ if (hadAlertTooltip.current !== hasAlertTooltip) {
10268
+ hadAlertTooltip.current = hasAlertTooltip;
10269
+ if (hasAlertTooltip && alertTooltipDismissed) setAlertTooltipDismissed(false);
10270
+ }
10271
+ const alertTooltipOpen = hasAlertTooltip && active && !alertTooltipDismissed;
10272
+ const dismissAlertTooltip = () => {
10273
+ if (!alertTooltipOpen) return;
10274
+ setAlertTooltipDismissed(true);
10275
+ alert2?.onTooltipDismiss?.();
10276
+ };
10222
10277
  const alertLabel = alert2?.label ?? GNB_SYSTEM_ALERT_LABEL;
10223
10278
  const settingLabel = setting?.label ?? GNB_SYSTEM_SETTING_LABEL;
10224
10279
  const alertButton = alert2 && /* @__PURE__ */ jsxRuntime.jsx(
@@ -10231,13 +10286,51 @@ var SGnbSystem = /* @__PURE__ */ react.forwardRef(function SGnbSystem2({
10231
10286
  paddingX: GNB_SYSTEM_LAYOUT.alertPaddingX,
10232
10287
  iconColor: notified ? alertIconColor : void 0,
10233
10288
  hoverBg: notified ? alertHoverBg : void 0,
10234
- count: folded ? void 0 : alertCount,
10235
- dot: folded && notified,
10289
+ count: folded || narrow ? void 0 : alertCount,
10290
+ dot: (folded || narrow) && notified,
10236
10291
  accentColor: alertCountColor,
10237
10292
  stretch: !folded && !isTop,
10238
- onClick: alert2.onClick
10293
+ ref: alertButtonRef,
10294
+ hasPopup: hasAlertList,
10295
+ expanded: alertListOpen,
10296
+ onClick: () => {
10297
+ dismissAlertTooltip();
10298
+ alert2.onClick?.();
10299
+ if (hasAlertList) commitAlertListOpen(!alertListOpen);
10300
+ },
10301
+ onMouseLeave: hasAlertTooltip ? dismissAlertTooltip : void 0
10239
10302
  }
10240
10303
  );
10304
+ const alertListBox = alert2 && hasAlertList && /* @__PURE__ */ jsxRuntime.jsx(
10305
+ SPortal,
10306
+ {
10307
+ open: alertListOpen && active,
10308
+ onClose: () => commitAlertListOpen(false),
10309
+ anchorRef: alertButtonRef,
10310
+ placement: isTop ? "bottom" : "right",
10311
+ align: "end",
10312
+ offset: 8,
10313
+ viewportPadding: 8,
10314
+ ariaLabel: alert2.label ?? GNB_SYSTEM_ALERT_LABEL,
10315
+ onOpenAutoFocus: (event) => event.preventDefault(),
10316
+ className: "rounded-(--radius-8)",
10317
+ children: alert2.listBox
10318
+ }
10319
+ );
10320
+ const alertNode = alertButton && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10321
+ hasAlertTooltip ? /* @__PURE__ */ jsxRuntime.jsx(
10322
+ STooltip2,
10323
+ {
10324
+ trigger: "none",
10325
+ open: alertTooltipOpen,
10326
+ message: alertTooltip,
10327
+ tooltipType: color === "light" ? "default" : "accent",
10328
+ placement: isTop ? "bottom" : "right",
10329
+ children: alertButton
10330
+ }
10331
+ ) : alertButton,
10332
+ alertListBox
10333
+ ] });
10241
10334
  const settingButton = setting && /* @__PURE__ */ jsxRuntime.jsx(
10242
10335
  SystemButton,
10243
10336
  {
@@ -10293,7 +10386,7 @@ var SGnbSystem = /* @__PURE__ */ react.forwardRef(function SGnbSystem2({
10293
10386
  )
10294
10387
  })
10295
10388
  );
10296
- if (alertButton) segments.push({ key: "alert", node: alertButton });
10389
+ if (alertNode) segments.push({ key: "alert", node: alertNode });
10297
10390
  if (settingButton) segments.push({ key: "setting", node: settingButton });
10298
10391
  if (domainTag || accountButton) {
10299
10392
  segments.push({
@@ -10351,7 +10444,7 @@ var SGnbSystem = /* @__PURE__ */ react.forwardRef(function SGnbSystem2({
10351
10444
  "data-folded": "",
10352
10445
  ...rest,
10353
10446
  children: [
10354
- alertButton,
10447
+ alertNode,
10355
10448
  account && /* @__PURE__ */ jsxRuntime.jsx(
10356
10449
  SystemButton,
10357
10450
  {
@@ -10359,7 +10452,7 @@ var SGnbSystem = /* @__PURE__ */ react.forwardRef(function SGnbSystem2({
10359
10452
  icon: "user",
10360
10453
  ariaLabel: account.label ?? "account",
10361
10454
  paddingX: GNB_SYSTEM_LAYOUT.alertPaddingX,
10362
- buttonRef: foldedAccountRef,
10455
+ ref: foldedAccountRef,
10363
10456
  hasPopup: true,
10364
10457
  expanded: accountOpen,
10365
10458
  onClick: () => {
@@ -10405,7 +10498,7 @@ var SGnbSystem = /* @__PURE__ */ react.forwardRef(function SGnbSystem2({
10405
10498
  domainTag,
10406
10499
  hasUserBlock && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10407
10500
  (alert2 || setting) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", style: { gap: GNB_SYSTEM_LAYOUT.gap }, children: [
10408
- alertButton,
10501
+ alertNode,
10409
10502
  alert2 && setting && /* @__PURE__ */ jsxRuntime.jsx(
10410
10503
  "span",
10411
10504
  {
@@ -11477,6 +11570,636 @@ var SStepper = /* @__PURE__ */ react.forwardRef(function SStepper2({
11477
11570
  );
11478
11571
  });
11479
11572
 
11573
+ // src/lib/date.ts
11574
+ function todayStr() {
11575
+ const d = /* @__PURE__ */ new Date();
11576
+ return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
11577
+ }
11578
+ function formatDate(year, month, day) {
11579
+ return `${year}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
11580
+ }
11581
+ function calcYearMonth(year, month, dir) {
11582
+ if (dir === "prev")
11583
+ return month === 1 ? { year: year - 1, month: 12 } : { year, month: month - 1 };
11584
+ return month === 12 ? { year: year + 1, month: 1 } : { year, month: month + 1 };
11585
+ }
11586
+ function monthCells(year, month) {
11587
+ const firstDayIndex = new Date(year, month - 1, 1).getDay();
11588
+ const daysInCurrent = new Date(year, month, 0).getDate();
11589
+ const prev = calcYearMonth(year, month, "prev");
11590
+ const daysInPrev = new Date(prev.year, prev.month, 0).getDate();
11591
+ const next = calcYearMonth(year, month, "next");
11592
+ const cells = [];
11593
+ for (let i = firstDayIndex - 1; i >= 0; i--) {
11594
+ const day = daysInPrev - i;
11595
+ cells.push({ date: formatDate(prev.year, prev.month, day), day, inCurrentMonth: false });
11596
+ }
11597
+ for (let day = 1; day <= daysInCurrent; day++) {
11598
+ cells.push({ date: formatDate(year, month, day), day, inCurrentMonth: true });
11599
+ }
11600
+ const remaining = (7 - cells.length % 7) % 7;
11601
+ for (let day = 1; day <= remaining; day++) {
11602
+ cells.push({ date: formatDate(next.year, next.month, day), day, inCurrentMonth: false });
11603
+ }
11604
+ return cells;
11605
+ }
11606
+ var WEEK_LABELS = ["\uC77C", "\uC6D4", "\uD654", "\uC218", "\uBAA9", "\uAE08", "\uD1A0"];
11607
+
11608
+ // src/components/SCalendarBoard/calendarBoard.config.ts
11609
+ var CALENDAR_BOARD_EVENT_COLORS = [
11610
+ "default",
11611
+ "blue",
11612
+ "oceanBlue",
11613
+ "lightBlue",
11614
+ "green",
11615
+ "yellow",
11616
+ "orange",
11617
+ "red",
11618
+ "white"
11619
+ ];
11620
+ var BG = (name) => `var(--cmp-calendarBoard-eventButton-bg-${name})`;
11621
+ var CALENDAR_BOARD_EVENT_PRESETS = {
11622
+ default: { bg: BG("default"), dot: "indigo" },
11623
+ blue: { bg: BG("blue"), dot: "blue" },
11624
+ oceanBlue: { bg: BG("oceanBlue"), dot: "darkblue" },
11625
+ lightBlue: { bg: BG("lightBlue"), dot: "lightblue" },
11626
+ green: { bg: BG("green"), dot: "green" },
11627
+ yellow: { bg: BG("yellow"), dot: "yellow" },
11628
+ orange: { bg: BG("orange"), dot: "orange" },
11629
+ red: { bg: BG("red"), dot: "red" },
11630
+ white: { bg: BG("white"), dot: "grey" }
11631
+ };
11632
+ var CALENDAR_BOARD_MAX_VISIBLE_EVENTS = 4;
11633
+ var CALENDAR_BOARD_DAY_COLORS = [
11634
+ "default",
11635
+ "danger",
11636
+ "accent",
11637
+ "complete",
11638
+ "dim"
11639
+ ];
11640
+ var CALENDAR_BOARD_DAY_BG = {
11641
+ default: "var(--cmp-calendarBoard-dayCard-bg)",
11642
+ danger: "var(--color-red-30)",
11643
+ accent: "var(--color-brilliantblue-40)",
11644
+ complete: "var(--color-green-45)",
11645
+ dim: "var(--color-grey-25)"
11646
+ };
11647
+ function CalendarEventButton({
11648
+ event,
11649
+ onSelect,
11650
+ className
11651
+ }) {
11652
+ const preset = CALENDAR_BOARD_EVENT_PRESETS[event.color ?? "default"];
11653
+ const dot = event.dotColor ?? preset.dot;
11654
+ const disabled = event.disabled === true;
11655
+ const hasDescription = event.description != null && event.description !== "";
11656
+ const hasValue = event.value != null && event.value !== "";
11657
+ const title = [event.label.replace(/<[^>]*>/g, ""), event.description, event.value].filter((v) => v != null && v !== "").join(" ") || void 0;
11658
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11659
+ "button",
11660
+ {
11661
+ type: "button",
11662
+ disabled,
11663
+ title,
11664
+ className: cn(
11665
+ // hover 는 배경 위에 8% 오버레이를 얹는다 — 프리셋 배경이 9종이라 색마다 hover 색을 두지 않는다.
11666
+ "group relative flex w-full min-w-0 items-center overflow-hidden text-left",
11667
+ "h-(--cmp-calendarBoard-item-height) shrink-0 rounded-(--cmp-calendarBoard-item-radius)",
11668
+ "gap-(--cmp-calendarBoard-eventButton-inline-gap) px-(--cmp-calendarBoard-item-paddingX)",
11669
+ "bg-(--ceb-bg) text-(--cmp-calendarBoard-eventButton-text-color-default)",
11670
+ disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer",
11671
+ className
11672
+ ),
11673
+ style: { "--ceb-bg": preset.bg },
11674
+ onClick: (e) => {
11675
+ if (disabled) return;
11676
+ onSelect?.(event, e);
11677
+ },
11678
+ children: [
11679
+ !disabled && /* @__PURE__ */ jsxRuntime.jsx(
11680
+ "span",
11681
+ {
11682
+ "aria-hidden": true,
11683
+ className: "pointer-events-none absolute inset-0 rounded-(--cmp-calendarBoard-item-radius) bg-(--cmp-calendarBoard-eventButton-hover-overlay-color) opacity-0 transition-opacity group-hover:opacity-(--cmp-calendarBoard-eventButton-hover-overlay-opacity)"
11684
+ }
11685
+ ),
11686
+ /* @__PURE__ */ jsxRuntime.jsx(SBadge, { "aria-hidden": true, color: dot, className: "shrink-0" }),
11687
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-1 items-center gap-(--cmp-calendarBoard-eventButton-label-gap)", children: [
11688
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "typo-body-sm-default min-w-0 flex-1 truncate", children: [
11689
+ /* @__PURE__ */ jsxRuntime.jsx(
11690
+ "span",
11691
+ {
11692
+ className: cn(
11693
+ "typo-body-sm-semibold",
11694
+ hasDescription && "me-(--cmp-calendarBoard-eventButton-label-gap)"
11695
+ ),
11696
+ dangerouslySetInnerHTML: { __html: sanitizeInlineHtml(event.label) }
11697
+ }
11698
+ ),
11699
+ hasDescription && event.description
11700
+ ] }),
11701
+ hasValue && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex shrink-0 items-center gap-(--cmp-calendarBoard-eventButton-label-gap)", children: [
11702
+ /* @__PURE__ */ jsxRuntime.jsx(
11703
+ "span",
11704
+ {
11705
+ "aria-hidden": true,
11706
+ className: "typo-body-sm-default text-(--cmp-calendarBoard-eventButton-text-color-separator)",
11707
+ children: "/"
11708
+ }
11709
+ ),
11710
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typo-body-sm-default whitespace-nowrap", children: event.value })
11711
+ ] })
11712
+ ] })
11713
+ ]
11714
+ }
11715
+ );
11716
+ }
11717
+ var CalendarMoreButton = /* @__PURE__ */ react.forwardRef(function CalendarMoreButton2({ count, label = "\uB354\uBCF4\uAE30", onClick, className }, ref) {
11718
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11719
+ "button",
11720
+ {
11721
+ ref,
11722
+ type: "button",
11723
+ className: cn(
11724
+ "group relative flex w-full min-w-0 cursor-pointer items-center overflow-hidden text-left",
11725
+ "h-(--cmp-calendarBoard-item-height) shrink-0 rounded-(--cmp-calendarBoard-item-radius)",
11726
+ "gap-(--cmp-calendarBoard-moreButton-gap) px-(--cmp-calendarBoard-item-paddingX)",
11727
+ "bg-(--cmp-calendarBoard-moreButton-bg)",
11728
+ className
11729
+ ),
11730
+ onClick,
11731
+ children: [
11732
+ /* @__PURE__ */ jsxRuntime.jsx(
11733
+ "span",
11734
+ {
11735
+ "aria-hidden": true,
11736
+ className: "pointer-events-none absolute inset-0 rounded-(--cmp-calendarBoard-item-radius) bg-(--cmp-calendarBoard-moreButton-hover-overlay-color) opacity-0 transition-opacity group-hover:opacity-(--cmp-calendarBoard-moreButton-hover-overlay-opacity)"
11737
+ }
11738
+ ),
11739
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "typo-body-sm-semibold shrink-0 text-(--cmp-calendarBoard-moreButton-count-color)", children: [
11740
+ count,
11741
+ "\uAC1C"
11742
+ ] }),
11743
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typo-body-sm-default min-w-0 truncate text-(--cmp-calendarBoard-moreButton-label-color)", children: label })
11744
+ ]
11745
+ }
11746
+ );
11747
+ });
11748
+ var CalendarDayCard = /* @__PURE__ */ react.forwardRef(function CalendarDayCard2({
11749
+ date,
11750
+ day,
11751
+ inCurrentMonth,
11752
+ isToday,
11753
+ isSelected,
11754
+ selectable,
11755
+ color,
11756
+ events,
11757
+ body,
11758
+ hiddenCount,
11759
+ isOpen,
11760
+ moreLabel,
11761
+ onDaySelect,
11762
+ onEventClick,
11763
+ onOpenEvents,
11764
+ ...rest
11765
+ }, ref) {
11766
+ const hasEvents = events.length + hiddenCount > 0;
11767
+ const interactive = selectable || hasEvents;
11768
+ const activate = () => {
11769
+ if (hasEvents) onOpenEvents?.();
11770
+ if (selectable) onDaySelect?.(date);
11771
+ };
11772
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11773
+ "div",
11774
+ {
11775
+ ...rest,
11776
+ ref,
11777
+ role: "gridcell",
11778
+ "data-date": date,
11779
+ "aria-selected": selectable ? isSelected : void 0,
11780
+ "aria-current": isToday ? "date" : void 0,
11781
+ "aria-haspopup": hasEvents ? "dialog" : void 0,
11782
+ "aria-expanded": hasEvents ? isOpen : void 0,
11783
+ tabIndex: interactive ? 0 : void 0,
11784
+ onClick: interactive ? activate : void 0,
11785
+ onKeyDown: interactive ? (e) => {
11786
+ if (e.key === "Enter" || e.key === " ") {
11787
+ e.preventDefault();
11788
+ activate();
11789
+ }
11790
+ } : void 0,
11791
+ className: cn(
11792
+ "relative flex min-h-(--cmp-calendarBoard-dayCard-minHeight) min-w-(--cmp-calendarBoard-dayCard-minWidth) flex-col bg-(--cdc-bg) px-(--cmp-calendarBoard-dayCard-paddingX) outline-none",
11793
+ interactive && "cursor-pointer"
11794
+ ),
11795
+ style: { ...rest.style, "--cdc-bg": CALENDAR_BOARD_DAY_BG[color] },
11796
+ children: [
11797
+ isSelected && /* @__PURE__ */ jsxRuntime.jsx(
11798
+ "span",
11799
+ {
11800
+ "aria-hidden": true,
11801
+ className: "pointer-events-none absolute inset-[1px] rounded-(--cmp-calendarBoard-dayCard-focus-border-radius) border-(length:--cmp-calendarBoard-dayCard-focus-border-width) border-solid border-(--cmp-calendarBoard-dayCard-focus-border-color)"
11802
+ }
11803
+ ),
11804
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex shrink-0 pt-(--cmp-calendarBoard-dayCard-header-paddingTop) pb-(--cmp-calendarBoard-dayCard-header-paddingBottom)", children: /* @__PURE__ */ jsxRuntime.jsx(
11805
+ "span",
11806
+ {
11807
+ className: cn(
11808
+ "inline-flex size-(--cmp-calendarBoard-daySequence-size) items-center justify-center rounded-(--cmp-calendarBoard-daySequence-radius)",
11809
+ isToday ? "typo-body-md-bold bg-(--cmp-calendarBoard-daySequence-bg-today) text-(--cmp-calendarBoard-daySequence-text-today)" : cn(
11810
+ "typo-body-md-medium",
11811
+ inCurrentMonth ? "text-(--cmp-calendarBoard-daySequence-text-default)" : "text-(--cmp-calendarBoard-daySequence-text-otherMonth)"
11812
+ ),
11813
+ // 오늘이 아니면서 선택된 날은 테두리 원으로 표시한다 (오늘은 이미 채운 원이라 겹치지 않는다).
11814
+ // 굵기는 1px 로 고정한다 — 칸을 감싸는 focus 테두리(2px)와 달리 얇은 원이고, 대응 토큰이 없다.
11815
+ isSelected && !isToday && "border border-solid border-(--cmp-calendarBoard-daySequence-border-selected)"
11816
+ ),
11817
+ children: day
11818
+ }
11819
+ ) }),
11820
+ /* @__PURE__ */ jsxRuntime.jsxs(
11821
+ "div",
11822
+ {
11823
+ className: cn(
11824
+ "flex min-h-0 flex-col gap-(--cmp-calendarBoard-dayCard-grid-gap) pb-(--cmp-calendarBoard-dayCard-grid-paddingBottom)",
11825
+ // 슬롯은 남는 세로를 다 갖는다 — 안에서 h-full 로 칸을 채울 수 있어야 한다.
11826
+ body != null && "flex-1"
11827
+ ),
11828
+ children: [
11829
+ body,
11830
+ body == null && events.map((event, i) => /* @__PURE__ */ jsxRuntime.jsx(
11831
+ CalendarEventButton,
11832
+ {
11833
+ event,
11834
+ onSelect: (ev, e) => {
11835
+ e.stopPropagation();
11836
+ onEventClick?.(ev, e);
11837
+ }
11838
+ },
11839
+ event.id ?? `${event.date}-${i}`
11840
+ )),
11841
+ hiddenCount > 0 && /* @__PURE__ */ jsxRuntime.jsx(
11842
+ CalendarMoreButton,
11843
+ {
11844
+ count: hiddenCount,
11845
+ label: moreLabel,
11846
+ onClick: (e) => {
11847
+ e.stopPropagation();
11848
+ onOpenEvents?.();
11849
+ }
11850
+ }
11851
+ )
11852
+ ]
11853
+ }
11854
+ )
11855
+ ]
11856
+ }
11857
+ );
11858
+ });
11859
+ var MAX_HEIGHT = 480;
11860
+ var MAX_WIDTH = "calc(100vw - 16px)";
11861
+ function CalendarDayEventListBox({
11862
+ date,
11863
+ events,
11864
+ onEventClick,
11865
+ minWidth,
11866
+ minHeight,
11867
+ onClose,
11868
+ closeLabel = "\uB2EB\uAE30"
11869
+ }) {
11870
+ const [y, m, d] = date.split("-").map(Number);
11871
+ const weekday = WEEK_LABELS[new Date(y, m - 1, d).getDay()];
11872
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11873
+ "div",
11874
+ {
11875
+ className: "flex w-max flex-col overflow-hidden rounded-(--cmp-calendarBoard-radius) bg-(--cmp-calendarBoard-bg) shadow-(--shadow-overlay)",
11876
+ style: { minWidth, maxWidth: MAX_WIDTH, minHeight, maxHeight: MAX_HEIGHT },
11877
+ children: [
11878
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center gap-(--cmp-calendarBoard-dayEvent-header-gap) px-(--cmp-calendarBoard-dayEvent-header-paddingX) py-(--cmp-calendarBoard-dayEvent-header-paddingY)", children: [
11879
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "typo-heading-md text-(--cmp-calendarBoard-header-content-color)", children: [
11880
+ d,
11881
+ "\uC77C"
11882
+ ] }),
11883
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "typo-body-lg-default flex-1 text-(--cmp-calendarBoard-header-content-color)", children: [
11884
+ "(",
11885
+ weekday,
11886
+ ")"
11887
+ ] }),
11888
+ /* @__PURE__ */ jsxRuntime.jsx(
11889
+ SGhostButton,
11890
+ {
11891
+ icon: "close",
11892
+ size: "xs",
11893
+ ariaLabel: closeLabel,
11894
+ className: "shrink-0",
11895
+ onClick: onClose
11896
+ }
11897
+ )
11898
+ ] }),
11899
+ /* @__PURE__ */ jsxRuntime.jsx(SScrollArea, { axis: "vertical", className: "min-h-0 flex-1", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-(--cmp-calendarBoard-dayEvent-body-gap) px-(--cmp-calendarBoard-dayEvent-body-paddingX) pb-(--cmp-calendarBoard-dayEvent-body-paddingBottom)", children: events.map((event, i) => /* @__PURE__ */ jsxRuntime.jsx(
11900
+ CalendarEventButton,
11901
+ {
11902
+ event,
11903
+ onSelect: onEventClick
11904
+ },
11905
+ event.id ?? `${event.date}-${i}`
11906
+ )) }) })
11907
+ ]
11908
+ }
11909
+ );
11910
+ }
11911
+ var DAY_EVENT_OUTDENT = 16;
11912
+ var VIEWPORT_PADDING2 = 8;
11913
+ function shiftIntoView(desired, size, viewport) {
11914
+ const max = Math.max(viewport - size - VIEWPORT_PADDING2, VIEWPORT_PADDING2);
11915
+ return Math.min(Math.max(desired, VIEWPORT_PADDING2), max) - desired;
11916
+ }
11917
+ function measureRowCapacity(cell) {
11918
+ const cs = getComputedStyle(cell);
11919
+ const v = (name) => Number.parseFloat(cs.getPropertyValue(name)) || 0;
11920
+ const gap = v("--cmp-calendarBoard-dayCard-grid-gap");
11921
+ const row = v("--cmp-calendarBoard-item-height") + gap;
11922
+ if (row <= 0) return null;
11923
+ const header = v("--cmp-calendarBoard-dayCard-header-paddingTop") + v("--cmp-calendarBoard-daySequence-size") + v("--cmp-calendarBoard-dayCard-header-paddingBottom");
11924
+ const free = cell.getBoundingClientRect().height - header - v("--cmp-calendarBoard-dayCard-grid-paddingBottom") + gap;
11925
+ if (free <= 0) return null;
11926
+ return Math.max(1, Math.floor(free / row));
11927
+ }
11928
+ function SCalendarBoard({
11929
+ year,
11930
+ month,
11931
+ defaultYear,
11932
+ defaultMonth,
11933
+ onViewChange,
11934
+ selectable = false,
11935
+ value,
11936
+ onValueChange,
11937
+ events,
11938
+ dayColors,
11939
+ dayContent,
11940
+ onEventClick,
11941
+ onMoreClick,
11942
+ todayLabel = "\uC624\uB298",
11943
+ moreLabel,
11944
+ headerRight,
11945
+ className,
11946
+ style
11947
+ }) {
11948
+ const today = todayStr();
11949
+ const [ty, tm] = [Number(today.slice(0, 4)), Number(today.slice(5, 7))];
11950
+ const [innerView, setInnerView] = react.useState(() => ({
11951
+ year: defaultYear ?? ty,
11952
+ month: defaultMonth ?? tm
11953
+ }));
11954
+ const controlled = year != null && month != null;
11955
+ const view = controlled ? { year, month } : innerView;
11956
+ const [openDate, setOpenDate] = react.useState(null);
11957
+ const [placement, setPlacement] = react.useState({ cellWidth: 0, cellHeight: 0, side: 0, align: 0 });
11958
+ const [panelEl, setPanelEl] = react.useState(null);
11959
+ const portalContainer = usePortalContainer();
11960
+ const setView = react.useCallback(
11961
+ (next) => {
11962
+ setOpenDate(null);
11963
+ if (!controlled) setInnerView(next);
11964
+ onViewChange?.(next);
11965
+ },
11966
+ [controlled, onViewChange]
11967
+ );
11968
+ const cells = react.useMemo(() => monthCells(view.year, view.month), [view.year, view.month]);
11969
+ const rowCount = cells.length / 7;
11970
+ const gridRef = react.useRef(null);
11971
+ const [rowCapacity, setRowCapacity] = react.useState(CALENDAR_BOARD_MAX_VISIBLE_EVENTS);
11972
+ react.useEffect(() => {
11973
+ const grid = gridRef.current;
11974
+ if (grid == null || typeof ResizeObserver === "undefined") return;
11975
+ const cell = grid.querySelector('[role="gridcell"]');
11976
+ if (cell == null) return;
11977
+ const apply = () => {
11978
+ const next = measureRowCapacity(cell);
11979
+ if (next != null) setRowCapacity(next);
11980
+ };
11981
+ apply();
11982
+ const observer = new ResizeObserver(apply);
11983
+ observer.observe(cell);
11984
+ return () => observer.disconnect();
11985
+ }, [rowCount]);
11986
+ const eventMap = react.useMemo(() => {
11987
+ const map = /* @__PURE__ */ new Map();
11988
+ (events ?? []).forEach((event) => {
11989
+ const list = map.get(event.date);
11990
+ if (list) list.push(event);
11991
+ else map.set(event.date, [event]);
11992
+ });
11993
+ return map;
11994
+ }, [events]);
11995
+ const openEvents = openDate ? eventMap.get(openDate) ?? [] : [];
11996
+ react.useLayoutEffect(() => {
11997
+ if (openDate == null || panelEl == null) return;
11998
+ const cell = gridRef.current?.querySelector(`[data-date="${openDate}"]`);
11999
+ if (cell == null) return;
12000
+ const adjust = () => {
12001
+ const cellRect = cell.getBoundingClientRect();
12002
+ const panelRect = panelEl.getBoundingClientRect();
12003
+ const next = {
12004
+ cellWidth: cellRect.width,
12005
+ cellHeight: cellRect.height,
12006
+ side: -(cellRect.height + DAY_EVENT_OUTDENT) + shiftIntoView(cellRect.top - DAY_EVENT_OUTDENT, panelRect.height, window.innerHeight),
12007
+ align: -DAY_EVENT_OUTDENT + shiftIntoView(cellRect.left - DAY_EVENT_OUTDENT, panelRect.width, window.innerWidth)
12008
+ };
12009
+ setPlacement(
12010
+ (prev) => prev.cellWidth === next.cellWidth && prev.cellHeight === next.cellHeight && prev.side === next.side && prev.align === next.align ? prev : next
12011
+ );
12012
+ };
12013
+ adjust();
12014
+ const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(adjust);
12015
+ observer?.observe(panelEl);
12016
+ window.addEventListener("scroll", adjust, true);
12017
+ window.addEventListener("resize", adjust);
12018
+ return () => {
12019
+ observer?.disconnect();
12020
+ window.removeEventListener("scroll", adjust, true);
12021
+ window.removeEventListener("resize", adjust);
12022
+ };
12023
+ }, [openDate, panelEl]);
12024
+ const columns = "repeat(7, minmax(var(--cmp-calendarBoard-dayCard-minWidth), 1fr))";
12025
+ const openEventList = (date, list) => {
12026
+ if (onMoreClick) {
12027
+ onMoreClick({ date, events: list });
12028
+ return;
12029
+ }
12030
+ setOpenDate((prev) => prev === date ? null : date);
12031
+ };
12032
+ return /* @__PURE__ */ jsxRuntime.jsxs(
12033
+ "div",
12034
+ {
12035
+ className: cn(
12036
+ // 판 높이는 부모가 정한다 — 행이 그 높이를 균등 분할하고, 칸 높이가 다시 "몇 줄 보일지" 를 정한다.
12037
+ "flex h-full w-full flex-col overflow-hidden rounded-(--cmp-calendarBoard-radius) border border-solid border-(--cmp-calendarBoard-border) bg-(--cmp-calendarBoard-bg)",
12038
+ className
12039
+ ),
12040
+ style,
12041
+ children: [
12042
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center gap-(--cmp-calendarBoard-header-gap) px-sd-16 py-sd-12", children: [
12043
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-(--cmp-calendarBoard-header-content-gap)", children: [
12044
+ /* @__PURE__ */ jsxRuntime.jsx(
12045
+ SGhostButton,
12046
+ {
12047
+ icon: "chevronLeft",
12048
+ size: "xxs",
12049
+ ariaLabel: "\uC774\uC804 \uD574",
12050
+ onClick: () => setView({ year: view.year - 1, month: view.month })
12051
+ }
12052
+ ),
12053
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typo-heading-lg inline-flex min-w-[48px] justify-center text-(--cmp-calendarBoard-header-content-color)", children: view.year }),
12054
+ /* @__PURE__ */ jsxRuntime.jsx(
12055
+ SGhostButton,
12056
+ {
12057
+ icon: "chevronRight",
12058
+ size: "xxs",
12059
+ ariaLabel: "\uB2E4\uC74C \uD574",
12060
+ onClick: () => setView({ year: view.year + 1, month: view.month })
12061
+ }
12062
+ )
12063
+ ] }),
12064
+ /* @__PURE__ */ jsxRuntime.jsx(SDivider, { vertical: true, height: "var(--cmp-calendarBoard-header-content-divider-height)" }),
12065
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-(--cmp-calendarBoard-header-content-gap)", children: [
12066
+ /* @__PURE__ */ jsxRuntime.jsx(
12067
+ SGhostButton,
12068
+ {
12069
+ icon: "chevronLeft",
12070
+ size: "xxs",
12071
+ ariaLabel: "\uC774\uC804 \uB2EC",
12072
+ onClick: () => setView(calcYearMonth(view.year, view.month, "prev"))
12073
+ }
12074
+ ),
12075
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "typo-heading-lg inline-flex min-w-[48px] justify-center text-(--cmp-calendarBoard-header-content-color)", children: [
12076
+ view.month,
12077
+ "\uC6D4"
12078
+ ] }),
12079
+ /* @__PURE__ */ jsxRuntime.jsx(
12080
+ SGhostButton,
12081
+ {
12082
+ icon: "chevronRight",
12083
+ size: "xxs",
12084
+ ariaLabel: "\uB2E4\uC74C \uB2EC",
12085
+ onClick: () => setView(calcYearMonth(view.year, view.month, "next"))
12086
+ }
12087
+ )
12088
+ ] }),
12089
+ todayLabel !== "" && /* @__PURE__ */ jsxRuntime.jsx(
12090
+ SButton,
12091
+ {
12092
+ color: "neutral",
12093
+ outline: true,
12094
+ size: "xs",
12095
+ label: todayLabel,
12096
+ onClick: () => setView({ year: ty, month: tm })
12097
+ }
12098
+ ),
12099
+ headerRight != null && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-auto flex items-center", children: headerRight })
12100
+ ] }),
12101
+ /* @__PURE__ */ jsxRuntime.jsx(SDivider, {}),
12102
+ /* @__PURE__ */ jsxRuntime.jsx(
12103
+ "div",
12104
+ {
12105
+ className: "grid shrink-0 bg-(--cmp-calendarBoard-grid-bg) pt-(--cmp-calendarBoard-grid-paddingTop) pb-(--cmp-calendarBoard-grid-gap)",
12106
+ style: { gridTemplateColumns: columns },
12107
+ children: WEEK_LABELS.map((label) => /* @__PURE__ */ jsxRuntime.jsx(
12108
+ "div",
12109
+ {
12110
+ className: "typo-body-md-default flex justify-center text-(--cmp-calendarBoard-grid-weekRow-color)",
12111
+ children: label
12112
+ },
12113
+ label
12114
+ ))
12115
+ }
12116
+ ),
12117
+ /* @__PURE__ */ jsxRuntime.jsxs(
12118
+ RPopover12__namespace.Root,
12119
+ {
12120
+ open: openDate !== null,
12121
+ onOpenChange: (open) => {
12122
+ if (!open) setOpenDate(null);
12123
+ },
12124
+ children: [
12125
+ /* @__PURE__ */ jsxRuntime.jsx(
12126
+ "div",
12127
+ {
12128
+ ref: gridRef,
12129
+ role: "grid",
12130
+ className: "grid min-h-0 flex-1 gap-px overflow-auto border-t border-solid border-(--cmp-calendarBoard-grid-month-border) bg-(--cmp-calendarBoard-grid-month-border)",
12131
+ style: {
12132
+ gridTemplateColumns: columns,
12133
+ // 행은 판 높이를 균등하게 나눠 갖는다 — 일정이 많은 주만 길어지면 격자가 깨진다.
12134
+ gridTemplateRows: `repeat(${rowCount}, minmax(var(--cmp-calendarBoard-dayCard-minHeight), 1fr))`
12135
+ },
12136
+ children: cells.map((cell) => {
12137
+ const content = dayContent?.[cell.date];
12138
+ const list = content == null ? eventMap.get(cell.date) ?? [] : [];
12139
+ const folded = list.length > rowCapacity;
12140
+ const visible = folded ? list.slice(0, rowCapacity - 1) : list;
12141
+ const card = /* @__PURE__ */ jsxRuntime.jsx(
12142
+ CalendarDayCard,
12143
+ {
12144
+ date: cell.date,
12145
+ day: cell.day,
12146
+ inCurrentMonth: cell.inCurrentMonth,
12147
+ isToday: cell.date === today,
12148
+ isSelected: value != null && value === cell.date,
12149
+ selectable,
12150
+ color: dayColors?.[cell.date] ?? "default",
12151
+ events: visible,
12152
+ body: content,
12153
+ hiddenCount: folded ? list.length - (rowCapacity - 1) : 0,
12154
+ isOpen: openDate === cell.date,
12155
+ moreLabel,
12156
+ onDaySelect: (date) => onValueChange?.(date, list),
12157
+ onEventClick,
12158
+ onOpenEvents: () => openEventList(cell.date, list)
12159
+ },
12160
+ cell.date
12161
+ );
12162
+ return cell.date === openDate ? /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Anchor, { asChild: true, children: card }, cell.date) : card;
12163
+ })
12164
+ }
12165
+ ),
12166
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
12167
+ RPopover12__namespace.Content,
12168
+ {
12169
+ onInteractOutside: (e) => {
12170
+ const target = e.detail.originalEvent.target;
12171
+ if (target instanceof Node && gridRef.current?.contains(target)) e.preventDefault();
12172
+ },
12173
+ side: "bottom",
12174
+ align: "start",
12175
+ ref: setPanelEl,
12176
+ sideOffset: placement.side,
12177
+ alignOffset: placement.align,
12178
+ avoidCollisions: false,
12179
+ className: cn("z-50 outline-none", FLOATING_SLIDE_ANIM),
12180
+ onOpenAutoFocus: (e) => e.preventDefault(),
12181
+ children: openDate != null && /* @__PURE__ */ jsxRuntime.jsx(
12182
+ CalendarDayEventListBox,
12183
+ {
12184
+ date: openDate,
12185
+ minWidth: placement.cellWidth > 0 ? placement.cellWidth + DAY_EVENT_OUTDENT * 2 : void 0,
12186
+ minHeight: placement.cellHeight > 0 ? placement.cellHeight + DAY_EVENT_OUTDENT * 2 : void 0,
12187
+ events: openEvents,
12188
+ onEventClick,
12189
+ onClose: () => setOpenDate(null)
12190
+ }
12191
+ )
12192
+ },
12193
+ openDate
12194
+ ) })
12195
+ ]
12196
+ }
12197
+ )
12198
+ ]
12199
+ }
12200
+ );
12201
+ }
12202
+
11480
12203
  // src/lib/floating-height.ts
11481
12204
  var POPOVER_AVAILABLE_HEIGHT = "var(--radix-popover-content-available-height)";
11482
12205
  function clampToAvailableHeight(value, availableHeight) {
@@ -13432,10 +14155,10 @@ function useTruncatedValueTooltip({
13432
14155
  valueRef: elRef,
13433
14156
  onMouseEnter: active ? onMouseEnter : cancelHide,
13434
14157
  onMouseLeave: active ? startHide : cancelHide,
13435
- tooltip: active ? /* @__PURE__ */ jsxRuntime.jsxs(RPopover11__namespace.Root, { open, onOpenChange: setOpen, children: [
13436
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Anchor, { virtualRef: elRef }),
13437
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
13438
- RPopover11__namespace.Content,
14158
+ tooltip: active ? /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open, onOpenChange: setOpen, children: [
14159
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Anchor, { virtualRef: elRef }),
14160
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
14161
+ RPopover12__namespace.Content,
13439
14162
  {
13440
14163
  side: "top",
13441
14164
  sideOffset: 4,
@@ -14191,41 +14914,6 @@ function SRadioGroup({
14191
14914
  }
14192
14915
  );
14193
14916
  }
14194
-
14195
- // src/lib/date.ts
14196
- function todayStr() {
14197
- const d = /* @__PURE__ */ new Date();
14198
- return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
14199
- }
14200
- function formatDate(year, month, day) {
14201
- return `${year}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
14202
- }
14203
- function calcYearMonth(year, month, dir) {
14204
- if (dir === "prev")
14205
- return month === 1 ? { year: year - 1, month: 12 } : { year, month: month - 1 };
14206
- return month === 12 ? { year: year + 1, month: 1 } : { year, month: month + 1 };
14207
- }
14208
- function monthCells(year, month) {
14209
- const firstDayIndex = new Date(year, month - 1, 1).getDay();
14210
- const daysInCurrent = new Date(year, month, 0).getDate();
14211
- const prev = calcYearMonth(year, month, "prev");
14212
- const daysInPrev = new Date(prev.year, prev.month, 0).getDate();
14213
- const next = calcYearMonth(year, month, "next");
14214
- const cells = [];
14215
- for (let i = firstDayIndex - 1; i >= 0; i--) {
14216
- const day = daysInPrev - i;
14217
- cells.push({ date: formatDate(prev.year, prev.month, day), day, inCurrentMonth: false });
14218
- }
14219
- for (let day = 1; day <= daysInCurrent; day++) {
14220
- cells.push({ date: formatDate(year, month, day), day, inCurrentMonth: true });
14221
- }
14222
- const remaining = (7 - cells.length % 7) % 7;
14223
- for (let day = 1; day <= remaining; day++) {
14224
- cells.push({ date: formatDate(next.year, next.month, day), day, inCurrentMonth: false });
14225
- }
14226
- return cells;
14227
- }
14228
- var WEEK_LABELS = ["\uC77C", "\uC6D4", "\uD654", "\uC218", "\uBAA9", "\uAE08", "\uD1A0"];
14229
14917
  function SCalendar({
14230
14918
  value,
14231
14919
  onValueChange,
@@ -14804,8 +15492,8 @@ function SDatePicker({
14804
15492
  disabled,
14805
15493
  className,
14806
15494
  style,
14807
- children: /* @__PURE__ */ jsxRuntime.jsxs(RPopover11__namespace.Root, { open, onOpenChange: (o) => !disabled && setOpen(o), children: [
14808
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
15495
+ children: /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open, onOpenChange: (o) => !disabled && setOpen(o), children: [
15496
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
14809
15497
  "div",
14810
15498
  {
14811
15499
  role: "button",
@@ -14864,8 +15552,8 @@ function SDatePicker({
14864
15552
  ]
14865
15553
  }
14866
15554
  ) }),
14867
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
14868
- RPopover11__namespace.Content,
15555
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
15556
+ RPopover12__namespace.Content,
14869
15557
  {
14870
15558
  side: "bottom",
14871
15559
  align: mode === "date" ? "start" : "center",
@@ -15338,7 +16026,7 @@ function SDateRangePicker({
15338
16026
  className,
15339
16027
  style,
15340
16028
  children: /* @__PURE__ */ jsxRuntime.jsxs(
15341
- RPopover11__namespace.Root,
16029
+ RPopover12__namespace.Root,
15342
16030
  {
15343
16031
  open,
15344
16032
  onOpenChange: (o) => {
@@ -15347,7 +16035,7 @@ function SDateRangePicker({
15347
16035
  if (!o) setPendingStart(null);
15348
16036
  },
15349
16037
  children: [
15350
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
16038
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
15351
16039
  "div",
15352
16040
  {
15353
16041
  role: "button",
@@ -15411,8 +16099,8 @@ function SDateRangePicker({
15411
16099
  ]
15412
16100
  }
15413
16101
  ) }),
15414
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
15415
- RPopover11__namespace.Content,
16102
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
16103
+ RPopover12__namespace.Content,
15416
16104
  {
15417
16105
  side: "bottom",
15418
16106
  align: "start",
@@ -17909,10 +18597,10 @@ function EditorToolbarBar({
17909
18597
  },
17910
18598
  item4
17911
18599
  );
17912
- return /* @__PURE__ */ jsxRuntime.jsxs(RPopover11__namespace.Root, { open: linkOpen, onOpenChange: setLinkOpen, children: [
17913
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Trigger, { asChild: true, disabled: off, children: /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { label: "\uB9C1\uD06C", active: state2.link, disabled: off, children: /* @__PURE__ */ jsxRuntime.jsx(IconLink, { size: ICON_SIZE }) }) }),
17914
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
17915
- RPopover11__namespace.Content,
18600
+ return /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open: linkOpen, onOpenChange: setLinkOpen, children: [
18601
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Trigger, { asChild: true, disabled: off, children: /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { label: "\uB9C1\uD06C", active: state2.link, disabled: off, children: /* @__PURE__ */ jsxRuntime.jsx(IconLink, { size: ICON_SIZE }) }) }),
18602
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
18603
+ RPopover12__namespace.Content,
17916
18604
  {
17917
18605
  sideOffset: 4,
17918
18606
  align: "start",
@@ -19120,7 +19808,7 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
19120
19808
  "div",
19121
19809
  {
19122
19810
  className: cn(
19123
- "flex w-full items-start gap-[var(--chipfilter-bar-gap)] border-b border-solid bg-[var(--chipfilter-bar-bg)] px-[var(--chipfilter-bar-padding-x)] py-[var(--chipfilter-bar-padding-y)]",
19811
+ "flex w-full items-start gap-[var(--chipfilter-bar-gap)] bg-[var(--chipfilter-bar-bg)] px-[var(--chipfilter-bar-padding-x)] py-[var(--chipfilter-bar-padding-y)]",
19124
19812
  className
19125
19813
  ),
19126
19814
  style: { ...rootStyle, borderColor: "var(--chipfilter-bar-border)" },
@@ -19248,8 +19936,8 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
19248
19936
  })(),
19249
19937
  hasRightActions && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
19250
19938
  /* @__PURE__ */ jsxRuntime.jsx(Divider, { inset: true }),
19251
- hasAddButton && /* @__PURE__ */ jsxRuntime.jsxs(RPopover11__namespace.Root, { open: addOpen, onOpenChange: setAddOpen, children: [
19252
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
19939
+ hasAddButton && /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open: addOpen, onOpenChange: setAddOpen, children: [
19940
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
19253
19941
  "button",
19254
19942
  {
19255
19943
  type: "button",
@@ -19274,8 +19962,8 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
19274
19962
  ]
19275
19963
  }
19276
19964
  ) }),
19277
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
19278
- RPopover11__namespace.Content,
19965
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
19966
+ RPopover12__namespace.Content,
19279
19967
  {
19280
19968
  side: "bottom",
19281
19969
  align: "start",
@@ -19310,17 +19998,17 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
19310
19998
  )
19311
19999
  ] })
19312
20000
  ] }),
19313
- /* @__PURE__ */ jsxRuntime.jsxs(RPopover11__namespace.Root, { open: openKey != null, onOpenChange: (next) => !next && setOpenKey(null), children: [
20001
+ /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open: openKey != null, onOpenChange: (next) => !next && setOpenKey(null), children: [
19314
20002
  /* @__PURE__ */ jsxRuntime.jsx(
19315
- RPopover11__namespace.Anchor,
20003
+ RPopover12__namespace.Anchor,
19316
20004
  {
19317
20005
  virtualRef: {
19318
20006
  current: openKey ? triggerRefs.current.get(openKey) : null
19319
20007
  }
19320
20008
  }
19321
20009
  ),
19322
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
19323
- RPopover11__namespace.Content,
20010
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
20011
+ RPopover12__namespace.Content,
19324
20012
  {
19325
20013
  side: "bottom",
19326
20014
  align: "start",
@@ -19912,8 +20600,8 @@ function InlineDatePresetFilter({
19912
20600
  applied && (rangeValue ? (
19913
20601
  // 뱃지 모양은 그대로 두고, 눌렀을 때 캘린더가 열려 기간을 직접 다시 고를 수 있게 한다.
19914
20602
  // 직접 고르면 프리셋 선택은 해제된다.
19915
- /* @__PURE__ */ jsxRuntime.jsxs(RPopover11__namespace.Root, { open: pickerOpen, onOpenChange: setPickerOpen, children: [
19916
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
20603
+ /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open: pickerOpen, onOpenChange: setPickerOpen, children: [
20604
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
19917
20605
  "button",
19918
20606
  {
19919
20607
  type: "button",
@@ -19922,8 +20610,8 @@ function InlineDatePresetFilter({
19922
20610
  children: badge
19923
20611
  }
19924
20612
  ) }),
19925
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
19926
- RPopover11__namespace.Content,
20613
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
20614
+ RPopover12__namespace.Content,
19927
20615
  {
19928
20616
  side: "bottom",
19929
20617
  align: "start",
@@ -21231,8 +21919,8 @@ function STimePicker({
21231
21919
  disabled,
21232
21920
  className,
21233
21921
  style,
21234
- children: /* @__PURE__ */ jsxRuntime.jsxs(RPopover11__namespace.Root, { open, onOpenChange: commitOpen, children: [
21235
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
21922
+ children: /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open, onOpenChange: commitOpen, children: [
21923
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
21236
21924
  "div",
21237
21925
  {
21238
21926
  ref: triggerRef,
@@ -21292,8 +21980,8 @@ function STimePicker({
21292
21980
  ]
21293
21981
  }
21294
21982
  ) }),
21295
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
21296
- RPopover11__namespace.Content,
21983
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
21984
+ RPopover12__namespace.Content,
21297
21985
  {
21298
21986
  side: "bottom",
21299
21987
  align: "start",
@@ -21698,8 +22386,8 @@ function STimeRangePicker({
21698
22386
  disabled,
21699
22387
  className,
21700
22388
  style,
21701
- children: /* @__PURE__ */ jsxRuntime.jsxs(RPopover11__namespace.Root, { open, onOpenChange: commitOpen, children: [
21702
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
22389
+ children: /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open, onOpenChange: commitOpen, children: [
22390
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
21703
22391
  "div",
21704
22392
  {
21705
22393
  ref: triggerRef,
@@ -21759,8 +22447,8 @@ function STimeRangePicker({
21759
22447
  ]
21760
22448
  }
21761
22449
  ) }),
21762
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
21763
- RPopover11__namespace.Content,
22450
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
22451
+ RPopover12__namespace.Content,
21764
22452
  {
21765
22453
  side: "bottom",
21766
22454
  align: "start",
@@ -21795,6 +22483,11 @@ exports.ACCOUNT_LIST_BOX_TONE_CONFIG = ACCOUNT_LIST_BOX_TONE_CONFIG;
21795
22483
  exports.BADGE_COLORS = BADGE_COLORS;
21796
22484
  exports.BUTTON_COLORS = BUTTON_COLORS;
21797
22485
  exports.BUTTON_SIZES = BUTTON_SIZES;
22486
+ exports.CALENDAR_BOARD_DAY_BG = CALENDAR_BOARD_DAY_BG;
22487
+ exports.CALENDAR_BOARD_DAY_COLORS = CALENDAR_BOARD_DAY_COLORS;
22488
+ exports.CALENDAR_BOARD_EVENT_COLORS = CALENDAR_BOARD_EVENT_COLORS;
22489
+ exports.CALENDAR_BOARD_EVENT_PRESETS = CALENDAR_BOARD_EVENT_PRESETS;
22490
+ exports.CALENDAR_BOARD_MAX_VISIBLE_EVENTS = CALENDAR_BOARD_MAX_VISIBLE_EVENTS;
21798
22491
  exports.COLOR_KEYS = COLOR_KEYS;
21799
22492
  exports.FIELD_WIDTH_GRADES = FIELD_WIDTH_GRADES;
21800
22493
  exports.GNB_COLORS = GNB_COLORS;
@@ -21823,6 +22516,7 @@ exports.SBarcodeInput = SBarcodeInput;
21823
22516
  exports.SButton = SButton;
21824
22517
  exports.SCROLL_AREA_AXES = SCROLL_AREA_AXES;
21825
22518
  exports.SCalendar = SCalendar;
22519
+ exports.SCalendarBoard = SCalendarBoard;
21826
22520
  exports.SCallout = SCallout;
21827
22521
  exports.SCard = SCard;
21828
22522
  exports.SCheckbox = SCheckbox;