sellmate-design-system-react 0.1.8 → 0.1.9

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 (104) hide show
  1. package/dist/components/SActionModal/SActionModal.cjs +1 -1
  2. package/dist/components/SActionModal/SActionModal.cjs.map +1 -1
  3. package/dist/components/SActionModal/SActionModal.js +1 -1
  4. package/dist/components/SActionModal/SActionModal.js.map +1 -1
  5. package/dist/components/SBarcodeInput/SBarcodeInput.cjs +218 -209
  6. package/dist/components/SBarcodeInput/SBarcodeInput.cjs.map +1 -1
  7. package/dist/components/SBarcodeInput/SBarcodeInput.js +218 -209
  8. package/dist/components/SBarcodeInput/SBarcodeInput.js.map +1 -1
  9. package/dist/components/SCalendar/SCalendar.cjs +1 -1
  10. package/dist/components/SCalendar/SCalendar.cjs.map +1 -1
  11. package/dist/components/SCalendar/SCalendar.js +1 -1
  12. package/dist/components/SCalendar/SCalendar.js.map +1 -1
  13. package/dist/components/SChip/SChip.cjs +1 -1
  14. package/dist/components/SChip/SChip.cjs.map +1 -1
  15. package/dist/components/SChip/SChip.d.ts +1 -1
  16. package/dist/components/SChip/SChip.js +1 -1
  17. package/dist/components/SChip/SChip.js.map +1 -1
  18. package/dist/components/SChipInput/SChipInput.cjs +235 -221
  19. package/dist/components/SChipInput/SChipInput.cjs.map +1 -1
  20. package/dist/components/SChipInput/SChipInput.js +235 -221
  21. package/dist/components/SChipInput/SChipInput.js.map +1 -1
  22. package/dist/components/SCircleProgress/SCircleProgress.cjs +53 -55
  23. package/dist/components/SCircleProgress/SCircleProgress.cjs.map +1 -1
  24. package/dist/components/SCircleProgress/SCircleProgress.js +53 -55
  25. package/dist/components/SCircleProgress/SCircleProgress.js.map +1 -1
  26. package/dist/components/SDatePicker/SDatePicker.cjs +223 -214
  27. package/dist/components/SDatePicker/SDatePicker.cjs.map +1 -1
  28. package/dist/components/SDatePicker/SDatePicker.js +223 -214
  29. package/dist/components/SDatePicker/SDatePicker.js.map +1 -1
  30. package/dist/components/SDateRangePicker/SDateRangePicker.cjs +298 -263
  31. package/dist/components/SDateRangePicker/SDateRangePicker.cjs.map +1 -1
  32. package/dist/components/SDateRangePicker/SDateRangePicker.js +298 -263
  33. package/dist/components/SDateRangePicker/SDateRangePicker.js.map +1 -1
  34. package/dist/components/SDropdownButton/SDropdownButton.cjs +4 -4
  35. package/dist/components/SDropdownButton/SDropdownButton.cjs.map +1 -1
  36. package/dist/components/SDropdownButton/SDropdownButton.js +4 -4
  37. package/dist/components/SDropdownButton/SDropdownButton.js.map +1 -1
  38. package/dist/components/SField/SField.cjs +218 -21
  39. package/dist/components/SField/SField.cjs.map +1 -1
  40. package/dist/components/SField/SField.d.ts +11 -0
  41. package/dist/components/SField/SField.js +218 -21
  42. package/dist/components/SField/SField.js.map +1 -1
  43. package/dist/components/SFilePicker/SFilePicker.cjs +298 -278
  44. package/dist/components/SFilePicker/SFilePicker.cjs.map +1 -1
  45. package/dist/components/SFilePicker/SFilePicker.d.ts +4 -2
  46. package/dist/components/SFilePicker/SFilePicker.js +298 -278
  47. package/dist/components/SFilePicker/SFilePicker.js.map +1 -1
  48. package/dist/components/SInput/SInput.cjs +218 -209
  49. package/dist/components/SInput/SInput.cjs.map +1 -1
  50. package/dist/components/SInput/SInput.js +218 -209
  51. package/dist/components/SInput/SInput.js.map +1 -1
  52. package/dist/components/SKeyValueTable/SKeyValueTable.cjs +610 -450
  53. package/dist/components/SKeyValueTable/SKeyValueTable.cjs.map +1 -1
  54. package/dist/components/SKeyValueTable/SKeyValueTable.d.ts +3 -1
  55. package/dist/components/SKeyValueTable/SKeyValueTable.js +610 -450
  56. package/dist/components/SKeyValueTable/SKeyValueTable.js.map +1 -1
  57. package/dist/components/SLoadingContainer/SLoadingContainer.cjs +61 -55
  58. package/dist/components/SLoadingContainer/SLoadingContainer.cjs.map +1 -1
  59. package/dist/components/SLoadingContainer/SLoadingContainer.js +61 -55
  60. package/dist/components/SLoadingContainer/SLoadingContainer.js.map +1 -1
  61. package/dist/components/SLoadingContainer/loading.cjs +61 -55
  62. package/dist/components/SLoadingContainer/loading.cjs.map +1 -1
  63. package/dist/components/SLoadingContainer/loading.js +61 -55
  64. package/dist/components/SLoadingContainer/loading.js.map +1 -1
  65. package/dist/components/SLoadingModal/SLoadingModal.cjs +56 -57
  66. package/dist/components/SLoadingModal/SLoadingModal.cjs.map +1 -1
  67. package/dist/components/SLoadingModal/SLoadingModal.js +56 -57
  68. package/dist/components/SLoadingModal/SLoadingModal.js.map +1 -1
  69. package/dist/components/SNumberInput/SNumberInput.cjs +326 -50
  70. package/dist/components/SNumberInput/SNumberInput.cjs.map +1 -1
  71. package/dist/components/SNumberInput/SNumberInput.d.ts +2 -0
  72. package/dist/components/SNumberInput/SNumberInput.js +326 -50
  73. package/dist/components/SNumberInput/SNumberInput.js.map +1 -1
  74. package/dist/components/SPagination/SPagination.cjs +1 -1
  75. package/dist/components/SPagination/SPagination.cjs.map +1 -1
  76. package/dist/components/SPagination/SPagination.js +1 -1
  77. package/dist/components/SPagination/SPagination.js.map +1 -1
  78. package/dist/components/SSelect/SSelect.cjs +67 -32
  79. package/dist/components/SSelect/SSelect.cjs.map +1 -1
  80. package/dist/components/SSelect/SSelect.js +67 -32
  81. package/dist/components/SSelect/SSelect.js.map +1 -1
  82. package/dist/components/STable/STable.cjs +121 -88
  83. package/dist/components/STable/STable.cjs.map +1 -1
  84. package/dist/components/STable/STable.js +121 -88
  85. package/dist/components/STable/STable.js.map +1 -1
  86. package/dist/components/STextarea/STextarea.cjs +218 -21
  87. package/dist/components/STextarea/STextarea.cjs.map +1 -1
  88. package/dist/components/STextarea/STextarea.js +218 -21
  89. package/dist/components/STextarea/STextarea.js.map +1 -1
  90. package/dist/components/SToast/SToastContainer.cjs +3 -3
  91. package/dist/components/SToast/SToastContainer.cjs.map +1 -1
  92. package/dist/components/SToast/SToastContainer.js +3 -3
  93. package/dist/components/SToast/SToastContainer.js.map +1 -1
  94. package/dist/components/STooltip/STooltip.cjs +209 -14
  95. package/dist/components/STooltip/STooltip.cjs.map +1 -1
  96. package/dist/components/STooltip/STooltip.js +209 -14
  97. package/dist/components/STooltip/STooltip.js.map +1 -1
  98. package/dist/index.cjs +432 -260
  99. package/dist/index.cjs.map +1 -1
  100. package/dist/index.js +432 -260
  101. package/dist/index.js.map +1 -1
  102. package/dist/styles.css +51 -27
  103. package/dist/theme.css +4 -2
  104. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3310,65 +3310,63 @@ var SCircleProgress = forwardRef(
3310
3310
  "div",
3311
3311
  {
3312
3312
  ref,
3313
- className: cn("inline-flex flex-col items-center gap-[8px]", className),
3313
+ className: cn(
3314
+ "inline-flex flex-col items-center gap-[var(--cmp-progress-circular-gap)]",
3315
+ className
3316
+ ),
3314
3317
  style,
3315
3318
  children: [
3316
- /* @__PURE__ */ jsxs("div", { className: "relative h-[80px] w-[80px]", children: [
3317
- /* @__PURE__ */ jsxs(
3318
- "svg",
3319
- {
3320
- viewBox: `0 0 ${VIEWBOX} ${VIEWBOX}`,
3321
- xmlns: "http://www.w3.org/2000/svg",
3322
- className: cn(
3323
- "h-[80px] w-[80px]",
3324
- indeterminate && "origin-center animate-circle-spin"
3319
+ /* @__PURE__ */ jsxs(
3320
+ "svg",
3321
+ {
3322
+ viewBox: `0 0 ${VIEWBOX} ${VIEWBOX}`,
3323
+ xmlns: "http://www.w3.org/2000/svg",
3324
+ className: cn("h-[80px] w-[80px]", indeterminate && "origin-center animate-circle-spin"),
3325
+ children: [
3326
+ /* @__PURE__ */ jsx(
3327
+ "circle",
3328
+ {
3329
+ cx: c,
3330
+ cy: c,
3331
+ r: RADIUS,
3332
+ fill: "none",
3333
+ strokeWidth: STROKE,
3334
+ style: { stroke: colors.track }
3335
+ }
3325
3336
  ),
3326
- children: [
3327
- /* @__PURE__ */ jsx(
3328
- "circle",
3329
- {
3330
- cx: c,
3331
- cy: c,
3332
- r: RADIUS,
3333
- fill: "none",
3334
- strokeWidth: STROKE,
3335
- style: { stroke: colors.track }
3336
- }
3337
- ),
3338
- /* @__PURE__ */ jsx(
3339
- "circle",
3340
- {
3341
- cx: c,
3342
- cy: c,
3343
- r: RADIUS,
3344
- fill: "none",
3345
- strokeWidth: STROKE,
3346
- strokeLinecap: "round",
3347
- className: cn(
3348
- "origin-center",
3349
- indeterminate ? "animate-circle-arc" : "-rotate-90 transition-[stroke-dasharray] duration-[400ms] ease-linear"
3350
- ),
3351
- style: {
3352
- stroke: colors.arc,
3353
- ...indeterminate ? {} : { strokeDasharray: `${filled} ${CIRCUMFERENCE}`, strokeDashoffset: 0 }
3354
- }
3337
+ /* @__PURE__ */ jsx(
3338
+ "circle",
3339
+ {
3340
+ cx: c,
3341
+ cy: c,
3342
+ r: RADIUS,
3343
+ fill: "none",
3344
+ strokeWidth: STROKE,
3345
+ strokeLinecap: "round",
3346
+ className: cn(
3347
+ "origin-center",
3348
+ indeterminate ? "animate-circle-arc" : "-rotate-90 transition-[stroke-dasharray] duration-[400ms] ease-linear"
3349
+ ),
3350
+ style: {
3351
+ stroke: colors.arc,
3352
+ ...indeterminate ? {} : { strokeDasharray: `${filled} ${CIRCUMFERENCE}`, strokeDashoffset: 0 }
3355
3353
  }
3356
- )
3357
- ]
3358
- }
3359
- ),
3360
- !indeterminate && /* @__PURE__ */ jsxs(
3361
- "span",
3362
- {
3363
- className: "absolute inset-0 flex items-center justify-center text-[16px] font-bold leading-[26px]",
3364
- style: { color: percentColor },
3365
- children: [
3366
- Math.round(v),
3367
- "%"
3368
- ]
3369
- }
3370
- )
3371
- ] }),
3354
+ }
3355
+ )
3356
+ ]
3357
+ }
3358
+ ),
3359
+ !indeterminate && /* @__PURE__ */ jsxs(
3360
+ "span",
3361
+ {
3362
+ className: "text-center text-[16px] font-bold leading-[26px]",
3363
+ style: { color: percentColor },
3364
+ children: [
3365
+ Math.round(v),
3366
+ "%"
3367
+ ]
3368
+ }
3369
+ ),
3372
3370
  label && /* @__PURE__ */ jsx("span", { className: "text-center text-[12px] font-normal leading-[20px] text-[color:var(--cmp-progress-color-label)]", children: label })
3373
3371
  ]
3374
3372
  }
@@ -3379,6 +3377,14 @@ var SLoadingContainer = forwardRef(
3379
3377
  function SLoadingContainer2({ open = false, message, zIndex = 1200, className, style }, ref) {
3380
3378
  const [mounted2, setMounted] = useState(false);
3381
3379
  useEffect(() => setMounted(true), []);
3380
+ useEffect(() => {
3381
+ if (!open) return;
3382
+ const prev = document.body.style.overflow;
3383
+ document.body.style.overflow = "hidden";
3384
+ return () => {
3385
+ document.body.style.overflow = prev;
3386
+ };
3387
+ }, [open]);
3382
3388
  const innerRef = useRef(null);
3383
3389
  const setRef = useCallback(
3384
3390
  (node) => {
@@ -3647,15 +3653,15 @@ var sanitizeInlineHtml = (value) => {
3647
3653
  return template.innerHTML;
3648
3654
  };
3649
3655
  var SIZE = {
3650
- xs: { height: 24, paddingX: 8, gap: 6, arrow: 12, fontSize: 12, minWidth: 44, splitMinWidth: 60 },
3656
+ xs: { height: 24, paddingX: 8, gap: 6, arrow: 12, fontSize: 12, minWidth: 64, splitMinWidth: 72 },
3651
3657
  sm: {
3652
3658
  height: 28,
3653
3659
  paddingX: 12,
3654
3660
  gap: 8,
3655
3661
  arrow: 12,
3656
3662
  fontSize: 12,
3657
- minWidth: 70,
3658
- splitMinWidth: 76
3663
+ minWidth: 72,
3664
+ splitMinWidth: 88
3659
3665
  },
3660
3666
  md: {
3661
3667
  height: 36,
@@ -3763,7 +3769,7 @@ var SDropdownButton = forwardRef(
3763
3769
  align: "start",
3764
3770
  alignOffset: split ? splitAlignOffset : 0,
3765
3771
  className: cn(
3766
- "z-50 overflow-hidden rounded-[var(--cmp-listBox-radius)] bg-[var(--cmp-listBox-bg)] py-[4px] shadow-normal-sm",
3772
+ "z-50 overflow-hidden rounded-[var(--cmp-listBox-radius)] bg-[var(--cmp-listBox-bg)] shadow-normal-sm",
3767
3773
  !split && "min-w-[var(--radix-dropdown-menu-trigger-width)]",
3768
3774
  FLOATING_SLIDE_ANIM
3769
3775
  ),
@@ -4060,7 +4066,8 @@ var HIDE_DELAY_MS = 100;
4060
4066
  function useBody(content, message = []) {
4061
4067
  if (content != null) return content;
4062
4068
  if (message.length === 0) return null;
4063
- return /* @__PURE__ */ jsx(Fragment, { children: message.map((line, i) => /* @__PURE__ */ jsx("div", { children: line }, i)) });
4069
+ const singleLine = message.length === 1;
4070
+ return /* @__PURE__ */ jsx(Fragment, { children: message.map((line, i) => /* @__PURE__ */ jsx("div", { className: singleLine ? "leading-[24px]" : void 0, children: line }, i)) });
4064
4071
  }
4065
4072
  var STooltip = forwardRef(function STooltip2({
4066
4073
  content,
@@ -4118,7 +4125,7 @@ var STooltip = forwardRef(function STooltip2({
4118
4125
  if (disabled || body == null) return /* @__PURE__ */ jsx(Fragment, { children: triggerNode });
4119
4126
  const isHover = trigger === "hover";
4120
4127
  const contentClass = cn(
4121
- "z-50 max-w-xs rounded-[6px] px-[16px] py-[12px] text-[12px] leading-[20px]",
4128
+ "z-50 max-w-xs rounded-[6px] px-[16px] py-[12px] text-[12px] leading-[20px] shadow-[2px_2px_12px_2px_rgba(0,0,0,0.1)]",
4122
4129
  FLOATING_SLIDE_ANIM,
4123
4130
  className
4124
4131
  );
@@ -4163,11 +4170,17 @@ var STooltip = forwardRef(function STooltip2({
4163
4170
  /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-[12px]", children: [
4164
4171
  /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: body }),
4165
4172
  useClose && /* @__PURE__ */ jsx(
4166
- RPopover2.Close,
4173
+ SGhostButton,
4167
4174
  {
4168
- "aria-label": "\uB2EB\uAE30",
4169
- className: "shrink-0 cursor-pointer opacity-70 hover:opacity-100",
4170
- children: /* @__PURE__ */ jsx(SIcon, { name: "close", size: 16, color: fg })
4175
+ icon: "close",
4176
+ size: "xs",
4177
+ intent: tooltipType === "default" ? "inverse" : "default",
4178
+ ariaLabel: "\uB2EB\uAE30",
4179
+ className: "shrink-0",
4180
+ onClick: () => {
4181
+ cancelHide();
4182
+ setOpen(false);
4183
+ }
4171
4184
  }
4172
4185
  )
4173
4186
  ] }),
@@ -4732,7 +4745,7 @@ function SActionModal({
4732
4745
  showClose: true,
4733
4746
  width,
4734
4747
  height,
4735
- className: "w-fit min-w-[480px]",
4748
+ className: "w-fit min-w-[480px] min-h-[320px]",
4736
4749
  children: /* @__PURE__ */ jsxs("div", { className: "flex h-full min-h-[320px] flex-col", children: [
4737
4750
  /* @__PURE__ */ jsx("header", { className: "flex flex-shrink-0 items-center gap-[var(--cmp-overlay-header-gap)] py-[var(--cmp-overlay-header-paddingY)] pl-[var(--cmp-overlay-header-paddingX)] pr-[calc(var(--cmp-overlay-header-paddingX)+20px)]", children: /* @__PURE__ */ jsx("h2", { className: "text-[16px] font-bold leading-[26px] text-[color:var(--cmp-overlay-header-title-color)]", children: modalTitle }) }),
4738
4751
  /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-auto px-[var(--cmp-modal-action-body-paddingX)] pb-[var(--cmp-modal-action-body-paddingBottom)]", children }),
@@ -4764,7 +4777,7 @@ function SActionModal({
4764
4777
  );
4765
4778
  }
4766
4779
  var DEFAULT_MESSAGE = {
4767
- loading: "",
4780
+ loading: "\uC791\uC5C5 \uC9C4\uD589\uC911...",
4768
4781
  error: "\uC791\uC5C5\uC5D0 \uC2E4\uD328\uD558\uC600\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2DC\uB3C4\uD574 \uC8FC\uC138\uC694."
4769
4782
  };
4770
4783
  var DEFAULT_BUTTON_LABEL = {
@@ -4786,6 +4799,7 @@ function SLoadingModal({
4786
4799
  }) {
4787
4800
  const resolvedMessage = message ?? DEFAULT_MESSAGE[state2];
4788
4801
  const lines = Array.isArray(resolvedMessage) ? resolvedMessage : resolvedMessage ? [resolvedMessage] : [];
4802
+ const showButton = useButton || state2 === "error";
4789
4803
  return /* @__PURE__ */ jsx(
4790
4804
  SModalContainer,
4791
4805
  {
@@ -4805,7 +4819,7 @@ function SLoadingModal({
4805
4819
  },
4806
4820
  i
4807
4821
  )) }),
4808
- useButton && /* @__PURE__ */ jsx(
4822
+ showButton && /* @__PURE__ */ jsx(
4809
4823
  SButton,
4810
4824
  {
4811
4825
  color: "neutral",
@@ -5036,7 +5050,7 @@ function SPagination({
5036
5050
  style,
5037
5051
  children: [
5038
5052
  /* @__PURE__ */ jsx("div", { className: "flex min-w-[calc(var(--cmp-pagination-height)*2+var(--cmp-pagination-move-gap))] items-center justify-end gap-[var(--cmp-pagination-move-gap)]", children: prevButtons }),
5039
- simple ? /* @__PURE__ */ jsxs("div", { className: "flex h-[var(--cmp-pagination-height)] items-center gap-[var(--cmp-pagination-move-gap)] px-[var(--cmp-pagination-paddingX)] text-[12px] font-medium leading-[20px] text-[color:var(--cmp-pagination-item-content-default)]", children: [
5053
+ simple ? /* @__PURE__ */ jsxs("div", { className: "flex h-[var(--cmp-pagination-height)] items-center gap-[var(--cmp-pagination-simple-gap)] px-[var(--cmp-pagination-paddingX)] text-[12px] font-medium leading-[20px] text-[color:var(--cmp-pagination-item-content-default)]", children: [
5040
5054
  /* @__PURE__ */ jsx("span", { className: "font-bold text-[color:var(--cmp-pagination-item-content-selected)]", children: currentPage }),
5041
5055
  /* @__PURE__ */ jsx("span", { children: "/" }),
5042
5056
  /* @__PURE__ */ jsx("span", { children: lastPage })
@@ -5160,8 +5174,8 @@ function useFormField(field) {
5160
5174
  }, [ctx, name]);
5161
5175
  }
5162
5176
  var FIELD_SIZE = {
5163
- sm: { height: 28, radius: 4, fieldGap: 12, labelGap: 6, fontSize: 12, lineHeight: 20, icon: 12 },
5164
- md: { height: 36, radius: 6, fieldGap: 16, labelGap: 8, fontSize: 14, lineHeight: 24, icon: 12 }
5177
+ sm: { height: 28, radius: 4, fieldGap: 12, labelGap: 6, fontSize: 12, lineHeight: 20, icon: 16 },
5178
+ md: { height: 36, radius: 6, fieldGap: 16, labelGap: 8, fontSize: 14, lineHeight: 24, icon: 16 }
5165
5179
  };
5166
5180
  var ALIGN = {
5167
5181
  start: "flex-start",
@@ -5176,6 +5190,7 @@ var SField = forwardRef(function SField2({
5176
5190
  labelTooltip = "",
5177
5191
  labelTooltipProps,
5178
5192
  labelWidth,
5193
+ labelHeight,
5179
5194
  size = "sm",
5180
5195
  addonLabel = "",
5181
5196
  addonAlign = "start",
@@ -5190,6 +5205,7 @@ var SField = forwardRef(function SField2({
5190
5205
  readOnly = false,
5191
5206
  width,
5192
5207
  multiline = false,
5208
+ borderless = false,
5193
5209
  children,
5194
5210
  className,
5195
5211
  style,
@@ -5223,8 +5239,8 @@ var SField = forwardRef(function SField2({
5223
5239
  const resolvedSuccess = status === "pass";
5224
5240
  const showError = resolvedError && errorMessage !== "";
5225
5241
  const interactive = !disabled && !readOnly;
5226
- const borderColor = 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)";
5227
- const bgColor = disabled ? "var(--color-grey-30)" : readOnly ? "var(--sys-color-field-bg-readOnly)" : "var(--sys-color-field-bg-default)";
5242
+ 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)";
5243
+ const bgColor = borderless ? "transparent" : disabled ? "var(--color-grey-30)" : readOnly ? "var(--sys-color-field-bg-readOnly)" : "var(--sys-color-field-bg-default)";
5228
5244
  const textColor = disabled ? "var(--color-grey-65)" : readOnly ? "var(--sys-color-field-text-readOnly)" : "var(--sys-color-field-text-default)";
5229
5245
  return /* @__PURE__ */ jsx(
5230
5246
  "div",
@@ -5241,7 +5257,7 @@ var SField = forwardRef(function SField2({
5241
5257
  {
5242
5258
  className: "flex shrink-0 items-center font-bold text-(--sys-color-field-text-default)",
5243
5259
  style: {
5244
- height: s.height,
5260
+ height: cssLen(labelHeight) ?? s.height,
5245
5261
  marginRight: s.fieldGap,
5246
5262
  width: cssLen(labelWidth),
5247
5263
  fontSize: s.fontSize,
@@ -5267,14 +5283,14 @@ var SField = forwardRef(function SField2({
5267
5283
  {
5268
5284
  className: cn(
5269
5285
  "relative box-border flex min-w-0 items-stretch overflow-hidden border border-solid border-(--field-bc)",
5270
- interactive && "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]",
5286
+ 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]",
5271
5287
  disabled && "cursor-not-allowed"
5272
5288
  ),
5273
5289
  style: {
5274
5290
  // @ts-expect-error CSS 변수
5275
5291
  "--field-bc": borderColor,
5276
5292
  // focused/hovered prop이 명시된 경우 강조를 즉시 반영
5277
- ...interactive && focused ? { boxShadow: "0px 0px 4px 0px #0071ff66" } : {},
5293
+ ...interactive && !borderless && focused ? { boxShadow: "0px 0px 4px 0px #0071ff66" } : {},
5278
5294
  ...multiline ? { minHeight: s.height } : { height: s.height },
5279
5295
  "width": cssLen(width),
5280
5296
  "borderRadius": s.radius,
@@ -5319,15 +5335,28 @@ function flattenOptions(options, depth = 1) {
5319
5335
  const out = [];
5320
5336
  for (const o of options) {
5321
5337
  const hasChildren = Array.isArray(o.children) && o.children.length > 0;
5322
- out.push({
5323
- value: String(o.value),
5324
- label: o.label,
5325
- disabled: !!o.disabled,
5326
- depth,
5327
- isGroup: hasChildren,
5328
- raw: o.value
5329
- });
5330
- if (hasChildren) out.push(...flattenOptions(o.children, depth + 1));
5338
+ if (hasChildren) {
5339
+ const childFlat = flattenOptions(o.children, depth + 1);
5340
+ const allChildrenDisabled = childFlat.every((c) => c.disabled);
5341
+ out.push({
5342
+ value: String(o.value),
5343
+ label: o.label,
5344
+ disabled: !!o.disabled || allChildrenDisabled,
5345
+ depth,
5346
+ isGroup: true,
5347
+ raw: o.value
5348
+ });
5349
+ out.push(...childFlat);
5350
+ } else {
5351
+ out.push({
5352
+ value: String(o.value),
5353
+ label: o.label,
5354
+ disabled: !!o.disabled,
5355
+ depth,
5356
+ isGroup: false,
5357
+ raw: o.value
5358
+ });
5359
+ }
5331
5360
  }
5332
5361
  return out;
5333
5362
  }
@@ -5382,6 +5411,9 @@ var SSelect = forwardRef(function SSelect2({
5382
5411
  );
5383
5412
  const flat = useMemo(() => flattenOptions(options), [options]);
5384
5413
  const selectable = useMemo(() => selectableOptions(flat), [flat]);
5414
+ const hasLeaf = useMemo(() => flat.some((o) => !o.isGroup), [flat]);
5415
+ const allOptionsDisabled = hasLeaf && selectable.length === 0;
5416
+ const effectiveDisabled = disabled || allOptionsDisabled;
5385
5417
  const showSearch = useSearch && selectable.length >= SEARCH_THRESHOLD;
5386
5418
  const labelByValue = useMemo(() => new Map(flat.map((o) => [o.value, o.label])), [flat]);
5387
5419
  const rawByValue = useMemo(() => new Map(flat.map((o) => [o.value, o.raw])), [flat]);
@@ -5448,10 +5480,10 @@ var SSelect = forwardRef(function SSelect2({
5448
5480
  Ariakit.Select,
5449
5481
  {
5450
5482
  ref: triggerRef,
5451
- disabled,
5483
+ disabled: effectiveDisabled,
5452
5484
  className: "flex h-full w-full cursor-pointer items-center justify-between gap-[8px] bg-transparent px-[12px] text-left text-[12px] leading-[20px] outline-none disabled:cursor-not-allowed",
5453
5485
  style: {
5454
- color: disabled ? "var(--cmp-select-text-disabled)" : isPlaceholder ? "var(--cmp-select-icon-default)" : "var(--cmp-select-text-default)"
5486
+ color: effectiveDisabled ? "var(--cmp-select-text-disabled)" : isPlaceholder ? "var(--cmp-select-icon-default)" : "var(--cmp-select-text-default)"
5455
5487
  },
5456
5488
  children: [
5457
5489
  isHtmlLabel(triggerText) ? /* @__PURE__ */ jsx(
@@ -5466,7 +5498,7 @@ var SSelect = forwardRef(function SSelect2({
5466
5498
  {
5467
5499
  name: "chevronDown",
5468
5500
  size: 12,
5469
- color: disabled ? "var(--cmp-select-icon-disabled)" : "var(--cmp-select-icon-default)",
5501
+ color: effectiveDisabled ? "var(--cmp-select-icon-disabled)" : "var(--cmp-select-icon-default)",
5470
5502
  className: cn("shrink-0 transition-transform duration-200", open && "rotate-180")
5471
5503
  }
5472
5504
  )
@@ -5480,7 +5512,7 @@ var SSelect = forwardRef(function SSelect2({
5480
5512
  portalElement: portalContainer,
5481
5513
  gutter: 4,
5482
5514
  sameWidth: !dropdownWidth,
5483
- className: "z-50 overflow-auto rounded-[var(--cmp-listBox-radius)] bg-[var(--cmp-listBox-bg)] py-[4px] shadow-[2px_2px_12px_2px_rgba(0,0,0,0.1)] data-[enter]:animate-floating-in-bottom data-[leave]:animate-floating-out-bottom",
5515
+ className: "z-50 overflow-auto rounded-[var(--cmp-listBox-radius)] bg-[var(--cmp-listBox-bg)] shadow-[2px_2px_12px_2px_rgba(0,0,0,0.1)] data-[enter]:animate-floating-in-bottom data-[leave]:animate-floating-out-bottom",
5484
5516
  style: {
5485
5517
  maxHeight: dropdownHeight,
5486
5518
  ...dropdownWidth ? { width: dropdownWidth } : {},
@@ -5521,7 +5553,7 @@ var SSelect = forwardRef(function SSelect2({
5521
5553
  ),
5522
5554
  hasItems ? /* @__PURE__ */ jsx(ItemList, { items: filtered, multi, selected, useSearch: showSearch }) : (
5523
5555
  // 원본 sd-select-listbox__empty (표시할 항목이 없을 때)
5524
- /* @__PURE__ */ jsx("div", { className: "px-[12px] py-[12px] text-center text-[12px] leading-[20px] text-[color:var(--cmp-listItem-content-disabled)]", children: "\uD45C\uC2DC\uD560 \uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4." })
5556
+ /* @__PURE__ */ jsx("div", { className: "px-[12px] py-[12px] text-left text-[12px] leading-[20px] text-[color:var(--cmp-listItem-content-disabled)]", children: "\uD45C\uC2DC\uD560 \uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4." })
5525
5557
  )
5526
5558
  ]
5527
5559
  }
@@ -5544,7 +5576,7 @@ var SSelect = forwardRef(function SSelect2({
5544
5576
  error: error || ruleError !== "",
5545
5577
  status: rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0,
5546
5578
  errorMessage: ruleError !== "" ? ruleError : errorMessage,
5547
- disabled,
5579
+ disabled: effectiveDisabled,
5548
5580
  width,
5549
5581
  className,
5550
5582
  style,
@@ -5579,7 +5611,11 @@ function ItemList({
5579
5611
  {
5580
5612
  className: cn(
5581
5613
  "select-none py-[4px] pr-[12px] text-[12px] leading-[20px] text-[color:var(--cmp-listItem-content-default)]",
5582
- isDepth1 ? "border-t border-solid border-[color:var(--cmp-listItem-depth1-border-color)] bg-[var(--cmp-listItem-depth1-bg-default)] font-bold" : "bg-[var(--cmp-listItem-depth2-middle-bg)] font-medium"
5614
+ isDepth1 ? "border-t border-solid border-[color:var(--cmp-listItem-depth1-border-color)] bg-[var(--cmp-listItem-depth1-bg-default)] font-bold" : "bg-[var(--cmp-listItem-depth2-middle-bg)] font-medium",
5615
+ // 하위가 전부 비활성이면(select.config 에서 bubble-up) 어미 그룹도 비활성 처리:
5616
+ // 텍스트는 회색(#888), depth1 그룹은 파란 배경 대신 회색(#EEE)으로 (depth2 는 #F6F6F6 유지)
5617
+ o.disabled && "text-[color:var(--cmp-listItem-content-disabled)]",
5618
+ o.disabled && isDepth1 && "bg-[var(--cmp-listItem-depth1-bg-disabled)]"
5583
5619
  ),
5584
5620
  style: { paddingLeft: padLeft },
5585
5621
  children: o.label
@@ -5606,15 +5642,21 @@ function ItemList({
5606
5642
  "span",
5607
5643
  {
5608
5644
  className: cn(
5609
- "flex h-[16px] w-[16px] flex-shrink-0 items-center justify-center rounded-[2px] border border-solid group-data-[active-item]:border-[color:var(--cmp-checkbox-checked-border-inverse)]",
5610
- isSelected ? "border-[color:var(--cmp-checkbox-checked-bg-default)] bg-[var(--cmp-checkbox-checked-bg-default)] group-data-[active-item]:bg-transparent" : "border-[color:var(--cmp-checkbox-unchecked-border-default)] bg-transparent"
5645
+ "flex h-[16px] w-[16px] flex-shrink-0 items-center justify-center rounded-[2px] border border-solid",
5646
+ o.disabled ? (
5647
+ // 비활성: 회색 채움(#E1E1E1) + 회색 테두리(#CCCCCC)
5648
+ "border-[color:var(--cmp-checkbox-border-disabled)] bg-[var(--cmp-checkbox-bg-disabled)]"
5649
+ ) : cn(
5650
+ "group-data-[active-item]:border-[color:var(--cmp-checkbox-checked-border-inverse)]",
5651
+ isSelected ? "border-[color:var(--cmp-checkbox-checked-bg-default)] bg-[var(--cmp-checkbox-checked-bg-default)] group-data-[active-item]:bg-transparent" : "border-[color:var(--cmp-checkbox-unchecked-border-default)] bg-transparent"
5652
+ )
5611
5653
  ),
5612
5654
  children: isSelected && /* @__PURE__ */ jsx(
5613
5655
  SIcon,
5614
5656
  {
5615
5657
  name: "checkboxCheck",
5616
5658
  size: 12,
5617
- color: "var(--cmp-checkbox-checked-icon-default)"
5659
+ color: o.disabled ? "var(--cmp-checkbox-checked-icon-disabled)" : "var(--cmp-checkbox-checked-icon-default)"
5618
5660
  }
5619
5661
  )
5620
5662
  }
@@ -6393,8 +6435,8 @@ var STextarea = forwardRef(function STextarea2({
6393
6435
  );
6394
6436
  });
6395
6437
  var PAD2 = {
6396
- sm: { fontSize: 12, stepper: 20, icon: 12 },
6397
- md: { fontSize: 14, stepper: 24, icon: 14 }
6438
+ sm: { fontSize: 12, lineHeight: 20, stepper: 20, icon: 12 },
6439
+ md: { fontSize: 14, lineHeight: 24, stepper: 24, icon: 14 }
6398
6440
  };
6399
6441
  var toNumber = (val) => {
6400
6442
  if (val === null || val === void 0 || val === "") return null;
@@ -6412,6 +6454,38 @@ var formatWithCommas = (value) => {
6412
6454
  const result = isNeg ? "-" + formatted : formatted;
6413
6455
  return decPart !== void 0 && decPart !== "" ? result + "." + decPart : result;
6414
6456
  };
6457
+ var addCommas = (value) => value.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
6458
+ var formatInputWithCommas = (value) => {
6459
+ const isNeg = value.startsWith("-");
6460
+ const unsigned = isNeg ? value.slice(1) : value;
6461
+ const hasDecimal = unsigned.includes(".");
6462
+ const [intPart = "", decPart = ""] = unsigned.split(".");
6463
+ const formattedInt = addCommas(intPart === "" ? "0" : intPart);
6464
+ return `${isNeg ? "-" : ""}${formattedInt}${hasDecimal ? `.${decPart}` : ""}`;
6465
+ };
6466
+ var getDecimalLimit = (useDecimal, maxDecimalLength) => {
6467
+ if (!useDecimal || maxDecimalLength === void 0 || !Number.isFinite(maxDecimalLength)) {
6468
+ return void 0;
6469
+ }
6470
+ return Math.max(0, Math.floor(maxDecimalLength));
6471
+ };
6472
+ var applyDecimalLimit = (value, decimalLimit) => {
6473
+ if (value === null || decimalLimit === void 0) return value;
6474
+ return Number(value.toFixed(decimalLimit));
6475
+ };
6476
+ var getLogicalCaret = (value, caret) => {
6477
+ return value.slice(0, caret ?? value.length).replace(/,/g, "").length;
6478
+ };
6479
+ var getDisplayCaret = (value, logicalCaret) => {
6480
+ if (logicalCaret <= 0) return 0;
6481
+ let seen = 0;
6482
+ for (let i = 0; i < value.length; i += 1) {
6483
+ if (value[i] === ",") continue;
6484
+ seen += 1;
6485
+ if (seen >= logicalCaret) return i + 1;
6486
+ }
6487
+ return value.length;
6488
+ };
6415
6489
  var SNumberInput = forwardRef(function SNumberInput2({
6416
6490
  value,
6417
6491
  onValueChange,
@@ -6421,6 +6495,7 @@ var SNumberInput = forwardRef(function SNumberInput2({
6421
6495
  step = 1,
6422
6496
  useButton = false,
6423
6497
  useDecimal = false,
6498
+ maxDecimalLength,
6424
6499
  inputPrefix = "",
6425
6500
  inputSuffix = "",
6426
6501
  inputClass,
@@ -6452,7 +6527,8 @@ var SNumberInput = forwardRef(function SNumberInput2({
6452
6527
  }, ref) {
6453
6528
  const p = PAD2[size];
6454
6529
  const padX = `var(--cmp-numberInput-${size}-paddingX)`;
6455
- const numValue = toNumber(value);
6530
+ const decimalLimit = getDecimalLimit(useDecimal, maxDecimalLength);
6531
+ const numValue = applyDecimalLimit(toNumber(value), decimalLimit);
6456
6532
  const [display, setDisplay] = useState(() => formatWithCommas(numValue));
6457
6533
  const [ruleError, setRuleError] = useState("");
6458
6534
  const innerRef = useRef(null);
@@ -6462,8 +6538,9 @@ var SNumberInput = forwardRef(function SNumberInput2({
6462
6538
  else if (ref) ref.current = el;
6463
6539
  };
6464
6540
  useEffect(() => {
6465
- setDisplay(formatWithCommas(toNumber(value)));
6466
- }, [value]);
6541
+ if (document.activeElement === innerRef.current) return;
6542
+ setDisplay(formatWithCommas(applyDecimalLimit(toNumber(value), decimalLimit)));
6543
+ }, [decimalLimit, value]);
6467
6544
  useFormField({
6468
6545
  name,
6469
6546
  validate: () => {
@@ -6475,48 +6552,87 @@ var SNumberInput = forwardRef(function SNumberInput2({
6475
6552
  });
6476
6553
  const resolvedError = error || ruleError !== "";
6477
6554
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
6478
- const emit2 = (n) => {
6479
- setDisplay(formatWithCommas(n));
6480
- onValueChange?.(n);
6555
+ const restoreCaret = (nextDisplay, logicalCaret) => {
6556
+ const input = innerRef.current;
6557
+ if (logicalCaret === void 0 || !input || document.activeElement !== input) return;
6558
+ const nextCaret = getDisplayCaret(nextDisplay, logicalCaret);
6559
+ requestAnimationFrame(() => {
6560
+ if (document.activeElement !== input) return;
6561
+ input.setSelectionRange(nextCaret, nextCaret);
6562
+ });
6563
+ };
6564
+ const setDisplayWithCaret = (nextDisplay, logicalCaret) => {
6565
+ setDisplay(nextDisplay);
6566
+ restoreCaret(nextDisplay, logicalCaret);
6567
+ };
6568
+ const resetRejectedInput = (target, logicalCaret) => {
6569
+ target.value = display;
6570
+ restoreCaret(display, Math.min(logicalCaret, display.replace(/,/g, "").length));
6571
+ };
6572
+ const emit2 = (n, logicalCaret) => {
6573
+ const next = applyDecimalLimit(n, decimalLimit);
6574
+ const nextDisplay = formatWithCommas(next);
6575
+ setDisplayWithCaret(nextDisplay, logicalCaret);
6576
+ onValueChange?.(next);
6481
6577
  };
6482
6578
  const incDisabled = disabled || readOnly || numValue !== null && numValue >= max;
6483
6579
  const decDisabled = disabled || readOnly || numValue !== null && numValue <= min;
6484
6580
  const increment = () => {
6485
6581
  if (incDisabled) return;
6486
6582
  const cur = numValue ?? (min === Number.NEGATIVE_INFINITY ? 0 : min);
6487
- const next = Math.min(cur + step, max);
6583
+ const next = applyDecimalLimit(Math.min(cur + step, max), decimalLimit);
6488
6584
  if (next !== cur) emit2(next);
6489
6585
  };
6490
6586
  const decrement = () => {
6491
6587
  if (decDisabled) return;
6492
6588
  const cur = numValue ?? (min === Number.NEGATIVE_INFINITY ? 0 : min);
6493
- const next = Math.max(cur - step, min);
6589
+ const next = applyDecimalLimit(Math.max(cur - step, min), decimalLimit);
6494
6590
  if (next !== cur) emit2(next);
6495
6591
  };
6496
- const handleInput = (raw) => {
6592
+ const handleInput = (event) => {
6593
+ const target = event.currentTarget;
6594
+ const raw = target.value;
6595
+ const logicalCaret = getLogicalCaret(raw, target.selectionStart);
6497
6596
  if (raw === "") {
6498
- setDisplay("");
6597
+ setDisplayWithCaret("", 0);
6499
6598
  onValueChange?.(null);
6500
6599
  return;
6501
6600
  }
6502
6601
  const cleaned = raw.replace(/,/g, "");
6503
6602
  const decimals = (cleaned.match(/\./g) || []).length;
6504
- if (decimals > 1) return;
6603
+ if (decimals > 1) {
6604
+ resetRejectedInput(target, logicalCaret);
6605
+ return;
6606
+ }
6505
6607
  if (cleaned === "-" || cleaned === "." || cleaned === "-.") {
6506
- setDisplay(cleaned);
6608
+ setDisplayWithCaret(cleaned, logicalCaret);
6609
+ return;
6610
+ }
6611
+ if (!useDecimal && cleaned.includes(".")) {
6612
+ resetRejectedInput(target, logicalCaret);
6507
6613
  return;
6508
6614
  }
6509
- if (!useDecimal && cleaned.includes(".")) return;
6615
+ if (decimalLimit !== void 0 && cleaned.includes(".")) {
6616
+ const fraction = cleaned.split(".")[1] ?? "";
6617
+ if (fraction.length > decimalLimit) {
6618
+ resetRejectedInput(target, logicalCaret);
6619
+ return;
6620
+ }
6621
+ }
6510
6622
  if (cleaned.endsWith(".") && decimals === 1) {
6511
6623
  const parsed2 = toNumber(cleaned.slice(0, -1));
6512
6624
  if (parsed2 !== null) {
6513
- setDisplay(formatWithCommas(parsed2) + ".");
6625
+ setDisplayWithCaret(formatInputWithCommas(cleaned), logicalCaret);
6514
6626
  return;
6515
6627
  }
6516
6628
  }
6517
6629
  const parsed = toNumber(cleaned);
6518
- if (parsed === null) return;
6519
- emit2(parsed);
6630
+ if (parsed === null) {
6631
+ resetRejectedInput(target, logicalCaret);
6632
+ return;
6633
+ }
6634
+ setDisplayWithCaret(formatInputWithCommas(cleaned), logicalCaret);
6635
+ onValueChange?.(applyDecimalLimit(parsed, decimalLimit));
6520
6636
  };
6521
6637
  const stepper = (dir) => {
6522
6638
  const off = dir === "inc" ? incDisabled : decDisabled;
@@ -6529,8 +6645,8 @@ var SNumberInput = forwardRef(function SNumberInput2({
6529
6645
  "aria-label": dir === "inc" ? "\uC99D\uAC00" : "\uAC10\uC18C",
6530
6646
  onClick: dir === "inc" ? increment : decrement,
6531
6647
  className: cn(
6532
- "flex flex-shrink-0 items-center justify-center",
6533
- off ? "cursor-not-allowed" : "cursor-pointer"
6648
+ "flex flex-shrink-0 items-center justify-center border border-solid border-transparent transition-colors",
6649
+ off ? "cursor-not-allowed" : "cursor-pointer hover:border-[var(--color-border-accentLight)]"
6534
6650
  ),
6535
6651
  style: {
6536
6652
  width: `var(--cmp-numberInput-stepper-${size}-size)`,
@@ -6579,24 +6695,26 @@ var SNumberInput = forwardRef(function SNumberInput2({
6579
6695
  style: {
6580
6696
  // 원본 sd-number-input: content gap = padding-x 토큰 (gap 토큰 아님)
6581
6697
  gap: `var(--cmp-numberInput-${size}-paddingX)`,
6582
- padding: `0 ${useButton ? padX : `calc(${padX} * 2)`}`
6698
+ padding: `0 ${useButton ? padX : `calc(${padX} * 2)`}`,
6699
+ fontSize: p.fontSize,
6700
+ lineHeight: `${p.lineHeight}px`
6583
6701
  },
6584
6702
  children: [
6585
6703
  useButton && stepper("dec"),
6586
- inputPrefix !== "" && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", style: { fontSize: p.fontSize, color: affixColor }, children: inputPrefix }),
6704
+ inputPrefix !== "" && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", style: { color: affixColor }, children: inputPrefix }),
6587
6705
  /* @__PURE__ */ jsx(
6588
6706
  "input",
6589
6707
  {
6590
6708
  ref: setRefs,
6591
6709
  name,
6592
6710
  type: "text",
6593
- inputMode: "numeric",
6711
+ inputMode: useDecimal ? "decimal" : "numeric",
6594
6712
  value: display,
6595
6713
  placeholder,
6596
6714
  disabled,
6597
6715
  readOnly,
6598
6716
  autoFocus,
6599
- onChange: (e) => handleInput(e.target.value),
6717
+ onChange: handleInput,
6600
6718
  onKeyDown: (e) => {
6601
6719
  if (e.key === "ArrowUp") {
6602
6720
  e.preventDefault();
@@ -6608,26 +6726,29 @@ var SNumberInput = forwardRef(function SNumberInput2({
6608
6726
  },
6609
6727
  onFocus: (e) => onFocus?.(e),
6610
6728
  onBlur: (e) => {
6611
- const n = toNumber(display);
6729
+ const cleaned = display.replace(/,/g, "");
6730
+ const n = toNumber(cleaned);
6612
6731
  const clamped = n === null ? null : Math.min(Math.max(n, min), max);
6613
6732
  if (clamped !== n) emit2(clamped);
6614
- else setDisplay(formatWithCommas(n));
6733
+ else setDisplay(n === null ? "" : formatInputWithCommas(cleaned));
6615
6734
  if (rules && rules.length > 0) setRuleError(runRules(clamped, rules));
6616
6735
  onBlur?.(e);
6617
6736
  },
6618
6737
  className: cn(
6619
- "h-full min-w-0 flex-1 border-0 bg-transparent p-0 outline-none placeholder:text-[color:var(--cmp-numberInput-text-placeholder)] disabled:cursor-not-allowed",
6738
+ // h-full 대신 라인박스 높이 그대로 두어 prefix/suffix 동일하게 flex 로 수직 센터링
6739
+ // (h-full 이면 input 내부 텍스트 센터링을 브라우저가 수행해 1px 어긋날 수 있음)
6740
+ "min-w-0 flex-1 border-0 bg-transparent p-0 outline-none placeholder:text-[color:var(--cmp-numberInput-text-placeholder)] disabled:cursor-not-allowed",
6620
6741
  inputClass
6621
6742
  ),
6622
6743
  style: {
6623
- fontSize: p.fontSize,
6744
+ // fontSize/lineHeight 는 컨테이너에서 상속
6624
6745
  textAlign: useButton ? "center" : "right",
6625
6746
  color: disabled ? "var(--cmp-numberInput-text-disabled)" : "var(--cmp-numberInput-text-default)",
6626
6747
  ...inputStyle
6627
6748
  }
6628
6749
  }
6629
6750
  ),
6630
- inputSuffix !== "" && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", style: { fontSize: p.fontSize, color: affixColor }, children: inputSuffix }),
6751
+ inputSuffix !== "" && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", style: { color: affixColor }, children: inputSuffix }),
6631
6752
  useButton && stepper("inc")
6632
6753
  ]
6633
6754
  }
@@ -6953,7 +7074,7 @@ function SCalendar({
6953
7074
  "span",
6954
7075
  {
6955
7076
  className: cn(
6956
- "flex h-[var(--cmp-datepicker-calendar-day-circle-size)] w-[var(--cmp-datepicker-calendar-day-circle-size)] items-center justify-center rounded-[var(--cmp-datepicker-calendar-day-circle-radius)] border border-solid border-transparent text-[14px]",
7077
+ "flex h-[var(--cmp-datepicker-calendar-day-circle-size)] w-[var(--cmp-datepicker-calendar-day-circle-size)] items-center justify-center rounded-[var(--cmp-datepicker-calendar-day-circle-radius)] border border-solid border-transparent text-[14px] leading-[var(--cmp-datepicker-calendar-day-circle-size)]",
6957
7078
  selected ? "bg-[var(--cmp-datepicker-calendar-day-select-bg)] text-[color:var(--cmp-datepicker-calendar-day-select-text)]" : disabled ? "text-[color:var(--cmp-datepicker-calendar-day-disabled-text)]" : "text-[color:var(--cmp-datepicker-calendar-day-default-text)] hover:border-[color:var(--cmp-datepicker-calendar-day-hover-border)]",
6958
7079
  isToday && !disabled && "font-bold"
6959
7080
  ),
@@ -7143,6 +7264,7 @@ function RangeCalendar({
7143
7264
  selectable,
7144
7265
  maxRange,
7145
7266
  onSelect,
7267
+ onPendingStartChange,
7146
7268
  onViewChange
7147
7269
  }) {
7148
7270
  const today = todayStr();
@@ -7205,9 +7327,11 @@ function RangeCalendar({
7205
7327
  setStart(d);
7206
7328
  setEnd(null);
7207
7329
  setHover(null);
7330
+ onPendingStartChange?.(d);
7208
7331
  return;
7209
7332
  }
7210
7333
  setEnd(d);
7334
+ onPendingStartChange?.(null);
7211
7335
  onSelect([start, d]);
7212
7336
  };
7213
7337
  const GRID_COLS = "grid grid-cols-[repeat(7,var(--cmp-datepicker-calendar-day-width))]";
@@ -7342,8 +7466,11 @@ function SDateRangePicker({
7342
7466
  const portalContainer = usePortalContainer();
7343
7467
  const [open, setOpen] = useState(false);
7344
7468
  const [ruleError, setRuleError] = useState("");
7469
+ const [pendingStart, setPendingStart] = useState(null);
7345
7470
  const hasValue = value != null && value[0] !== "" && value[1] !== "";
7346
- const display = hasValue ? `${value[0]} ~ ${value[1]}` : placeholder;
7471
+ const hasDisplay = pendingStart != null || hasValue;
7472
+ const startText = pendingStart ?? (hasValue ? value[0] : "");
7473
+ const endText = pendingStart ? "" : hasValue ? value[1] : "";
7347
7474
  useFormField({
7348
7475
  name,
7349
7476
  validate: () => {
@@ -7357,6 +7484,7 @@ function SDateRangePicker({
7357
7484
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
7358
7485
  const dims = size === "md" ? { padX: 16, gap: 12, icon: 20, minW: 104, fontSize: 14, lineHeight: 24, radius: 6 } : { padX: 12, gap: 8, icon: 16, minW: 80, fontSize: 12, lineHeight: 20, radius: 4 };
7359
7486
  const select = (r) => {
7487
+ setPendingStart(null);
7360
7488
  onValueChange?.(r);
7361
7489
  if (rules && rules.length > 0) setRuleError(runRules(r, rules));
7362
7490
  setOpen(false);
@@ -7381,61 +7509,80 @@ function SDateRangePicker({
7381
7509
  disabled,
7382
7510
  className,
7383
7511
  style,
7384
- children: /* @__PURE__ */ jsxs(RPopover2.Root, { open, onOpenChange: (o) => !disabled && setOpen(o), children: [
7385
- /* @__PURE__ */ jsx(RPopover2.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
7386
- "button",
7387
- {
7388
- type: "button",
7389
- name,
7390
- disabled,
7391
- className: "flex h-full w-full items-center overflow-hidden bg-transparent outline-none disabled:cursor-not-allowed",
7392
- style: { padding: `0 ${dims.padX}px`, gap: dims.gap, borderRadius: dims.radius },
7393
- children: [
7394
- /* @__PURE__ */ jsx(
7395
- SIcon,
7396
- {
7397
- name: "date",
7398
- size: dims.icon,
7399
- color: disabled ? "var(--cmp-datepicker-icon-disabled)" : "var(--cmp-datepicker-icon-default)",
7400
- className: "flex-shrink-0"
7401
- }
7402
- ),
7403
- /* @__PURE__ */ jsx(
7404
- "span",
7405
- {
7406
- className: "flex-1 truncate text-center",
7407
- style: {
7408
- minWidth: dims.minW,
7409
- fontSize: dims.fontSize,
7410
- lineHeight: `${dims.lineHeight}px`,
7411
- color: disabled ? "var(--cmp-datepicker-text-disabled)" : hasValue ? "var(--cmp-datepicker-text-default)" : "var(--cmp-field-hint-color)"
7412
- },
7413
- children: display
7414
- }
7415
- )
7416
- ]
7417
- }
7418
- ) }),
7419
- /* @__PURE__ */ jsx(RPopover2.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
7420
- RPopover2.Content,
7421
- {
7422
- side: "bottom",
7423
- align: "start",
7424
- sideOffset: 4,
7425
- className: cn("z-50", FLOATING_SLIDE_ANIM),
7426
- children: /* @__PURE__ */ jsx(
7427
- RangeCalendar,
7512
+ children: /* @__PURE__ */ jsxs(
7513
+ RPopover2.Root,
7514
+ {
7515
+ open,
7516
+ onOpenChange: (o) => {
7517
+ if (disabled) return;
7518
+ setOpen(o);
7519
+ if (!o) setPendingStart(null);
7520
+ },
7521
+ children: [
7522
+ /* @__PURE__ */ jsx(RPopover2.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
7523
+ "button",
7428
7524
  {
7429
- value: value ?? null,
7430
- selectable,
7431
- maxRange,
7432
- onSelect: select,
7433
- onViewChange
7525
+ type: "button",
7526
+ name,
7527
+ disabled,
7528
+ className: "flex h-full w-full items-center overflow-hidden bg-transparent outline-none disabled:cursor-not-allowed",
7529
+ style: { padding: `0 ${dims.padX}px`, gap: dims.gap, borderRadius: dims.radius },
7530
+ children: [
7531
+ /* @__PURE__ */ jsx(
7532
+ SIcon,
7533
+ {
7534
+ name: "date",
7535
+ size: dims.icon,
7536
+ color: disabled ? "var(--cmp-datepicker-icon-disabled)" : "var(--cmp-datepicker-icon-default)",
7537
+ className: "flex-shrink-0"
7538
+ }
7539
+ ),
7540
+ /* @__PURE__ */ jsx(
7541
+ "span",
7542
+ {
7543
+ className: cn(
7544
+ "flex-1 items-center",
7545
+ hasDisplay ? "flex" : "block truncate text-center"
7546
+ ),
7547
+ style: {
7548
+ minWidth: dims.minW,
7549
+ fontSize: dims.fontSize,
7550
+ lineHeight: `${dims.lineHeight}px`,
7551
+ color: disabled ? "var(--cmp-datepicker-text-disabled)" : hasDisplay ? "var(--cmp-datepicker-text-default)" : "var(--cmp-field-hint-color)"
7552
+ },
7553
+ children: hasDisplay ? /* @__PURE__ */ jsxs(Fragment, { children: [
7554
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-right", children: startText }),
7555
+ /* @__PURE__ */ jsx("span", { className: "px-[4px]", children: "~" }),
7556
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-left", children: endText })
7557
+ ] }) : placeholder
7558
+ }
7559
+ )
7560
+ ]
7434
7561
  }
7435
- )
7436
- }
7437
- ) })
7438
- ] })
7562
+ ) }),
7563
+ /* @__PURE__ */ jsx(RPopover2.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
7564
+ RPopover2.Content,
7565
+ {
7566
+ side: "bottom",
7567
+ align: "start",
7568
+ sideOffset: 4,
7569
+ className: cn("z-50", FLOATING_SLIDE_ANIM),
7570
+ children: /* @__PURE__ */ jsx(
7571
+ RangeCalendar,
7572
+ {
7573
+ value: value ?? null,
7574
+ selectable,
7575
+ maxRange,
7576
+ onSelect: select,
7577
+ onPendingStartChange: setPendingStart,
7578
+ onViewChange
7579
+ }
7580
+ )
7581
+ }
7582
+ ) })
7583
+ ]
7584
+ }
7585
+ )
7439
7586
  }
7440
7587
  );
7441
7588
  }
@@ -7444,7 +7591,7 @@ var SChip = forwardRef(function SChip2({
7444
7591
  value = "",
7445
7592
  error: errorProp = false,
7446
7593
  disabled = false,
7447
- editable = true,
7594
+ editable = false,
7448
7595
  showRemove = true,
7449
7596
  placeholder = "",
7450
7597
  rules,
@@ -7597,6 +7744,7 @@ function SFilePicker({
7597
7744
  hovered = false,
7598
7745
  inline = false,
7599
7746
  multiple = false,
7747
+ useMultipleListBox = false,
7600
7748
  accept,
7601
7749
  maxFileSize,
7602
7750
  maxTotalSize,
@@ -7624,8 +7772,8 @@ function SFilePicker({
7624
7772
  const inputRef = useRef(null);
7625
7773
  const [ruleError, setRuleError] = useState("");
7626
7774
  const files = multiple ? Array.isArray(value) ? value : [] : value && !Array.isArray(value) ? value : null;
7627
- const hasSingle = !multiple && !!files;
7628
- const displayText = hasSingle ? files.name : placeholder;
7775
+ const hasFiles = multiple ? files.length > 0 : !!files;
7776
+ const displayText = !hasFiles ? placeholder : multiple ? files.map((f) => f.name).join(", ") : files.name;
7629
7777
  useFormField({
7630
7778
  name,
7631
7779
  validate: () => {
@@ -7689,78 +7837,88 @@ function SFilePicker({
7689
7837
  const padX = size === "md" ? "var(--cmp-filepicker-md-paddingX)" : "var(--cmp-filepicker-sm-paddingX)";
7690
7838
  const iconSize = size === "md" ? 20 : 16;
7691
7839
  const gapCls = size === "md" ? "gap-[var(--cmp-filepicker-md-gap)]" : "gap-[var(--cmp-filepicker-sm-gap)]";
7692
- const content = /* @__PURE__ */ jsxs("div", { className: cn("flex h-full w-full items-center", gapCls), style: { padding: `0 ${padX}` }, children: [
7693
- /* @__PURE__ */ jsx(
7694
- "input",
7695
- {
7696
- ref: inputRef,
7697
- type: "file",
7698
- className: "hidden",
7699
- disabled,
7700
- multiple,
7701
- accept,
7702
- name: resolvedName,
7703
- onChange,
7704
- "aria-label": placeholder
7705
- }
7706
- ),
7707
- /* @__PURE__ */ jsxs(
7708
- "button",
7709
- {
7710
- type: "button",
7711
- disabled,
7712
- onClick: open,
7713
- "aria-label": placeholder,
7714
- className: cn(
7715
- "flex min-w-0 flex-1 items-center bg-transparent text-left",
7716
- gapCls,
7717
- disabled ? "cursor-not-allowed" : "cursor-pointer"
7840
+ const inlinePlaceholder = inline && !disabled && !hasFiles;
7841
+ const content = /* @__PURE__ */ jsxs(
7842
+ "div",
7843
+ {
7844
+ className: cn("group/filepicker flex h-full w-full items-center", gapCls),
7845
+ style: { padding: inline ? 0 : `0 ${padX}` },
7846
+ children: [
7847
+ /* @__PURE__ */ jsx(
7848
+ "input",
7849
+ {
7850
+ ref: inputRef,
7851
+ type: "file",
7852
+ className: "hidden",
7853
+ disabled,
7854
+ multiple,
7855
+ accept,
7856
+ name: resolvedName,
7857
+ onChange,
7858
+ "aria-label": placeholder
7859
+ }
7718
7860
  ),
7719
- children: [
7720
- /* @__PURE__ */ jsx(
7721
- SIcon,
7722
- {
7723
- name: "attachFile",
7724
- size: iconSize,
7725
- color: disabled ? "var(--cmp-filepicker-icon-disabled)" : "var(--color-grey-65)"
7726
- }
7727
- ),
7728
- /* @__PURE__ */ jsx(
7729
- "span",
7730
- {
7731
- className: "min-w-0 flex-1 truncate text-[12px]",
7732
- style: {
7733
- color: disabled ? "var(--cmp-filepicker-text-disabled)" : hasSingle ? "var(--cmp-filepicker-text-default)" : "var(--cmp-filepicker-text-placeholder)"
7734
- },
7735
- children: displayText
7736
- }
7737
- )
7738
- ]
7739
- }
7740
- ),
7741
- !disabled && hasSingle && /* @__PURE__ */ jsx(SGhostButton, { icon: "close", size: "xxs", ariaLabel: "clear", onClick: clear })
7742
- ] });
7743
- const chips = multiple && files.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-[8px] flex flex-wrap gap-[8px]", children: files.map((f, i) => /* @__PURE__ */ jsx(SChip, { value: f.name, editable: false, onRemove: () => removeChip(i) }, i)) });
7744
- if (inline) {
7745
- return /* @__PURE__ */ jsxs("div", { className: cn("inline-flex flex-col", className), style, children: [
7746
- /* @__PURE__ */ jsx(
7747
- "div",
7748
- {
7749
- className: "box-border flex items-center rounded-[var(--cmp-filepicker-sm-radius)] border border-solid border-[color:var(--cmp-filepicker-border-default)] bg-[var(--cmp-filepicker-bg-default)]",
7750
- style: {
7751
- height: "var(--cmp-filepicker-sm-height)",
7752
- width: typeof width === "number" ? `${width}px` : width
7753
- },
7754
- children: content
7755
- }
7861
+ /* @__PURE__ */ jsxs(
7862
+ "button",
7863
+ {
7864
+ type: "button",
7865
+ disabled,
7866
+ onClick: open,
7867
+ "aria-label": placeholder,
7868
+ className: cn(
7869
+ "flex min-w-0 flex-1 items-center bg-transparent text-left",
7870
+ gapCls,
7871
+ disabled ? "cursor-not-allowed" : "cursor-pointer"
7872
+ ),
7873
+ children: [
7874
+ /* @__PURE__ */ jsx(
7875
+ SIcon,
7876
+ {
7877
+ name: "attachFile",
7878
+ size: iconSize,
7879
+ color: disabled ? "var(--cmp-filepicker-icon-disabled)" : "var(--color-grey-65)"
7880
+ }
7881
+ ),
7882
+ /* @__PURE__ */ jsx(
7883
+ "span",
7884
+ {
7885
+ className: cn(
7886
+ "min-w-0 flex-1 truncate text-[12px]",
7887
+ inlinePlaceholder && "text-[color:var(--cmp-filepicker-text-placeholder)] transition-colors group-hover/filepicker:text-[color:var(--cmp-filepicker-text-default)]"
7888
+ ),
7889
+ style: inlinePlaceholder ? void 0 : {
7890
+ color: disabled ? "var(--cmp-filepicker-text-disabled)" : hasFiles ? "var(--cmp-filepicker-text-default)" : "var(--cmp-filepicker-text-placeholder)"
7891
+ },
7892
+ children: displayText
7893
+ }
7894
+ )
7895
+ ]
7896
+ }
7897
+ ),
7898
+ !disabled && hasFiles && /* @__PURE__ */ jsx(SGhostButton, { icon: "close", size: "xxs", ariaLabel: "clear", onClick: clear })
7899
+ ]
7900
+ }
7901
+ );
7902
+ const chips = multiple && files.length > 0 && /* @__PURE__ */ jsx(
7903
+ "div",
7904
+ {
7905
+ className: cn(
7906
+ "mt-[8px] flex gap-[8px]",
7907
+ useMultipleListBox ? "box-border flex-col items-start rounded-[var(--cmp-listBox-radius)] bg-[var(--cmp-listBox-bg)] p-[8px] shadow-[2px_2px_12px_2px_rgba(0,0,0,0.1)]" : "flex-wrap"
7756
7908
  ),
7757
- chips
7758
- ] });
7759
- }
7909
+ style: useMultipleListBox ? {
7910
+ width: typeof width === "number" ? `${width}px` : width,
7911
+ // label 이 있으면 SField 입력 박스 시작 위치(labelWidth + fieldGap)에 맞춰 정렬
7912
+ marginLeft: label && labelWidth != null ? `calc(${typeof labelWidth === "number" ? `${labelWidth}px` : labelWidth} + var(--sys-space-field-${size}-gap))` : void 0
7913
+ } : void 0,
7914
+ children: files.map((f, i) => /* @__PURE__ */ jsx(SChip, { value: f.name, editable: false, onRemove: () => removeChip(i) }, i))
7915
+ }
7916
+ );
7760
7917
  return /* @__PURE__ */ jsxs("div", { className, style, children: [
7761
7918
  /* @__PURE__ */ jsx(
7762
7919
  SField,
7763
7920
  {
7921
+ borderless: inline,
7764
7922
  label,
7765
7923
  labelWidth,
7766
7924
  icon,
@@ -7788,6 +7946,7 @@ function SKeyValueTable({
7788
7946
  fields = [],
7789
7947
  search = false,
7790
7948
  radius = "default",
7949
+ dense = false,
7791
7950
  onChange,
7792
7951
  onSearch,
7793
7952
  className,
@@ -7795,6 +7954,8 @@ function SKeyValueTable({
7795
7954
  }) {
7796
7955
  if (fields.length === 0) return null;
7797
7956
  const emit2 = (name, value) => onChange?.({ name, value });
7957
+ const cellHeight = dense ? "var(--cmp-table-body-dense-height)" : "var(--cmp-table-keyValue-height)";
7958
+ const cellPadY = dense ? "var(--cmp-table-body-dense-paddingY)" : "var(--cmp-table-keyValue-body-paddingY)";
7798
7959
  const renderField = (f) => {
7799
7960
  if (f.render) return f.render;
7800
7961
  const opt = f.options ?? {};
@@ -7875,10 +8036,15 @@ function SKeyValueTable({
7875
8036
  rowSpan: f.thRowSpan && f.thRowSpan > 1 ? f.thRowSpan : void 0,
7876
8037
  colSpan: f.thColSpan && f.thColSpan > 1 ? f.thColSpan : void 0,
7877
8038
  className: cn(
7878
- "h-[var(--cmp-table-keyValue-height)] box-border bg-[var(--cmp-table-header-bg)] px-[var(--cmp-table-header-paddingX)] py-[var(--cmp-table-keyValue-body-paddingY)] text-left align-middle",
8039
+ "box-border bg-[var(--cmp-table-header-bg)] px-[var(--cmp-table-header-paddingX)] text-left align-middle",
7879
8040
  cellBorder,
7880
8041
  f.thClass
7881
8042
  ),
8043
+ style: {
8044
+ height: cellHeight,
8045
+ paddingTop: cellPadY,
8046
+ paddingBottom: cellPadY
8047
+ },
7882
8048
  children: /* @__PURE__ */ jsxs("div", { className: "flex h-full w-full items-center justify-between gap-[var(--cmp-table-header-gap)]", children: [
7883
8049
  /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-[8px]", children: [
7884
8050
  /* @__PURE__ */ jsx("span", { className: "text-[12px] font-bold leading-[20px] text-[color:var(--sys-color-fg-primary)]", children: f.label }),
@@ -7904,10 +8070,11 @@ function SKeyValueTable({
7904
8070
  rowSpan: f.tdRowSpan && f.tdRowSpan > 1 ? f.tdRowSpan : void 0,
7905
8071
  colSpan: f.tdColSpan && f.tdColSpan > 1 ? f.tdColSpan : void 0,
7906
8072
  className: cn(
7907
- "h-[var(--cmp-table-keyValue-height)] box-border bg-[var(--sys-color-bg-frame)] px-[var(--cmp-table-keyValue-body-paddingX-default)] py-[var(--cmp-table-keyValue-body-paddingY)] align-middle",
8073
+ "box-border bg-[var(--sys-color-bg-frame)] px-[var(--cmp-table-keyValue-body-paddingX-default)] align-middle",
7908
8074
  cellBorder,
7909
8075
  f.tdClass
7910
8076
  ),
8077
+ style: { height: cellHeight, paddingTop: cellPadY, paddingBottom: cellPadY },
7911
8078
  children: renderField(f)
7912
8079
  },
7913
8080
  `td-${r}-${c}`
@@ -8028,9 +8195,9 @@ var POS_ANCHOR = {
8028
8195
  "top-left": { top: 20, left: 20 },
8029
8196
  "top-center": { top: 20, left: "50%" },
8030
8197
  "top-right": { top: 20, right: 20 },
8031
- "bottom-left": { bottom: 20, left: 20 },
8032
- "bottom-center": { bottom: 20, left: "50%" },
8033
- "bottom-right": { bottom: 20, right: 20 }
8198
+ "bottom-left": { bottom: 100, left: 20 },
8199
+ "bottom-center": { bottom: 100, left: "50%" },
8200
+ "bottom-right": { bottom: 100, right: 20 }
8034
8201
  };
8035
8202
  var counter = 0;
8036
8203
  var SToastContainer = forwardRef(
@@ -8390,7 +8557,7 @@ var SChipInput = forwardRef(function SChipInput2({
8390
8557
  disabledChips = [],
8391
8558
  size = "sm",
8392
8559
  disabled = false,
8393
- placeholder = "\uC785\uB825\uD574 \uC8FC\uC138\uC694.",
8560
+ placeholder = "\uD0DC\uADF8 \uC785\uB825 (Enter\uB85C \uB4F1\uB85D / \uCF64\uB9C8\uB85C \uAD6C\uBD84 / \uB744\uC5B4\uC4F0\uAE30 \uBD88\uAC00)",
8394
8561
  name,
8395
8562
  rules,
8396
8563
  error,
@@ -8541,6 +8708,7 @@ var SChipInput = forwardRef(function SChipInput2({
8541
8708
  {
8542
8709
  label,
8543
8710
  labelWidth,
8711
+ labelHeight: `calc(var(--cmp-chipInput-${size}-minHeight) + 2px)`,
8544
8712
  icon,
8545
8713
  labelTooltip,
8546
8714
  labelTooltipProps,
@@ -8611,9 +8779,11 @@ var SChipInput = forwardRef(function SChipInput2({
8611
8779
  paddingInline: isFieldFilled ? "var(--cmp-chip-paddingX)" : void 0,
8612
8780
  borderWidth: isFieldFilled ? "var(--cmp-chip-border-width)" : void 0,
8613
8781
  borderStyle: isFieldFilled ? "solid" : void 0,
8614
- borderColor: isFieldFilled ? "transparent" : void 0,
8782
+ // 작성중 필드는 SChip의 editable 수정중(editing) 스타일과 동일하게 —
8783
+ // bg/보더/글자색 모두 focus 토큰을 사용한다.
8784
+ borderColor: isFieldFilled ? "var(--cmp-chip-border-focus)" : void 0,
8615
8785
  borderRadius: isFieldFilled ? "var(--cmp-chip-radius)" : 0,
8616
- background: isFieldFilled ? "var(--cmp-chip-bg-default)" : "transparent",
8786
+ background: isFieldFilled ? "var(--cmp-chip-bg-focus)" : "transparent",
8617
8787
  overflow: "hidden"
8618
8788
  },
8619
8789
  children: [
@@ -8622,7 +8792,7 @@ var SChipInput = forwardRef(function SChipInput2({
8622
8792
  {
8623
8793
  "aria-hidden": true,
8624
8794
  className: cn(
8625
- "invisible col-start-1 row-start-1 whitespace-pre font-medium",
8795
+ "invisible col-start-1 row-start-1 whitespace-pre font-normal",
8626
8796
  size === "md" ? "text-14 leading-24" : "text-12 leading-20"
8627
8797
  ),
8628
8798
  children: inputValue !== "" ? inputValue : values.length === 0 ? placeholder : ""
@@ -8635,12 +8805,14 @@ var SChipInput = forwardRef(function SChipInput2({
8635
8805
  name: resolvedName,
8636
8806
  size: 1,
8637
8807
  className: cn(
8638
- "s-chip-input__input col-start-1 row-start-1 w-full border-0 bg-transparent p-0 font-medium text-(--cmp-chip-content-focus) outline-none placeholder:text-(--cmp-chipInput-text-placeholder) disabled:cursor-not-allowed",
8808
+ "s-chip-input__input col-start-1 row-start-1 w-full border-0 bg-transparent p-0 font-normal text-(--cmp-chip-content-focus) outline-none placeholder:text-(--cmp-chipInput-text-placeholder) disabled:cursor-not-allowed",
8639
8809
  size === "md" ? "text-14 leading-24" : "text-12 leading-20"
8640
8810
  ),
8641
8811
  style: {
8642
8812
  minWidth: "1ch",
8643
- height: "var(--cmp-chip-height)",
8813
+ // height 지정하지 않고 line-height(20/24px)에 맞춰 자동 크기로 둔다.
8814
+ // var(--cmp-chip-height)(24px)로 고정하면 네이티브 <input>이 남는 세로 여백에
8815
+ // 텍스트를 아래로 밀어 넣어, 확정된 chip 텍스트보다 2px 낮게 보인다.
8644
8816
  margin: 0,
8645
8817
  overflow: "hidden",
8646
8818
  textOverflow: "ellipsis"
@@ -8685,7 +8857,7 @@ var SChipInput = forwardRef(function SChipInput2({
8685
8857
  showMetaInfo && /* @__PURE__ */ jsxs(
8686
8858
  "div",
8687
8859
  {
8688
- className: "s-chip-input__meta flex items-center gap-8",
8860
+ className: "s-chip-input__meta ml-auto flex items-center gap-8",
8689
8861
  onMouseDown: (e) => e.preventDefault(),
8690
8862
  children: [
8691
8863
  /* @__PURE__ */ jsx(