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
@@ -2,7 +2,7 @@
2
2
  'use strict';
3
3
 
4
4
  var react = require('react');
5
- var RPopover = require('@radix-ui/react-popover');
5
+ var RPopover2 = require('@radix-ui/react-popover');
6
6
  var clsx = require('clsx');
7
7
  var tailwindMerge = require('tailwind-merge');
8
8
  var jsxRuntime = require('react/jsx-runtime');
@@ -25,7 +25,7 @@ function _interopNamespace(e) {
25
25
  return Object.freeze(n);
26
26
  }
27
27
 
28
- var RPopover__namespace = /*#__PURE__*/_interopNamespace(RPopover);
28
+ var RPopover2__namespace = /*#__PURE__*/_interopNamespace(RPopover2);
29
29
 
30
30
  var twMerge = tailwindMerge.extendTailwindMerge({
31
31
  extend: {
@@ -2897,11 +2897,200 @@ PortalContainerContext.Provider;
2897
2897
  function usePortalContainer() {
2898
2898
  return react.useContext(PortalContainerContext) ?? void 0;
2899
2899
  }
2900
+
2901
+ // src/components/STag/tag.config.ts
2902
+ var TAG_SIZE_CONFIG = {
2903
+ xs: {
2904
+ height: 20,
2905
+ paddingX: 8,
2906
+ gap: 4,
2907
+ radius: 6,
2908
+ iconSize: 12,
2909
+ fontSize: 11,
2910
+ fontWeight: 500,
2911
+ lineHeight: 18
2912
+ },
2913
+ sm: {
2914
+ height: 24,
2915
+ paddingX: 8,
2916
+ gap: 4,
2917
+ radius: 6,
2918
+ iconSize: 16,
2919
+ fontSize: 12,
2920
+ fontWeight: 700,
2921
+ lineHeight: 20
2922
+ },
2923
+ md: {
2924
+ height: 28,
2925
+ paddingX: 12,
2926
+ gap: 6,
2927
+ radius: 8,
2928
+ iconSize: 16,
2929
+ fontSize: 14,
2930
+ fontWeight: 700,
2931
+ lineHeight: 24
2932
+ }
2933
+ };
2934
+ var STag = react.forwardRef(function STag2({
2935
+ shape = "square",
2936
+ size = "sm",
2937
+ color = "grey",
2938
+ label = "",
2939
+ icon,
2940
+ iconLeft = true,
2941
+ width,
2942
+ className,
2943
+ style,
2944
+ ...rest
2945
+ }, ref) {
2946
+ const s = TAG_SIZE_CONFIG[size];
2947
+ const contentColor = `var(--cmp-tag-${color}-content)`;
2948
+ const iconNode = icon ? /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: icon, size: s.iconSize, color: contentColor }) : null;
2949
+ const resolvedWidth = typeof width === "number" ? `${width}px` : width;
2950
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2951
+ "span",
2952
+ {
2953
+ ref,
2954
+ "aria-label": label || "tag",
2955
+ className: cn(
2956
+ "box-border inline-flex w-fit select-none items-center justify-center whitespace-nowrap",
2957
+ className
2958
+ ),
2959
+ style: {
2960
+ minHeight: s.height,
2961
+ padding: `0 ${s.paddingX}px`,
2962
+ gap: s.gap,
2963
+ borderRadius: shape === "pill" ? 999 : s.radius,
2964
+ fontSize: s.fontSize,
2965
+ fontWeight: s.fontWeight,
2966
+ lineHeight: `${s.lineHeight}px`,
2967
+ background: `var(--cmp-tag-${color}-bg)`,
2968
+ color: contentColor,
2969
+ ...resolvedWidth != null ? { width: resolvedWidth } : {},
2970
+ ...style
2971
+ },
2972
+ ...rest,
2973
+ children: [
2974
+ icon && iconLeft && iconNode,
2975
+ label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex min-w-0 items-center justify-center", children: label }),
2976
+ icon && !iconLeft && iconNode
2977
+ ]
2978
+ }
2979
+ );
2980
+ });
2981
+ var SIZE = {
2982
+ xxs: { icon: 12, radius: "sm" },
2983
+ xs: { icon: 16, radius: "sm" },
2984
+ sm: { icon: 20, radius: "sm" },
2985
+ md: { icon: 24, radius: "md" },
2986
+ lg: { icon: 32, radius: "md" }
2987
+ };
2988
+ var TOOLTIP_HIDE_DELAY_MS = 100;
2989
+ function SGhostButton({
2990
+ icon,
2991
+ size = "sm",
2992
+ intent = "default",
2993
+ ariaLabel = "",
2994
+ tooltipText,
2995
+ disabled = false,
2996
+ onClick,
2997
+ className,
2998
+ style
2999
+ }) {
3000
+ const portalContainer = usePortalContainer();
3001
+ const [open, setOpen] = react.useState(false);
3002
+ const hideTimer = react.useRef(void 0);
3003
+ const cancelHide = () => {
3004
+ if (hideTimer.current) {
3005
+ clearTimeout(hideTimer.current);
3006
+ hideTimer.current = void 0;
3007
+ }
3008
+ };
3009
+ const openNow = () => {
3010
+ cancelHide();
3011
+ setOpen(true);
3012
+ };
3013
+ const startHide = () => {
3014
+ cancelHide();
3015
+ hideTimer.current = setTimeout(() => setOpen(false), TOOLTIP_HIDE_DELAY_MS);
3016
+ };
3017
+ const s = SIZE[size];
3018
+ const contentColor = disabled ? intent === "inverse" ? "var(--cmp-ghostButton-inverse-disabled)" : "var(--cmp-ghostButton-icon-disabled)" : `var(--cmp-ghostButton-${intent}-content)`;
3019
+ const btn = /* @__PURE__ */ jsxRuntime.jsxs(
3020
+ "button",
3021
+ {
3022
+ type: "button",
3023
+ disabled,
3024
+ "aria-disabled": disabled ? "true" : void 0,
3025
+ "aria-label": ariaLabel.trim() || void 0,
3026
+ tabIndex: disabled ? -1 : void 0,
3027
+ onClick: (e) => {
3028
+ if (disabled) {
3029
+ e.preventDefault();
3030
+ return;
3031
+ }
3032
+ onClick?.(e);
3033
+ },
3034
+ className: cn(
3035
+ "group relative box-border inline-flex items-center justify-center border-none bg-transparent p-0 transition-shadow",
3036
+ disabled ? "cursor-not-allowed" : "cursor-pointer",
3037
+ "focus-visible:outline-none focus-visible:shadow-[0_0_0_2px_var(--cmp-ghostButton-action-hover-bg)]",
3038
+ className
3039
+ ),
3040
+ style: {
3041
+ width: `var(--cmp-ghostButton-${size}-size)`,
3042
+ height: `var(--cmp-ghostButton-${size}-size)`,
3043
+ borderRadius: `var(--cmp-ghostButton-radius-${s.radius})`,
3044
+ ...style
3045
+ },
3046
+ children: [
3047
+ !disabled && /* @__PURE__ */ jsxRuntime.jsx(
3048
+ "span",
3049
+ {
3050
+ "aria-hidden": true,
3051
+ className: "pointer-events-none absolute inset-0 rounded-[inherit] opacity-0 transition-opacity duration-200 group-hover:opacity-5",
3052
+ style: { background: `var(--cmp-ghostButton-${intent}-hover-bg)` }
3053
+ }
3054
+ ),
3055
+ /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: icon, size: s.icon, color: contentColor })
3056
+ ]
3057
+ }
3058
+ );
3059
+ const text = (tooltipText ?? "").trim();
3060
+ if (text === "") return btn;
3061
+ return /* @__PURE__ */ jsxRuntime.jsxs(RPopover2__namespace.Root, { open, onOpenChange: setOpen, children: [
3062
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Anchor, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
3063
+ "span",
3064
+ {
3065
+ className: "inline-flex",
3066
+ onMouseEnter: openNow,
3067
+ onMouseLeave: startHide,
3068
+ onFocus: openNow,
3069
+ onBlur: startHide,
3070
+ children: btn
3071
+ }
3072
+ ) }),
3073
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
3074
+ RPopover2__namespace.Content,
3075
+ {
3076
+ side: "top",
3077
+ sideOffset: 4,
3078
+ className: cn("z-50", FLOATING_SLIDE_ANIM),
3079
+ "aria-hidden": true,
3080
+ onOpenAutoFocus: (e) => e.preventDefault(),
3081
+ onMouseEnter: cancelHide,
3082
+ onMouseLeave: startHide,
3083
+ children: /* @__PURE__ */ jsxRuntime.jsx(STag, { shape: "square", size: "xs", color: "grey", label: text })
3084
+ }
3085
+ ) })
3086
+ ] });
3087
+ }
2900
3088
  var HIDE_DELAY_MS = 100;
2901
3089
  function useBody(content, message = []) {
2902
3090
  if (content != null) return content;
2903
3091
  if (message.length === 0) return null;
2904
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: message.map((line, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { children: line }, i)) });
3092
+ const singleLine = message.length === 1;
3093
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: message.map((line, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: singleLine ? "leading-[24px]" : void 0, children: line }, i)) });
2905
3094
  }
2906
3095
  var STooltip = react.forwardRef(function STooltip2({
2907
3096
  content,
@@ -2959,7 +3148,7 @@ var STooltip = react.forwardRef(function STooltip2({
2959
3148
  if (disabled || body == null) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: triggerNode });
2960
3149
  const isHover = trigger === "hover";
2961
3150
  const contentClass = cn(
2962
- "z-50 max-w-xs rounded-[6px] px-[16px] py-[12px] text-[12px] leading-[20px]",
3151
+ "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)]",
2963
3152
  FLOATING_SLIDE_ANIM,
2964
3153
  className
2965
3154
  );
@@ -2969,10 +3158,10 @@ var STooltip = react.forwardRef(function STooltip2({
2969
3158
  fontWeight: tooltipType === "default" ? 500 : 700,
2970
3159
  ...style
2971
3160
  };
2972
- return /* @__PURE__ */ jsxRuntime.jsxs(RPopover__namespace.Root, { open, onOpenChange: setOpen, children: [
3161
+ return /* @__PURE__ */ jsxRuntime.jsxs(RPopover2__namespace.Root, { open, onOpenChange: setOpen, children: [
2973
3162
  isHover ? (
2974
3163
  // hover: Anchor(위치 기준) + 직접 mouse 핸들러 — 클릭으로 토글되지 않도록 Trigger 미사용
2975
- /* @__PURE__ */ jsxRuntime.jsx(RPopover__namespace.Anchor, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
3164
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Anchor, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
2976
3165
  "span",
2977
3166
  {
2978
3167
  className: "inline-flex",
@@ -2983,9 +3172,9 @@ var STooltip = react.forwardRef(function STooltip2({
2983
3172
  children: triggerNode
2984
3173
  }
2985
3174
  ) })
2986
- ) : /* @__PURE__ */ jsxRuntime.jsx(RPopover__namespace.Trigger, { asChild: true, children: triggerNode }),
2987
- /* @__PURE__ */ jsxRuntime.jsx(RPopover__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(
2988
- RPopover__namespace.Content,
3175
+ ) : /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Trigger, { asChild: true, children: triggerNode }),
3176
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(
3177
+ RPopover2__namespace.Content,
2989
3178
  {
2990
3179
  side: placement,
2991
3180
  sideOffset: 8,
@@ -3004,15 +3193,21 @@ var STooltip = react.forwardRef(function STooltip2({
3004
3193
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-[12px]", children: [
3005
3194
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children: body }),
3006
3195
  useClose && /* @__PURE__ */ jsxRuntime.jsx(
3007
- RPopover__namespace.Close,
3196
+ SGhostButton,
3008
3197
  {
3009
- "aria-label": "\uB2EB\uAE30",
3010
- className: "shrink-0 cursor-pointer opacity-70 hover:opacity-100",
3011
- children: /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: "close", size: 16, color: fg })
3198
+ icon: "close",
3199
+ size: "xs",
3200
+ intent: tooltipType === "default" ? "inverse" : "default",
3201
+ ariaLabel: "\uB2EB\uAE30",
3202
+ className: "shrink-0",
3203
+ onClick: () => {
3204
+ cancelHide();
3205
+ setOpen(false);
3206
+ }
3012
3207
  }
3013
3208
  )
3014
3209
  ] }),
3015
- /* @__PURE__ */ jsxRuntime.jsx(RPopover__namespace.Arrow, { width: 16, height: 12, style: { fill: bg } })
3210
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Arrow, { width: 16, height: 12, style: { fill: bg } })
3016
3211
  ]
3017
3212
  }
3018
3213
  ) })
@@ -3046,8 +3241,8 @@ function useFormField(field) {
3046
3241
  }, [ctx, name]);
3047
3242
  }
3048
3243
  var FIELD_SIZE = {
3049
- sm: { height: 28, radius: 4, fieldGap: 12, labelGap: 6, fontSize: 12, lineHeight: 20, icon: 12 },
3050
- md: { height: 36, radius: 6, fieldGap: 16, labelGap: 8, fontSize: 14, lineHeight: 24, icon: 12 }
3244
+ sm: { height: 28, radius: 4, fieldGap: 12, labelGap: 6, fontSize: 12, lineHeight: 20, icon: 16 },
3245
+ md: { height: 36, radius: 6, fieldGap: 16, labelGap: 8, fontSize: 14, lineHeight: 24, icon: 16 }
3051
3246
  };
3052
3247
  var ALIGN = {
3053
3248
  start: "flex-start",
@@ -3062,6 +3257,7 @@ var SField = react.forwardRef(function SField2({
3062
3257
  labelTooltip = "",
3063
3258
  labelTooltipProps,
3064
3259
  labelWidth,
3260
+ labelHeight,
3065
3261
  size = "sm",
3066
3262
  addonLabel = "",
3067
3263
  addonAlign = "start",
@@ -3076,6 +3272,7 @@ var SField = react.forwardRef(function SField2({
3076
3272
  readOnly = false,
3077
3273
  width,
3078
3274
  multiline = false,
3275
+ borderless = false,
3079
3276
  children,
3080
3277
  className,
3081
3278
  style,
@@ -3109,8 +3306,8 @@ var SField = react.forwardRef(function SField2({
3109
3306
  const resolvedSuccess = status === "pass";
3110
3307
  const showError = resolvedError && errorMessage !== "";
3111
3308
  const interactive = !disabled && !readOnly;
3112
- 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)";
3113
- const bgColor = disabled ? "var(--color-grey-30)" : readOnly ? "var(--sys-color-field-bg-readOnly)" : "var(--sys-color-field-bg-default)";
3309
+ 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)";
3310
+ const bgColor = borderless ? "transparent" : disabled ? "var(--color-grey-30)" : readOnly ? "var(--sys-color-field-bg-readOnly)" : "var(--sys-color-field-bg-default)";
3114
3311
  const textColor = disabled ? "var(--color-grey-65)" : readOnly ? "var(--sys-color-field-text-readOnly)" : "var(--sys-color-field-text-default)";
3115
3312
  return /* @__PURE__ */ jsxRuntime.jsx(
3116
3313
  "div",
@@ -3127,7 +3324,7 @@ var SField = react.forwardRef(function SField2({
3127
3324
  {
3128
3325
  className: "flex shrink-0 items-center font-bold text-(--sys-color-field-text-default)",
3129
3326
  style: {
3130
- height: s.height,
3327
+ height: cssLen(labelHeight) ?? s.height,
3131
3328
  marginRight: s.fieldGap,
3132
3329
  width: cssLen(labelWidth),
3133
3330
  fontSize: s.fontSize,
@@ -3153,14 +3350,14 @@ var SField = react.forwardRef(function SField2({
3153
3350
  {
3154
3351
  className: cn(
3155
3352
  "relative box-border flex min-w-0 items-stretch overflow-hidden border border-solid border-(--field-bc)",
3156
- 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]",
3353
+ 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]",
3157
3354
  disabled && "cursor-not-allowed"
3158
3355
  ),
3159
3356
  style: {
3160
3357
  // @ts-expect-error CSS 변수
3161
3358
  "--field-bc": borderColor,
3162
3359
  // focused/hovered prop이 명시된 경우 강조를 즉시 반영
3163
- ...interactive && focused ? { boxShadow: "0px 0px 4px 0px #0071ff66" } : {},
3360
+ ...interactive && !borderless && focused ? { boxShadow: "0px 0px 4px 0px #0071ff66" } : {},
3164
3361
  ...multiline ? { minHeight: s.height } : { height: s.height },
3165
3362
  "width": cssLen(width),
3166
3363
  "borderRadius": s.radius,
@@ -3200,194 +3397,6 @@ var SField = react.forwardRef(function SField2({
3200
3397
  );
3201
3398
  });
3202
3399
 
3203
- // src/components/STag/tag.config.ts
3204
- var TAG_SIZE_CONFIG = {
3205
- xs: {
3206
- height: 20,
3207
- paddingX: 8,
3208
- gap: 4,
3209
- radius: 6,
3210
- iconSize: 12,
3211
- fontSize: 11,
3212
- fontWeight: 500,
3213
- lineHeight: 18
3214
- },
3215
- sm: {
3216
- height: 24,
3217
- paddingX: 8,
3218
- gap: 4,
3219
- radius: 6,
3220
- iconSize: 16,
3221
- fontSize: 12,
3222
- fontWeight: 700,
3223
- lineHeight: 20
3224
- },
3225
- md: {
3226
- height: 28,
3227
- paddingX: 12,
3228
- gap: 6,
3229
- radius: 8,
3230
- iconSize: 16,
3231
- fontSize: 14,
3232
- fontWeight: 700,
3233
- lineHeight: 24
3234
- }
3235
- };
3236
- var STag = react.forwardRef(function STag2({
3237
- shape = "square",
3238
- size = "sm",
3239
- color = "grey",
3240
- label = "",
3241
- icon,
3242
- iconLeft = true,
3243
- width,
3244
- className,
3245
- style,
3246
- ...rest
3247
- }, ref) {
3248
- const s = TAG_SIZE_CONFIG[size];
3249
- const contentColor = `var(--cmp-tag-${color}-content)`;
3250
- const iconNode = icon ? /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: icon, size: s.iconSize, color: contentColor }) : null;
3251
- const resolvedWidth = typeof width === "number" ? `${width}px` : width;
3252
- return /* @__PURE__ */ jsxRuntime.jsxs(
3253
- "span",
3254
- {
3255
- ref,
3256
- "aria-label": label || "tag",
3257
- className: cn(
3258
- "box-border inline-flex w-fit select-none items-center justify-center whitespace-nowrap",
3259
- className
3260
- ),
3261
- style: {
3262
- minHeight: s.height,
3263
- padding: `0 ${s.paddingX}px`,
3264
- gap: s.gap,
3265
- borderRadius: shape === "pill" ? 999 : s.radius,
3266
- fontSize: s.fontSize,
3267
- fontWeight: s.fontWeight,
3268
- lineHeight: `${s.lineHeight}px`,
3269
- background: `var(--cmp-tag-${color}-bg)`,
3270
- color: contentColor,
3271
- ...resolvedWidth != null ? { width: resolvedWidth } : {},
3272
- ...style
3273
- },
3274
- ...rest,
3275
- children: [
3276
- icon && iconLeft && iconNode,
3277
- label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex min-w-0 items-center justify-center", children: label }),
3278
- icon && !iconLeft && iconNode
3279
- ]
3280
- }
3281
- );
3282
- });
3283
- var SIZE = {
3284
- xxs: { icon: 12, radius: "sm" },
3285
- xs: { icon: 16, radius: "sm" },
3286
- sm: { icon: 20, radius: "sm" },
3287
- md: { icon: 24, radius: "md" },
3288
- lg: { icon: 32, radius: "md" }
3289
- };
3290
- var TOOLTIP_HIDE_DELAY_MS = 100;
3291
- function SGhostButton({
3292
- icon,
3293
- size = "sm",
3294
- intent = "default",
3295
- ariaLabel = "",
3296
- tooltipText,
3297
- disabled = false,
3298
- onClick,
3299
- className,
3300
- style
3301
- }) {
3302
- const portalContainer = usePortalContainer();
3303
- const [open, setOpen] = react.useState(false);
3304
- const hideTimer = react.useRef(void 0);
3305
- const cancelHide = () => {
3306
- if (hideTimer.current) {
3307
- clearTimeout(hideTimer.current);
3308
- hideTimer.current = void 0;
3309
- }
3310
- };
3311
- const openNow = () => {
3312
- cancelHide();
3313
- setOpen(true);
3314
- };
3315
- const startHide = () => {
3316
- cancelHide();
3317
- hideTimer.current = setTimeout(() => setOpen(false), TOOLTIP_HIDE_DELAY_MS);
3318
- };
3319
- const s = SIZE[size];
3320
- const contentColor = disabled ? intent === "inverse" ? "var(--cmp-ghostButton-inverse-disabled)" : "var(--cmp-ghostButton-icon-disabled)" : `var(--cmp-ghostButton-${intent}-content)`;
3321
- const btn = /* @__PURE__ */ jsxRuntime.jsxs(
3322
- "button",
3323
- {
3324
- type: "button",
3325
- disabled,
3326
- "aria-disabled": disabled ? "true" : void 0,
3327
- "aria-label": ariaLabel.trim() || void 0,
3328
- tabIndex: disabled ? -1 : void 0,
3329
- onClick: (e) => {
3330
- if (disabled) {
3331
- e.preventDefault();
3332
- return;
3333
- }
3334
- onClick?.(e);
3335
- },
3336
- className: cn(
3337
- "group relative box-border inline-flex items-center justify-center border-none bg-transparent p-0 transition-shadow",
3338
- disabled ? "cursor-not-allowed" : "cursor-pointer",
3339
- "focus-visible:outline-none focus-visible:shadow-[0_0_0_2px_var(--cmp-ghostButton-action-hover-bg)]",
3340
- className
3341
- ),
3342
- style: {
3343
- width: `var(--cmp-ghostButton-${size}-size)`,
3344
- height: `var(--cmp-ghostButton-${size}-size)`,
3345
- borderRadius: `var(--cmp-ghostButton-radius-${s.radius})`,
3346
- ...style
3347
- },
3348
- children: [
3349
- !disabled && /* @__PURE__ */ jsxRuntime.jsx(
3350
- "span",
3351
- {
3352
- "aria-hidden": true,
3353
- className: "pointer-events-none absolute inset-0 rounded-[inherit] opacity-0 transition-opacity duration-200 group-hover:opacity-5",
3354
- style: { background: `var(--cmp-ghostButton-${intent}-hover-bg)` }
3355
- }
3356
- ),
3357
- /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: icon, size: s.icon, color: contentColor })
3358
- ]
3359
- }
3360
- );
3361
- const text = (tooltipText ?? "").trim();
3362
- if (text === "") return btn;
3363
- return /* @__PURE__ */ jsxRuntime.jsxs(RPopover__namespace.Root, { open, onOpenChange: setOpen, children: [
3364
- /* @__PURE__ */ jsxRuntime.jsx(RPopover__namespace.Anchor, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
3365
- "span",
3366
- {
3367
- className: "inline-flex",
3368
- onMouseEnter: openNow,
3369
- onMouseLeave: startHide,
3370
- onFocus: openNow,
3371
- onBlur: startHide,
3372
- children: btn
3373
- }
3374
- ) }),
3375
- /* @__PURE__ */ jsxRuntime.jsx(RPopover__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
3376
- RPopover__namespace.Content,
3377
- {
3378
- side: "top",
3379
- sideOffset: 4,
3380
- className: cn("z-50", FLOATING_SLIDE_ANIM),
3381
- "aria-hidden": true,
3382
- onOpenAutoFocus: (e) => e.preventDefault(),
3383
- onMouseEnter: cancelHide,
3384
- onMouseLeave: startHide,
3385
- children: /* @__PURE__ */ jsxRuntime.jsx(STag, { shape: "square", size: "xs", color: "grey", label: text })
3386
- }
3387
- ) })
3388
- ] });
3389
- }
3390
-
3391
3400
  // src/lib/date.ts
3392
3401
  function todayStr() {
3393
3402
  const d = /* @__PURE__ */ new Date();
@@ -3427,6 +3436,7 @@ function RangeCalendar({
3427
3436
  selectable,
3428
3437
  maxRange,
3429
3438
  onSelect,
3439
+ onPendingStartChange,
3430
3440
  onViewChange
3431
3441
  }) {
3432
3442
  const today = todayStr();
@@ -3489,9 +3499,11 @@ function RangeCalendar({
3489
3499
  setStart(d);
3490
3500
  setEnd(null);
3491
3501
  setHover(null);
3502
+ onPendingStartChange?.(d);
3492
3503
  return;
3493
3504
  }
3494
3505
  setEnd(d);
3506
+ onPendingStartChange?.(null);
3495
3507
  onSelect([start, d]);
3496
3508
  };
3497
3509
  const GRID_COLS = "grid grid-cols-[repeat(7,var(--cmp-datepicker-calendar-day-width))]";
@@ -3626,8 +3638,11 @@ function SDateRangePicker({
3626
3638
  const portalContainer = usePortalContainer();
3627
3639
  const [open, setOpen] = react.useState(false);
3628
3640
  const [ruleError, setRuleError] = react.useState("");
3641
+ const [pendingStart, setPendingStart] = react.useState(null);
3629
3642
  const hasValue = value != null && value[0] !== "" && value[1] !== "";
3630
- const display = hasValue ? `${value[0]} ~ ${value[1]}` : placeholder;
3643
+ const hasDisplay = pendingStart != null || hasValue;
3644
+ const startText = pendingStart ?? (hasValue ? value[0] : "");
3645
+ const endText = pendingStart ? "" : hasValue ? value[1] : "";
3631
3646
  useFormField({
3632
3647
  name,
3633
3648
  validate: () => {
@@ -3641,6 +3656,7 @@ function SDateRangePicker({
3641
3656
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
3642
3657
  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 };
3643
3658
  const select = (r) => {
3659
+ setPendingStart(null);
3644
3660
  onValueChange?.(r);
3645
3661
  if (rules && rules.length > 0) setRuleError(runRules(r, rules));
3646
3662
  setOpen(false);
@@ -3665,61 +3681,80 @@ function SDateRangePicker({
3665
3681
  disabled,
3666
3682
  className,
3667
3683
  style,
3668
- children: /* @__PURE__ */ jsxRuntime.jsxs(RPopover__namespace.Root, { open, onOpenChange: (o) => !disabled && setOpen(o), children: [
3669
- /* @__PURE__ */ jsxRuntime.jsx(RPopover__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
3670
- "button",
3671
- {
3672
- type: "button",
3673
- name,
3674
- disabled,
3675
- className: "flex h-full w-full items-center overflow-hidden bg-transparent outline-none disabled:cursor-not-allowed",
3676
- style: { padding: `0 ${dims.padX}px`, gap: dims.gap, borderRadius: dims.radius },
3677
- children: [
3678
- /* @__PURE__ */ jsxRuntime.jsx(
3679
- SIcon,
3680
- {
3681
- name: "date",
3682
- size: dims.icon,
3683
- color: disabled ? "var(--cmp-datepicker-icon-disabled)" : "var(--cmp-datepicker-icon-default)",
3684
- className: "flex-shrink-0"
3685
- }
3686
- ),
3687
- /* @__PURE__ */ jsxRuntime.jsx(
3688
- "span",
3689
- {
3690
- className: "flex-1 truncate text-center",
3691
- style: {
3692
- minWidth: dims.minW,
3693
- fontSize: dims.fontSize,
3694
- lineHeight: `${dims.lineHeight}px`,
3695
- color: disabled ? "var(--cmp-datepicker-text-disabled)" : hasValue ? "var(--cmp-datepicker-text-default)" : "var(--cmp-field-hint-color)"
3696
- },
3697
- children: display
3698
- }
3699
- )
3700
- ]
3701
- }
3702
- ) }),
3703
- /* @__PURE__ */ jsxRuntime.jsx(RPopover__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
3704
- RPopover__namespace.Content,
3705
- {
3706
- side: "bottom",
3707
- align: "start",
3708
- sideOffset: 4,
3709
- className: cn("z-50", FLOATING_SLIDE_ANIM),
3710
- children: /* @__PURE__ */ jsxRuntime.jsx(
3711
- RangeCalendar,
3684
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
3685
+ RPopover2__namespace.Root,
3686
+ {
3687
+ open,
3688
+ onOpenChange: (o) => {
3689
+ if (disabled) return;
3690
+ setOpen(o);
3691
+ if (!o) setPendingStart(null);
3692
+ },
3693
+ children: [
3694
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
3695
+ "button",
3712
3696
  {
3713
- value: value ?? null,
3714
- selectable,
3715
- maxRange,
3716
- onSelect: select,
3717
- onViewChange
3697
+ type: "button",
3698
+ name,
3699
+ disabled,
3700
+ className: "flex h-full w-full items-center overflow-hidden bg-transparent outline-none disabled:cursor-not-allowed",
3701
+ style: { padding: `0 ${dims.padX}px`, gap: dims.gap, borderRadius: dims.radius },
3702
+ children: [
3703
+ /* @__PURE__ */ jsxRuntime.jsx(
3704
+ SIcon,
3705
+ {
3706
+ name: "date",
3707
+ size: dims.icon,
3708
+ color: disabled ? "var(--cmp-datepicker-icon-disabled)" : "var(--cmp-datepicker-icon-default)",
3709
+ className: "flex-shrink-0"
3710
+ }
3711
+ ),
3712
+ /* @__PURE__ */ jsxRuntime.jsx(
3713
+ "span",
3714
+ {
3715
+ className: cn(
3716
+ "flex-1 items-center",
3717
+ hasDisplay ? "flex" : "block truncate text-center"
3718
+ ),
3719
+ style: {
3720
+ minWidth: dims.minW,
3721
+ fontSize: dims.fontSize,
3722
+ lineHeight: `${dims.lineHeight}px`,
3723
+ color: disabled ? "var(--cmp-datepicker-text-disabled)" : hasDisplay ? "var(--cmp-datepicker-text-default)" : "var(--cmp-field-hint-color)"
3724
+ },
3725
+ children: hasDisplay ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3726
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate text-right", children: startText }),
3727
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-[4px]", children: "~" }),
3728
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate text-left", children: endText })
3729
+ ] }) : placeholder
3730
+ }
3731
+ )
3732
+ ]
3718
3733
  }
3719
- )
3720
- }
3721
- ) })
3722
- ] })
3734
+ ) }),
3735
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
3736
+ RPopover2__namespace.Content,
3737
+ {
3738
+ side: "bottom",
3739
+ align: "start",
3740
+ sideOffset: 4,
3741
+ className: cn("z-50", FLOATING_SLIDE_ANIM),
3742
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3743
+ RangeCalendar,
3744
+ {
3745
+ value: value ?? null,
3746
+ selectable,
3747
+ maxRange,
3748
+ onSelect: select,
3749
+ onPendingStartChange: setPendingStart,
3750
+ onViewChange
3751
+ }
3752
+ )
3753
+ }
3754
+ ) })
3755
+ ]
3756
+ }
3757
+ )
3723
3758
  }
3724
3759
  );
3725
3760
  }