sellmate-design-system-react 0.11.0 → 1.0.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.
Files changed (95) hide show
  1. package/dist/components/SActionModal/SActionModal.cjs +3 -3
  2. package/dist/components/SActionModal/SActionModal.cjs.map +1 -1
  3. package/dist/components/SActionModal/SActionModal.js +3 -3
  4. package/dist/components/SActionModal/SActionModal.js.map +1 -1
  5. package/dist/components/SBarcodeInput/SBarcodeInput.cjs +1 -1
  6. package/dist/components/SBarcodeInput/SBarcodeInput.cjs.map +1 -1
  7. package/dist/components/SBarcodeInput/SBarcodeInput.js +1 -1
  8. package/dist/components/SBarcodeInput/SBarcodeInput.js.map +1 -1
  9. package/dist/components/SChipInput/SChipInput.cjs +1 -1
  10. package/dist/components/SChipInput/SChipInput.cjs.map +1 -1
  11. package/dist/components/SChipInput/SChipInput.js +1 -1
  12. package/dist/components/SChipInput/SChipInput.js.map +1 -1
  13. package/dist/components/SConfirmModal/SConfirmModal.cjs +4 -4
  14. package/dist/components/SConfirmModal/SConfirmModal.cjs.map +1 -1
  15. package/dist/components/SConfirmModal/SConfirmModal.js +4 -4
  16. package/dist/components/SConfirmModal/SConfirmModal.js.map +1 -1
  17. package/dist/components/SDatePicker/SDatePicker.cjs +1 -1
  18. package/dist/components/SDatePicker/SDatePicker.cjs.map +1 -1
  19. package/dist/components/SDatePicker/SDatePicker.js +1 -1
  20. package/dist/components/SDatePicker/SDatePicker.js.map +1 -1
  21. package/dist/components/SDateRangePicker/SDateRangePicker.cjs +1 -1
  22. package/dist/components/SDateRangePicker/SDateRangePicker.cjs.map +1 -1
  23. package/dist/components/SDateRangePicker/SDateRangePicker.js +1 -1
  24. package/dist/components/SDateRangePicker/SDateRangePicker.js.map +1 -1
  25. package/dist/components/SExpansionItem/SExpansionItem.cjs +42 -12
  26. package/dist/components/SExpansionItem/SExpansionItem.cjs.map +1 -1
  27. package/dist/components/SExpansionItem/SExpansionItem.d.ts +2 -0
  28. package/dist/components/SExpansionItem/SExpansionItem.js +43 -13
  29. package/dist/components/SExpansionItem/SExpansionItem.js.map +1 -1
  30. package/dist/components/SField/SField.cjs +1 -1
  31. package/dist/components/SField/SField.cjs.map +1 -1
  32. package/dist/components/SField/SField.js +1 -1
  33. package/dist/components/SField/SField.js.map +1 -1
  34. package/dist/components/SFilePicker/SFilePicker.cjs +1 -1
  35. package/dist/components/SFilePicker/SFilePicker.cjs.map +1 -1
  36. package/dist/components/SFilePicker/SFilePicker.js +1 -1
  37. package/dist/components/SFilePicker/SFilePicker.js.map +1 -1
  38. package/dist/components/SInput/SInput.cjs +1 -1
  39. package/dist/components/SInput/SInput.cjs.map +1 -1
  40. package/dist/components/SInput/SInput.js +1 -1
  41. package/dist/components/SInput/SInput.js.map +1 -1
  42. package/dist/components/SKeyValueTable/SKeyValueTable.cjs +1 -1
  43. package/dist/components/SKeyValueTable/SKeyValueTable.cjs.map +1 -1
  44. package/dist/components/SKeyValueTable/SKeyValueTable.js +1 -1
  45. package/dist/components/SKeyValueTable/SKeyValueTable.js.map +1 -1
  46. package/dist/components/SLoadingModal/SLoadingModal.cjs +3 -3
  47. package/dist/components/SLoadingModal/SLoadingModal.cjs.map +1 -1
  48. package/dist/components/SLoadingModal/SLoadingModal.js +3 -3
  49. package/dist/components/SLoadingModal/SLoadingModal.js.map +1 -1
  50. package/dist/components/SModal/SModal.cjs +3863 -0
  51. package/dist/components/SModal/SModal.cjs.map +1 -0
  52. package/dist/components/SModal/SModal.d.ts +121 -0
  53. package/dist/components/SModal/SModal.js +3840 -0
  54. package/dist/components/SModal/SModal.js.map +1 -0
  55. package/dist/components/SModal/index.d.ts +1 -0
  56. package/dist/components/SModalContainer/SModalContainer.cjs +1 -1
  57. package/dist/components/SModalContainer/SModalContainer.cjs.map +1 -1
  58. package/dist/components/SModalContainer/SModalContainer.js +1 -1
  59. package/dist/components/SModalContainer/SModalContainer.js.map +1 -1
  60. package/dist/components/SNumberInput/SNumberInput.cjs +1 -1
  61. package/dist/components/SNumberInput/SNumberInput.cjs.map +1 -1
  62. package/dist/components/SNumberInput/SNumberInput.js +1 -1
  63. package/dist/components/SNumberInput/SNumberInput.js.map +1 -1
  64. package/dist/components/SSelect/SSelect.cjs +1 -1
  65. package/dist/components/SSelect/SSelect.cjs.map +1 -1
  66. package/dist/components/SSelect/SSelect.js +1 -1
  67. package/dist/components/SSelect/SSelect.js.map +1 -1
  68. package/dist/components/STable/STable.cjs +2 -2
  69. package/dist/components/STable/STable.cjs.map +1 -1
  70. package/dist/components/STable/STable.d.ts +2 -1
  71. package/dist/components/STable/STable.js +2 -2
  72. package/dist/components/STable/STable.js.map +1 -1
  73. package/dist/components/STextarea/STextarea.cjs +1 -1
  74. package/dist/components/STextarea/STextarea.cjs.map +1 -1
  75. package/dist/components/STextarea/STextarea.js +1 -1
  76. package/dist/components/STextarea/STextarea.js.map +1 -1
  77. package/dist/components/STimePicker/STimePicker.cjs +1 -1
  78. package/dist/components/STimePicker/STimePicker.cjs.map +1 -1
  79. package/dist/components/STimePicker/STimePicker.js +1 -1
  80. package/dist/components/STimePicker/STimePicker.js.map +1 -1
  81. package/dist/components/STimeRangePicker/STimeRangePicker.cjs +1 -1
  82. package/dist/components/STimeRangePicker/STimeRangePicker.cjs.map +1 -1
  83. package/dist/components/STimeRangePicker/STimeRangePicker.js +1 -1
  84. package/dist/components/STimeRangePicker/STimeRangePicker.js.map +1 -1
  85. package/dist/components/STooltip/STooltip.cjs +1 -1
  86. package/dist/components/STooltip/STooltip.cjs.map +1 -1
  87. package/dist/components/STooltip/STooltip.js +1 -1
  88. package/dist/components/STooltip/STooltip.js.map +1 -1
  89. package/dist/index.cjs +291 -22
  90. package/dist/index.cjs.map +1 -1
  91. package/dist/index.d.ts +1 -0
  92. package/dist/index.js +292 -24
  93. package/dist/index.js.map +1 -1
  94. package/dist/styles.css +83 -33
  95. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -2927,6 +2927,7 @@ var SExpansionItem = react.forwardRef(
2927
2927
  leading,
2928
2928
  trailing,
2929
2929
  bodyPadding = true,
2930
+ bordered = false,
2930
2931
  expanded,
2931
2932
  defaultExpanded = false,
2932
2933
  dense = false,
@@ -2938,9 +2939,6 @@ var SExpansionItem = react.forwardRef(
2938
2939
  }, ref) {
2939
2940
  const [internalExpanded, setInternalExpanded] = react.useState(defaultExpanded);
2940
2941
  const isExpanded = expanded ?? internalExpanded;
2941
- const hasBody = react.Children.toArray(children).some(
2942
- (child) => child !== null && child !== void 0 && (typeof child !== "string" || child.trim() !== "")
2943
- );
2944
2942
  const leadingNode = typeof leading === "function" ? leading({ expanded: isExpanded, disabled }) : leading;
2945
2943
  const id = react.useId();
2946
2944
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -2949,6 +2947,9 @@ var SExpansionItem = react.forwardRef(
2949
2947
  ref,
2950
2948
  className: cn(
2951
2949
  "group overflow-hidden bg-[var(--cmp-expansionItem-title-bg-default)]",
2950
+ // TODO: expansionItem/bordered/radius 및 border intent 토큰 생성 후 고정값을 토큰으로 교체한다.
2951
+ bordered && "rounded-[8px] border border-[#E1E1E1] hover:border-[#AAAAAA] [&:has(>button:hover)]:border-[#AAAAAA]",
2952
+ bordered && isExpanded && "!border-[#93C4FF]",
2952
2953
  className
2953
2954
  ),
2954
2955
  ...rest,
@@ -2968,23 +2969,52 @@ var SExpansionItem = react.forwardRef(
2968
2969
  },
2969
2970
  className: cn(
2970
2971
  "flex w-full items-center justify-between border-0 text-left text-[14px] font-bold leading-[24px] text-[var(--cmp-expansionItem-title-text-default)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-[var(--sys-color-border-accent)] disabled:cursor-not-allowed disabled:text-[var(--sys-color-disabled-text)] cursor-pointer",
2971
- isExpanded && "border-b border-[var(--cmp-expansionItem-title-border)]",
2972
- !isExpanded && "hover:bg-[var(--cmp-expansionItem-title-bg-hover)]",
2973
- dense ? "min-h-8 py-[var(--cmp-expansionItem-title-paddingY-dense)]" : "min-h-10 py-[var(--cmp-expansionItem-title-paddingY-normal)]",
2974
- "gap-[var(--cmp-expansionItem-title-gap)]",
2975
- "pr-[var(--cmp-expansionItem-title-paddingX)]",
2976
- depth === 2 ? "pl-[calc(var(--cmp-expansionItem-title-paddingX)+32px)]" : depth === 3 ? "pl-[calc(var(--cmp-expansionItem-title-paddingX)+64px)]" : "pl-[var(--cmp-expansionItem-title-paddingX)]",
2977
- isExpanded && "bg-[var(--cmp-expansionItem-title-bg-expanded)] text-[var(--cmp-expansionItem-title-text-expanded)]"
2972
+ isExpanded && "border-b border-(--cmp-expansionItem-title-border)",
2973
+ !isExpanded && "hover:bg-(--cmp-expansionItem-title-bg-hover)",
2974
+ dense ? "min-h-8 py-(--cmp-expansionItem-title-paddingY-dense)" : "min-h-10 py-(--cmp-expansionItem-title-paddingY-normal)",
2975
+ "gap-(--cmp-expansionItem-title-gap)",
2976
+ "pr-(--cmp-expansionItem-title-paddingX)",
2977
+ depth === 2 ? "pl-[calc(var(--cmp-expansionItem-title-paddingX)+32px)]" : depth === 3 ? "pl-[calc(var(--cmp-expansionItem-title-paddingX)+64px)]" : "pl-(--cmp-expansionItem-title-paddingX)",
2978
+ isExpanded && "bg-(--cmp-expansionItem-title-bg-expanded) text-(--cmp-expansionItem-title-text-expanded)"
2978
2979
  ),
2979
2980
  children: [
2980
- !leading && hasBody && /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: isExpanded ? "caretUp" : "caretDown", size: 12 }),
2981
+ !leading && /* @__PURE__ */ jsxRuntime.jsx(
2982
+ "span",
2983
+ {
2984
+ className: cn(
2985
+ "flex transition-transform duration-200 ease-out motion-reduce:transition-none",
2986
+ isExpanded && "rotate-180"
2987
+ ),
2988
+ children: /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: "caretDown", size: 12 })
2989
+ }
2990
+ ),
2981
2991
  leadingNode,
2982
2992
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex min-w-0 flex-1 flex-col", children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: title }) }),
2983
2993
  trailing
2984
2994
  ]
2985
2995
  }
2986
2996
  ),
2987
- /* @__PURE__ */ jsxRuntime.jsx("div", { id, hidden: !isExpanded, className: "bg-[var(--cmp-expansionItem-body-bg)]", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: bodyPadding ? "p-[var(--cmp-expansionItem-body-padding)]" : void 0, children }) })
2997
+ /* @__PURE__ */ jsxRuntime.jsx(
2998
+ "div",
2999
+ {
3000
+ id,
3001
+ "aria-hidden": !isExpanded,
3002
+ className: cn(
3003
+ "grid overflow-hidden bg-[var(--cmp-expansionItem-body-bg)] transition-[grid-template-rows] duration-200 ease-out motion-reduce:transition-none",
3004
+ isExpanded ? "grid-rows-[1fr]" : "grid-rows-[0fr]"
3005
+ ),
3006
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3007
+ "div",
3008
+ {
3009
+ className: cn(
3010
+ "min-h-0 overflow-hidden",
3011
+ bodyPadding && isExpanded && "p-(--cmp-expansionItem-body-padding)"
3012
+ ),
3013
+ children
3014
+ }
3015
+ )
3016
+ }
3017
+ )
2988
3018
  ]
2989
3019
  }
2990
3020
  );
@@ -4310,7 +4340,7 @@ var STooltip = react.forwardRef(function STooltip2({
4310
4340
  if (disabled || body == null) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: triggerNode });
4311
4341
  const isHover = trigger === "hover";
4312
4342
  const contentClass = cn(
4313
- "z-50 w-fit whitespace-nowrap rounded-[6px] px-[16px] py-[12px] text-[12px] leading-[20px]",
4343
+ "z-50 w-fit whitespace-nowrap rounded-[6px] px-[16px] py-[12px] text-[12px] leading-[20px] shadow-normal-sm",
4314
4344
  FLOATING_SLIDE_ANIM,
4315
4345
  className
4316
4346
  );
@@ -4777,7 +4807,7 @@ function SModalContainer({
4777
4807
  "div",
4778
4808
  {
4779
4809
  className: cn(
4780
- "relative overflow-hidden rounded-[var(--cmp-modal-radius)] bg-[var(--cmp-modal-bg)] shadow-normal-md",
4810
+ "relative flex max-h-[calc(100dvh-48px)] flex-col overflow-hidden rounded-[var(--cmp-modal-radius)] bg-[var(--cmp-modal-bg)] shadow-normal-md",
4781
4811
  shaking && "animate-modal-shake",
4782
4812
  className
4783
4813
  ),
@@ -4869,8 +4899,8 @@ function SConfirmModal({
4869
4899
  showClose: true,
4870
4900
  onClose,
4871
4901
  className: "w-fit min-w-[520px]",
4872
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-[40px] px-[32px] py-[40px]", children: [
4873
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full flex-col items-center gap-[20px]", children: [
4902
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-auto flex-col items-center gap-[40px] px-[32px] py-[40px]", children: [
4903
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full min-h-0 flex-col items-center gap-[20px] overflow-y-auto", children: [
4874
4904
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-[12px]", children: [
4875
4905
  iconName && /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: iconName, size: 32, color: TYPE_ICON_COLOR[type] }),
4876
4906
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -4892,7 +4922,7 @@ function SConfirmModal({
4892
4922
  optionNode != null && optionNode
4893
4923
  ] })
4894
4924
  ] }),
4895
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-[8px]", children: [
4925
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-shrink-0 gap-[8px]", children: [
4896
4926
  subButtonLabel && /* @__PURE__ */ jsxRuntime.jsx(
4897
4927
  SButton,
4898
4928
  {
@@ -4945,8 +4975,8 @@ function SActionModal({
4945
4975
  showClose: true,
4946
4976
  width,
4947
4977
  height,
4948
- className: "w-fit min-w-[480px] min-h-[320px]",
4949
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full min-h-[320px] flex-col", children: [
4978
+ className: "w-fit min-w-[480px] min-h-[min(320px,calc(100dvh-48px))]",
4979
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-auto flex-col", children: [
4950
4980
  /* @__PURE__ */ jsxRuntime.jsx("header", { className: "flex flex-shrink-0 items-center gap-[var(--cmp-overlay-header-gap)] py-[var(--cmp-overlay-header-paddingY)] pl-[var(--cmp-overlay-header-paddingX)] pr-[calc(var(--cmp-overlay-header-paddingX)+20px)]", children: /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-[16px] font-bold leading-[26px] text-[color:var(--cmp-overlay-header-title-color)]", children: modalTitle }) }),
4951
4981
  /* @__PURE__ */ jsxRuntime.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 }),
4952
4982
  button && /* @__PURE__ */ jsxRuntime.jsx(
@@ -5012,7 +5042,7 @@ function SLoadingModal({
5012
5042
  ariaTitle: lines[0] || "\uB85C\uB529 \uC911",
5013
5043
  width,
5014
5044
  height,
5015
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col items-center justify-center gap-[20px] px-[32px]", children: [
5045
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-h-0 flex-auto flex-col overflow-y-auto px-[32px]", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "m-auto flex flex-col items-center gap-[20px]", children: [
5016
5046
  state2 === "loading" ? progress !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(SCircleProgress, { value: progress }) : /* @__PURE__ */ jsxRuntime.jsx(SCircleProgress, { indeterminate: true }) : /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: "warningOutline", size: 80, color: "var(--cmp-modal-confirm-negative-icon)" }),
5017
5047
  lines.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-[2px]", children: lines.map((m, i) => /* @__PURE__ */ jsxRuntime.jsx(
5018
5048
  "p",
@@ -5035,10 +5065,248 @@ function SLoadingModal({
5035
5065
  label: buttonLabel ?? DEFAULT_BUTTON_LABEL[state2]
5036
5066
  }
5037
5067
  )
5038
- ] })
5068
+ ] }) })
5039
5069
  }
5040
5070
  );
5041
5071
  }
5072
+ var EXIT_DURATION = 300;
5073
+ var EXIT_BUFFER = 100;
5074
+ var SModalRefImpl = class {
5075
+ constructor() {
5076
+ this.pendingClose = false;
5077
+ this.pendingPatches = [];
5078
+ this.dismissRequested = false;
5079
+ }
5080
+ onOk(fn) {
5081
+ this.okFn = fn;
5082
+ return this;
5083
+ }
5084
+ onCancel(fn) {
5085
+ this.cancelFn = fn;
5086
+ return this;
5087
+ }
5088
+ onClose(fn) {
5089
+ this.closeFn = fn;
5090
+ return this;
5091
+ }
5092
+ onClick(fn) {
5093
+ this.clickFn = fn;
5094
+ return this;
5095
+ }
5096
+ onSubmit(fn) {
5097
+ this.submitFn = fn;
5098
+ return this;
5099
+ }
5100
+ onDismissed(fn) {
5101
+ this.dismissedFn = fn;
5102
+ return this;
5103
+ }
5104
+ update(patch) {
5105
+ if (this.updateBinding) this.updateBinding(patch);
5106
+ else this.pendingPatches.push(patch);
5107
+ return this;
5108
+ }
5109
+ // 닫힘 트리거 — 이미 닫힘이 시작됐으면 무시(중복 콜백 방지)
5110
+ settle(emit2) {
5111
+ if (this.dismissRequested) return;
5112
+ this.dismissRequested = true;
5113
+ emit2();
5114
+ if (this.closeBinding) this.closeBinding();
5115
+ else this.pendingClose = true;
5116
+ }
5117
+ ok() {
5118
+ this.settle(() => this.okFn?.());
5119
+ return this;
5120
+ }
5121
+ cancel() {
5122
+ this.settle(() => this.cancelFn?.());
5123
+ return this;
5124
+ }
5125
+ close() {
5126
+ this.settle(() => this.closeFn?.());
5127
+ return this;
5128
+ }
5129
+ submit() {
5130
+ this.submitFn?.();
5131
+ return this;
5132
+ }
5133
+ /** @internal 마운트 컴포넌트가 닫기 함수를 등록 (등록 전 close() 호출은 지연 반영) */
5134
+ _bindClose(fn) {
5135
+ this.closeBinding = fn;
5136
+ if (this.pendingClose) fn();
5137
+ }
5138
+ /** @internal 마운트 컴포넌트가 옵션 갱신 함수를 등록 (등록 전 update() 호출은 지연 반영) */
5139
+ _bindUpdate(fn) {
5140
+ this.updateBinding = fn;
5141
+ if (this.pendingPatches.length) {
5142
+ this.pendingPatches.forEach(fn);
5143
+ this.pendingPatches = [];
5144
+ }
5145
+ }
5146
+ /** @internal 정리 대상(root·host) 주입 */
5147
+ _setTeardown(root, host) {
5148
+ this.root = root;
5149
+ this.host = host;
5150
+ }
5151
+ /** @internal create 의 마운트 검사용 host 조회 */
5152
+ _getHost() {
5153
+ return this.host;
5154
+ }
5155
+ /** @internal 닫힘 시작 표시 — 컴포넌트 버튼·백드롭·ESC 닫힘 경로가 호출(중복 트리거 방지) */
5156
+ _markDismissed() {
5157
+ this.dismissRequested = true;
5158
+ }
5159
+ /** @internal confirm 버튼 경로에서 onOk 발화 */
5160
+ _emitOk() {
5161
+ this.okFn?.();
5162
+ }
5163
+ /** @internal confirm 버튼 경로에서 onCancel 발화 */
5164
+ _emitCancel() {
5165
+ this.cancelFn?.();
5166
+ }
5167
+ /** @internal 닫기(X) 경로에서 onClose 발화 */
5168
+ _emitClose() {
5169
+ this.closeFn?.();
5170
+ }
5171
+ /** @internal loading 버튼 경로에서 onClick 발화 */
5172
+ _emitClick() {
5173
+ this.clickFn?.();
5174
+ }
5175
+ /** @internal */
5176
+ _emitDismissed() {
5177
+ this.dismissedFn?.();
5178
+ }
5179
+ /** @internal 닫힘 애니메이션 종료 후 언마운트 */
5180
+ _teardown() {
5181
+ this.root?.unmount();
5182
+ this.host?.remove();
5183
+ }
5184
+ };
5185
+ function useExitTeardown(open, refImpl) {
5186
+ const dismissedRef = react.useRef(false);
5187
+ react.useEffect(() => {
5188
+ if (open || dismissedRef.current) return;
5189
+ dismissedRef.current = true;
5190
+ const t = setTimeout(() => {
5191
+ refImpl._emitDismissed();
5192
+ refImpl._teardown();
5193
+ }, EXIT_DURATION + EXIT_BUFFER);
5194
+ return () => clearTimeout(t);
5195
+ }, [open, refImpl]);
5196
+ }
5197
+ function ConfirmMount({ options, refImpl }) {
5198
+ const [open, setOpen] = react.useState(true);
5199
+ const [opts, setOpts] = react.useState(options);
5200
+ react.useEffect(() => {
5201
+ refImpl._bindClose(() => setOpen(false));
5202
+ refImpl._bindUpdate((patch) => setOpts((prev) => ({ ...prev, ...patch })));
5203
+ }, [refImpl]);
5204
+ useExitTeardown(open, refImpl);
5205
+ return /* @__PURE__ */ jsxRuntime.jsx(
5206
+ SConfirmModal,
5207
+ {
5208
+ ...opts,
5209
+ open,
5210
+ onOpenChange: (o) => {
5211
+ if (!o) refImpl._markDismissed();
5212
+ setOpen(o);
5213
+ },
5214
+ onOk: () => refImpl._emitOk(),
5215
+ onCancel: () => refImpl._emitCancel(),
5216
+ onClose: () => refImpl._emitClose()
5217
+ }
5218
+ );
5219
+ }
5220
+ function LoadingMount({ options, refImpl }) {
5221
+ const [open, setOpen] = react.useState(true);
5222
+ const [opts, setOpts] = react.useState(options);
5223
+ const buttonClicked = react.useRef(false);
5224
+ react.useEffect(() => {
5225
+ refImpl._bindClose(() => setOpen(false));
5226
+ refImpl._bindUpdate((patch) => setOpts((prev) => ({ ...prev, ...patch })));
5227
+ }, [refImpl]);
5228
+ useExitTeardown(open, refImpl);
5229
+ return /* @__PURE__ */ jsxRuntime.jsx(
5230
+ SLoadingModal,
5231
+ {
5232
+ ...opts,
5233
+ open,
5234
+ onOpenChange: (o) => {
5235
+ if (!o && buttonClicked.current) {
5236
+ buttonClicked.current = false;
5237
+ return;
5238
+ }
5239
+ if (!o) refImpl._markDismissed();
5240
+ setOpen(o);
5241
+ },
5242
+ onClose: () => refImpl._emitClose(),
5243
+ onButtonClick: () => {
5244
+ buttonClicked.current = true;
5245
+ refImpl._emitClick();
5246
+ }
5247
+ }
5248
+ );
5249
+ }
5250
+ function warnIfNotModal(host, component) {
5251
+ if (typeof process !== "undefined" && process?.env?.NODE_ENV === "production") return;
5252
+ if (!host || host.childElementCount === 0) return;
5253
+ const name = component?.name || "component";
5254
+ console.warn(
5255
+ `[SModal.create] ${name} \uC774(\uAC00) \uBAA8\uB2EC\uC744 \uB744\uC6B0\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. create \uB294 \uCEE8\uD14C\uC774\uB108\uB97C \uB367\uC50C\uC6B0\uC9C0 \uC54A\uC73C\uBBC0\uB85C component \uB294 \uB8E8\uD2B8\uC5D0 SActionModal \uC744 \uB80C\uB354\uD558\uACE0, \uC8FC\uC785\uBC1B\uC740 open/onOpenChange/onClose \uB97C \uADF8\uB300\uB85C \uC804\uB2EC\uD574\uC57C \uD569\uB2C8\uB2E4. \uD655\uC778/\uCDE8\uC18C\uB294 SModal.confirm, \uB85C\uB529\uC740 SModal.loading \uC744 \uC0AC\uC6A9\uD558\uC138\uC694.`
5256
+ );
5257
+ }
5258
+ function CreateMount({ options, refImpl }) {
5259
+ const { component: Component, componentProps } = options;
5260
+ const [open, setOpen] = react.useState(true);
5261
+ react.useEffect(() => {
5262
+ refImpl._bindClose(() => setOpen(false));
5263
+ refImpl._bindUpdate(() => {
5264
+ });
5265
+ warnIfNotModal(refImpl._getHost(), Component);
5266
+ }, [refImpl, Component]);
5267
+ useExitTeardown(open, refImpl);
5268
+ const componentAllProps = {
5269
+ ...componentProps,
5270
+ open,
5271
+ onOpenChange: (o) => {
5272
+ if (!o) refImpl._markDismissed();
5273
+ setOpen(o);
5274
+ },
5275
+ onClose: () => refImpl._emitClose(),
5276
+ modalRef: refImpl
5277
+ };
5278
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...componentAllProps });
5279
+ }
5280
+ function mount(render) {
5281
+ const host = document.createElement("div");
5282
+ document.body.appendChild(host);
5283
+ const refImpl = new SModalRefImpl();
5284
+ const root = client.createRoot(host);
5285
+ refImpl._setTeardown(root, host);
5286
+ root.render(render(refImpl));
5287
+ return refImpl;
5288
+ }
5289
+ var SModal = {
5290
+ /** 확인/취소 모달을 즉시 띄운다. 반환 핸들에 onOk/onCancel/onClose/onDismissed 체이닝. */
5291
+ confirm(options) {
5292
+ return mount((refImpl) => /* @__PURE__ */ jsxRuntime.jsx(ConfirmMount, { options, refImpl }));
5293
+ },
5294
+ /**
5295
+ * 로딩(스피너/에러) 모달을 즉시 띄운다. 로딩 중 임의 닫힘 방지를 위해 persistent 기본 true.
5296
+ * 버튼 클릭은 자동 닫힘 없이 onClick 만 발화 — update()/close() 로 후속 동작을 결정한다.
5297
+ */
5298
+ loading(options = {}) {
5299
+ return mount((refImpl) => /* @__PURE__ */ jsxRuntime.jsx(LoadingMount, { options: { persistent: true, ...options }, refImpl }));
5300
+ },
5301
+ /**
5302
+ * SActionModal 을 루트로 렌더하는 컴포넌트를 띄운다. 컨테이너를 덧씌우지 않고 표시 제어
5303
+ * (open/onOpenChange/onClose)와 modalRef 만 주입하며, 닫힘 애니메이션 종료 후 자동으로
5304
+ * 언마운트한다. 컴포넌트가 모달을 띄우지 않으면 개발 모드에서 경고한다.
5305
+ */
5306
+ create(options) {
5307
+ return mount((refImpl) => /* @__PURE__ */ jsxRuntime.jsx(CreateMount, { options, refImpl }));
5308
+ }
5309
+ };
5042
5310
 
5043
5311
  // src/components/SGnb/gnb.config.ts
5044
5312
  var gnb = (p) => `var(--cmp-gnb-${p})`;
@@ -7509,7 +7777,7 @@ var STable = react.forwardRef(function STable2({
7509
7777
  rowBg,
7510
7778
  "group-hover:bg-[var(--color-grey-05)]",
7511
7779
  stickyShadowClass(i),
7512
- col.tdClass
7780
+ typeof col.tdClass === "function" ? col.tdClass(row) : col.tdClass
7513
7781
  ),
7514
7782
  style: {
7515
7783
  paddingLeft: cellPadX,
@@ -11634,6 +11902,7 @@ exports.SLinearProgress = SLinearProgress;
11634
11902
  exports.SLoadingContainer = SLoadingContainer;
11635
11903
  exports.SLoadingModal = SLoadingModal;
11636
11904
  exports.SLoadingViewport = SLoadingViewport;
11905
+ exports.SModal = SModal;
11637
11906
  exports.SNumberInput = SNumberInput;
11638
11907
  exports.SPage = SPage;
11639
11908
  exports.SPagination = SPagination;