sellmate-design-system-react 0.6.1 → 0.8.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 (92) hide show
  1. package/dist/components/SBarcodeInput/SBarcodeInput.cjs +62 -48
  2. package/dist/components/SBarcodeInput/SBarcodeInput.cjs.map +1 -1
  3. package/dist/components/SBarcodeInput/SBarcodeInput.js +62 -48
  4. package/dist/components/SBarcodeInput/SBarcodeInput.js.map +1 -1
  5. package/dist/components/SChipInput/SChipInput.cjs +62 -48
  6. package/dist/components/SChipInput/SChipInput.cjs.map +1 -1
  7. package/dist/components/SChipInput/SChipInput.js +62 -48
  8. package/dist/components/SChipInput/SChipInput.js.map +1 -1
  9. package/dist/components/SDatePicker/SDatePicker.cjs +62 -48
  10. package/dist/components/SDatePicker/SDatePicker.cjs.map +1 -1
  11. package/dist/components/SDatePicker/SDatePicker.js +62 -48
  12. package/dist/components/SDatePicker/SDatePicker.js.map +1 -1
  13. package/dist/components/SDateRangePicker/SDateRangePicker.cjs +62 -48
  14. package/dist/components/SDateRangePicker/SDateRangePicker.cjs.map +1 -1
  15. package/dist/components/SDateRangePicker/SDateRangePicker.js +62 -48
  16. package/dist/components/SDateRangePicker/SDateRangePicker.js.map +1 -1
  17. package/dist/components/SField/SField.cjs +62 -48
  18. package/dist/components/SField/SField.cjs.map +1 -1
  19. package/dist/components/SField/SField.d.ts +6 -1
  20. package/dist/components/SField/SField.js +62 -48
  21. package/dist/components/SField/SField.js.map +1 -1
  22. package/dist/components/SFilePicker/SFilePicker.cjs +62 -48
  23. package/dist/components/SFilePicker/SFilePicker.cjs.map +1 -1
  24. package/dist/components/SFilePicker/SFilePicker.js +62 -48
  25. package/dist/components/SFilePicker/SFilePicker.js.map +1 -1
  26. package/dist/components/SInput/SInput.cjs +62 -48
  27. package/dist/components/SInput/SInput.cjs.map +1 -1
  28. package/dist/components/SInput/SInput.js +62 -48
  29. package/dist/components/SInput/SInput.js.map +1 -1
  30. package/dist/components/SKeyValueTable/SKeyValueTable.cjs +74 -49
  31. package/dist/components/SKeyValueTable/SKeyValueTable.cjs.map +1 -1
  32. package/dist/components/SKeyValueTable/SKeyValueTable.js +74 -49
  33. package/dist/components/SKeyValueTable/SKeyValueTable.js.map +1 -1
  34. package/dist/components/SNumberInput/SNumberInput.cjs +62 -48
  35. package/dist/components/SNumberInput/SNumberInput.cjs.map +1 -1
  36. package/dist/components/SNumberInput/SNumberInput.js +62 -48
  37. package/dist/components/SNumberInput/SNumberInput.js.map +1 -1
  38. package/dist/components/SPage/SPage.cjs +19 -2
  39. package/dist/components/SPage/SPage.cjs.map +1 -1
  40. package/dist/components/SPage/SPage.d.ts +7 -1
  41. package/dist/components/SPage/SPage.js +19 -2
  42. package/dist/components/SPage/SPage.js.map +1 -1
  43. package/dist/components/SPage/index.d.ts +1 -0
  44. package/dist/components/SPage/page.config.d.ts +8 -0
  45. package/dist/components/SPopup/SPopup.cjs +18 -1
  46. package/dist/components/SPopup/SPopup.cjs.map +1 -1
  47. package/dist/components/SPopup/SPopup.js +18 -1
  48. package/dist/components/SPopup/SPopup.js.map +1 -1
  49. package/dist/components/SScrollArea/SScrollArea.cjs +64 -0
  50. package/dist/components/SScrollArea/SScrollArea.cjs.map +1 -0
  51. package/dist/components/SScrollArea/SScrollArea.d.ts +21 -0
  52. package/dist/components/SScrollArea/SScrollArea.js +62 -0
  53. package/dist/components/SScrollArea/SScrollArea.js.map +1 -0
  54. package/dist/components/SScrollArea/index.d.ts +2 -0
  55. package/dist/components/SScrollArea/scrollArea.config.d.ts +2 -0
  56. package/dist/components/SSelect/SSelect.cjs +74 -49
  57. package/dist/components/SSelect/SSelect.cjs.map +1 -1
  58. package/dist/components/SSelect/SSelect.js +74 -49
  59. package/dist/components/SSelect/SSelect.js.map +1 -1
  60. package/dist/components/SStepper/SStepper.cjs +7 -11
  61. package/dist/components/SStepper/SStepper.cjs.map +1 -1
  62. package/dist/components/SStepper/SStepper.js +7 -11
  63. package/dist/components/SStepper/SStepper.js.map +1 -1
  64. package/dist/components/STable/STable.cjs +83 -55
  65. package/dist/components/STable/STable.cjs.map +1 -1
  66. package/dist/components/STable/STable.d.ts +2 -0
  67. package/dist/components/STable/STable.js +83 -55
  68. package/dist/components/STable/STable.js.map +1 -1
  69. package/dist/components/STextarea/STextarea.cjs +62 -48
  70. package/dist/components/STextarea/STextarea.cjs.map +1 -1
  71. package/dist/components/STextarea/STextarea.js +62 -48
  72. package/dist/components/STextarea/STextarea.js.map +1 -1
  73. package/dist/components/STimePicker/STimePicker.cjs +91 -54
  74. package/dist/components/STimePicker/STimePicker.cjs.map +1 -1
  75. package/dist/components/STimePicker/STimePicker.js +91 -54
  76. package/dist/components/STimePicker/STimePicker.js.map +1 -1
  77. package/dist/components/STimeRangePicker/STimeRangePicker.cjs +93 -54
  78. package/dist/components/STimeRangePicker/STimeRangePicker.cjs.map +1 -1
  79. package/dist/components/STimeRangePicker/STimeRangePicker.js +93 -54
  80. package/dist/components/STimeRangePicker/STimeRangePicker.js.map +1 -1
  81. package/dist/index.cjs +220 -81
  82. package/dist/index.cjs.map +1 -1
  83. package/dist/index.d.ts +1 -0
  84. package/dist/index.js +218 -82
  85. package/dist/index.js.map +1 -1
  86. package/dist/lib/scrollbar.cjs +15 -0
  87. package/dist/lib/scrollbar.cjs.map +1 -0
  88. package/dist/lib/scrollbar.d.ts +32 -0
  89. package/dist/lib/scrollbar.js +10 -0
  90. package/dist/lib/scrollbar.js.map +1 -0
  91. package/dist/styles.css +168 -17
  92. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -2937,6 +2937,52 @@ 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_BG_WHITE_CLASS = "supports-[not_selector(::-webkit-scrollbar)]:[scrollbar-color:var(--color-grey-45)_var(--color-white)] [&::-webkit-scrollbar]:bg-[var(--color-white)] [&::-webkit-scrollbar-track]:bg-[var(--color-white)]";
2945
+ 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]";
2946
+ var AXIS_CLASS = {
2947
+ vertical: "overflow-x-hidden overflow-y-auto",
2948
+ horizontal: "overflow-x-auto overflow-y-hidden",
2949
+ both: "overflow-auto"
2950
+ };
2951
+ var SScrollArea = react.forwardRef(function SScrollArea2({
2952
+ axis = "both",
2953
+ background = false,
2954
+ bordered = false,
2955
+ maxHeight,
2956
+ maxWidth,
2957
+ className,
2958
+ style,
2959
+ children,
2960
+ ...rest
2961
+ }, ref) {
2962
+ const mergedStyle = { ...style };
2963
+ if (maxHeight) mergedStyle.maxHeight = maxHeight;
2964
+ if (maxWidth) mergedStyle.maxWidth = maxWidth;
2965
+ return /* @__PURE__ */ jsxRuntime.jsx(
2966
+ "div",
2967
+ {
2968
+ ref,
2969
+ className: cn(
2970
+ AXIS_CLASS[axis],
2971
+ SCROLLBAR_CLASS,
2972
+ background && SCROLLBAR_TRACK_BG_CLASS,
2973
+ bordered && SCROLLBAR_TRACK_BORDER_CLASS,
2974
+ className
2975
+ ),
2976
+ style: mergedStyle,
2977
+ ...rest,
2978
+ children
2979
+ }
2980
+ );
2981
+ });
2982
+
2983
+ // src/components/SScrollArea/scrollArea.config.ts
2984
+ var SCROLL_AREA_AXES = ["vertical", "horizontal", "both"];
2985
+
2940
2986
  // src/components/STag/tag.config.ts
2941
2987
  var TAG_SHAPES = ["square", "pill"];
2942
2988
  var TAG_SIZES = ["xs", "sm", "md"];
@@ -4472,7 +4518,18 @@ var SPopup = react.forwardRef(function SPopup2({
4472
4518
  )
4473
4519
  }
4474
4520
  ),
4475
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1 overflow-auto", children }),
4521
+ /* @__PURE__ */ jsxRuntime.jsx(
4522
+ "div",
4523
+ {
4524
+ className: cn(
4525
+ "min-h-0 flex-1 overflow-auto",
4526
+ SCROLLBAR_CLASS,
4527
+ SCROLLBAR_TRACK_BG_CLASS,
4528
+ SCROLLBAR_TRACK_BORDER_CLASS
4529
+ ),
4530
+ children
4531
+ }
4532
+ ),
4476
4533
  useFooter && /* @__PURE__ */ jsxRuntime.jsxs(
4477
4534
  "footer",
4478
4535
  {
@@ -5533,14 +5590,24 @@ var SGnb = react.forwardRef(function SGnb2({
5533
5590
  }
5534
5591
  );
5535
5592
  });
5536
- var SPage = react.forwardRef(function SPage2({ className, style, children, ...rest }, ref) {
5593
+ var BACKGROUND_CLASS = {
5594
+ frame: `bg-[var(--sys-color-bg-frame)] ${SCROLLBAR_TRACK_BORDER_CLASS} ${SCROLLBAR_TRACK_BG_CLASS}`,
5595
+ neutral: `bg-[var(--sys-color-bg-neutralLight)] ${SCROLLBAR_TRACK_BORDER_CLASS} ${SCROLLBAR_TRACK_BG_WHITE_CLASS}`,
5596
+ screen: `bg-[var(--sys-color-bg-screen)] ${SCROLLBAR_TRACK_BORDER_CLASS} ${SCROLLBAR_TRACK_BG_CLASS}`
5597
+ };
5598
+ var SPage = react.forwardRef(function SPage2({ background = "frame", className, style, children, ...rest }, ref) {
5537
5599
  const layout = react.useContext(SLayoutContext);
5538
5600
  const gridStyle = layout?.header === "full" ? { gridColumn: 2, gridRow: 2 } : void 0;
5539
5601
  return /* @__PURE__ */ jsxRuntime.jsx(
5540
5602
  "main",
5541
5603
  {
5542
5604
  ref,
5543
- className: cn("box-border min-h-0 min-w-0 flex-1 overflow-auto p-20", className),
5605
+ className: cn(
5606
+ "box-border min-h-0 min-w-0 flex-1 overflow-auto p-20",
5607
+ SCROLLBAR_CLASS,
5608
+ BACKGROUND_CLASS[background],
5609
+ className
5610
+ ),
5544
5611
  style: { ...gridStyle, ...style },
5545
5612
  ...rest,
5546
5613
  children
@@ -5548,6 +5615,9 @@ var SPage = react.forwardRef(function SPage2({ className, style, children, ...re
5548
5615
  );
5549
5616
  });
5550
5617
 
5618
+ // src/components/SPage/page.config.ts
5619
+ var PAGE_BACKGROUNDS = ["frame", "neutral", "screen"];
5620
+
5551
5621
  // src/components/STabs/tabs.config.ts
5552
5622
  var TAB_MAIN_SIZE = {
5553
5623
  md: { height: 36, paddingX: 24 },
@@ -5910,7 +5980,7 @@ function SStepper({
5910
5980
  "aria-hidden": true,
5911
5981
  className: "inline-flex h-px shrink-0 items-center",
5912
5982
  style: { width: STEPPER_LAYOUT.dashWidth, color: STEPPER_COLORS.dash },
5913
- children: /* @__PURE__ */ jsxRuntime.jsx(
5983
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
5914
5984
  "svg",
5915
5985
  {
5916
5986
  width: "20",
@@ -5918,16 +5988,12 @@ function SStepper({
5918
5988
  viewBox: "0 0 20 1",
5919
5989
  fill: "none",
5920
5990
  xmlns: "http://www.w3.org/2000/svg",
5921
- children: /* @__PURE__ */ jsxRuntime.jsx(
5922
- "line",
5923
- {
5924
- y1: "0.5",
5925
- x2: "20",
5926
- y2: "0.5",
5927
- stroke: "#888888",
5928
- strokeDasharray: "4 4"
5929
- }
5930
- )
5991
+ children: [
5992
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "1.6", height: "1", fill: "#888888" }),
5993
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "5", width: "3.3", height: "1", fill: "#888888" }),
5994
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "11.7", width: "3.3", height: "1", fill: "#888888" }),
5995
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "18.4", width: "1.6", height: "1", fill: "#888888" })
5996
+ ]
5931
5997
  }
5932
5998
  )
5933
5999
  }
@@ -6068,6 +6134,7 @@ var SField = react.forwardRef(function SField2({
6068
6134
  disabled = false,
6069
6135
  readOnly = false,
6070
6136
  width,
6137
+ minWidth,
6071
6138
  multiline = false,
6072
6139
  borderless = false,
6073
6140
  children,
@@ -6103,6 +6170,7 @@ var SField = react.forwardRef(function SField2({
6103
6170
  const resolvedSuccess = status === "pass";
6104
6171
  const showError = resolvedError && errorMessage !== "";
6105
6172
  const interactive = !disabled && !readOnly;
6173
+ const hug = cssLen(width) !== void 0;
6106
6174
  const borderColor = borderless ? "transparent" : disabled ? "var(--color-grey-45)" : interactive && focused ? "var(--sys-color-field-border-focus)" : resolvedSuccess ? "var(--sys-color-field-border-success)" : resolvedError ? "var(--sys-color-field-border-danger)" : "var(--sys-color-field-border-default)";
6107
6175
  const bgColor = borderless ? "transparent" : disabled ? "var(--color-grey-30)" : readOnly ? "var(--sys-color-field-bg-readOnly)" : "var(--sys-color-field-bg-default)";
6108
6176
  const textColor = disabled ? "var(--color-grey-65)" : readOnly ? "var(--sys-color-field-text-readOnly)" : "var(--sys-color-field-text-default)";
@@ -6111,7 +6179,13 @@ var SField = react.forwardRef(function SField2({
6111
6179
  {
6112
6180
  ref: rootRef,
6113
6181
  "data-name": name || void 0,
6114
- className: cn("inline-flex h-fit w-full flex-col", className),
6182
+ className: cn(
6183
+ "h-fit flex-col",
6184
+ // hug 시 inline-flex 를 유지하면 기존에 세로로 쌓여 있던 필드들이 한 줄에 붙어버리므로
6185
+ // 블록 레벨(flex)로 두어 쌓임은 그대로 유지한다. 나란히 놓으려면 부모를 flex 로.
6186
+ hug ? "flex w-fit max-w-full" : "inline-flex w-full",
6187
+ className
6188
+ ),
6115
6189
  style,
6116
6190
  onMouseEnter,
6117
6191
  onMouseLeave,
@@ -6149,54 +6223,60 @@ var SField = react.forwardRef(function SField2({
6149
6223
  ]
6150
6224
  }
6151
6225
  ),
6152
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
6153
- /* @__PURE__ */ jsxRuntime.jsxs(
6154
- "div",
6155
- {
6156
- className: cn(
6157
- "relative box-border flex min-w-0 items-stretch overflow-hidden border border-solid border-(--field-bc)",
6158
- interactive && !borderless && "hover:border-(--sys-color-field-border-focus) hover:shadow-[0px_0px_4px_0px_#0071ff66] focus-within:border-(--sys-color-field-border-focus) focus-within:shadow-[0px_0px_4px_0px_#0071ff66]",
6159
- disabled && "cursor-not-allowed"
6226
+ /* @__PURE__ */ jsxRuntime.jsxs(
6227
+ "div",
6228
+ {
6229
+ className: cn("flex min-w-0 flex-col", !hug && "flex-1"),
6230
+ style: { width: cssLen(width), minWidth: cssLen(minWidth) },
6231
+ children: [
6232
+ /* @__PURE__ */ jsxRuntime.jsxs(
6233
+ "div",
6234
+ {
6235
+ className: cn(
6236
+ "relative box-border flex min-w-0 items-stretch overflow-hidden border border-solid border-(--field-bc)",
6237
+ interactive && !borderless && "hover:border-(--sys-color-field-border-focus) hover:shadow-[0px_0px_4px_0px_#0071ff66] focus-within:border-(--sys-color-field-border-focus) focus-within:shadow-[0px_0px_4px_0px_#0071ff66]",
6238
+ disabled && "cursor-not-allowed"
6239
+ ),
6240
+ style: {
6241
+ // @ts-expect-error CSS 변수
6242
+ "--field-bc": borderColor,
6243
+ // focused/hovered prop이 명시된 경우 강조를 즉시 반영
6244
+ ...interactive && !borderless && focused ? { boxShadow: "0px 0px 4px 0px #0071ff66" } : {},
6245
+ ...multiline ? { minHeight: s.height } : { height: s.height },
6246
+ "borderRadius": s.radius,
6247
+ "background": bgColor,
6248
+ "color": textColor
6249
+ },
6250
+ "data-focused": focused || void 0,
6251
+ "data-hovered": hovered || void 0,
6252
+ children: [
6253
+ effectiveAddonLabel !== "" && /* @__PURE__ */ jsxRuntime.jsxs(
6254
+ "div",
6255
+ {
6256
+ className: "flex shrink-0 items-center gap-(--cmp-field-addonLabel-gap) whitespace-nowrap border-r border-solid px-(--cmp-field-addonLabel-paddingX) text-12 font-medium leading-20",
6257
+ style: {
6258
+ // 원본 sd-field: labelWidth가 addon 폭(--sd-field-addon-width)에도 적용됨
6259
+ width: cssLen(labelWidth),
6260
+ justifyContent: ALIGN[addonAlign],
6261
+ background: "var(--cmp-field-addonLabel-bg)",
6262
+ borderRightColor: disabled ? "var(--cmp-field-addonLabel-border-disabled)" : "var(--cmp-field-addonLabel-border-default)",
6263
+ borderTopLeftRadius: s.radius - 1,
6264
+ borderBottomLeftRadius: s.radius - 1
6265
+ },
6266
+ children: [
6267
+ icon && !label && /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: icon, size: s.icon, color: iconColor }),
6268
+ effectiveAddonLabel
6269
+ ]
6270
+ }
6271
+ ),
6272
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-0 flex-1", children })
6273
+ ]
6274
+ }
6160
6275
  ),
6161
- style: {
6162
- // @ts-expect-error CSS 변수
6163
- "--field-bc": borderColor,
6164
- // focused/hovered prop이 명시된 경우 강조를 즉시 반영
6165
- ...interactive && !borderless && focused ? { boxShadow: "0px 0px 4px 0px #0071ff66" } : {},
6166
- ...multiline ? { minHeight: s.height } : { height: s.height },
6167
- "width": cssLen(width),
6168
- "borderRadius": s.radius,
6169
- "background": bgColor,
6170
- "color": textColor
6171
- },
6172
- "data-focused": focused || void 0,
6173
- "data-hovered": hovered || void 0,
6174
- children: [
6175
- effectiveAddonLabel !== "" && /* @__PURE__ */ jsxRuntime.jsxs(
6176
- "div",
6177
- {
6178
- className: "flex shrink-0 items-center gap-(--cmp-field-addonLabel-gap) whitespace-nowrap border-r border-solid px-(--cmp-field-addonLabel-paddingX) text-12 font-medium leading-20",
6179
- style: {
6180
- // 원본 sd-field: labelWidth가 addon 폭(--sd-field-addon-width)에도 적용됨
6181
- width: cssLen(labelWidth),
6182
- justifyContent: ALIGN[addonAlign],
6183
- background: "var(--cmp-field-addonLabel-bg)",
6184
- borderRightColor: disabled ? "var(--cmp-field-addonLabel-border-disabled)" : "var(--cmp-field-addonLabel-border-default)",
6185
- borderTopLeftRadius: s.radius - 1,
6186
- borderBottomLeftRadius: s.radius - 1
6187
- },
6188
- children: [
6189
- icon && !label && /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: icon, size: s.icon, color: iconColor }),
6190
- effectiveAddonLabel
6191
- ]
6192
- }
6193
- ),
6194
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-0 flex-1", children })
6195
- ]
6196
- }
6197
- ),
6198
- showError ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-(--cmp-field-contents-gap) text-12 font-normal leading-20 text-(--cmp-field-errorMessage-color)", children: errorMessage }) : hint !== "" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-(--cmp-field-contents-gap) text-12 font-normal leading-20 text-(--cmp-field-hint-color)", children: hint }) : null
6199
- ] })
6276
+ showError ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-(--cmp-field-contents-gap) text-12 font-normal leading-20 text-(--cmp-field-errorMessage-color)", children: errorMessage }) : hint !== "" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-(--cmp-field-contents-gap) text-12 font-normal leading-20 text-(--cmp-field-hint-color)", children: hint }) : null
6277
+ ]
6278
+ }
6279
+ )
6200
6280
  ] })
6201
6281
  }
6202
6282
  );
@@ -6545,7 +6625,12 @@ var SSelect = react.forwardRef(function SSelect2({
6545
6625
  "div",
6546
6626
  {
6547
6627
  ref: listRef,
6548
- 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)]",
6628
+ className: cn(
6629
+ "overflow-auto",
6630
+ SCROLLBAR_CLASS,
6631
+ SCROLLBAR_TRACK_BG_CLASS,
6632
+ SCROLLBAR_TRACK_BORDER_CLASS
6633
+ ),
6549
6634
  style: { maxHeight: dropdownHeight },
6550
6635
  onMouseLeave: () => setFocusedIndex(-1),
6551
6636
  children: [
@@ -7034,7 +7119,7 @@ var STable = react.forwardRef(function STable2({
7034
7119
  position: "sticky",
7035
7120
  left: isLeft ? "var(--sticky-left-offset)" : void 0,
7036
7121
  right: isRight ? "var(--sticky-right-offset)" : void 0,
7037
- zIndex: 3
7122
+ zIndex: 6
7038
7123
  };
7039
7124
  };
7040
7125
  const stickyShadowClass = (i) => {
@@ -7060,6 +7145,9 @@ var STable = react.forwardRef(function STable2({
7060
7145
  onScroll: handleScroll,
7061
7146
  className: cn(
7062
7147
  "bg-white relative overflow-auto border border-solid border-[color:var(--cmp-table-border-color)]",
7148
+ SCROLLBAR_CLASS,
7149
+ SCROLLBAR_TRACK_BG_CLASS,
7150
+ SCROLLBAR_TRACK_BORDER_CLASS,
7063
7151
  radiusClass,
7064
7152
  // 원본 sd-table__scroll-container--loading/--no-data: 로딩·데이터 없음 시 스크롤·인터랙션 차단
7065
7153
  (isLoading || rowCount === 0) && "overflow-hidden pointer-events-none"
@@ -7088,7 +7176,7 @@ var STable = react.forwardRef(function STable2({
7088
7176
  {
7089
7177
  className: cn(
7090
7178
  // 원본 .th--selected: 48px 고정폭, 항상 left sticky, 체크박스 중앙정렬
7091
- "sticky left-0 z-[4] border-b border-solid border-[color:var(--cmp-table-border-color)] bg-[var(--cmp-table-header-bg)] text-center align-middle",
7179
+ "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",
7092
7180
  stickyLeft === 0 && scrolledLeft && "shadow-[5px_0_8px_0_rgba(34,34,34,0.1)]"
7093
7181
  ),
7094
7182
  style: {
@@ -7113,13 +7201,13 @@ var STable = react.forwardRef(function STable2({
7113
7201
  {
7114
7202
  className: cn(
7115
7203
  "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)]",
7116
- stickyInfo(i).isSticky && "z-[4]",
7204
+ stickyInfo(i).isSticky && "z-[6]",
7117
7205
  stickyShadowClass(i),
7118
7206
  col.thClass
7119
7207
  ),
7120
7208
  style: { textAlign: col.align ?? "left", ...cellStyle(i), ...col.thStyle },
7121
7209
  children: [
7122
- /* @__PURE__ */ jsxRuntime.jsxs(
7210
+ /* @__PURE__ */ jsxRuntime.jsx(
7123
7211
  "span",
7124
7212
  {
7125
7213
  className: cn(
@@ -7128,10 +7216,10 @@ var STable = react.forwardRef(function STable2({
7128
7216
  col.align === "center" && "justify-center",
7129
7217
  col.align === "right" && "justify-end"
7130
7218
  ),
7131
- children: [
7219
+ children: col.renderHeader ? col.renderHeader(col, i) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7132
7220
  col.icon && /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: col.icon, size: 16, color: col.iconColor }),
7133
7221
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: col.label })
7134
- ]
7222
+ ] })
7135
7223
  }
7136
7224
  ),
7137
7225
  resizable && !col.autoWidth && i < visibleCols.length - 1 && // 원본 th__resizer: 셀 우측 경계 안쪽 4px 그립(좌우 1px #CCCCCC 라인, 세로 16px).
@@ -10431,6 +10519,8 @@ function formatTimeDisplay(value, type) {
10431
10519
  const displayHour = hour % 12 === 0 ? 12 : hour % 12;
10432
10520
  return `${meridiem} ${padTimePart(displayHour)}:${padTimePart(minute)}`;
10433
10521
  }
10522
+ var TIME_SELECTOR_WIDTH = 136;
10523
+ var MERIDIEM_TIME_SELECTOR_WIDTH = 154;
10434
10524
  function TimeSelector({
10435
10525
  value,
10436
10526
  useMeridiem,
@@ -10669,7 +10759,9 @@ function STimePicker({
10669
10759
  style
10670
10760
  }) {
10671
10761
  const portalContainer = usePortalContainer();
10762
+ const triggerRef = react.useRef(null);
10672
10763
  const [open, setOpen] = react.useState(false);
10764
+ const [popoverAlignOffset, setPopoverAlignOffset] = react.useState(0);
10673
10765
  const [focused, setFocused] = react.useState(false);
10674
10766
  const [ruleError, setRuleError] = react.useState("");
10675
10767
  const dims = TIMEPICKER_SIZE_CONFIG[size] ?? TIMEPICKER_SIZE_CONFIG.sm;
@@ -10690,6 +10782,11 @@ function STimePicker({
10690
10782
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
10691
10783
  const commitOpen = (next) => {
10692
10784
  if (disabled) return;
10785
+ if (next) {
10786
+ const triggerWidth = triggerRef.current?.getBoundingClientRect().width ?? 0;
10787
+ const selectorWidth = effectiveUseMeridiem ? MERIDIEM_TIME_SELECTOR_WIDTH : TIME_SELECTOR_WIDTH;
10788
+ setPopoverAlignOffset(Math.max(0, (triggerWidth - selectorWidth) / 2));
10789
+ }
10693
10790
  setOpen(next);
10694
10791
  onOpenChange?.(next);
10695
10792
  if (!next && rules && rules.length > 0) setRuleError(runRules(value, rules));
@@ -10716,19 +10813,32 @@ function STimePicker({
10716
10813
  focused: focused || open,
10717
10814
  errorMessage: ruleError !== "" ? ruleError : errorMessage,
10718
10815
  width,
10816
+ minWidth: dims.fieldMinWidth,
10719
10817
  disabled,
10720
10818
  className,
10721
- style: { minWidth: dims.fieldMinWidth, ...style },
10819
+ style,
10722
10820
  children: /* @__PURE__ */ jsxRuntime.jsxs(RPopover2__namespace.Root, { open, onOpenChange: commitOpen, children: [
10723
10821
  /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
10724
- "button",
10822
+ "div",
10725
10823
  {
10726
- type: "button",
10727
- name,
10728
- disabled,
10824
+ ref: triggerRef,
10825
+ role: "button",
10826
+ "aria-disabled": disabled,
10827
+ tabIndex: disabled ? -1 : 0,
10828
+ "data-name": name,
10729
10829
  onFocus: () => setFocused(true),
10730
10830
  onBlur: () => setFocused(false),
10731
- className: "flex h-full w-full items-center overflow-hidden bg-transparent outline-none disabled:cursor-not-allowed",
10831
+ onKeyDown: (event) => {
10832
+ if (disabled) return;
10833
+ if (event.key === "Enter" || event.key === " ") {
10834
+ event.preventDefault();
10835
+ commitOpen(!open);
10836
+ }
10837
+ },
10838
+ className: cn(
10839
+ "flex h-full w-full items-center overflow-hidden bg-transparent outline-none",
10840
+ disabled ? "cursor-not-allowed" : "cursor-pointer"
10841
+ ),
10732
10842
  style: { padding: `0 ${dims.paddingX}`, gap: dims.gap, borderRadius: dims.radius },
10733
10843
  children: [
10734
10844
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -10774,6 +10884,7 @@ function STimePicker({
10774
10884
  side: "bottom",
10775
10885
  align: "start",
10776
10886
  sideOffset: 4,
10887
+ alignOffset: popoverAlignOffset,
10777
10888
  className: cn("z-50", FLOATING_SLIDE_ANIM),
10778
10889
  children: /* @__PURE__ */ jsxRuntime.jsx(
10779
10890
  TimeSelector,
@@ -10811,6 +10922,11 @@ function formatTimeRangeDisplay(value, type) {
10811
10922
  if (value == null || value[0] === "" || value[1] === "") return "";
10812
10923
  return `${formatTimeDisplay(value[0], type)} ~ ${formatTimeDisplay(value[1], type)}`;
10813
10924
  }
10925
+ var TIME_RANGE_SELECTOR_WIDTH = 345;
10926
+ var MIDDAY_FIELD_MIN_WIDTH = {
10927
+ sm: 178,
10928
+ md: 216
10929
+ };
10814
10930
  function RangeTimeSelector({
10815
10931
  value,
10816
10932
  useMeridiem,
@@ -11100,7 +11216,9 @@ function STimeRangePicker({
11100
11216
  style
11101
11217
  }) {
11102
11218
  const portalContainer = usePortalContainer();
11219
+ const triggerRef = react.useRef(null);
11103
11220
  const [open, setOpen] = react.useState(false);
11221
+ const [popoverAlignOffset, setPopoverAlignOffset] = react.useState(0);
11104
11222
  const [focused, setFocused] = react.useState(false);
11105
11223
  const [ruleError, setRuleError] = react.useState("");
11106
11224
  const dims = TIMEPICKER_SIZE_CONFIG[size] ?? TIMEPICKER_SIZE_CONFIG.sm;
@@ -11124,6 +11242,10 @@ function STimeRangePicker({
11124
11242
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
11125
11243
  const commitOpen = (next) => {
11126
11244
  if (disabled) return;
11245
+ if (next) {
11246
+ const triggerWidth = triggerRef.current?.getBoundingClientRect().width ?? 0;
11247
+ setPopoverAlignOffset(Math.max(0, (triggerWidth - TIME_RANGE_SELECTOR_WIDTH) / 2));
11248
+ }
11127
11249
  setOpen(next);
11128
11250
  onOpenChange?.(next);
11129
11251
  if (!next && rules && rules.length > 0) setRuleError(runRules(value, rules));
@@ -11150,19 +11272,32 @@ function STimeRangePicker({
11150
11272
  focused: focused || open,
11151
11273
  errorMessage: ruleError !== "" ? ruleError : errorMessage,
11152
11274
  width,
11275
+ minWidth: effectiveUseMeridiem ? MIDDAY_FIELD_MIN_WIDTH[size] : dims.fieldMinWidth,
11153
11276
  disabled,
11154
11277
  className,
11155
- style: { minWidth: dims.fieldMinWidth, ...style },
11278
+ style,
11156
11279
  children: /* @__PURE__ */ jsxRuntime.jsxs(RPopover2__namespace.Root, { open, onOpenChange: commitOpen, children: [
11157
11280
  /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
11158
- "button",
11281
+ "div",
11159
11282
  {
11160
- type: "button",
11161
- name,
11162
- disabled,
11283
+ ref: triggerRef,
11284
+ role: "button",
11285
+ "aria-disabled": disabled,
11286
+ tabIndex: disabled ? -1 : 0,
11287
+ "data-name": name,
11163
11288
  onFocus: () => setFocused(true),
11164
11289
  onBlur: () => setFocused(false),
11165
- className: "flex h-full w-full items-center overflow-hidden bg-transparent outline-none disabled:cursor-not-allowed",
11290
+ onKeyDown: (event) => {
11291
+ if (disabled) return;
11292
+ if (event.key === "Enter" || event.key === " ") {
11293
+ event.preventDefault();
11294
+ commitOpen(!open);
11295
+ }
11296
+ },
11297
+ className: cn(
11298
+ "flex h-full w-full items-center overflow-hidden bg-transparent outline-none",
11299
+ disabled ? "cursor-not-allowed" : "cursor-pointer"
11300
+ ),
11166
11301
  style: { padding: `0 ${dims.paddingX}`, gap: dims.gap, borderRadius: dims.radius },
11167
11302
  children: [
11168
11303
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -11208,6 +11343,7 @@ function STimeRangePicker({
11208
11343
  side: "bottom",
11209
11344
  align: "start",
11210
11345
  sideOffset: 4,
11346
+ alignOffset: popoverAlignOffset,
11211
11347
  className: cn("z-50", FLOATING_SLIDE_ANIM),
11212
11348
  children: /* @__PURE__ */ jsxRuntime.jsx(
11213
11349
  RangeTimeSelector,
@@ -11239,10 +11375,12 @@ exports.GNB_MENU_WIDTH = GNB_MENU_WIDTH;
11239
11375
  exports.GNB_RAIL = GNB_RAIL;
11240
11376
  exports.GNB_RAIL_WIDTH = GNB_RAIL_WIDTH;
11241
11377
  exports.ICONS = ICONS;
11378
+ exports.PAGE_BACKGROUNDS = PAGE_BACKGROUNDS;
11242
11379
  exports.SActionModal = SActionModal;
11243
11380
  exports.SBadge = SBadge;
11244
11381
  exports.SBarcodeInput = SBarcodeInput;
11245
11382
  exports.SButton = SButton;
11383
+ exports.SCROLL_AREA_AXES = SCROLL_AREA_AXES;
11246
11384
  exports.SCalendar = SCalendar;
11247
11385
  exports.SCallout = SCallout;
11248
11386
  exports.SCard = SCard;
@@ -11279,6 +11417,7 @@ exports.SPortal = SPortal;
11279
11417
  exports.SRadio = SRadio;
11280
11418
  exports.SRadioButton = SRadioButton;
11281
11419
  exports.SRadioGroup = SRadioGroup;
11420
+ exports.SScrollArea = SScrollArea;
11282
11421
  exports.SSelect = SSelect;
11283
11422
  exports.SStepper = SStepper;
11284
11423
  exports.SSwitch = SSwitch;