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.
- package/AGENTS.md +21 -6
- package/dist/components/SBadge/README.md +2 -0
- package/dist/components/SButton/README.md +2 -0
- package/dist/components/SCalendarBoard/CalendarDayCard.d.ts +38 -0
- package/dist/components/SCalendarBoard/CalendarDayEventListBox.d.ts +26 -0
- package/dist/components/SCalendarBoard/CalendarEventButton.d.ts +13 -0
- package/dist/components/SCalendarBoard/CalendarMoreButton.d.ts +12 -0
- package/dist/components/SCalendarBoard/README.md +137 -0
- package/dist/components/SCalendarBoard/SCalendarBoard.d.ts +68 -0
- package/dist/components/SCalendarBoard/calendarBoard.config.d.ts +33 -0
- package/dist/components/SCalendarBoard/index.d.ts +3 -0
- package/dist/components/SCalendarBoard/types.d.ts +31 -0
- package/dist/components/SDivider/README.md +2 -0
- package/dist/components/SGhostButton/README.md +2 -0
- package/dist/components/SGnb/SGnb.d.ts +6 -0
- package/dist/components/SGnb/gnb.config.d.ts +3 -3
- package/dist/components/SGnbSystem/README.md +43 -1
- package/dist/components/SGnbSystem/SGnbSystem.d.ts +48 -2
- package/dist/components/SPortal/README.md +2 -0
- package/dist/components/SScrollArea/README.md +13 -0
- package/dist/components/SSystemActionButton/systemActionButton.config.d.ts +8 -2
- package/dist/components/STooltip/README.md +2 -0
- package/dist/index.cjs +823 -129
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +817 -129
- package/dist/index.js.map +1 -1
- package/dist/llms-full.txt +206 -7
- package/dist/llms.txt +23 -8
- package/dist/styles.css +290 -9
- package/dist/theme.css +74 -8
- 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
|
|
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
|
|
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(
|
|
5196
|
-
/* @__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(
|
|
5209
|
-
|
|
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(
|
|
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(
|
|
5789
|
+
/* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Anchor, { asChild: true, children: triggerNode })
|
|
5790
5790
|
) : isHover ? (
|
|
5791
5791
|
// hover: Anchor(위치 기준) + 직접 mouse 핸들러 — 클릭으로 토글되지 않도록 Trigger 미사용
|
|
5792
|
-
/* @__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(
|
|
5804
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5805
|
-
|
|
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(
|
|
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
|
-
|
|
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(
|
|
6926
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6927
|
-
|
|
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-
|
|
7373
|
-
// 어두운 면에는 글리프색 토큰이 없다.
|
|
7374
|
-
//
|
|
7375
|
+
iconBgHover: item2("dark-icon-bg-default"),
|
|
7376
|
+
// 어두운 면에는 글리프색 토큰이 없다. 프레임이 배경과 블렌딩되므로 라벨색(흰색)을 쓰고,
|
|
7377
|
+
// 프레임이 hover 에서 그대로이므로 글리프도 그대로 둔다.
|
|
7375
7378
|
iconGlyph: item2("dark-text"),
|
|
7376
|
-
iconGlyphHover: item2("dark-
|
|
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-
|
|
7393
|
+
iconBgHover: item2("darker-icon-bg-default"),
|
|
7390
7394
|
iconGlyph: item2("darker-text"),
|
|
7391
|
-
iconGlyphHover: item2("darker-
|
|
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 &&
|
|
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(
|
|
7661
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7662
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7663
|
-
|
|
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(
|
|
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(
|
|
7841
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7842
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7843
|
-
|
|
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 =
|
|
9291
|
+
var GNB_MENU_WIDTH = 214;
|
|
9274
9292
|
var GNB_MENU_MIN_WIDTH = 200;
|
|
9275
|
-
var GNB_MENU_MAX_WIDTH =
|
|
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
|
-
|
|
9834
|
-
|
|
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(
|
|
9988
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9989
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9990
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
10174
|
-
count != null && count > 0 &&
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
13436
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
13437
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
13438
|
-
|
|
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(
|
|
14808
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
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(
|
|
14868
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
15415
|
-
|
|
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(
|
|
17913
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17914
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17915
|
-
|
|
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)]
|
|
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(
|
|
19252
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
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(
|
|
19278
|
-
|
|
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(
|
|
20001
|
+
/* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open: openKey != null, onOpenChange: (next) => !next && setOpenKey(null), children: [
|
|
19314
20002
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
19315
|
-
|
|
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(
|
|
19323
|
-
|
|
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(
|
|
19916
|
-
/* @__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(
|
|
19926
|
-
|
|
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(
|
|
21235
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
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(
|
|
21296
|
-
|
|
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(
|
|
21702
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
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(
|
|
21763
|
-
|
|
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;
|