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.
- package/dist/components/SActionModal/SActionModal.cjs +1 -1
- package/dist/components/SActionModal/SActionModal.cjs.map +1 -1
- package/dist/components/SActionModal/SActionModal.js +1 -1
- package/dist/components/SActionModal/SActionModal.js.map +1 -1
- package/dist/components/SBarcodeInput/SBarcodeInput.cjs +218 -209
- package/dist/components/SBarcodeInput/SBarcodeInput.cjs.map +1 -1
- package/dist/components/SBarcodeInput/SBarcodeInput.js +218 -209
- package/dist/components/SBarcodeInput/SBarcodeInput.js.map +1 -1
- package/dist/components/SCalendar/SCalendar.cjs +1 -1
- package/dist/components/SCalendar/SCalendar.cjs.map +1 -1
- package/dist/components/SCalendar/SCalendar.js +1 -1
- package/dist/components/SCalendar/SCalendar.js.map +1 -1
- package/dist/components/SChip/SChip.cjs +1 -1
- package/dist/components/SChip/SChip.cjs.map +1 -1
- package/dist/components/SChip/SChip.d.ts +1 -1
- package/dist/components/SChip/SChip.js +1 -1
- package/dist/components/SChip/SChip.js.map +1 -1
- package/dist/components/SChipInput/SChipInput.cjs +235 -221
- package/dist/components/SChipInput/SChipInput.cjs.map +1 -1
- package/dist/components/SChipInput/SChipInput.js +235 -221
- package/dist/components/SChipInput/SChipInput.js.map +1 -1
- package/dist/components/SCircleProgress/SCircleProgress.cjs +53 -55
- package/dist/components/SCircleProgress/SCircleProgress.cjs.map +1 -1
- package/dist/components/SCircleProgress/SCircleProgress.js +53 -55
- package/dist/components/SCircleProgress/SCircleProgress.js.map +1 -1
- package/dist/components/SDatePicker/SDatePicker.cjs +223 -214
- package/dist/components/SDatePicker/SDatePicker.cjs.map +1 -1
- package/dist/components/SDatePicker/SDatePicker.js +223 -214
- package/dist/components/SDatePicker/SDatePicker.js.map +1 -1
- package/dist/components/SDateRangePicker/SDateRangePicker.cjs +298 -263
- package/dist/components/SDateRangePicker/SDateRangePicker.cjs.map +1 -1
- package/dist/components/SDateRangePicker/SDateRangePicker.js +298 -263
- package/dist/components/SDateRangePicker/SDateRangePicker.js.map +1 -1
- package/dist/components/SDropdownButton/SDropdownButton.cjs +4 -4
- package/dist/components/SDropdownButton/SDropdownButton.cjs.map +1 -1
- package/dist/components/SDropdownButton/SDropdownButton.js +4 -4
- package/dist/components/SDropdownButton/SDropdownButton.js.map +1 -1
- package/dist/components/SField/SField.cjs +218 -21
- package/dist/components/SField/SField.cjs.map +1 -1
- package/dist/components/SField/SField.d.ts +11 -0
- package/dist/components/SField/SField.js +218 -21
- package/dist/components/SField/SField.js.map +1 -1
- package/dist/components/SFilePicker/SFilePicker.cjs +298 -278
- package/dist/components/SFilePicker/SFilePicker.cjs.map +1 -1
- package/dist/components/SFilePicker/SFilePicker.d.ts +4 -2
- package/dist/components/SFilePicker/SFilePicker.js +298 -278
- package/dist/components/SFilePicker/SFilePicker.js.map +1 -1
- package/dist/components/SInput/SInput.cjs +218 -209
- package/dist/components/SInput/SInput.cjs.map +1 -1
- package/dist/components/SInput/SInput.js +218 -209
- package/dist/components/SInput/SInput.js.map +1 -1
- package/dist/components/SKeyValueTable/SKeyValueTable.cjs +610 -450
- package/dist/components/SKeyValueTable/SKeyValueTable.cjs.map +1 -1
- package/dist/components/SKeyValueTable/SKeyValueTable.d.ts +3 -1
- package/dist/components/SKeyValueTable/SKeyValueTable.js +610 -450
- package/dist/components/SKeyValueTable/SKeyValueTable.js.map +1 -1
- package/dist/components/SLoadingContainer/SLoadingContainer.cjs +61 -55
- package/dist/components/SLoadingContainer/SLoadingContainer.cjs.map +1 -1
- package/dist/components/SLoadingContainer/SLoadingContainer.js +61 -55
- package/dist/components/SLoadingContainer/SLoadingContainer.js.map +1 -1
- package/dist/components/SLoadingContainer/loading.cjs +61 -55
- package/dist/components/SLoadingContainer/loading.cjs.map +1 -1
- package/dist/components/SLoadingContainer/loading.js +61 -55
- package/dist/components/SLoadingContainer/loading.js.map +1 -1
- package/dist/components/SLoadingModal/SLoadingModal.cjs +56 -57
- package/dist/components/SLoadingModal/SLoadingModal.cjs.map +1 -1
- package/dist/components/SLoadingModal/SLoadingModal.js +56 -57
- package/dist/components/SLoadingModal/SLoadingModal.js.map +1 -1
- package/dist/components/SNumberInput/SNumberInput.cjs +326 -50
- package/dist/components/SNumberInput/SNumberInput.cjs.map +1 -1
- package/dist/components/SNumberInput/SNumberInput.d.ts +2 -0
- package/dist/components/SNumberInput/SNumberInput.js +326 -50
- package/dist/components/SNumberInput/SNumberInput.js.map +1 -1
- package/dist/components/SPagination/SPagination.cjs +1 -1
- package/dist/components/SPagination/SPagination.cjs.map +1 -1
- package/dist/components/SPagination/SPagination.js +1 -1
- package/dist/components/SPagination/SPagination.js.map +1 -1
- package/dist/components/SSelect/SSelect.cjs +67 -32
- package/dist/components/SSelect/SSelect.cjs.map +1 -1
- package/dist/components/SSelect/SSelect.js +67 -32
- package/dist/components/SSelect/SSelect.js.map +1 -1
- package/dist/components/STable/STable.cjs +121 -88
- package/dist/components/STable/STable.cjs.map +1 -1
- package/dist/components/STable/STable.js +121 -88
- package/dist/components/STable/STable.js.map +1 -1
- package/dist/components/STextarea/STextarea.cjs +218 -21
- package/dist/components/STextarea/STextarea.cjs.map +1 -1
- package/dist/components/STextarea/STextarea.js +218 -21
- package/dist/components/STextarea/STextarea.js.map +1 -1
- package/dist/components/SToast/SToastContainer.cjs +3 -3
- package/dist/components/SToast/SToastContainer.cjs.map +1 -1
- package/dist/components/SToast/SToastContainer.js +3 -3
- package/dist/components/SToast/SToastContainer.js.map +1 -1
- package/dist/components/STooltip/STooltip.cjs +209 -14
- package/dist/components/STooltip/STooltip.cjs.map +1 -1
- package/dist/components/STooltip/STooltip.js +209 -14
- package/dist/components/STooltip/STooltip.js.map +1 -1
- package/dist/index.cjs +432 -260
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +432 -260
- package/dist/index.js.map +1 -1
- package/dist/styles.css +51 -27
- package/dist/theme.css +4 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3338,65 +3338,63 @@ var SCircleProgress = react.forwardRef(
|
|
|
3338
3338
|
"div",
|
|
3339
3339
|
{
|
|
3340
3340
|
ref,
|
|
3341
|
-
className: cn(
|
|
3341
|
+
className: cn(
|
|
3342
|
+
"inline-flex flex-col items-center gap-[var(--cmp-progress-circular-gap)]",
|
|
3343
|
+
className
|
|
3344
|
+
),
|
|
3342
3345
|
style,
|
|
3343
3346
|
children: [
|
|
3344
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
{
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3347
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3348
|
+
"svg",
|
|
3349
|
+
{
|
|
3350
|
+
viewBox: `0 0 ${VIEWBOX} ${VIEWBOX}`,
|
|
3351
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3352
|
+
className: cn("h-[80px] w-[80px]", indeterminate && "origin-center animate-circle-spin"),
|
|
3353
|
+
children: [
|
|
3354
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3355
|
+
"circle",
|
|
3356
|
+
{
|
|
3357
|
+
cx: c,
|
|
3358
|
+
cy: c,
|
|
3359
|
+
r: RADIUS,
|
|
3360
|
+
fill: "none",
|
|
3361
|
+
strokeWidth: STROKE,
|
|
3362
|
+
style: { stroke: colors.track }
|
|
3363
|
+
}
|
|
3353
3364
|
),
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
cy: c,
|
|
3371
|
-
r: RADIUS,
|
|
3372
|
-
fill: "none",
|
|
3373
|
-
strokeWidth: STROKE,
|
|
3374
|
-
strokeLinecap: "round",
|
|
3375
|
-
className: cn(
|
|
3376
|
-
"origin-center",
|
|
3377
|
-
indeterminate ? "animate-circle-arc" : "-rotate-90 transition-[stroke-dasharray] duration-[400ms] ease-linear"
|
|
3378
|
-
),
|
|
3379
|
-
style: {
|
|
3380
|
-
stroke: colors.arc,
|
|
3381
|
-
...indeterminate ? {} : { strokeDasharray: `${filled} ${CIRCUMFERENCE}`, strokeDashoffset: 0 }
|
|
3382
|
-
}
|
|
3365
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3366
|
+
"circle",
|
|
3367
|
+
{
|
|
3368
|
+
cx: c,
|
|
3369
|
+
cy: c,
|
|
3370
|
+
r: RADIUS,
|
|
3371
|
+
fill: "none",
|
|
3372
|
+
strokeWidth: STROKE,
|
|
3373
|
+
strokeLinecap: "round",
|
|
3374
|
+
className: cn(
|
|
3375
|
+
"origin-center",
|
|
3376
|
+
indeterminate ? "animate-circle-arc" : "-rotate-90 transition-[stroke-dasharray] duration-[400ms] ease-linear"
|
|
3377
|
+
),
|
|
3378
|
+
style: {
|
|
3379
|
+
stroke: colors.arc,
|
|
3380
|
+
...indeterminate ? {} : { strokeDasharray: `${filled} ${CIRCUMFERENCE}`, strokeDashoffset: 0 }
|
|
3383
3381
|
}
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3382
|
+
}
|
|
3383
|
+
)
|
|
3384
|
+
]
|
|
3385
|
+
}
|
|
3386
|
+
),
|
|
3387
|
+
!indeterminate && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3388
|
+
"span",
|
|
3389
|
+
{
|
|
3390
|
+
className: "text-center text-[16px] font-bold leading-[26px]",
|
|
3391
|
+
style: { color: percentColor },
|
|
3392
|
+
children: [
|
|
3393
|
+
Math.round(v),
|
|
3394
|
+
"%"
|
|
3395
|
+
]
|
|
3396
|
+
}
|
|
3397
|
+
),
|
|
3400
3398
|
label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-center text-[12px] font-normal leading-[20px] text-[color:var(--cmp-progress-color-label)]", children: label })
|
|
3401
3399
|
]
|
|
3402
3400
|
}
|
|
@@ -3407,6 +3405,14 @@ var SLoadingContainer = react.forwardRef(
|
|
|
3407
3405
|
function SLoadingContainer2({ open = false, message, zIndex = 1200, className, style }, ref) {
|
|
3408
3406
|
const [mounted2, setMounted] = react.useState(false);
|
|
3409
3407
|
react.useEffect(() => setMounted(true), []);
|
|
3408
|
+
react.useEffect(() => {
|
|
3409
|
+
if (!open) return;
|
|
3410
|
+
const prev = document.body.style.overflow;
|
|
3411
|
+
document.body.style.overflow = "hidden";
|
|
3412
|
+
return () => {
|
|
3413
|
+
document.body.style.overflow = prev;
|
|
3414
|
+
};
|
|
3415
|
+
}, [open]);
|
|
3410
3416
|
const innerRef = react.useRef(null);
|
|
3411
3417
|
const setRef = react.useCallback(
|
|
3412
3418
|
(node) => {
|
|
@@ -3675,15 +3681,15 @@ var sanitizeInlineHtml = (value) => {
|
|
|
3675
3681
|
return template.innerHTML;
|
|
3676
3682
|
};
|
|
3677
3683
|
var SIZE = {
|
|
3678
|
-
xs: { height: 24, paddingX: 8, gap: 6, arrow: 12, fontSize: 12, minWidth:
|
|
3684
|
+
xs: { height: 24, paddingX: 8, gap: 6, arrow: 12, fontSize: 12, minWidth: 64, splitMinWidth: 72 },
|
|
3679
3685
|
sm: {
|
|
3680
3686
|
height: 28,
|
|
3681
3687
|
paddingX: 12,
|
|
3682
3688
|
gap: 8,
|
|
3683
3689
|
arrow: 12,
|
|
3684
3690
|
fontSize: 12,
|
|
3685
|
-
minWidth:
|
|
3686
|
-
splitMinWidth:
|
|
3691
|
+
minWidth: 72,
|
|
3692
|
+
splitMinWidth: 88
|
|
3687
3693
|
},
|
|
3688
3694
|
md: {
|
|
3689
3695
|
height: 36,
|
|
@@ -3791,7 +3797,7 @@ var SDropdownButton = react.forwardRef(
|
|
|
3791
3797
|
align: "start",
|
|
3792
3798
|
alignOffset: split ? splitAlignOffset : 0,
|
|
3793
3799
|
className: cn(
|
|
3794
|
-
"z-50 overflow-hidden rounded-[var(--cmp-listBox-radius)] bg-[var(--cmp-listBox-bg)]
|
|
3800
|
+
"z-50 overflow-hidden rounded-[var(--cmp-listBox-radius)] bg-[var(--cmp-listBox-bg)] shadow-normal-sm",
|
|
3795
3801
|
!split && "min-w-[var(--radix-dropdown-menu-trigger-width)]",
|
|
3796
3802
|
FLOATING_SLIDE_ANIM
|
|
3797
3803
|
),
|
|
@@ -4088,7 +4094,8 @@ var HIDE_DELAY_MS = 100;
|
|
|
4088
4094
|
function useBody(content, message = []) {
|
|
4089
4095
|
if (content != null) return content;
|
|
4090
4096
|
if (message.length === 0) return null;
|
|
4091
|
-
|
|
4097
|
+
const singleLine = message.length === 1;
|
|
4098
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: message.map((line, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: singleLine ? "leading-[24px]" : void 0, children: line }, i)) });
|
|
4092
4099
|
}
|
|
4093
4100
|
var STooltip = react.forwardRef(function STooltip2({
|
|
4094
4101
|
content,
|
|
@@ -4146,7 +4153,7 @@ var STooltip = react.forwardRef(function STooltip2({
|
|
|
4146
4153
|
if (disabled || body == null) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: triggerNode });
|
|
4147
4154
|
const isHover = trigger === "hover";
|
|
4148
4155
|
const contentClass = cn(
|
|
4149
|
-
"z-50 max-w-xs rounded-[6px] px-[16px] py-[12px] text-[12px] leading-[20px]",
|
|
4156
|
+
"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)]",
|
|
4150
4157
|
FLOATING_SLIDE_ANIM,
|
|
4151
4158
|
className
|
|
4152
4159
|
);
|
|
@@ -4191,11 +4198,17 @@ var STooltip = react.forwardRef(function STooltip2({
|
|
|
4191
4198
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-[12px]", children: [
|
|
4192
4199
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children: body }),
|
|
4193
4200
|
useClose && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4194
|
-
|
|
4201
|
+
SGhostButton,
|
|
4195
4202
|
{
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4203
|
+
icon: "close",
|
|
4204
|
+
size: "xs",
|
|
4205
|
+
intent: tooltipType === "default" ? "inverse" : "default",
|
|
4206
|
+
ariaLabel: "\uB2EB\uAE30",
|
|
4207
|
+
className: "shrink-0",
|
|
4208
|
+
onClick: () => {
|
|
4209
|
+
cancelHide();
|
|
4210
|
+
setOpen(false);
|
|
4211
|
+
}
|
|
4199
4212
|
}
|
|
4200
4213
|
)
|
|
4201
4214
|
] }),
|
|
@@ -4760,7 +4773,7 @@ function SActionModal({
|
|
|
4760
4773
|
showClose: true,
|
|
4761
4774
|
width,
|
|
4762
4775
|
height,
|
|
4763
|
-
className: "w-fit min-w-[480px]",
|
|
4776
|
+
className: "w-fit min-w-[480px] min-h-[320px]",
|
|
4764
4777
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full min-h-[320px] flex-col", children: [
|
|
4765
4778
|
/* @__PURE__ */ jsxRuntime.jsx("header", { className: "flex flex-shrink-0 items-center gap-[var(--cmp-overlay-header-gap)] py-[var(--cmp-overlay-header-paddingY)] pl-[var(--cmp-overlay-header-paddingX)] pr-[calc(var(--cmp-overlay-header-paddingX)+20px)]", children: /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-[16px] font-bold leading-[26px] text-[color:var(--cmp-overlay-header-title-color)]", children: modalTitle }) }),
|
|
4766
4779
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1 overflow-auto px-[var(--cmp-modal-action-body-paddingX)] pb-[var(--cmp-modal-action-body-paddingBottom)]", children }),
|
|
@@ -4792,7 +4805,7 @@ function SActionModal({
|
|
|
4792
4805
|
);
|
|
4793
4806
|
}
|
|
4794
4807
|
var DEFAULT_MESSAGE = {
|
|
4795
|
-
loading: "",
|
|
4808
|
+
loading: "\uC791\uC5C5 \uC9C4\uD589\uC911...",
|
|
4796
4809
|
error: "\uC791\uC5C5\uC5D0 \uC2E4\uD328\uD558\uC600\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2DC\uB3C4\uD574 \uC8FC\uC138\uC694."
|
|
4797
4810
|
};
|
|
4798
4811
|
var DEFAULT_BUTTON_LABEL = {
|
|
@@ -4814,6 +4827,7 @@ function SLoadingModal({
|
|
|
4814
4827
|
}) {
|
|
4815
4828
|
const resolvedMessage = message ?? DEFAULT_MESSAGE[state2];
|
|
4816
4829
|
const lines = Array.isArray(resolvedMessage) ? resolvedMessage : resolvedMessage ? [resolvedMessage] : [];
|
|
4830
|
+
const showButton = useButton || state2 === "error";
|
|
4817
4831
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4818
4832
|
SModalContainer,
|
|
4819
4833
|
{
|
|
@@ -4833,7 +4847,7 @@ function SLoadingModal({
|
|
|
4833
4847
|
},
|
|
4834
4848
|
i
|
|
4835
4849
|
)) }),
|
|
4836
|
-
|
|
4850
|
+
showButton && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4837
4851
|
SButton,
|
|
4838
4852
|
{
|
|
4839
4853
|
color: "neutral",
|
|
@@ -5064,7 +5078,7 @@ function SPagination({
|
|
|
5064
5078
|
style,
|
|
5065
5079
|
children: [
|
|
5066
5080
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-[calc(var(--cmp-pagination-height)*2+var(--cmp-pagination-move-gap))] items-center justify-end gap-[var(--cmp-pagination-move-gap)]", children: prevButtons }),
|
|
5067
|
-
simple ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-[var(--cmp-pagination-height)] items-center gap-[var(--cmp-pagination-
|
|
5081
|
+
simple ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-[var(--cmp-pagination-height)] items-center gap-[var(--cmp-pagination-simple-gap)] px-[var(--cmp-pagination-paddingX)] text-[12px] font-medium leading-[20px] text-[color:var(--cmp-pagination-item-content-default)]", children: [
|
|
5068
5082
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-bold text-[color:var(--cmp-pagination-item-content-selected)]", children: currentPage }),
|
|
5069
5083
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "/" }),
|
|
5070
5084
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: lastPage })
|
|
@@ -5188,8 +5202,8 @@ function useFormField(field) {
|
|
|
5188
5202
|
}, [ctx, name]);
|
|
5189
5203
|
}
|
|
5190
5204
|
var FIELD_SIZE = {
|
|
5191
|
-
sm: { height: 28, radius: 4, fieldGap: 12, labelGap: 6, fontSize: 12, lineHeight: 20, icon:
|
|
5192
|
-
md: { height: 36, radius: 6, fieldGap: 16, labelGap: 8, fontSize: 14, lineHeight: 24, icon:
|
|
5205
|
+
sm: { height: 28, radius: 4, fieldGap: 12, labelGap: 6, fontSize: 12, lineHeight: 20, icon: 16 },
|
|
5206
|
+
md: { height: 36, radius: 6, fieldGap: 16, labelGap: 8, fontSize: 14, lineHeight: 24, icon: 16 }
|
|
5193
5207
|
};
|
|
5194
5208
|
var ALIGN = {
|
|
5195
5209
|
start: "flex-start",
|
|
@@ -5204,6 +5218,7 @@ var SField = react.forwardRef(function SField2({
|
|
|
5204
5218
|
labelTooltip = "",
|
|
5205
5219
|
labelTooltipProps,
|
|
5206
5220
|
labelWidth,
|
|
5221
|
+
labelHeight,
|
|
5207
5222
|
size = "sm",
|
|
5208
5223
|
addonLabel = "",
|
|
5209
5224
|
addonAlign = "start",
|
|
@@ -5218,6 +5233,7 @@ var SField = react.forwardRef(function SField2({
|
|
|
5218
5233
|
readOnly = false,
|
|
5219
5234
|
width,
|
|
5220
5235
|
multiline = false,
|
|
5236
|
+
borderless = false,
|
|
5221
5237
|
children,
|
|
5222
5238
|
className,
|
|
5223
5239
|
style,
|
|
@@ -5251,8 +5267,8 @@ var SField = react.forwardRef(function SField2({
|
|
|
5251
5267
|
const resolvedSuccess = status === "pass";
|
|
5252
5268
|
const showError = resolvedError && errorMessage !== "";
|
|
5253
5269
|
const interactive = !disabled && !readOnly;
|
|
5254
|
-
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)";
|
|
5255
|
-
const bgColor = disabled ? "var(--color-grey-30)" : readOnly ? "var(--sys-color-field-bg-readOnly)" : "var(--sys-color-field-bg-default)";
|
|
5270
|
+
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)";
|
|
5271
|
+
const bgColor = borderless ? "transparent" : disabled ? "var(--color-grey-30)" : readOnly ? "var(--sys-color-field-bg-readOnly)" : "var(--sys-color-field-bg-default)";
|
|
5256
5272
|
const textColor = disabled ? "var(--color-grey-65)" : readOnly ? "var(--sys-color-field-text-readOnly)" : "var(--sys-color-field-text-default)";
|
|
5257
5273
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5258
5274
|
"div",
|
|
@@ -5269,7 +5285,7 @@ var SField = react.forwardRef(function SField2({
|
|
|
5269
5285
|
{
|
|
5270
5286
|
className: "flex shrink-0 items-center font-bold text-(--sys-color-field-text-default)",
|
|
5271
5287
|
style: {
|
|
5272
|
-
height: s.height,
|
|
5288
|
+
height: cssLen(labelHeight) ?? s.height,
|
|
5273
5289
|
marginRight: s.fieldGap,
|
|
5274
5290
|
width: cssLen(labelWidth),
|
|
5275
5291
|
fontSize: s.fontSize,
|
|
@@ -5295,14 +5311,14 @@ var SField = react.forwardRef(function SField2({
|
|
|
5295
5311
|
{
|
|
5296
5312
|
className: cn(
|
|
5297
5313
|
"relative box-border flex min-w-0 items-stretch overflow-hidden border border-solid border-(--field-bc)",
|
|
5298
|
-
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]",
|
|
5314
|
+
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]",
|
|
5299
5315
|
disabled && "cursor-not-allowed"
|
|
5300
5316
|
),
|
|
5301
5317
|
style: {
|
|
5302
5318
|
// @ts-expect-error CSS 변수
|
|
5303
5319
|
"--field-bc": borderColor,
|
|
5304
5320
|
// focused/hovered prop이 명시된 경우 강조를 즉시 반영
|
|
5305
|
-
...interactive && focused ? { boxShadow: "0px 0px 4px 0px #0071ff66" } : {},
|
|
5321
|
+
...interactive && !borderless && focused ? { boxShadow: "0px 0px 4px 0px #0071ff66" } : {},
|
|
5306
5322
|
...multiline ? { minHeight: s.height } : { height: s.height },
|
|
5307
5323
|
"width": cssLen(width),
|
|
5308
5324
|
"borderRadius": s.radius,
|
|
@@ -5347,15 +5363,28 @@ function flattenOptions(options, depth = 1) {
|
|
|
5347
5363
|
const out = [];
|
|
5348
5364
|
for (const o of options) {
|
|
5349
5365
|
const hasChildren = Array.isArray(o.children) && o.children.length > 0;
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
|
|
5356
|
-
|
|
5357
|
-
|
|
5358
|
-
|
|
5366
|
+
if (hasChildren) {
|
|
5367
|
+
const childFlat = flattenOptions(o.children, depth + 1);
|
|
5368
|
+
const allChildrenDisabled = childFlat.every((c) => c.disabled);
|
|
5369
|
+
out.push({
|
|
5370
|
+
value: String(o.value),
|
|
5371
|
+
label: o.label,
|
|
5372
|
+
disabled: !!o.disabled || allChildrenDisabled,
|
|
5373
|
+
depth,
|
|
5374
|
+
isGroup: true,
|
|
5375
|
+
raw: o.value
|
|
5376
|
+
});
|
|
5377
|
+
out.push(...childFlat);
|
|
5378
|
+
} else {
|
|
5379
|
+
out.push({
|
|
5380
|
+
value: String(o.value),
|
|
5381
|
+
label: o.label,
|
|
5382
|
+
disabled: !!o.disabled,
|
|
5383
|
+
depth,
|
|
5384
|
+
isGroup: false,
|
|
5385
|
+
raw: o.value
|
|
5386
|
+
});
|
|
5387
|
+
}
|
|
5359
5388
|
}
|
|
5360
5389
|
return out;
|
|
5361
5390
|
}
|
|
@@ -5410,6 +5439,9 @@ var SSelect = react.forwardRef(function SSelect2({
|
|
|
5410
5439
|
);
|
|
5411
5440
|
const flat = react.useMemo(() => flattenOptions(options), [options]);
|
|
5412
5441
|
const selectable = react.useMemo(() => selectableOptions(flat), [flat]);
|
|
5442
|
+
const hasLeaf = react.useMemo(() => flat.some((o) => !o.isGroup), [flat]);
|
|
5443
|
+
const allOptionsDisabled = hasLeaf && selectable.length === 0;
|
|
5444
|
+
const effectiveDisabled = disabled || allOptionsDisabled;
|
|
5413
5445
|
const showSearch = useSearch && selectable.length >= SEARCH_THRESHOLD;
|
|
5414
5446
|
const labelByValue = react.useMemo(() => new Map(flat.map((o) => [o.value, o.label])), [flat]);
|
|
5415
5447
|
const rawByValue = react.useMemo(() => new Map(flat.map((o) => [o.value, o.raw])), [flat]);
|
|
@@ -5476,10 +5508,10 @@ var SSelect = react.forwardRef(function SSelect2({
|
|
|
5476
5508
|
Ariakit__namespace.Select,
|
|
5477
5509
|
{
|
|
5478
5510
|
ref: triggerRef,
|
|
5479
|
-
disabled,
|
|
5511
|
+
disabled: effectiveDisabled,
|
|
5480
5512
|
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",
|
|
5481
5513
|
style: {
|
|
5482
|
-
color:
|
|
5514
|
+
color: effectiveDisabled ? "var(--cmp-select-text-disabled)" : isPlaceholder ? "var(--cmp-select-icon-default)" : "var(--cmp-select-text-default)"
|
|
5483
5515
|
},
|
|
5484
5516
|
children: [
|
|
5485
5517
|
isHtmlLabel(triggerText) ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -5494,7 +5526,7 @@ var SSelect = react.forwardRef(function SSelect2({
|
|
|
5494
5526
|
{
|
|
5495
5527
|
name: "chevronDown",
|
|
5496
5528
|
size: 12,
|
|
5497
|
-
color:
|
|
5529
|
+
color: effectiveDisabled ? "var(--cmp-select-icon-disabled)" : "var(--cmp-select-icon-default)",
|
|
5498
5530
|
className: cn("shrink-0 transition-transform duration-200", open && "rotate-180")
|
|
5499
5531
|
}
|
|
5500
5532
|
)
|
|
@@ -5508,7 +5540,7 @@ var SSelect = react.forwardRef(function SSelect2({
|
|
|
5508
5540
|
portalElement: portalContainer,
|
|
5509
5541
|
gutter: 4,
|
|
5510
5542
|
sameWidth: !dropdownWidth,
|
|
5511
|
-
className: "z-50 overflow-auto rounded-[var(--cmp-listBox-radius)] bg-[var(--cmp-listBox-bg)]
|
|
5543
|
+
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",
|
|
5512
5544
|
style: {
|
|
5513
5545
|
maxHeight: dropdownHeight,
|
|
5514
5546
|
...dropdownWidth ? { width: dropdownWidth } : {},
|
|
@@ -5549,7 +5581,7 @@ var SSelect = react.forwardRef(function SSelect2({
|
|
|
5549
5581
|
),
|
|
5550
5582
|
hasItems ? /* @__PURE__ */ jsxRuntime.jsx(ItemList, { items: filtered, multi, selected, useSearch: showSearch }) : (
|
|
5551
5583
|
// 원본 sd-select-listbox__empty (표시할 항목이 없을 때)
|
|
5552
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-[12px] py-[12px] text-
|
|
5584
|
+
/* @__PURE__ */ jsxRuntime.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." })
|
|
5553
5585
|
)
|
|
5554
5586
|
]
|
|
5555
5587
|
}
|
|
@@ -5572,7 +5604,7 @@ var SSelect = react.forwardRef(function SSelect2({
|
|
|
5572
5604
|
error: error || ruleError !== "",
|
|
5573
5605
|
status: rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0,
|
|
5574
5606
|
errorMessage: ruleError !== "" ? ruleError : errorMessage,
|
|
5575
|
-
disabled,
|
|
5607
|
+
disabled: effectiveDisabled,
|
|
5576
5608
|
width,
|
|
5577
5609
|
className,
|
|
5578
5610
|
style,
|
|
@@ -5607,7 +5639,11 @@ function ItemList({
|
|
|
5607
5639
|
{
|
|
5608
5640
|
className: cn(
|
|
5609
5641
|
"select-none py-[4px] pr-[12px] text-[12px] leading-[20px] text-[color:var(--cmp-listItem-content-default)]",
|
|
5610
|
-
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"
|
|
5642
|
+
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",
|
|
5643
|
+
// 하위가 전부 비활성이면(select.config 에서 bubble-up) 어미 그룹도 비활성 처리:
|
|
5644
|
+
// 텍스트는 회색(#888), depth1 그룹은 파란 배경 대신 회색(#EEE)으로 (depth2 는 #F6F6F6 유지)
|
|
5645
|
+
o.disabled && "text-[color:var(--cmp-listItem-content-disabled)]",
|
|
5646
|
+
o.disabled && isDepth1 && "bg-[var(--cmp-listItem-depth1-bg-disabled)]"
|
|
5611
5647
|
),
|
|
5612
5648
|
style: { paddingLeft: padLeft },
|
|
5613
5649
|
children: o.label
|
|
@@ -5634,15 +5670,21 @@ function ItemList({
|
|
|
5634
5670
|
"span",
|
|
5635
5671
|
{
|
|
5636
5672
|
className: cn(
|
|
5637
|
-
"flex h-[16px] w-[16px] flex-shrink-0 items-center justify-center rounded-[2px] border border-solid
|
|
5638
|
-
|
|
5673
|
+
"flex h-[16px] w-[16px] flex-shrink-0 items-center justify-center rounded-[2px] border border-solid",
|
|
5674
|
+
o.disabled ? (
|
|
5675
|
+
// 비활성: 회색 채움(#E1E1E1) + 회색 테두리(#CCCCCC)
|
|
5676
|
+
"border-[color:var(--cmp-checkbox-border-disabled)] bg-[var(--cmp-checkbox-bg-disabled)]"
|
|
5677
|
+
) : cn(
|
|
5678
|
+
"group-data-[active-item]:border-[color:var(--cmp-checkbox-checked-border-inverse)]",
|
|
5679
|
+
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"
|
|
5680
|
+
)
|
|
5639
5681
|
),
|
|
5640
5682
|
children: isSelected && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5641
5683
|
SIcon,
|
|
5642
5684
|
{
|
|
5643
5685
|
name: "checkboxCheck",
|
|
5644
5686
|
size: 12,
|
|
5645
|
-
color: "var(--cmp-checkbox-checked-icon-default)"
|
|
5687
|
+
color: o.disabled ? "var(--cmp-checkbox-checked-icon-disabled)" : "var(--cmp-checkbox-checked-icon-default)"
|
|
5646
5688
|
}
|
|
5647
5689
|
)
|
|
5648
5690
|
}
|
|
@@ -6421,8 +6463,8 @@ var STextarea = react.forwardRef(function STextarea2({
|
|
|
6421
6463
|
);
|
|
6422
6464
|
});
|
|
6423
6465
|
var PAD2 = {
|
|
6424
|
-
sm: { fontSize: 12, stepper: 20, icon: 12 },
|
|
6425
|
-
md: { fontSize: 14, stepper: 24, icon: 14 }
|
|
6466
|
+
sm: { fontSize: 12, lineHeight: 20, stepper: 20, icon: 12 },
|
|
6467
|
+
md: { fontSize: 14, lineHeight: 24, stepper: 24, icon: 14 }
|
|
6426
6468
|
};
|
|
6427
6469
|
var toNumber = (val) => {
|
|
6428
6470
|
if (val === null || val === void 0 || val === "") return null;
|
|
@@ -6440,6 +6482,38 @@ var formatWithCommas = (value) => {
|
|
|
6440
6482
|
const result = isNeg ? "-" + formatted : formatted;
|
|
6441
6483
|
return decPart !== void 0 && decPart !== "" ? result + "." + decPart : result;
|
|
6442
6484
|
};
|
|
6485
|
+
var addCommas = (value) => value.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
6486
|
+
var formatInputWithCommas = (value) => {
|
|
6487
|
+
const isNeg = value.startsWith("-");
|
|
6488
|
+
const unsigned = isNeg ? value.slice(1) : value;
|
|
6489
|
+
const hasDecimal = unsigned.includes(".");
|
|
6490
|
+
const [intPart = "", decPart = ""] = unsigned.split(".");
|
|
6491
|
+
const formattedInt = addCommas(intPart === "" ? "0" : intPart);
|
|
6492
|
+
return `${isNeg ? "-" : ""}${formattedInt}${hasDecimal ? `.${decPart}` : ""}`;
|
|
6493
|
+
};
|
|
6494
|
+
var getDecimalLimit = (useDecimal, maxDecimalLength) => {
|
|
6495
|
+
if (!useDecimal || maxDecimalLength === void 0 || !Number.isFinite(maxDecimalLength)) {
|
|
6496
|
+
return void 0;
|
|
6497
|
+
}
|
|
6498
|
+
return Math.max(0, Math.floor(maxDecimalLength));
|
|
6499
|
+
};
|
|
6500
|
+
var applyDecimalLimit = (value, decimalLimit) => {
|
|
6501
|
+
if (value === null || decimalLimit === void 0) return value;
|
|
6502
|
+
return Number(value.toFixed(decimalLimit));
|
|
6503
|
+
};
|
|
6504
|
+
var getLogicalCaret = (value, caret) => {
|
|
6505
|
+
return value.slice(0, caret ?? value.length).replace(/,/g, "").length;
|
|
6506
|
+
};
|
|
6507
|
+
var getDisplayCaret = (value, logicalCaret) => {
|
|
6508
|
+
if (logicalCaret <= 0) return 0;
|
|
6509
|
+
let seen = 0;
|
|
6510
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
6511
|
+
if (value[i] === ",") continue;
|
|
6512
|
+
seen += 1;
|
|
6513
|
+
if (seen >= logicalCaret) return i + 1;
|
|
6514
|
+
}
|
|
6515
|
+
return value.length;
|
|
6516
|
+
};
|
|
6443
6517
|
var SNumberInput = react.forwardRef(function SNumberInput2({
|
|
6444
6518
|
value,
|
|
6445
6519
|
onValueChange,
|
|
@@ -6449,6 +6523,7 @@ var SNumberInput = react.forwardRef(function SNumberInput2({
|
|
|
6449
6523
|
step = 1,
|
|
6450
6524
|
useButton = false,
|
|
6451
6525
|
useDecimal = false,
|
|
6526
|
+
maxDecimalLength,
|
|
6452
6527
|
inputPrefix = "",
|
|
6453
6528
|
inputSuffix = "",
|
|
6454
6529
|
inputClass,
|
|
@@ -6480,7 +6555,8 @@ var SNumberInput = react.forwardRef(function SNumberInput2({
|
|
|
6480
6555
|
}, ref) {
|
|
6481
6556
|
const p = PAD2[size];
|
|
6482
6557
|
const padX = `var(--cmp-numberInput-${size}-paddingX)`;
|
|
6483
|
-
const
|
|
6558
|
+
const decimalLimit = getDecimalLimit(useDecimal, maxDecimalLength);
|
|
6559
|
+
const numValue = applyDecimalLimit(toNumber(value), decimalLimit);
|
|
6484
6560
|
const [display, setDisplay] = react.useState(() => formatWithCommas(numValue));
|
|
6485
6561
|
const [ruleError, setRuleError] = react.useState("");
|
|
6486
6562
|
const innerRef = react.useRef(null);
|
|
@@ -6490,8 +6566,9 @@ var SNumberInput = react.forwardRef(function SNumberInput2({
|
|
|
6490
6566
|
else if (ref) ref.current = el;
|
|
6491
6567
|
};
|
|
6492
6568
|
react.useEffect(() => {
|
|
6493
|
-
|
|
6494
|
-
|
|
6569
|
+
if (document.activeElement === innerRef.current) return;
|
|
6570
|
+
setDisplay(formatWithCommas(applyDecimalLimit(toNumber(value), decimalLimit)));
|
|
6571
|
+
}, [decimalLimit, value]);
|
|
6495
6572
|
useFormField({
|
|
6496
6573
|
name,
|
|
6497
6574
|
validate: () => {
|
|
@@ -6503,48 +6580,87 @@ var SNumberInput = react.forwardRef(function SNumberInput2({
|
|
|
6503
6580
|
});
|
|
6504
6581
|
const resolvedError = error || ruleError !== "";
|
|
6505
6582
|
const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
|
|
6506
|
-
const
|
|
6507
|
-
|
|
6508
|
-
|
|
6583
|
+
const restoreCaret = (nextDisplay, logicalCaret) => {
|
|
6584
|
+
const input = innerRef.current;
|
|
6585
|
+
if (logicalCaret === void 0 || !input || document.activeElement !== input) return;
|
|
6586
|
+
const nextCaret = getDisplayCaret(nextDisplay, logicalCaret);
|
|
6587
|
+
requestAnimationFrame(() => {
|
|
6588
|
+
if (document.activeElement !== input) return;
|
|
6589
|
+
input.setSelectionRange(nextCaret, nextCaret);
|
|
6590
|
+
});
|
|
6591
|
+
};
|
|
6592
|
+
const setDisplayWithCaret = (nextDisplay, logicalCaret) => {
|
|
6593
|
+
setDisplay(nextDisplay);
|
|
6594
|
+
restoreCaret(nextDisplay, logicalCaret);
|
|
6595
|
+
};
|
|
6596
|
+
const resetRejectedInput = (target, logicalCaret) => {
|
|
6597
|
+
target.value = display;
|
|
6598
|
+
restoreCaret(display, Math.min(logicalCaret, display.replace(/,/g, "").length));
|
|
6599
|
+
};
|
|
6600
|
+
const emit2 = (n, logicalCaret) => {
|
|
6601
|
+
const next = applyDecimalLimit(n, decimalLimit);
|
|
6602
|
+
const nextDisplay = formatWithCommas(next);
|
|
6603
|
+
setDisplayWithCaret(nextDisplay, logicalCaret);
|
|
6604
|
+
onValueChange?.(next);
|
|
6509
6605
|
};
|
|
6510
6606
|
const incDisabled = disabled || readOnly || numValue !== null && numValue >= max;
|
|
6511
6607
|
const decDisabled = disabled || readOnly || numValue !== null && numValue <= min;
|
|
6512
6608
|
const increment = () => {
|
|
6513
6609
|
if (incDisabled) return;
|
|
6514
6610
|
const cur = numValue ?? (min === Number.NEGATIVE_INFINITY ? 0 : min);
|
|
6515
|
-
const next = Math.min(cur + step, max);
|
|
6611
|
+
const next = applyDecimalLimit(Math.min(cur + step, max), decimalLimit);
|
|
6516
6612
|
if (next !== cur) emit2(next);
|
|
6517
6613
|
};
|
|
6518
6614
|
const decrement = () => {
|
|
6519
6615
|
if (decDisabled) return;
|
|
6520
6616
|
const cur = numValue ?? (min === Number.NEGATIVE_INFINITY ? 0 : min);
|
|
6521
|
-
const next = Math.max(cur - step, min);
|
|
6617
|
+
const next = applyDecimalLimit(Math.max(cur - step, min), decimalLimit);
|
|
6522
6618
|
if (next !== cur) emit2(next);
|
|
6523
6619
|
};
|
|
6524
|
-
const handleInput = (
|
|
6620
|
+
const handleInput = (event) => {
|
|
6621
|
+
const target = event.currentTarget;
|
|
6622
|
+
const raw = target.value;
|
|
6623
|
+
const logicalCaret = getLogicalCaret(raw, target.selectionStart);
|
|
6525
6624
|
if (raw === "") {
|
|
6526
|
-
|
|
6625
|
+
setDisplayWithCaret("", 0);
|
|
6527
6626
|
onValueChange?.(null);
|
|
6528
6627
|
return;
|
|
6529
6628
|
}
|
|
6530
6629
|
const cleaned = raw.replace(/,/g, "");
|
|
6531
6630
|
const decimals = (cleaned.match(/\./g) || []).length;
|
|
6532
|
-
if (decimals > 1)
|
|
6631
|
+
if (decimals > 1) {
|
|
6632
|
+
resetRejectedInput(target, logicalCaret);
|
|
6633
|
+
return;
|
|
6634
|
+
}
|
|
6533
6635
|
if (cleaned === "-" || cleaned === "." || cleaned === "-.") {
|
|
6534
|
-
|
|
6636
|
+
setDisplayWithCaret(cleaned, logicalCaret);
|
|
6637
|
+
return;
|
|
6638
|
+
}
|
|
6639
|
+
if (!useDecimal && cleaned.includes(".")) {
|
|
6640
|
+
resetRejectedInput(target, logicalCaret);
|
|
6535
6641
|
return;
|
|
6536
6642
|
}
|
|
6537
|
-
if (
|
|
6643
|
+
if (decimalLimit !== void 0 && cleaned.includes(".")) {
|
|
6644
|
+
const fraction = cleaned.split(".")[1] ?? "";
|
|
6645
|
+
if (fraction.length > decimalLimit) {
|
|
6646
|
+
resetRejectedInput(target, logicalCaret);
|
|
6647
|
+
return;
|
|
6648
|
+
}
|
|
6649
|
+
}
|
|
6538
6650
|
if (cleaned.endsWith(".") && decimals === 1) {
|
|
6539
6651
|
const parsed2 = toNumber(cleaned.slice(0, -1));
|
|
6540
6652
|
if (parsed2 !== null) {
|
|
6541
|
-
|
|
6653
|
+
setDisplayWithCaret(formatInputWithCommas(cleaned), logicalCaret);
|
|
6542
6654
|
return;
|
|
6543
6655
|
}
|
|
6544
6656
|
}
|
|
6545
6657
|
const parsed = toNumber(cleaned);
|
|
6546
|
-
if (parsed === null)
|
|
6547
|
-
|
|
6658
|
+
if (parsed === null) {
|
|
6659
|
+
resetRejectedInput(target, logicalCaret);
|
|
6660
|
+
return;
|
|
6661
|
+
}
|
|
6662
|
+
setDisplayWithCaret(formatInputWithCommas(cleaned), logicalCaret);
|
|
6663
|
+
onValueChange?.(applyDecimalLimit(parsed, decimalLimit));
|
|
6548
6664
|
};
|
|
6549
6665
|
const stepper = (dir) => {
|
|
6550
6666
|
const off = dir === "inc" ? incDisabled : decDisabled;
|
|
@@ -6557,8 +6673,8 @@ var SNumberInput = react.forwardRef(function SNumberInput2({
|
|
|
6557
6673
|
"aria-label": dir === "inc" ? "\uC99D\uAC00" : "\uAC10\uC18C",
|
|
6558
6674
|
onClick: dir === "inc" ? increment : decrement,
|
|
6559
6675
|
className: cn(
|
|
6560
|
-
"flex flex-shrink-0 items-center justify-center",
|
|
6561
|
-
off ? "cursor-not-allowed" : "cursor-pointer"
|
|
6676
|
+
"flex flex-shrink-0 items-center justify-center border border-solid border-transparent transition-colors",
|
|
6677
|
+
off ? "cursor-not-allowed" : "cursor-pointer hover:border-[var(--color-border-accentLight)]"
|
|
6562
6678
|
),
|
|
6563
6679
|
style: {
|
|
6564
6680
|
width: `var(--cmp-numberInput-stepper-${size}-size)`,
|
|
@@ -6607,24 +6723,26 @@ var SNumberInput = react.forwardRef(function SNumberInput2({
|
|
|
6607
6723
|
style: {
|
|
6608
6724
|
// 원본 sd-number-input: content gap = padding-x 토큰 (gap 토큰 아님)
|
|
6609
6725
|
gap: `var(--cmp-numberInput-${size}-paddingX)`,
|
|
6610
|
-
padding: `0 ${useButton ? padX : `calc(${padX} * 2)`}
|
|
6726
|
+
padding: `0 ${useButton ? padX : `calc(${padX} * 2)`}`,
|
|
6727
|
+
fontSize: p.fontSize,
|
|
6728
|
+
lineHeight: `${p.lineHeight}px`
|
|
6611
6729
|
},
|
|
6612
6730
|
children: [
|
|
6613
6731
|
useButton && stepper("dec"),
|
|
6614
|
-
inputPrefix !== "" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", style: {
|
|
6732
|
+
inputPrefix !== "" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", style: { color: affixColor }, children: inputPrefix }),
|
|
6615
6733
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6616
6734
|
"input",
|
|
6617
6735
|
{
|
|
6618
6736
|
ref: setRefs,
|
|
6619
6737
|
name,
|
|
6620
6738
|
type: "text",
|
|
6621
|
-
inputMode: "numeric",
|
|
6739
|
+
inputMode: useDecimal ? "decimal" : "numeric",
|
|
6622
6740
|
value: display,
|
|
6623
6741
|
placeholder,
|
|
6624
6742
|
disabled,
|
|
6625
6743
|
readOnly,
|
|
6626
6744
|
autoFocus,
|
|
6627
|
-
onChange:
|
|
6745
|
+
onChange: handleInput,
|
|
6628
6746
|
onKeyDown: (e) => {
|
|
6629
6747
|
if (e.key === "ArrowUp") {
|
|
6630
6748
|
e.preventDefault();
|
|
@@ -6636,26 +6754,29 @@ var SNumberInput = react.forwardRef(function SNumberInput2({
|
|
|
6636
6754
|
},
|
|
6637
6755
|
onFocus: (e) => onFocus?.(e),
|
|
6638
6756
|
onBlur: (e) => {
|
|
6639
|
-
const
|
|
6757
|
+
const cleaned = display.replace(/,/g, "");
|
|
6758
|
+
const n = toNumber(cleaned);
|
|
6640
6759
|
const clamped = n === null ? null : Math.min(Math.max(n, min), max);
|
|
6641
6760
|
if (clamped !== n) emit2(clamped);
|
|
6642
|
-
else setDisplay(
|
|
6761
|
+
else setDisplay(n === null ? "" : formatInputWithCommas(cleaned));
|
|
6643
6762
|
if (rules && rules.length > 0) setRuleError(runRules(clamped, rules));
|
|
6644
6763
|
onBlur?.(e);
|
|
6645
6764
|
},
|
|
6646
6765
|
className: cn(
|
|
6647
|
-
|
|
6766
|
+
// h-full 대신 라인박스 높이 그대로 두어 prefix/suffix 와 동일하게 flex 로 수직 센터링
|
|
6767
|
+
// (h-full 이면 input 내부 텍스트 센터링을 브라우저가 수행해 1px 어긋날 수 있음)
|
|
6768
|
+
"min-w-0 flex-1 border-0 bg-transparent p-0 outline-none placeholder:text-[color:var(--cmp-numberInput-text-placeholder)] disabled:cursor-not-allowed",
|
|
6648
6769
|
inputClass
|
|
6649
6770
|
),
|
|
6650
6771
|
style: {
|
|
6651
|
-
fontSize
|
|
6772
|
+
// fontSize/lineHeight 는 컨테이너에서 상속
|
|
6652
6773
|
textAlign: useButton ? "center" : "right",
|
|
6653
6774
|
color: disabled ? "var(--cmp-numberInput-text-disabled)" : "var(--cmp-numberInput-text-default)",
|
|
6654
6775
|
...inputStyle
|
|
6655
6776
|
}
|
|
6656
6777
|
}
|
|
6657
6778
|
),
|
|
6658
|
-
inputSuffix !== "" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", style: {
|
|
6779
|
+
inputSuffix !== "" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", style: { color: affixColor }, children: inputSuffix }),
|
|
6659
6780
|
useButton && stepper("inc")
|
|
6660
6781
|
]
|
|
6661
6782
|
}
|
|
@@ -6981,7 +7102,7 @@ function SCalendar({
|
|
|
6981
7102
|
"span",
|
|
6982
7103
|
{
|
|
6983
7104
|
className: cn(
|
|
6984
|
-
"flex h-[var(--cmp-datepicker-calendar-day-circle-size)] w-[var(--cmp-datepicker-calendar-day-circle-size)] items-center justify-center rounded-[var(--cmp-datepicker-calendar-day-circle-radius)] border border-solid border-transparent text-[14px]",
|
|
7105
|
+
"flex h-[var(--cmp-datepicker-calendar-day-circle-size)] w-[var(--cmp-datepicker-calendar-day-circle-size)] items-center justify-center rounded-[var(--cmp-datepicker-calendar-day-circle-radius)] border border-solid border-transparent text-[14px] leading-[var(--cmp-datepicker-calendar-day-circle-size)]",
|
|
6985
7106
|
selected ? "bg-[var(--cmp-datepicker-calendar-day-select-bg)] text-[color:var(--cmp-datepicker-calendar-day-select-text)]" : disabled ? "text-[color:var(--cmp-datepicker-calendar-day-disabled-text)]" : "text-[color:var(--cmp-datepicker-calendar-day-default-text)] hover:border-[color:var(--cmp-datepicker-calendar-day-hover-border)]",
|
|
6986
7107
|
isToday && !disabled && "font-bold"
|
|
6987
7108
|
),
|
|
@@ -7171,6 +7292,7 @@ function RangeCalendar({
|
|
|
7171
7292
|
selectable,
|
|
7172
7293
|
maxRange,
|
|
7173
7294
|
onSelect,
|
|
7295
|
+
onPendingStartChange,
|
|
7174
7296
|
onViewChange
|
|
7175
7297
|
}) {
|
|
7176
7298
|
const today = todayStr();
|
|
@@ -7233,9 +7355,11 @@ function RangeCalendar({
|
|
|
7233
7355
|
setStart(d);
|
|
7234
7356
|
setEnd(null);
|
|
7235
7357
|
setHover(null);
|
|
7358
|
+
onPendingStartChange?.(d);
|
|
7236
7359
|
return;
|
|
7237
7360
|
}
|
|
7238
7361
|
setEnd(d);
|
|
7362
|
+
onPendingStartChange?.(null);
|
|
7239
7363
|
onSelect([start, d]);
|
|
7240
7364
|
};
|
|
7241
7365
|
const GRID_COLS = "grid grid-cols-[repeat(7,var(--cmp-datepicker-calendar-day-width))]";
|
|
@@ -7370,8 +7494,11 @@ function SDateRangePicker({
|
|
|
7370
7494
|
const portalContainer = usePortalContainer();
|
|
7371
7495
|
const [open, setOpen] = react.useState(false);
|
|
7372
7496
|
const [ruleError, setRuleError] = react.useState("");
|
|
7497
|
+
const [pendingStart, setPendingStart] = react.useState(null);
|
|
7373
7498
|
const hasValue = value != null && value[0] !== "" && value[1] !== "";
|
|
7374
|
-
const
|
|
7499
|
+
const hasDisplay = pendingStart != null || hasValue;
|
|
7500
|
+
const startText = pendingStart ?? (hasValue ? value[0] : "");
|
|
7501
|
+
const endText = pendingStart ? "" : hasValue ? value[1] : "";
|
|
7375
7502
|
useFormField({
|
|
7376
7503
|
name,
|
|
7377
7504
|
validate: () => {
|
|
@@ -7385,6 +7512,7 @@ function SDateRangePicker({
|
|
|
7385
7512
|
const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
|
|
7386
7513
|
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 };
|
|
7387
7514
|
const select = (r) => {
|
|
7515
|
+
setPendingStart(null);
|
|
7388
7516
|
onValueChange?.(r);
|
|
7389
7517
|
if (rules && rules.length > 0) setRuleError(runRules(r, rules));
|
|
7390
7518
|
setOpen(false);
|
|
@@ -7409,61 +7537,80 @@ function SDateRangePicker({
|
|
|
7409
7537
|
disabled,
|
|
7410
7538
|
className,
|
|
7411
7539
|
style,
|
|
7412
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7418
|
-
|
|
7419
|
-
|
|
7420
|
-
|
|
7421
|
-
|
|
7422
|
-
|
|
7423
|
-
|
|
7424
|
-
{
|
|
7425
|
-
name: "date",
|
|
7426
|
-
size: dims.icon,
|
|
7427
|
-
color: disabled ? "var(--cmp-datepicker-icon-disabled)" : "var(--cmp-datepicker-icon-default)",
|
|
7428
|
-
className: "flex-shrink-0"
|
|
7429
|
-
}
|
|
7430
|
-
),
|
|
7431
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7432
|
-
"span",
|
|
7433
|
-
{
|
|
7434
|
-
className: "flex-1 truncate text-center",
|
|
7435
|
-
style: {
|
|
7436
|
-
minWidth: dims.minW,
|
|
7437
|
-
fontSize: dims.fontSize,
|
|
7438
|
-
lineHeight: `${dims.lineHeight}px`,
|
|
7439
|
-
color: disabled ? "var(--cmp-datepicker-text-disabled)" : hasValue ? "var(--cmp-datepicker-text-default)" : "var(--cmp-field-hint-color)"
|
|
7440
|
-
},
|
|
7441
|
-
children: display
|
|
7442
|
-
}
|
|
7443
|
-
)
|
|
7444
|
-
]
|
|
7445
|
-
}
|
|
7446
|
-
) }),
|
|
7447
|
-
/* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7448
|
-
RPopover2__namespace.Content,
|
|
7449
|
-
{
|
|
7450
|
-
side: "bottom",
|
|
7451
|
-
align: "start",
|
|
7452
|
-
sideOffset: 4,
|
|
7453
|
-
className: cn("z-50", FLOATING_SLIDE_ANIM),
|
|
7454
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7455
|
-
RangeCalendar,
|
|
7540
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7541
|
+
RPopover2__namespace.Root,
|
|
7542
|
+
{
|
|
7543
|
+
open,
|
|
7544
|
+
onOpenChange: (o) => {
|
|
7545
|
+
if (disabled) return;
|
|
7546
|
+
setOpen(o);
|
|
7547
|
+
if (!o) setPendingStart(null);
|
|
7548
|
+
},
|
|
7549
|
+
children: [
|
|
7550
|
+
/* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7551
|
+
"button",
|
|
7456
7552
|
{
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
|
|
7461
|
-
|
|
7553
|
+
type: "button",
|
|
7554
|
+
name,
|
|
7555
|
+
disabled,
|
|
7556
|
+
className: "flex h-full w-full items-center overflow-hidden bg-transparent outline-none disabled:cursor-not-allowed",
|
|
7557
|
+
style: { padding: `0 ${dims.padX}px`, gap: dims.gap, borderRadius: dims.radius },
|
|
7558
|
+
children: [
|
|
7559
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7560
|
+
SIcon,
|
|
7561
|
+
{
|
|
7562
|
+
name: "date",
|
|
7563
|
+
size: dims.icon,
|
|
7564
|
+
color: disabled ? "var(--cmp-datepicker-icon-disabled)" : "var(--cmp-datepicker-icon-default)",
|
|
7565
|
+
className: "flex-shrink-0"
|
|
7566
|
+
}
|
|
7567
|
+
),
|
|
7568
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7569
|
+
"span",
|
|
7570
|
+
{
|
|
7571
|
+
className: cn(
|
|
7572
|
+
"flex-1 items-center",
|
|
7573
|
+
hasDisplay ? "flex" : "block truncate text-center"
|
|
7574
|
+
),
|
|
7575
|
+
style: {
|
|
7576
|
+
minWidth: dims.minW,
|
|
7577
|
+
fontSize: dims.fontSize,
|
|
7578
|
+
lineHeight: `${dims.lineHeight}px`,
|
|
7579
|
+
color: disabled ? "var(--cmp-datepicker-text-disabled)" : hasDisplay ? "var(--cmp-datepicker-text-default)" : "var(--cmp-field-hint-color)"
|
|
7580
|
+
},
|
|
7581
|
+
children: hasDisplay ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
7582
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate text-right", children: startText }),
|
|
7583
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-[4px]", children: "~" }),
|
|
7584
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate text-left", children: endText })
|
|
7585
|
+
] }) : placeholder
|
|
7586
|
+
}
|
|
7587
|
+
)
|
|
7588
|
+
]
|
|
7462
7589
|
}
|
|
7463
|
-
)
|
|
7464
|
-
|
|
7465
|
-
|
|
7466
|
-
|
|
7590
|
+
) }),
|
|
7591
|
+
/* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7592
|
+
RPopover2__namespace.Content,
|
|
7593
|
+
{
|
|
7594
|
+
side: "bottom",
|
|
7595
|
+
align: "start",
|
|
7596
|
+
sideOffset: 4,
|
|
7597
|
+
className: cn("z-50", FLOATING_SLIDE_ANIM),
|
|
7598
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7599
|
+
RangeCalendar,
|
|
7600
|
+
{
|
|
7601
|
+
value: value ?? null,
|
|
7602
|
+
selectable,
|
|
7603
|
+
maxRange,
|
|
7604
|
+
onSelect: select,
|
|
7605
|
+
onPendingStartChange: setPendingStart,
|
|
7606
|
+
onViewChange
|
|
7607
|
+
}
|
|
7608
|
+
)
|
|
7609
|
+
}
|
|
7610
|
+
) })
|
|
7611
|
+
]
|
|
7612
|
+
}
|
|
7613
|
+
)
|
|
7467
7614
|
}
|
|
7468
7615
|
);
|
|
7469
7616
|
}
|
|
@@ -7472,7 +7619,7 @@ var SChip = react.forwardRef(function SChip2({
|
|
|
7472
7619
|
value = "",
|
|
7473
7620
|
error: errorProp = false,
|
|
7474
7621
|
disabled = false,
|
|
7475
|
-
editable =
|
|
7622
|
+
editable = false,
|
|
7476
7623
|
showRemove = true,
|
|
7477
7624
|
placeholder = "",
|
|
7478
7625
|
rules,
|
|
@@ -7625,6 +7772,7 @@ function SFilePicker({
|
|
|
7625
7772
|
hovered = false,
|
|
7626
7773
|
inline = false,
|
|
7627
7774
|
multiple = false,
|
|
7775
|
+
useMultipleListBox = false,
|
|
7628
7776
|
accept,
|
|
7629
7777
|
maxFileSize,
|
|
7630
7778
|
maxTotalSize,
|
|
@@ -7652,8 +7800,8 @@ function SFilePicker({
|
|
|
7652
7800
|
const inputRef = react.useRef(null);
|
|
7653
7801
|
const [ruleError, setRuleError] = react.useState("");
|
|
7654
7802
|
const files = multiple ? Array.isArray(value) ? value : [] : value && !Array.isArray(value) ? value : null;
|
|
7655
|
-
const
|
|
7656
|
-
const displayText =
|
|
7803
|
+
const hasFiles = multiple ? files.length > 0 : !!files;
|
|
7804
|
+
const displayText = !hasFiles ? placeholder : multiple ? files.map((f) => f.name).join(", ") : files.name;
|
|
7657
7805
|
useFormField({
|
|
7658
7806
|
name,
|
|
7659
7807
|
validate: () => {
|
|
@@ -7717,78 +7865,88 @@ function SFilePicker({
|
|
|
7717
7865
|
const padX = size === "md" ? "var(--cmp-filepicker-md-paddingX)" : "var(--cmp-filepicker-sm-paddingX)";
|
|
7718
7866
|
const iconSize = size === "md" ? 20 : 16;
|
|
7719
7867
|
const gapCls = size === "md" ? "gap-[var(--cmp-filepicker-md-gap)]" : "gap-[var(--cmp-filepicker-sm-gap)]";
|
|
7720
|
-
const
|
|
7721
|
-
|
|
7722
|
-
|
|
7723
|
-
|
|
7724
|
-
|
|
7725
|
-
|
|
7726
|
-
|
|
7727
|
-
|
|
7728
|
-
|
|
7729
|
-
|
|
7730
|
-
|
|
7731
|
-
|
|
7732
|
-
|
|
7733
|
-
|
|
7734
|
-
|
|
7735
|
-
|
|
7736
|
-
|
|
7737
|
-
|
|
7738
|
-
|
|
7739
|
-
|
|
7740
|
-
onClick: open,
|
|
7741
|
-
"aria-label": placeholder,
|
|
7742
|
-
className: cn(
|
|
7743
|
-
"flex min-w-0 flex-1 items-center bg-transparent text-left",
|
|
7744
|
-
gapCls,
|
|
7745
|
-
disabled ? "cursor-not-allowed" : "cursor-pointer"
|
|
7868
|
+
const inlinePlaceholder = inline && !disabled && !hasFiles;
|
|
7869
|
+
const content = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7870
|
+
"div",
|
|
7871
|
+
{
|
|
7872
|
+
className: cn("group/filepicker flex h-full w-full items-center", gapCls),
|
|
7873
|
+
style: { padding: inline ? 0 : `0 ${padX}` },
|
|
7874
|
+
children: [
|
|
7875
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7876
|
+
"input",
|
|
7877
|
+
{
|
|
7878
|
+
ref: inputRef,
|
|
7879
|
+
type: "file",
|
|
7880
|
+
className: "hidden",
|
|
7881
|
+
disabled,
|
|
7882
|
+
multiple,
|
|
7883
|
+
accept,
|
|
7884
|
+
name: resolvedName,
|
|
7885
|
+
onChange,
|
|
7886
|
+
"aria-label": placeholder
|
|
7887
|
+
}
|
|
7746
7888
|
),
|
|
7747
|
-
|
|
7748
|
-
|
|
7749
|
-
|
|
7750
|
-
|
|
7751
|
-
|
|
7752
|
-
|
|
7753
|
-
|
|
7754
|
-
|
|
7755
|
-
|
|
7756
|
-
|
|
7757
|
-
|
|
7758
|
-
|
|
7759
|
-
|
|
7760
|
-
|
|
7761
|
-
|
|
7762
|
-
|
|
7763
|
-
|
|
7764
|
-
|
|
7765
|
-
|
|
7766
|
-
|
|
7767
|
-
|
|
7768
|
-
|
|
7769
|
-
|
|
7770
|
-
|
|
7771
|
-
|
|
7772
|
-
|
|
7773
|
-
|
|
7774
|
-
|
|
7775
|
-
|
|
7776
|
-
|
|
7777
|
-
|
|
7778
|
-
|
|
7779
|
-
|
|
7780
|
-
|
|
7781
|
-
|
|
7782
|
-
|
|
7783
|
-
|
|
7889
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7890
|
+
"button",
|
|
7891
|
+
{
|
|
7892
|
+
type: "button",
|
|
7893
|
+
disabled,
|
|
7894
|
+
onClick: open,
|
|
7895
|
+
"aria-label": placeholder,
|
|
7896
|
+
className: cn(
|
|
7897
|
+
"flex min-w-0 flex-1 items-center bg-transparent text-left",
|
|
7898
|
+
gapCls,
|
|
7899
|
+
disabled ? "cursor-not-allowed" : "cursor-pointer"
|
|
7900
|
+
),
|
|
7901
|
+
children: [
|
|
7902
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7903
|
+
SIcon,
|
|
7904
|
+
{
|
|
7905
|
+
name: "attachFile",
|
|
7906
|
+
size: iconSize,
|
|
7907
|
+
color: disabled ? "var(--cmp-filepicker-icon-disabled)" : "var(--color-grey-65)"
|
|
7908
|
+
}
|
|
7909
|
+
),
|
|
7910
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7911
|
+
"span",
|
|
7912
|
+
{
|
|
7913
|
+
className: cn(
|
|
7914
|
+
"min-w-0 flex-1 truncate text-[12px]",
|
|
7915
|
+
inlinePlaceholder && "text-[color:var(--cmp-filepicker-text-placeholder)] transition-colors group-hover/filepicker:text-[color:var(--cmp-filepicker-text-default)]"
|
|
7916
|
+
),
|
|
7917
|
+
style: inlinePlaceholder ? void 0 : {
|
|
7918
|
+
color: disabled ? "var(--cmp-filepicker-text-disabled)" : hasFiles ? "var(--cmp-filepicker-text-default)" : "var(--cmp-filepicker-text-placeholder)"
|
|
7919
|
+
},
|
|
7920
|
+
children: displayText
|
|
7921
|
+
}
|
|
7922
|
+
)
|
|
7923
|
+
]
|
|
7924
|
+
}
|
|
7925
|
+
),
|
|
7926
|
+
!disabled && hasFiles && /* @__PURE__ */ jsxRuntime.jsx(SGhostButton, { icon: "close", size: "xxs", ariaLabel: "clear", onClick: clear })
|
|
7927
|
+
]
|
|
7928
|
+
}
|
|
7929
|
+
);
|
|
7930
|
+
const chips = multiple && files.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7931
|
+
"div",
|
|
7932
|
+
{
|
|
7933
|
+
className: cn(
|
|
7934
|
+
"mt-[8px] flex gap-[8px]",
|
|
7935
|
+
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"
|
|
7784
7936
|
),
|
|
7785
|
-
|
|
7786
|
-
|
|
7787
|
-
|
|
7937
|
+
style: useMultipleListBox ? {
|
|
7938
|
+
width: typeof width === "number" ? `${width}px` : width,
|
|
7939
|
+
// label 이 있으면 SField 입력 박스 시작 위치(labelWidth + fieldGap)에 맞춰 정렬
|
|
7940
|
+
marginLeft: label && labelWidth != null ? `calc(${typeof labelWidth === "number" ? `${labelWidth}px` : labelWidth} + var(--sys-space-field-${size}-gap))` : void 0
|
|
7941
|
+
} : void 0,
|
|
7942
|
+
children: files.map((f, i) => /* @__PURE__ */ jsxRuntime.jsx(SChip, { value: f.name, editable: false, onRemove: () => removeChip(i) }, i))
|
|
7943
|
+
}
|
|
7944
|
+
);
|
|
7788
7945
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style, children: [
|
|
7789
7946
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7790
7947
|
SField,
|
|
7791
7948
|
{
|
|
7949
|
+
borderless: inline,
|
|
7792
7950
|
label,
|
|
7793
7951
|
labelWidth,
|
|
7794
7952
|
icon,
|
|
@@ -7816,6 +7974,7 @@ function SKeyValueTable({
|
|
|
7816
7974
|
fields = [],
|
|
7817
7975
|
search = false,
|
|
7818
7976
|
radius = "default",
|
|
7977
|
+
dense = false,
|
|
7819
7978
|
onChange,
|
|
7820
7979
|
onSearch,
|
|
7821
7980
|
className,
|
|
@@ -7823,6 +7982,8 @@ function SKeyValueTable({
|
|
|
7823
7982
|
}) {
|
|
7824
7983
|
if (fields.length === 0) return null;
|
|
7825
7984
|
const emit2 = (name, value) => onChange?.({ name, value });
|
|
7985
|
+
const cellHeight = dense ? "var(--cmp-table-body-dense-height)" : "var(--cmp-table-keyValue-height)";
|
|
7986
|
+
const cellPadY = dense ? "var(--cmp-table-body-dense-paddingY)" : "var(--cmp-table-keyValue-body-paddingY)";
|
|
7826
7987
|
const renderField = (f) => {
|
|
7827
7988
|
if (f.render) return f.render;
|
|
7828
7989
|
const opt = f.options ?? {};
|
|
@@ -7903,10 +8064,15 @@ function SKeyValueTable({
|
|
|
7903
8064
|
rowSpan: f.thRowSpan && f.thRowSpan > 1 ? f.thRowSpan : void 0,
|
|
7904
8065
|
colSpan: f.thColSpan && f.thColSpan > 1 ? f.thColSpan : void 0,
|
|
7905
8066
|
className: cn(
|
|
7906
|
-
"
|
|
8067
|
+
"box-border bg-[var(--cmp-table-header-bg)] px-[var(--cmp-table-header-paddingX)] text-left align-middle",
|
|
7907
8068
|
cellBorder,
|
|
7908
8069
|
f.thClass
|
|
7909
8070
|
),
|
|
8071
|
+
style: {
|
|
8072
|
+
height: cellHeight,
|
|
8073
|
+
paddingTop: cellPadY,
|
|
8074
|
+
paddingBottom: cellPadY
|
|
8075
|
+
},
|
|
7910
8076
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full w-full items-center justify-between gap-[var(--cmp-table-header-gap)]", children: [
|
|
7911
8077
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex items-center gap-[8px]", children: [
|
|
7912
8078
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[12px] font-bold leading-[20px] text-[color:var(--sys-color-fg-primary)]", children: f.label }),
|
|
@@ -7932,10 +8098,11 @@ function SKeyValueTable({
|
|
|
7932
8098
|
rowSpan: f.tdRowSpan && f.tdRowSpan > 1 ? f.tdRowSpan : void 0,
|
|
7933
8099
|
colSpan: f.tdColSpan && f.tdColSpan > 1 ? f.tdColSpan : void 0,
|
|
7934
8100
|
className: cn(
|
|
7935
|
-
"
|
|
8101
|
+
"box-border bg-[var(--sys-color-bg-frame)] px-[var(--cmp-table-keyValue-body-paddingX-default)] align-middle",
|
|
7936
8102
|
cellBorder,
|
|
7937
8103
|
f.tdClass
|
|
7938
8104
|
),
|
|
8105
|
+
style: { height: cellHeight, paddingTop: cellPadY, paddingBottom: cellPadY },
|
|
7939
8106
|
children: renderField(f)
|
|
7940
8107
|
},
|
|
7941
8108
|
`td-${r}-${c}`
|
|
@@ -8056,9 +8223,9 @@ var POS_ANCHOR = {
|
|
|
8056
8223
|
"top-left": { top: 20, left: 20 },
|
|
8057
8224
|
"top-center": { top: 20, left: "50%" },
|
|
8058
8225
|
"top-right": { top: 20, right: 20 },
|
|
8059
|
-
"bottom-left": { bottom:
|
|
8060
|
-
"bottom-center": { bottom:
|
|
8061
|
-
"bottom-right": { bottom:
|
|
8226
|
+
"bottom-left": { bottom: 100, left: 20 },
|
|
8227
|
+
"bottom-center": { bottom: 100, left: "50%" },
|
|
8228
|
+
"bottom-right": { bottom: 100, right: 20 }
|
|
8062
8229
|
};
|
|
8063
8230
|
var counter = 0;
|
|
8064
8231
|
var SToastContainer = react.forwardRef(
|
|
@@ -8418,7 +8585,7 @@ var SChipInput = react.forwardRef(function SChipInput2({
|
|
|
8418
8585
|
disabledChips = [],
|
|
8419
8586
|
size = "sm",
|
|
8420
8587
|
disabled = false,
|
|
8421
|
-
placeholder = "\uC785\uB825\
|
|
8588
|
+
placeholder = "\uD0DC\uADF8 \uC785\uB825 (Enter\uB85C \uB4F1\uB85D / \uCF64\uB9C8\uB85C \uAD6C\uBD84 / \uB744\uC5B4\uC4F0\uAE30 \uBD88\uAC00)",
|
|
8422
8589
|
name,
|
|
8423
8590
|
rules,
|
|
8424
8591
|
error,
|
|
@@ -8569,6 +8736,7 @@ var SChipInput = react.forwardRef(function SChipInput2({
|
|
|
8569
8736
|
{
|
|
8570
8737
|
label,
|
|
8571
8738
|
labelWidth,
|
|
8739
|
+
labelHeight: `calc(var(--cmp-chipInput-${size}-minHeight) + 2px)`,
|
|
8572
8740
|
icon,
|
|
8573
8741
|
labelTooltip,
|
|
8574
8742
|
labelTooltipProps,
|
|
@@ -8639,9 +8807,11 @@ var SChipInput = react.forwardRef(function SChipInput2({
|
|
|
8639
8807
|
paddingInline: isFieldFilled ? "var(--cmp-chip-paddingX)" : void 0,
|
|
8640
8808
|
borderWidth: isFieldFilled ? "var(--cmp-chip-border-width)" : void 0,
|
|
8641
8809
|
borderStyle: isFieldFilled ? "solid" : void 0,
|
|
8642
|
-
|
|
8810
|
+
// 작성중 필드는 SChip의 editable 수정중(editing) 스타일과 동일하게 —
|
|
8811
|
+
// bg/보더/글자색 모두 focus 토큰을 사용한다.
|
|
8812
|
+
borderColor: isFieldFilled ? "var(--cmp-chip-border-focus)" : void 0,
|
|
8643
8813
|
borderRadius: isFieldFilled ? "var(--cmp-chip-radius)" : 0,
|
|
8644
|
-
background: isFieldFilled ? "var(--cmp-chip-bg-
|
|
8814
|
+
background: isFieldFilled ? "var(--cmp-chip-bg-focus)" : "transparent",
|
|
8645
8815
|
overflow: "hidden"
|
|
8646
8816
|
},
|
|
8647
8817
|
children: [
|
|
@@ -8650,7 +8820,7 @@ var SChipInput = react.forwardRef(function SChipInput2({
|
|
|
8650
8820
|
{
|
|
8651
8821
|
"aria-hidden": true,
|
|
8652
8822
|
className: cn(
|
|
8653
|
-
"invisible col-start-1 row-start-1 whitespace-pre font-
|
|
8823
|
+
"invisible col-start-1 row-start-1 whitespace-pre font-normal",
|
|
8654
8824
|
size === "md" ? "text-14 leading-24" : "text-12 leading-20"
|
|
8655
8825
|
),
|
|
8656
8826
|
children: inputValue !== "" ? inputValue : values.length === 0 ? placeholder : ""
|
|
@@ -8663,12 +8833,14 @@ var SChipInput = react.forwardRef(function SChipInput2({
|
|
|
8663
8833
|
name: resolvedName,
|
|
8664
8834
|
size: 1,
|
|
8665
8835
|
className: cn(
|
|
8666
|
-
"s-chip-input__input col-start-1 row-start-1 w-full border-0 bg-transparent p-0 font-
|
|
8836
|
+
"s-chip-input__input col-start-1 row-start-1 w-full border-0 bg-transparent p-0 font-normal text-(--cmp-chip-content-focus) outline-none placeholder:text-(--cmp-chipInput-text-placeholder) disabled:cursor-not-allowed",
|
|
8667
8837
|
size === "md" ? "text-14 leading-24" : "text-12 leading-20"
|
|
8668
8838
|
),
|
|
8669
8839
|
style: {
|
|
8670
8840
|
minWidth: "1ch",
|
|
8671
|
-
height
|
|
8841
|
+
// height는 지정하지 않고 line-height(20/24px)에 맞춰 자동 크기로 둔다.
|
|
8842
|
+
// var(--cmp-chip-height)(24px)로 고정하면 네이티브 <input>이 남는 세로 여백에
|
|
8843
|
+
// 텍스트를 아래로 밀어 넣어, 확정된 chip 텍스트보다 2px 낮게 보인다.
|
|
8672
8844
|
margin: 0,
|
|
8673
8845
|
overflow: "hidden",
|
|
8674
8846
|
textOverflow: "ellipsis"
|
|
@@ -8713,7 +8885,7 @@ var SChipInput = react.forwardRef(function SChipInput2({
|
|
|
8713
8885
|
showMetaInfo && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8714
8886
|
"div",
|
|
8715
8887
|
{
|
|
8716
|
-
className: "s-chip-input__meta flex items-center gap-8",
|
|
8888
|
+
className: "s-chip-input__meta ml-auto flex items-center gap-8",
|
|
8717
8889
|
onMouseDown: (e) => e.preventDefault(),
|
|
8718
8890
|
children: [
|
|
8719
8891
|
/* @__PURE__ */ jsxRuntime.jsx(
|