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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -6266,6 +6266,28 @@ var SSplitter2 = /* @__PURE__ */ Object.assign(SSplitterRoot, {
6266
6266
  Before: SSplitterBefore2,
6267
6267
  After: SSplitterAfter2
6268
6268
  });
6269
+ var SURFACE = {
6270
+ default: {
6271
+ bg: "var(--cmp-callout-default-bg)",
6272
+ border: "var(--cmp-callout-default-border)",
6273
+ content: "var(--cmp-callout-default-content)"
6274
+ },
6275
+ danger: {
6276
+ bg: "var(--cmp-callout-danger-bg)",
6277
+ border: "var(--cmp-callout-danger-border)",
6278
+ content: "var(--cmp-callout-danger-content)"
6279
+ },
6280
+ // default 와 같은 안내인데 배경만 흰 면이다 — 회색 면(neutral·screen) 위에서 default 의
6281
+ // 옅은 회색이 묻히는 자리에 쓴다.
6282
+ //
6283
+ // ⚠️ callout.white 토큰 그룹이 아직 없어 배경은 시스템 흰 면을, 테두리·본문색은 default 것을
6284
+ // 빌려 쓴다. 디자인팀이 전용 토큰을 내면 이 세 줄을 그것으로 갈아끼운다(토큰 키는 만들지 않는다).
6285
+ white: {
6286
+ bg: "var(--sys-color-bg-frame)",
6287
+ border: "var(--cmp-callout-default-border)",
6288
+ content: "var(--cmp-callout-default-content)"
6289
+ }
6290
+ };
6269
6291
  var DANGER_TITLE_LABEL = "\uC8FC\uC758\uC0AC\uD56D";
6270
6292
  function renderItems(message, depth = 1) {
6271
6293
  const out = [];
@@ -6299,10 +6321,11 @@ function renderItems(message, depth = 1) {
6299
6321
  }
6300
6322
  var SCallout = /* @__PURE__ */ react.forwardRef(function SCallout2({ type = "default", message = [], children, className, style }, ref) {
6301
6323
  const isDanger = type === "danger";
6324
+ const surface = SURFACE[type];
6302
6325
  const vars = {
6303
- "--co-bg": `var(--cmp-callout-${type}-bg)`,
6304
- "--co-border": `var(--cmp-callout-${type}-border)`,
6305
- "--co-content": `var(--cmp-callout-${type}-content)`
6326
+ "--co-bg": surface.bg,
6327
+ "--co-border": surface.border,
6328
+ "--co-content": surface.content
6306
6329
  };
6307
6330
  return /* @__PURE__ */ jsxRuntime.jsxs(
6308
6331
  "div",
@@ -6528,6 +6551,7 @@ var STextLink = /* @__PURE__ */ react.forwardRef(function STextLink2({
6528
6551
  iconRotate,
6529
6552
  labelClass,
6530
6553
  rightArrow = "none",
6554
+ rightArrowRotate,
6531
6555
  underline = false,
6532
6556
  disabled = false,
6533
6557
  size = "sm",
@@ -6582,7 +6606,8 @@ var STextLink = /* @__PURE__ */ react.forwardRef(function STextLink2({
6582
6606
  {
6583
6607
  name: rightArrow === "chevron" ? "chevronRight" : "caretRight",
6584
6608
  size: 12,
6585
- color: disabled ? "var(--cmp-textLink-icon-disabled)" : "var(--color-grey-65)"
6609
+ color: disabled ? "var(--cmp-textLink-icon-disabled)" : "var(--color-grey-65)",
6610
+ rotate: rightArrowRotate
6586
6611
  }
6587
6612
  ) })
6588
6613
  ]
@@ -9074,8 +9099,22 @@ function SModalOutlet() {
9074
9099
  return /* @__PURE__ */ jsxRuntime.jsx(PortalContainerProvider, { value: null, children: /* @__PURE__ */ jsxRuntime.jsx(InsideModalProvider, { value: false, children: entries3.map((entry) => /* @__PURE__ */ jsxRuntime.jsx(SModalEntryPortal, { entry }, entry.id)) }) });
9075
9100
  }
9076
9101
  var useIsomorphicLayoutEffect = typeof window !== "undefined" ? react.useLayoutEffect : react.useEffect;
9102
+ var SPageColumnContext = /* @__PURE__ */ react.createContext(null);
9103
+ function SPageColumn({ full, children }) {
9104
+ const [scrolled, setScrolled] = react.useState(false);
9105
+ const value = react.useMemo(() => ({ scrolled, setScrolled }), [scrolled]);
9106
+ return /* @__PURE__ */ jsxRuntime.jsx(SPageColumnContext.Provider, { value, children: /* @__PURE__ */ jsxRuntime.jsx(
9107
+ "div",
9108
+ {
9109
+ className: "flex min-h-0 min-w-0 flex-1 flex-col",
9110
+ style: full ? { gridArea: "page" } : void 0,
9111
+ children
9112
+ }
9113
+ ) });
9114
+ }
9077
9115
  var isSameNav = (a, b) => a === b || !!a && !!b && a.columnWidth === b.columnWidth && a.topHeight === b.topHeight && a.foldMs === b.foldMs && a.requireFullHeader === b.requireFullHeader && a.resizing === b.resizing;
9078
9116
  var SLayoutContext = /* @__PURE__ */ react.createContext(null);
9117
+ var isPageHeaderElement = (node) => react.isValidElement(node) && node.type?.displayName === "SPageHeader";
9079
9118
  var SLAYOUT_MIN_WIDTH = 1366;
9080
9119
  var SLAYOUT_MIN_WIDTH_VAR = "--s-layout-min-width";
9081
9120
  function useSLayout() {
@@ -9137,6 +9176,15 @@ var SLayout = /* @__PURE__ */ react.forwardRef(function SLayout2({
9137
9176
  // 단 폭을 끄는 중에는 전환을 끈다 — 그러지 않으면 열이 손보다 늦게 따라온다.
9138
9177
  transition: nav?.resizing ? "none" : `grid-template-columns ${nav?.foldMs ?? 0}ms ease-out`
9139
9178
  } : void 0;
9179
+ const laidOutChildren = react.useMemo(() => {
9180
+ const kids = react.Children.toArray(children);
9181
+ const at = kids.findIndex(isPageHeaderElement);
9182
+ if (at === -1) return children;
9183
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9184
+ kids.slice(0, at),
9185
+ /* @__PURE__ */ jsxRuntime.jsx(SPageColumn, { full: isFullHeader, children: kids.slice(at) })
9186
+ ] });
9187
+ }, [children, isFullHeader]);
9140
9188
  return /* @__PURE__ */ jsxRuntime.jsx(SLayoutContext.Provider, { value: ctx, children: /* @__PURE__ */ jsxRuntime.jsx(
9141
9189
  "div",
9142
9190
  {
@@ -9150,7 +9198,7 @@ var SLayout = /* @__PURE__ */ react.forwardRef(function SLayout2({
9150
9198
  ),
9151
9199
  style: { ...minWidthStyle, ...frameStyle, ...style },
9152
9200
  ...rest,
9153
- children
9201
+ children: laidOutChildren
9154
9202
  }
9155
9203
  ) });
9156
9204
  });
@@ -10515,63 +10563,12 @@ var SGnbSystem = /* @__PURE__ */ react.forwardRef(function SGnbSystem2({
10515
10563
  }
10516
10564
  );
10517
10565
  });
10518
- var SPageHeader = /* @__PURE__ */ withDisplayName(
10519
- react.forwardRef(function SPageHeader2({ title, subText, fix = false, onBack, slot, scrolled = false, className, style, ...rest }, ref) {
10520
- const hasBack = onBack != null;
10521
- return /* @__PURE__ */ jsxRuntime.jsxs(
10522
- "header",
10523
- {
10524
- ref,
10525
- className: cn(
10526
- "relative z-10 box-border flex shrink-0 items-center gap-(--cmp-pageHeader-gap) px-(--cmp-pageHeader-paddingX)",
10527
- fix ? "h-(--cmp-pageHeader-bar-height) border-b border-(--cmp-pageHeader-bar-border) bg-(--cmp-pageHeader-bar-bg) py-(--cmp-pageHeader-bar-paddingY)" : cn(
10528
- // 배경은 항상 투명 — 페이지 배경을 따라갈지는 fix 가 정하지 scrolled 가 정하지 않는다.
10529
- // 스크롤되면 그림자만 더해 콘텐츠 위에 뜬 것처럼 보이게 한다.
10530
- "bg-transparent pt-(--cmp-pageHeader-plain-paddingTop) pb-(--cmp-pageHeader-plain-paddingBottom)",
10531
- scrolled && "shadow-floating"
10532
- ),
10533
- className
10534
- ),
10535
- style,
10536
- ...rest,
10537
- children: [
10538
- hasBack && /* @__PURE__ */ jsxRuntime.jsx(
10539
- SGhostButton,
10540
- {
10541
- icon: "chevronLeft",
10542
- size: "xs",
10543
- ariaLabel: "\uB4A4\uB85C\uAC00\uAE30",
10544
- onClick: onBack,
10545
- className: "shrink-0"
10546
- }
10547
- ),
10548
- /* @__PURE__ */ jsxRuntime.jsxs(
10549
- "div",
10550
- {
10551
- className: cn(
10552
- "flex min-w-0 flex-1 items-center",
10553
- fix ? "flex-row gap-(--cmp-pageHeader-gap)" : "flex-col items-start gap-(--cmp-pageHeader-plain-title-gap)",
10554
- !hasBack && "pl-(--cmp-pageHeader-title-paddingLeft)"
10555
- ),
10556
- children: [
10557
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typo-heading-lg min-w-0 truncate text-(--cmp-pageHeader-title-text)", children: title }),
10558
- subText && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typo-body-md-default min-w-0 truncate text-(--cmp-pageHeader-subtitle-text)", children: subText })
10559
- ]
10560
- }
10561
- ),
10562
- slot && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-auto flex shrink-0 items-center", children: slot })
10563
- ]
10564
- }
10565
- );
10566
- }),
10567
- "SPageHeader"
10568
- );
10569
- var MIN_CONTENT_WIDTH = `calc(var(${SLAYOUT_MIN_WIDTH_VAR}, 0px) - 100cqw + 100%)`;
10570
10566
  var BACKGROUND_CLASS = {
10571
10567
  frame: "bg-[var(--sys-color-bg-frame)]",
10572
10568
  neutral: "bg-[var(--sys-color-bg-neutralLight)]",
10573
10569
  screen: "bg-[var(--sys-color-bg-screen)]"
10574
10570
  };
10571
+ var MIN_CONTENT_WIDTH = `calc(var(${SLAYOUT_MIN_WIDTH_VAR}, 0px) - 100cqw + 100%)`;
10575
10572
  var NATIVE_SCROLLBAR_BACKGROUND_CLASS = {
10576
10573
  frame: `${SCROLLBAR_TRACK_BORDER_CLASS} ${SCROLLBAR_TRACK_BG_CLASS}`,
10577
10574
  neutral: `${SCROLLBAR_TRACK_BORDER_CLASS} ${SCROLLBAR_TRACK_BG_WHITE_CLASS}`,
@@ -10718,7 +10715,6 @@ var SPage = /* @__PURE__ */ react.forwardRef(function SPage2({
10718
10715
  scrollEndSpacing = false,
10719
10716
  overlayScrollbar = false,
10720
10717
  contentHeight = "auto",
10721
- header,
10722
10718
  className,
10723
10719
  style,
10724
10720
  children,
@@ -10726,7 +10722,8 @@ var SPage = /* @__PURE__ */ react.forwardRef(function SPage2({
10726
10722
  ...rest
10727
10723
  }, ref) {
10728
10724
  const layout = react.useContext(SLayoutContext);
10729
- const gridStyle = layout?.header === "full" ? { gridArea: "page" } : void 0;
10725
+ const column = react.useContext(SPageColumnContext);
10726
+ const gridStyle = layout?.header === "full" && !column ? { gridArea: "page" } : void 0;
10730
10727
  const scrollRef = react.useRef(null);
10731
10728
  const setMainRef = react.useCallback(
10732
10729
  (node) => {
@@ -10735,10 +10732,10 @@ var SPage = /* @__PURE__ */ react.forwardRef(function SPage2({
10735
10732
  },
10736
10733
  [ref]
10737
10734
  );
10738
- const [scrolled, setScrolled] = react.useState(false);
10735
+ const setColumnScrolled = column?.setScrolled;
10739
10736
  const handleScroll = (e) => {
10740
10737
  onScroll?.(e);
10741
- if (header != null && !header.fix) setScrolled(e.currentTarget.scrollTop > 0);
10738
+ setColumnScrolled?.(e.currentTarget.scrollTop > 0);
10742
10739
  };
10743
10740
  const fill = contentHeight === "fill";
10744
10741
  const main = /* @__PURE__ */ jsxRuntime.jsx(
@@ -10753,69 +10750,86 @@ var SPage = /* @__PURE__ */ react.forwardRef(function SPage2({
10753
10750
  BACKGROUND_CLASS[background],
10754
10751
  className
10755
10752
  ),
10756
- style: header == null && !overlayScrollbar ? { ...gridStyle, ...style } : style,
10753
+ style: !overlayScrollbar ? { ...gridStyle, ...style } : style,
10757
10754
  onScroll: handleScroll,
10758
10755
  ...rest,
10759
10756
  children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(fill && "h-full"), style: { minWidth: MIN_CONTENT_WIDTH }, children })
10760
10757
  }
10761
10758
  );
10762
- if (!overlayScrollbar) {
10763
- if (header == null) return main;
10764
- return (
10765
- // fix 가 아닌 헤더는 자기 배경이 투명이라(SPageHeader.tsx) 이 배경이 그대로 비친다.
10766
- /* @__PURE__ */ jsxRuntime.jsxs(
10767
- "div",
10768
- {
10769
- className: cn("flex min-h-0 min-w-0 flex-1 flex-col", BACKGROUND_CLASS[background]),
10770
- style: gridStyle,
10771
- children: [
10772
- /* @__PURE__ */ jsxRuntime.jsx(SPageHeader, { ...header, scrolled }),
10773
- main
10774
- ]
10775
- }
10776
- )
10777
- );
10778
- }
10779
- if (header == null) {
10759
+ if (!overlayScrollbar) return main;
10760
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10761
+ "div",
10762
+ {
10763
+ className: cn(
10764
+ "relative min-h-0 min-w-0 flex-1 overflow-hidden",
10765
+ BACKGROUND_CLASS[background]
10766
+ ),
10767
+ style: gridStyle,
10768
+ children: [
10769
+ main,
10770
+ /* @__PURE__ */ jsxRuntime.jsx(SPageOverlayScrollbars, { scrollRef })
10771
+ ]
10772
+ }
10773
+ );
10774
+ });
10775
+
10776
+ // src/components/SPage/page.config.ts
10777
+ var PAGE_BACKGROUNDS = ["frame", "neutral", "screen"];
10778
+ var PAGE_CONTENT_HEIGHTS = ["auto", "fill"];
10779
+ var SPageHeader = /* @__PURE__ */ withDisplayName(
10780
+ react.forwardRef(function SPageHeader2({ title, subText, fix = false, onBack, slot, scrolled, className, style, ...rest }, ref) {
10781
+ const hasBack = onBack != null;
10782
+ const column = react.useContext(SPageColumnContext);
10783
+ const isScrolled = scrolled ?? column?.scrolled ?? false;
10780
10784
  return /* @__PURE__ */ jsxRuntime.jsxs(
10781
- "div",
10785
+ "header",
10782
10786
  {
10787
+ ref,
10783
10788
  className: cn(
10784
- "relative min-h-0 min-w-0 flex-1 overflow-hidden",
10785
- BACKGROUND_CLASS[background]
10789
+ "relative z-10 box-border flex shrink-0 items-center gap-(--cmp-pageHeader-gap) px-(--cmp-pageHeader-paddingX)",
10790
+ // 배경은 두 베리에이션이 같은 흰 면이다 — fix 가 가르는 것은 높이·구분선·서브 텍스트 자리다.
10791
+ // plain 에는 전용 배경 토큰이 없어 시스템 흰 표면을 쓴다(토큰이 생기면 그것으로 갈아끼운다).
10792
+ fix ? "h-(--cmp-pageHeader-bar-height) border-b border-(--cmp-pageHeader-bar-border) bg-(--cmp-pageHeader-bar-bg) py-(--cmp-pageHeader-bar-paddingY)" : cn(
10793
+ // 스크롤되면 그림자를 더해 콘텐츠 위에 뜬 것처럼 보이게 한다.
10794
+ "bg-(--sys-color-bg-frame) pt-(--cmp-pageHeader-plain-paddingTop) pb-(--cmp-pageHeader-plain-paddingBottom)",
10795
+ isScrolled && "shadow-floating"
10796
+ ),
10797
+ className
10786
10798
  ),
10787
- style: gridStyle,
10799
+ style,
10800
+ ...rest,
10788
10801
  children: [
10789
- main,
10790
- /* @__PURE__ */ jsxRuntime.jsx(SPageOverlayScrollbars, { scrollRef })
10802
+ hasBack && /* @__PURE__ */ jsxRuntime.jsx(
10803
+ SGhostButton,
10804
+ {
10805
+ icon: "chevronLeft",
10806
+ size: "xs",
10807
+ ariaLabel: "\uB4A4\uB85C\uAC00\uAE30",
10808
+ onClick: onBack,
10809
+ className: "shrink-0"
10810
+ }
10811
+ ),
10812
+ /* @__PURE__ */ jsxRuntime.jsxs(
10813
+ "div",
10814
+ {
10815
+ className: cn(
10816
+ "flex min-w-0 flex-1 items-center",
10817
+ fix ? "flex-row gap-(--cmp-pageHeader-gap)" : "flex-col items-start gap-(--cmp-pageHeader-plain-title-gap)",
10818
+ !hasBack && "pl-(--cmp-pageHeader-title-paddingLeft)"
10819
+ ),
10820
+ children: [
10821
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typo-heading-lg min-w-0 truncate text-(--cmp-pageHeader-title-text)", children: title }),
10822
+ subText && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typo-body-md-default min-w-0 truncate text-(--cmp-pageHeader-subtitle-text)", children: subText })
10823
+ ]
10824
+ }
10825
+ ),
10826
+ slot && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-auto flex shrink-0 items-center", children: slot })
10791
10827
  ]
10792
10828
  }
10793
10829
  );
10794
- }
10795
- return (
10796
- // fix 가 아닌 헤더는 자기 배경이 투명이라(SPageHeader.tsx) 이 배경이 그대로 비친다 —
10797
- // 그래서 SPage 의 background 를 main 뿐 아니라 여기에도 칠한다(스크롤바 관련 클래스는
10798
- // 스크롤 요소가 아닌 여기서는 그냥 무시된다). fix 헤더는 자체 흰 배경이 덮으므로 무관하다.
10799
- /* @__PURE__ */ jsxRuntime.jsxs(
10800
- "div",
10801
- {
10802
- className: cn("flex min-h-0 min-w-0 flex-1 flex-col", BACKGROUND_CLASS[background]),
10803
- style: gridStyle,
10804
- children: [
10805
- /* @__PURE__ */ jsxRuntime.jsx(SPageHeader, { ...header, scrolled }),
10806
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative min-h-0 min-w-0 flex-1 overflow-hidden", children: [
10807
- main,
10808
- /* @__PURE__ */ jsxRuntime.jsx(SPageOverlayScrollbars, { scrollRef })
10809
- ] })
10810
- ]
10811
- }
10812
- )
10813
- );
10814
- });
10815
-
10816
- // src/components/SPage/page.config.ts
10817
- var PAGE_BACKGROUNDS = ["frame", "neutral", "screen"];
10818
- var PAGE_CONTENT_HEIGHTS = ["auto", "fill"];
10830
+ }),
10831
+ "SPageHeader"
10832
+ );
10819
10833
 
10820
10834
  // src/components/STabs/tabs.config.ts
10821
10835
  var TAB_MAIN_SIZE = { height: 36, paddingX: 24 };
@@ -22567,6 +22581,7 @@ exports.SModal = SModal;
22567
22581
  exports.SModalOutlet = SModalOutlet;
22568
22582
  exports.SNumberInput = SNumberInput;
22569
22583
  exports.SPage = SPage;
22584
+ exports.SPageHeader = SPageHeader;
22570
22585
  exports.SPagination = SPagination;
22571
22586
  exports.SPopover = SPopover;
22572
22587
  exports.SPopup = SPopup;