sellmate-design-system-react 1.1.1 → 1.2.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 (58) hide show
  1. package/dist/components/SActionModal/SActionModal.cjs +7 -0
  2. package/dist/components/SActionModal/SActionModal.cjs.map +1 -1
  3. package/dist/components/SActionModal/SActionModal.d.ts +1 -0
  4. package/dist/components/SActionModal/SActionModal.js +8 -1
  5. package/dist/components/SActionModal/SActionModal.js.map +1 -1
  6. package/dist/components/SConfirmModal/SConfirmModal.cjs +6 -0
  7. package/dist/components/SConfirmModal/SConfirmModal.cjs.map +1 -1
  8. package/dist/components/SConfirmModal/SConfirmModal.js +7 -1
  9. package/dist/components/SConfirmModal/SConfirmModal.js.map +1 -1
  10. package/dist/components/SGnb/SGnb.cjs.map +1 -1
  11. package/dist/components/SGnb/SGnb.js.map +1 -1
  12. package/dist/components/SKeyValueTable/SKeyValueTable.cjs +2 -2
  13. package/dist/components/SKeyValueTable/SKeyValueTable.cjs.map +1 -1
  14. package/dist/components/SKeyValueTable/SKeyValueTable.js +2 -2
  15. package/dist/components/SKeyValueTable/SKeyValueTable.js.map +1 -1
  16. package/dist/components/SLoadingModal/SLoadingModal.cjs +6 -0
  17. package/dist/components/SLoadingModal/SLoadingModal.cjs.map +1 -1
  18. package/dist/components/SLoadingModal/SLoadingModal.js +7 -1
  19. package/dist/components/SLoadingModal/SLoadingModal.js.map +1 -1
  20. package/dist/components/SModal/SModal.cjs +6 -0
  21. package/dist/components/SModal/SModal.cjs.map +1 -1
  22. package/dist/components/SModal/SModal.js +6 -0
  23. package/dist/components/SModal/SModal.js.map +1 -1
  24. package/dist/components/SModalContainer/SModalContainer.cjs +6 -0
  25. package/dist/components/SModalContainer/SModalContainer.cjs.map +1 -1
  26. package/dist/components/SModalContainer/SModalContainer.js +7 -1
  27. package/dist/components/SModalContainer/SModalContainer.js.map +1 -1
  28. package/dist/components/SPage/SPage.cjs +3 -3
  29. package/dist/components/SPage/SPage.cjs.map +1 -1
  30. package/dist/components/SPage/SPage.js +3 -3
  31. package/dist/components/SPage/SPage.js.map +1 -1
  32. package/dist/components/SPopup/SPopup.cjs +2 -2
  33. package/dist/components/SPopup/SPopup.cjs.map +1 -1
  34. package/dist/components/SPopup/SPopup.js +2 -2
  35. package/dist/components/SPopup/SPopup.js.map +1 -1
  36. package/dist/components/SScrollArea/SScrollArea.cjs +2 -2
  37. package/dist/components/SScrollArea/SScrollArea.cjs.map +1 -1
  38. package/dist/components/SScrollArea/SScrollArea.js +2 -2
  39. package/dist/components/SScrollArea/SScrollArea.js.map +1 -1
  40. package/dist/components/SSelect/SSelect.cjs +2 -2
  41. package/dist/components/SSelect/SSelect.cjs.map +1 -1
  42. package/dist/components/SSelect/SSelect.js +2 -2
  43. package/dist/components/SSelect/SSelect.js.map +1 -1
  44. package/dist/components/STable/STable.cjs +137 -95
  45. package/dist/components/STable/STable.cjs.map +1 -1
  46. package/dist/components/STable/STable.d.ts +1 -1
  47. package/dist/components/STable/STable.js +137 -95
  48. package/dist/components/STable/STable.js.map +1 -1
  49. package/dist/index.cjs +145 -96
  50. package/dist/index.cjs.map +1 -1
  51. package/dist/index.js +145 -96
  52. package/dist/index.js.map +1 -1
  53. package/dist/lib/scrollbar.cjs +3 -3
  54. package/dist/lib/scrollbar.cjs.map +1 -1
  55. package/dist/lib/scrollbar.js +3 -3
  56. package/dist/lib/scrollbar.js.map +1 -1
  57. package/dist/styles.css +33 -3
  58. package/package.json +1 -1
@@ -43,8 +43,8 @@ function cn(...inputs) {
43
43
  // src/lib/scrollbar.ts
44
44
  var FIREFOX_SCROLLBAR_CLASS = "supports-[not_selector(::-webkit-scrollbar)]:[scrollbar-width:thin] supports-[not_selector(::-webkit-scrollbar)]:[scrollbar-color:var(--color-grey-45)_transparent]";
45
45
  var SCROLLBAR_CLASS = `${FIREFOX_SCROLLBAR_CLASS} [&::-webkit-scrollbar]:h-[12px] [&::-webkit-scrollbar]:w-[12px] [&::-webkit-scrollbar]:bg-transparent [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:border-2 [&::-webkit-scrollbar-thumb]:border-solid [&::-webkit-scrollbar-thumb]:border-transparent [&::-webkit-scrollbar-thumb]:bg-[var(--color-grey-45)] [&::-webkit-scrollbar-thumb]:bg-clip-padding`;
46
- var SCROLLBAR_TRACK_BG_CLASS = "supports-[not_selector(::-webkit-scrollbar)]:[scrollbar-color:var(--color-grey-45)_var(--color-grey-10)] [&::-webkit-scrollbar]:bg-[var(--color-grey-10)] [&::-webkit-scrollbar-track]:bg-[var(--color-grey-10)]";
47
- var SCROLLBAR_TRACK_BORDER_CLASS = "[&::-webkit-scrollbar-track:vertical]:[border-left:1px_solid_var(--sys-color-border-default)] [&::-webkit-scrollbar-track:horizontal]:[border-top:1px_solid_var(--sys-color-border-default)] [&::-webkit-scrollbar-thumb:vertical]:[border-left-width:3px] [&::-webkit-scrollbar-thumb:horizontal]:[border-top-width:3px]";
46
+ var SCROLLBAR_TRACK_BG_CLASS = "supports-[not_selector(::-webkit-scrollbar)]:[scrollbar-color:var(--color-grey-45)_var(--color-grey-10)] [&::-webkit-scrollbar]:bg-[var(--color-grey-10)] [&::-webkit-scrollbar-track]:bg-[var(--color-grey-10)] [&::-webkit-scrollbar-corner]:bg-[var(--color-grey-10)]";
47
+ var SCROLLBAR_TRACK_BORDER_CLASS = "[&::-webkit-scrollbar-track:vertical]:[border-left:1px_solid_var(--sys-color-border-default)] [&::-webkit-scrollbar-track:horizontal]:[border-top:1px_solid_var(--sys-color-border-default)] [&::-webkit-scrollbar-corner]:[border-top:1px_solid_var(--sys-color-border-default)] [&::-webkit-scrollbar-corner]:[border-left:1px_solid_var(--sys-color-border-default)] [&::-webkit-scrollbar-thumb:vertical]:[border-left-width:3px] [&::-webkit-scrollbar-thumb:horizontal]:[border-top-width:3px]";
48
48
 
49
49
  // src/lib/color.ts
50
50
  var COLOR_KEYS = [
@@ -4528,7 +4528,6 @@ var STable = react.forwardRef(function STable2({
4528
4528
  resizable = false,
4529
4529
  width,
4530
4530
  height,
4531
- stickyHeader = false,
4532
4531
  stickyColumn,
4533
4532
  radius = "default",
4534
4533
  noDataLabel = "\uB370\uC774\uD130\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.",
@@ -4594,6 +4593,8 @@ var STable = react.forwardRef(function STable2({
4594
4593
  const [rowCountOverride, setRowCountOverride] = react.useState(null);
4595
4594
  const rowCount = rowCountOverride ?? rows.length;
4596
4595
  const scrollRef = react.useRef(null);
4596
+ const headerScrollRef = react.useRef(null);
4597
+ const [headerGutter, setHeaderGutter] = react.useState(0);
4597
4598
  const [vsRange, setVsRange] = react.useState({ start: 0, end: 0 });
4598
4599
  const lastReachEndRef = react.useRef(-1);
4599
4600
  const cbRef = react.useRef({ onVirtualUpdate, onVirtualReachEnd });
@@ -4618,6 +4619,9 @@ var STable = react.forwardRef(function STable2({
4618
4619
  const handleScroll = react.useCallback(() => {
4619
4620
  const el = scrollRef.current;
4620
4621
  if (!el) return;
4622
+ const header = headerScrollRef.current;
4623
+ if (header) header.scrollLeft = el.scrollLeft;
4624
+ setHeaderGutter(el.offsetWidth - el.clientWidth);
4621
4625
  setScrolledLeft(el.scrollLeft > 0);
4622
4626
  setScrolledRight(el.scrollLeft + el.clientWidth < el.scrollWidth - 1);
4623
4627
  if (useVirtualScroll) {
@@ -4627,7 +4631,7 @@ var STable = react.forwardRef(function STable2({
4627
4631
  }, [useVirtualScroll, calcRange]);
4628
4632
  react.useEffect(() => {
4629
4633
  handleScroll();
4630
- }, [handleScroll, rowCount, columnWidths]);
4634
+ }, [handleScroll, rowCount, columnWidths, isLoading, height]);
4631
4635
  react.useEffect(() => {
4632
4636
  if (!useVirtualScroll) return;
4633
4637
  cbRef.current.onVirtualUpdate?.({ from: vsRange.start, to: vsRange.end });
@@ -4807,6 +4811,10 @@ var STable = react.forwardRef(function STable2({
4807
4811
  isRightEdge && scrolledRight && "shadow-[-5px_0_8px_0_rgba(34,34,34,0.1)]"
4808
4812
  );
4809
4813
  };
4814
+ const colgroup = /* @__PURE__ */ jsxRuntime.jsxs("colgroup", { children: [
4815
+ selectable && /* @__PURE__ */ jsxRuntime.jsx("col", { style: { width: SELECTABLE_COLUMN_WIDTH } }),
4816
+ visibleCols.map((col, i) => /* @__PURE__ */ jsxRuntime.jsx("col", { style: col.autoWidth ? void 0 : { width: columnWidths[i] } }, col.name))
4817
+ ] });
4810
4818
  return /* @__PURE__ */ jsxRuntime.jsxs(
4811
4819
  "div",
4812
4820
  {
@@ -4817,42 +4825,45 @@ var STable = react.forwardRef(function STable2({
4817
4825
  /* @__PURE__ */ jsxRuntime.jsxs(
4818
4826
  "div",
4819
4827
  {
4820
- ref: scrollRef,
4821
- onScroll: handleScroll,
4822
4828
  className: cn(
4823
- "bg-white relative overflow-auto border border-solid border-[color:var(--cmp-table-border-color)]",
4824
- SCROLLBAR_CLASS,
4825
- SCROLLBAR_TRACK_BG_CLASS,
4826
- SCROLLBAR_TRACK_BORDER_CLASS,
4829
+ "bg-white relative flex flex-col overflow-hidden border border-solid border-[color:var(--cmp-table-border-color)]",
4830
+ // height가 없으면 루트가 받은 높이를 끝까지 채운다. 호스트가 className으로
4831
+ // `flex-1 min-h-0` 등을 줘 루트 높이가 확정된 경우, 행이 적어도 테두리 박스가
4832
+ // 남은 영역을 그대로 차지한다. basis는 auto로 둬 높이가 확정되지 않은
4833
+ // 기본 사용(내용만큼 커지는 케이스)에서는 동작이 바뀌지 않는다.
4834
+ !height && "min-h-0 grow",
4827
4835
  radiusClass,
4828
- // 원본 sd-table__scroll-container--loading/--no-data: 로딩·데이터 없음 시 스크롤·인터랙션 차단
4829
- (isLoading || rowCount === 0) && "overflow-hidden pointer-events-none"
4836
+ // 원본 sd-table__scroll-container--loading/--no-data: 로딩·데이터 없음 시 인터랙션 차단
4837
+ (isLoading || rowCount === 0) && "pointer-events-none"
4830
4838
  ),
4831
4839
  style: {
4832
4840
  height,
4833
4841
  minHeight: isNoData ? "calc(var(--cmp-table-header-height) + 60px)" : void 0
4834
4842
  },
4835
4843
  children: [
4836
- /* @__PURE__ */ jsxRuntime.jsxs(
4837
- "table",
4844
+ /* @__PURE__ */ jsxRuntime.jsx(
4845
+ "div",
4838
4846
  {
4839
- className: "w-full table-fixed border-separate border-spacing-0 text-left",
4840
- style: { fontSize: 12 },
4841
- children: [
4842
- /* @__PURE__ */ jsxRuntime.jsx("thead", { className: cn(isNoData && "opacity-40"), children: /* @__PURE__ */ jsxRuntime.jsxs(
4843
- "tr",
4844
- {
4845
- className: cn(
4846
- "h-[var(--cmp-table-header-height)] bg-[var(--cmp-table-header-bg)]",
4847
- stickyHeader && "sticky top-0 z-20"
4848
- ),
4849
- children: [
4847
+ ref: headerScrollRef,
4848
+ className: "flex-none overflow-hidden",
4849
+ style: {
4850
+ borderRight: headerGutter ? `${headerGutter}px solid var(--cmp-table-header-bg)` : void 0
4851
+ },
4852
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
4853
+ "table",
4854
+ {
4855
+ className: "w-full table-fixed border-separate border-spacing-0 text-left",
4856
+ style: { fontSize: 12 },
4857
+ children: [
4858
+ colgroup,
4859
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { className: cn(isNoData && "opacity-40"), children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "h-[var(--cmp-table-header-height)] bg-[var(--cmp-table-header-bg)]", children: [
4850
4860
  selectable && /* @__PURE__ */ jsxRuntime.jsxs(
4851
4861
  "th",
4852
4862
  {
4853
4863
  className: cn(
4854
4864
  // 원본 .th--selected: 48px 고정폭, 항상 left sticky, 체크박스 중앙정렬
4855
- "sticky left-0 z-[7] border-b border-solid border-[color:var(--cmp-table-border-color)] bg-[var(--cmp-table-header-bg)] text-center align-middle",
4865
+ // 하단 border 헤더 래퍼가 연속으로 그리므로 셀에는 두지 않는다.
4866
+ "sticky left-0 z-[7] bg-[var(--cmp-table-header-bg)] text-center align-middle",
4856
4867
  stickyLeft === 0 && scrolledLeft && "shadow-[5px_0_8px_0_rgba(34,34,34,0.1)]"
4857
4868
  ),
4858
4869
  style: {
@@ -4876,7 +4887,8 @@ var STable = react.forwardRef(function STable2({
4876
4887
  "th",
4877
4888
  {
4878
4889
  className: cn(
4879
- "relative border-b border-solid border-[color:var(--cmp-table-border-color)] bg-[var(--cmp-table-header-bg)] px-[16px] text-[12px] font-medium leading-[20px] text-[color:var(--sys-color-fg-primary)]",
4890
+ // 하단 border 헤더 래퍼가 연속으로 그린다 (거터 영역까지 이어짐).
4891
+ "relative bg-[var(--cmp-table-header-bg)] px-[16px] text-[12px] font-medium leading-[20px] text-[color:var(--sys-color-fg-primary)]",
4880
4892
  stickyInfo(i).isSticky && "z-[6]",
4881
4893
  stickyShadowClass(i),
4882
4894
  col.thClass
@@ -4914,74 +4926,102 @@ var STable = react.forwardRef(function STable2({
4914
4926
  },
4915
4927
  col.name
4916
4928
  ))
4917
- ]
4918
- }
4919
- ) }),
4920
- /* @__PURE__ */ jsxRuntime.jsxs("tbody", { children: [
4921
- useVirtualScroll && topSpacer > 0 && /* @__PURE__ */ jsxRuntime.jsx("tr", { "aria-hidden": true, style: { height: topSpacer }, children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: totalColSpan, className: "p-0" }) }),
4922
- rowCount === 0 ? null : bodyRows.map((row, ri) => {
4923
- const isSel = selectedKeys.has(row[rowKey]);
4924
- const rowBg = "bg-white";
4925
- return /* @__PURE__ */ jsxRuntime.jsxs(
4926
- "tr",
4927
- {
4928
- onClick: () => onRowClick?.(row),
4929
- className: cn(
4930
- "group/table-row hover:bg-[var(--color-grey-05)]",
4931
- onRowClick && "cursor-pointer"
4932
- ),
4933
- style: { height: useVirtualScroll ? effectiveRowHeight : rowH },
4934
- children: [
4935
- selectable && /* @__PURE__ */ jsxRuntime.jsx(
4936
- "td",
4937
- {
4938
- className: cn(
4939
- // 원본 .td--selected: 48px 고정폭, 항상 left sticky, 체크박스 중앙정렬
4940
- "sticky left-0 z-[2] border-b border-solid border-[color:var(--cmp-table-border-color)] align-middle group-hover/table-row:bg-[var(--color-grey-05)]",
4941
- rowBg,
4942
- stickyLeft === 0 && scrolledLeft && "shadow-[5px_0_8px_0_rgba(34,34,34,0.1)]"
4943
- ),
4944
- style: {
4945
- width: SELECTABLE_COLUMN_WIDTH,
4946
- minWidth: SELECTABLE_COLUMN_WIDTH,
4947
- maxWidth: SELECTABLE_COLUMN_WIDTH
4948
- },
4949
- onClick: (e) => e.stopPropagation(),
4950
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(SCheckbox, { value: isSel, onValueChange: () => toggleRow(row) }) })
4951
- }
4952
- ),
4953
- visibleCols.map((col, i) => /* @__PURE__ */ jsxRuntime.jsx(
4954
- "td",
4955
- {
4956
- className: cn(
4957
- // 원본 .td: 컬럼 폭에 맞춰 내용 말줄임(overflow hidden + ellipsis) + 행 구분선(border-b)
4958
- // 셀 배경은 흰색으로 채워 뒤 배경이 비치지 않게 하고, hover 시 행 배경(grey_05)을 따른다.
4959
- "overflow-hidden text-ellipsis whitespace-nowrap border-b border-solid border-[color:var(--cmp-table-border-color)] text-[12px] leading-[20px] text-[color:var(--sys-color-fg-primary)]",
4960
- rowBg,
4961
- "group-hover/table-row:bg-[var(--color-grey-05)]",
4962
- stickyShadowClass(i),
4963
- typeof col.tdClass === "function" ? col.tdClass(row) : col.tdClass
4929
+ ] }) })
4930
+ ]
4931
+ }
4932
+ )
4933
+ }
4934
+ ),
4935
+ /* @__PURE__ */ jsxRuntime.jsx(
4936
+ "div",
4937
+ {
4938
+ ref: scrollRef,
4939
+ onScroll: handleScroll,
4940
+ className: cn(
4941
+ // 헤더 하단 구분선은 body 상단 border로 그린다. body 래퍼는 스크롤바를 포함한
4942
+ // 전체 폭을 차지하므로(스크롤바는 border 안쪽) 헤더 거터의 border-right와 미터가
4943
+ // 생기지 않아 색·길이가 균일한 한 줄이 된다.
4944
+ "min-h-0 flex-1 overflow-auto border-t border-solid border-[color:var(--cmp-table-border-color)]",
4945
+ SCROLLBAR_CLASS,
4946
+ SCROLLBAR_TRACK_BG_CLASS,
4947
+ SCROLLBAR_TRACK_BORDER_CLASS,
4948
+ // 원본 sd-table__scroll-container--loading/--no-data: 로딩·데이터 없음 시 스크롤 차단
4949
+ (isLoading || rowCount === 0) && "overflow-hidden"
4950
+ ),
4951
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
4952
+ "table",
4953
+ {
4954
+ className: "w-full table-fixed border-separate border-spacing-0 text-left",
4955
+ style: { fontSize: 12 },
4956
+ children: [
4957
+ colgroup,
4958
+ /* @__PURE__ */ jsxRuntime.jsxs("tbody", { children: [
4959
+ useVirtualScroll && topSpacer > 0 && /* @__PURE__ */ jsxRuntime.jsx("tr", { "aria-hidden": true, style: { height: topSpacer }, children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: totalColSpan, className: "p-0" }) }),
4960
+ rowCount === 0 ? null : bodyRows.map((row, ri) => {
4961
+ const isSel = selectedKeys.has(row[rowKey]);
4962
+ const rowBg = "bg-white";
4963
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4964
+ "tr",
4965
+ {
4966
+ onClick: () => onRowClick?.(row),
4967
+ className: cn(
4968
+ "group/table-row hover:bg-[var(--color-grey-05)]",
4969
+ onRowClick && "cursor-pointer"
4970
+ ),
4971
+ style: { height: useVirtualScroll ? effectiveRowHeight : rowH },
4972
+ children: [
4973
+ selectable && /* @__PURE__ */ jsxRuntime.jsx(
4974
+ "td",
4975
+ {
4976
+ className: cn(
4977
+ // 원본 .td--selected: 48px 고정폭, 항상 left sticky, 체크박스 중앙정렬
4978
+ "sticky left-0 z-[2] border-b border-solid border-[color:var(--cmp-table-border-color)] align-middle group-hover/table-row:bg-[var(--color-grey-05)]",
4979
+ rowBg,
4980
+ stickyLeft === 0 && scrolledLeft && "shadow-[5px_0_8px_0_rgba(34,34,34,0.1)]"
4981
+ ),
4982
+ style: {
4983
+ width: SELECTABLE_COLUMN_WIDTH,
4984
+ minWidth: SELECTABLE_COLUMN_WIDTH,
4985
+ maxWidth: SELECTABLE_COLUMN_WIDTH
4986
+ },
4987
+ onClick: (e) => e.stopPropagation(),
4988
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(SCheckbox, { value: isSel, onValueChange: () => toggleRow(row) }) })
4989
+ }
4964
4990
  ),
4965
- style: {
4966
- paddingLeft: cellPadX,
4967
- paddingRight: cellPadX,
4968
- paddingTop: cellPadY,
4969
- paddingBottom: cellPadY,
4970
- textAlign: col.align ?? "left",
4971
- ...cellStyle(i)
4972
- },
4973
- children: col.render ? col.render(row, cellValue(col, row)) : cellValue(col, row)
4974
- },
4975
- col.name
4976
- ))
4977
- ]
4978
- },
4979
- row[rowKey] ?? ri
4980
- );
4981
- }),
4982
- useVirtualScroll && bottomSpacer > 0 && /* @__PURE__ */ jsxRuntime.jsx("tr", { "aria-hidden": true, style: { height: bottomSpacer }, children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: totalColSpan, className: "p-0" }) })
4983
- ] })
4984
- ]
4991
+ visibleCols.map((col, i) => /* @__PURE__ */ jsxRuntime.jsx(
4992
+ "td",
4993
+ {
4994
+ className: cn(
4995
+ // 원본 .td: 컬럼 폭에 맞춰 내용 말줄임(overflow hidden + ellipsis) + 행 구분선(border-b)
4996
+ // 배경은 흰색으로 채워 뒤 배경이 비치지 않게 하고, hover 시 행 배경(grey_05)을 따른다.
4997
+ "overflow-hidden text-ellipsis whitespace-nowrap border-b border-solid border-[color:var(--cmp-table-border-color)] text-[12px] leading-[20px] text-[color:var(--sys-color-fg-primary)]",
4998
+ rowBg,
4999
+ "group-hover/table-row:bg-[var(--color-grey-05)]",
5000
+ stickyShadowClass(i),
5001
+ typeof col.tdClass === "function" ? col.tdClass(row) : col.tdClass
5002
+ ),
5003
+ style: {
5004
+ paddingLeft: cellPadX,
5005
+ paddingRight: cellPadX,
5006
+ paddingTop: cellPadY,
5007
+ paddingBottom: cellPadY,
5008
+ textAlign: col.align ?? "left",
5009
+ ...cellStyle(i)
5010
+ },
5011
+ children: col.render ? col.render(row, cellValue(col, row)) : cellValue(col, row)
5012
+ },
5013
+ col.name
5014
+ ))
5015
+ ]
5016
+ },
5017
+ row[rowKey] ?? ri
5018
+ );
5019
+ }),
5020
+ useVirtualScroll && bottomSpacer > 0 && /* @__PURE__ */ jsxRuntime.jsx("tr", { "aria-hidden": true, style: { height: bottomSpacer }, children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: totalColSpan, className: "p-0" }) })
5021
+ ] })
5022
+ ]
5023
+ }
5024
+ )
4985
5025
  }
4986
5026
  ),
4987
5027
  isNoData && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -5000,7 +5040,9 @@ var STable = react.forwardRef(function STable2({
5000
5040
  ),
5001
5041
  showPagination && // 원본 sd-table__pagination: 테이블 하단에 이어붙는 회색 바(높이 48px, margin-top:-1px로 테두리 겹침).
5002
5042
  // SPagination은 전체 폭 기준 중앙, rows-per-page SSelect는 우측에 absolute 배치해 중앙 정렬을 유지한다.
5003
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative -mt-px flex h-[48px] items-center justify-center rounded-[var(--cmp-table-radius)] border border-solid border-[color:var(--cmp-table-border-color)] bg-[var(--color-grey-05)]", children: [
5043
+ // 루트 높이가 확정된 경우(테이블이 남은 영역을 채우는 배치) 페이지네이션 바가
5044
+ // 눌리지 않도록 shrink-0으로 48px를 보장한다.
5045
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative -mt-px flex h-[48px] shrink-0 items-center justify-center rounded-[var(--cmp-table-radius)] border border-solid border-[color:var(--cmp-table-border-color)] bg-[var(--color-grey-05)]", children: [
5004
5046
  /* @__PURE__ */ jsxRuntime.jsx(SPagination, { currentPage: displayPage, lastPage, onPageChange: changePage }),
5005
5047
  useRowsPerPageSelect && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-[10px] top-1/2 -translate-y-1/2", children: /* @__PURE__ */ jsxRuntime.jsx(
5006
5048
  SSelect,