sellmate-design-system-react 0.6.0 → 0.7.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 (91) hide show
  1. package/dist/components/SBarcodeInput/SBarcodeInput.cjs +2 -0
  2. package/dist/components/SBarcodeInput/SBarcodeInput.cjs.map +1 -1
  3. package/dist/components/SBarcodeInput/SBarcodeInput.js +2 -0
  4. package/dist/components/SBarcodeInput/SBarcodeInput.js.map +1 -1
  5. package/dist/components/SChipInput/SChipInput.cjs +2 -0
  6. package/dist/components/SChipInput/SChipInput.cjs.map +1 -1
  7. package/dist/components/SChipInput/SChipInput.js +2 -0
  8. package/dist/components/SChipInput/SChipInput.js.map +1 -1
  9. package/dist/components/SDatePicker/SDatePicker.cjs +2 -0
  10. package/dist/components/SDatePicker/SDatePicker.cjs.map +1 -1
  11. package/dist/components/SDatePicker/SDatePicker.js +2 -0
  12. package/dist/components/SDatePicker/SDatePicker.js.map +1 -1
  13. package/dist/components/SDateRangePicker/SDateRangePicker.cjs +2 -0
  14. package/dist/components/SDateRangePicker/SDateRangePicker.cjs.map +1 -1
  15. package/dist/components/SDateRangePicker/SDateRangePicker.js +2 -0
  16. package/dist/components/SDateRangePicker/SDateRangePicker.js.map +1 -1
  17. package/dist/components/SField/SField.cjs +2 -0
  18. package/dist/components/SField/SField.cjs.map +1 -1
  19. package/dist/components/SField/SField.d.ts +2 -0
  20. package/dist/components/SField/SField.js +2 -0
  21. package/dist/components/SField/SField.js.map +1 -1
  22. package/dist/components/SFilePicker/SFilePicker.cjs +2 -0
  23. package/dist/components/SFilePicker/SFilePicker.cjs.map +1 -1
  24. package/dist/components/SFilePicker/SFilePicker.js +2 -0
  25. package/dist/components/SFilePicker/SFilePicker.js.map +1 -1
  26. package/dist/components/SGnb/SGnb.cjs +21 -3
  27. package/dist/components/SGnb/SGnb.cjs.map +1 -1
  28. package/dist/components/SGnb/SGnb.js +21 -3
  29. package/dist/components/SGnb/SGnb.js.map +1 -1
  30. package/dist/components/SInput/SInput.cjs +2 -0
  31. package/dist/components/SInput/SInput.cjs.map +1 -1
  32. package/dist/components/SInput/SInput.js +2 -0
  33. package/dist/components/SInput/SInput.js.map +1 -1
  34. package/dist/components/SKeyValueTable/SKeyValueTable.cjs +14 -1
  35. package/dist/components/SKeyValueTable/SKeyValueTable.cjs.map +1 -1
  36. package/dist/components/SKeyValueTable/SKeyValueTable.js +14 -1
  37. package/dist/components/SKeyValueTable/SKeyValueTable.js.map +1 -1
  38. package/dist/components/SNumberInput/SNumberInput.cjs +2 -0
  39. package/dist/components/SNumberInput/SNumberInput.cjs.map +1 -1
  40. package/dist/components/SNumberInput/SNumberInput.js +2 -0
  41. package/dist/components/SNumberInput/SNumberInput.js.map +1 -1
  42. package/dist/components/SPopup/SPopup.cjs +18 -1
  43. package/dist/components/SPopup/SPopup.cjs.map +1 -1
  44. package/dist/components/SPopup/SPopup.js +18 -1
  45. package/dist/components/SPopup/SPopup.js.map +1 -1
  46. package/dist/components/SScrollArea/SScrollArea.cjs +64 -0
  47. package/dist/components/SScrollArea/SScrollArea.cjs.map +1 -0
  48. package/dist/components/SScrollArea/SScrollArea.d.ts +21 -0
  49. package/dist/components/SScrollArea/SScrollArea.js +62 -0
  50. package/dist/components/SScrollArea/SScrollArea.js.map +1 -0
  51. package/dist/components/SScrollArea/index.d.ts +2 -0
  52. package/dist/components/SScrollArea/scrollArea.config.d.ts +2 -0
  53. package/dist/components/SSelect/SSelect.cjs +14 -1
  54. package/dist/components/SSelect/SSelect.cjs.map +1 -1
  55. package/dist/components/SSelect/SSelect.js +14 -1
  56. package/dist/components/SSelect/SSelect.js.map +1 -1
  57. package/dist/components/SStepper/SStepper.cjs +3015 -0
  58. package/dist/components/SStepper/SStepper.cjs.map +1 -0
  59. package/dist/components/SStepper/SStepper.d.ts +16 -0
  60. package/dist/components/SStepper/SStepper.js +3013 -0
  61. package/dist/components/SStepper/SStepper.js.map +1 -0
  62. package/dist/components/SStepper/index.d.ts +2 -0
  63. package/dist/components/SStepper/stepper.config.d.ts +42 -0
  64. package/dist/components/STable/STable.cjs +17 -1
  65. package/dist/components/STable/STable.cjs.map +1 -1
  66. package/dist/components/STable/STable.js +17 -1
  67. package/dist/components/STable/STable.js.map +1 -1
  68. package/dist/components/STextarea/STextarea.cjs +2 -0
  69. package/dist/components/STextarea/STextarea.cjs.map +1 -1
  70. package/dist/components/STextarea/STextarea.js +2 -0
  71. package/dist/components/STextarea/STextarea.js.map +1 -1
  72. package/dist/components/STimePicker/STimePicker.cjs +31 -6
  73. package/dist/components/STimePicker/STimePicker.cjs.map +1 -1
  74. package/dist/components/STimePicker/STimePicker.js +31 -6
  75. package/dist/components/STimePicker/STimePicker.js.map +1 -1
  76. package/dist/components/STimeRangePicker/STimeRangePicker.cjs +33 -6
  77. package/dist/components/STimeRangePicker/STimeRangePicker.cjs.map +1 -1
  78. package/dist/components/STimeRangePicker/STimeRangePicker.js +33 -6
  79. package/dist/components/STimeRangePicker/STimeRangePicker.js.map +1 -1
  80. package/dist/index.cjs +323 -28
  81. package/dist/index.cjs.map +1 -1
  82. package/dist/index.d.ts +2 -0
  83. package/dist/index.js +320 -29
  84. package/dist/index.js.map +1 -1
  85. package/dist/lib/scrollbar.cjs +13 -0
  86. package/dist/lib/scrollbar.cjs.map +1 -0
  87. package/dist/lib/scrollbar.d.ts +20 -0
  88. package/dist/lib/scrollbar.js +9 -0
  89. package/dist/lib/scrollbar.js.map +1 -0
  90. package/dist/styles.css +115 -14
  91. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -5,6 +5,7 @@ export * from './components/SIcon';
5
5
  export * from './components/SBadge';
6
6
  export * from './components/SCard';
7
7
  export * from './components/SDivider';
8
+ export * from './components/SScrollArea';
8
9
  export * from './components/STag';
9
10
  export * from './components/SButton';
10
11
  export * from './components/SCallout';
@@ -29,6 +30,7 @@ export * from './components/SLayout';
29
30
  export * from './components/SPage';
30
31
  export * from './components/STabs';
31
32
  export * from './components/SPagination';
33
+ export * from './components/SStepper';
32
34
  export * from './components/STable';
33
35
  export * from './components/SKeyValueTable';
34
36
  export * from './components/SToast';
package/dist/index.js CHANGED
@@ -2909,6 +2909,51 @@ var SDivider = forwardRef(function SDivider2({ vertical = false, className, styl
2909
2909
  );
2910
2910
  });
2911
2911
 
2912
+ // src/lib/scrollbar.ts
2913
+ var FIREFOX_SCROLLBAR_CLASS = "supports-[not_selector(::-webkit-scrollbar)]:[scrollbar-width:thin] supports-[not_selector(::-webkit-scrollbar)]:[scrollbar-color:var(--color-grey-45)_transparent]";
2914
+ 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`;
2915
+ 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)]";
2916
+ 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]";
2917
+ var AXIS_CLASS = {
2918
+ vertical: "overflow-x-hidden overflow-y-auto",
2919
+ horizontal: "overflow-x-auto overflow-y-hidden",
2920
+ both: "overflow-auto"
2921
+ };
2922
+ var SScrollArea = forwardRef(function SScrollArea2({
2923
+ axis = "both",
2924
+ background = false,
2925
+ bordered = false,
2926
+ maxHeight,
2927
+ maxWidth,
2928
+ className,
2929
+ style,
2930
+ children,
2931
+ ...rest
2932
+ }, ref) {
2933
+ const mergedStyle = { ...style };
2934
+ if (maxHeight) mergedStyle.maxHeight = maxHeight;
2935
+ if (maxWidth) mergedStyle.maxWidth = maxWidth;
2936
+ return /* @__PURE__ */ jsx(
2937
+ "div",
2938
+ {
2939
+ ref,
2940
+ className: cn(
2941
+ AXIS_CLASS[axis],
2942
+ SCROLLBAR_CLASS,
2943
+ background && SCROLLBAR_TRACK_BG_CLASS,
2944
+ bordered && SCROLLBAR_TRACK_BORDER_CLASS,
2945
+ className
2946
+ ),
2947
+ style: mergedStyle,
2948
+ ...rest,
2949
+ children
2950
+ }
2951
+ );
2952
+ });
2953
+
2954
+ // src/components/SScrollArea/scrollArea.config.ts
2955
+ var SCROLL_AREA_AXES = ["vertical", "horizontal", "both"];
2956
+
2912
2957
  // src/components/STag/tag.config.ts
2913
2958
  var TAG_SHAPES = ["square", "pill"];
2914
2959
  var TAG_SIZES = ["xs", "sm", "md"];
@@ -4444,7 +4489,18 @@ var SPopup = forwardRef(function SPopup2({
4444
4489
  )
4445
4490
  }
4446
4491
  ),
4447
- /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-auto", children }),
4492
+ /* @__PURE__ */ jsx(
4493
+ "div",
4494
+ {
4495
+ className: cn(
4496
+ "min-h-0 flex-1 overflow-auto",
4497
+ SCROLLBAR_CLASS,
4498
+ SCROLLBAR_TRACK_BG_CLASS,
4499
+ SCROLLBAR_TRACK_BORDER_CLASS
4500
+ ),
4501
+ children
4502
+ }
4503
+ ),
4448
4504
  useFooter && /* @__PURE__ */ jsxs(
4449
4505
  "footer",
4450
4506
  {
@@ -5244,9 +5300,24 @@ var SGnb = forwardRef(function SGnb2({
5244
5300
  onMouseEnter: () => setHoveredKey(item.value),
5245
5301
  onMouseLeave: () => setHoveredKey((prev) => prev === item.value ? null : prev),
5246
5302
  children: [
5247
- depth === 1 && item.icon && /* @__PURE__ */ jsx(SIcon, { name: item.icon, size: M.depth1Icon, color: C.itemIcon, className: "shrink-0" }),
5303
+ depth === 1 && item.icon && /* @__PURE__ */ jsx(
5304
+ SIcon,
5305
+ {
5306
+ name: item.icon,
5307
+ size: M.depth1Icon,
5308
+ color: isSelected ? C.itemColorActive : C.itemIcon,
5309
+ className: "shrink-0"
5310
+ }
5311
+ ),
5248
5312
  /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1 overflow-hidden text-ellipsis whitespace-nowrap flex flex-no-wrap items-center", children: [
5249
- depth > 1 && iconBranch ? /* @__PURE__ */ jsx("div", { className: "w-[20px] h-[24px] flex items-center justify-center mr-[8px]", children: "-" }) : null,
5313
+ depth > 1 && iconBranch ? /* @__PURE__ */ jsx(
5314
+ "div",
5315
+ {
5316
+ className: "w-[20px] flex items-center justify-center mr-[8px]",
5317
+ style: { height: M.itemLineHeight },
5318
+ children: "-"
5319
+ }
5320
+ ) : null,
5250
5321
  item.label
5251
5322
  ] }),
5252
5323
  item.tag !== void 0 && item.tag !== "" && /* @__PURE__ */ jsx(
@@ -5305,10 +5376,11 @@ var SGnb = forwardRef(function SGnb2({
5305
5376
  }, [layout, railHasLeaf, showMenu]);
5306
5377
  const railFolded = folded && header === "fix";
5307
5378
  const rootWidth = header === "full" ? "100%" : folded ? GNB_COMMON.foldWidth : bodyWidth;
5379
+ const rightBorder = color === "light" ? `1px solid ${C.topBorder}` : void 0;
5308
5380
  const rootStyle = {
5309
5381
  width: rootWidth,
5310
5382
  transition: `width ${GNB_FOLD_MS}ms ease-out`,
5311
- ...header === "full" ? { gridArea: "1 / 1 / -1 / -1", pointerEvents: "none" } : { backgroundColor: C.panelBg },
5383
+ ...header === "full" ? { gridArea: "1 / 1 / -1 / -1", pointerEvents: "none" } : { backgroundColor: C.panelBg, borderRight: rightBorder },
5312
5384
  ...style
5313
5385
  };
5314
5386
  const hideAfterSlide = (hidden) => `visibility 0s linear ${hidden ? `${GNB_FOLD_MS}ms` : "0s"}`;
@@ -5475,6 +5547,8 @@ var SGnb = forwardRef(function SGnb2({
5475
5547
  paddingTop: M.bodyPaddingY,
5476
5548
  paddingBottom: M.bodyPaddingY,
5477
5549
  backgroundColor: C.panelBg,
5550
+ // full 은 상단바가 전폭이라 루트가 오른쪽 선을 못 그린다 → 메뉴 오른쪽(페이지 경계)이 대신 그린다.
5551
+ borderRight: header === "full" ? rightBorder : void 0,
5478
5552
  pointerEvents: "auto"
5479
5553
  },
5480
5554
  children: /* @__PURE__ */ jsx("ul", { className: "m-0 flex list-none flex-col p-0", children: menuItems.map((item) => renderItem(item, 1)) })
@@ -5731,6 +5805,165 @@ function SPagination({
5731
5805
  }
5732
5806
  );
5733
5807
  }
5808
+
5809
+ // src/components/SStepper/stepper.config.ts
5810
+ var STEPPER_SIZES = ["sm", "lg"];
5811
+ var V2 = (path) => `var(--cmp-stepper-${path})`;
5812
+ var STEPPER_SIZE_CONFIG = {
5813
+ sm: {
5814
+ sequenceSize: V2("sm-sequence-size"),
5815
+ fontSize: "12px",
5816
+ lineHeight: "20px",
5817
+ fontWeightActive: 700,
5818
+ fontWeightDefault: 500
5819
+ },
5820
+ lg: {
5821
+ sequenceSize: V2("lg-sequence-size"),
5822
+ fontSize: "14px",
5823
+ lineHeight: "24px",
5824
+ fontWeightActive: 700,
5825
+ fontWeightDefault: 500
5826
+ }
5827
+ };
5828
+ var STEPPER_LAYOUT = {
5829
+ containerGap: V2("container-gap"),
5830
+ itemGap: V2("item-gap"),
5831
+ dashWidth: V2("dash-width"),
5832
+ sequenceRadius: V2("sequence-radius"),
5833
+ sequenceBorderWidth: V2("sequence-border-witdh"),
5834
+ sequenceIcon: V2("sequence-icon")
5835
+ };
5836
+ var STEPPER_COLORS = {
5837
+ dash: V2("dash-color"),
5838
+ sequenceBorder: {
5839
+ active: V2("sequence-border-active"),
5840
+ default: V2("sequence-border-default"),
5841
+ completed: V2("sequence-border-completed")
5842
+ },
5843
+ sequenceBg: {
5844
+ active: V2("sequence-bg-active"),
5845
+ default: V2("sequence-bg-default"),
5846
+ completed: V2("sequence-bg-completed")
5847
+ },
5848
+ sequenceText: {
5849
+ active: V2("sequence-text-active"),
5850
+ default: V2("sequence-text-default")
5851
+ },
5852
+ text: {
5853
+ active: V2("text-active"),
5854
+ default: V2("text-default")
5855
+ }
5856
+ };
5857
+ function getItemValue(item, index) {
5858
+ return item.value ?? String(index + 1);
5859
+ }
5860
+ function SStepper({
5861
+ items,
5862
+ value,
5863
+ size = "sm",
5864
+ ariaLabel = "\uC9C4\uD589 \uB2E8\uACC4",
5865
+ className,
5866
+ style
5867
+ }) {
5868
+ const config = STEPPER_SIZE_CONFIG[size];
5869
+ const activeIndex = Math.max(
5870
+ 0,
5871
+ items.findIndex((item, index) => getItemValue(item, index) === value)
5872
+ );
5873
+ const getState = (index) => {
5874
+ if (index < activeIndex) return "completed";
5875
+ if (index === activeIndex) return "active";
5876
+ return "default";
5877
+ };
5878
+ return /* @__PURE__ */ jsx(
5879
+ "div",
5880
+ {
5881
+ role: "list",
5882
+ "aria-label": ariaLabel,
5883
+ className: cn("inline-flex items-center", className),
5884
+ style: {
5885
+ gap: STEPPER_LAYOUT.containerGap,
5886
+ fontSize: config.fontSize,
5887
+ lineHeight: config.lineHeight,
5888
+ ...style
5889
+ },
5890
+ children: items.map((item, index) => {
5891
+ const state2 = getState(index);
5892
+ const itemStyle = {
5893
+ gap: STEPPER_LAYOUT.itemGap,
5894
+ color: state2 === "active" ? STEPPER_COLORS.text.active : STEPPER_COLORS.text.default,
5895
+ fontWeight: state2 === "active" ? config.fontWeightActive : config.fontWeightDefault
5896
+ };
5897
+ const sequenceStyle = {
5898
+ width: config.sequenceSize,
5899
+ height: config.sequenceSize,
5900
+ flexBasis: config.sequenceSize,
5901
+ borderRadius: STEPPER_LAYOUT.sequenceRadius,
5902
+ borderWidth: STEPPER_LAYOUT.sequenceBorderWidth,
5903
+ borderColor: STEPPER_COLORS.sequenceBorder[state2],
5904
+ background: STEPPER_COLORS.sequenceBg[state2],
5905
+ color: state2 === "completed" ? STEPPER_COLORS.text.default : STEPPER_COLORS.sequenceText[state2]
5906
+ };
5907
+ const content = /* @__PURE__ */ jsxs(
5908
+ "span",
5909
+ {
5910
+ role: "listitem",
5911
+ "aria-current": state2 === "active" ? "step" : void 0,
5912
+ className: "inline-flex items-center whitespace-nowrap",
5913
+ style: itemStyle,
5914
+ children: [
5915
+ /* @__PURE__ */ jsx(
5916
+ "span",
5917
+ {
5918
+ "aria-hidden": true,
5919
+ className: "box-border inline-flex shrink-0 items-center justify-center border border-solid font-bold",
5920
+ style: sequenceStyle,
5921
+ children: state2 === "completed" ? /* @__PURE__ */ jsx(SIcon, { name: "check", size: STEPPER_LAYOUT.sequenceIcon, color: "currentColor" }) : index + 1
5922
+ }
5923
+ ),
5924
+ /* @__PURE__ */ jsx("span", { children: item.label })
5925
+ ]
5926
+ }
5927
+ );
5928
+ return /* @__PURE__ */ jsxs(
5929
+ "span",
5930
+ {
5931
+ className: "inline-flex items-center",
5932
+ style: { gap: STEPPER_LAYOUT.containerGap },
5933
+ children: [
5934
+ content,
5935
+ index < items.length - 1 && /* @__PURE__ */ jsx(
5936
+ "span",
5937
+ {
5938
+ "aria-hidden": true,
5939
+ className: "inline-flex h-px shrink-0 items-center",
5940
+ style: { width: STEPPER_LAYOUT.dashWidth, color: STEPPER_COLORS.dash },
5941
+ children: /* @__PURE__ */ jsxs(
5942
+ "svg",
5943
+ {
5944
+ width: "20",
5945
+ height: "1",
5946
+ viewBox: "0 0 20 1",
5947
+ fill: "none",
5948
+ xmlns: "http://www.w3.org/2000/svg",
5949
+ children: [
5950
+ /* @__PURE__ */ jsx("rect", { width: "1.6", height: "1", fill: "#888888" }),
5951
+ /* @__PURE__ */ jsx("rect", { x: "5", width: "3.3", height: "1", fill: "#888888" }),
5952
+ /* @__PURE__ */ jsx("rect", { x: "11.7", width: "3.3", height: "1", fill: "#888888" }),
5953
+ /* @__PURE__ */ jsx("rect", { x: "18.4", width: "1.6", height: "1", fill: "#888888" })
5954
+ ]
5955
+ }
5956
+ )
5957
+ }
5958
+ )
5959
+ ]
5960
+ },
5961
+ getItemValue(item, index)
5962
+ );
5963
+ })
5964
+ }
5965
+ );
5966
+ }
5734
5967
  function SCheckbox({
5735
5968
  value = false,
5736
5969
  val,
@@ -5859,6 +6092,7 @@ var SField = forwardRef(function SField2({
5859
6092
  disabled = false,
5860
6093
  readOnly = false,
5861
6094
  width,
6095
+ minWidth,
5862
6096
  multiline = false,
5863
6097
  borderless = false,
5864
6098
  children,
@@ -5955,6 +6189,7 @@ var SField = forwardRef(function SField2({
5955
6189
  // focused/hovered prop이 명시된 경우 강조를 즉시 반영
5956
6190
  ...interactive && !borderless && focused ? { boxShadow: "0px 0px 4px 0px #0071ff66" } : {},
5957
6191
  ...multiline ? { minHeight: s.height } : { height: s.height },
6192
+ "minWidth": cssLen(minWidth),
5958
6193
  "width": cssLen(width),
5959
6194
  "borderRadius": s.radius,
5960
6195
  "background": bgColor,
@@ -6336,7 +6571,12 @@ var SSelect = forwardRef(function SSelect2({
6336
6571
  "div",
6337
6572
  {
6338
6573
  ref: listRef,
6339
- className: "overflow-auto [scrollbar-width:auto] [&::-webkit-scrollbar]:w-[8px] [&::-webkit-scrollbar]:bg-[var(--color-grey-25)] [&::-webkit-scrollbar:horizontal]:h-[8px] [&::-webkit-scrollbar-thumb]:rounded-[4px] [&::-webkit-scrollbar-thumb]:bg-[var(--color-grey-45)] [&::-webkit-scrollbar-track]:bg-[var(--color-grey-25)]",
6574
+ className: cn(
6575
+ "overflow-auto",
6576
+ SCROLLBAR_CLASS,
6577
+ SCROLLBAR_TRACK_BG_CLASS,
6578
+ SCROLLBAR_TRACK_BORDER_CLASS
6579
+ ),
6340
6580
  style: { maxHeight: dropdownHeight },
6341
6581
  onMouseLeave: () => setFocusedIndex(-1),
6342
6582
  children: [
@@ -6851,6 +7091,9 @@ var STable = forwardRef(function STable2({
6851
7091
  onScroll: handleScroll,
6852
7092
  className: cn(
6853
7093
  "bg-white relative overflow-auto border border-solid border-[color:var(--cmp-table-border-color)]",
7094
+ SCROLLBAR_CLASS,
7095
+ SCROLLBAR_TRACK_BG_CLASS,
7096
+ SCROLLBAR_TRACK_BORDER_CLASS,
6854
7097
  radiusClass,
6855
7098
  // 원본 sd-table__scroll-container--loading/--no-data: 로딩·데이터 없음 시 스크롤·인터랙션 차단
6856
7099
  (isLoading || rowCount === 0) && "overflow-hidden pointer-events-none"
@@ -10168,15 +10411,15 @@ var SBarcodeInput = forwardRef(
10168
10411
  );
10169
10412
 
10170
10413
  // src/components/STimePicker/timepicker.config.ts
10171
- var V2 = (path) => `var(--cmp-timepicker-${path})`;
10414
+ var V3 = (path) => `var(--cmp-timepicker-${path})`;
10172
10415
  var TIMEPICKER_SIZES = ["sm", "md"];
10173
10416
  var TIMEPICKER_SIZE_CONFIG = {
10174
10417
  sm: {
10175
- height: V2("sm-height"),
10176
- paddingX: V2("sm-paddingX"),
10177
- gap: V2("sm-gap"),
10178
- icon: V2("sm-icon"),
10179
- radius: V2("sm-radius"),
10418
+ height: V3("sm-height"),
10419
+ paddingX: V3("sm-paddingX"),
10420
+ gap: V3("sm-gap"),
10421
+ icon: V3("sm-icon"),
10422
+ radius: V3("sm-radius"),
10180
10423
  // TODO: component.timepicker 토큰에 typography가 추가되면 CSS 변수로 교체한다.
10181
10424
  fontSize: 12,
10182
10425
  lineHeight: 20,
@@ -10184,11 +10427,11 @@ var TIMEPICKER_SIZE_CONFIG = {
10184
10427
  fieldMinWidth: 128
10185
10428
  },
10186
10429
  md: {
10187
- height: V2("md-height"),
10188
- paddingX: V2("md-paddingX"),
10189
- gap: V2("md-gap"),
10190
- icon: V2("md-icon"),
10191
- radius: V2("md-radius"),
10430
+ height: V3("md-height"),
10431
+ paddingX: V3("md-paddingX"),
10432
+ gap: V3("md-gap"),
10433
+ icon: V3("md-icon"),
10434
+ radius: V3("md-radius"),
10192
10435
  // TODO: component.timepicker 토큰에 typography가 추가되면 CSS 변수로 교체한다.
10193
10436
  fontSize: 14,
10194
10437
  lineHeight: 24,
@@ -10222,6 +10465,8 @@ function formatTimeDisplay(value, type) {
10222
10465
  const displayHour = hour % 12 === 0 ? 12 : hour % 12;
10223
10466
  return `${meridiem} ${padTimePart(displayHour)}:${padTimePart(minute)}`;
10224
10467
  }
10468
+ var TIME_SELECTOR_WIDTH = 136;
10469
+ var MERIDIEM_TIME_SELECTOR_WIDTH = 154;
10225
10470
  function TimeSelector({
10226
10471
  value,
10227
10472
  useMeridiem,
@@ -10460,7 +10705,9 @@ function STimePicker({
10460
10705
  style
10461
10706
  }) {
10462
10707
  const portalContainer = usePortalContainer();
10708
+ const triggerRef = useRef(null);
10463
10709
  const [open, setOpen] = useState(false);
10710
+ const [popoverAlignOffset, setPopoverAlignOffset] = useState(0);
10464
10711
  const [focused, setFocused] = useState(false);
10465
10712
  const [ruleError, setRuleError] = useState("");
10466
10713
  const dims = TIMEPICKER_SIZE_CONFIG[size] ?? TIMEPICKER_SIZE_CONFIG.sm;
@@ -10481,6 +10728,11 @@ function STimePicker({
10481
10728
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
10482
10729
  const commitOpen = (next) => {
10483
10730
  if (disabled) return;
10731
+ if (next) {
10732
+ const triggerWidth = triggerRef.current?.getBoundingClientRect().width ?? 0;
10733
+ const selectorWidth = effectiveUseMeridiem ? MERIDIEM_TIME_SELECTOR_WIDTH : TIME_SELECTOR_WIDTH;
10734
+ setPopoverAlignOffset(Math.max(0, (triggerWidth - selectorWidth) / 2));
10735
+ }
10484
10736
  setOpen(next);
10485
10737
  onOpenChange?.(next);
10486
10738
  if (!next && rules && rules.length > 0) setRuleError(runRules(value, rules));
@@ -10507,19 +10759,32 @@ function STimePicker({
10507
10759
  focused: focused || open,
10508
10760
  errorMessage: ruleError !== "" ? ruleError : errorMessage,
10509
10761
  width,
10762
+ minWidth: dims.fieldMinWidth,
10510
10763
  disabled,
10511
10764
  className,
10512
- style: { minWidth: dims.fieldMinWidth, ...style },
10765
+ style,
10513
10766
  children: /* @__PURE__ */ jsxs(RPopover2.Root, { open, onOpenChange: commitOpen, children: [
10514
10767
  /* @__PURE__ */ jsx(RPopover2.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
10515
- "button",
10768
+ "div",
10516
10769
  {
10517
- type: "button",
10518
- name,
10519
- disabled,
10770
+ ref: triggerRef,
10771
+ role: "button",
10772
+ "aria-disabled": disabled,
10773
+ tabIndex: disabled ? -1 : 0,
10774
+ "data-name": name,
10520
10775
  onFocus: () => setFocused(true),
10521
10776
  onBlur: () => setFocused(false),
10522
- className: "flex h-full w-full items-center overflow-hidden bg-transparent outline-none disabled:cursor-not-allowed",
10777
+ onKeyDown: (event) => {
10778
+ if (disabled) return;
10779
+ if (event.key === "Enter" || event.key === " ") {
10780
+ event.preventDefault();
10781
+ commitOpen(!open);
10782
+ }
10783
+ },
10784
+ className: cn(
10785
+ "flex h-full w-full items-center overflow-hidden bg-transparent outline-none",
10786
+ disabled ? "cursor-not-allowed" : "cursor-pointer"
10787
+ ),
10523
10788
  style: { padding: `0 ${dims.paddingX}`, gap: dims.gap, borderRadius: dims.radius },
10524
10789
  children: [
10525
10790
  /* @__PURE__ */ jsx(
@@ -10565,6 +10830,7 @@ function STimePicker({
10565
10830
  side: "bottom",
10566
10831
  align: "start",
10567
10832
  sideOffset: 4,
10833
+ alignOffset: popoverAlignOffset,
10568
10834
  className: cn("z-50", FLOATING_SLIDE_ANIM),
10569
10835
  children: /* @__PURE__ */ jsx(
10570
10836
  TimeSelector,
@@ -10602,6 +10868,11 @@ function formatTimeRangeDisplay(value, type) {
10602
10868
  if (value == null || value[0] === "" || value[1] === "") return "";
10603
10869
  return `${formatTimeDisplay(value[0], type)} ~ ${formatTimeDisplay(value[1], type)}`;
10604
10870
  }
10871
+ var TIME_RANGE_SELECTOR_WIDTH = 345;
10872
+ var MIDDAY_FIELD_MIN_WIDTH = {
10873
+ sm: 178,
10874
+ md: 216
10875
+ };
10605
10876
  function RangeTimeSelector({
10606
10877
  value,
10607
10878
  useMeridiem,
@@ -10891,7 +11162,9 @@ function STimeRangePicker({
10891
11162
  style
10892
11163
  }) {
10893
11164
  const portalContainer = usePortalContainer();
11165
+ const triggerRef = useRef(null);
10894
11166
  const [open, setOpen] = useState(false);
11167
+ const [popoverAlignOffset, setPopoverAlignOffset] = useState(0);
10895
11168
  const [focused, setFocused] = useState(false);
10896
11169
  const [ruleError, setRuleError] = useState("");
10897
11170
  const dims = TIMEPICKER_SIZE_CONFIG[size] ?? TIMEPICKER_SIZE_CONFIG.sm;
@@ -10915,6 +11188,10 @@ function STimeRangePicker({
10915
11188
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
10916
11189
  const commitOpen = (next) => {
10917
11190
  if (disabled) return;
11191
+ if (next) {
11192
+ const triggerWidth = triggerRef.current?.getBoundingClientRect().width ?? 0;
11193
+ setPopoverAlignOffset(Math.max(0, (triggerWidth - TIME_RANGE_SELECTOR_WIDTH) / 2));
11194
+ }
10918
11195
  setOpen(next);
10919
11196
  onOpenChange?.(next);
10920
11197
  if (!next && rules && rules.length > 0) setRuleError(runRules(value, rules));
@@ -10941,19 +11218,32 @@ function STimeRangePicker({
10941
11218
  focused: focused || open,
10942
11219
  errorMessage: ruleError !== "" ? ruleError : errorMessage,
10943
11220
  width,
11221
+ minWidth: effectiveUseMeridiem ? MIDDAY_FIELD_MIN_WIDTH[size] : dims.fieldMinWidth,
10944
11222
  disabled,
10945
11223
  className,
10946
- style: { minWidth: dims.fieldMinWidth, ...style },
11224
+ style,
10947
11225
  children: /* @__PURE__ */ jsxs(RPopover2.Root, { open, onOpenChange: commitOpen, children: [
10948
11226
  /* @__PURE__ */ jsx(RPopover2.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
10949
- "button",
11227
+ "div",
10950
11228
  {
10951
- type: "button",
10952
- name,
10953
- disabled,
11229
+ ref: triggerRef,
11230
+ role: "button",
11231
+ "aria-disabled": disabled,
11232
+ tabIndex: disabled ? -1 : 0,
11233
+ "data-name": name,
10954
11234
  onFocus: () => setFocused(true),
10955
11235
  onBlur: () => setFocused(false),
10956
- className: "flex h-full w-full items-center overflow-hidden bg-transparent outline-none disabled:cursor-not-allowed",
11236
+ onKeyDown: (event) => {
11237
+ if (disabled) return;
11238
+ if (event.key === "Enter" || event.key === " ") {
11239
+ event.preventDefault();
11240
+ commitOpen(!open);
11241
+ }
11242
+ },
11243
+ className: cn(
11244
+ "flex h-full w-full items-center overflow-hidden bg-transparent outline-none",
11245
+ disabled ? "cursor-not-allowed" : "cursor-pointer"
11246
+ ),
10957
11247
  style: { padding: `0 ${dims.paddingX}`, gap: dims.gap, borderRadius: dims.radius },
10958
11248
  children: [
10959
11249
  /* @__PURE__ */ jsx(
@@ -10999,6 +11289,7 @@ function STimeRangePicker({
10999
11289
  side: "bottom",
11000
11290
  align: "start",
11001
11291
  sideOffset: 4,
11292
+ alignOffset: popoverAlignOffset,
11002
11293
  className: cn("z-50", FLOATING_SLIDE_ANIM),
11003
11294
  children: /* @__PURE__ */ jsx(
11004
11295
  RangeTimeSelector,
@@ -11017,6 +11308,6 @@ function STimeRangePicker({
11017
11308
  );
11018
11309
  }
11019
11310
 
11020
- export { BADGE_COLORS, BUTTON_COLORS, BUTTON_SIZES, COLOR_KEYS, GNB_COLORS, GNB_COMMON, GNB_FOLD_MS, GNB_HEADER, GNB_MENU, GNB_MENU_WIDTH, GNB_RAIL, GNB_RAIL_WIDTH, ICONS, SActionModal, SBadge, SBarcodeInput, SButton, SCalendar, SCallout, SCard, SCheckbox, SChip, SChipInput, SCircleProgress, SConfirmModal, SDatePicker, SDateRangePicker, SDivider, SDropdownButton, SField, SFilePicker, SForm, SGhostButton, SGnb, SGuide, SIcon, SInput, SKeyValueTable, SLayout, SLayoutContext, SLinearProgress, SLoadingContainer, SLoadingModal, SLoadingViewport, SNumberInput, SPage, SPagination, SPopover, SPopup, SPortal, SRadio, SRadioButton, SRadioGroup, SSelect, SSwitch, STable, STabs, STag, STextLink, STextarea, STimePicker, STimeRangePicker, SToast, SToastContainer, SToggle, STooltip, TAG_COLORS, TAG_SHAPES, TAG_SIZES, TIMEPICKER_SIZES, TIMEPICKER_SIZE_CONFIG, buttonPreset, cn, findGnbAncestors, findGnbRailValue, isColorKey, loading, resolveColor, useSLayout };
11311
+ export { BADGE_COLORS, BUTTON_COLORS, BUTTON_SIZES, COLOR_KEYS, GNB_COLORS, GNB_COMMON, GNB_FOLD_MS, GNB_HEADER, GNB_MENU, GNB_MENU_WIDTH, GNB_RAIL, GNB_RAIL_WIDTH, ICONS, SActionModal, SBadge, SBarcodeInput, SButton, SCROLL_AREA_AXES, SCalendar, SCallout, SCard, SCheckbox, SChip, SChipInput, SCircleProgress, SConfirmModal, SDatePicker, SDateRangePicker, SDivider, SDropdownButton, SField, SFilePicker, SForm, SGhostButton, SGnb, SGuide, SIcon, SInput, SKeyValueTable, SLayout, SLayoutContext, SLinearProgress, SLoadingContainer, SLoadingModal, SLoadingViewport, SNumberInput, SPage, SPagination, SPopover, SPopup, SPortal, SRadio, SRadioButton, SRadioGroup, SScrollArea, SSelect, SStepper, SSwitch, STEPPER_SIZES, STable, STabs, STag, STextLink, STextarea, STimePicker, STimeRangePicker, SToast, SToastContainer, SToggle, STooltip, TAG_COLORS, TAG_SHAPES, TAG_SIZES, TIMEPICKER_SIZES, TIMEPICKER_SIZE_CONFIG, buttonPreset, cn, findGnbAncestors, findGnbRailValue, isColorKey, loading, resolveColor, useSLayout };
11021
11312
  //# sourceMappingURL=index.js.map
11022
11313
  //# sourceMappingURL=index.js.map