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.cjs CHANGED
@@ -2937,6 +2937,51 @@ var SDivider = react.forwardRef(function SDivider2({ vertical = false, className
2937
2937
  );
2938
2938
  });
2939
2939
 
2940
+ // src/lib/scrollbar.ts
2941
+ var FIREFOX_SCROLLBAR_CLASS = "supports-[not_selector(::-webkit-scrollbar)]:[scrollbar-width:thin] supports-[not_selector(::-webkit-scrollbar)]:[scrollbar-color:var(--color-grey-45)_transparent]";
2942
+ 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`;
2943
+ 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)]";
2944
+ 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]";
2945
+ var AXIS_CLASS = {
2946
+ vertical: "overflow-x-hidden overflow-y-auto",
2947
+ horizontal: "overflow-x-auto overflow-y-hidden",
2948
+ both: "overflow-auto"
2949
+ };
2950
+ var SScrollArea = react.forwardRef(function SScrollArea2({
2951
+ axis = "both",
2952
+ background = false,
2953
+ bordered = false,
2954
+ maxHeight,
2955
+ maxWidth,
2956
+ className,
2957
+ style,
2958
+ children,
2959
+ ...rest
2960
+ }, ref) {
2961
+ const mergedStyle = { ...style };
2962
+ if (maxHeight) mergedStyle.maxHeight = maxHeight;
2963
+ if (maxWidth) mergedStyle.maxWidth = maxWidth;
2964
+ return /* @__PURE__ */ jsxRuntime.jsx(
2965
+ "div",
2966
+ {
2967
+ ref,
2968
+ className: cn(
2969
+ AXIS_CLASS[axis],
2970
+ SCROLLBAR_CLASS,
2971
+ background && SCROLLBAR_TRACK_BG_CLASS,
2972
+ bordered && SCROLLBAR_TRACK_BORDER_CLASS,
2973
+ className
2974
+ ),
2975
+ style: mergedStyle,
2976
+ ...rest,
2977
+ children
2978
+ }
2979
+ );
2980
+ });
2981
+
2982
+ // src/components/SScrollArea/scrollArea.config.ts
2983
+ var SCROLL_AREA_AXES = ["vertical", "horizontal", "both"];
2984
+
2940
2985
  // src/components/STag/tag.config.ts
2941
2986
  var TAG_SHAPES = ["square", "pill"];
2942
2987
  var TAG_SIZES = ["xs", "sm", "md"];
@@ -4472,7 +4517,18 @@ var SPopup = react.forwardRef(function SPopup2({
4472
4517
  )
4473
4518
  }
4474
4519
  ),
4475
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1 overflow-auto", children }),
4520
+ /* @__PURE__ */ jsxRuntime.jsx(
4521
+ "div",
4522
+ {
4523
+ className: cn(
4524
+ "min-h-0 flex-1 overflow-auto",
4525
+ SCROLLBAR_CLASS,
4526
+ SCROLLBAR_TRACK_BG_CLASS,
4527
+ SCROLLBAR_TRACK_BORDER_CLASS
4528
+ ),
4529
+ children
4530
+ }
4531
+ ),
4476
4532
  useFooter && /* @__PURE__ */ jsxRuntime.jsxs(
4477
4533
  "footer",
4478
4534
  {
@@ -5272,9 +5328,24 @@ var SGnb = react.forwardRef(function SGnb2({
5272
5328
  onMouseEnter: () => setHoveredKey(item.value),
5273
5329
  onMouseLeave: () => setHoveredKey((prev) => prev === item.value ? null : prev),
5274
5330
  children: [
5275
- depth === 1 && item.icon && /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: item.icon, size: M.depth1Icon, color: C.itemIcon, className: "shrink-0" }),
5331
+ depth === 1 && item.icon && /* @__PURE__ */ jsxRuntime.jsx(
5332
+ SIcon,
5333
+ {
5334
+ name: item.icon,
5335
+ size: M.depth1Icon,
5336
+ color: isSelected ? C.itemColorActive : C.itemIcon,
5337
+ className: "shrink-0"
5338
+ }
5339
+ ),
5276
5340
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0 flex-1 overflow-hidden text-ellipsis whitespace-nowrap flex flex-no-wrap items-center", children: [
5277
- depth > 1 && iconBranch ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-[20px] h-[24px] flex items-center justify-center mr-[8px]", children: "-" }) : null,
5341
+ depth > 1 && iconBranch ? /* @__PURE__ */ jsxRuntime.jsx(
5342
+ "div",
5343
+ {
5344
+ className: "w-[20px] flex items-center justify-center mr-[8px]",
5345
+ style: { height: M.itemLineHeight },
5346
+ children: "-"
5347
+ }
5348
+ ) : null,
5278
5349
  item.label
5279
5350
  ] }),
5280
5351
  item.tag !== void 0 && item.tag !== "" && /* @__PURE__ */ jsxRuntime.jsx(
@@ -5333,10 +5404,11 @@ var SGnb = react.forwardRef(function SGnb2({
5333
5404
  }, [layout, railHasLeaf, showMenu]);
5334
5405
  const railFolded = folded && header === "fix";
5335
5406
  const rootWidth = header === "full" ? "100%" : folded ? GNB_COMMON.foldWidth : bodyWidth;
5407
+ const rightBorder = color === "light" ? `1px solid ${C.topBorder}` : void 0;
5336
5408
  const rootStyle = {
5337
5409
  width: rootWidth,
5338
5410
  transition: `width ${GNB_FOLD_MS}ms ease-out`,
5339
- ...header === "full" ? { gridArea: "1 / 1 / -1 / -1", pointerEvents: "none" } : { backgroundColor: C.panelBg },
5411
+ ...header === "full" ? { gridArea: "1 / 1 / -1 / -1", pointerEvents: "none" } : { backgroundColor: C.panelBg, borderRight: rightBorder },
5340
5412
  ...style
5341
5413
  };
5342
5414
  const hideAfterSlide = (hidden) => `visibility 0s linear ${hidden ? `${GNB_FOLD_MS}ms` : "0s"}`;
@@ -5503,6 +5575,8 @@ var SGnb = react.forwardRef(function SGnb2({
5503
5575
  paddingTop: M.bodyPaddingY,
5504
5576
  paddingBottom: M.bodyPaddingY,
5505
5577
  backgroundColor: C.panelBg,
5578
+ // full 은 상단바가 전폭이라 루트가 오른쪽 선을 못 그린다 → 메뉴 오른쪽(페이지 경계)이 대신 그린다.
5579
+ borderRight: header === "full" ? rightBorder : void 0,
5506
5580
  pointerEvents: "auto"
5507
5581
  },
5508
5582
  children: /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "m-0 flex list-none flex-col p-0", children: menuItems.map((item) => renderItem(item, 1)) })
@@ -5759,6 +5833,165 @@ function SPagination({
5759
5833
  }
5760
5834
  );
5761
5835
  }
5836
+
5837
+ // src/components/SStepper/stepper.config.ts
5838
+ var STEPPER_SIZES = ["sm", "lg"];
5839
+ var V2 = (path) => `var(--cmp-stepper-${path})`;
5840
+ var STEPPER_SIZE_CONFIG = {
5841
+ sm: {
5842
+ sequenceSize: V2("sm-sequence-size"),
5843
+ fontSize: "12px",
5844
+ lineHeight: "20px",
5845
+ fontWeightActive: 700,
5846
+ fontWeightDefault: 500
5847
+ },
5848
+ lg: {
5849
+ sequenceSize: V2("lg-sequence-size"),
5850
+ fontSize: "14px",
5851
+ lineHeight: "24px",
5852
+ fontWeightActive: 700,
5853
+ fontWeightDefault: 500
5854
+ }
5855
+ };
5856
+ var STEPPER_LAYOUT = {
5857
+ containerGap: V2("container-gap"),
5858
+ itemGap: V2("item-gap"),
5859
+ dashWidth: V2("dash-width"),
5860
+ sequenceRadius: V2("sequence-radius"),
5861
+ sequenceBorderWidth: V2("sequence-border-witdh"),
5862
+ sequenceIcon: V2("sequence-icon")
5863
+ };
5864
+ var STEPPER_COLORS = {
5865
+ dash: V2("dash-color"),
5866
+ sequenceBorder: {
5867
+ active: V2("sequence-border-active"),
5868
+ default: V2("sequence-border-default"),
5869
+ completed: V2("sequence-border-completed")
5870
+ },
5871
+ sequenceBg: {
5872
+ active: V2("sequence-bg-active"),
5873
+ default: V2("sequence-bg-default"),
5874
+ completed: V2("sequence-bg-completed")
5875
+ },
5876
+ sequenceText: {
5877
+ active: V2("sequence-text-active"),
5878
+ default: V2("sequence-text-default")
5879
+ },
5880
+ text: {
5881
+ active: V2("text-active"),
5882
+ default: V2("text-default")
5883
+ }
5884
+ };
5885
+ function getItemValue(item, index) {
5886
+ return item.value ?? String(index + 1);
5887
+ }
5888
+ function SStepper({
5889
+ items,
5890
+ value,
5891
+ size = "sm",
5892
+ ariaLabel = "\uC9C4\uD589 \uB2E8\uACC4",
5893
+ className,
5894
+ style
5895
+ }) {
5896
+ const config = STEPPER_SIZE_CONFIG[size];
5897
+ const activeIndex = Math.max(
5898
+ 0,
5899
+ items.findIndex((item, index) => getItemValue(item, index) === value)
5900
+ );
5901
+ const getState = (index) => {
5902
+ if (index < activeIndex) return "completed";
5903
+ if (index === activeIndex) return "active";
5904
+ return "default";
5905
+ };
5906
+ return /* @__PURE__ */ jsxRuntime.jsx(
5907
+ "div",
5908
+ {
5909
+ role: "list",
5910
+ "aria-label": ariaLabel,
5911
+ className: cn("inline-flex items-center", className),
5912
+ style: {
5913
+ gap: STEPPER_LAYOUT.containerGap,
5914
+ fontSize: config.fontSize,
5915
+ lineHeight: config.lineHeight,
5916
+ ...style
5917
+ },
5918
+ children: items.map((item, index) => {
5919
+ const state2 = getState(index);
5920
+ const itemStyle = {
5921
+ gap: STEPPER_LAYOUT.itemGap,
5922
+ color: state2 === "active" ? STEPPER_COLORS.text.active : STEPPER_COLORS.text.default,
5923
+ fontWeight: state2 === "active" ? config.fontWeightActive : config.fontWeightDefault
5924
+ };
5925
+ const sequenceStyle = {
5926
+ width: config.sequenceSize,
5927
+ height: config.sequenceSize,
5928
+ flexBasis: config.sequenceSize,
5929
+ borderRadius: STEPPER_LAYOUT.sequenceRadius,
5930
+ borderWidth: STEPPER_LAYOUT.sequenceBorderWidth,
5931
+ borderColor: STEPPER_COLORS.sequenceBorder[state2],
5932
+ background: STEPPER_COLORS.sequenceBg[state2],
5933
+ color: state2 === "completed" ? STEPPER_COLORS.text.default : STEPPER_COLORS.sequenceText[state2]
5934
+ };
5935
+ const content = /* @__PURE__ */ jsxRuntime.jsxs(
5936
+ "span",
5937
+ {
5938
+ role: "listitem",
5939
+ "aria-current": state2 === "active" ? "step" : void 0,
5940
+ className: "inline-flex items-center whitespace-nowrap",
5941
+ style: itemStyle,
5942
+ children: [
5943
+ /* @__PURE__ */ jsxRuntime.jsx(
5944
+ "span",
5945
+ {
5946
+ "aria-hidden": true,
5947
+ className: "box-border inline-flex shrink-0 items-center justify-center border border-solid font-bold",
5948
+ style: sequenceStyle,
5949
+ children: state2 === "completed" ? /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: "check", size: STEPPER_LAYOUT.sequenceIcon, color: "currentColor" }) : index + 1
5950
+ }
5951
+ ),
5952
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: item.label })
5953
+ ]
5954
+ }
5955
+ );
5956
+ return /* @__PURE__ */ jsxRuntime.jsxs(
5957
+ "span",
5958
+ {
5959
+ className: "inline-flex items-center",
5960
+ style: { gap: STEPPER_LAYOUT.containerGap },
5961
+ children: [
5962
+ content,
5963
+ index < items.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(
5964
+ "span",
5965
+ {
5966
+ "aria-hidden": true,
5967
+ className: "inline-flex h-px shrink-0 items-center",
5968
+ style: { width: STEPPER_LAYOUT.dashWidth, color: STEPPER_COLORS.dash },
5969
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
5970
+ "svg",
5971
+ {
5972
+ width: "20",
5973
+ height: "1",
5974
+ viewBox: "0 0 20 1",
5975
+ fill: "none",
5976
+ xmlns: "http://www.w3.org/2000/svg",
5977
+ children: [
5978
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "1.6", height: "1", fill: "#888888" }),
5979
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "5", width: "3.3", height: "1", fill: "#888888" }),
5980
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "11.7", width: "3.3", height: "1", fill: "#888888" }),
5981
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "18.4", width: "1.6", height: "1", fill: "#888888" })
5982
+ ]
5983
+ }
5984
+ )
5985
+ }
5986
+ )
5987
+ ]
5988
+ },
5989
+ getItemValue(item, index)
5990
+ );
5991
+ })
5992
+ }
5993
+ );
5994
+ }
5762
5995
  function SCheckbox({
5763
5996
  value = false,
5764
5997
  val,
@@ -5887,6 +6120,7 @@ var SField = react.forwardRef(function SField2({
5887
6120
  disabled = false,
5888
6121
  readOnly = false,
5889
6122
  width,
6123
+ minWidth,
5890
6124
  multiline = false,
5891
6125
  borderless = false,
5892
6126
  children,
@@ -5983,6 +6217,7 @@ var SField = react.forwardRef(function SField2({
5983
6217
  // focused/hovered prop이 명시된 경우 강조를 즉시 반영
5984
6218
  ...interactive && !borderless && focused ? { boxShadow: "0px 0px 4px 0px #0071ff66" } : {},
5985
6219
  ...multiline ? { minHeight: s.height } : { height: s.height },
6220
+ "minWidth": cssLen(minWidth),
5986
6221
  "width": cssLen(width),
5987
6222
  "borderRadius": s.radius,
5988
6223
  "background": bgColor,
@@ -6364,7 +6599,12 @@ var SSelect = react.forwardRef(function SSelect2({
6364
6599
  "div",
6365
6600
  {
6366
6601
  ref: listRef,
6367
- 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)]",
6602
+ className: cn(
6603
+ "overflow-auto",
6604
+ SCROLLBAR_CLASS,
6605
+ SCROLLBAR_TRACK_BG_CLASS,
6606
+ SCROLLBAR_TRACK_BORDER_CLASS
6607
+ ),
6368
6608
  style: { maxHeight: dropdownHeight },
6369
6609
  onMouseLeave: () => setFocusedIndex(-1),
6370
6610
  children: [
@@ -6879,6 +7119,9 @@ var STable = react.forwardRef(function STable2({
6879
7119
  onScroll: handleScroll,
6880
7120
  className: cn(
6881
7121
  "bg-white relative overflow-auto border border-solid border-[color:var(--cmp-table-border-color)]",
7122
+ SCROLLBAR_CLASS,
7123
+ SCROLLBAR_TRACK_BG_CLASS,
7124
+ SCROLLBAR_TRACK_BORDER_CLASS,
6882
7125
  radiusClass,
6883
7126
  // 원본 sd-table__scroll-container--loading/--no-data: 로딩·데이터 없음 시 스크롤·인터랙션 차단
6884
7127
  (isLoading || rowCount === 0) && "overflow-hidden pointer-events-none"
@@ -10196,15 +10439,15 @@ var SBarcodeInput = react.forwardRef(
10196
10439
  );
10197
10440
 
10198
10441
  // src/components/STimePicker/timepicker.config.ts
10199
- var V2 = (path) => `var(--cmp-timepicker-${path})`;
10442
+ var V3 = (path) => `var(--cmp-timepicker-${path})`;
10200
10443
  var TIMEPICKER_SIZES = ["sm", "md"];
10201
10444
  var TIMEPICKER_SIZE_CONFIG = {
10202
10445
  sm: {
10203
- height: V2("sm-height"),
10204
- paddingX: V2("sm-paddingX"),
10205
- gap: V2("sm-gap"),
10206
- icon: V2("sm-icon"),
10207
- radius: V2("sm-radius"),
10446
+ height: V3("sm-height"),
10447
+ paddingX: V3("sm-paddingX"),
10448
+ gap: V3("sm-gap"),
10449
+ icon: V3("sm-icon"),
10450
+ radius: V3("sm-radius"),
10208
10451
  // TODO: component.timepicker 토큰에 typography가 추가되면 CSS 변수로 교체한다.
10209
10452
  fontSize: 12,
10210
10453
  lineHeight: 20,
@@ -10212,11 +10455,11 @@ var TIMEPICKER_SIZE_CONFIG = {
10212
10455
  fieldMinWidth: 128
10213
10456
  },
10214
10457
  md: {
10215
- height: V2("md-height"),
10216
- paddingX: V2("md-paddingX"),
10217
- gap: V2("md-gap"),
10218
- icon: V2("md-icon"),
10219
- radius: V2("md-radius"),
10458
+ height: V3("md-height"),
10459
+ paddingX: V3("md-paddingX"),
10460
+ gap: V3("md-gap"),
10461
+ icon: V3("md-icon"),
10462
+ radius: V3("md-radius"),
10220
10463
  // TODO: component.timepicker 토큰에 typography가 추가되면 CSS 변수로 교체한다.
10221
10464
  fontSize: 14,
10222
10465
  lineHeight: 24,
@@ -10250,6 +10493,8 @@ function formatTimeDisplay(value, type) {
10250
10493
  const displayHour = hour % 12 === 0 ? 12 : hour % 12;
10251
10494
  return `${meridiem} ${padTimePart(displayHour)}:${padTimePart(minute)}`;
10252
10495
  }
10496
+ var TIME_SELECTOR_WIDTH = 136;
10497
+ var MERIDIEM_TIME_SELECTOR_WIDTH = 154;
10253
10498
  function TimeSelector({
10254
10499
  value,
10255
10500
  useMeridiem,
@@ -10488,7 +10733,9 @@ function STimePicker({
10488
10733
  style
10489
10734
  }) {
10490
10735
  const portalContainer = usePortalContainer();
10736
+ const triggerRef = react.useRef(null);
10491
10737
  const [open, setOpen] = react.useState(false);
10738
+ const [popoverAlignOffset, setPopoverAlignOffset] = react.useState(0);
10492
10739
  const [focused, setFocused] = react.useState(false);
10493
10740
  const [ruleError, setRuleError] = react.useState("");
10494
10741
  const dims = TIMEPICKER_SIZE_CONFIG[size] ?? TIMEPICKER_SIZE_CONFIG.sm;
@@ -10509,6 +10756,11 @@ function STimePicker({
10509
10756
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
10510
10757
  const commitOpen = (next) => {
10511
10758
  if (disabled) return;
10759
+ if (next) {
10760
+ const triggerWidth = triggerRef.current?.getBoundingClientRect().width ?? 0;
10761
+ const selectorWidth = effectiveUseMeridiem ? MERIDIEM_TIME_SELECTOR_WIDTH : TIME_SELECTOR_WIDTH;
10762
+ setPopoverAlignOffset(Math.max(0, (triggerWidth - selectorWidth) / 2));
10763
+ }
10512
10764
  setOpen(next);
10513
10765
  onOpenChange?.(next);
10514
10766
  if (!next && rules && rules.length > 0) setRuleError(runRules(value, rules));
@@ -10535,19 +10787,32 @@ function STimePicker({
10535
10787
  focused: focused || open,
10536
10788
  errorMessage: ruleError !== "" ? ruleError : errorMessage,
10537
10789
  width,
10790
+ minWidth: dims.fieldMinWidth,
10538
10791
  disabled,
10539
10792
  className,
10540
- style: { minWidth: dims.fieldMinWidth, ...style },
10793
+ style,
10541
10794
  children: /* @__PURE__ */ jsxRuntime.jsxs(RPopover2__namespace.Root, { open, onOpenChange: commitOpen, children: [
10542
10795
  /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
10543
- "button",
10796
+ "div",
10544
10797
  {
10545
- type: "button",
10546
- name,
10547
- disabled,
10798
+ ref: triggerRef,
10799
+ role: "button",
10800
+ "aria-disabled": disabled,
10801
+ tabIndex: disabled ? -1 : 0,
10802
+ "data-name": name,
10548
10803
  onFocus: () => setFocused(true),
10549
10804
  onBlur: () => setFocused(false),
10550
- className: "flex h-full w-full items-center overflow-hidden bg-transparent outline-none disabled:cursor-not-allowed",
10805
+ onKeyDown: (event) => {
10806
+ if (disabled) return;
10807
+ if (event.key === "Enter" || event.key === " ") {
10808
+ event.preventDefault();
10809
+ commitOpen(!open);
10810
+ }
10811
+ },
10812
+ className: cn(
10813
+ "flex h-full w-full items-center overflow-hidden bg-transparent outline-none",
10814
+ disabled ? "cursor-not-allowed" : "cursor-pointer"
10815
+ ),
10551
10816
  style: { padding: `0 ${dims.paddingX}`, gap: dims.gap, borderRadius: dims.radius },
10552
10817
  children: [
10553
10818
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -10593,6 +10858,7 @@ function STimePicker({
10593
10858
  side: "bottom",
10594
10859
  align: "start",
10595
10860
  sideOffset: 4,
10861
+ alignOffset: popoverAlignOffset,
10596
10862
  className: cn("z-50", FLOATING_SLIDE_ANIM),
10597
10863
  children: /* @__PURE__ */ jsxRuntime.jsx(
10598
10864
  TimeSelector,
@@ -10630,6 +10896,11 @@ function formatTimeRangeDisplay(value, type) {
10630
10896
  if (value == null || value[0] === "" || value[1] === "") return "";
10631
10897
  return `${formatTimeDisplay(value[0], type)} ~ ${formatTimeDisplay(value[1], type)}`;
10632
10898
  }
10899
+ var TIME_RANGE_SELECTOR_WIDTH = 345;
10900
+ var MIDDAY_FIELD_MIN_WIDTH = {
10901
+ sm: 178,
10902
+ md: 216
10903
+ };
10633
10904
  function RangeTimeSelector({
10634
10905
  value,
10635
10906
  useMeridiem,
@@ -10919,7 +11190,9 @@ function STimeRangePicker({
10919
11190
  style
10920
11191
  }) {
10921
11192
  const portalContainer = usePortalContainer();
11193
+ const triggerRef = react.useRef(null);
10922
11194
  const [open, setOpen] = react.useState(false);
11195
+ const [popoverAlignOffset, setPopoverAlignOffset] = react.useState(0);
10923
11196
  const [focused, setFocused] = react.useState(false);
10924
11197
  const [ruleError, setRuleError] = react.useState("");
10925
11198
  const dims = TIMEPICKER_SIZE_CONFIG[size] ?? TIMEPICKER_SIZE_CONFIG.sm;
@@ -10943,6 +11216,10 @@ function STimeRangePicker({
10943
11216
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
10944
11217
  const commitOpen = (next) => {
10945
11218
  if (disabled) return;
11219
+ if (next) {
11220
+ const triggerWidth = triggerRef.current?.getBoundingClientRect().width ?? 0;
11221
+ setPopoverAlignOffset(Math.max(0, (triggerWidth - TIME_RANGE_SELECTOR_WIDTH) / 2));
11222
+ }
10946
11223
  setOpen(next);
10947
11224
  onOpenChange?.(next);
10948
11225
  if (!next && rules && rules.length > 0) setRuleError(runRules(value, rules));
@@ -10969,19 +11246,32 @@ function STimeRangePicker({
10969
11246
  focused: focused || open,
10970
11247
  errorMessage: ruleError !== "" ? ruleError : errorMessage,
10971
11248
  width,
11249
+ minWidth: effectiveUseMeridiem ? MIDDAY_FIELD_MIN_WIDTH[size] : dims.fieldMinWidth,
10972
11250
  disabled,
10973
11251
  className,
10974
- style: { minWidth: dims.fieldMinWidth, ...style },
11252
+ style,
10975
11253
  children: /* @__PURE__ */ jsxRuntime.jsxs(RPopover2__namespace.Root, { open, onOpenChange: commitOpen, children: [
10976
11254
  /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
10977
- "button",
11255
+ "div",
10978
11256
  {
10979
- type: "button",
10980
- name,
10981
- disabled,
11257
+ ref: triggerRef,
11258
+ role: "button",
11259
+ "aria-disabled": disabled,
11260
+ tabIndex: disabled ? -1 : 0,
11261
+ "data-name": name,
10982
11262
  onFocus: () => setFocused(true),
10983
11263
  onBlur: () => setFocused(false),
10984
- className: "flex h-full w-full items-center overflow-hidden bg-transparent outline-none disabled:cursor-not-allowed",
11264
+ onKeyDown: (event) => {
11265
+ if (disabled) return;
11266
+ if (event.key === "Enter" || event.key === " ") {
11267
+ event.preventDefault();
11268
+ commitOpen(!open);
11269
+ }
11270
+ },
11271
+ className: cn(
11272
+ "flex h-full w-full items-center overflow-hidden bg-transparent outline-none",
11273
+ disabled ? "cursor-not-allowed" : "cursor-pointer"
11274
+ ),
10985
11275
  style: { padding: `0 ${dims.paddingX}`, gap: dims.gap, borderRadius: dims.radius },
10986
11276
  children: [
10987
11277
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -11027,6 +11317,7 @@ function STimeRangePicker({
11027
11317
  side: "bottom",
11028
11318
  align: "start",
11029
11319
  sideOffset: 4,
11320
+ alignOffset: popoverAlignOffset,
11030
11321
  className: cn("z-50", FLOATING_SLIDE_ANIM),
11031
11322
  children: /* @__PURE__ */ jsxRuntime.jsx(
11032
11323
  RangeTimeSelector,
@@ -11062,6 +11353,7 @@ exports.SActionModal = SActionModal;
11062
11353
  exports.SBadge = SBadge;
11063
11354
  exports.SBarcodeInput = SBarcodeInput;
11064
11355
  exports.SButton = SButton;
11356
+ exports.SCROLL_AREA_AXES = SCROLL_AREA_AXES;
11065
11357
  exports.SCalendar = SCalendar;
11066
11358
  exports.SCallout = SCallout;
11067
11359
  exports.SCard = SCard;
@@ -11098,8 +11390,11 @@ exports.SPortal = SPortal;
11098
11390
  exports.SRadio = SRadio;
11099
11391
  exports.SRadioButton = SRadioButton;
11100
11392
  exports.SRadioGroup = SRadioGroup;
11393
+ exports.SScrollArea = SScrollArea;
11101
11394
  exports.SSelect = SSelect;
11395
+ exports.SStepper = SStepper;
11102
11396
  exports.SSwitch = SSwitch;
11397
+ exports.STEPPER_SIZES = STEPPER_SIZES;
11103
11398
  exports.STable = STable;
11104
11399
  exports.STabs = STabs;
11105
11400
  exports.STag = STag;