sellmate-design-system-react 4.3.0 → 5.0.1
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 +18 -0
- package/README.md +2 -2
- package/dist/components/SActionModal/README.md +6 -4
- package/dist/components/SActionModal/SActionModal.d.ts +3 -12
- package/dist/components/SActionModal/index.d.ts +1 -1
- package/dist/components/SButton/README.md +2 -6
- package/dist/components/SConfirmModal/README.md +1 -1
- package/dist/components/SConfirmModal/SConfirmModal.d.ts +1 -1
- package/dist/components/SDrawer/README.md +8 -5
- package/dist/components/SDrawer/SDrawer.d.ts +14 -11
- package/dist/components/SFooter/README.md +40 -0
- package/dist/components/SFooter/SFooter.d.ts +36 -0
- package/dist/components/SFooter/index.d.ts +1 -0
- package/dist/components/SGhostButton/README.md +2 -2
- package/dist/components/SGnb/README.md +0 -5
- package/dist/components/SGnb/SGnb.d.ts +6 -2
- package/dist/components/SGnb/gnb.config.d.ts +2 -0
- package/dist/components/SLayout/README.md +1 -6
- package/dist/components/SLayout/SLayout.d.ts +39 -17
- package/dist/components/SLoadingModal/README.md +1 -1
- package/dist/components/SLoadingModal/SLoadingModal.d.ts +1 -1
- package/dist/components/SModalContainer/README.md +1 -1
- package/dist/components/SModalContainer/SModalContainer.d.ts +6 -2
- package/dist/components/SOverlayHeader/README.md +45 -0
- package/dist/components/SOverlayHeader/SOverlayHeader.d.ts +28 -0
- package/dist/components/SOverlayHeader/index.d.ts +1 -0
- package/dist/components/SPage/SPage.d.ts +2 -2
- package/dist/components/SPopup/README.md +2 -2
- package/dist/index.cjs +439 -256
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +439 -256
- package/dist/index.js.map +1 -1
- package/dist/lib/global-overlay.d.ts +17 -0
- package/dist/lib/isomorphic-layout-effect.d.ts +8 -0
- package/dist/llms-full.txt +109 -23
- package/dist/llms.txt +18 -0
- package/dist/styles.css +27 -17
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5301,6 +5301,16 @@ var SCircleProgress = /* @__PURE__ */ forwardRef(
|
|
|
5301
5301
|
);
|
|
5302
5302
|
}
|
|
5303
5303
|
);
|
|
5304
|
+
|
|
5305
|
+
// src/lib/global-overlay.ts
|
|
5306
|
+
var GLOBAL_OVERLAY_ATTR = "data-s-global-overlay";
|
|
5307
|
+
var globalOverlayProps = { [GLOBAL_OVERLAY_ATTR]: "" };
|
|
5308
|
+
function isFromGlobalOverlay(event) {
|
|
5309
|
+
const detail = event.detail;
|
|
5310
|
+
const target = detail?.originalEvent?.target ?? event.target;
|
|
5311
|
+
const element = target instanceof Element ? target : target instanceof Node ? target.parentElement : null;
|
|
5312
|
+
return !!element?.closest(`[${GLOBAL_OVERLAY_ATTR}]`);
|
|
5313
|
+
}
|
|
5304
5314
|
var SLoadingContainer = /* @__PURE__ */ forwardRef(
|
|
5305
5315
|
function SLoadingContainer2({ open = false, message, zIndex = Z_INDEX.loading, className, style }, ref) {
|
|
5306
5316
|
const [mounted2, setMounted] = useState(false);
|
|
@@ -5337,6 +5347,7 @@ var SLoadingContainer = /* @__PURE__ */ forwardRef(
|
|
|
5337
5347
|
"div",
|
|
5338
5348
|
{
|
|
5339
5349
|
ref: setRef,
|
|
5350
|
+
...globalOverlayProps,
|
|
5340
5351
|
"aria-hidden": !open,
|
|
5341
5352
|
className: cn(
|
|
5342
5353
|
"fixed inset-0 flex items-center justify-center transition-opacity duration-200",
|
|
@@ -5544,6 +5555,7 @@ var SDropdownButtonImpl = /* @__PURE__ */ forwardRef(
|
|
|
5544
5555
|
style
|
|
5545
5556
|
}, ref) {
|
|
5546
5557
|
const portalContainer = usePortalContainer();
|
|
5558
|
+
const insideModal = useInsideModal();
|
|
5547
5559
|
const [open, setOpen] = useState(false);
|
|
5548
5560
|
const splitWrapRef = useRef(null);
|
|
5549
5561
|
const splitToggleRef = useRef(null);
|
|
@@ -5632,6 +5644,7 @@ var SDropdownButtonImpl = /* @__PURE__ */ forwardRef(
|
|
|
5632
5644
|
return /* @__PURE__ */ jsxs(
|
|
5633
5645
|
RDropdown.Root,
|
|
5634
5646
|
{
|
|
5647
|
+
modal: !insideModal,
|
|
5635
5648
|
open,
|
|
5636
5649
|
onOpenChange: (o) => {
|
|
5637
5650
|
setOpen(o);
|
|
@@ -5974,6 +5987,53 @@ function SPortal({
|
|
|
5974
5987
|
}
|
|
5975
5988
|
);
|
|
5976
5989
|
}
|
|
5990
|
+
function SFooter({
|
|
5991
|
+
bg = "white",
|
|
5992
|
+
left,
|
|
5993
|
+
button,
|
|
5994
|
+
children,
|
|
5995
|
+
className,
|
|
5996
|
+
leftClassName,
|
|
5997
|
+
style
|
|
5998
|
+
}) {
|
|
5999
|
+
const isGrey = bg === "grey";
|
|
6000
|
+
const hasSlot = left != null || children != null;
|
|
6001
|
+
const hasButton = button != null;
|
|
6002
|
+
return /* @__PURE__ */ jsxs(
|
|
6003
|
+
"footer",
|
|
6004
|
+
{
|
|
6005
|
+
className: cn(
|
|
6006
|
+
"relative flex w-full flex-shrink-0 items-center justify-end gap-[var(--cmp-overlay-footer-gap)] overflow-hidden px-[var(--cmp-overlay-footer-paddingX)] py-[var(--cmp-overlay-footer-paddingY)] shadow-[var(--shadow-spread-md)]",
|
|
6007
|
+
isGrey ? "bg-[var(--cmp-overlay-footer-bg-neutral)]" : "bg-[var(--cmp-overlay-footer-bg-default)]",
|
|
6008
|
+
className
|
|
6009
|
+
),
|
|
6010
|
+
style,
|
|
6011
|
+
children: [
|
|
6012
|
+
hasSlot && /* @__PURE__ */ jsxs(
|
|
6013
|
+
"div",
|
|
6014
|
+
{
|
|
6015
|
+
className: cn("flex min-w-px flex-[1_0_0] items-center justify-between", leftClassName),
|
|
6016
|
+
children: [
|
|
6017
|
+
left,
|
|
6018
|
+
children
|
|
6019
|
+
]
|
|
6020
|
+
}
|
|
6021
|
+
),
|
|
6022
|
+
hasButton && /* @__PURE__ */ jsx(
|
|
6023
|
+
SButton,
|
|
6024
|
+
{
|
|
6025
|
+
color: button.color ?? "primary",
|
|
6026
|
+
outline: button.outline,
|
|
6027
|
+
size: button.size ?? "md",
|
|
6028
|
+
disabled: button.disabled,
|
|
6029
|
+
onClick: () => button.onClick?.(),
|
|
6030
|
+
label: button.label ?? "\uD655\uC778"
|
|
6031
|
+
}
|
|
6032
|
+
)
|
|
6033
|
+
]
|
|
6034
|
+
}
|
|
6035
|
+
);
|
|
6036
|
+
}
|
|
5977
6037
|
var SPopup = /* @__PURE__ */ forwardRef(function SPopup2({
|
|
5978
6038
|
popupTitle = "",
|
|
5979
6039
|
type = "default",
|
|
@@ -6022,29 +6082,7 @@ var SPopup = /* @__PURE__ */ forwardRef(function SPopup2({
|
|
|
6022
6082
|
children
|
|
6023
6083
|
}
|
|
6024
6084
|
),
|
|
6025
|
-
useFooter && /* @__PURE__ */
|
|
6026
|
-
"footer",
|
|
6027
|
-
{
|
|
6028
|
-
className: "relative z-[1] flex h-[52px] w-full flex-shrink-0 items-center gap-[var(--cmp-overlay-footer-gap)] px-[var(--cmp-overlay-footer-paddingX)] py-[var(--cmp-overlay-footer-paddingY)]",
|
|
6029
|
-
style: {
|
|
6030
|
-
background: "var(--cmp-overlay-footer-bg-default)",
|
|
6031
|
-
boxShadow: "var(--shadow-spread-md)"
|
|
6032
|
-
},
|
|
6033
|
-
children: [
|
|
6034
|
-
/* @__PURE__ */ jsx("div", { className: "flex min-w-0 flex-1 items-center", children: footerLeft }),
|
|
6035
|
-
/* @__PURE__ */ jsx(
|
|
6036
|
-
SButton,
|
|
6037
|
-
{
|
|
6038
|
-
color: submitButton?.color ?? "primary",
|
|
6039
|
-
outline: submitButton?.outline,
|
|
6040
|
-
size: submitButton?.size ?? "md",
|
|
6041
|
-
onClick: onSubmit,
|
|
6042
|
-
label: submitButton?.label ?? "\uD655\uC778"
|
|
6043
|
-
}
|
|
6044
|
-
)
|
|
6045
|
-
]
|
|
6046
|
-
}
|
|
6047
|
-
)
|
|
6085
|
+
useFooter && /* @__PURE__ */ jsx(SFooter, { left: footerLeft, button: { ...submitButton, onClick: onSubmit } })
|
|
6048
6086
|
]
|
|
6049
6087
|
}
|
|
6050
6088
|
);
|
|
@@ -6066,6 +6104,7 @@ function SGuide({
|
|
|
6066
6104
|
style
|
|
6067
6105
|
}) {
|
|
6068
6106
|
const [open, setOpen] = useState(false);
|
|
6107
|
+
const portalContainer = usePortalContainer();
|
|
6069
6108
|
const isNotion = type === "notion";
|
|
6070
6109
|
const defaultLabel = DEFAULT_LABEL[type];
|
|
6071
6110
|
const iconName = ICON[type];
|
|
@@ -6100,7 +6139,7 @@ function SGuide({
|
|
|
6100
6139
|
return /* @__PURE__ */ jsx("span", { className, style, children: trigger });
|
|
6101
6140
|
return /* @__PURE__ */ jsxs(RPopover2.Root, { open, onOpenChange: setOpen, children: [
|
|
6102
6141
|
/* @__PURE__ */ jsx(RPopover2.Trigger, { asChild: true, children: trigger }),
|
|
6103
|
-
/* @__PURE__ */ jsx(RPopover2.Portal, { children: /* @__PURE__ */ jsxs(
|
|
6142
|
+
/* @__PURE__ */ jsx(RPopover2.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxs(
|
|
6104
6143
|
RPopover2.Content,
|
|
6105
6144
|
{
|
|
6106
6145
|
side: "bottom",
|
|
@@ -6198,7 +6237,7 @@ function SModalContainer({
|
|
|
6198
6237
|
ariaTitle = "\uBAA8\uB2EC",
|
|
6199
6238
|
showClose = false,
|
|
6200
6239
|
onClose,
|
|
6201
|
-
persistent =
|
|
6240
|
+
persistent = true,
|
|
6202
6241
|
width,
|
|
6203
6242
|
height,
|
|
6204
6243
|
children,
|
|
@@ -6241,6 +6280,13 @@ function SModalContainer({
|
|
|
6241
6280
|
e.preventDefault();
|
|
6242
6281
|
if (stackRegistrationRef.current?.isTop()) triggerShake();
|
|
6243
6282
|
} : void 0;
|
|
6283
|
+
const guardInteractOutside = (e) => {
|
|
6284
|
+
if (isFromGlobalOverlay(e)) {
|
|
6285
|
+
e.preventDefault();
|
|
6286
|
+
return;
|
|
6287
|
+
}
|
|
6288
|
+
guardClose?.(e);
|
|
6289
|
+
};
|
|
6244
6290
|
return /* @__PURE__ */ jsx(RDialog.Root, { open, onOpenChange, children: /* @__PURE__ */ jsx(RDialog.Portal, { container: modalHost, forceMount: rendered ? true : void 0, children: /* @__PURE__ */ jsxs("div", { className: "pointer-events-none absolute inset-0", style: { zIndex: layerIndex ?? 0 }, children: [
|
|
6245
6291
|
/* @__PURE__ */ jsx(
|
|
6246
6292
|
RDialog.Overlay,
|
|
@@ -6267,8 +6313,8 @@ function SModalContainer({
|
|
|
6267
6313
|
contentRef.current?.focus({ preventScroll: true });
|
|
6268
6314
|
},
|
|
6269
6315
|
onEscapeKeyDown: guardClose,
|
|
6270
|
-
onPointerDownOutside:
|
|
6271
|
-
onInteractOutside:
|
|
6316
|
+
onPointerDownOutside: guardInteractOutside,
|
|
6317
|
+
onInteractOutside: guardInteractOutside,
|
|
6272
6318
|
children: [
|
|
6273
6319
|
/* @__PURE__ */ jsx(RDialog.Title, { className: "sr-only", children: ariaTitle }),
|
|
6274
6320
|
/* @__PURE__ */ jsxs(
|
|
@@ -6419,7 +6465,7 @@ function SConfirmModal({
|
|
|
6419
6465
|
)) })
|
|
6420
6466
|
] })
|
|
6421
6467
|
] }),
|
|
6422
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-shrink-0 gap-[
|
|
6468
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-shrink-0 gap-[var(--cmp-modal-confirm-button-gap)]", children: [
|
|
6423
6469
|
subButtonLabel && /* @__PURE__ */ jsx(
|
|
6424
6470
|
SButton,
|
|
6425
6471
|
{
|
|
@@ -6450,6 +6496,64 @@ function SConfirmModal({
|
|
|
6450
6496
|
}
|
|
6451
6497
|
);
|
|
6452
6498
|
}
|
|
6499
|
+
function SOverlayHeader({
|
|
6500
|
+
title,
|
|
6501
|
+
description,
|
|
6502
|
+
showClose = false,
|
|
6503
|
+
onClose,
|
|
6504
|
+
reserveCloseSpace = false,
|
|
6505
|
+
className,
|
|
6506
|
+
titleClassName,
|
|
6507
|
+
descriptionClassName,
|
|
6508
|
+
style
|
|
6509
|
+
}) {
|
|
6510
|
+
const hasDescription = description != null && description !== "";
|
|
6511
|
+
return /* @__PURE__ */ jsxs(
|
|
6512
|
+
"header",
|
|
6513
|
+
{
|
|
6514
|
+
className: cn(
|
|
6515
|
+
"relative flex w-full flex-shrink-0 items-center",
|
|
6516
|
+
"gap-[var(--cmp-overlay-header-gap)] bg-[var(--cmp-overlay-header-bg)] py-[var(--cmp-overlay-header-paddingY)] pl-[var(--cmp-overlay-header-paddingX)]",
|
|
6517
|
+
showClose || reserveCloseSpace ? "pr-[calc(var(--cmp-overlay-header-paddingX)+20px)]" : "pr-[var(--cmp-overlay-header-paddingX)]",
|
|
6518
|
+
className
|
|
6519
|
+
),
|
|
6520
|
+
style,
|
|
6521
|
+
children: [
|
|
6522
|
+
/* @__PURE__ */ jsx(
|
|
6523
|
+
"h2",
|
|
6524
|
+
{
|
|
6525
|
+
className: cn(
|
|
6526
|
+
"m-0 overflow-hidden text-ellipsis whitespace-nowrap",
|
|
6527
|
+
"text-[16px] font-bold leading-[26px]",
|
|
6528
|
+
titleClassName
|
|
6529
|
+
),
|
|
6530
|
+
style: { color: "var(--cmp-overlay-header-title-color)" },
|
|
6531
|
+
children: title
|
|
6532
|
+
}
|
|
6533
|
+
),
|
|
6534
|
+
hasDescription && /* @__PURE__ */ jsx(
|
|
6535
|
+
"div",
|
|
6536
|
+
{
|
|
6537
|
+
className: cn(
|
|
6538
|
+
"flex min-w-0 flex-1 items-center gap-sd-2 text-[12px] font-normal leading-[20px] text-[color:var(--color-grey-65)]",
|
|
6539
|
+
descriptionClassName
|
|
6540
|
+
),
|
|
6541
|
+
children: description
|
|
6542
|
+
}
|
|
6543
|
+
),
|
|
6544
|
+
showClose && /* @__PURE__ */ jsx(
|
|
6545
|
+
SGhostButton,
|
|
6546
|
+
{
|
|
6547
|
+
icon: "close",
|
|
6548
|
+
ariaLabel: "\uB2EB\uAE30",
|
|
6549
|
+
onClick: () => onClose?.(),
|
|
6550
|
+
className: "absolute right-[12px] top-[12px]"
|
|
6551
|
+
}
|
|
6552
|
+
)
|
|
6553
|
+
]
|
|
6554
|
+
}
|
|
6555
|
+
);
|
|
6556
|
+
}
|
|
6453
6557
|
function SActionModal({
|
|
6454
6558
|
open,
|
|
6455
6559
|
onOpenChange,
|
|
@@ -6476,35 +6580,9 @@ function SActionModal({
|
|
|
6476
6580
|
height,
|
|
6477
6581
|
className: "w-fit min-w-[min(480px,calc(100dvw-48px))] min-h-[min(320px,calc(100dvh-48px))]",
|
|
6478
6582
|
children: /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-auto flex-col", children: [
|
|
6479
|
-
/* @__PURE__ */
|
|
6480
|
-
/* @__PURE__ */ jsx("h2", { className: "whitespace-nowrap text-[16px] font-bold leading-[26px] text-[color:var(--cmp-overlay-header-title-color)]", children: modalTitle }),
|
|
6481
|
-
description != null && description !== "" && /* @__PURE__ */ jsx("div", { className: "flex min-w-0 flex-1 items-center gap-sd-2 text-[12px] font-normal leading-[20px] text-[color:var(--color-grey-65)]", children: description })
|
|
6482
|
-
] }),
|
|
6583
|
+
/* @__PURE__ */ jsx(SOverlayHeader, { title: modalTitle, description, reserveCloseSpace: true }),
|
|
6483
6584
|
/* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-auto px-[var(--cmp-modal-action-body-paddingX)] pb-[var(--cmp-modal-action-body-paddingBottom)]", children }),
|
|
6484
|
-
(button || footerLeft) && /* @__PURE__ */
|
|
6485
|
-
"footer",
|
|
6486
|
-
{
|
|
6487
|
-
className: "flex flex-shrink-0 items-center justify-end gap-[var(--cmp-modal-action-footer-gap)] border-t border-solid px-[var(--cmp-modal-action-footer-paddingX)] py-[var(--cmp-modal-action-footer-paddingY)]",
|
|
6488
|
-
style: {
|
|
6489
|
-
background: "var(--cmp-modal-action-footer-bg)",
|
|
6490
|
-
borderTopColor: "var(--cmp-modal-action-footer-border)"
|
|
6491
|
-
},
|
|
6492
|
-
children: [
|
|
6493
|
-
/* @__PURE__ */ jsx("div", { className: "flex min-w-0 flex-1 items-center gap-sd-2", children: footerLeft }),
|
|
6494
|
-
button && /* @__PURE__ */ jsx(
|
|
6495
|
-
SButton,
|
|
6496
|
-
{
|
|
6497
|
-
color: button.color ?? "primary",
|
|
6498
|
-
outline: button.outline,
|
|
6499
|
-
size: button.size ?? "md",
|
|
6500
|
-
disabled: button.disabled,
|
|
6501
|
-
onClick: () => button.onClick?.(),
|
|
6502
|
-
label: button.label ?? "\uD655\uC778"
|
|
6503
|
-
}
|
|
6504
|
-
)
|
|
6505
|
-
]
|
|
6506
|
-
}
|
|
6507
|
-
)
|
|
6585
|
+
(button || footerLeft) && /* @__PURE__ */ jsx(SFooter, { bg: "grey", left: footerLeft, button })
|
|
6508
6586
|
] })
|
|
6509
6587
|
}
|
|
6510
6588
|
);
|
|
@@ -6573,13 +6651,43 @@ function SLoadingModal({
|
|
|
6573
6651
|
);
|
|
6574
6652
|
}
|
|
6575
6653
|
var CLOSE_ANIMATION_DURATION2 = 300;
|
|
6654
|
+
function toPx(value, percentBase) {
|
|
6655
|
+
if (typeof value === "number") return value;
|
|
6656
|
+
if (typeof value !== "string") return void 0;
|
|
6657
|
+
const normalized = value.trim();
|
|
6658
|
+
if (normalized.endsWith("px")) {
|
|
6659
|
+
const numeric = Number(normalized.slice(0, -2));
|
|
6660
|
+
return Number.isFinite(numeric) ? numeric : void 0;
|
|
6661
|
+
}
|
|
6662
|
+
if (normalized.endsWith("%")) {
|
|
6663
|
+
const numeric = Number(normalized.slice(0, -1));
|
|
6664
|
+
return Number.isFinite(numeric) ? percentBase * numeric / 100 : void 0;
|
|
6665
|
+
}
|
|
6666
|
+
if (normalized.endsWith("vw")) {
|
|
6667
|
+
const numeric = Number(normalized.slice(0, -2));
|
|
6668
|
+
return Number.isFinite(numeric) ? window.innerWidth * numeric / 100 : void 0;
|
|
6669
|
+
}
|
|
6670
|
+
if (normalized.endsWith("vh")) {
|
|
6671
|
+
const numeric = Number(normalized.slice(0, -2));
|
|
6672
|
+
return Number.isFinite(numeric) ? window.innerHeight * numeric / 100 : void 0;
|
|
6673
|
+
}
|
|
6674
|
+
return void 0;
|
|
6675
|
+
}
|
|
6676
|
+
function clamp3(value, min, max) {
|
|
6677
|
+
const minValue = min ?? Number.NEGATIVE_INFINITY;
|
|
6678
|
+
const maxValue = max ?? Number.POSITIVE_INFINITY;
|
|
6679
|
+
return Math.min(Math.max(value, minValue), maxValue);
|
|
6680
|
+
}
|
|
6576
6681
|
function SDrawer({
|
|
6577
6682
|
open,
|
|
6578
6683
|
onOpenChange,
|
|
6579
6684
|
onClose,
|
|
6580
|
-
persistent =
|
|
6685
|
+
persistent = true,
|
|
6581
6686
|
title = "",
|
|
6582
6687
|
width = 572,
|
|
6688
|
+
resizable = false,
|
|
6689
|
+
minWidth,
|
|
6690
|
+
maxWidth,
|
|
6583
6691
|
footerLeft,
|
|
6584
6692
|
button,
|
|
6585
6693
|
children,
|
|
@@ -6593,7 +6701,13 @@ function SDrawer({
|
|
|
6593
6701
|
const backdropPointerDownRef = useRef(false);
|
|
6594
6702
|
const contentRef = useRef(null);
|
|
6595
6703
|
const stackRegistrationRef = useRef(null);
|
|
6704
|
+
const resizeCleanupRef = useRef(null);
|
|
6705
|
+
const resizeStateRef = useRef(null);
|
|
6596
6706
|
const [layerIndex, setLayerIndex] = useState(null);
|
|
6707
|
+
const [currentWidth, setCurrentWidth] = useState(width);
|
|
6708
|
+
useEffect(() => {
|
|
6709
|
+
setCurrentWidth(width);
|
|
6710
|
+
}, [width]);
|
|
6597
6711
|
useEffect(() => {
|
|
6598
6712
|
if (open) {
|
|
6599
6713
|
setRendered(true);
|
|
@@ -6603,6 +6717,9 @@ function SDrawer({
|
|
|
6603
6717
|
const timer = window.setTimeout(() => setRendered(false), CLOSE_ANIMATION_DURATION2);
|
|
6604
6718
|
return () => window.clearTimeout(timer);
|
|
6605
6719
|
}, [open, rendered]);
|
|
6720
|
+
useEffect(() => {
|
|
6721
|
+
return () => resizeCleanupRef.current?.();
|
|
6722
|
+
}, []);
|
|
6606
6723
|
useEffect(() => {
|
|
6607
6724
|
if (!open) {
|
|
6608
6725
|
setEntered(false);
|
|
@@ -6630,6 +6747,13 @@ function SDrawer({
|
|
|
6630
6747
|
event.preventDefault();
|
|
6631
6748
|
if (stackRegistrationRef.current?.isTop()) triggerShake();
|
|
6632
6749
|
} : void 0;
|
|
6750
|
+
const guardInteractOutside = (e) => {
|
|
6751
|
+
if (isFromGlobalOverlay(e)) {
|
|
6752
|
+
e.preventDefault();
|
|
6753
|
+
return;
|
|
6754
|
+
}
|
|
6755
|
+
guardClose?.(e);
|
|
6756
|
+
};
|
|
6633
6757
|
const handleBackdropInteraction = () => {
|
|
6634
6758
|
if (persistent) {
|
|
6635
6759
|
if (stackRegistrationRef.current?.isTop()) triggerShake();
|
|
@@ -6637,6 +6761,40 @@ function SDrawer({
|
|
|
6637
6761
|
}
|
|
6638
6762
|
onOpenChange?.(false);
|
|
6639
6763
|
};
|
|
6764
|
+
const handleResizeStart = (event) => {
|
|
6765
|
+
event.preventDefault();
|
|
6766
|
+
event.stopPropagation();
|
|
6767
|
+
const panel = contentRef.current?.querySelector("[data-s-drawer-panel]");
|
|
6768
|
+
if (!panel) return;
|
|
6769
|
+
resizeStateRef.current = {
|
|
6770
|
+
startX: event.clientX,
|
|
6771
|
+
startWidth: panel.getBoundingClientRect().width,
|
|
6772
|
+
minWidth: toPx(minWidth, window.innerWidth),
|
|
6773
|
+
maxWidth: toPx(maxWidth, window.innerWidth)
|
|
6774
|
+
};
|
|
6775
|
+
const onMove = (moveEvent) => {
|
|
6776
|
+
const resizeState = resizeStateRef.current;
|
|
6777
|
+
if (!resizeState) return;
|
|
6778
|
+
const nextWidth = resizeState.startWidth + resizeState.startX - moveEvent.clientX;
|
|
6779
|
+
setCurrentWidth(clamp3(nextWidth, resizeState.minWidth, resizeState.maxWidth));
|
|
6780
|
+
};
|
|
6781
|
+
resizeCleanupRef.current?.();
|
|
6782
|
+
const previousCursor = document.body.style.cursor;
|
|
6783
|
+
const previousUserSelect = document.body.style.userSelect;
|
|
6784
|
+
const cleanupResize = () => {
|
|
6785
|
+
resizeStateRef.current = null;
|
|
6786
|
+
document.body.style.cursor = previousCursor;
|
|
6787
|
+
document.body.style.userSelect = previousUserSelect;
|
|
6788
|
+
document.removeEventListener("mousemove", onMove);
|
|
6789
|
+
document.removeEventListener("mouseup", cleanupResize);
|
|
6790
|
+
resizeCleanupRef.current = null;
|
|
6791
|
+
};
|
|
6792
|
+
resizeCleanupRef.current = cleanupResize;
|
|
6793
|
+
document.body.style.cursor = "col-resize";
|
|
6794
|
+
document.body.style.userSelect = "none";
|
|
6795
|
+
document.addEventListener("mousemove", onMove);
|
|
6796
|
+
document.addEventListener("mouseup", cleanupResize);
|
|
6797
|
+
};
|
|
6640
6798
|
const modalHost = getModalHost();
|
|
6641
6799
|
return /* @__PURE__ */ jsx(RDialog.Root, { open, onOpenChange, children: /* @__PURE__ */ jsx(RDialog.Portal, { container: modalHost, forceMount: rendered ? true : void 0, children: /* @__PURE__ */ jsxs("div", { className: "pointer-events-none absolute inset-0", style: { zIndex: layerIndex ?? 0 }, children: [
|
|
6642
6800
|
/* @__PURE__ */ jsx(
|
|
@@ -6666,14 +6824,14 @@ function SDrawer({
|
|
|
6666
6824
|
{
|
|
6667
6825
|
forceMount: rendered ? true : void 0,
|
|
6668
6826
|
ref: contentRef,
|
|
6669
|
-
className: "pointer-events-
|
|
6827
|
+
className: "pointer-events-none absolute inset-y-0 right-0 flex w-fit max-w-full justify-end outline-none",
|
|
6670
6828
|
onOpenAutoFocus: (event) => {
|
|
6671
6829
|
event.preventDefault();
|
|
6672
6830
|
contentRef.current?.focus({ preventScroll: true });
|
|
6673
6831
|
},
|
|
6674
6832
|
onEscapeKeyDown: guardClose,
|
|
6675
|
-
onPointerDownOutside:
|
|
6676
|
-
onInteractOutside:
|
|
6833
|
+
onPointerDownOutside: guardInteractOutside,
|
|
6834
|
+
onInteractOutside: guardInteractOutside,
|
|
6677
6835
|
children: [
|
|
6678
6836
|
/* @__PURE__ */ jsx(RDialog.Title, { className: "sr-only", children: title || "Drawer" }),
|
|
6679
6837
|
/* @__PURE__ */ jsxs(
|
|
@@ -6684,42 +6842,35 @@ function SDrawer({
|
|
|
6684
6842
|
shaking && "animate-drawer-shake",
|
|
6685
6843
|
className
|
|
6686
6844
|
),
|
|
6845
|
+
"data-s-drawer-panel": true,
|
|
6687
6846
|
"data-state": open && entered ? "open" : "closed",
|
|
6688
|
-
style: { width, ...style },
|
|
6847
|
+
style: { width: currentWidth, minWidth, maxWidth, ...style },
|
|
6689
6848
|
onAnimationEnd: (event) => {
|
|
6690
6849
|
if (event.animationName === "drawer-shake") setShaking(false);
|
|
6691
6850
|
},
|
|
6692
6851
|
children: [
|
|
6693
|
-
/* @__PURE__ */
|
|
6694
|
-
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
|
|
6698
|
-
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6852
|
+
resizable && /* @__PURE__ */ jsx(
|
|
6853
|
+
"button",
|
|
6854
|
+
{
|
|
6855
|
+
type: "button",
|
|
6856
|
+
"aria-label": "Drawer \uB108\uBE44 \uC870\uC808",
|
|
6857
|
+
className: "absolute inset-y-0 left-0 z-[1] w-[8px] -translate-x-1/2 cursor-col-resize touch-none border-0 bg-transparent p-0",
|
|
6858
|
+
onMouseDown: handleResizeStart
|
|
6859
|
+
}
|
|
6860
|
+
),
|
|
6861
|
+
/* @__PURE__ */ jsx(
|
|
6862
|
+
SOverlayHeader,
|
|
6863
|
+
{
|
|
6864
|
+
title,
|
|
6865
|
+
showClose: true,
|
|
6866
|
+
onClose: () => {
|
|
6867
|
+
onClose?.();
|
|
6868
|
+
onOpenChange?.(false);
|
|
6705
6869
|
}
|
|
6706
|
-
|
|
6707
|
-
|
|
6870
|
+
}
|
|
6871
|
+
),
|
|
6708
6872
|
/* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-auto border-t border-solid border-[color:var(--cmp-drawer-body-border)]", children: /* @__PURE__ */ jsx(InsideModalProvider, { value: true, children: /* @__PURE__ */ jsx(PortalContainerProvider, { value: portalContainer, children }) }) }),
|
|
6709
|
-
(button || footerLeft) && /* @__PURE__ */
|
|
6710
|
-
/* @__PURE__ */ jsx("div", { className: "flex min-w-0 flex-1 items-center justify-between", children: footerLeft }),
|
|
6711
|
-
button && /* @__PURE__ */ jsx(
|
|
6712
|
-
SButton,
|
|
6713
|
-
{
|
|
6714
|
-
color: button.color ?? "primary",
|
|
6715
|
-
outline: button.outline,
|
|
6716
|
-
size: button.size ?? "md",
|
|
6717
|
-
disabled: button.disabled,
|
|
6718
|
-
onClick: () => button.onClick?.(),
|
|
6719
|
-
label: button.label ?? "\uD655\uC778"
|
|
6720
|
-
}
|
|
6721
|
-
)
|
|
6722
|
-
] })
|
|
6873
|
+
(button || footerLeft) && /* @__PURE__ */ jsx(SFooter, { left: footerLeft, leftClassName: "justify-between", button })
|
|
6723
6874
|
]
|
|
6724
6875
|
}
|
|
6725
6876
|
),
|
|
@@ -6974,6 +7125,80 @@ var SModal = {
|
|
|
6974
7125
|
return mount((refImpl) => /* @__PURE__ */ jsx(CreateMount, { options, refImpl }));
|
|
6975
7126
|
}
|
|
6976
7127
|
};
|
|
7128
|
+
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
|
7129
|
+
var isSameNav = (a, b) => a === b || !!a && !!b && a.columnWidth === b.columnWidth && a.topHeight === b.topHeight && a.foldMs === b.foldMs && a.requireFullHeader === b.requireFullHeader;
|
|
7130
|
+
var SLayoutContext = /* @__PURE__ */ createContext(null);
|
|
7131
|
+
function useSLayout() {
|
|
7132
|
+
const ctx = useContext(SLayoutContext);
|
|
7133
|
+
if (!ctx) throw new Error("useSLayout \uC740 <SLayout> \uC548\uC5D0\uC11C\uB9CC \uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.");
|
|
7134
|
+
return ctx;
|
|
7135
|
+
}
|
|
7136
|
+
var SLayout = /* @__PURE__ */ forwardRef(function SLayout2({
|
|
7137
|
+
type = "box",
|
|
7138
|
+
header = "fix",
|
|
7139
|
+
useRail = false,
|
|
7140
|
+
folded,
|
|
7141
|
+
defaultFolded = false,
|
|
7142
|
+
onFoldedChange,
|
|
7143
|
+
className,
|
|
7144
|
+
style,
|
|
7145
|
+
children,
|
|
7146
|
+
...rest
|
|
7147
|
+
}, ref) {
|
|
7148
|
+
const [uncontrolledFolded, setUncontrolledFolded] = useState(defaultFolded);
|
|
7149
|
+
const isControlled = folded !== void 0;
|
|
7150
|
+
const currentFolded = isControlled ? folded : uncontrolledFolded;
|
|
7151
|
+
const setFolded = useCallback(
|
|
7152
|
+
(next) => {
|
|
7153
|
+
if (!isControlled) setUncontrolledFolded(next);
|
|
7154
|
+
onFoldedChange?.(next);
|
|
7155
|
+
},
|
|
7156
|
+
[isControlled, onFoldedChange]
|
|
7157
|
+
);
|
|
7158
|
+
const [nav, setNav] = useState(null);
|
|
7159
|
+
const registerNav = useCallback(
|
|
7160
|
+
(next) => setNav((prev) => isSameNav(prev, next) ? prev : next),
|
|
7161
|
+
[]
|
|
7162
|
+
);
|
|
7163
|
+
const effectiveHeader = header === "full" || nav?.requireFullHeader ? "full" : "fix";
|
|
7164
|
+
const ctx = useMemo(
|
|
7165
|
+
() => ({
|
|
7166
|
+
type,
|
|
7167
|
+
header: effectiveHeader,
|
|
7168
|
+
useRail,
|
|
7169
|
+
folded: currentFolded,
|
|
7170
|
+
setFolded,
|
|
7171
|
+
registerNav
|
|
7172
|
+
}),
|
|
7173
|
+
[type, effectiveHeader, useRail, currentFolded, setFolded, registerNav]
|
|
7174
|
+
);
|
|
7175
|
+
const isFullHeader = effectiveHeader === "full";
|
|
7176
|
+
const frameStyle = isFullHeader ? {
|
|
7177
|
+
// 자식이 좌표가 아니라 이름으로 자리를 잡게 한다 — 열·행이 늘어도 자식을 고칠 일이 없다.
|
|
7178
|
+
gridTemplateAreas: '"header header" "nav page"',
|
|
7179
|
+
gridTemplateColumns: `${currentFolded ? 0 : nav?.columnWidth ?? 0}px 1fr`,
|
|
7180
|
+
gridTemplateRows: `${nav?.topHeight ?? "0px"} 1fr`,
|
|
7181
|
+
// 메뉴가 미끄러지는 동안 페이지 열도 같은 길이로 따라와야 한 덩어리로 읽힌다.
|
|
7182
|
+
// (fix 는 SGnb 가 제 폭을 직접 전환하므로 프레임이 손댈 게 없다)
|
|
7183
|
+
transition: `grid-template-columns ${nav?.foldMs ?? 0}ms ease-out`
|
|
7184
|
+
} : void 0;
|
|
7185
|
+
return /* @__PURE__ */ jsx(SLayoutContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx(
|
|
7186
|
+
"div",
|
|
7187
|
+
{
|
|
7188
|
+
ref,
|
|
7189
|
+
"data-type": type,
|
|
7190
|
+
"data-header": effectiveHeader,
|
|
7191
|
+
className: cn(
|
|
7192
|
+
"box-border h-full overflow-hidden",
|
|
7193
|
+
isFullHeader ? "grid" : "flex flex-row",
|
|
7194
|
+
className
|
|
7195
|
+
),
|
|
7196
|
+
style: { ...frameStyle, ...style },
|
|
7197
|
+
...rest,
|
|
7198
|
+
children
|
|
7199
|
+
}
|
|
7200
|
+
) });
|
|
7201
|
+
});
|
|
6977
7202
|
|
|
6978
7203
|
// src/components/SGnb/gnb.config.ts
|
|
6979
7204
|
var gnb = (p) => `var(--cmp-gnb-${p})`;
|
|
@@ -7106,6 +7331,21 @@ function findGnbRailValue(items, value) {
|
|
|
7106
7331
|
if (items.some((item) => item.value === value)) return value;
|
|
7107
7332
|
return findGnbAncestors(items, value)[0];
|
|
7108
7333
|
}
|
|
7334
|
+
function findGnbSiblingValues(items, value) {
|
|
7335
|
+
const walk = (list) => {
|
|
7336
|
+
if (list.some((item) => item.value === value)) {
|
|
7337
|
+
return list.filter((item) => item.value !== value).map((item) => item.value);
|
|
7338
|
+
}
|
|
7339
|
+
for (const item of list) {
|
|
7340
|
+
if (item.children) {
|
|
7341
|
+
const found = walk(item.children);
|
|
7342
|
+
if (found) return found;
|
|
7343
|
+
}
|
|
7344
|
+
}
|
|
7345
|
+
return null;
|
|
7346
|
+
};
|
|
7347
|
+
return walk(items) ?? [];
|
|
7348
|
+
}
|
|
7109
7349
|
function findGnbAncestors(items, value) {
|
|
7110
7350
|
const walk = (list, trail) => {
|
|
7111
7351
|
for (const item of list) {
|
|
@@ -7119,79 +7359,6 @@ function findGnbAncestors(items, value) {
|
|
|
7119
7359
|
};
|
|
7120
7360
|
return walk(items, []) ?? [];
|
|
7121
7361
|
}
|
|
7122
|
-
var SLayoutContext = /* @__PURE__ */ createContext(null);
|
|
7123
|
-
function useSLayout() {
|
|
7124
|
-
const ctx = useContext(SLayoutContext);
|
|
7125
|
-
if (!ctx) throw new Error("useSLayout \uC740 <SLayout> \uC548\uC5D0\uC11C\uB9CC \uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.");
|
|
7126
|
-
return ctx;
|
|
7127
|
-
}
|
|
7128
|
-
var SLayout = /* @__PURE__ */ forwardRef(function SLayout2({
|
|
7129
|
-
type = "box",
|
|
7130
|
-
header = "fix",
|
|
7131
|
-
useRail = false,
|
|
7132
|
-
folded,
|
|
7133
|
-
defaultFolded = false,
|
|
7134
|
-
onFoldedChange,
|
|
7135
|
-
className,
|
|
7136
|
-
style,
|
|
7137
|
-
children,
|
|
7138
|
-
...rest
|
|
7139
|
-
}, ref) {
|
|
7140
|
-
const [uncontrolledFolded, setUncontrolledFolded] = useState(defaultFolded);
|
|
7141
|
-
const isControlled = folded !== void 0;
|
|
7142
|
-
const currentFolded = isControlled ? folded : uncontrolledFolded;
|
|
7143
|
-
const setFolded = useCallback(
|
|
7144
|
-
(next) => {
|
|
7145
|
-
if (!isControlled) setUncontrolledFolded(next);
|
|
7146
|
-
onFoldedChange?.(next);
|
|
7147
|
-
},
|
|
7148
|
-
[isControlled, onFoldedChange]
|
|
7149
|
-
);
|
|
7150
|
-
const [gnbState, setGnbState] = useState({ forceFull: false, menuVisible: true });
|
|
7151
|
-
const reportGnbState = useCallback(
|
|
7152
|
-
(next) => setGnbState(
|
|
7153
|
-
(prev) => prev.forceFull === next.forceFull && prev.menuVisible === next.menuVisible ? prev : next
|
|
7154
|
-
),
|
|
7155
|
-
[]
|
|
7156
|
-
);
|
|
7157
|
-
const effectiveHeader = header === "full" || gnbState.forceFull ? "full" : "fix";
|
|
7158
|
-
const ctx = useMemo(
|
|
7159
|
-
() => ({
|
|
7160
|
-
type,
|
|
7161
|
-
header: effectiveHeader,
|
|
7162
|
-
useRail,
|
|
7163
|
-
folded: currentFolded,
|
|
7164
|
-
setFolded,
|
|
7165
|
-
reportGnbState
|
|
7166
|
-
}),
|
|
7167
|
-
[type, effectiveHeader, useRail, currentFolded, setFolded, reportGnbState]
|
|
7168
|
-
);
|
|
7169
|
-
const isFullHeader = effectiveHeader === "full";
|
|
7170
|
-
const gnbColumnWidth = (useRail ? GNB_RAIL_WIDTH : 0) + (gnbState.menuVisible ? GNB_MENU_WIDTH : 0);
|
|
7171
|
-
const frameStyle = isFullHeader ? {
|
|
7172
|
-
gridTemplateColumns: `${currentFolded ? 0 : gnbColumnWidth}px 1fr`,
|
|
7173
|
-
gridTemplateRows: `${GNB_HEADER[effectiveHeader].topHeight} 1fr`,
|
|
7174
|
-
// 메뉴가 미끄러지는 동안 페이지 열도 같은 길이로 따라와야 한 덩어리로 읽힌다.
|
|
7175
|
-
// (fix 는 SGnb 가 제 폭을 직접 전환하므로 프레임이 손댈 게 없다)
|
|
7176
|
-
transition: `grid-template-columns ${GNB_FOLD_MS}ms ease-out`
|
|
7177
|
-
} : void 0;
|
|
7178
|
-
return /* @__PURE__ */ jsx(SLayoutContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx(
|
|
7179
|
-
"div",
|
|
7180
|
-
{
|
|
7181
|
-
ref,
|
|
7182
|
-
"data-type": type,
|
|
7183
|
-
"data-header": effectiveHeader,
|
|
7184
|
-
className: cn(
|
|
7185
|
-
"box-border h-full overflow-hidden",
|
|
7186
|
-
isFullHeader ? "grid" : "flex flex-row",
|
|
7187
|
-
className
|
|
7188
|
-
),
|
|
7189
|
-
style: { ...frameStyle, ...style },
|
|
7190
|
-
...rest,
|
|
7191
|
-
children
|
|
7192
|
-
}
|
|
7193
|
-
) });
|
|
7194
|
-
});
|
|
7195
7362
|
var DEPTH_PADDING_LEFT = (M, depth) => depth === 1 ? M.depth1PaddingLeft : depth === 2 ? M.depth2PaddingLeft : M.depth3PaddingLeft;
|
|
7196
7363
|
var SGnb = /* @__PURE__ */ forwardRef(function SGnb2({
|
|
7197
7364
|
type: typeProp,
|
|
@@ -7253,8 +7420,12 @@ var SGnb = /* @__PURE__ */ forwardRef(function SGnb2({
|
|
|
7253
7420
|
const toggleExpand = (key) => {
|
|
7254
7421
|
setExpandedKeys((prev) => {
|
|
7255
7422
|
const next = new Set(prev);
|
|
7256
|
-
if (next.has(key))
|
|
7257
|
-
|
|
7423
|
+
if (next.has(key)) {
|
|
7424
|
+
next.delete(key);
|
|
7425
|
+
} else {
|
|
7426
|
+
findGnbSiblingValues(items, key).forEach((sibling) => next.delete(sibling));
|
|
7427
|
+
next.add(key);
|
|
7428
|
+
}
|
|
7258
7429
|
return next;
|
|
7259
7430
|
});
|
|
7260
7431
|
};
|
|
@@ -7425,16 +7596,30 @@ var SGnb = /* @__PURE__ */ forwardRef(function SGnb2({
|
|
|
7425
7596
|
const menuItems = useRail ? items.find((item) => item.value === activeRail)?.children ?? [] : items;
|
|
7426
7597
|
const showMenu = !useRail || menuItems.length > 0;
|
|
7427
7598
|
const bodyWidth = (useRail ? GNB_RAIL_WIDTH : 0) + (showMenu ? GNB_MENU_WIDTH : 0);
|
|
7428
|
-
|
|
7429
|
-
|
|
7430
|
-
|
|
7599
|
+
const registerNav = layout?.registerNav;
|
|
7600
|
+
useIsomorphicLayoutEffect(() => {
|
|
7601
|
+
if (!registerNav) return;
|
|
7602
|
+
registerNav({
|
|
7603
|
+
columnWidth: bodyWidth,
|
|
7604
|
+
topHeight: H.topHeight,
|
|
7605
|
+
foldMs: GNB_FOLD_MS,
|
|
7606
|
+
requireFullHeader: railHasLeaf
|
|
7607
|
+
});
|
|
7608
|
+
return () => registerNav(null);
|
|
7609
|
+
}, [registerNav, bodyWidth, H.topHeight, railHasLeaf]);
|
|
7431
7610
|
const railFolded = folded && header === "fix";
|
|
7432
|
-
const
|
|
7611
|
+
const isFull = header === "full";
|
|
7612
|
+
const isFullFrame = isFull && !!layout;
|
|
7433
7613
|
const rightBorder = color === "light" ? `1px solid ${C.topBorder}` : void 0;
|
|
7434
|
-
const rootStyle = {
|
|
7435
|
-
|
|
7614
|
+
const rootStyle = isFullFrame ? { display: "contents", ...style } : isFull ? (
|
|
7615
|
+
// 단독 full — 상단바가 전폭이어야 하므로 루트도 전폭이고, 배경·선은 상단바·메뉴가 각자 그린다.
|
|
7616
|
+
{ width: "100%", ...style }
|
|
7617
|
+
) : {
|
|
7618
|
+
// fix 를 닫으면 48px 레일로 좁혀진다.
|
|
7619
|
+
width: folded ? GNB_COMMON.foldWidth : bodyWidth,
|
|
7436
7620
|
transition: `width ${GNB_FOLD_MS}ms ease-out`,
|
|
7437
|
-
|
|
7621
|
+
backgroundColor: C.panelBg,
|
|
7622
|
+
borderRight: rightBorder,
|
|
7438
7623
|
...style
|
|
7439
7624
|
};
|
|
7440
7625
|
const hideAfterSlide = (hidden) => `visibility 0s linear ${hidden ? `${GNB_FOLD_MS}ms` : "0s"}`;
|
|
@@ -7507,7 +7692,11 @@ var SGnb = /* @__PURE__ */ forwardRef(function SGnb2({
|
|
|
7507
7692
|
"div",
|
|
7508
7693
|
{
|
|
7509
7694
|
ref,
|
|
7510
|
-
className: cn(
|
|
7695
|
+
className: cn(
|
|
7696
|
+
"box-border",
|
|
7697
|
+
!isFullFrame && "flex h-full shrink-0 flex-col overflow-hidden",
|
|
7698
|
+
className
|
|
7699
|
+
),
|
|
7511
7700
|
style: rootStyle,
|
|
7512
7701
|
"data-type": type,
|
|
7513
7702
|
"data-header": header,
|
|
@@ -7519,6 +7708,7 @@ var SGnb = /* @__PURE__ */ forwardRef(function SGnb2({
|
|
|
7519
7708
|
{
|
|
7520
7709
|
className: "relative box-border flex shrink-0 items-center overflow-hidden",
|
|
7521
7710
|
style: {
|
|
7711
|
+
...isFullFrame ? { gridArea: "header" } : null,
|
|
7522
7712
|
height: H.topHeight,
|
|
7523
7713
|
// 간격은 컨테이너 gap 대신 각 요소 margin 으로 준다 — 순서가 header 마다 달라
|
|
7524
7714
|
// 이웃 쌍마다 값이 다르기 때문(위 launcherButton/logoBox 주석).
|
|
@@ -7526,7 +7716,6 @@ var SGnb = /* @__PURE__ */ forwardRef(function SGnb2({
|
|
|
7526
7716
|
padding: `0 ${railFolded ? GNB_RAIL.padding : H.topPaddingX}`,
|
|
7527
7717
|
borderBottom: `1px solid ${C.topBorder}`,
|
|
7528
7718
|
backgroundColor: C.panelBg,
|
|
7529
|
-
pointerEvents: "auto",
|
|
7530
7719
|
transition: `padding ${GNB_FOLD_MS}ms ease-out`,
|
|
7531
7720
|
// 아이콘 버튼은 자체 ghostButton 토큰을 쓰므로, 이 색은 logo 슬롯 상속용
|
|
7532
7721
|
color: C.itemColorDefault
|
|
@@ -7543,94 +7732,87 @@ var SGnb = /* @__PURE__ */ forwardRef(function SGnb2({
|
|
|
7543
7732
|
] })
|
|
7544
7733
|
}
|
|
7545
7734
|
),
|
|
7546
|
-
/* @__PURE__ */
|
|
7735
|
+
/* @__PURE__ */ jsx(
|
|
7547
7736
|
"div",
|
|
7548
7737
|
{
|
|
7549
|
-
className: "
|
|
7550
|
-
style: {
|
|
7551
|
-
|
|
7552
|
-
|
|
7553
|
-
|
|
7554
|
-
|
|
7555
|
-
|
|
7556
|
-
|
|
7557
|
-
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
|
|
7561
|
-
|
|
7562
|
-
|
|
7563
|
-
|
|
7564
|
-
|
|
7565
|
-
|
|
7566
|
-
|
|
7567
|
-
|
|
7568
|
-
|
|
7569
|
-
|
|
7570
|
-
|
|
7571
|
-
|
|
7572
|
-
|
|
7573
|
-
|
|
7574
|
-
|
|
7575
|
-
|
|
7576
|
-
|
|
7577
|
-
|
|
7578
|
-
|
|
7579
|
-
|
|
7580
|
-
|
|
7581
|
-
|
|
7582
|
-
|
|
7738
|
+
className: cn("overflow-hidden", !isFullFrame && "min-h-0 flex-1"),
|
|
7739
|
+
style: isFullFrame ? { gridArea: "nav" } : void 0,
|
|
7740
|
+
children: /* @__PURE__ */ jsxs(
|
|
7741
|
+
"div",
|
|
7742
|
+
{
|
|
7743
|
+
className: "flex h-full flex-row",
|
|
7744
|
+
style: {
|
|
7745
|
+
width: bodyWidth,
|
|
7746
|
+
transform: folded ? "translateX(-100%)" : "none",
|
|
7747
|
+
visibility: folded ? "hidden" : "visible",
|
|
7748
|
+
transition: `transform ${GNB_FOLD_MS}ms ease-out, ${hideAfterSlide(folded)}`
|
|
7749
|
+
},
|
|
7750
|
+
children: [
|
|
7751
|
+
useRail && // 레일 컬럼 — 스크롤되는 아이템 목록(nav)과 하단 고정 footer 를 한 컬럼에 담는다.
|
|
7752
|
+
// footer 는 내비게이션이 아니므로 nav(landmark) 밖에 두고, 컬럼 폭·구분선·배경은 이 래퍼가
|
|
7753
|
+
// 전체 높이에 걸쳐 책임진다(그래야 footer 자리까지 배경·오른쪽 선이 이어진다).
|
|
7754
|
+
/* @__PURE__ */ jsxs(
|
|
7755
|
+
"div",
|
|
7756
|
+
{
|
|
7757
|
+
className: "flex shrink-0 flex-col overflow-hidden",
|
|
7758
|
+
style: {
|
|
7759
|
+
width: GNB_RAIL_WIDTH,
|
|
7760
|
+
borderRight: `1px solid ${C.topBorder}`,
|
|
7761
|
+
backgroundColor: C.panelBg
|
|
7762
|
+
},
|
|
7763
|
+
children: [
|
|
7764
|
+
/* @__PURE__ */ jsx(
|
|
7765
|
+
"nav",
|
|
7766
|
+
{
|
|
7767
|
+
"aria-label": `${ariaLabel} rail`,
|
|
7768
|
+
className: cn(
|
|
7769
|
+
"flex min-h-0 flex-1 flex-col overflow-x-hidden overflow-y-auto",
|
|
7770
|
+
SCROLLBAR_HIDDEN_CLASS
|
|
7771
|
+
),
|
|
7772
|
+
style: { padding: GNB_RAIL.padding },
|
|
7773
|
+
children: /* @__PURE__ */ jsx("ul", { className: "m-0 flex list-none flex-col p-0", style: { gap: GNB_RAIL.gap }, children: railItems.map(renderRailItem) })
|
|
7774
|
+
}
|
|
7583
7775
|
),
|
|
7584
|
-
|
|
7585
|
-
|
|
7586
|
-
|
|
7587
|
-
|
|
7588
|
-
|
|
7589
|
-
|
|
7590
|
-
|
|
7591
|
-
|
|
7592
|
-
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
|
|
7599
|
-
|
|
7600
|
-
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
|
|
7604
|
-
|
|
7605
|
-
|
|
7606
|
-
|
|
7607
|
-
|
|
7608
|
-
|
|
7609
|
-
|
|
7610
|
-
|
|
7776
|
+
railFooter && /* @__PURE__ */ jsx("div", { className: "shrink-0", children: railFooter })
|
|
7777
|
+
]
|
|
7778
|
+
}
|
|
7779
|
+
),
|
|
7780
|
+
showMenu && /* @__PURE__ */ jsxs(
|
|
7781
|
+
"div",
|
|
7782
|
+
{
|
|
7783
|
+
className: "flex shrink-0 flex-col overflow-hidden",
|
|
7784
|
+
style: {
|
|
7785
|
+
width: GNB_MENU_WIDTH,
|
|
7786
|
+
backgroundColor: C.panelBg,
|
|
7787
|
+
// full 은 루트가 오른쪽 선을 못 그리므로(전폭이거나 아예 없다) 메뉴 오른쪽(페이지 경계)이 대신 그린다.
|
|
7788
|
+
borderRight: isFull ? rightBorder : void 0
|
|
7789
|
+
},
|
|
7790
|
+
children: [
|
|
7791
|
+
/* @__PURE__ */ jsx(
|
|
7792
|
+
"nav",
|
|
7793
|
+
{
|
|
7794
|
+
"aria-label": ariaLabel,
|
|
7795
|
+
className: cn(
|
|
7796
|
+
"flex min-h-0 flex-1 flex-col overflow-x-hidden overflow-y-auto",
|
|
7797
|
+
SCROLLBAR_HIDDEN_CLASS
|
|
7798
|
+
),
|
|
7799
|
+
style: {
|
|
7800
|
+
paddingTop: M.bodyPaddingY,
|
|
7801
|
+
paddingBottom: M.bodyPaddingY
|
|
7802
|
+
},
|
|
7803
|
+
children: /* @__PURE__ */ jsx("ul", { className: "m-0 flex list-none flex-col p-0", children: menuItems.map((item) => renderItem(item, 1)) })
|
|
7804
|
+
}
|
|
7611
7805
|
),
|
|
7612
|
-
|
|
7613
|
-
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
menuFooter && /* @__PURE__ */ jsx("div", { className: "shrink-0", children: menuFooter })
|
|
7620
|
-
]
|
|
7621
|
-
}
|
|
7622
|
-
)
|
|
7623
|
-
]
|
|
7806
|
+
menuFooter && /* @__PURE__ */ jsx("div", { className: "shrink-0", children: menuFooter })
|
|
7807
|
+
]
|
|
7808
|
+
}
|
|
7809
|
+
)
|
|
7810
|
+
]
|
|
7811
|
+
}
|
|
7812
|
+
)
|
|
7624
7813
|
}
|
|
7625
7814
|
),
|
|
7626
|
-
railFolded && foldedFooter && /* @__PURE__ */ jsx(
|
|
7627
|
-
"div",
|
|
7628
|
-
{
|
|
7629
|
-
className: "flex shrink-0 items-center justify-center mb-[24px]",
|
|
7630
|
-
style: { pointerEvents: "auto" },
|
|
7631
|
-
children: foldedFooter
|
|
7632
|
-
}
|
|
7633
|
-
)
|
|
7815
|
+
railFolded && foldedFooter && /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center justify-center mb-[24px]", children: foldedFooter })
|
|
7634
7816
|
]
|
|
7635
7817
|
}
|
|
7636
7818
|
);
|
|
@@ -7642,7 +7824,7 @@ var BACKGROUND_CLASS = {
|
|
|
7642
7824
|
};
|
|
7643
7825
|
var SPage = /* @__PURE__ */ forwardRef(function SPage2({ background = "frame", className, style, children, ...rest }, ref) {
|
|
7644
7826
|
const layout = useContext(SLayoutContext);
|
|
7645
|
-
const gridStyle = layout?.header === "full" ? {
|
|
7827
|
+
const gridStyle = layout?.header === "full" ? { gridArea: "page" } : void 0;
|
|
7646
7828
|
return /* @__PURE__ */ jsx(
|
|
7647
7829
|
"main",
|
|
7648
7830
|
{
|
|
@@ -11949,6 +12131,7 @@ var SToastContainer = /* @__PURE__ */ forwardRef(
|
|
|
11949
12131
|
/* @__PURE__ */ jsx(
|
|
11950
12132
|
"div",
|
|
11951
12133
|
{
|
|
12134
|
+
...globalOverlayProps,
|
|
11952
12135
|
style: {
|
|
11953
12136
|
position: "fixed",
|
|
11954
12137
|
zIndex,
|