sellmate-design-system-react 0.1.9 → 0.1.11

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 (148) hide show
  1. package/dist/components/SActionModal/SActionModal.cjs +3 -1
  2. package/dist/components/SActionModal/SActionModal.cjs.map +1 -1
  3. package/dist/components/SActionModal/SActionModal.js +3 -1
  4. package/dist/components/SActionModal/SActionModal.js.map +1 -1
  5. package/dist/components/SBarcodeInput/SBarcodeInput.cjs +16 -3
  6. package/dist/components/SBarcodeInput/SBarcodeInput.cjs.map +1 -1
  7. package/dist/components/SBarcodeInput/SBarcodeInput.d.ts +3 -1
  8. package/dist/components/SBarcodeInput/SBarcodeInput.js +16 -3
  9. package/dist/components/SBarcodeInput/SBarcodeInput.js.map +1 -1
  10. package/dist/components/SCalendar/SCalendar.cjs +2 -0
  11. package/dist/components/SCalendar/SCalendar.cjs.map +1 -1
  12. package/dist/components/SCalendar/SCalendar.js +2 -0
  13. package/dist/components/SCalendar/SCalendar.js.map +1 -1
  14. package/dist/components/SChip/SChip.cjs +2 -0
  15. package/dist/components/SChip/SChip.cjs.map +1 -1
  16. package/dist/components/SChip/SChip.js +2 -0
  17. package/dist/components/SChip/SChip.js.map +1 -1
  18. package/dist/components/SChipInput/SChipInput.cjs +22 -4
  19. package/dist/components/SChipInput/SChipInput.cjs.map +1 -1
  20. package/dist/components/SChipInput/SChipInput.d.ts +5 -0
  21. package/dist/components/SChipInput/SChipInput.js +22 -4
  22. package/dist/components/SChipInput/SChipInput.js.map +1 -1
  23. package/dist/components/SChipInput/index.d.ts +1 -1
  24. package/dist/components/SCircleProgress/SCircleProgress.cjs +69 -50
  25. package/dist/components/SCircleProgress/SCircleProgress.cjs.map +1 -1
  26. package/dist/components/SCircleProgress/SCircleProgress.d.ts +2 -0
  27. package/dist/components/SCircleProgress/SCircleProgress.js +69 -50
  28. package/dist/components/SCircleProgress/SCircleProgress.js.map +1 -1
  29. package/dist/components/SConfirmModal/SConfirmModal.cjs +13 -10
  30. package/dist/components/SConfirmModal/SConfirmModal.cjs.map +1 -1
  31. package/dist/components/SConfirmModal/SConfirmModal.d.ts +7 -4
  32. package/dist/components/SConfirmModal/SConfirmModal.js +13 -10
  33. package/dist/components/SConfirmModal/SConfirmModal.js.map +1 -1
  34. package/dist/components/SDatePicker/SDatePicker.cjs +16 -3
  35. package/dist/components/SDatePicker/SDatePicker.cjs.map +1 -1
  36. package/dist/components/SDatePicker/SDatePicker.d.ts +3 -1
  37. package/dist/components/SDatePicker/SDatePicker.js +16 -3
  38. package/dist/components/SDatePicker/SDatePicker.js.map +1 -1
  39. package/dist/components/SDateRangePicker/SDateRangePicker.cjs +16 -3
  40. package/dist/components/SDateRangePicker/SDateRangePicker.cjs.map +1 -1
  41. package/dist/components/SDateRangePicker/SDateRangePicker.d.ts +3 -1
  42. package/dist/components/SDateRangePicker/SDateRangePicker.js +16 -3
  43. package/dist/components/SDateRangePicker/SDateRangePicker.js.map +1 -1
  44. package/dist/components/SDropdownButton/SDropdownButton.cjs +2 -0
  45. package/dist/components/SDropdownButton/SDropdownButton.cjs.map +1 -1
  46. package/dist/components/SDropdownButton/SDropdownButton.js +2 -0
  47. package/dist/components/SDropdownButton/SDropdownButton.js.map +1 -1
  48. package/dist/components/SField/SField.cjs +14 -3
  49. package/dist/components/SField/SField.cjs.map +1 -1
  50. package/dist/components/SField/SField.d.ts +4 -1
  51. package/dist/components/SField/SField.js +14 -3
  52. package/dist/components/SField/SField.js.map +1 -1
  53. package/dist/components/SFilePicker/SFilePicker.cjs +51 -19
  54. package/dist/components/SFilePicker/SFilePicker.cjs.map +1 -1
  55. package/dist/components/SFilePicker/SFilePicker.d.ts +4 -2
  56. package/dist/components/SFilePicker/SFilePicker.js +50 -19
  57. package/dist/components/SFilePicker/SFilePicker.js.map +1 -1
  58. package/dist/components/SGhostButton/SGhostButton.cjs +2 -0
  59. package/dist/components/SGhostButton/SGhostButton.cjs.map +1 -1
  60. package/dist/components/SGhostButton/SGhostButton.js +2 -0
  61. package/dist/components/SGhostButton/SGhostButton.js.map +1 -1
  62. package/dist/components/SGuide/SGuide.cjs +2 -0
  63. package/dist/components/SGuide/SGuide.cjs.map +1 -1
  64. package/dist/components/SGuide/SGuide.js +2 -0
  65. package/dist/components/SGuide/SGuide.js.map +1 -1
  66. package/dist/components/SInput/SInput.cjs +16 -3
  67. package/dist/components/SInput/SInput.cjs.map +1 -1
  68. package/dist/components/SInput/SInput.d.ts +4 -1
  69. package/dist/components/SInput/SInput.js +16 -3
  70. package/dist/components/SInput/SInput.js.map +1 -1
  71. package/dist/components/SKeyValueTable/SKeyValueTable.cjs +530 -219
  72. package/dist/components/SKeyValueTable/SKeyValueTable.cjs.map +1 -1
  73. package/dist/components/SKeyValueTable/SKeyValueTable.d.ts +27 -6
  74. package/dist/components/SKeyValueTable/SKeyValueTable.js +529 -218
  75. package/dist/components/SKeyValueTable/SKeyValueTable.js.map +1 -1
  76. package/dist/components/SLoadingContainer/SLoadingContainer.cjs +69 -50
  77. package/dist/components/SLoadingContainer/SLoadingContainer.cjs.map +1 -1
  78. package/dist/components/SLoadingContainer/SLoadingContainer.js +69 -50
  79. package/dist/components/SLoadingContainer/SLoadingContainer.js.map +1 -1
  80. package/dist/components/SLoadingContainer/loading.cjs +69 -50
  81. package/dist/components/SLoadingContainer/loading.cjs.map +1 -1
  82. package/dist/components/SLoadingContainer/loading.js +69 -50
  83. package/dist/components/SLoadingContainer/loading.js.map +1 -1
  84. package/dist/components/SLoadingModal/SLoadingModal.cjs +75 -51
  85. package/dist/components/SLoadingModal/SLoadingModal.cjs.map +1 -1
  86. package/dist/components/SLoadingModal/SLoadingModal.d.ts +3 -1
  87. package/dist/components/SLoadingModal/SLoadingModal.js +75 -51
  88. package/dist/components/SLoadingModal/SLoadingModal.js.map +1 -1
  89. package/dist/components/SModalContainer/SModalContainer.cjs +3 -1
  90. package/dist/components/SModalContainer/SModalContainer.cjs.map +1 -1
  91. package/dist/components/SModalContainer/SModalContainer.js +3 -1
  92. package/dist/components/SModalContainer/SModalContainer.js.map +1 -1
  93. package/dist/components/SNumberInput/SNumberInput.cjs +16 -3
  94. package/dist/components/SNumberInput/SNumberInput.cjs.map +1 -1
  95. package/dist/components/SNumberInput/SNumberInput.d.ts +2 -0
  96. package/dist/components/SNumberInput/SNumberInput.js +16 -3
  97. package/dist/components/SNumberInput/SNumberInput.js.map +1 -1
  98. package/dist/components/SPopover/SPopover.cjs +2 -0
  99. package/dist/components/SPopover/SPopover.cjs.map +1 -1
  100. package/dist/components/SPopover/SPopover.js +2 -0
  101. package/dist/components/SPopover/SPopover.js.map +1 -1
  102. package/dist/components/SPortal/SPortal.cjs +2 -0
  103. package/dist/components/SPortal/SPortal.cjs.map +1 -1
  104. package/dist/components/SPortal/SPortal.js +2 -0
  105. package/dist/components/SPortal/SPortal.js.map +1 -1
  106. package/dist/components/SRadio/SRadioGroup.cjs +1 -1
  107. package/dist/components/SRadio/SRadioGroup.cjs.map +1 -1
  108. package/dist/components/SRadio/SRadioGroup.js +1 -1
  109. package/dist/components/SRadio/SRadioGroup.js.map +1 -1
  110. package/dist/components/SSelect/SSelect.cjs +530 -258
  111. package/dist/components/SSelect/SSelect.cjs.map +1 -1
  112. package/dist/components/SSelect/SSelect.d.ts +4 -2
  113. package/dist/components/SSelect/SSelect.js +531 -258
  114. package/dist/components/SSelect/SSelect.js.map +1 -1
  115. package/dist/components/STable/STable.cjs +603 -309
  116. package/dist/components/STable/STable.cjs.map +1 -1
  117. package/dist/components/STable/STable.js +604 -309
  118. package/dist/components/STable/STable.js.map +1 -1
  119. package/dist/components/STextLink/STextLink.cjs +2 -0
  120. package/dist/components/STextLink/STextLink.cjs.map +1 -1
  121. package/dist/components/STextLink/STextLink.js +2 -0
  122. package/dist/components/STextLink/STextLink.js.map +1 -1
  123. package/dist/components/STextarea/STextarea.cjs +16 -3
  124. package/dist/components/STextarea/STextarea.cjs.map +1 -1
  125. package/dist/components/STextarea/STextarea.d.ts +2 -0
  126. package/dist/components/STextarea/STextarea.js +16 -3
  127. package/dist/components/STextarea/STextarea.js.map +1 -1
  128. package/dist/components/SToast/SToast.cjs +2 -0
  129. package/dist/components/SToast/SToast.cjs.map +1 -1
  130. package/dist/components/SToast/SToast.js +2 -0
  131. package/dist/components/SToast/SToast.js.map +1 -1
  132. package/dist/components/SToast/SToastContainer.cjs +2 -0
  133. package/dist/components/SToast/SToastContainer.cjs.map +1 -1
  134. package/dist/components/SToast/SToastContainer.js +2 -0
  135. package/dist/components/SToast/SToastContainer.js.map +1 -1
  136. package/dist/components/STooltip/STooltip.cjs +3 -1
  137. package/dist/components/STooltip/STooltip.cjs.map +1 -1
  138. package/dist/components/STooltip/STooltip.js +3 -1
  139. package/dist/components/STooltip/STooltip.js.map +1 -1
  140. package/dist/index.cjs +522 -248
  141. package/dist/index.cjs.map +1 -1
  142. package/dist/index.d.ts +0 -1
  143. package/dist/index.js +523 -248
  144. package/dist/index.js.map +1 -1
  145. package/dist/lib/portal-container.d.ts +7 -0
  146. package/dist/styles.css +123 -58
  147. package/dist/theme.css +45 -21
  148. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3300,12 +3300,35 @@ var COLOR_MAP = {
3300
3300
  };
3301
3301
  var clamp2 = (v) => Number.isFinite(v) ? Math.max(0, Math.min(100, v)) : 0;
3302
3302
  var SCircleProgress = forwardRef(
3303
- function SCircleProgress2({ value = 0, type = "primary", indeterminate = false, label, className, style }, ref) {
3303
+ function SCircleProgress2({
3304
+ value = 0,
3305
+ type = "primary",
3306
+ indeterminate = false,
3307
+ label,
3308
+ innerValue = false,
3309
+ className,
3310
+ style
3311
+ }, ref) {
3304
3312
  const v = clamp2(value);
3305
3313
  const colors = COLOR_MAP[type];
3306
3314
  const c = VIEWBOX / 2;
3307
3315
  const percentColor = v === 0 ? "var(--sys-color-fg-tertiary, #888888)" : colors.arc;
3308
3316
  const filled = v / 100 * CIRCUMFERENCE;
3317
+ const showPercent = !indeterminate;
3318
+ const percentNode = /* @__PURE__ */ jsxs(
3319
+ "span",
3320
+ {
3321
+ className: cn(
3322
+ "text-center text-[16px] font-bold leading-[26px]",
3323
+ innerValue && "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2"
3324
+ ),
3325
+ style: { color: percentColor },
3326
+ children: [
3327
+ Math.round(v),
3328
+ "%"
3329
+ ]
3330
+ }
3331
+ );
3309
3332
  return /* @__PURE__ */ jsxs(
3310
3333
  "div",
3311
3334
  {
@@ -3316,57 +3339,53 @@ var SCircleProgress = forwardRef(
3316
3339
  ),
3317
3340
  style,
3318
3341
  children: [
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
- }
3342
+ /* @__PURE__ */ jsxs("div", { className: cn(innerValue && "relative"), children: [
3343
+ /* @__PURE__ */ jsxs(
3344
+ "svg",
3345
+ {
3346
+ viewBox: `0 0 ${VIEWBOX} ${VIEWBOX}`,
3347
+ xmlns: "http://www.w3.org/2000/svg",
3348
+ className: cn(
3349
+ "h-[80px] w-[80px]",
3350
+ indeterminate && "origin-center animate-circle-spin"
3336
3351
  ),
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 }
3352
+ children: [
3353
+ /* @__PURE__ */ jsx(
3354
+ "circle",
3355
+ {
3356
+ cx: c,
3357
+ cy: c,
3358
+ r: RADIUS,
3359
+ fill: "none",
3360
+ strokeWidth: STROKE,
3361
+ style: { stroke: colors.track }
3353
3362
  }
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
- ),
3363
+ ),
3364
+ /* @__PURE__ */ jsx(
3365
+ "circle",
3366
+ {
3367
+ cx: c,
3368
+ cy: c,
3369
+ r: RADIUS,
3370
+ fill: "none",
3371
+ strokeWidth: STROKE,
3372
+ strokeLinecap: "round",
3373
+ className: cn(
3374
+ "origin-center",
3375
+ indeterminate ? "animate-circle-arc" : "-rotate-90 transition-[stroke-dasharray] duration-[400ms] ease-linear"
3376
+ ),
3377
+ style: {
3378
+ stroke: colors.arc,
3379
+ ...indeterminate ? {} : { strokeDasharray: `${filled} ${CIRCUMFERENCE}`, strokeDashoffset: 0 }
3380
+ }
3381
+ }
3382
+ )
3383
+ ]
3384
+ }
3385
+ ),
3386
+ showPercent && innerValue && percentNode
3387
+ ] }),
3388
+ showPercent && !innerValue && percentNode,
3370
3389
  label && /* @__PURE__ */ jsx("span", { className: "text-center text-[12px] font-normal leading-[20px] text-[color:var(--cmp-progress-color-label)]", children: label })
3371
3390
  ]
3372
3391
  }
@@ -3486,10 +3505,15 @@ var FLOATING_SLIDE_ANIM = [
3486
3505
  "data-[state=closed]:data-[side=right]:animate-floating-out-right"
3487
3506
  ].join(" ");
3488
3507
  var PortalContainerContext = createContext(null);
3508
+ var InsideModalContext = createContext(false);
3489
3509
  var PortalContainerProvider = PortalContainerContext.Provider;
3510
+ var InsideModalProvider = InsideModalContext.Provider;
3490
3511
  function usePortalContainer() {
3491
3512
  return useContext(PortalContainerContext) ?? void 0;
3492
3513
  }
3514
+ function useInsideModal() {
3515
+ return useContext(InsideModalContext);
3516
+ }
3493
3517
  var SIZE_CONFIG = {
3494
3518
  sm: {
3495
3519
  gap: 4,
@@ -4125,7 +4149,7 @@ var STooltip = forwardRef(function STooltip2({
4125
4149
  if (disabled || body == null) return /* @__PURE__ */ jsx(Fragment, { children: triggerNode });
4126
4150
  const isHover = trigger === "hover";
4127
4151
  const contentClass = cn(
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)]",
4152
+ "z-50 max-w-xs rounded-[6px] px-[16px] py-[12px] text-[12px] leading-[20px]",
4129
4153
  FLOATING_SLIDE_ANIM,
4130
4154
  className
4131
4155
  );
@@ -4600,7 +4624,7 @@ function SModalContainer({
4600
4624
  className: "absolute right-[16px] top-[16px] z-10"
4601
4625
  }
4602
4626
  ),
4603
- /* @__PURE__ */ jsx(PortalContainerProvider, { value: portalContainer, children })
4627
+ /* @__PURE__ */ jsx(InsideModalProvider, { value: true, children: /* @__PURE__ */ jsx(PortalContainerProvider, { value: portalContainer, children }) })
4604
4628
  ]
4605
4629
  }
4606
4630
  )
@@ -4646,7 +4670,8 @@ function SConfirmModal({
4646
4670
  tagSize = "sm",
4647
4671
  tagColor = "grey",
4648
4672
  slotLabel,
4649
- children,
4673
+ tagSlot,
4674
+ optionSlot,
4650
4675
  mainButtonLabel = "\uD655\uC778",
4651
4676
  mainButtonName,
4652
4677
  subButtonLabel,
@@ -4656,6 +4681,9 @@ function SConfirmModal({
4656
4681
  }) {
4657
4682
  const iconName = TYPE_ICON[type];
4658
4683
  const mainStyle = MAIN_BUTTON_STYLE[mainButtonName ?? DEFAULT_MAIN_BUTTON[type]];
4684
+ const tagNode = tagSlot ?? (tagLabel ? /* @__PURE__ */ jsx(STag, { shape: tagShape, size: tagSize, color: tagColor, label: tagLabel }) : null);
4685
+ const optionNode = optionSlot ?? (slotLabel ? /* @__PURE__ */ jsx("span", { children: slotLabel }) : null);
4686
+ const hasBody = topMessage.length > 0 || bottomMessage.length > 0 || tagNode != null || optionNode != null;
4659
4687
  return /* @__PURE__ */ jsx(
4660
4688
  SModalContainer,
4661
4689
  {
@@ -4681,15 +4709,12 @@ function SConfirmModal({
4681
4709
  }
4682
4710
  )
4683
4711
  ] }),
4684
- (topMessage.length > 0 || bottomMessage.length > 0 || tagLabel || slotLabel || children) && /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-[20px] text-center text-[12px] font-normal leading-[20px] text-[color:var(--cmp-modal-confirm-message-color)]", children: [
4712
+ hasBody && /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-[20px] text-center text-[12px] font-normal leading-[20px] text-[color:var(--cmp-modal-confirm-message-color)] w-full", children: [
4685
4713
  topMessage.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-[2px]", children: topMessage.map((m, i) => /* @__PURE__ */ jsx("p", { className: "m-0", children: m }, i)) }),
4686
- (tagLabel || slotLabel || children) && // content-box: 흰 박스 + 1px 테두리 + 패딩 + 14/700 (원본 sd-confirm-modal__content-box)
4687
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-[8px] rounded-[8px] border border-solid border-[color:var(--color-grey-30)] bg-white px-[16px] py-[12px] text-[14px] font-bold leading-[22px]", children: [
4688
- tagLabel && /* @__PURE__ */ jsx(STag, { shape: tagShape, size: tagSize, color: tagColor, label: tagLabel }),
4689
- slotLabel && /* @__PURE__ */ jsx("span", { children: slotLabel }),
4690
- children
4691
- ] }),
4692
- bottomMessage.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-[2px]", children: bottomMessage.map((m, i) => /* @__PURE__ */ jsx("p", { className: "m-0", children: m }, i)) })
4714
+ tagNode != null && // tag 위치 content-box: 흰 박스 + 1px 테두리 + 패딩 + 14/700 (원본 sd-confirm-modal__content-box)
4715
+ /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center gap-[8px] rounded-[8px] border border-solid border-[color:var(--color-grey-30)] bg-white px-[16px] py-[12px] text-[14px] font-bold leading-[22px] w-full", children: tagNode }),
4716
+ bottomMessage.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-[2px]", children: bottomMessage.map((m, i) => /* @__PURE__ */ jsx("p", { className: "m-0", children: m }, i)) }),
4717
+ optionNode != null && optionNode
4693
4718
  ] })
4694
4719
  ] }),
4695
4720
  /* @__PURE__ */ jsxs("div", { className: "flex gap-[8px]", children: [
@@ -4787,6 +4812,7 @@ var DEFAULT_BUTTON_LABEL = {
4787
4812
  function SLoadingModal({
4788
4813
  open,
4789
4814
  onOpenChange,
4815
+ onClose,
4790
4816
  persistent,
4791
4817
  state: state2 = "loading",
4792
4818
  progress,
@@ -4805,6 +4831,8 @@ function SLoadingModal({
4805
4831
  {
4806
4832
  open,
4807
4833
  onOpenChange,
4834
+ onClose,
4835
+ showClose: state2 === "error",
4808
4836
  persistent,
4809
4837
  ariaTitle: lines[0] || "\uB85C\uB529 \uC911",
4810
4838
  width,
@@ -5187,6 +5215,7 @@ var SField = forwardRef(function SField2({
5187
5215
  name,
5188
5216
  label = "",
5189
5217
  icon,
5218
+ iconColor,
5190
5219
  labelTooltip = "",
5191
5220
  labelTooltipProps,
5192
5221
  labelWidth,
@@ -5264,7 +5293,15 @@ var SField = forwardRef(function SField2({
5264
5293
  lineHeight: `${s.lineHeight}px`
5265
5294
  },
5266
5295
  children: [
5267
- icon && /* @__PURE__ */ jsx(SIcon, { name: icon, size: s.icon, style: { marginRight: s.labelGap } }),
5296
+ icon && /* @__PURE__ */ jsx(
5297
+ SIcon,
5298
+ {
5299
+ name: icon,
5300
+ size: s.icon,
5301
+ color: iconColor,
5302
+ style: { marginRight: s.labelGap }
5303
+ }
5304
+ ),
5268
5305
  /* @__PURE__ */ jsx("span", { className: "min-w-0 overflow-hidden text-ellipsis whitespace-nowrap", children: label }),
5269
5306
  (labelTooltip !== "" || labelTooltipProps) && /* @__PURE__ */ jsx("span", { className: "shrink-0", style: { marginLeft: s.labelGap }, children: /* @__PURE__ */ jsx(
5270
5307
  STooltip,
@@ -5314,7 +5351,7 @@ var SField = forwardRef(function SField2({
5314
5351
  borderBottomLeftRadius: s.radius - 1
5315
5352
  },
5316
5353
  children: [
5317
- icon && !label && /* @__PURE__ */ jsx(SIcon, { name: icon, size: s.icon }),
5354
+ icon && !label && /* @__PURE__ */ jsx(SIcon, { name: icon, size: s.icon, color: iconColor }),
5318
5355
  effectiveAddonLabel
5319
5356
  ]
5320
5357
  }
@@ -5386,6 +5423,7 @@ var SSelect = forwardRef(function SSelect2({
5386
5423
  label,
5387
5424
  labelWidth,
5388
5425
  icon,
5426
+ iconColor,
5389
5427
  labelTooltip,
5390
5428
  addonLabel,
5391
5429
  addonAlign,
@@ -5397,18 +5435,15 @@ var SSelect = forwardRef(function SSelect2({
5397
5435
  }, ref) {
5398
5436
  const multi = type === "multi" || type === "multi_depth";
5399
5437
  const portalContainer = usePortalContainer();
5438
+ const insideModal = useInsideModal();
5400
5439
  const [search, setSearch] = useState("");
5401
5440
  const [ruleError, setRuleError] = useState("");
5402
5441
  const [open, setOpen] = useState(false);
5442
+ const [pendingOpen, setPendingOpen] = useState(false);
5443
+ const [focusedIndex, setFocusedIndex] = useState(-1);
5403
5444
  const triggerRef = useRef(null);
5404
- useImperativeHandle(
5405
- ref,
5406
- () => ({
5407
- focus: () => triggerRef.current?.focus(),
5408
- open: () => setOpen(true)
5409
- }),
5410
- []
5411
- );
5445
+ const searchInputRef = useRef(null);
5446
+ const listRef = useRef(null);
5412
5447
  const flat = useMemo(() => flattenOptions(options), [options]);
5413
5448
  const selectable = useMemo(() => selectableOptions(flat), [flat]);
5414
5449
  const hasLeaf = useMemo(() => flat.some((o) => !o.isGroup), [flat]);
@@ -5426,6 +5461,46 @@ var SSelect = forwardRef(function SSelect2({
5426
5461
  const arr = Array.isArray(value) ? value : [value];
5427
5462
  return arr.map((v) => v != null && typeof v === "object" ? v.value : v).filter((v) => v != null && v !== "").map(String);
5428
5463
  }, [value]);
5464
+ const selectedRef = useRef(selected);
5465
+ selectedRef.current = selected;
5466
+ const emit2 = (next) => {
5467
+ if (!onValueChange) return;
5468
+ const mapped = next.map(
5469
+ (v) => emitValue ? rawByValue.get(v) ?? v : optionByValue.get(v) ?? { value: v, label: v }
5470
+ );
5471
+ onValueChange(multi ? mapped : mapped[0] ?? (emitValue ? "" : null));
5472
+ };
5473
+ const commitOpen = (next) => {
5474
+ setOpen(next);
5475
+ onOpenChange?.(next);
5476
+ if (!next) {
5477
+ setPendingOpen(false);
5478
+ setSearch("");
5479
+ if (rules && rules.length > 0) {
5480
+ setRuleError(runRules(multi ? selectedRef.current : selectedRef.current[0] ?? "", rules));
5481
+ }
5482
+ }
5483
+ };
5484
+ const requestOpen = (next) => {
5485
+ if (next && insideModal && portalContainer == null) {
5486
+ setPendingOpen(true);
5487
+ return;
5488
+ }
5489
+ commitOpen(next);
5490
+ };
5491
+ useEffect(() => {
5492
+ if (!insideModal || portalContainer == null || !pendingOpen) return;
5493
+ setPendingOpen(false);
5494
+ commitOpen(true);
5495
+ }, [insideModal, pendingOpen, portalContainer]);
5496
+ useImperativeHandle(
5497
+ ref,
5498
+ () => ({
5499
+ focus: () => triggerRef.current?.focus(),
5500
+ open: () => requestOpen(true)
5501
+ }),
5502
+ [insideModal, portalContainer]
5503
+ );
5429
5504
  useFormField({
5430
5505
  name,
5431
5506
  validate: () => {
@@ -5435,13 +5510,6 @@ var SSelect = forwardRef(function SSelect2({
5435
5510
  },
5436
5511
  resetValidation: () => setRuleError("")
5437
5512
  });
5438
- const emit2 = (next) => {
5439
- if (!onValueChange) return;
5440
- const mapped = next.map(
5441
- (v) => emitValue ? rawByValue.get(v) ?? v : optionByValue.get(v) ?? { value: v, label: v }
5442
- );
5443
- onValueChange(multi ? mapped : mapped[0] ?? (emitValue ? "" : null));
5444
- };
5445
5513
  const filtered = useMemo(() => {
5446
5514
  if (!showSearch || search.trim() === "") return flat;
5447
5515
  const q = search.trim().toLowerCase();
@@ -5452,6 +5520,16 @@ var SSelect = forwardRef(function SSelect2({
5452
5520
  const allValues = selectable.map((o) => o.value);
5453
5521
  const allSelected = allValues.length > 0 && allValues.every((v) => selected.includes(v));
5454
5522
  const hasItems = filtered.some((o) => !o.isGroup);
5523
+ const navigableItems = useMemo(() => {
5524
+ const items = [];
5525
+ if (multi && useSelectAll && allValues.length > 0) {
5526
+ items.push({ value: "__select_all__", isSelectAll: true });
5527
+ }
5528
+ filtered.forEach((o) => {
5529
+ if (!o.isGroup && !o.disabled) items.push({ value: o.value });
5530
+ });
5531
+ return items;
5532
+ }, [allValues.length, filtered, multi, useSelectAll]);
5455
5533
  const triggerText = (() => {
5456
5534
  if (selected.length === 0) return placeholder;
5457
5535
  if (multi) {
@@ -5461,26 +5539,119 @@ var SSelect = forwardRef(function SSelect2({
5461
5539
  return labelByValue.get(selected[0]) ?? selected[0];
5462
5540
  })();
5463
5541
  const isPlaceholder = selected.length === 0;
5464
- const selectStore = /* @__PURE__ */ jsxs(
5465
- Ariakit.SelectProvider,
5542
+ const handleSelect = (nextValue) => {
5543
+ if (multi) {
5544
+ const next = selected.includes(nextValue) ? selected.filter((v) => v !== nextValue) : [...selected, nextValue];
5545
+ emit2(next);
5546
+ return;
5547
+ }
5548
+ emit2([nextValue]);
5549
+ commitOpen(false);
5550
+ };
5551
+ const handleSelectAll = () => {
5552
+ emit2(allSelected ? [] : allValues);
5553
+ };
5554
+ useEffect(() => {
5555
+ if (!open) {
5556
+ setFocusedIndex(-1);
5557
+ return;
5558
+ }
5559
+ setFocusedIndex(navigableItems.length > 0 ? 0 : -1);
5560
+ }, [open, navigableItems.length]);
5561
+ useEffect(() => {
5562
+ if (!open) return;
5563
+ setFocusedIndex(navigableItems.length > 0 ? 0 : -1);
5564
+ }, [search, open, navigableItems.length]);
5565
+ useEffect(() => {
5566
+ if (!open || focusedIndex < 0) return;
5567
+ const list = listRef.current;
5568
+ const focusedEl = list?.querySelector('[data-select-focused="true"]');
5569
+ if (!list || !focusedEl) return;
5570
+ const listRect = list.getBoundingClientRect();
5571
+ const itemRect = focusedEl.getBoundingClientRect();
5572
+ if (itemRect.top < listRect.top) {
5573
+ list.scrollTop += itemRect.top - listRect.top;
5574
+ } else if (itemRect.bottom > listRect.bottom) {
5575
+ list.scrollTop += itemRect.bottom - listRect.bottom;
5576
+ }
5577
+ }, [focusedIndex, open]);
5578
+ const moveFocusedIndex = (direction) => {
5579
+ if (!open || navigableItems.length === 0) return;
5580
+ setFocusedIndex((current) => {
5581
+ if (direction === "next") {
5582
+ return current < 0 ? 0 : (current + 1) % navigableItems.length;
5583
+ }
5584
+ return current <= 0 ? navigableItems.length - 1 : current - 1;
5585
+ });
5586
+ };
5587
+ const selectFocusedItem = () => {
5588
+ if (focusedIndex < 0 || focusedIndex >= navigableItems.length) return;
5589
+ const focused = navigableItems[focusedIndex];
5590
+ if (focused.isSelectAll) {
5591
+ handleSelectAll();
5592
+ return;
5593
+ }
5594
+ handleSelect(focused.value);
5595
+ };
5596
+ const handleKeyDown = (event) => {
5597
+ if (!open) {
5598
+ if ((event.key === "ArrowDown" || event.key === "ArrowUp") && !effectiveDisabled) {
5599
+ event.preventDefault();
5600
+ requestOpen(true);
5601
+ }
5602
+ return;
5603
+ }
5604
+ if (event.key === "ArrowDown") {
5605
+ event.preventDefault();
5606
+ moveFocusedIndex("next");
5607
+ return;
5608
+ }
5609
+ if (event.key === "ArrowUp") {
5610
+ event.preventDefault();
5611
+ moveFocusedIndex("prev");
5612
+ return;
5613
+ }
5614
+ if (event.key === "Enter") {
5615
+ event.preventDefault();
5616
+ selectFocusedItem();
5617
+ return;
5618
+ }
5619
+ if (event.key === "Escape") {
5620
+ event.preventDefault();
5621
+ commitOpen(false);
5622
+ }
5623
+ };
5624
+ return /* @__PURE__ */ jsxs(
5625
+ SField,
5466
5626
  {
5467
- animated: portalContainer == null ? 150 : false,
5468
- value: multi ? selected : selected[0] ?? "",
5469
- setValue: (v) => emit2(Array.isArray(v) ? v : v === "" ? [] : [v]),
5470
- open,
5471
- setOpen: (o) => {
5472
- setOpen(o);
5473
- onOpenChange?.(o);
5474
- if (!o && rules && rules.length > 0) {
5475
- setRuleError(runRules(multi ? selected : selected[0] ?? "", rules));
5476
- }
5477
- },
5627
+ label,
5628
+ labelWidth,
5629
+ icon,
5630
+ iconColor,
5631
+ labelTooltip,
5632
+ labelTooltipProps,
5633
+ addonLabel,
5634
+ addonAlign,
5635
+ hint,
5636
+ error: error || ruleError !== "",
5637
+ status: rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0,
5638
+ errorMessage: ruleError !== "" ? ruleError : errorMessage,
5639
+ disabled: effectiveDisabled,
5640
+ width,
5641
+ className,
5642
+ style,
5478
5643
  children: [
5644
+ name && /* @__PURE__ */ jsx("input", { type: "hidden", name, value: selected.join(",") }),
5479
5645
  /* @__PURE__ */ jsxs(
5480
- Ariakit.Select,
5646
+ "button",
5481
5647
  {
5482
5648
  ref: triggerRef,
5649
+ type: "button",
5483
5650
  disabled: effectiveDisabled,
5651
+ "aria-haspopup": "listbox",
5652
+ "aria-expanded": open,
5653
+ onClick: () => requestOpen(!open),
5654
+ onKeyDown: handleKeyDown,
5484
5655
  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",
5485
5656
  style: {
5486
5657
  color: effectiveDisabled ? "var(--cmp-select-text-disabled)" : isPlaceholder ? "var(--cmp-select-icon-default)" : "var(--cmp-select-text-default)"
@@ -5505,174 +5676,229 @@ var SSelect = forwardRef(function SSelect2({
5505
5676
  ]
5506
5677
  }
5507
5678
  ),
5508
- /* @__PURE__ */ jsxs(
5509
- Ariakit.SelectPopover,
5679
+ /* @__PURE__ */ jsx(
5680
+ SPortal,
5510
5681
  {
5511
- portal: true,
5512
- portalElement: portalContainer,
5513
- gutter: 4,
5514
- sameWidth: !dropdownWidth,
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",
5682
+ open,
5683
+ onClose: () => commitOpen(false),
5684
+ onOpenChange: (next) => {
5685
+ if (next) requestOpen(true);
5686
+ },
5687
+ anchorRef: triggerRef,
5688
+ placement: "bottom",
5689
+ align: "start",
5690
+ offset: 4,
5691
+ fit: !dropdownWidth,
5692
+ onOpenAutoFocus: (event) => {
5693
+ if (!showSearch) {
5694
+ event.preventDefault();
5695
+ return;
5696
+ }
5697
+ event.preventDefault();
5698
+ requestAnimationFrame(() => searchInputRef.current?.focus());
5699
+ },
5700
+ onCloseAutoFocus: (event) => {
5701
+ event.preventDefault();
5702
+ triggerRef.current?.focus();
5703
+ },
5704
+ className: "rounded-[var(--cmp-listBox-radius)] bg-[var(--cmp-listBox-bg)] py-[4px] shadow-[2px_2px_12px_2px_rgba(0,0,0,0.1)]",
5516
5705
  style: {
5517
- maxHeight: dropdownHeight,
5518
5706
  ...dropdownWidth ? { width: dropdownWidth } : {},
5519
5707
  maxWidth: maxDropdownWidth
5520
5708
  },
5521
- children: [
5522
- showSearch && // 원본 sd-select-list-item-search: sticky + 검색 아이콘 + 테두리 input + focus-within + clear
5523
- /* @__PURE__ */ jsx("div", { className: "sticky top-0 z-[1] bg-[var(--cmp-listBox-bg)] px-[8px] py-[4px]", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-[6px] rounded-[4px] border border-solid border-[color:var(--color-grey-45)] bg-white px-[8px] py-[4px] focus-within:border-[color:var(--sys-color-field-border-focus)]", children: [
5524
- /* @__PURE__ */ jsx(SIcon, { name: "search", size: 16, color: "var(--color-grey-70)", className: "shrink-0" }),
5525
- /* @__PURE__ */ jsx(
5526
- Ariakit.Combobox,
5527
- {
5528
- autoSelect: true,
5529
- placeholder: "\uAC80\uC0C9",
5530
- className: "min-w-0 flex-1 border-none bg-transparent text-[12px] leading-[20px] text-[color:var(--cmp-select-text-default)] outline-none placeholder:text-[color:var(--color-grey-55)]"
5531
- }
5532
- ),
5533
- search !== "" && /* @__PURE__ */ jsx(
5534
- SGhostButton,
5535
- {
5536
- icon: "close",
5537
- size: "xxs",
5538
- intent: "default",
5539
- ariaLabel: "\uAC80\uC0C9\uC5B4 \uC9C0\uC6B0\uAE30",
5540
- onClick: () => setSearch(""),
5541
- className: "shrink-0"
5542
- }
5543
- )
5544
- ] }) }),
5545
- multi && useSelectAll && /* @__PURE__ */ jsx(
5546
- "button",
5547
- {
5548
- type: "button",
5549
- className: "flex w-full items-center px-[12px] py-[4px] text-left text-[12px] leading-[20px] text-[color:var(--cmp-listItem-content-default)] hover:bg-[var(--cmp-listItem-bg-hover)] hover:text-[color:var(--cmp-listItem-content-hover)]",
5550
- onClick: () => emit2(allSelected ? [] : allValues),
5551
- children: allSelectedLabel
5552
- }
5553
- ),
5554
- hasItems ? /* @__PURE__ */ jsx(ItemList, { items: filtered, multi, selected, useSearch: showSearch }) : (
5555
- // 원본 sd-select-listbox__empty (표시할 항목이 없을 때)
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." })
5557
- )
5558
- ]
5709
+ children: /* @__PURE__ */ jsxs(
5710
+ "div",
5711
+ {
5712
+ ref: listRef,
5713
+ 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)]",
5714
+ style: { maxHeight: dropdownHeight },
5715
+ onMouseLeave: () => setFocusedIndex(-1),
5716
+ children: [
5717
+ showSearch && /* @__PURE__ */ jsx("div", { className: "sticky top-0 z-[1] bg-[var(--cmp-listBox-bg)] px-[8px] py-[4px]", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-[6px] rounded-[4px] border border-solid border-[color:var(--color-grey-45)] bg-white px-[8px] py-[4px] focus-within:border-[color:var(--sys-color-field-border-focus)]", children: [
5718
+ /* @__PURE__ */ jsx(SIcon, { name: "search", size: 16, color: "var(--color-grey-70)", className: "shrink-0" }),
5719
+ /* @__PURE__ */ jsx(
5720
+ "input",
5721
+ {
5722
+ ref: searchInputRef,
5723
+ value: search,
5724
+ onChange: (e) => setSearch(e.target.value),
5725
+ onKeyDown: handleKeyDown,
5726
+ placeholder: "\uAC80\uC0C9",
5727
+ className: "min-w-0 flex-1 border-none bg-transparent text-[12px] leading-[20px] text-[color:var(--cmp-select-text-default)] outline-none placeholder:text-[color:var(--color-grey-55)]"
5728
+ }
5729
+ ),
5730
+ search !== "" && /* @__PURE__ */ jsx(
5731
+ SGhostButton,
5732
+ {
5733
+ icon: "close",
5734
+ size: "xxs",
5735
+ intent: "default",
5736
+ ariaLabel: "\uAC80\uC0C9\uC5B4 \uC9C0\uC6B0\uAE30",
5737
+ onClick: () => setSearch(""),
5738
+ className: "shrink-0"
5739
+ }
5740
+ )
5741
+ ] }) }),
5742
+ hasItems ? /* @__PURE__ */ jsx(
5743
+ ItemList,
5744
+ {
5745
+ items: filtered,
5746
+ multi,
5747
+ selected,
5748
+ focusedValue: navigableItems[focusedIndex]?.isSelectAll ? "__select_all__" : navigableItems[focusedIndex]?.value,
5749
+ showSelectAll: multi && useSelectAll && allValues.length > 0,
5750
+ selectAllLabel: allSelectedLabel,
5751
+ selectAllSelected: allSelected,
5752
+ onSelectAll: handleSelectAll,
5753
+ onSelect: handleSelect,
5754
+ onHoverValue: (value2) => {
5755
+ const index = navigableItems.findIndex(
5756
+ (item) => item.isSelectAll ? value2 === "__select_all__" : item.value === value2
5757
+ );
5758
+ if (index >= 0) setFocusedIndex(index);
5759
+ }
5760
+ }
5761
+ ) : /* @__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." })
5762
+ ]
5763
+ }
5764
+ )
5559
5765
  }
5560
5766
  )
5561
5767
  ]
5562
5768
  }
5563
5769
  );
5564
- const control = showSearch ? /* @__PURE__ */ jsx(Ariakit.ComboboxProvider, { value: search, setValue: setSearch, resetValueOnHide: true, children: selectStore }) : selectStore;
5565
- return /* @__PURE__ */ jsxs(
5566
- SField,
5567
- {
5568
- label,
5569
- labelWidth,
5570
- icon,
5571
- labelTooltip,
5572
- labelTooltipProps,
5573
- addonLabel,
5574
- addonAlign,
5575
- hint,
5576
- error: error || ruleError !== "",
5577
- status: rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0,
5578
- errorMessage: ruleError !== "" ? ruleError : errorMessage,
5579
- disabled: effectiveDisabled,
5580
- width,
5581
- className,
5582
- style,
5583
- children: [
5584
- name && /* @__PURE__ */ jsx("input", { type: "hidden", name, value: selected.join(",") }),
5585
- control
5586
- ]
5587
- }
5588
- );
5589
5770
  });
5590
5771
  SSelect.displayName = "SSelect";
5591
5772
  function ItemList({
5592
5773
  items,
5593
5774
  multi,
5594
5775
  selected,
5595
- useSearch
5776
+ focusedValue,
5777
+ showSelectAll,
5778
+ selectAllLabel,
5779
+ selectAllSelected,
5780
+ onSelectAll,
5781
+ onSelect,
5782
+ onHoverValue
5596
5783
  }) {
5597
5784
  const itemBase = cn(
5598
- // group: 체크박스 inverse(group-data-[active-item])를 위해 필요
5599
- "group flex cursor-pointer select-none items-center gap-[8px] text-[12px] leading-[20px] outline-none",
5785
+ "group flex w-full cursor-pointer select-none items-center gap-[8px] border-none bg-transparent text-left text-[12px] leading-[20px] outline-none",
5600
5786
  "text-[color:var(--cmp-listItem-content-default)]",
5601
- // Ariakit은 disabled 항목에 aria-disabled를 붙이므로 aria-disabled 변형으로 스타일 (data-disabled 아님)
5602
- "aria-disabled:cursor-not-allowed aria-disabled:text-[color:var(--cmp-listItem-content-disabled)]"
5603
- );
5604
- const activeClass = "data-[active-item]:bg-[var(--cmp-listItem-bg-hover)] data-[active-item]:text-[color:var(--cmp-listItem-content-hover)]";
5605
- return /* @__PURE__ */ jsx(Fragment, { children: items.map((o) => {
5606
- const padLeft = o.depth === 1 ? 12 : o.depth === 2 ? 20 : 28;
5607
- if (o.isGroup) {
5608
- const isDepth1 = o.depth === 1;
5609
- return /* @__PURE__ */ jsx(
5610
- "div",
5611
- {
5612
- className: cn(
5613
- "select-none py-[4px] pr-[12px] text-[12px] leading-[20px] text-[color:var(--cmp-listItem-content-default)]",
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)]"
5619
- ),
5620
- style: { paddingLeft: padLeft },
5621
- children: o.label
5622
- },
5623
- o.value
5624
- );
5625
- }
5626
- const isSelected = selected.includes(o.value);
5627
- return /* @__PURE__ */ jsxs(
5628
- Ariakit.SelectItem,
5787
+ "disabled:cursor-not-allowed disabled:text-[color:var(--cmp-listItem-content-disabled)]"
5788
+ );
5789
+ const activeClass = "hover:bg-[var(--cmp-listItem-bg-hover)] hover:text-[color:var(--cmp-listItem-content-hover)] focus:bg-[var(--cmp-listItem-bg-hover)] focus:text-[color:var(--cmp-listItem-content-hover)]";
5790
+ return /* @__PURE__ */ jsxs("div", { role: "listbox", "aria-multiselectable": multi || void 0, children: [
5791
+ showSelectAll && /* @__PURE__ */ jsxs(
5792
+ "button",
5629
5793
  {
5630
- value: o.value,
5631
- disabled: o.disabled,
5794
+ type: "button",
5795
+ "data-select-focused": focusedValue === "__select_all__" ? "true" : void 0,
5796
+ "data-select-active": focusedValue === "__select_all__" ? "true" : void 0,
5632
5797
  className: cn(
5633
5798
  itemBase,
5634
- isSelected && !multi && "font-bold text-[color:var(--cmp-listItem-content-selected)]",
5635
- activeClass
5799
+ focusedValue === "__select_all__" && "bg-[var(--cmp-listItem-bg-hover)] text-[color:var(--cmp-listItem-content-hover)]"
5636
5800
  ),
5637
- style: { paddingTop: 4, paddingBottom: 4, paddingRight: 12, paddingLeft: padLeft },
5638
- render: useSearch ? /* @__PURE__ */ jsx(Ariakit.ComboboxItem, {}) : void 0,
5801
+ style: { paddingTop: 4, paddingBottom: 4, paddingRight: 12, paddingLeft: 12 },
5802
+ onMouseEnter: () => onHoverValue("__select_all__"),
5803
+ onClick: onSelectAll,
5639
5804
  children: [
5640
- multi && // hover(active) 시 checkbox inverse — 파란 hover 배경 위에서 checked/unchecked 모두 흰 테두리 + 투명 배경
5641
5805
  /* @__PURE__ */ jsx(
5642
5806
  "span",
5643
5807
  {
5644
5808
  className: cn(
5645
5809
  "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
- )
5810
+ selectAllSelected ? focusedValue === "__select_all__" ? "border-[color:var(--cmp-checkbox-checked-border-inverse)] bg-[var(--cmp-checkbox-checked-bg-default)]" : "border-[color:var(--cmp-checkbox-checked-bg-default)] bg-[var(--cmp-checkbox-checked-bg-default)]" : "border-[color:var(--cmp-checkbox-unchecked-border-default)] bg-[var(--cmp-checkbox-unchecked-bg-default)]"
5653
5811
  ),
5654
- children: isSelected && /* @__PURE__ */ jsx(
5812
+ children: selectAllSelected && /* @__PURE__ */ jsx(
5655
5813
  SIcon,
5656
5814
  {
5657
5815
  name: "checkboxCheck",
5658
5816
  size: 12,
5659
- color: o.disabled ? "var(--cmp-checkbox-checked-icon-disabled)" : "var(--cmp-checkbox-checked-icon-default)"
5817
+ color: "var(--cmp-checkbox-checked-icon-default)"
5660
5818
  }
5661
5819
  )
5662
5820
  }
5663
5821
  ),
5664
- isHtmlLabel(o.label) ? /* @__PURE__ */ jsx(
5665
- "span",
5666
- {
5667
- className: "flex-1 truncate",
5668
- dangerouslySetInnerHTML: { __html: sanitizeInlineHtml(o.label) }
5669
- }
5670
- ) : /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: o.label })
5822
+ /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: selectAllLabel })
5671
5823
  ]
5672
- },
5673
- o.value
5674
- );
5675
- }) });
5824
+ }
5825
+ ),
5826
+ items.map((o) => {
5827
+ const padLeft = o.depth === 1 ? 12 : o.depth === 2 ? 20 : 28;
5828
+ if (o.isGroup) {
5829
+ const isDepth1 = o.depth === 1;
5830
+ return /* @__PURE__ */ jsx(
5831
+ "div",
5832
+ {
5833
+ className: cn(
5834
+ "select-none py-[4px] pr-[12px] text-[12px] leading-[20px] text-[color:var(--cmp-listItem-content-default)]",
5835
+ 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",
5836
+ // 하위가 전부 비활성이면(select.config 에서 bubble-up) 어미 그룹도 비활성 처리:
5837
+ // 텍스트는 회색(#888), depth1 그룹은 파란 배경 대신 회색(#EEE)으로 (depth2 는 #F6F6F6 유지)
5838
+ o.disabled && "cursor-not-allowed text-[color:var(--cmp-listItem-content-disabled)]",
5839
+ o.disabled && isDepth1 && "bg-[var(--cmp-listItem-depth1-bg-disabled)]"
5840
+ ),
5841
+ style: { paddingLeft: padLeft },
5842
+ children: o.label
5843
+ },
5844
+ o.value
5845
+ );
5846
+ }
5847
+ const isSelected = selected.includes(o.value);
5848
+ return /* @__PURE__ */ jsxs(
5849
+ "button",
5850
+ {
5851
+ type: "button",
5852
+ disabled: o.disabled,
5853
+ role: "option",
5854
+ "aria-selected": isSelected,
5855
+ "data-select-focused": focusedValue === o.value ? "true" : void 0,
5856
+ "data-select-active": focusedValue === o.value ? "true" : void 0,
5857
+ className: cn(
5858
+ itemBase,
5859
+ isSelected && !multi && "font-bold text-[color:var(--cmp-listItem-content-selected)]",
5860
+ focusedValue === o.value && "bg-[var(--cmp-listItem-bg-hover)] text-[color:var(--cmp-listItem-content-hover)]",
5861
+ activeClass
5862
+ ),
5863
+ style: { paddingTop: 4, paddingBottom: 4, paddingRight: 12, paddingLeft: padLeft },
5864
+ onMouseEnter: () => onHoverValue(o.value),
5865
+ onClick: () => onSelect(o.value),
5866
+ children: [
5867
+ multi && /* @__PURE__ */ jsx(
5868
+ "span",
5869
+ {
5870
+ className: cn(
5871
+ "flex h-[16px] w-[16px] flex-shrink-0 items-center justify-center rounded-[2px] border border-solid",
5872
+ o.disabled ? (
5873
+ // 비활성: 회색 채움(#E1E1E1) + 회색 테두리(#CCCCCC)
5874
+ "cursor-not-allowed border-[color:var(--cmp-checkbox-border-disabled)] bg-[var(--cmp-checkbox-bg-disabled)]"
5875
+ ) : cn(
5876
+ isSelected ? focusedValue === o.value ? "border-[color:var(--cmp-checkbox-checked-border-inverse)] bg-[var(--cmp-checkbox-checked-bg-default)]" : "border-[color:var(--cmp-checkbox-checked-bg-default)] bg-[var(--cmp-checkbox-checked-bg-default)]" : "border-[color:var(--cmp-checkbox-unchecked-border-default)] bg-[var(--cmp-checkbox-unchecked-bg-default)]"
5877
+ )
5878
+ ),
5879
+ children: isSelected && /* @__PURE__ */ jsx(
5880
+ SIcon,
5881
+ {
5882
+ name: "checkboxCheck",
5883
+ size: 12,
5884
+ color: o.disabled ? "var(--cmp-checkbox-checked-icon-disabled)" : "var(--cmp-checkbox-checked-icon-default)"
5885
+ }
5886
+ )
5887
+ }
5888
+ ),
5889
+ isHtmlLabel(o.label) ? /* @__PURE__ */ jsx(
5890
+ "span",
5891
+ {
5892
+ className: "flex-1 truncate",
5893
+ dangerouslySetInnerHTML: { __html: sanitizeInlineHtml(o.label) }
5894
+ }
5895
+ ) : /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: o.label })
5896
+ ]
5897
+ },
5898
+ o.value
5899
+ );
5900
+ })
5901
+ ] });
5676
5902
  }
5677
5903
  var DEFAULT_ROW_HEIGHT = 44;
5678
5904
  var DENSE_ROW_HEIGHT = 32;
@@ -5947,7 +6173,8 @@ var STable = forwardRef(function STable2({
5947
6173
  else onSelectedChange?.([...selected, row]);
5948
6174
  };
5949
6175
  const radiusClass = radius === "full" ? "rounded-none" : radius === "useTop" ? "rounded-b-[var(--cmp-table-radius)] rounded-t-none" : "rounded-[var(--cmp-table-radius)]";
5950
- const cellPadY = dense ? "var(--cmp-table-body-dense-paddingY)" : "var(--cmp-table-body-default-paddingY)";
6176
+ const cellPadY = dense ? "var(--cmp-table-body-paddingY-dense)" : "var(--cmp-table-body-paddingY-default)";
6177
+ const cellPadX = "var(--cmp-table-body-paddingX-wide)";
5951
6178
  const rowH = dense ? "var(--cmp-table-body-dense-height)" : "var(--cmp-table-body-default-height)";
5952
6179
  const totalColSpan = visibleCols.length + (selectable ? 1 : 0);
5953
6180
  const stickyInfo = (i) => {
@@ -6122,13 +6349,15 @@ var STable = forwardRef(function STable2({
6122
6349
  className: cn(
6123
6350
  // 원본 .td: 컬럼 폭에 맞춰 내용 말줄임(overflow hidden + ellipsis) + 행 구분선(border-b)
6124
6351
  // 셀 배경은 흰색으로 채워 뒤 배경이 비치지 않게 하고, hover 시 행 배경(grey_05)을 따른다.
6125
- "overflow-hidden text-ellipsis whitespace-nowrap border-b border-solid border-[color:var(--cmp-table-border-color)] px-[16px] text-[12px] leading-[20px] text-[color:var(--sys-color-fg-primary)]",
6352
+ "overflow-hidden text-ellipsis whitespace-nowrap border-b border-solid border-[color:var(--cmp-table-border-color)] text-[12px] leading-[20px] text-[color:var(--sys-color-fg-primary)]",
6126
6353
  rowBg,
6127
6354
  "group-hover:bg-[var(--color-grey-05)]",
6128
6355
  stickyShadowClass(i),
6129
6356
  col.tdClass
6130
6357
  ),
6131
6358
  style: {
6359
+ paddingLeft: cellPadX,
6360
+ paddingRight: cellPadX,
6132
6361
  paddingTop: cellPadY,
6133
6362
  paddingBottom: cellPadY,
6134
6363
  textAlign: col.align ?? "left",
@@ -6192,6 +6421,7 @@ var SInput = forwardRef(function SInput2({
6192
6421
  type = "text",
6193
6422
  size = "sm",
6194
6423
  icon,
6424
+ iconColor,
6195
6425
  prefix,
6196
6426
  suffix,
6197
6427
  clearable = false,
@@ -6245,6 +6475,7 @@ var SInput = forwardRef(function SInput2({
6245
6475
  labelTooltip,
6246
6476
  labelTooltipProps,
6247
6477
  icon,
6478
+ iconColor,
6248
6479
  size,
6249
6480
  hint,
6250
6481
  error: resolvedError,
@@ -6346,6 +6577,7 @@ var STextarea = forwardRef(function STextarea2({
6346
6577
  label,
6347
6578
  labelWidth,
6348
6579
  icon,
6580
+ iconColor,
6349
6581
  labelTooltip,
6350
6582
  labelTooltipProps,
6351
6583
  addonLabel,
@@ -6382,6 +6614,7 @@ var STextarea = forwardRef(function STextarea2({
6382
6614
  label,
6383
6615
  labelWidth,
6384
6616
  icon,
6617
+ iconColor,
6385
6618
  labelTooltip,
6386
6619
  labelTooltipProps,
6387
6620
  addonLabel,
@@ -6514,6 +6747,7 @@ var SNumberInput = forwardRef(function SNumberInput2({
6514
6747
  label,
6515
6748
  labelWidth,
6516
6749
  icon,
6750
+ iconColor,
6517
6751
  labelTooltip,
6518
6752
  labelTooltipProps,
6519
6753
  addonLabel,
@@ -6672,6 +6906,7 @@ var SNumberInput = forwardRef(function SNumberInput2({
6672
6906
  label,
6673
6907
  labelWidth,
6674
6908
  icon,
6909
+ iconColor,
6675
6910
  labelTooltip,
6676
6911
  labelTooltipProps,
6677
6912
  addonLabel,
@@ -6862,7 +7097,7 @@ function SRadioGroup({
6862
7097
  role: "radiogroup",
6863
7098
  className: cn(
6864
7099
  "inline-flex",
6865
- direction === "vertical" ? "flex-col gap-[8px]" : "flex-row gap-[20px]",
7100
+ direction === "vertical" ? "flex-col gap-[var(--cmp-radio-group-gap-vertical)]" : "flex-row gap-[var(--cmp-radio-group-gap-horizontal)]",
6866
7101
  className
6867
7102
  ),
6868
7103
  style,
@@ -7147,6 +7382,7 @@ function SDatePicker({
7147
7382
  label,
7148
7383
  labelWidth,
7149
7384
  icon,
7385
+ iconColor,
7150
7386
  labelTooltip,
7151
7387
  labelTooltipProps,
7152
7388
  addonLabel,
@@ -7185,6 +7421,7 @@ function SDatePicker({
7185
7421
  label,
7186
7422
  labelWidth,
7187
7423
  icon,
7424
+ iconColor,
7188
7425
  labelTooltip,
7189
7426
  labelTooltipProps,
7190
7427
  addonLabel,
@@ -7453,6 +7690,7 @@ function SDateRangePicker({
7453
7690
  label,
7454
7691
  labelWidth,
7455
7692
  icon,
7693
+ iconColor,
7456
7694
  labelTooltip,
7457
7695
  labelTooltipProps,
7458
7696
  addonLabel,
@@ -7495,6 +7733,7 @@ function SDateRangePicker({
7495
7733
  label,
7496
7734
  labelWidth,
7497
7735
  icon,
7736
+ iconColor,
7498
7737
  labelTooltip,
7499
7738
  labelTooltipProps,
7500
7739
  addonLabel,
@@ -7756,6 +7995,7 @@ function SFilePicker({
7756
7995
  label,
7757
7996
  labelWidth,
7758
7997
  icon,
7998
+ iconColor,
7759
7999
  labelTooltip,
7760
8000
  labelTooltipProps,
7761
8001
  addonLabel,
@@ -7770,7 +8010,10 @@ function SFilePicker({
7770
8010
  const autoId = useId();
7771
8011
  const resolvedName = name ?? autoId;
7772
8012
  const inputRef = useRef(null);
8013
+ const contentBoxRef = useRef(null);
7773
8014
  const [ruleError, setRuleError] = useState("");
8015
+ const [listOpen, setListOpen] = useState(false);
8016
+ const portalContainer = usePortalContainer();
7774
8017
  const files = multiple ? Array.isArray(value) ? value : [] : value && !Array.isArray(value) ? value : null;
7775
8018
  const hasFiles = multiple ? files.length > 0 : !!files;
7776
8019
  const displayText = !hasFiles ? placeholder : multiple ? files.map((f) => f.name).join(", ") : files.name;
@@ -7824,10 +8067,12 @@ function SFilePicker({
7824
8067
  e.stopPropagation();
7825
8068
  if (disabled) return;
7826
8069
  onValueChange?.(multiple ? [] : null);
8070
+ setListOpen(false);
7827
8071
  };
7828
8072
  const removeChip = (i) => {
7829
8073
  const next = files.filter((_, idx) => idx !== i);
7830
8074
  onValueChange?.(next);
8075
+ if (next.length === 0) setListOpen(false);
7831
8076
  };
7832
8077
  const open = () => {
7833
8078
  if (!disabled) inputRef.current?.click();
@@ -7838,9 +8083,12 @@ function SFilePicker({
7838
8083
  const iconSize = size === "md" ? 20 : 16;
7839
8084
  const gapCls = size === "md" ? "gap-[var(--cmp-filepicker-md-gap)]" : "gap-[var(--cmp-filepicker-sm-gap)]";
7840
8085
  const inlinePlaceholder = inline && !disabled && !hasFiles;
7841
- const content = /* @__PURE__ */ jsxs(
8086
+ const showListbox = multiple && useMultipleListBox;
8087
+ const filesArr = multiple ? files : [];
8088
+ const contentInner = /* @__PURE__ */ jsxs(
7842
8089
  "div",
7843
8090
  {
8091
+ ref: contentBoxRef,
7844
8092
  className: cn("group/filepicker flex h-full w-full items-center", gapCls),
7845
8093
  style: { padding: inline ? 0 : `0 ${padX}` },
7846
8094
  children: [
@@ -7895,25 +8143,34 @@ function SFilePicker({
7895
8143
  ]
7896
8144
  }
7897
8145
  ),
8146
+ showListbox && hasFiles && !disabled && /* @__PURE__ */ jsx(
8147
+ Ariakit.PopoverDisclosure,
8148
+ {
8149
+ render: /* @__PURE__ */ jsx(SGhostButton, { icon: "caretDown", size: "xxs", ariaLabel: "toggle file list" }),
8150
+ className: cn("shrink-0 transition-transform duration-150", listOpen && "rotate-180")
8151
+ }
8152
+ ),
7898
8153
  !disabled && hasFiles && /* @__PURE__ */ jsx(SGhostButton, { icon: "close", size: "xxs", ariaLabel: "clear", onClick: clear })
7899
8154
  ]
7900
8155
  }
7901
8156
  );
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"
7908
- ),
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
- );
8157
+ const content = showListbox ? /* @__PURE__ */ jsxs(Ariakit.PopoverProvider, { open: listOpen, setOpen: setListOpen, placement: "bottom-start", children: [
8158
+ contentInner,
8159
+ /* @__PURE__ */ jsx(
8160
+ Ariakit.Popover,
8161
+ {
8162
+ portal: true,
8163
+ portalElement: portalContainer,
8164
+ gutter: 4,
8165
+ unmountOnHide: true,
8166
+ getAnchorRect: () => contentBoxRef.current?.getBoundingClientRect() ?? null,
8167
+ style: { minWidth: contentBoxRef.current?.offsetWidth },
8168
+ className: "z-50 box-border flex flex-col items-start gap-[8px] rounded-[var(--cmp-listBox-radius)] bg-[var(--cmp-listBox-bg)] p-[8px] shadow-[2px_2px_12px_2px_rgba(0,0,0,0.1)]",
8169
+ children: filesArr.map((f, i) => /* @__PURE__ */ jsx(SChip, { value: f.name, editable: false, onRemove: () => removeChip(i) }, i))
8170
+ }
8171
+ )
8172
+ ] }) : contentInner;
8173
+ const chips = multiple && !useMultipleListBox && filesArr.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-[8px] flex flex-wrap gap-[8px]", children: filesArr.map((f, i) => /* @__PURE__ */ jsx(SChip, { value: f.name, editable: false, onRemove: () => removeChip(i) }, i)) });
7917
8174
  return /* @__PURE__ */ jsxs("div", { className, style, children: [
7918
8175
  /* @__PURE__ */ jsx(
7919
8176
  SField,
@@ -7922,6 +8179,7 @@ function SFilePicker({
7922
8179
  label,
7923
8180
  labelWidth,
7924
8181
  icon,
8182
+ iconColor,
7925
8183
  labelTooltip,
7926
8184
  labelTooltipProps,
7927
8185
  addonLabel,
@@ -7944,21 +8202,26 @@ function SFilePicker({
7944
8202
  var cssLen2 = (v) => v == null ? void 0 : typeof v === "number" ? `${v}px` : v;
7945
8203
  function SKeyValueTable({
7946
8204
  fields = [],
8205
+ values = {},
7947
8206
  search = false,
7948
8207
  radius = "default",
7949
- dense = false,
7950
8208
  onChange,
7951
8209
  onSearch,
7952
8210
  className,
7953
8211
  style
7954
8212
  }) {
7955
8213
  if (fields.length === 0) return null;
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)";
8214
+ const emit2 = (name, value) => onChange?.({
8215
+ name,
8216
+ value,
8217
+ values: { ...values, [name]: value }
8218
+ });
8219
+ const cellHeight = "var(--cmp-table-keyValue-height)";
8220
+ const cellPadY = "var(--cmp-table-keyValue-body-paddingY)";
7959
8221
  const renderField = (f) => {
7960
8222
  if (f.render) return f.render;
7961
- const opt = f.options ?? {};
8223
+ const opt = { ...f.options ?? {} };
8224
+ if (Object.prototype.hasOwnProperty.call(values, f.name)) opt.value = values[f.name];
7962
8225
  const up = (v) => emit2(f.name, v);
7963
8226
  switch (f.type) {
7964
8227
  case "input":
@@ -8070,7 +8333,10 @@ function SKeyValueTable({
8070
8333
  rowSpan: f.tdRowSpan && f.tdRowSpan > 1 ? f.tdRowSpan : void 0,
8071
8334
  colSpan: f.tdColSpan && f.tdColSpan > 1 ? f.tdColSpan : void 0,
8072
8335
  className: cn(
8073
- "box-border bg-[var(--sys-color-bg-frame)] px-[var(--cmp-table-keyValue-body-paddingX-default)] align-middle",
8336
+ "box-border bg-[var(--sys-color-bg-frame)] align-middle",
8337
+ // text 타입(및 미지정 기본값)은 읽기 전용 콘텐츠라 넓은 paddingX(wide),
8338
+ // 폼 필드 셀은 default paddingX 유지
8339
+ f.type == null || f.type === "text" ? "px-[var(--cmp-table-keyValue-body-paddingX-wide)]" : "px-[var(--cmp-table-keyValue-body-paddingX-default)]",
8074
8340
  cellBorder,
8075
8341
  f.tdClass
8076
8342
  ),
@@ -8563,6 +8829,7 @@ var SChipInput = forwardRef(function SChipInput2({
8563
8829
  error,
8564
8830
  useReset = false,
8565
8831
  maxCount,
8832
+ metaPlacement = "end",
8566
8833
  duplicateLabel,
8567
8834
  suggestions = [],
8568
8835
  loadingSuggestions = false,
@@ -8576,6 +8843,7 @@ var SChipInput = forwardRef(function SChipInput2({
8576
8843
  width,
8577
8844
  status,
8578
8845
  icon,
8846
+ iconColor,
8579
8847
  labelTooltip,
8580
8848
  labelTooltipProps,
8581
8849
  className,
@@ -8710,6 +8978,7 @@ var SChipInput = forwardRef(function SChipInput2({
8710
8978
  labelWidth,
8711
8979
  labelHeight: `calc(var(--cmp-chipInput-${size}-minHeight) + 2px)`,
8712
8980
  icon,
8981
+ iconColor,
8713
8982
  labelTooltip,
8714
8983
  labelTooltipProps,
8715
8984
  size,
@@ -8857,7 +9126,11 @@ var SChipInput = forwardRef(function SChipInput2({
8857
9126
  showMetaInfo && /* @__PURE__ */ jsxs(
8858
9127
  "div",
8859
9128
  {
8860
- className: "s-chip-input__meta ml-auto flex items-center gap-8",
9129
+ className: cn(
9130
+ "s-chip-input__meta flex items-center gap-8",
9131
+ metaPlacement === "end" && "ml-auto"
9132
+ ),
9133
+ "data-placement": metaPlacement,
8861
9134
  onMouseDown: (e) => e.preventDefault(),
8862
9135
  children: [
8863
9136
  /* @__PURE__ */ jsx(
@@ -8997,6 +9270,7 @@ var SBarcodeInput = forwardRef(
8997
9270
  label,
8998
9271
  labelWidth,
8999
9272
  icon,
9273
+ iconColor,
9000
9274
  labelTooltip,
9001
9275
  labelTooltipProps,
9002
9276
  addonLabel,
@@ -9028,6 +9302,7 @@ var SBarcodeInput = forwardRef(
9028
9302
  label,
9029
9303
  labelWidth,
9030
9304
  icon,
9305
+ iconColor,
9031
9306
  labelTooltip,
9032
9307
  labelTooltipProps,
9033
9308
  addonLabel,
@@ -9106,6 +9381,6 @@ var SBarcodeInput = forwardRef(
9106
9381
  }
9107
9382
  );
9108
9383
 
9109
- export { BADGE_COLORS, BUTTON_COLORS, BUTTON_SIZES, COLOR_KEYS, ICONS, SActionModal, SBadge, SBarcodeInput, SButton, SCalendar, SCallout, SCard, SCheckbox, SChip, SChipInput, SCircleProgress, SConfirmModal, SDatePicker, SDateRangePicker, SDivider, SDropdownButton, SField, SFilePicker, SForm, SGhostButton, SGuide, SIcon, SInput, SKeyValueTable, SLinearProgress, SLoadingContainer, SLoadingModal, SLoadingViewport, SModalContainer, SNumberInput, SPagination, SPopover, SPopup, SPortal, SRadio, SRadioButton, SRadioGroup, SSelect, SSwitch, STable, STabs, STag, STextLink, STextarea, SToast, SToastContainer, SToggle, STooltip, TAG_COLORS, TAG_SHAPES, TAG_SIZES, buttonPreset, cn, isColorKey, loading, resolveColor };
9384
+ export { BADGE_COLORS, BUTTON_COLORS, BUTTON_SIZES, COLOR_KEYS, ICONS, SActionModal, SBadge, SBarcodeInput, SButton, SCalendar, SCallout, SCard, SCheckbox, SChip, SChipInput, SCircleProgress, SConfirmModal, SDatePicker, SDateRangePicker, SDivider, SDropdownButton, SField, SFilePicker, SForm, SGhostButton, SGuide, SIcon, SInput, SKeyValueTable, SLinearProgress, SLoadingContainer, SLoadingModal, SLoadingViewport, SNumberInput, SPagination, SPopover, SPopup, SPortal, SRadio, SRadioButton, SRadioGroup, SSelect, SSwitch, STable, STabs, STag, STextLink, STextarea, SToast, SToastContainer, SToggle, STooltip, TAG_COLORS, TAG_SHAPES, TAG_SIZES, buttonPreset, cn, isColorKey, loading, resolveColor };
9110
9385
  //# sourceMappingURL=index.js.map
9111
9386
  //# sourceMappingURL=index.js.map