sellmate-design-system-react 4.2.0 → 4.3.0

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.d.ts CHANGED
@@ -33,6 +33,7 @@ export * from './components/SGuide';
33
33
  export * from './components/SConfirmModal';
34
34
  export * from './components/SActionModal';
35
35
  export * from './components/SLoadingModal';
36
+ export * from './components/SDrawer';
36
37
  export * from './components/SModal';
37
38
  export * from './components/SGnb';
38
39
  export * from './components/SLayout';
package/dist/index.js CHANGED
@@ -3617,9 +3617,10 @@ var SExpansionItem = /* @__PURE__ */ forwardRef(
3617
3617
  className: cn(
3618
3618
  "group/expansion-item relative overflow-hidden bg-(--cmp-listExpansionItem-title-bg-default)",
3619
3619
  !bordered && "border-b border-(--cmp-listExpansionItem-border-default)",
3620
- // TODO: expansionItem/bordered/radius border intent 토큰 생성 고정값을 토큰으로 교체한다.
3621
- bordered && "rounded-[8px] border border-[#E1E1E1] hover:border-[#AAAAAA] [&:has(>button:hover)]:border-[#AAAAAA]",
3622
- bordered && isExpanded && "!border-[#93C4FF]",
3620
+ // 보더 색은 시맨틱 토큰(border-default hover strong 펼침 accentLight)을 쓴다.
3621
+ // TODO: expansionItem/bordered/radius 토큰 생성 후 rounded 고정값도 토큰으로 교체한다.
3622
+ bordered && "rounded-[8px] border border-border-default hover:border-border-strong [&:has(>button:hover)]:border-border-strong",
3623
+ bordered && isExpanded && "!border-border-accentLight",
3623
3624
  className
3624
3625
  ),
3625
3626
  ...rest,
@@ -6571,6 +6572,170 @@ function SLoadingModal({
6571
6572
  }
6572
6573
  );
6573
6574
  }
6575
+ var CLOSE_ANIMATION_DURATION2 = 300;
6576
+ function SDrawer({
6577
+ open,
6578
+ onOpenChange,
6579
+ onClose,
6580
+ persistent = false,
6581
+ title = "",
6582
+ width = 572,
6583
+ footerLeft,
6584
+ button,
6585
+ children,
6586
+ className,
6587
+ style
6588
+ }) {
6589
+ const [shaking, setShaking] = useState(false);
6590
+ const [rendered, setRendered] = useState(() => Boolean(open));
6591
+ const [entered, setEntered] = useState(false);
6592
+ const [portalContainer, setPortalContainer] = useState(null);
6593
+ const backdropPointerDownRef = useRef(false);
6594
+ const contentRef = useRef(null);
6595
+ const stackRegistrationRef = useRef(null);
6596
+ const [layerIndex, setLayerIndex] = useState(null);
6597
+ useEffect(() => {
6598
+ if (open) {
6599
+ setRendered(true);
6600
+ return;
6601
+ }
6602
+ if (!rendered) return;
6603
+ const timer = window.setTimeout(() => setRendered(false), CLOSE_ANIMATION_DURATION2);
6604
+ return () => window.clearTimeout(timer);
6605
+ }, [open, rendered]);
6606
+ useEffect(() => {
6607
+ if (!open) {
6608
+ setEntered(false);
6609
+ return;
6610
+ }
6611
+ setEntered(false);
6612
+ const frame = requestAnimationFrame(() => setEntered(true));
6613
+ return () => cancelAnimationFrame(frame);
6614
+ }, [open]);
6615
+ useEffect(() => {
6616
+ if (!open) return;
6617
+ const registration = registerModalStackEntry();
6618
+ stackRegistrationRef.current = registration;
6619
+ setLayerIndex(registration.layerIndex);
6620
+ return () => {
6621
+ registration.unregister();
6622
+ if (stackRegistrationRef.current === registration) stackRegistrationRef.current = null;
6623
+ };
6624
+ }, [open]);
6625
+ const triggerShake = useCallback(() => {
6626
+ setShaking(false);
6627
+ requestAnimationFrame(() => setShaking(true));
6628
+ }, []);
6629
+ const guardClose = persistent ? (event) => {
6630
+ event.preventDefault();
6631
+ if (stackRegistrationRef.current?.isTop()) triggerShake();
6632
+ } : void 0;
6633
+ const handleBackdropInteraction = () => {
6634
+ if (persistent) {
6635
+ if (stackRegistrationRef.current?.isTop()) triggerShake();
6636
+ return;
6637
+ }
6638
+ onOpenChange?.(false);
6639
+ };
6640
+ const modalHost = getModalHost();
6641
+ 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
+ /* @__PURE__ */ jsx(
6643
+ RDialog.Overlay,
6644
+ {
6645
+ forceMount: rendered ? true : void 0,
6646
+ className: "pointer-events-auto absolute inset-0 bg-black/40 data-[state=open]:animate-overlay-in data-[state=closed]:animate-overlay-out",
6647
+ style: { zIndex: 0, animationFillMode: "forwards" },
6648
+ onPointerDown: (event) => {
6649
+ event.preventDefault();
6650
+ event.stopPropagation();
6651
+ backdropPointerDownRef.current = true;
6652
+ handleBackdropInteraction();
6653
+ },
6654
+ onClick: (event) => {
6655
+ event.stopPropagation();
6656
+ if (backdropPointerDownRef.current) {
6657
+ backdropPointerDownRef.current = false;
6658
+ return;
6659
+ }
6660
+ handleBackdropInteraction();
6661
+ }
6662
+ }
6663
+ ),
6664
+ /* @__PURE__ */ jsxs(
6665
+ RDialog.Content,
6666
+ {
6667
+ forceMount: rendered ? true : void 0,
6668
+ ref: contentRef,
6669
+ className: "pointer-events-auto absolute inset-y-0 right-0 w-fit max-w-full outline-none",
6670
+ onOpenAutoFocus: (event) => {
6671
+ event.preventDefault();
6672
+ contentRef.current?.focus({ preventScroll: true });
6673
+ },
6674
+ onEscapeKeyDown: guardClose,
6675
+ onPointerDownOutside: guardClose,
6676
+ onInteractOutside: guardClose,
6677
+ children: [
6678
+ /* @__PURE__ */ jsx(RDialog.Title, { className: "sr-only", children: title || "Drawer" }),
6679
+ /* @__PURE__ */ jsxs(
6680
+ "div",
6681
+ {
6682
+ className: cn(
6683
+ "pointer-events-auto relative flex h-full max-w-full translate-x-full flex-col overflow-hidden bg-[var(--cmp-drawer-bg)] shadow-[var(--shadow-overlay)] transition-transform duration-300 ease-out data-[state=open]:translate-x-0 data-[state=closed]:translate-x-full",
6684
+ shaking && "animate-drawer-shake",
6685
+ className
6686
+ ),
6687
+ "data-state": open && entered ? "open" : "closed",
6688
+ style: { width, ...style },
6689
+ onAnimationEnd: (event) => {
6690
+ if (event.animationName === "drawer-shake") setShaking(false);
6691
+ },
6692
+ children: [
6693
+ /* @__PURE__ */ jsxs("header", { className: "relative flex flex-shrink-0 items-center gap-[var(--cmp-overlay-header-gap)] bg-[var(--cmp-overlay-header-bg)] px-[var(--cmp-overlay-header-paddingX)] py-[var(--cmp-overlay-header-paddingY)]", children: [
6694
+ /* @__PURE__ */ jsx("h2", { className: "m-0 whitespace-nowrap text-[16px] font-bold leading-[26px] text-[color:var(--cmp-overlay-header-title-color)]", children: title }),
6695
+ /* @__PURE__ */ jsx(
6696
+ SGhostButton,
6697
+ {
6698
+ icon: "close",
6699
+ ariaLabel: "\uB2EB\uAE30",
6700
+ onClick: () => {
6701
+ onClose?.();
6702
+ onOpenChange?.(false);
6703
+ },
6704
+ className: "absolute right-[12px] top-[12px]"
6705
+ }
6706
+ )
6707
+ ] }),
6708
+ /* @__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__ */ jsxs("footer", { className: "flex flex-shrink-0 items-center justify-end gap-[var(--cmp-overlay-footer-gap)] bg-[var(--cmp-overlay-footer-bg-default)] px-[var(--cmp-overlay-footer-paddingX)] py-[var(--cmp-overlay-footer-paddingY)] shadow-[var(--shadow-overlay)]", children: [
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
+ ] })
6723
+ ]
6724
+ }
6725
+ ),
6726
+ /* @__PURE__ */ jsx(
6727
+ "div",
6728
+ {
6729
+ ref: setPortalContainer,
6730
+ className: "pointer-events-auto fixed left-0 top-0",
6731
+ style: { zIndex: 2 }
6732
+ }
6733
+ )
6734
+ ]
6735
+ }
6736
+ )
6737
+ ] }) }) });
6738
+ }
6574
6739
  var EXIT_DURATION = 300;
6575
6740
  var EXIT_BUFFER = 100;
6576
6741
  var SModalRefImpl = class {
@@ -6935,6 +7100,8 @@ var GNB_EXPAND_MS = 200;
6935
7100
  var GNB_MENU_WIDTH = 240;
6936
7101
  var GNB_FULL_LOGO_WIDTH = 140;
6937
7102
  var GNB_TOP_ICON_GAP = 8;
7103
+ var GNB_TOP_ICON_SIZE = 24;
7104
+ var GNB_FULL_LOGO_WIDTH_NO_LAUNCHER = GNB_FULL_LOGO_WIDTH + GNB_TOP_ICON_SIZE + GNB_TOP_ICON_GAP;
6938
7105
  function findGnbRailValue(items, value) {
6939
7106
  if (items.some((item) => item.value === value)) return value;
6940
7107
  return findGnbAncestors(items, value)[0];
@@ -7312,7 +7479,11 @@ var SGnb = /* @__PURE__ */ forwardRef(function SGnb2({
7312
7479
  ...header === "full" ? (
7313
7480
  // full 은 전폭이라 로고 자리가 고정이다 — 폭 140px(디자인 스펙, 전용 토큰 없음)로 못 박아
7314
7481
  // 로고 내용이 바뀌어도 오른쪽 topContent 시작점이 흔들리지 않게 한다.
7315
- { width: GNB_FULL_LOGO_WIDTH, marginLeft: H.topGap }
7482
+ // 런처가 없으면 자리(버튼 + 간격)를 로고가 이어받아, 런처 유무로 topContent 가 밀리지 않는다.
7483
+ {
7484
+ width: launcherButton ? GNB_FULL_LOGO_WIDTH : GNB_FULL_LOGO_WIDTH_NO_LAUNCHER,
7485
+ marginLeft: H.topGap
7486
+ }
7316
7487
  ) : (
7317
7488
  // fix 는 폴드가 ml-auto 로 밀려나므로(margin-left 를 못 쓴다) 로고 오른쪽에 최소 간격을 둔다
7318
7489
  { marginRight: H.topGap }
@@ -7863,10 +8034,10 @@ function SStepper({
7863
8034
  fill: "none",
7864
8035
  xmlns: "http://www.w3.org/2000/svg",
7865
8036
  children: [
7866
- /* @__PURE__ */ jsx("rect", { width: "1.6", height: "1", fill: "#888888" }),
7867
- /* @__PURE__ */ jsx("rect", { x: "5", width: "3.3", height: "1", fill: "#888888" }),
7868
- /* @__PURE__ */ jsx("rect", { x: "11.7", width: "3.3", height: "1", fill: "#888888" }),
7869
- /* @__PURE__ */ jsx("rect", { x: "18.4", width: "1.6", height: "1", fill: "#888888" })
8037
+ /* @__PURE__ */ jsx("rect", { width: "1.6", height: "1", fill: "currentColor" }),
8038
+ /* @__PURE__ */ jsx("rect", { x: "5", width: "3.3", height: "1", fill: "currentColor" }),
8039
+ /* @__PURE__ */ jsx("rect", { x: "11.7", width: "3.3", height: "1", fill: "currentColor" }),
8040
+ /* @__PURE__ */ jsx("rect", { x: "18.4", width: "1.6", height: "1", fill: "currentColor" })
7870
8041
  ]
7871
8042
  }
7872
8043
  )
@@ -8016,7 +8187,7 @@ var SField = /* @__PURE__ */ forwardRef(function SField2({
8016
8187
  }
8017
8188
  ),
8018
8189
  /* @__PURE__ */ jsx("span", { className: "min-w-0 overflow-hidden text-ellipsis whitespace-nowrap", children: label }),
8019
- (labelTooltip !== "" || labelTooltipProps) && /* @__PURE__ */ jsx("span", { className: "shrink-0", style: { marginLeft: s.labelGap }, children: /* @__PURE__ */ jsx(
8190
+ (labelTooltip !== "" || labelTooltipProps) && /* @__PURE__ */ jsx("span", { className: "shrink-0 flex items-center", style: { marginLeft: s.labelGap }, children: /* @__PURE__ */ jsx(
8020
8191
  STooltip2,
8021
8192
  {
8022
8193
  message: labelTooltip !== "" ? [labelTooltip] : void 0,
@@ -12261,7 +12432,7 @@ var SChipInput = /* @__PURE__ */ forwardRef(function SChipInput2({
12261
12432
  "span",
12262
12433
  {
12263
12434
  className: "s-chip-input__divider shrink-0",
12264
- style: { width: 1, height: 12, backgroundColor: "#E1E1E1" }
12435
+ style: { width: 1, height: 12, backgroundColor: "var(--color-divider-default)" }
12265
12436
  }
12266
12437
  ),
12267
12438
  showMaxCount && /* @__PURE__ */ jsxs(
@@ -12323,7 +12494,7 @@ var SChipInput = /* @__PURE__ */ forwardRef(function SChipInput2({
12323
12494
  role: "option",
12324
12495
  "aria-selected": selected || active,
12325
12496
  className: "rounded-full",
12326
- style: active ? { outline: "2px solid #0075FF", outlineOffset: 1 } : void 0,
12497
+ style: active ? { outline: "2px solid var(--color-border-accent)", outlineOffset: 1 } : void 0,
12327
12498
  onMouseDown: (e) => {
12328
12499
  e.preventDefault();
12329
12500
  if (!selected) addChip(item);
@@ -13419,6 +13590,6 @@ function STimeRangePicker({
13419
13590
  );
13420
13591
  }
13421
13592
 
13422
- export { BADGE_COLORS, BUTTON_COLORS, BUTTON_SIZES, COLOR_KEYS, GNB_COLORS, GNB_COMMON, GNB_FOLD_MS, GNB_FULL_LOGO_WIDTH, GNB_HEADER, GNB_MENU, GNB_MENU_WIDTH, GNB_RAIL, GNB_RAIL_WIDTH, ICONS, PAGE_BACKGROUNDS, SActionModal, SBadge, SBarcodeInput, SButton, SCROLL_AREA_AXES, SCalendar, SCallout, SCard, SCheckbox, SChip2 as SChip, SChipInput, SCircleProgress, SConfirmModal, SDatePicker, SDateRangePicker, SDivider, SDraggableGroup, SDraggableItem2 as SDraggableItem, SDraggableList, SDraggableProvider, SDropdownButton2 as SDropdownButton, SExpansionItem, SExpansionList2 as SExpansionList, SField, SFilePicker, SForm, SGhostButton, SGnb, SGuide, SIcon, SInput, SKeyValueTable, SLayout, SLayoutContext, SLinearProgress, SList2 as SList, SListItem2 as SListItem, SLoadingContainer, SLoadingModal, SLoadingViewport, SModal, SNumberInput, SPage, SPagination, SPopover, SPopup, SPortal, SRadio, SRadioButton, SRadioGroup, SScrollArea, SSectionHeaderCard2 as SSectionHeaderCard, SSelect2 as SSelect, SStepper, SSwitch, STEPPER_SIZES, STable, STableBar, STabs, STag, STextLink, STextarea, STimePicker, STimeRangePicker, SToast, SToastContainer, SToggle, STooltip2 as STooltip, STree2 as STree, STreeItem2 as STreeItem, TAG_COLORS, TAG_SHAPES, TAG_SIZES, TIMEPICKER_SIZES, TIMEPICKER_SIZE_CONFIG, buttonPreset, cn, findGnbAncestors, findGnbRailValue, isColorKey, loading, resolveColor, useSLayout };
13593
+ export { BADGE_COLORS, BUTTON_COLORS, BUTTON_SIZES, COLOR_KEYS, GNB_COLORS, GNB_COMMON, GNB_FOLD_MS, GNB_FULL_LOGO_WIDTH, GNB_HEADER, GNB_MENU, GNB_MENU_WIDTH, GNB_RAIL, GNB_RAIL_WIDTH, ICONS, PAGE_BACKGROUNDS, SActionModal, SBadge, SBarcodeInput, SButton, SCROLL_AREA_AXES, SCalendar, SCallout, SCard, SCheckbox, SChip2 as SChip, SChipInput, SCircleProgress, SConfirmModal, SDatePicker, SDateRangePicker, SDivider, SDraggableGroup, SDraggableItem2 as SDraggableItem, SDraggableList, SDraggableProvider, SDrawer, SDropdownButton2 as SDropdownButton, SExpansionItem, SExpansionList2 as SExpansionList, SField, SFilePicker, SForm, SGhostButton, SGnb, SGuide, SIcon, SInput, SKeyValueTable, SLayout, SLayoutContext, SLinearProgress, SList2 as SList, SListItem2 as SListItem, SLoadingContainer, SLoadingModal, SLoadingViewport, SModal, SNumberInput, SPage, SPagination, SPopover, SPopup, SPortal, SRadio, SRadioButton, SRadioGroup, SScrollArea, SSectionHeaderCard2 as SSectionHeaderCard, SSelect2 as SSelect, SStepper, SSwitch, STEPPER_SIZES, STable, STableBar, STabs, STag, STextLink, STextarea, STimePicker, STimeRangePicker, SToast, SToastContainer, SToggle, STooltip2 as STooltip, STree2 as STree, STreeItem2 as STreeItem, TAG_COLORS, TAG_SHAPES, TAG_SIZES, TIMEPICKER_SIZES, TIMEPICKER_SIZE_CONFIG, buttonPreset, cn, findGnbAncestors, findGnbRailValue, isColorKey, loading, resolveColor, useSLayout };
13423
13594
  //# sourceMappingURL=index.js.map
13424
13595
  //# sourceMappingURL=index.js.map