sellmate-design-system-react 0.1.8 → 0.1.10
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 +217 -208
- package/dist/components/SBarcodeInput/SBarcodeInput.cjs.map +1 -1
- package/dist/components/SBarcodeInput/SBarcodeInput.js +217 -208
- 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 +234 -220
- package/dist/components/SChipInput/SChipInput.cjs.map +1 -1
- package/dist/components/SChipInput/SChipInput.js +234 -220
- package/dist/components/SChipInput/SChipInput.js.map +1 -1
- package/dist/components/SCircleProgress/SCircleProgress.cjs +31 -14
- package/dist/components/SCircleProgress/SCircleProgress.cjs.map +1 -1
- package/dist/components/SCircleProgress/SCircleProgress.d.ts +2 -0
- package/dist/components/SCircleProgress/SCircleProgress.js +31 -14
- package/dist/components/SCircleProgress/SCircleProgress.js.map +1 -1
- package/dist/components/SDatePicker/SDatePicker.cjs +222 -213
- package/dist/components/SDatePicker/SDatePicker.cjs.map +1 -1
- package/dist/components/SDatePicker/SDatePicker.js +222 -213
- package/dist/components/SDatePicker/SDatePicker.js.map +1 -1
- package/dist/components/SDateRangePicker/SDateRangePicker.cjs +297 -262
- package/dist/components/SDateRangePicker/SDateRangePicker.cjs.map +1 -1
- package/dist/components/SDateRangePicker/SDateRangePicker.js +297 -262
- 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 +217 -20
- package/dist/components/SField/SField.cjs.map +1 -1
- package/dist/components/SField/SField.d.ts +11 -0
- package/dist/components/SField/SField.js +217 -20
- package/dist/components/SField/SField.js.map +1 -1
- package/dist/components/SFilePicker/SFilePicker.cjs +315 -276
- package/dist/components/SFilePicker/SFilePicker.cjs.map +1 -1
- package/dist/components/SFilePicker/SFilePicker.d.ts +4 -2
- package/dist/components/SFilePicker/SFilePicker.js +314 -276
- package/dist/components/SFilePicker/SFilePicker.js.map +1 -1
- package/dist/components/SInput/SInput.cjs +217 -208
- package/dist/components/SInput/SInput.cjs.map +1 -1
- package/dist/components/SInput/SInput.js +217 -208
- package/dist/components/SInput/SInput.js.map +1 -1
- package/dist/components/SKeyValueTable/SKeyValueTable.cjs +631 -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 +631 -450
- package/dist/components/SKeyValueTable/SKeyValueTable.js.map +1 -1
- package/dist/components/SLoadingContainer/SLoadingContainer.cjs +39 -14
- package/dist/components/SLoadingContainer/SLoadingContainer.cjs.map +1 -1
- package/dist/components/SLoadingContainer/SLoadingContainer.js +39 -14
- package/dist/components/SLoadingContainer/SLoadingContainer.js.map +1 -1
- package/dist/components/SLoadingContainer/loading.cjs +39 -14
- package/dist/components/SLoadingContainer/loading.cjs.map +1 -1
- package/dist/components/SLoadingContainer/loading.js +39 -14
- package/dist/components/SLoadingContainer/loading.js.map +1 -1
- package/dist/components/SLoadingModal/SLoadingModal.cjs +37 -16
- package/dist/components/SLoadingModal/SLoadingModal.cjs.map +1 -1
- package/dist/components/SLoadingModal/SLoadingModal.d.ts +3 -1
- package/dist/components/SLoadingModal/SLoadingModal.js +37 -16
- package/dist/components/SLoadingModal/SLoadingModal.js.map +1 -1
- package/dist/components/SNumberInput/SNumberInput.cjs +325 -49
- package/dist/components/SNumberInput/SNumberInput.cjs.map +1 -1
- package/dist/components/SNumberInput/SNumberInput.d.ts +2 -0
- package/dist/components/SNumberInput/SNumberInput.js +325 -49
- 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/SRadio/SRadioGroup.cjs +1 -1
- package/dist/components/SRadio/SRadioGroup.cjs.map +1 -1
- package/dist/components/SRadio/SRadioGroup.js +1 -1
- package/dist/components/SRadio/SRadioGroup.js.map +1 -1
- package/dist/components/SSelect/SSelect.cjs +71 -32
- package/dist/components/SSelect/SSelect.cjs.map +1 -1
- package/dist/components/SSelect/SSelect.js +71 -32
- package/dist/components/SSelect/SSelect.js.map +1 -1
- package/dist/components/STable/STable.cjs +108 -49
- package/dist/components/STable/STable.cjs.map +1 -1
- package/dist/components/STable/STable.js +108 -49
- package/dist/components/STable/STable.js.map +1 -1
- package/dist/components/STextarea/STextarea.cjs +217 -20
- package/dist/components/STextarea/STextarea.cjs.map +1 -1
- package/dist/components/STextarea/STextarea.js +217 -20
- 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 +208 -13
- package/dist/components/STooltip/STooltip.cjs.map +1 -1
- package/dist/components/STooltip/STooltip.js +208 -13
- package/dist/components/STooltip/STooltip.js.map +1 -1
- package/dist/index.cjs +439 -221
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +439 -221
- package/dist/index.js.map +1 -1
- package/dist/styles.css +113 -48
- package/dist/theme.css +49 -23
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3300,20 +3300,46 @@ var COLOR_MAP = {
|
|
|
3300
3300
|
};
|
|
3301
3301
|
var clamp2 = (v) => Number.isFinite(v) ? Math.max(0, Math.min(100, v)) : 0;
|
|
3302
3302
|
var SCircleProgress = forwardRef(
|
|
3303
|
-
function SCircleProgress2({
|
|
3303
|
+
function SCircleProgress2({
|
|
3304
|
+
value = 0,
|
|
3305
|
+
type = "primary",
|
|
3306
|
+
indeterminate = false,
|
|
3307
|
+
label,
|
|
3308
|
+
innerValue = false,
|
|
3309
|
+
className,
|
|
3310
|
+
style
|
|
3311
|
+
}, ref) {
|
|
3304
3312
|
const v = clamp2(value);
|
|
3305
3313
|
const colors = COLOR_MAP[type];
|
|
3306
3314
|
const c = VIEWBOX / 2;
|
|
3307
3315
|
const percentColor = v === 0 ? "var(--sys-color-fg-tertiary, #888888)" : colors.arc;
|
|
3308
3316
|
const filled = v / 100 * CIRCUMFERENCE;
|
|
3317
|
+
const showPercent = !indeterminate;
|
|
3318
|
+
const percentNode = /* @__PURE__ */ jsxs(
|
|
3319
|
+
"span",
|
|
3320
|
+
{
|
|
3321
|
+
className: cn(
|
|
3322
|
+
"text-center text-[16px] font-bold leading-[26px]",
|
|
3323
|
+
innerValue && "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2"
|
|
3324
|
+
),
|
|
3325
|
+
style: { color: percentColor },
|
|
3326
|
+
children: [
|
|
3327
|
+
Math.round(v),
|
|
3328
|
+
"%"
|
|
3329
|
+
]
|
|
3330
|
+
}
|
|
3331
|
+
);
|
|
3309
3332
|
return /* @__PURE__ */ jsxs(
|
|
3310
3333
|
"div",
|
|
3311
3334
|
{
|
|
3312
3335
|
ref,
|
|
3313
|
-
className: cn(
|
|
3336
|
+
className: cn(
|
|
3337
|
+
"inline-flex flex-col items-center gap-[var(--cmp-progress-circular-gap)]",
|
|
3338
|
+
className
|
|
3339
|
+
),
|
|
3314
3340
|
style,
|
|
3315
3341
|
children: [
|
|
3316
|
-
/* @__PURE__ */ jsxs("div", { className:
|
|
3342
|
+
/* @__PURE__ */ jsxs("div", { className: cn(innerValue && "relative"), children: [
|
|
3317
3343
|
/* @__PURE__ */ jsxs(
|
|
3318
3344
|
"svg",
|
|
3319
3345
|
{
|
|
@@ -3357,18 +3383,9 @@ var SCircleProgress = forwardRef(
|
|
|
3357
3383
|
]
|
|
3358
3384
|
}
|
|
3359
3385
|
),
|
|
3360
|
-
|
|
3361
|
-
"span",
|
|
3362
|
-
{
|
|
3363
|
-
className: "absolute inset-0 flex items-center justify-center text-[16px] font-bold leading-[26px]",
|
|
3364
|
-
style: { color: percentColor },
|
|
3365
|
-
children: [
|
|
3366
|
-
Math.round(v),
|
|
3367
|
-
"%"
|
|
3368
|
-
]
|
|
3369
|
-
}
|
|
3370
|
-
)
|
|
3386
|
+
showPercent && innerValue && percentNode
|
|
3371
3387
|
] }),
|
|
3388
|
+
showPercent && !innerValue && percentNode,
|
|
3372
3389
|
label && /* @__PURE__ */ jsx("span", { className: "text-center text-[12px] font-normal leading-[20px] text-[color:var(--cmp-progress-color-label)]", children: label })
|
|
3373
3390
|
]
|
|
3374
3391
|
}
|
|
@@ -3379,6 +3396,14 @@ var SLoadingContainer = forwardRef(
|
|
|
3379
3396
|
function SLoadingContainer2({ open = false, message, zIndex = 1200, className, style }, ref) {
|
|
3380
3397
|
const [mounted2, setMounted] = useState(false);
|
|
3381
3398
|
useEffect(() => setMounted(true), []);
|
|
3399
|
+
useEffect(() => {
|
|
3400
|
+
if (!open) return;
|
|
3401
|
+
const prev = document.body.style.overflow;
|
|
3402
|
+
document.body.style.overflow = "hidden";
|
|
3403
|
+
return () => {
|
|
3404
|
+
document.body.style.overflow = prev;
|
|
3405
|
+
};
|
|
3406
|
+
}, [open]);
|
|
3382
3407
|
const innerRef = useRef(null);
|
|
3383
3408
|
const setRef = useCallback(
|
|
3384
3409
|
(node) => {
|
|
@@ -3647,15 +3672,15 @@ var sanitizeInlineHtml = (value) => {
|
|
|
3647
3672
|
return template.innerHTML;
|
|
3648
3673
|
};
|
|
3649
3674
|
var SIZE = {
|
|
3650
|
-
xs: { height: 24, paddingX: 8, gap: 6, arrow: 12, fontSize: 12, minWidth:
|
|
3675
|
+
xs: { height: 24, paddingX: 8, gap: 6, arrow: 12, fontSize: 12, minWidth: 64, splitMinWidth: 72 },
|
|
3651
3676
|
sm: {
|
|
3652
3677
|
height: 28,
|
|
3653
3678
|
paddingX: 12,
|
|
3654
3679
|
gap: 8,
|
|
3655
3680
|
arrow: 12,
|
|
3656
3681
|
fontSize: 12,
|
|
3657
|
-
minWidth:
|
|
3658
|
-
splitMinWidth:
|
|
3682
|
+
minWidth: 72,
|
|
3683
|
+
splitMinWidth: 88
|
|
3659
3684
|
},
|
|
3660
3685
|
md: {
|
|
3661
3686
|
height: 36,
|
|
@@ -3763,7 +3788,7 @@ var SDropdownButton = forwardRef(
|
|
|
3763
3788
|
align: "start",
|
|
3764
3789
|
alignOffset: split ? splitAlignOffset : 0,
|
|
3765
3790
|
className: cn(
|
|
3766
|
-
"z-50 overflow-hidden rounded-[var(--cmp-listBox-radius)] bg-[var(--cmp-listBox-bg)]
|
|
3791
|
+
"z-50 overflow-hidden rounded-[var(--cmp-listBox-radius)] bg-[var(--cmp-listBox-bg)] shadow-normal-sm",
|
|
3767
3792
|
!split && "min-w-[var(--radix-dropdown-menu-trigger-width)]",
|
|
3768
3793
|
FLOATING_SLIDE_ANIM
|
|
3769
3794
|
),
|
|
@@ -4060,7 +4085,8 @@ var HIDE_DELAY_MS = 100;
|
|
|
4060
4085
|
function useBody(content, message = []) {
|
|
4061
4086
|
if (content != null) return content;
|
|
4062
4087
|
if (message.length === 0) return null;
|
|
4063
|
-
|
|
4088
|
+
const singleLine = message.length === 1;
|
|
4089
|
+
return /* @__PURE__ */ jsx(Fragment, { children: message.map((line, i) => /* @__PURE__ */ jsx("div", { className: singleLine ? "leading-[24px]" : void 0, children: line }, i)) });
|
|
4064
4090
|
}
|
|
4065
4091
|
var STooltip = forwardRef(function STooltip2({
|
|
4066
4092
|
content,
|
|
@@ -4163,11 +4189,17 @@ var STooltip = forwardRef(function STooltip2({
|
|
|
4163
4189
|
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-[12px]", children: [
|
|
4164
4190
|
/* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: body }),
|
|
4165
4191
|
useClose && /* @__PURE__ */ jsx(
|
|
4166
|
-
|
|
4192
|
+
SGhostButton,
|
|
4167
4193
|
{
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4194
|
+
icon: "close",
|
|
4195
|
+
size: "xs",
|
|
4196
|
+
intent: tooltipType === "default" ? "inverse" : "default",
|
|
4197
|
+
ariaLabel: "\uB2EB\uAE30",
|
|
4198
|
+
className: "shrink-0",
|
|
4199
|
+
onClick: () => {
|
|
4200
|
+
cancelHide();
|
|
4201
|
+
setOpen(false);
|
|
4202
|
+
}
|
|
4171
4203
|
}
|
|
4172
4204
|
)
|
|
4173
4205
|
] }),
|
|
@@ -4732,7 +4764,7 @@ function SActionModal({
|
|
|
4732
4764
|
showClose: true,
|
|
4733
4765
|
width,
|
|
4734
4766
|
height,
|
|
4735
|
-
className: "w-fit min-w-[480px]",
|
|
4767
|
+
className: "w-fit min-w-[480px] min-h-[320px]",
|
|
4736
4768
|
children: /* @__PURE__ */ jsxs("div", { className: "flex h-full min-h-[320px] flex-col", children: [
|
|
4737
4769
|
/* @__PURE__ */ jsx("header", { className: "flex flex-shrink-0 items-center gap-[var(--cmp-overlay-header-gap)] py-[var(--cmp-overlay-header-paddingY)] pl-[var(--cmp-overlay-header-paddingX)] pr-[calc(var(--cmp-overlay-header-paddingX)+20px)]", children: /* @__PURE__ */ jsx("h2", { className: "text-[16px] font-bold leading-[26px] text-[color:var(--cmp-overlay-header-title-color)]", children: modalTitle }) }),
|
|
4738
4770
|
/* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-auto px-[var(--cmp-modal-action-body-paddingX)] pb-[var(--cmp-modal-action-body-paddingBottom)]", children }),
|
|
@@ -4764,7 +4796,7 @@ function SActionModal({
|
|
|
4764
4796
|
);
|
|
4765
4797
|
}
|
|
4766
4798
|
var DEFAULT_MESSAGE = {
|
|
4767
|
-
loading: "",
|
|
4799
|
+
loading: "\uC791\uC5C5 \uC9C4\uD589\uC911...",
|
|
4768
4800
|
error: "\uC791\uC5C5\uC5D0 \uC2E4\uD328\uD558\uC600\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2DC\uB3C4\uD574 \uC8FC\uC138\uC694."
|
|
4769
4801
|
};
|
|
4770
4802
|
var DEFAULT_BUTTON_LABEL = {
|
|
@@ -4774,6 +4806,7 @@ var DEFAULT_BUTTON_LABEL = {
|
|
|
4774
4806
|
function SLoadingModal({
|
|
4775
4807
|
open,
|
|
4776
4808
|
onOpenChange,
|
|
4809
|
+
onClose,
|
|
4777
4810
|
persistent,
|
|
4778
4811
|
state: state2 = "loading",
|
|
4779
4812
|
progress,
|
|
@@ -4786,11 +4819,14 @@ function SLoadingModal({
|
|
|
4786
4819
|
}) {
|
|
4787
4820
|
const resolvedMessage = message ?? DEFAULT_MESSAGE[state2];
|
|
4788
4821
|
const lines = Array.isArray(resolvedMessage) ? resolvedMessage : resolvedMessage ? [resolvedMessage] : [];
|
|
4822
|
+
const showButton = useButton || state2 === "error";
|
|
4789
4823
|
return /* @__PURE__ */ jsx(
|
|
4790
4824
|
SModalContainer,
|
|
4791
4825
|
{
|
|
4792
4826
|
open,
|
|
4793
4827
|
onOpenChange,
|
|
4828
|
+
onClose,
|
|
4829
|
+
showClose: state2 === "error",
|
|
4794
4830
|
persistent,
|
|
4795
4831
|
ariaTitle: lines[0] || "\uB85C\uB529 \uC911",
|
|
4796
4832
|
width,
|
|
@@ -4805,7 +4841,7 @@ function SLoadingModal({
|
|
|
4805
4841
|
},
|
|
4806
4842
|
i
|
|
4807
4843
|
)) }),
|
|
4808
|
-
|
|
4844
|
+
showButton && /* @__PURE__ */ jsx(
|
|
4809
4845
|
SButton,
|
|
4810
4846
|
{
|
|
4811
4847
|
color: "neutral",
|
|
@@ -5036,7 +5072,7 @@ function SPagination({
|
|
|
5036
5072
|
style,
|
|
5037
5073
|
children: [
|
|
5038
5074
|
/* @__PURE__ */ jsx("div", { className: "flex min-w-[calc(var(--cmp-pagination-height)*2+var(--cmp-pagination-move-gap))] items-center justify-end gap-[var(--cmp-pagination-move-gap)]", children: prevButtons }),
|
|
5039
|
-
simple ? /* @__PURE__ */ jsxs("div", { className: "flex h-[var(--cmp-pagination-height)] items-center gap-[var(--cmp-pagination-
|
|
5075
|
+
simple ? /* @__PURE__ */ jsxs("div", { className: "flex h-[var(--cmp-pagination-height)] items-center gap-[var(--cmp-pagination-simple-gap)] px-[var(--cmp-pagination-paddingX)] text-[12px] font-medium leading-[20px] text-[color:var(--cmp-pagination-item-content-default)]", children: [
|
|
5040
5076
|
/* @__PURE__ */ jsx("span", { className: "font-bold text-[color:var(--cmp-pagination-item-content-selected)]", children: currentPage }),
|
|
5041
5077
|
/* @__PURE__ */ jsx("span", { children: "/" }),
|
|
5042
5078
|
/* @__PURE__ */ jsx("span", { children: lastPage })
|
|
@@ -5160,8 +5196,8 @@ function useFormField(field) {
|
|
|
5160
5196
|
}, [ctx, name]);
|
|
5161
5197
|
}
|
|
5162
5198
|
var FIELD_SIZE = {
|
|
5163
|
-
sm: { height: 28, radius: 4, fieldGap: 12, labelGap: 6, fontSize: 12, lineHeight: 20, icon:
|
|
5164
|
-
md: { height: 36, radius: 6, fieldGap: 16, labelGap: 8, fontSize: 14, lineHeight: 24, icon:
|
|
5199
|
+
sm: { height: 28, radius: 4, fieldGap: 12, labelGap: 6, fontSize: 12, lineHeight: 20, icon: 16 },
|
|
5200
|
+
md: { height: 36, radius: 6, fieldGap: 16, labelGap: 8, fontSize: 14, lineHeight: 24, icon: 16 }
|
|
5165
5201
|
};
|
|
5166
5202
|
var ALIGN = {
|
|
5167
5203
|
start: "flex-start",
|
|
@@ -5176,6 +5212,7 @@ var SField = forwardRef(function SField2({
|
|
|
5176
5212
|
labelTooltip = "",
|
|
5177
5213
|
labelTooltipProps,
|
|
5178
5214
|
labelWidth,
|
|
5215
|
+
labelHeight,
|
|
5179
5216
|
size = "sm",
|
|
5180
5217
|
addonLabel = "",
|
|
5181
5218
|
addonAlign = "start",
|
|
@@ -5190,6 +5227,7 @@ var SField = forwardRef(function SField2({
|
|
|
5190
5227
|
readOnly = false,
|
|
5191
5228
|
width,
|
|
5192
5229
|
multiline = false,
|
|
5230
|
+
borderless = false,
|
|
5193
5231
|
children,
|
|
5194
5232
|
className,
|
|
5195
5233
|
style,
|
|
@@ -5223,8 +5261,8 @@ var SField = forwardRef(function SField2({
|
|
|
5223
5261
|
const resolvedSuccess = status === "pass";
|
|
5224
5262
|
const showError = resolvedError && errorMessage !== "";
|
|
5225
5263
|
const interactive = !disabled && !readOnly;
|
|
5226
|
-
const borderColor = disabled ? "var(--color-grey-45)" : interactive && focused ? "var(--sys-color-field-border-focus)" : resolvedSuccess ? "var(--sys-color-field-border-success)" : resolvedError ? "var(--sys-color-field-border-danger)" : "var(--sys-color-field-border-default)";
|
|
5227
|
-
const bgColor = disabled ? "var(--color-grey-30)" : readOnly ? "var(--sys-color-field-bg-readOnly)" : "var(--sys-color-field-bg-default)";
|
|
5264
|
+
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)";
|
|
5265
|
+
const bgColor = borderless ? "transparent" : disabled ? "var(--color-grey-30)" : readOnly ? "var(--sys-color-field-bg-readOnly)" : "var(--sys-color-field-bg-default)";
|
|
5228
5266
|
const textColor = disabled ? "var(--color-grey-65)" : readOnly ? "var(--sys-color-field-text-readOnly)" : "var(--sys-color-field-text-default)";
|
|
5229
5267
|
return /* @__PURE__ */ jsx(
|
|
5230
5268
|
"div",
|
|
@@ -5241,7 +5279,7 @@ var SField = forwardRef(function SField2({
|
|
|
5241
5279
|
{
|
|
5242
5280
|
className: "flex shrink-0 items-center font-bold text-(--sys-color-field-text-default)",
|
|
5243
5281
|
style: {
|
|
5244
|
-
height: s.height,
|
|
5282
|
+
height: cssLen(labelHeight) ?? s.height,
|
|
5245
5283
|
marginRight: s.fieldGap,
|
|
5246
5284
|
width: cssLen(labelWidth),
|
|
5247
5285
|
fontSize: s.fontSize,
|
|
@@ -5267,14 +5305,14 @@ var SField = forwardRef(function SField2({
|
|
|
5267
5305
|
{
|
|
5268
5306
|
className: cn(
|
|
5269
5307
|
"relative box-border flex min-w-0 items-stretch overflow-hidden border border-solid border-(--field-bc)",
|
|
5270
|
-
interactive && "hover:border-(--sys-color-field-border-focus) hover:shadow-[0px_0px_4px_0px_#0071ff66] focus-within:border-(--sys-color-field-border-focus) focus-within:shadow-[0px_0px_4px_0px_#0071ff66]",
|
|
5308
|
+
interactive && !borderless && "hover:border-(--sys-color-field-border-focus) hover:shadow-[0px_0px_4px_0px_#0071ff66] focus-within:border-(--sys-color-field-border-focus) focus-within:shadow-[0px_0px_4px_0px_#0071ff66]",
|
|
5271
5309
|
disabled && "cursor-not-allowed"
|
|
5272
5310
|
),
|
|
5273
5311
|
style: {
|
|
5274
5312
|
// @ts-expect-error CSS 변수
|
|
5275
5313
|
"--field-bc": borderColor,
|
|
5276
5314
|
// focused/hovered prop이 명시된 경우 강조를 즉시 반영
|
|
5277
|
-
...interactive && focused ? { boxShadow: "0px 0px 4px 0px #0071ff66" } : {},
|
|
5315
|
+
...interactive && !borderless && focused ? { boxShadow: "0px 0px 4px 0px #0071ff66" } : {},
|
|
5278
5316
|
...multiline ? { minHeight: s.height } : { height: s.height },
|
|
5279
5317
|
"width": cssLen(width),
|
|
5280
5318
|
"borderRadius": s.radius,
|
|
@@ -5319,15 +5357,28 @@ function flattenOptions(options, depth = 1) {
|
|
|
5319
5357
|
const out = [];
|
|
5320
5358
|
for (const o of options) {
|
|
5321
5359
|
const hasChildren = Array.isArray(o.children) && o.children.length > 0;
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5360
|
+
if (hasChildren) {
|
|
5361
|
+
const childFlat = flattenOptions(o.children, depth + 1);
|
|
5362
|
+
const allChildrenDisabled = childFlat.every((c) => c.disabled);
|
|
5363
|
+
out.push({
|
|
5364
|
+
value: String(o.value),
|
|
5365
|
+
label: o.label,
|
|
5366
|
+
disabled: !!o.disabled || allChildrenDisabled,
|
|
5367
|
+
depth,
|
|
5368
|
+
isGroup: true,
|
|
5369
|
+
raw: o.value
|
|
5370
|
+
});
|
|
5371
|
+
out.push(...childFlat);
|
|
5372
|
+
} else {
|
|
5373
|
+
out.push({
|
|
5374
|
+
value: String(o.value),
|
|
5375
|
+
label: o.label,
|
|
5376
|
+
disabled: !!o.disabled,
|
|
5377
|
+
depth,
|
|
5378
|
+
isGroup: false,
|
|
5379
|
+
raw: o.value
|
|
5380
|
+
});
|
|
5381
|
+
}
|
|
5331
5382
|
}
|
|
5332
5383
|
return out;
|
|
5333
5384
|
}
|
|
@@ -5382,6 +5433,9 @@ var SSelect = forwardRef(function SSelect2({
|
|
|
5382
5433
|
);
|
|
5383
5434
|
const flat = useMemo(() => flattenOptions(options), [options]);
|
|
5384
5435
|
const selectable = useMemo(() => selectableOptions(flat), [flat]);
|
|
5436
|
+
const hasLeaf = useMemo(() => flat.some((o) => !o.isGroup), [flat]);
|
|
5437
|
+
const allOptionsDisabled = hasLeaf && selectable.length === 0;
|
|
5438
|
+
const effectiveDisabled = disabled || allOptionsDisabled;
|
|
5385
5439
|
const showSearch = useSearch && selectable.length >= SEARCH_THRESHOLD;
|
|
5386
5440
|
const labelByValue = useMemo(() => new Map(flat.map((o) => [o.value, o.label])), [flat]);
|
|
5387
5441
|
const rawByValue = useMemo(() => new Map(flat.map((o) => [o.value, o.raw])), [flat]);
|
|
@@ -5448,10 +5502,10 @@ var SSelect = forwardRef(function SSelect2({
|
|
|
5448
5502
|
Ariakit.Select,
|
|
5449
5503
|
{
|
|
5450
5504
|
ref: triggerRef,
|
|
5451
|
-
disabled,
|
|
5505
|
+
disabled: effectiveDisabled,
|
|
5452
5506
|
className: "flex h-full w-full cursor-pointer items-center justify-between gap-[8px] bg-transparent px-[12px] text-left text-[12px] leading-[20px] outline-none disabled:cursor-not-allowed",
|
|
5453
5507
|
style: {
|
|
5454
|
-
color:
|
|
5508
|
+
color: effectiveDisabled ? "var(--cmp-select-text-disabled)" : isPlaceholder ? "var(--cmp-select-icon-default)" : "var(--cmp-select-text-default)"
|
|
5455
5509
|
},
|
|
5456
5510
|
children: [
|
|
5457
5511
|
isHtmlLabel(triggerText) ? /* @__PURE__ */ jsx(
|
|
@@ -5466,7 +5520,7 @@ var SSelect = forwardRef(function SSelect2({
|
|
|
5466
5520
|
{
|
|
5467
5521
|
name: "chevronDown",
|
|
5468
5522
|
size: 12,
|
|
5469
|
-
color:
|
|
5523
|
+
color: effectiveDisabled ? "var(--cmp-select-icon-disabled)" : "var(--cmp-select-icon-default)",
|
|
5470
5524
|
className: cn("shrink-0 transition-transform duration-200", open && "rotate-180")
|
|
5471
5525
|
}
|
|
5472
5526
|
)
|
|
@@ -5480,7 +5534,7 @@ var SSelect = forwardRef(function SSelect2({
|
|
|
5480
5534
|
portalElement: portalContainer,
|
|
5481
5535
|
gutter: 4,
|
|
5482
5536
|
sameWidth: !dropdownWidth,
|
|
5483
|
-
className: "z-50 overflow-auto rounded-[var(--cmp-listBox-radius)] bg-[var(--cmp-listBox-bg)]
|
|
5537
|
+
className: "z-50 overflow-auto rounded-[var(--cmp-listBox-radius)] bg-[var(--cmp-listBox-bg)] shadow-[2px_2px_12px_2px_rgba(0,0,0,0.1)] data-[enter]:animate-floating-in-bottom data-[leave]:animate-floating-out-bottom",
|
|
5484
5538
|
style: {
|
|
5485
5539
|
maxHeight: dropdownHeight,
|
|
5486
5540
|
...dropdownWidth ? { width: dropdownWidth } : {},
|
|
@@ -5521,7 +5575,7 @@ var SSelect = forwardRef(function SSelect2({
|
|
|
5521
5575
|
),
|
|
5522
5576
|
hasItems ? /* @__PURE__ */ jsx(ItemList, { items: filtered, multi, selected, useSearch: showSearch }) : (
|
|
5523
5577
|
// 원본 sd-select-listbox__empty (표시할 항목이 없을 때)
|
|
5524
|
-
/* @__PURE__ */ jsx("div", { className: "px-[12px] py-[12px] text-
|
|
5578
|
+
/* @__PURE__ */ jsx("div", { className: "px-[12px] py-[12px] text-left text-[12px] leading-[20px] text-[color:var(--cmp-listItem-content-disabled)]", children: "\uD45C\uC2DC\uD560 \uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4." })
|
|
5525
5579
|
)
|
|
5526
5580
|
]
|
|
5527
5581
|
}
|
|
@@ -5544,7 +5598,7 @@ var SSelect = forwardRef(function SSelect2({
|
|
|
5544
5598
|
error: error || ruleError !== "",
|
|
5545
5599
|
status: rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0,
|
|
5546
5600
|
errorMessage: ruleError !== "" ? ruleError : errorMessage,
|
|
5547
|
-
disabled,
|
|
5601
|
+
disabled: effectiveDisabled,
|
|
5548
5602
|
width,
|
|
5549
5603
|
className,
|
|
5550
5604
|
style,
|
|
@@ -5579,7 +5633,11 @@ function ItemList({
|
|
|
5579
5633
|
{
|
|
5580
5634
|
className: cn(
|
|
5581
5635
|
"select-none py-[4px] pr-[12px] text-[12px] leading-[20px] text-[color:var(--cmp-listItem-content-default)]",
|
|
5582
|
-
isDepth1 ? "border-t border-solid border-[color:var(--cmp-listItem-depth1-border-color)] bg-[var(--cmp-listItem-depth1-bg-default)] font-bold" : "bg-[var(--cmp-listItem-depth2-middle-bg)] font-medium"
|
|
5636
|
+
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",
|
|
5637
|
+
// 하위가 전부 비활성이면(select.config 에서 bubble-up) 어미 그룹도 비활성 처리:
|
|
5638
|
+
// 텍스트는 회색(#888), depth1 그룹은 파란 배경 대신 회색(#EEE)으로 (depth2 는 #F6F6F6 유지)
|
|
5639
|
+
o.disabled && "cursor-not-allowed text-[color:var(--cmp-listItem-content-disabled)]",
|
|
5640
|
+
o.disabled && isDepth1 && "bg-[var(--cmp-listItem-depth1-bg-disabled)]"
|
|
5583
5641
|
),
|
|
5584
5642
|
style: { paddingLeft: padLeft },
|
|
5585
5643
|
children: o.label
|
|
@@ -5593,10 +5651,14 @@ function ItemList({
|
|
|
5593
5651
|
{
|
|
5594
5652
|
value: o.value,
|
|
5595
5653
|
disabled: o.disabled,
|
|
5654
|
+
accessibleWhenDisabled: true,
|
|
5596
5655
|
className: cn(
|
|
5597
5656
|
itemBase,
|
|
5598
5657
|
isSelected && !multi && "font-bold text-[color:var(--cmp-listItem-content-selected)]",
|
|
5599
|
-
|
|
5658
|
+
// Ariakit은 disabled 항목도 hover 시 active(data-active-item) 처리하므로,
|
|
5659
|
+
// 비활성 항목에는 hover 하이라이트를 적용하지 않아 회색 비활성 스타일을 유지한다.
|
|
5660
|
+
// (원본 Stencil의 `--focused...:not(--disabled)` 규칙과 동일한 의도)
|
|
5661
|
+
!o.disabled && activeClass
|
|
5600
5662
|
),
|
|
5601
5663
|
style: { paddingTop: 4, paddingBottom: 4, paddingRight: 12, paddingLeft: padLeft },
|
|
5602
5664
|
render: useSearch ? /* @__PURE__ */ jsx(Ariakit.ComboboxItem, {}) : void 0,
|
|
@@ -5606,15 +5668,21 @@ function ItemList({
|
|
|
5606
5668
|
"span",
|
|
5607
5669
|
{
|
|
5608
5670
|
className: cn(
|
|
5609
|
-
"flex h-[16px] w-[16px] flex-shrink-0 items-center justify-center rounded-[2px] border border-solid
|
|
5610
|
-
|
|
5671
|
+
"flex h-[16px] w-[16px] flex-shrink-0 items-center justify-center rounded-[2px] border border-solid",
|
|
5672
|
+
o.disabled ? (
|
|
5673
|
+
// 비활성: 회색 채움(#E1E1E1) + 회색 테두리(#CCCCCC)
|
|
5674
|
+
"cursor-not-allowed border-[color:var(--cmp-checkbox-border-disabled)] bg-[var(--cmp-checkbox-bg-disabled)]"
|
|
5675
|
+
) : cn(
|
|
5676
|
+
"group-data-[active-item]:border-[color:var(--cmp-checkbox-checked-border-inverse)]",
|
|
5677
|
+
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"
|
|
5678
|
+
)
|
|
5611
5679
|
),
|
|
5612
5680
|
children: isSelected && /* @__PURE__ */ jsx(
|
|
5613
5681
|
SIcon,
|
|
5614
5682
|
{
|
|
5615
5683
|
name: "checkboxCheck",
|
|
5616
5684
|
size: 12,
|
|
5617
|
-
color: "var(--cmp-checkbox-checked-icon-default)"
|
|
5685
|
+
color: o.disabled ? "var(--cmp-checkbox-checked-icon-disabled)" : "var(--cmp-checkbox-checked-icon-default)"
|
|
5618
5686
|
}
|
|
5619
5687
|
)
|
|
5620
5688
|
}
|
|
@@ -5905,7 +5973,8 @@ var STable = forwardRef(function STable2({
|
|
|
5905
5973
|
else onSelectedChange?.([...selected, row]);
|
|
5906
5974
|
};
|
|
5907
5975
|
const radiusClass = radius === "full" ? "rounded-none" : radius === "useTop" ? "rounded-b-[var(--cmp-table-radius)] rounded-t-none" : "rounded-[var(--cmp-table-radius)]";
|
|
5908
|
-
const cellPadY = dense ? "var(--cmp-table-body-dense
|
|
5976
|
+
const cellPadY = dense ? "var(--cmp-table-body-paddingY-dense)" : "var(--cmp-table-body-paddingY-default)";
|
|
5977
|
+
const cellPadX = dense ? "var(--cmp-table-body-paddingX-default)" : "var(--cmp-table-body-paddingX-wide)";
|
|
5909
5978
|
const rowH = dense ? "var(--cmp-table-body-dense-height)" : "var(--cmp-table-body-default-height)";
|
|
5910
5979
|
const totalColSpan = visibleCols.length + (selectable ? 1 : 0);
|
|
5911
5980
|
const stickyInfo = (i) => {
|
|
@@ -6080,13 +6149,15 @@ var STable = forwardRef(function STable2({
|
|
|
6080
6149
|
className: cn(
|
|
6081
6150
|
// 원본 .td: 컬럼 폭에 맞춰 내용 말줄임(overflow hidden + ellipsis) + 행 구분선(border-b)
|
|
6082
6151
|
// 셀 배경은 흰색으로 채워 뒤 배경이 비치지 않게 하고, hover 시 행 배경(grey_05)을 따른다.
|
|
6083
|
-
"overflow-hidden text-ellipsis whitespace-nowrap border-b border-solid border-[color:var(--cmp-table-border-color)]
|
|
6152
|
+
"overflow-hidden text-ellipsis whitespace-nowrap border-b border-solid border-[color:var(--cmp-table-border-color)] text-[12px] leading-[20px] text-[color:var(--sys-color-fg-primary)]",
|
|
6084
6153
|
rowBg,
|
|
6085
6154
|
"group-hover:bg-[var(--color-grey-05)]",
|
|
6086
6155
|
stickyShadowClass(i),
|
|
6087
6156
|
col.tdClass
|
|
6088
6157
|
),
|
|
6089
6158
|
style: {
|
|
6159
|
+
paddingLeft: cellPadX,
|
|
6160
|
+
paddingRight: cellPadX,
|
|
6090
6161
|
paddingTop: cellPadY,
|
|
6091
6162
|
paddingBottom: cellPadY,
|
|
6092
6163
|
textAlign: col.align ?? "left",
|
|
@@ -6393,8 +6464,8 @@ var STextarea = forwardRef(function STextarea2({
|
|
|
6393
6464
|
);
|
|
6394
6465
|
});
|
|
6395
6466
|
var PAD2 = {
|
|
6396
|
-
sm: { fontSize: 12, stepper: 20, icon: 12 },
|
|
6397
|
-
md: { fontSize: 14, stepper: 24, icon: 14 }
|
|
6467
|
+
sm: { fontSize: 12, lineHeight: 20, stepper: 20, icon: 12 },
|
|
6468
|
+
md: { fontSize: 14, lineHeight: 24, stepper: 24, icon: 14 }
|
|
6398
6469
|
};
|
|
6399
6470
|
var toNumber = (val) => {
|
|
6400
6471
|
if (val === null || val === void 0 || val === "") return null;
|
|
@@ -6412,6 +6483,38 @@ var formatWithCommas = (value) => {
|
|
|
6412
6483
|
const result = isNeg ? "-" + formatted : formatted;
|
|
6413
6484
|
return decPart !== void 0 && decPart !== "" ? result + "." + decPart : result;
|
|
6414
6485
|
};
|
|
6486
|
+
var addCommas = (value) => value.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
6487
|
+
var formatInputWithCommas = (value) => {
|
|
6488
|
+
const isNeg = value.startsWith("-");
|
|
6489
|
+
const unsigned = isNeg ? value.slice(1) : value;
|
|
6490
|
+
const hasDecimal = unsigned.includes(".");
|
|
6491
|
+
const [intPart = "", decPart = ""] = unsigned.split(".");
|
|
6492
|
+
const formattedInt = addCommas(intPart === "" ? "0" : intPart);
|
|
6493
|
+
return `${isNeg ? "-" : ""}${formattedInt}${hasDecimal ? `.${decPart}` : ""}`;
|
|
6494
|
+
};
|
|
6495
|
+
var getDecimalLimit = (useDecimal, maxDecimalLength) => {
|
|
6496
|
+
if (!useDecimal || maxDecimalLength === void 0 || !Number.isFinite(maxDecimalLength)) {
|
|
6497
|
+
return void 0;
|
|
6498
|
+
}
|
|
6499
|
+
return Math.max(0, Math.floor(maxDecimalLength));
|
|
6500
|
+
};
|
|
6501
|
+
var applyDecimalLimit = (value, decimalLimit) => {
|
|
6502
|
+
if (value === null || decimalLimit === void 0) return value;
|
|
6503
|
+
return Number(value.toFixed(decimalLimit));
|
|
6504
|
+
};
|
|
6505
|
+
var getLogicalCaret = (value, caret) => {
|
|
6506
|
+
return value.slice(0, caret ?? value.length).replace(/,/g, "").length;
|
|
6507
|
+
};
|
|
6508
|
+
var getDisplayCaret = (value, logicalCaret) => {
|
|
6509
|
+
if (logicalCaret <= 0) return 0;
|
|
6510
|
+
let seen = 0;
|
|
6511
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
6512
|
+
if (value[i] === ",") continue;
|
|
6513
|
+
seen += 1;
|
|
6514
|
+
if (seen >= logicalCaret) return i + 1;
|
|
6515
|
+
}
|
|
6516
|
+
return value.length;
|
|
6517
|
+
};
|
|
6415
6518
|
var SNumberInput = forwardRef(function SNumberInput2({
|
|
6416
6519
|
value,
|
|
6417
6520
|
onValueChange,
|
|
@@ -6421,6 +6524,7 @@ var SNumberInput = forwardRef(function SNumberInput2({
|
|
|
6421
6524
|
step = 1,
|
|
6422
6525
|
useButton = false,
|
|
6423
6526
|
useDecimal = false,
|
|
6527
|
+
maxDecimalLength,
|
|
6424
6528
|
inputPrefix = "",
|
|
6425
6529
|
inputSuffix = "",
|
|
6426
6530
|
inputClass,
|
|
@@ -6452,7 +6556,8 @@ var SNumberInput = forwardRef(function SNumberInput2({
|
|
|
6452
6556
|
}, ref) {
|
|
6453
6557
|
const p = PAD2[size];
|
|
6454
6558
|
const padX = `var(--cmp-numberInput-${size}-paddingX)`;
|
|
6455
|
-
const
|
|
6559
|
+
const decimalLimit = getDecimalLimit(useDecimal, maxDecimalLength);
|
|
6560
|
+
const numValue = applyDecimalLimit(toNumber(value), decimalLimit);
|
|
6456
6561
|
const [display, setDisplay] = useState(() => formatWithCommas(numValue));
|
|
6457
6562
|
const [ruleError, setRuleError] = useState("");
|
|
6458
6563
|
const innerRef = useRef(null);
|
|
@@ -6462,8 +6567,9 @@ var SNumberInput = forwardRef(function SNumberInput2({
|
|
|
6462
6567
|
else if (ref) ref.current = el;
|
|
6463
6568
|
};
|
|
6464
6569
|
useEffect(() => {
|
|
6465
|
-
|
|
6466
|
-
|
|
6570
|
+
if (document.activeElement === innerRef.current) return;
|
|
6571
|
+
setDisplay(formatWithCommas(applyDecimalLimit(toNumber(value), decimalLimit)));
|
|
6572
|
+
}, [decimalLimit, value]);
|
|
6467
6573
|
useFormField({
|
|
6468
6574
|
name,
|
|
6469
6575
|
validate: () => {
|
|
@@ -6475,48 +6581,87 @@ var SNumberInput = forwardRef(function SNumberInput2({
|
|
|
6475
6581
|
});
|
|
6476
6582
|
const resolvedError = error || ruleError !== "";
|
|
6477
6583
|
const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
|
|
6478
|
-
const
|
|
6479
|
-
|
|
6480
|
-
|
|
6584
|
+
const restoreCaret = (nextDisplay, logicalCaret) => {
|
|
6585
|
+
const input = innerRef.current;
|
|
6586
|
+
if (logicalCaret === void 0 || !input || document.activeElement !== input) return;
|
|
6587
|
+
const nextCaret = getDisplayCaret(nextDisplay, logicalCaret);
|
|
6588
|
+
requestAnimationFrame(() => {
|
|
6589
|
+
if (document.activeElement !== input) return;
|
|
6590
|
+
input.setSelectionRange(nextCaret, nextCaret);
|
|
6591
|
+
});
|
|
6592
|
+
};
|
|
6593
|
+
const setDisplayWithCaret = (nextDisplay, logicalCaret) => {
|
|
6594
|
+
setDisplay(nextDisplay);
|
|
6595
|
+
restoreCaret(nextDisplay, logicalCaret);
|
|
6596
|
+
};
|
|
6597
|
+
const resetRejectedInput = (target, logicalCaret) => {
|
|
6598
|
+
target.value = display;
|
|
6599
|
+
restoreCaret(display, Math.min(logicalCaret, display.replace(/,/g, "").length));
|
|
6600
|
+
};
|
|
6601
|
+
const emit2 = (n, logicalCaret) => {
|
|
6602
|
+
const next = applyDecimalLimit(n, decimalLimit);
|
|
6603
|
+
const nextDisplay = formatWithCommas(next);
|
|
6604
|
+
setDisplayWithCaret(nextDisplay, logicalCaret);
|
|
6605
|
+
onValueChange?.(next);
|
|
6481
6606
|
};
|
|
6482
6607
|
const incDisabled = disabled || readOnly || numValue !== null && numValue >= max;
|
|
6483
6608
|
const decDisabled = disabled || readOnly || numValue !== null && numValue <= min;
|
|
6484
6609
|
const increment = () => {
|
|
6485
6610
|
if (incDisabled) return;
|
|
6486
6611
|
const cur = numValue ?? (min === Number.NEGATIVE_INFINITY ? 0 : min);
|
|
6487
|
-
const next = Math.min(cur + step, max);
|
|
6612
|
+
const next = applyDecimalLimit(Math.min(cur + step, max), decimalLimit);
|
|
6488
6613
|
if (next !== cur) emit2(next);
|
|
6489
6614
|
};
|
|
6490
6615
|
const decrement = () => {
|
|
6491
6616
|
if (decDisabled) return;
|
|
6492
6617
|
const cur = numValue ?? (min === Number.NEGATIVE_INFINITY ? 0 : min);
|
|
6493
|
-
const next = Math.max(cur - step, min);
|
|
6618
|
+
const next = applyDecimalLimit(Math.max(cur - step, min), decimalLimit);
|
|
6494
6619
|
if (next !== cur) emit2(next);
|
|
6495
6620
|
};
|
|
6496
|
-
const handleInput = (
|
|
6621
|
+
const handleInput = (event) => {
|
|
6622
|
+
const target = event.currentTarget;
|
|
6623
|
+
const raw = target.value;
|
|
6624
|
+
const logicalCaret = getLogicalCaret(raw, target.selectionStart);
|
|
6497
6625
|
if (raw === "") {
|
|
6498
|
-
|
|
6626
|
+
setDisplayWithCaret("", 0);
|
|
6499
6627
|
onValueChange?.(null);
|
|
6500
6628
|
return;
|
|
6501
6629
|
}
|
|
6502
6630
|
const cleaned = raw.replace(/,/g, "");
|
|
6503
6631
|
const decimals = (cleaned.match(/\./g) || []).length;
|
|
6504
|
-
if (decimals > 1)
|
|
6632
|
+
if (decimals > 1) {
|
|
6633
|
+
resetRejectedInput(target, logicalCaret);
|
|
6634
|
+
return;
|
|
6635
|
+
}
|
|
6505
6636
|
if (cleaned === "-" || cleaned === "." || cleaned === "-.") {
|
|
6506
|
-
|
|
6637
|
+
setDisplayWithCaret(cleaned, logicalCaret);
|
|
6638
|
+
return;
|
|
6639
|
+
}
|
|
6640
|
+
if (!useDecimal && cleaned.includes(".")) {
|
|
6641
|
+
resetRejectedInput(target, logicalCaret);
|
|
6507
6642
|
return;
|
|
6508
6643
|
}
|
|
6509
|
-
if (
|
|
6644
|
+
if (decimalLimit !== void 0 && cleaned.includes(".")) {
|
|
6645
|
+
const fraction = cleaned.split(".")[1] ?? "";
|
|
6646
|
+
if (fraction.length > decimalLimit) {
|
|
6647
|
+
resetRejectedInput(target, logicalCaret);
|
|
6648
|
+
return;
|
|
6649
|
+
}
|
|
6650
|
+
}
|
|
6510
6651
|
if (cleaned.endsWith(".") && decimals === 1) {
|
|
6511
6652
|
const parsed2 = toNumber(cleaned.slice(0, -1));
|
|
6512
6653
|
if (parsed2 !== null) {
|
|
6513
|
-
|
|
6654
|
+
setDisplayWithCaret(formatInputWithCommas(cleaned), logicalCaret);
|
|
6514
6655
|
return;
|
|
6515
6656
|
}
|
|
6516
6657
|
}
|
|
6517
6658
|
const parsed = toNumber(cleaned);
|
|
6518
|
-
if (parsed === null)
|
|
6519
|
-
|
|
6659
|
+
if (parsed === null) {
|
|
6660
|
+
resetRejectedInput(target, logicalCaret);
|
|
6661
|
+
return;
|
|
6662
|
+
}
|
|
6663
|
+
setDisplayWithCaret(formatInputWithCommas(cleaned), logicalCaret);
|
|
6664
|
+
onValueChange?.(applyDecimalLimit(parsed, decimalLimit));
|
|
6520
6665
|
};
|
|
6521
6666
|
const stepper = (dir) => {
|
|
6522
6667
|
const off = dir === "inc" ? incDisabled : decDisabled;
|
|
@@ -6529,8 +6674,8 @@ var SNumberInput = forwardRef(function SNumberInput2({
|
|
|
6529
6674
|
"aria-label": dir === "inc" ? "\uC99D\uAC00" : "\uAC10\uC18C",
|
|
6530
6675
|
onClick: dir === "inc" ? increment : decrement,
|
|
6531
6676
|
className: cn(
|
|
6532
|
-
"flex flex-shrink-0 items-center justify-center",
|
|
6533
|
-
off ? "cursor-not-allowed" : "cursor-pointer"
|
|
6677
|
+
"flex flex-shrink-0 items-center justify-center border border-solid border-transparent transition-colors",
|
|
6678
|
+
off ? "cursor-not-allowed" : "cursor-pointer hover:border-[var(--color-border-accentLight)]"
|
|
6534
6679
|
),
|
|
6535
6680
|
style: {
|
|
6536
6681
|
width: `var(--cmp-numberInput-stepper-${size}-size)`,
|
|
@@ -6579,24 +6724,26 @@ var SNumberInput = forwardRef(function SNumberInput2({
|
|
|
6579
6724
|
style: {
|
|
6580
6725
|
// 원본 sd-number-input: content gap = padding-x 토큰 (gap 토큰 아님)
|
|
6581
6726
|
gap: `var(--cmp-numberInput-${size}-paddingX)`,
|
|
6582
|
-
padding: `0 ${useButton ? padX : `calc(${padX} * 2)`}
|
|
6727
|
+
padding: `0 ${useButton ? padX : `calc(${padX} * 2)`}`,
|
|
6728
|
+
fontSize: p.fontSize,
|
|
6729
|
+
lineHeight: `${p.lineHeight}px`
|
|
6583
6730
|
},
|
|
6584
6731
|
children: [
|
|
6585
6732
|
useButton && stepper("dec"),
|
|
6586
|
-
inputPrefix !== "" && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", style: {
|
|
6733
|
+
inputPrefix !== "" && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", style: { color: affixColor }, children: inputPrefix }),
|
|
6587
6734
|
/* @__PURE__ */ jsx(
|
|
6588
6735
|
"input",
|
|
6589
6736
|
{
|
|
6590
6737
|
ref: setRefs,
|
|
6591
6738
|
name,
|
|
6592
6739
|
type: "text",
|
|
6593
|
-
inputMode: "numeric",
|
|
6740
|
+
inputMode: useDecimal ? "decimal" : "numeric",
|
|
6594
6741
|
value: display,
|
|
6595
6742
|
placeholder,
|
|
6596
6743
|
disabled,
|
|
6597
6744
|
readOnly,
|
|
6598
6745
|
autoFocus,
|
|
6599
|
-
onChange:
|
|
6746
|
+
onChange: handleInput,
|
|
6600
6747
|
onKeyDown: (e) => {
|
|
6601
6748
|
if (e.key === "ArrowUp") {
|
|
6602
6749
|
e.preventDefault();
|
|
@@ -6608,26 +6755,29 @@ var SNumberInput = forwardRef(function SNumberInput2({
|
|
|
6608
6755
|
},
|
|
6609
6756
|
onFocus: (e) => onFocus?.(e),
|
|
6610
6757
|
onBlur: (e) => {
|
|
6611
|
-
const
|
|
6758
|
+
const cleaned = display.replace(/,/g, "");
|
|
6759
|
+
const n = toNumber(cleaned);
|
|
6612
6760
|
const clamped = n === null ? null : Math.min(Math.max(n, min), max);
|
|
6613
6761
|
if (clamped !== n) emit2(clamped);
|
|
6614
|
-
else setDisplay(
|
|
6762
|
+
else setDisplay(n === null ? "" : formatInputWithCommas(cleaned));
|
|
6615
6763
|
if (rules && rules.length > 0) setRuleError(runRules(clamped, rules));
|
|
6616
6764
|
onBlur?.(e);
|
|
6617
6765
|
},
|
|
6618
6766
|
className: cn(
|
|
6619
|
-
|
|
6767
|
+
// h-full 대신 라인박스 높이 그대로 두어 prefix/suffix 와 동일하게 flex 로 수직 센터링
|
|
6768
|
+
// (h-full 이면 input 내부 텍스트 센터링을 브라우저가 수행해 1px 어긋날 수 있음)
|
|
6769
|
+
"min-w-0 flex-1 border-0 bg-transparent p-0 outline-none placeholder:text-[color:var(--cmp-numberInput-text-placeholder)] disabled:cursor-not-allowed",
|
|
6620
6770
|
inputClass
|
|
6621
6771
|
),
|
|
6622
6772
|
style: {
|
|
6623
|
-
fontSize
|
|
6773
|
+
// fontSize/lineHeight 는 컨테이너에서 상속
|
|
6624
6774
|
textAlign: useButton ? "center" : "right",
|
|
6625
6775
|
color: disabled ? "var(--cmp-numberInput-text-disabled)" : "var(--cmp-numberInput-text-default)",
|
|
6626
6776
|
...inputStyle
|
|
6627
6777
|
}
|
|
6628
6778
|
}
|
|
6629
6779
|
),
|
|
6630
|
-
inputSuffix !== "" && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", style: {
|
|
6780
|
+
inputSuffix !== "" && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", style: { color: affixColor }, children: inputSuffix }),
|
|
6631
6781
|
useButton && stepper("inc")
|
|
6632
6782
|
]
|
|
6633
6783
|
}
|
|
@@ -6741,7 +6891,7 @@ function SRadioGroup({
|
|
|
6741
6891
|
role: "radiogroup",
|
|
6742
6892
|
className: cn(
|
|
6743
6893
|
"inline-flex",
|
|
6744
|
-
direction === "vertical" ? "flex-col gap-[
|
|
6894
|
+
direction === "vertical" ? "flex-col gap-[var(--cmp-radio-group-gap-vertical)]" : "flex-row gap-[var(--cmp-radio-group-gap-horizontal)]",
|
|
6745
6895
|
className
|
|
6746
6896
|
),
|
|
6747
6897
|
style,
|
|
@@ -6953,7 +7103,7 @@ function SCalendar({
|
|
|
6953
7103
|
"span",
|
|
6954
7104
|
{
|
|
6955
7105
|
className: cn(
|
|
6956
|
-
"flex h-[var(--cmp-datepicker-calendar-day-circle-size)] w-[var(--cmp-datepicker-calendar-day-circle-size)] items-center justify-center rounded-[var(--cmp-datepicker-calendar-day-circle-radius)] border border-solid border-transparent text-[14px]",
|
|
7106
|
+
"flex h-[var(--cmp-datepicker-calendar-day-circle-size)] w-[var(--cmp-datepicker-calendar-day-circle-size)] items-center justify-center rounded-[var(--cmp-datepicker-calendar-day-circle-radius)] border border-solid border-transparent text-[14px] leading-[var(--cmp-datepicker-calendar-day-circle-size)]",
|
|
6957
7107
|
selected ? "bg-[var(--cmp-datepicker-calendar-day-select-bg)] text-[color:var(--cmp-datepicker-calendar-day-select-text)]" : disabled ? "text-[color:var(--cmp-datepicker-calendar-day-disabled-text)]" : "text-[color:var(--cmp-datepicker-calendar-day-default-text)] hover:border-[color:var(--cmp-datepicker-calendar-day-hover-border)]",
|
|
6958
7108
|
isToday && !disabled && "font-bold"
|
|
6959
7109
|
),
|
|
@@ -7143,6 +7293,7 @@ function RangeCalendar({
|
|
|
7143
7293
|
selectable,
|
|
7144
7294
|
maxRange,
|
|
7145
7295
|
onSelect,
|
|
7296
|
+
onPendingStartChange,
|
|
7146
7297
|
onViewChange
|
|
7147
7298
|
}) {
|
|
7148
7299
|
const today = todayStr();
|
|
@@ -7205,9 +7356,11 @@ function RangeCalendar({
|
|
|
7205
7356
|
setStart(d);
|
|
7206
7357
|
setEnd(null);
|
|
7207
7358
|
setHover(null);
|
|
7359
|
+
onPendingStartChange?.(d);
|
|
7208
7360
|
return;
|
|
7209
7361
|
}
|
|
7210
7362
|
setEnd(d);
|
|
7363
|
+
onPendingStartChange?.(null);
|
|
7211
7364
|
onSelect([start, d]);
|
|
7212
7365
|
};
|
|
7213
7366
|
const GRID_COLS = "grid grid-cols-[repeat(7,var(--cmp-datepicker-calendar-day-width))]";
|
|
@@ -7342,8 +7495,11 @@ function SDateRangePicker({
|
|
|
7342
7495
|
const portalContainer = usePortalContainer();
|
|
7343
7496
|
const [open, setOpen] = useState(false);
|
|
7344
7497
|
const [ruleError, setRuleError] = useState("");
|
|
7498
|
+
const [pendingStart, setPendingStart] = useState(null);
|
|
7345
7499
|
const hasValue = value != null && value[0] !== "" && value[1] !== "";
|
|
7346
|
-
const
|
|
7500
|
+
const hasDisplay = pendingStart != null || hasValue;
|
|
7501
|
+
const startText = pendingStart ?? (hasValue ? value[0] : "");
|
|
7502
|
+
const endText = pendingStart ? "" : hasValue ? value[1] : "";
|
|
7347
7503
|
useFormField({
|
|
7348
7504
|
name,
|
|
7349
7505
|
validate: () => {
|
|
@@ -7357,6 +7513,7 @@ function SDateRangePicker({
|
|
|
7357
7513
|
const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
|
|
7358
7514
|
const dims = size === "md" ? { padX: 16, gap: 12, icon: 20, minW: 104, fontSize: 14, lineHeight: 24, radius: 6 } : { padX: 12, gap: 8, icon: 16, minW: 80, fontSize: 12, lineHeight: 20, radius: 4 };
|
|
7359
7515
|
const select = (r) => {
|
|
7516
|
+
setPendingStart(null);
|
|
7360
7517
|
onValueChange?.(r);
|
|
7361
7518
|
if (rules && rules.length > 0) setRuleError(runRules(r, rules));
|
|
7362
7519
|
setOpen(false);
|
|
@@ -7381,61 +7538,80 @@ function SDateRangePicker({
|
|
|
7381
7538
|
disabled,
|
|
7382
7539
|
className,
|
|
7383
7540
|
style,
|
|
7384
|
-
children: /* @__PURE__ */ jsxs(
|
|
7385
|
-
|
|
7386
|
-
|
|
7387
|
-
|
|
7388
|
-
|
|
7389
|
-
|
|
7390
|
-
|
|
7391
|
-
|
|
7392
|
-
|
|
7393
|
-
|
|
7394
|
-
|
|
7395
|
-
|
|
7396
|
-
{
|
|
7397
|
-
name: "date",
|
|
7398
|
-
size: dims.icon,
|
|
7399
|
-
color: disabled ? "var(--cmp-datepicker-icon-disabled)" : "var(--cmp-datepicker-icon-default)",
|
|
7400
|
-
className: "flex-shrink-0"
|
|
7401
|
-
}
|
|
7402
|
-
),
|
|
7403
|
-
/* @__PURE__ */ jsx(
|
|
7404
|
-
"span",
|
|
7405
|
-
{
|
|
7406
|
-
className: "flex-1 truncate text-center",
|
|
7407
|
-
style: {
|
|
7408
|
-
minWidth: dims.minW,
|
|
7409
|
-
fontSize: dims.fontSize,
|
|
7410
|
-
lineHeight: `${dims.lineHeight}px`,
|
|
7411
|
-
color: disabled ? "var(--cmp-datepicker-text-disabled)" : hasValue ? "var(--cmp-datepicker-text-default)" : "var(--cmp-field-hint-color)"
|
|
7412
|
-
},
|
|
7413
|
-
children: display
|
|
7414
|
-
}
|
|
7415
|
-
)
|
|
7416
|
-
]
|
|
7417
|
-
}
|
|
7418
|
-
) }),
|
|
7419
|
-
/* @__PURE__ */ jsx(RPopover2.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
|
|
7420
|
-
RPopover2.Content,
|
|
7421
|
-
{
|
|
7422
|
-
side: "bottom",
|
|
7423
|
-
align: "start",
|
|
7424
|
-
sideOffset: 4,
|
|
7425
|
-
className: cn("z-50", FLOATING_SLIDE_ANIM),
|
|
7426
|
-
children: /* @__PURE__ */ jsx(
|
|
7427
|
-
RangeCalendar,
|
|
7541
|
+
children: /* @__PURE__ */ jsxs(
|
|
7542
|
+
RPopover2.Root,
|
|
7543
|
+
{
|
|
7544
|
+
open,
|
|
7545
|
+
onOpenChange: (o) => {
|
|
7546
|
+
if (disabled) return;
|
|
7547
|
+
setOpen(o);
|
|
7548
|
+
if (!o) setPendingStart(null);
|
|
7549
|
+
},
|
|
7550
|
+
children: [
|
|
7551
|
+
/* @__PURE__ */ jsx(RPopover2.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
7552
|
+
"button",
|
|
7428
7553
|
{
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
|
|
7432
|
-
|
|
7433
|
-
|
|
7554
|
+
type: "button",
|
|
7555
|
+
name,
|
|
7556
|
+
disabled,
|
|
7557
|
+
className: "flex h-full w-full items-center overflow-hidden bg-transparent outline-none disabled:cursor-not-allowed",
|
|
7558
|
+
style: { padding: `0 ${dims.padX}px`, gap: dims.gap, borderRadius: dims.radius },
|
|
7559
|
+
children: [
|
|
7560
|
+
/* @__PURE__ */ jsx(
|
|
7561
|
+
SIcon,
|
|
7562
|
+
{
|
|
7563
|
+
name: "date",
|
|
7564
|
+
size: dims.icon,
|
|
7565
|
+
color: disabled ? "var(--cmp-datepicker-icon-disabled)" : "var(--cmp-datepicker-icon-default)",
|
|
7566
|
+
className: "flex-shrink-0"
|
|
7567
|
+
}
|
|
7568
|
+
),
|
|
7569
|
+
/* @__PURE__ */ jsx(
|
|
7570
|
+
"span",
|
|
7571
|
+
{
|
|
7572
|
+
className: cn(
|
|
7573
|
+
"flex-1 items-center",
|
|
7574
|
+
hasDisplay ? "flex" : "block truncate text-center"
|
|
7575
|
+
),
|
|
7576
|
+
style: {
|
|
7577
|
+
minWidth: dims.minW,
|
|
7578
|
+
fontSize: dims.fontSize,
|
|
7579
|
+
lineHeight: `${dims.lineHeight}px`,
|
|
7580
|
+
color: disabled ? "var(--cmp-datepicker-text-disabled)" : hasDisplay ? "var(--cmp-datepicker-text-default)" : "var(--cmp-field-hint-color)"
|
|
7581
|
+
},
|
|
7582
|
+
children: hasDisplay ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7583
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-right", children: startText }),
|
|
7584
|
+
/* @__PURE__ */ jsx("span", { className: "px-[4px]", children: "~" }),
|
|
7585
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-left", children: endText })
|
|
7586
|
+
] }) : placeholder
|
|
7587
|
+
}
|
|
7588
|
+
)
|
|
7589
|
+
]
|
|
7434
7590
|
}
|
|
7435
|
-
)
|
|
7436
|
-
|
|
7437
|
-
|
|
7438
|
-
|
|
7591
|
+
) }),
|
|
7592
|
+
/* @__PURE__ */ jsx(RPopover2.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
|
|
7593
|
+
RPopover2.Content,
|
|
7594
|
+
{
|
|
7595
|
+
side: "bottom",
|
|
7596
|
+
align: "start",
|
|
7597
|
+
sideOffset: 4,
|
|
7598
|
+
className: cn("z-50", FLOATING_SLIDE_ANIM),
|
|
7599
|
+
children: /* @__PURE__ */ jsx(
|
|
7600
|
+
RangeCalendar,
|
|
7601
|
+
{
|
|
7602
|
+
value: value ?? null,
|
|
7603
|
+
selectable,
|
|
7604
|
+
maxRange,
|
|
7605
|
+
onSelect: select,
|
|
7606
|
+
onPendingStartChange: setPendingStart,
|
|
7607
|
+
onViewChange
|
|
7608
|
+
}
|
|
7609
|
+
)
|
|
7610
|
+
}
|
|
7611
|
+
) })
|
|
7612
|
+
]
|
|
7613
|
+
}
|
|
7614
|
+
)
|
|
7439
7615
|
}
|
|
7440
7616
|
);
|
|
7441
7617
|
}
|
|
@@ -7444,7 +7620,7 @@ var SChip = forwardRef(function SChip2({
|
|
|
7444
7620
|
value = "",
|
|
7445
7621
|
error: errorProp = false,
|
|
7446
7622
|
disabled = false,
|
|
7447
|
-
editable =
|
|
7623
|
+
editable = false,
|
|
7448
7624
|
showRemove = true,
|
|
7449
7625
|
placeholder = "",
|
|
7450
7626
|
rules,
|
|
@@ -7597,6 +7773,7 @@ function SFilePicker({
|
|
|
7597
7773
|
hovered = false,
|
|
7598
7774
|
inline = false,
|
|
7599
7775
|
multiple = false,
|
|
7776
|
+
useMultipleListBox = false,
|
|
7600
7777
|
accept,
|
|
7601
7778
|
maxFileSize,
|
|
7602
7779
|
maxTotalSize,
|
|
@@ -7622,10 +7799,13 @@ function SFilePicker({
|
|
|
7622
7799
|
const autoId = useId();
|
|
7623
7800
|
const resolvedName = name ?? autoId;
|
|
7624
7801
|
const inputRef = useRef(null);
|
|
7802
|
+
const contentBoxRef = useRef(null);
|
|
7625
7803
|
const [ruleError, setRuleError] = useState("");
|
|
7804
|
+
const [listOpen, setListOpen] = useState(false);
|
|
7805
|
+
const portalContainer = usePortalContainer();
|
|
7626
7806
|
const files = multiple ? Array.isArray(value) ? value : [] : value && !Array.isArray(value) ? value : null;
|
|
7627
|
-
const
|
|
7628
|
-
const displayText =
|
|
7807
|
+
const hasFiles = multiple ? files.length > 0 : !!files;
|
|
7808
|
+
const displayText = !hasFiles ? placeholder : multiple ? files.map((f) => f.name).join(", ") : files.name;
|
|
7629
7809
|
useFormField({
|
|
7630
7810
|
name,
|
|
7631
7811
|
validate: () => {
|
|
@@ -7676,10 +7856,12 @@ function SFilePicker({
|
|
|
7676
7856
|
e.stopPropagation();
|
|
7677
7857
|
if (disabled) return;
|
|
7678
7858
|
onValueChange?.(multiple ? [] : null);
|
|
7859
|
+
setListOpen(false);
|
|
7679
7860
|
};
|
|
7680
7861
|
const removeChip = (i) => {
|
|
7681
7862
|
const next = files.filter((_, idx) => idx !== i);
|
|
7682
7863
|
onValueChange?.(next);
|
|
7864
|
+
if (next.length === 0) setListOpen(false);
|
|
7683
7865
|
};
|
|
7684
7866
|
const open = () => {
|
|
7685
7867
|
if (!disabled) inputRef.current?.click();
|
|
@@ -7689,78 +7871,100 @@ function SFilePicker({
|
|
|
7689
7871
|
const padX = size === "md" ? "var(--cmp-filepicker-md-paddingX)" : "var(--cmp-filepicker-sm-paddingX)";
|
|
7690
7872
|
const iconSize = size === "md" ? 20 : 16;
|
|
7691
7873
|
const gapCls = size === "md" ? "gap-[var(--cmp-filepicker-md-gap)]" : "gap-[var(--cmp-filepicker-sm-gap)]";
|
|
7692
|
-
const
|
|
7874
|
+
const inlinePlaceholder = inline && !disabled && !hasFiles;
|
|
7875
|
+
const showListbox = multiple && useMultipleListBox;
|
|
7876
|
+
const filesArr = multiple ? files : [];
|
|
7877
|
+
const contentInner = /* @__PURE__ */ jsxs(
|
|
7878
|
+
"div",
|
|
7879
|
+
{
|
|
7880
|
+
ref: contentBoxRef,
|
|
7881
|
+
className: cn("group/filepicker flex h-full w-full items-center", gapCls),
|
|
7882
|
+
style: { padding: inline ? 0 : `0 ${padX}` },
|
|
7883
|
+
children: [
|
|
7884
|
+
/* @__PURE__ */ jsx(
|
|
7885
|
+
"input",
|
|
7886
|
+
{
|
|
7887
|
+
ref: inputRef,
|
|
7888
|
+
type: "file",
|
|
7889
|
+
className: "hidden",
|
|
7890
|
+
disabled,
|
|
7891
|
+
multiple,
|
|
7892
|
+
accept,
|
|
7893
|
+
name: resolvedName,
|
|
7894
|
+
onChange,
|
|
7895
|
+
"aria-label": placeholder
|
|
7896
|
+
}
|
|
7897
|
+
),
|
|
7898
|
+
/* @__PURE__ */ jsxs(
|
|
7899
|
+
"button",
|
|
7900
|
+
{
|
|
7901
|
+
type: "button",
|
|
7902
|
+
disabled,
|
|
7903
|
+
onClick: open,
|
|
7904
|
+
"aria-label": placeholder,
|
|
7905
|
+
className: cn(
|
|
7906
|
+
"flex min-w-0 flex-1 items-center bg-transparent text-left",
|
|
7907
|
+
gapCls,
|
|
7908
|
+
disabled ? "cursor-not-allowed" : "cursor-pointer"
|
|
7909
|
+
),
|
|
7910
|
+
children: [
|
|
7911
|
+
/* @__PURE__ */ jsx(
|
|
7912
|
+
SIcon,
|
|
7913
|
+
{
|
|
7914
|
+
name: "attachFile",
|
|
7915
|
+
size: iconSize,
|
|
7916
|
+
color: disabled ? "var(--cmp-filepicker-icon-disabled)" : "var(--color-grey-65)"
|
|
7917
|
+
}
|
|
7918
|
+
),
|
|
7919
|
+
/* @__PURE__ */ jsx(
|
|
7920
|
+
"span",
|
|
7921
|
+
{
|
|
7922
|
+
className: cn(
|
|
7923
|
+
"min-w-0 flex-1 truncate text-[12px]",
|
|
7924
|
+
inlinePlaceholder && "text-[color:var(--cmp-filepicker-text-placeholder)] transition-colors group-hover/filepicker:text-[color:var(--cmp-filepicker-text-default)]"
|
|
7925
|
+
),
|
|
7926
|
+
style: inlinePlaceholder ? void 0 : {
|
|
7927
|
+
color: disabled ? "var(--cmp-filepicker-text-disabled)" : hasFiles ? "var(--cmp-filepicker-text-default)" : "var(--cmp-filepicker-text-placeholder)"
|
|
7928
|
+
},
|
|
7929
|
+
children: displayText
|
|
7930
|
+
}
|
|
7931
|
+
)
|
|
7932
|
+
]
|
|
7933
|
+
}
|
|
7934
|
+
),
|
|
7935
|
+
showListbox && hasFiles && !disabled && /* @__PURE__ */ jsx(
|
|
7936
|
+
Ariakit.PopoverDisclosure,
|
|
7937
|
+
{
|
|
7938
|
+
render: /* @__PURE__ */ jsx(SGhostButton, { icon: "caretDown", size: "xxs", ariaLabel: "toggle file list" }),
|
|
7939
|
+
className: cn("shrink-0 transition-transform duration-150", listOpen && "rotate-180")
|
|
7940
|
+
}
|
|
7941
|
+
),
|
|
7942
|
+
!disabled && hasFiles && /* @__PURE__ */ jsx(SGhostButton, { icon: "close", size: "xxs", ariaLabel: "clear", onClick: clear })
|
|
7943
|
+
]
|
|
7944
|
+
}
|
|
7945
|
+
);
|
|
7946
|
+
const content = showListbox ? /* @__PURE__ */ jsxs(Ariakit.PopoverProvider, { open: listOpen, setOpen: setListOpen, placement: "bottom-start", children: [
|
|
7947
|
+
contentInner,
|
|
7693
7948
|
/* @__PURE__ */ jsx(
|
|
7694
|
-
|
|
7949
|
+
Ariakit.Popover,
|
|
7695
7950
|
{
|
|
7696
|
-
|
|
7697
|
-
|
|
7698
|
-
|
|
7699
|
-
|
|
7700
|
-
|
|
7701
|
-
|
|
7702
|
-
|
|
7703
|
-
|
|
7704
|
-
"aria-label": placeholder
|
|
7705
|
-
}
|
|
7706
|
-
),
|
|
7707
|
-
/* @__PURE__ */ jsxs(
|
|
7708
|
-
"button",
|
|
7709
|
-
{
|
|
7710
|
-
type: "button",
|
|
7711
|
-
disabled,
|
|
7712
|
-
onClick: open,
|
|
7713
|
-
"aria-label": placeholder,
|
|
7714
|
-
className: cn(
|
|
7715
|
-
"flex min-w-0 flex-1 items-center bg-transparent text-left",
|
|
7716
|
-
gapCls,
|
|
7717
|
-
disabled ? "cursor-not-allowed" : "cursor-pointer"
|
|
7718
|
-
),
|
|
7719
|
-
children: [
|
|
7720
|
-
/* @__PURE__ */ jsx(
|
|
7721
|
-
SIcon,
|
|
7722
|
-
{
|
|
7723
|
-
name: "attachFile",
|
|
7724
|
-
size: iconSize,
|
|
7725
|
-
color: disabled ? "var(--cmp-filepicker-icon-disabled)" : "var(--color-grey-65)"
|
|
7726
|
-
}
|
|
7727
|
-
),
|
|
7728
|
-
/* @__PURE__ */ jsx(
|
|
7729
|
-
"span",
|
|
7730
|
-
{
|
|
7731
|
-
className: "min-w-0 flex-1 truncate text-[12px]",
|
|
7732
|
-
style: {
|
|
7733
|
-
color: disabled ? "var(--cmp-filepicker-text-disabled)" : hasSingle ? "var(--cmp-filepicker-text-default)" : "var(--cmp-filepicker-text-placeholder)"
|
|
7734
|
-
},
|
|
7735
|
-
children: displayText
|
|
7736
|
-
}
|
|
7737
|
-
)
|
|
7738
|
-
]
|
|
7951
|
+
portal: true,
|
|
7952
|
+
portalElement: portalContainer,
|
|
7953
|
+
gutter: 4,
|
|
7954
|
+
unmountOnHide: true,
|
|
7955
|
+
getAnchorRect: () => contentBoxRef.current?.getBoundingClientRect() ?? null,
|
|
7956
|
+
style: { minWidth: contentBoxRef.current?.offsetWidth },
|
|
7957
|
+
className: "z-50 box-border flex flex-col items-stretch gap-[8px] rounded-[var(--cmp-listBox-radius)] bg-[var(--cmp-listBox-bg)] p-[8px] shadow-[2px_2px_12px_2px_rgba(0,0,0,0.1)]",
|
|
7958
|
+
children: filesArr.map((f, i) => /* @__PURE__ */ jsx(SChip, { value: f.name, editable: false, onRemove: () => removeChip(i) }, i))
|
|
7739
7959
|
}
|
|
7740
|
-
)
|
|
7741
|
-
|
|
7742
|
-
] });
|
|
7743
|
-
const chips = multiple && files.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-[8px] flex flex-wrap gap-[8px]", children: files.map((f, i) => /* @__PURE__ */ jsx(SChip, { value: f.name, editable: false, onRemove: () => removeChip(i) }, i)) });
|
|
7744
|
-
if (inline) {
|
|
7745
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("inline-flex flex-col", className), style, children: [
|
|
7746
|
-
/* @__PURE__ */ jsx(
|
|
7747
|
-
"div",
|
|
7748
|
-
{
|
|
7749
|
-
className: "box-border flex items-center rounded-[var(--cmp-filepicker-sm-radius)] border border-solid border-[color:var(--cmp-filepicker-border-default)] bg-[var(--cmp-filepicker-bg-default)]",
|
|
7750
|
-
style: {
|
|
7751
|
-
height: "var(--cmp-filepicker-sm-height)",
|
|
7752
|
-
width: typeof width === "number" ? `${width}px` : width
|
|
7753
|
-
},
|
|
7754
|
-
children: content
|
|
7755
|
-
}
|
|
7756
|
-
),
|
|
7757
|
-
chips
|
|
7758
|
-
] });
|
|
7759
|
-
}
|
|
7960
|
+
)
|
|
7961
|
+
] }) : contentInner;
|
|
7962
|
+
const chips = multiple && !useMultipleListBox && filesArr.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-[8px] flex flex-wrap gap-[8px]", children: filesArr.map((f, i) => /* @__PURE__ */ jsx(SChip, { value: f.name, editable: false, onRemove: () => removeChip(i) }, i)) });
|
|
7760
7963
|
return /* @__PURE__ */ jsxs("div", { className, style, children: [
|
|
7761
7964
|
/* @__PURE__ */ jsx(
|
|
7762
7965
|
SField,
|
|
7763
7966
|
{
|
|
7967
|
+
borderless: inline,
|
|
7764
7968
|
label,
|
|
7765
7969
|
labelWidth,
|
|
7766
7970
|
icon,
|
|
@@ -7788,6 +7992,7 @@ function SKeyValueTable({
|
|
|
7788
7992
|
fields = [],
|
|
7789
7993
|
search = false,
|
|
7790
7994
|
radius = "default",
|
|
7995
|
+
dense = false,
|
|
7791
7996
|
onChange,
|
|
7792
7997
|
onSearch,
|
|
7793
7998
|
className,
|
|
@@ -7795,6 +8000,8 @@ function SKeyValueTable({
|
|
|
7795
8000
|
}) {
|
|
7796
8001
|
if (fields.length === 0) return null;
|
|
7797
8002
|
const emit2 = (name, value) => onChange?.({ name, value });
|
|
8003
|
+
const cellHeight = dense ? "var(--cmp-table-body-dense-height)" : "var(--cmp-table-keyValue-height)";
|
|
8004
|
+
const cellPadY = dense ? "var(--cmp-table-body-paddingY-dense)" : "var(--cmp-table-keyValue-body-paddingY)";
|
|
7798
8005
|
const renderField = (f) => {
|
|
7799
8006
|
if (f.render) return f.render;
|
|
7800
8007
|
const opt = f.options ?? {};
|
|
@@ -7875,10 +8082,15 @@ function SKeyValueTable({
|
|
|
7875
8082
|
rowSpan: f.thRowSpan && f.thRowSpan > 1 ? f.thRowSpan : void 0,
|
|
7876
8083
|
colSpan: f.thColSpan && f.thColSpan > 1 ? f.thColSpan : void 0,
|
|
7877
8084
|
className: cn(
|
|
7878
|
-
"
|
|
8085
|
+
"box-border bg-[var(--cmp-table-header-bg)] px-[var(--cmp-table-header-paddingX)] text-left align-middle",
|
|
7879
8086
|
cellBorder,
|
|
7880
8087
|
f.thClass
|
|
7881
8088
|
),
|
|
8089
|
+
style: {
|
|
8090
|
+
height: cellHeight,
|
|
8091
|
+
paddingTop: cellPadY,
|
|
8092
|
+
paddingBottom: cellPadY
|
|
8093
|
+
},
|
|
7882
8094
|
children: /* @__PURE__ */ jsxs("div", { className: "flex h-full w-full items-center justify-between gap-[var(--cmp-table-header-gap)]", children: [
|
|
7883
8095
|
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-[8px]", children: [
|
|
7884
8096
|
/* @__PURE__ */ jsx("span", { className: "text-[12px] font-bold leading-[20px] text-[color:var(--sys-color-fg-primary)]", children: f.label }),
|
|
@@ -7904,10 +8116,11 @@ function SKeyValueTable({
|
|
|
7904
8116
|
rowSpan: f.tdRowSpan && f.tdRowSpan > 1 ? f.tdRowSpan : void 0,
|
|
7905
8117
|
colSpan: f.tdColSpan && f.tdColSpan > 1 ? f.tdColSpan : void 0,
|
|
7906
8118
|
className: cn(
|
|
7907
|
-
"
|
|
8119
|
+
"box-border bg-[var(--sys-color-bg-frame)] px-[var(--cmp-table-keyValue-body-paddingX-default)] align-middle",
|
|
7908
8120
|
cellBorder,
|
|
7909
8121
|
f.tdClass
|
|
7910
8122
|
),
|
|
8123
|
+
style: { height: cellHeight, paddingTop: cellPadY, paddingBottom: cellPadY },
|
|
7911
8124
|
children: renderField(f)
|
|
7912
8125
|
},
|
|
7913
8126
|
`td-${r}-${c}`
|
|
@@ -8028,9 +8241,9 @@ var POS_ANCHOR = {
|
|
|
8028
8241
|
"top-left": { top: 20, left: 20 },
|
|
8029
8242
|
"top-center": { top: 20, left: "50%" },
|
|
8030
8243
|
"top-right": { top: 20, right: 20 },
|
|
8031
|
-
"bottom-left": { bottom:
|
|
8032
|
-
"bottom-center": { bottom:
|
|
8033
|
-
"bottom-right": { bottom:
|
|
8244
|
+
"bottom-left": { bottom: 100, left: 20 },
|
|
8245
|
+
"bottom-center": { bottom: 100, left: "50%" },
|
|
8246
|
+
"bottom-right": { bottom: 100, right: 20 }
|
|
8034
8247
|
};
|
|
8035
8248
|
var counter = 0;
|
|
8036
8249
|
var SToastContainer = forwardRef(
|
|
@@ -8390,7 +8603,7 @@ var SChipInput = forwardRef(function SChipInput2({
|
|
|
8390
8603
|
disabledChips = [],
|
|
8391
8604
|
size = "sm",
|
|
8392
8605
|
disabled = false,
|
|
8393
|
-
placeholder = "\uC785\uB825\
|
|
8606
|
+
placeholder = "\uD0DC\uADF8 \uC785\uB825 (Enter\uB85C \uB4F1\uB85D / \uCF64\uB9C8\uB85C \uAD6C\uBD84 / \uB744\uC5B4\uC4F0\uAE30 \uBD88\uAC00)",
|
|
8394
8607
|
name,
|
|
8395
8608
|
rules,
|
|
8396
8609
|
error,
|
|
@@ -8541,6 +8754,7 @@ var SChipInput = forwardRef(function SChipInput2({
|
|
|
8541
8754
|
{
|
|
8542
8755
|
label,
|
|
8543
8756
|
labelWidth,
|
|
8757
|
+
labelHeight: `calc(var(--cmp-chipInput-${size}-minHeight) + 2px)`,
|
|
8544
8758
|
icon,
|
|
8545
8759
|
labelTooltip,
|
|
8546
8760
|
labelTooltipProps,
|
|
@@ -8611,9 +8825,11 @@ var SChipInput = forwardRef(function SChipInput2({
|
|
|
8611
8825
|
paddingInline: isFieldFilled ? "var(--cmp-chip-paddingX)" : void 0,
|
|
8612
8826
|
borderWidth: isFieldFilled ? "var(--cmp-chip-border-width)" : void 0,
|
|
8613
8827
|
borderStyle: isFieldFilled ? "solid" : void 0,
|
|
8614
|
-
|
|
8828
|
+
// 작성중 필드는 SChip의 editable 수정중(editing) 스타일과 동일하게 —
|
|
8829
|
+
// bg/보더/글자색 모두 focus 토큰을 사용한다.
|
|
8830
|
+
borderColor: isFieldFilled ? "var(--cmp-chip-border-focus)" : void 0,
|
|
8615
8831
|
borderRadius: isFieldFilled ? "var(--cmp-chip-radius)" : 0,
|
|
8616
|
-
background: isFieldFilled ? "var(--cmp-chip-bg-
|
|
8832
|
+
background: isFieldFilled ? "var(--cmp-chip-bg-focus)" : "transparent",
|
|
8617
8833
|
overflow: "hidden"
|
|
8618
8834
|
},
|
|
8619
8835
|
children: [
|
|
@@ -8622,7 +8838,7 @@ var SChipInput = forwardRef(function SChipInput2({
|
|
|
8622
8838
|
{
|
|
8623
8839
|
"aria-hidden": true,
|
|
8624
8840
|
className: cn(
|
|
8625
|
-
"invisible col-start-1 row-start-1 whitespace-pre font-
|
|
8841
|
+
"invisible col-start-1 row-start-1 whitespace-pre font-normal",
|
|
8626
8842
|
size === "md" ? "text-14 leading-24" : "text-12 leading-20"
|
|
8627
8843
|
),
|
|
8628
8844
|
children: inputValue !== "" ? inputValue : values.length === 0 ? placeholder : ""
|
|
@@ -8635,12 +8851,14 @@ var SChipInput = forwardRef(function SChipInput2({
|
|
|
8635
8851
|
name: resolvedName,
|
|
8636
8852
|
size: 1,
|
|
8637
8853
|
className: cn(
|
|
8638
|
-
"s-chip-input__input col-start-1 row-start-1 w-full border-0 bg-transparent p-0 font-
|
|
8854
|
+
"s-chip-input__input col-start-1 row-start-1 w-full border-0 bg-transparent p-0 font-normal text-(--cmp-chip-content-focus) outline-none placeholder:text-(--cmp-chipInput-text-placeholder) disabled:cursor-not-allowed",
|
|
8639
8855
|
size === "md" ? "text-14 leading-24" : "text-12 leading-20"
|
|
8640
8856
|
),
|
|
8641
8857
|
style: {
|
|
8642
8858
|
minWidth: "1ch",
|
|
8643
|
-
height
|
|
8859
|
+
// height는 지정하지 않고 line-height(20/24px)에 맞춰 자동 크기로 둔다.
|
|
8860
|
+
// var(--cmp-chip-height)(24px)로 고정하면 네이티브 <input>이 남는 세로 여백에
|
|
8861
|
+
// 텍스트를 아래로 밀어 넣어, 확정된 chip 텍스트보다 2px 낮게 보인다.
|
|
8644
8862
|
margin: 0,
|
|
8645
8863
|
overflow: "hidden",
|
|
8646
8864
|
textOverflow: "ellipsis"
|
|
@@ -8685,7 +8903,7 @@ var SChipInput = forwardRef(function SChipInput2({
|
|
|
8685
8903
|
showMetaInfo && /* @__PURE__ */ jsxs(
|
|
8686
8904
|
"div",
|
|
8687
8905
|
{
|
|
8688
|
-
className: "s-chip-input__meta flex items-center gap-8",
|
|
8906
|
+
className: "s-chip-input__meta ml-auto flex items-center gap-8",
|
|
8689
8907
|
onMouseDown: (e) => e.preventDefault(),
|
|
8690
8908
|
children: [
|
|
8691
8909
|
/* @__PURE__ */ jsx(
|