sellmate-design-system-react 0.1.10 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/SActionModal/SActionModal.cjs +3 -1
- package/dist/components/SActionModal/SActionModal.cjs.map +1 -1
- package/dist/components/SActionModal/SActionModal.js +3 -1
- package/dist/components/SActionModal/SActionModal.js.map +1 -1
- package/dist/components/SBarcodeInput/SBarcodeInput.cjs +15 -2
- package/dist/components/SBarcodeInput/SBarcodeInput.cjs.map +1 -1
- package/dist/components/SBarcodeInput/SBarcodeInput.d.ts +3 -1
- package/dist/components/SBarcodeInput/SBarcodeInput.js +15 -2
- package/dist/components/SBarcodeInput/SBarcodeInput.js.map +1 -1
- package/dist/components/SCalendar/SCalendar.cjs +2 -0
- package/dist/components/SCalendar/SCalendar.cjs.map +1 -1
- package/dist/components/SCalendar/SCalendar.js +2 -0
- package/dist/components/SCalendar/SCalendar.js.map +1 -1
- package/dist/components/SChip/SChip.cjs +2 -0
- package/dist/components/SChip/SChip.cjs.map +1 -1
- package/dist/components/SChip/SChip.js +2 -0
- package/dist/components/SChip/SChip.js.map +1 -1
- package/dist/components/SChipInput/SChipInput.cjs +21 -3
- package/dist/components/SChipInput/SChipInput.cjs.map +1 -1
- package/dist/components/SChipInput/SChipInput.d.ts +5 -0
- package/dist/components/SChipInput/SChipInput.js +21 -3
- package/dist/components/SChipInput/SChipInput.js.map +1 -1
- package/dist/components/SChipInput/index.d.ts +1 -1
- package/dist/components/SConfirmModal/SConfirmModal.cjs +13 -10
- package/dist/components/SConfirmModal/SConfirmModal.cjs.map +1 -1
- package/dist/components/SConfirmModal/SConfirmModal.d.ts +7 -4
- package/dist/components/SConfirmModal/SConfirmModal.js +13 -10
- package/dist/components/SConfirmModal/SConfirmModal.js.map +1 -1
- package/dist/components/SDatePicker/SDatePicker.cjs +15 -2
- package/dist/components/SDatePicker/SDatePicker.cjs.map +1 -1
- package/dist/components/SDatePicker/SDatePicker.d.ts +3 -1
- package/dist/components/SDatePicker/SDatePicker.js +15 -2
- package/dist/components/SDatePicker/SDatePicker.js.map +1 -1
- package/dist/components/SDateRangePicker/SDateRangePicker.cjs +15 -2
- package/dist/components/SDateRangePicker/SDateRangePicker.cjs.map +1 -1
- package/dist/components/SDateRangePicker/SDateRangePicker.d.ts +3 -1
- package/dist/components/SDateRangePicker/SDateRangePicker.js +15 -2
- package/dist/components/SDateRangePicker/SDateRangePicker.js.map +1 -1
- package/dist/components/SDropdownButton/SDropdownButton.cjs +2 -0
- package/dist/components/SDropdownButton/SDropdownButton.cjs.map +1 -1
- package/dist/components/SDropdownButton/SDropdownButton.js +2 -0
- package/dist/components/SDropdownButton/SDropdownButton.js.map +1 -1
- package/dist/components/SField/SField.cjs +13 -2
- package/dist/components/SField/SField.cjs.map +1 -1
- package/dist/components/SField/SField.d.ts +4 -1
- package/dist/components/SField/SField.js +13 -2
- package/dist/components/SField/SField.js.map +1 -1
- package/dist/components/SFilePicker/SFilePicker.cjs +16 -3
- package/dist/components/SFilePicker/SFilePicker.cjs.map +1 -1
- package/dist/components/SFilePicker/SFilePicker.d.ts +3 -1
- package/dist/components/SFilePicker/SFilePicker.js +16 -3
- package/dist/components/SFilePicker/SFilePicker.js.map +1 -1
- package/dist/components/SGhostButton/SGhostButton.cjs +2 -0
- package/dist/components/SGhostButton/SGhostButton.cjs.map +1 -1
- package/dist/components/SGhostButton/SGhostButton.js +2 -0
- package/dist/components/SGhostButton/SGhostButton.js.map +1 -1
- package/dist/components/SGuide/SGuide.cjs +2 -0
- package/dist/components/SGuide/SGuide.cjs.map +1 -1
- package/dist/components/SGuide/SGuide.js +2 -0
- package/dist/components/SGuide/SGuide.js.map +1 -1
- package/dist/components/SInput/SInput.cjs +15 -2
- package/dist/components/SInput/SInput.cjs.map +1 -1
- package/dist/components/SInput/SInput.d.ts +4 -1
- package/dist/components/SInput/SInput.js +15 -2
- package/dist/components/SInput/SInput.js.map +1 -1
- package/dist/components/SKeyValueTable/SKeyValueTable.cjs +496 -206
- package/dist/components/SKeyValueTable/SKeyValueTable.cjs.map +1 -1
- package/dist/components/SKeyValueTable/SKeyValueTable.d.ts +27 -6
- package/dist/components/SKeyValueTable/SKeyValueTable.js +495 -205
- package/dist/components/SKeyValueTable/SKeyValueTable.js.map +1 -1
- package/dist/components/SLoadingModal/SLoadingModal.cjs +3 -1
- package/dist/components/SLoadingModal/SLoadingModal.cjs.map +1 -1
- package/dist/components/SLoadingModal/SLoadingModal.js +3 -1
- package/dist/components/SLoadingModal/SLoadingModal.js.map +1 -1
- package/dist/components/SModalContainer/SModalContainer.cjs +3 -1
- package/dist/components/SModalContainer/SModalContainer.cjs.map +1 -1
- package/dist/components/SModalContainer/SModalContainer.js +3 -1
- package/dist/components/SModalContainer/SModalContainer.js.map +1 -1
- package/dist/components/SNumberInput/SNumberInput.cjs +15 -2
- package/dist/components/SNumberInput/SNumberInput.cjs.map +1 -1
- package/dist/components/SNumberInput/SNumberInput.d.ts +2 -0
- package/dist/components/SNumberInput/SNumberInput.js +15 -2
- package/dist/components/SNumberInput/SNumberInput.js.map +1 -1
- package/dist/components/SPopover/SPopover.cjs +2 -0
- package/dist/components/SPopover/SPopover.cjs.map +1 -1
- package/dist/components/SPopover/SPopover.js +2 -0
- package/dist/components/SPopover/SPopover.js.map +1 -1
- package/dist/components/SPortal/SPortal.cjs +2 -0
- package/dist/components/SPortal/SPortal.cjs.map +1 -1
- package/dist/components/SPortal/SPortal.js +2 -0
- package/dist/components/SPortal/SPortal.js.map +1 -1
- package/dist/components/SSelect/SSelect.cjs +530 -262
- package/dist/components/SSelect/SSelect.cjs.map +1 -1
- package/dist/components/SSelect/SSelect.d.ts +4 -2
- package/dist/components/SSelect/SSelect.js +531 -262
- package/dist/components/SSelect/SSelect.js.map +1 -1
- package/dist/components/STable/STable.cjs +529 -261
- package/dist/components/STable/STable.cjs.map +1 -1
- package/dist/components/STable/STable.js +530 -261
- package/dist/components/STable/STable.js.map +1 -1
- package/dist/components/STextLink/STextLink.cjs +2 -0
- package/dist/components/STextLink/STextLink.cjs.map +1 -1
- package/dist/components/STextLink/STextLink.js +2 -0
- package/dist/components/STextLink/STextLink.js.map +1 -1
- package/dist/components/STextarea/STextarea.cjs +15 -2
- package/dist/components/STextarea/STextarea.cjs.map +1 -1
- package/dist/components/STextarea/STextarea.d.ts +2 -0
- package/dist/components/STextarea/STextarea.js +15 -2
- package/dist/components/STextarea/STextarea.js.map +1 -1
- package/dist/components/SToast/SToast.cjs +2 -0
- package/dist/components/SToast/SToast.cjs.map +1 -1
- package/dist/components/SToast/SToast.js +2 -0
- package/dist/components/SToast/SToast.js.map +1 -1
- package/dist/components/SToast/SToastContainer.cjs +2 -0
- package/dist/components/SToast/SToastContainer.cjs.map +1 -1
- package/dist/components/SToast/SToastContainer.js +2 -0
- package/dist/components/SToast/SToastContainer.js.map +1 -1
- package/dist/components/STooltip/STooltip.cjs +2 -0
- package/dist/components/STooltip/STooltip.cjs.map +1 -1
- package/dist/components/STooltip/STooltip.js +2 -0
- package/dist/components/STooltip/STooltip.js.map +1 -1
- package/dist/index.cjs +412 -184
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +413 -184
- package/dist/index.js.map +1 -1
- package/dist/lib/portal-container.d.ts +7 -0
- package/dist/styles.css +61 -37
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3533,10 +3533,15 @@ var FLOATING_SLIDE_ANIM = [
|
|
|
3533
3533
|
"data-[state=closed]:data-[side=right]:animate-floating-out-right"
|
|
3534
3534
|
].join(" ");
|
|
3535
3535
|
var PortalContainerContext = react.createContext(null);
|
|
3536
|
+
var InsideModalContext = react.createContext(false);
|
|
3536
3537
|
var PortalContainerProvider = PortalContainerContext.Provider;
|
|
3538
|
+
var InsideModalProvider = InsideModalContext.Provider;
|
|
3537
3539
|
function usePortalContainer() {
|
|
3538
3540
|
return react.useContext(PortalContainerContext) ?? void 0;
|
|
3539
3541
|
}
|
|
3542
|
+
function useInsideModal() {
|
|
3543
|
+
return react.useContext(InsideModalContext);
|
|
3544
|
+
}
|
|
3540
3545
|
var SIZE_CONFIG = {
|
|
3541
3546
|
sm: {
|
|
3542
3547
|
gap: 4,
|
|
@@ -4647,7 +4652,7 @@ function SModalContainer({
|
|
|
4647
4652
|
className: "absolute right-[16px] top-[16px] z-10"
|
|
4648
4653
|
}
|
|
4649
4654
|
),
|
|
4650
|
-
/* @__PURE__ */ jsxRuntime.jsx(PortalContainerProvider, { value: portalContainer, children })
|
|
4655
|
+
/* @__PURE__ */ jsxRuntime.jsx(InsideModalProvider, { value: true, children: /* @__PURE__ */ jsxRuntime.jsx(PortalContainerProvider, { value: portalContainer, children }) })
|
|
4651
4656
|
]
|
|
4652
4657
|
}
|
|
4653
4658
|
)
|
|
@@ -4693,7 +4698,8 @@ function SConfirmModal({
|
|
|
4693
4698
|
tagSize = "sm",
|
|
4694
4699
|
tagColor = "grey",
|
|
4695
4700
|
slotLabel,
|
|
4696
|
-
|
|
4701
|
+
tagSlot,
|
|
4702
|
+
optionSlot,
|
|
4697
4703
|
mainButtonLabel = "\uD655\uC778",
|
|
4698
4704
|
mainButtonName,
|
|
4699
4705
|
subButtonLabel,
|
|
@@ -4703,6 +4709,9 @@ function SConfirmModal({
|
|
|
4703
4709
|
}) {
|
|
4704
4710
|
const iconName = TYPE_ICON[type];
|
|
4705
4711
|
const mainStyle = MAIN_BUTTON_STYLE[mainButtonName ?? DEFAULT_MAIN_BUTTON[type]];
|
|
4712
|
+
const tagNode = tagSlot ?? (tagLabel ? /* @__PURE__ */ jsxRuntime.jsx(STag, { shape: tagShape, size: tagSize, color: tagColor, label: tagLabel }) : null);
|
|
4713
|
+
const optionNode = optionSlot ?? (slotLabel ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: slotLabel }) : null);
|
|
4714
|
+
const hasBody = topMessage.length > 0 || bottomMessage.length > 0 || tagNode != null || optionNode != null;
|
|
4706
4715
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4707
4716
|
SModalContainer,
|
|
4708
4717
|
{
|
|
@@ -4728,15 +4737,12 @@ function SConfirmModal({
|
|
|
4728
4737
|
}
|
|
4729
4738
|
)
|
|
4730
4739
|
] }),
|
|
4731
|
-
|
|
4740
|
+
hasBody && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-[20px] text-center text-[12px] font-normal leading-[20px] text-[color:var(--cmp-modal-confirm-message-color)] w-full", children: [
|
|
4732
4741
|
topMessage.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-[2px]", children: topMessage.map((m, i) => /* @__PURE__ */ jsxRuntime.jsx("p", { className: "m-0", children: m }, i)) }),
|
|
4733
|
-
|
|
4734
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4735
|
-
|
|
4736
|
-
|
|
4737
|
-
children
|
|
4738
|
-
] }),
|
|
4739
|
-
bottomMessage.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-[2px]", children: bottomMessage.map((m, i) => /* @__PURE__ */ jsxRuntime.jsx("p", { className: "m-0", children: m }, i)) })
|
|
4742
|
+
tagNode != null && // tag 위치 content-box: 흰 박스 + 1px 테두리 + 패딩 + 14/700 (원본 sd-confirm-modal__content-box)
|
|
4743
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center gap-[8px] rounded-[8px] border border-solid border-[color:var(--color-grey-30)] bg-white px-[16px] py-[12px] text-[14px] font-bold leading-[22px] w-full", children: tagNode }),
|
|
4744
|
+
bottomMessage.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-[2px]", children: bottomMessage.map((m, i) => /* @__PURE__ */ jsxRuntime.jsx("p", { className: "m-0", children: m }, i)) }),
|
|
4745
|
+
optionNode != null && optionNode
|
|
4740
4746
|
] })
|
|
4741
4747
|
] }),
|
|
4742
4748
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-[8px]", children: [
|
|
@@ -5237,6 +5243,7 @@ var SField = react.forwardRef(function SField2({
|
|
|
5237
5243
|
name,
|
|
5238
5244
|
label = "",
|
|
5239
5245
|
icon,
|
|
5246
|
+
iconColor,
|
|
5240
5247
|
labelTooltip = "",
|
|
5241
5248
|
labelTooltipProps,
|
|
5242
5249
|
labelWidth,
|
|
@@ -5314,7 +5321,15 @@ var SField = react.forwardRef(function SField2({
|
|
|
5314
5321
|
lineHeight: `${s.lineHeight}px`
|
|
5315
5322
|
},
|
|
5316
5323
|
children: [
|
|
5317
|
-
icon && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5324
|
+
icon && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5325
|
+
SIcon,
|
|
5326
|
+
{
|
|
5327
|
+
name: icon,
|
|
5328
|
+
size: s.icon,
|
|
5329
|
+
color: iconColor,
|
|
5330
|
+
style: { marginRight: s.labelGap }
|
|
5331
|
+
}
|
|
5332
|
+
),
|
|
5318
5333
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 overflow-hidden text-ellipsis whitespace-nowrap", children: label }),
|
|
5319
5334
|
(labelTooltip !== "" || labelTooltipProps) && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0", style: { marginLeft: s.labelGap }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5320
5335
|
STooltip,
|
|
@@ -5364,7 +5379,7 @@ var SField = react.forwardRef(function SField2({
|
|
|
5364
5379
|
borderBottomLeftRadius: s.radius - 1
|
|
5365
5380
|
},
|
|
5366
5381
|
children: [
|
|
5367
|
-
icon && !label && /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: icon, size: s.icon }),
|
|
5382
|
+
icon && !label && /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: icon, size: s.icon, color: iconColor }),
|
|
5368
5383
|
effectiveAddonLabel
|
|
5369
5384
|
]
|
|
5370
5385
|
}
|
|
@@ -5436,6 +5451,7 @@ var SSelect = react.forwardRef(function SSelect2({
|
|
|
5436
5451
|
label,
|
|
5437
5452
|
labelWidth,
|
|
5438
5453
|
icon,
|
|
5454
|
+
iconColor,
|
|
5439
5455
|
labelTooltip,
|
|
5440
5456
|
addonLabel,
|
|
5441
5457
|
addonAlign,
|
|
@@ -5447,18 +5463,15 @@ var SSelect = react.forwardRef(function SSelect2({
|
|
|
5447
5463
|
}, ref) {
|
|
5448
5464
|
const multi = type === "multi" || type === "multi_depth";
|
|
5449
5465
|
const portalContainer = usePortalContainer();
|
|
5466
|
+
const insideModal = useInsideModal();
|
|
5450
5467
|
const [search, setSearch] = react.useState("");
|
|
5451
5468
|
const [ruleError, setRuleError] = react.useState("");
|
|
5452
5469
|
const [open, setOpen] = react.useState(false);
|
|
5470
|
+
const [pendingOpen, setPendingOpen] = react.useState(false);
|
|
5471
|
+
const [focusedIndex, setFocusedIndex] = react.useState(-1);
|
|
5453
5472
|
const triggerRef = react.useRef(null);
|
|
5454
|
-
react.
|
|
5455
|
-
|
|
5456
|
-
() => ({
|
|
5457
|
-
focus: () => triggerRef.current?.focus(),
|
|
5458
|
-
open: () => setOpen(true)
|
|
5459
|
-
}),
|
|
5460
|
-
[]
|
|
5461
|
-
);
|
|
5473
|
+
const searchInputRef = react.useRef(null);
|
|
5474
|
+
const listRef = react.useRef(null);
|
|
5462
5475
|
const flat = react.useMemo(() => flattenOptions(options), [options]);
|
|
5463
5476
|
const selectable = react.useMemo(() => selectableOptions(flat), [flat]);
|
|
5464
5477
|
const hasLeaf = react.useMemo(() => flat.some((o) => !o.isGroup), [flat]);
|
|
@@ -5476,6 +5489,46 @@ var SSelect = react.forwardRef(function SSelect2({
|
|
|
5476
5489
|
const arr = Array.isArray(value) ? value : [value];
|
|
5477
5490
|
return arr.map((v) => v != null && typeof v === "object" ? v.value : v).filter((v) => v != null && v !== "").map(String);
|
|
5478
5491
|
}, [value]);
|
|
5492
|
+
const selectedRef = react.useRef(selected);
|
|
5493
|
+
selectedRef.current = selected;
|
|
5494
|
+
const emit2 = (next) => {
|
|
5495
|
+
if (!onValueChange) return;
|
|
5496
|
+
const mapped = next.map(
|
|
5497
|
+
(v) => emitValue ? rawByValue.get(v) ?? v : optionByValue.get(v) ?? { value: v, label: v }
|
|
5498
|
+
);
|
|
5499
|
+
onValueChange(multi ? mapped : mapped[0] ?? (emitValue ? "" : null));
|
|
5500
|
+
};
|
|
5501
|
+
const commitOpen = (next) => {
|
|
5502
|
+
setOpen(next);
|
|
5503
|
+
onOpenChange?.(next);
|
|
5504
|
+
if (!next) {
|
|
5505
|
+
setPendingOpen(false);
|
|
5506
|
+
setSearch("");
|
|
5507
|
+
if (rules && rules.length > 0) {
|
|
5508
|
+
setRuleError(runRules(multi ? selectedRef.current : selectedRef.current[0] ?? "", rules));
|
|
5509
|
+
}
|
|
5510
|
+
}
|
|
5511
|
+
};
|
|
5512
|
+
const requestOpen = (next) => {
|
|
5513
|
+
if (next && insideModal && portalContainer == null) {
|
|
5514
|
+
setPendingOpen(true);
|
|
5515
|
+
return;
|
|
5516
|
+
}
|
|
5517
|
+
commitOpen(next);
|
|
5518
|
+
};
|
|
5519
|
+
react.useEffect(() => {
|
|
5520
|
+
if (!insideModal || portalContainer == null || !pendingOpen) return;
|
|
5521
|
+
setPendingOpen(false);
|
|
5522
|
+
commitOpen(true);
|
|
5523
|
+
}, [insideModal, pendingOpen, portalContainer]);
|
|
5524
|
+
react.useImperativeHandle(
|
|
5525
|
+
ref,
|
|
5526
|
+
() => ({
|
|
5527
|
+
focus: () => triggerRef.current?.focus(),
|
|
5528
|
+
open: () => requestOpen(true)
|
|
5529
|
+
}),
|
|
5530
|
+
[insideModal, portalContainer]
|
|
5531
|
+
);
|
|
5479
5532
|
useFormField({
|
|
5480
5533
|
name,
|
|
5481
5534
|
validate: () => {
|
|
@@ -5485,13 +5538,6 @@ var SSelect = react.forwardRef(function SSelect2({
|
|
|
5485
5538
|
},
|
|
5486
5539
|
resetValidation: () => setRuleError("")
|
|
5487
5540
|
});
|
|
5488
|
-
const emit2 = (next) => {
|
|
5489
|
-
if (!onValueChange) return;
|
|
5490
|
-
const mapped = next.map(
|
|
5491
|
-
(v) => emitValue ? rawByValue.get(v) ?? v : optionByValue.get(v) ?? { value: v, label: v }
|
|
5492
|
-
);
|
|
5493
|
-
onValueChange(multi ? mapped : mapped[0] ?? (emitValue ? "" : null));
|
|
5494
|
-
};
|
|
5495
5541
|
const filtered = react.useMemo(() => {
|
|
5496
5542
|
if (!showSearch || search.trim() === "") return flat;
|
|
5497
5543
|
const q = search.trim().toLowerCase();
|
|
@@ -5502,6 +5548,16 @@ var SSelect = react.forwardRef(function SSelect2({
|
|
|
5502
5548
|
const allValues = selectable.map((o) => o.value);
|
|
5503
5549
|
const allSelected = allValues.length > 0 && allValues.every((v) => selected.includes(v));
|
|
5504
5550
|
const hasItems = filtered.some((o) => !o.isGroup);
|
|
5551
|
+
const navigableItems = react.useMemo(() => {
|
|
5552
|
+
const items = [];
|
|
5553
|
+
if (multi && useSelectAll && allValues.length > 0) {
|
|
5554
|
+
items.push({ value: "__select_all__", isSelectAll: true });
|
|
5555
|
+
}
|
|
5556
|
+
filtered.forEach((o) => {
|
|
5557
|
+
if (!o.isGroup && !o.disabled) items.push({ value: o.value });
|
|
5558
|
+
});
|
|
5559
|
+
return items;
|
|
5560
|
+
}, [allValues.length, filtered, multi, useSelectAll]);
|
|
5505
5561
|
const triggerText = (() => {
|
|
5506
5562
|
if (selected.length === 0) return placeholder;
|
|
5507
5563
|
if (multi) {
|
|
@@ -5511,26 +5567,119 @@ var SSelect = react.forwardRef(function SSelect2({
|
|
|
5511
5567
|
return labelByValue.get(selected[0]) ?? selected[0];
|
|
5512
5568
|
})();
|
|
5513
5569
|
const isPlaceholder = selected.length === 0;
|
|
5514
|
-
const
|
|
5515
|
-
|
|
5570
|
+
const handleSelect = (nextValue) => {
|
|
5571
|
+
if (multi) {
|
|
5572
|
+
const next = selected.includes(nextValue) ? selected.filter((v) => v !== nextValue) : [...selected, nextValue];
|
|
5573
|
+
emit2(next);
|
|
5574
|
+
return;
|
|
5575
|
+
}
|
|
5576
|
+
emit2([nextValue]);
|
|
5577
|
+
commitOpen(false);
|
|
5578
|
+
};
|
|
5579
|
+
const handleSelectAll = () => {
|
|
5580
|
+
emit2(allSelected ? [] : allValues);
|
|
5581
|
+
};
|
|
5582
|
+
react.useEffect(() => {
|
|
5583
|
+
if (!open) {
|
|
5584
|
+
setFocusedIndex(-1);
|
|
5585
|
+
return;
|
|
5586
|
+
}
|
|
5587
|
+
setFocusedIndex(navigableItems.length > 0 ? 0 : -1);
|
|
5588
|
+
}, [open, navigableItems.length]);
|
|
5589
|
+
react.useEffect(() => {
|
|
5590
|
+
if (!open) return;
|
|
5591
|
+
setFocusedIndex(navigableItems.length > 0 ? 0 : -1);
|
|
5592
|
+
}, [search, open, navigableItems.length]);
|
|
5593
|
+
react.useEffect(() => {
|
|
5594
|
+
if (!open || focusedIndex < 0) return;
|
|
5595
|
+
const list = listRef.current;
|
|
5596
|
+
const focusedEl = list?.querySelector('[data-select-focused="true"]');
|
|
5597
|
+
if (!list || !focusedEl) return;
|
|
5598
|
+
const listRect = list.getBoundingClientRect();
|
|
5599
|
+
const itemRect = focusedEl.getBoundingClientRect();
|
|
5600
|
+
if (itemRect.top < listRect.top) {
|
|
5601
|
+
list.scrollTop += itemRect.top - listRect.top;
|
|
5602
|
+
} else if (itemRect.bottom > listRect.bottom) {
|
|
5603
|
+
list.scrollTop += itemRect.bottom - listRect.bottom;
|
|
5604
|
+
}
|
|
5605
|
+
}, [focusedIndex, open]);
|
|
5606
|
+
const moveFocusedIndex = (direction) => {
|
|
5607
|
+
if (!open || navigableItems.length === 0) return;
|
|
5608
|
+
setFocusedIndex((current) => {
|
|
5609
|
+
if (direction === "next") {
|
|
5610
|
+
return current < 0 ? 0 : (current + 1) % navigableItems.length;
|
|
5611
|
+
}
|
|
5612
|
+
return current <= 0 ? navigableItems.length - 1 : current - 1;
|
|
5613
|
+
});
|
|
5614
|
+
};
|
|
5615
|
+
const selectFocusedItem = () => {
|
|
5616
|
+
if (focusedIndex < 0 || focusedIndex >= navigableItems.length) return;
|
|
5617
|
+
const focused = navigableItems[focusedIndex];
|
|
5618
|
+
if (focused.isSelectAll) {
|
|
5619
|
+
handleSelectAll();
|
|
5620
|
+
return;
|
|
5621
|
+
}
|
|
5622
|
+
handleSelect(focused.value);
|
|
5623
|
+
};
|
|
5624
|
+
const handleKeyDown = (event) => {
|
|
5625
|
+
if (!open) {
|
|
5626
|
+
if ((event.key === "ArrowDown" || event.key === "ArrowUp") && !effectiveDisabled) {
|
|
5627
|
+
event.preventDefault();
|
|
5628
|
+
requestOpen(true);
|
|
5629
|
+
}
|
|
5630
|
+
return;
|
|
5631
|
+
}
|
|
5632
|
+
if (event.key === "ArrowDown") {
|
|
5633
|
+
event.preventDefault();
|
|
5634
|
+
moveFocusedIndex("next");
|
|
5635
|
+
return;
|
|
5636
|
+
}
|
|
5637
|
+
if (event.key === "ArrowUp") {
|
|
5638
|
+
event.preventDefault();
|
|
5639
|
+
moveFocusedIndex("prev");
|
|
5640
|
+
return;
|
|
5641
|
+
}
|
|
5642
|
+
if (event.key === "Enter") {
|
|
5643
|
+
event.preventDefault();
|
|
5644
|
+
selectFocusedItem();
|
|
5645
|
+
return;
|
|
5646
|
+
}
|
|
5647
|
+
if (event.key === "Escape") {
|
|
5648
|
+
event.preventDefault();
|
|
5649
|
+
commitOpen(false);
|
|
5650
|
+
}
|
|
5651
|
+
};
|
|
5652
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5653
|
+
SField,
|
|
5516
5654
|
{
|
|
5517
|
-
|
|
5518
|
-
|
|
5519
|
-
|
|
5520
|
-
|
|
5521
|
-
|
|
5522
|
-
|
|
5523
|
-
|
|
5524
|
-
|
|
5525
|
-
|
|
5526
|
-
|
|
5527
|
-
|
|
5655
|
+
label,
|
|
5656
|
+
labelWidth,
|
|
5657
|
+
icon,
|
|
5658
|
+
iconColor,
|
|
5659
|
+
labelTooltip,
|
|
5660
|
+
labelTooltipProps,
|
|
5661
|
+
addonLabel,
|
|
5662
|
+
addonAlign,
|
|
5663
|
+
hint,
|
|
5664
|
+
error: error || ruleError !== "",
|
|
5665
|
+
status: rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0,
|
|
5666
|
+
errorMessage: ruleError !== "" ? ruleError : errorMessage,
|
|
5667
|
+
disabled: effectiveDisabled,
|
|
5668
|
+
width,
|
|
5669
|
+
className,
|
|
5670
|
+
style,
|
|
5528
5671
|
children: [
|
|
5672
|
+
name && /* @__PURE__ */ jsxRuntime.jsx("input", { type: "hidden", name, value: selected.join(",") }),
|
|
5529
5673
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5530
|
-
|
|
5674
|
+
"button",
|
|
5531
5675
|
{
|
|
5532
5676
|
ref: triggerRef,
|
|
5677
|
+
type: "button",
|
|
5533
5678
|
disabled: effectiveDisabled,
|
|
5679
|
+
"aria-haspopup": "listbox",
|
|
5680
|
+
"aria-expanded": open,
|
|
5681
|
+
onClick: () => requestOpen(!open),
|
|
5682
|
+
onKeyDown: handleKeyDown,
|
|
5534
5683
|
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",
|
|
5535
5684
|
style: {
|
|
5536
5685
|
color: effectiveDisabled ? "var(--cmp-select-text-disabled)" : isPlaceholder ? "var(--cmp-select-icon-default)" : "var(--cmp-select-text-default)"
|
|
@@ -5555,178 +5704,229 @@ var SSelect = react.forwardRef(function SSelect2({
|
|
|
5555
5704
|
]
|
|
5556
5705
|
}
|
|
5557
5706
|
),
|
|
5558
|
-
/* @__PURE__ */ jsxRuntime.
|
|
5559
|
-
|
|
5707
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5708
|
+
SPortal,
|
|
5560
5709
|
{
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
|
|
5710
|
+
open,
|
|
5711
|
+
onClose: () => commitOpen(false),
|
|
5712
|
+
onOpenChange: (next) => {
|
|
5713
|
+
if (next) requestOpen(true);
|
|
5714
|
+
},
|
|
5715
|
+
anchorRef: triggerRef,
|
|
5716
|
+
placement: "bottom",
|
|
5717
|
+
align: "start",
|
|
5718
|
+
offset: 4,
|
|
5719
|
+
fit: !dropdownWidth,
|
|
5720
|
+
onOpenAutoFocus: (event) => {
|
|
5721
|
+
if (!showSearch) {
|
|
5722
|
+
event.preventDefault();
|
|
5723
|
+
return;
|
|
5724
|
+
}
|
|
5725
|
+
event.preventDefault();
|
|
5726
|
+
requestAnimationFrame(() => searchInputRef.current?.focus());
|
|
5727
|
+
},
|
|
5728
|
+
onCloseAutoFocus: (event) => {
|
|
5729
|
+
event.preventDefault();
|
|
5730
|
+
triggerRef.current?.focus();
|
|
5731
|
+
},
|
|
5732
|
+
className: "rounded-[var(--cmp-listBox-radius)] bg-[var(--cmp-listBox-bg)] py-[4px] shadow-[2px_2px_12px_2px_rgba(0,0,0,0.1)]",
|
|
5566
5733
|
style: {
|
|
5567
|
-
maxHeight: dropdownHeight,
|
|
5568
5734
|
...dropdownWidth ? { width: dropdownWidth } : {},
|
|
5569
5735
|
maxWidth: maxDropdownWidth
|
|
5570
5736
|
},
|
|
5571
|
-
children:
|
|
5572
|
-
|
|
5573
|
-
|
|
5574
|
-
|
|
5575
|
-
|
|
5576
|
-
|
|
5577
|
-
|
|
5578
|
-
|
|
5579
|
-
|
|
5580
|
-
|
|
5581
|
-
|
|
5582
|
-
|
|
5583
|
-
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
|
|
5737
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5738
|
+
"div",
|
|
5739
|
+
{
|
|
5740
|
+
ref: listRef,
|
|
5741
|
+
className: "overflow-auto [scrollbar-width:auto] [&::-webkit-scrollbar]:w-[8px] [&::-webkit-scrollbar]:bg-[var(--color-grey-25)] [&::-webkit-scrollbar:horizontal]:h-[8px] [&::-webkit-scrollbar-thumb]:rounded-[4px] [&::-webkit-scrollbar-thumb]:bg-[var(--color-grey-45)] [&::-webkit-scrollbar-track]:bg-[var(--color-grey-25)]",
|
|
5742
|
+
style: { maxHeight: dropdownHeight },
|
|
5743
|
+
onMouseLeave: () => setFocusedIndex(-1),
|
|
5744
|
+
children: [
|
|
5745
|
+
showSearch && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-0 z-[1] bg-[var(--cmp-listBox-bg)] px-[8px] py-[4px]", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-[6px] rounded-[4px] border border-solid border-[color:var(--color-grey-45)] bg-white px-[8px] py-[4px] focus-within:border-[color:var(--sys-color-field-border-focus)]", children: [
|
|
5746
|
+
/* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: "search", size: 16, color: "var(--color-grey-70)", className: "shrink-0" }),
|
|
5747
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5748
|
+
"input",
|
|
5749
|
+
{
|
|
5750
|
+
ref: searchInputRef,
|
|
5751
|
+
value: search,
|
|
5752
|
+
onChange: (e) => setSearch(e.target.value),
|
|
5753
|
+
onKeyDown: handleKeyDown,
|
|
5754
|
+
placeholder: "\uAC80\uC0C9",
|
|
5755
|
+
className: "min-w-0 flex-1 border-none bg-transparent text-[12px] leading-[20px] text-[color:var(--cmp-select-text-default)] outline-none placeholder:text-[color:var(--color-grey-55)]"
|
|
5756
|
+
}
|
|
5757
|
+
),
|
|
5758
|
+
search !== "" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5759
|
+
SGhostButton,
|
|
5760
|
+
{
|
|
5761
|
+
icon: "close",
|
|
5762
|
+
size: "xxs",
|
|
5763
|
+
intent: "default",
|
|
5764
|
+
ariaLabel: "\uAC80\uC0C9\uC5B4 \uC9C0\uC6B0\uAE30",
|
|
5765
|
+
onClick: () => setSearch(""),
|
|
5766
|
+
className: "shrink-0"
|
|
5767
|
+
}
|
|
5768
|
+
)
|
|
5769
|
+
] }) }),
|
|
5770
|
+
hasItems ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5771
|
+
ItemList,
|
|
5772
|
+
{
|
|
5773
|
+
items: filtered,
|
|
5774
|
+
multi,
|
|
5775
|
+
selected,
|
|
5776
|
+
focusedValue: navigableItems[focusedIndex]?.isSelectAll ? "__select_all__" : navigableItems[focusedIndex]?.value,
|
|
5777
|
+
showSelectAll: multi && useSelectAll && allValues.length > 0,
|
|
5778
|
+
selectAllLabel: allSelectedLabel,
|
|
5779
|
+
selectAllSelected: allSelected,
|
|
5780
|
+
onSelectAll: handleSelectAll,
|
|
5781
|
+
onSelect: handleSelect,
|
|
5782
|
+
onHoverValue: (value2) => {
|
|
5783
|
+
const index = navigableItems.findIndex(
|
|
5784
|
+
(item) => item.isSelectAll ? value2 === "__select_all__" : item.value === value2
|
|
5785
|
+
);
|
|
5786
|
+
if (index >= 0) setFocusedIndex(index);
|
|
5787
|
+
}
|
|
5788
|
+
}
|
|
5789
|
+
) : /* @__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." })
|
|
5790
|
+
]
|
|
5791
|
+
}
|
|
5792
|
+
)
|
|
5609
5793
|
}
|
|
5610
5794
|
)
|
|
5611
5795
|
]
|
|
5612
5796
|
}
|
|
5613
5797
|
);
|
|
5614
|
-
const control = showSearch ? /* @__PURE__ */ jsxRuntime.jsx(Ariakit__namespace.ComboboxProvider, { value: search, setValue: setSearch, resetValueOnHide: true, children: selectStore }) : selectStore;
|
|
5615
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5616
|
-
SField,
|
|
5617
|
-
{
|
|
5618
|
-
label,
|
|
5619
|
-
labelWidth,
|
|
5620
|
-
icon,
|
|
5621
|
-
labelTooltip,
|
|
5622
|
-
labelTooltipProps,
|
|
5623
|
-
addonLabel,
|
|
5624
|
-
addonAlign,
|
|
5625
|
-
hint,
|
|
5626
|
-
error: error || ruleError !== "",
|
|
5627
|
-
status: rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0,
|
|
5628
|
-
errorMessage: ruleError !== "" ? ruleError : errorMessage,
|
|
5629
|
-
disabled: effectiveDisabled,
|
|
5630
|
-
width,
|
|
5631
|
-
className,
|
|
5632
|
-
style,
|
|
5633
|
-
children: [
|
|
5634
|
-
name && /* @__PURE__ */ jsxRuntime.jsx("input", { type: "hidden", name, value: selected.join(",") }),
|
|
5635
|
-
control
|
|
5636
|
-
]
|
|
5637
|
-
}
|
|
5638
|
-
);
|
|
5639
5798
|
});
|
|
5640
5799
|
SSelect.displayName = "SSelect";
|
|
5641
5800
|
function ItemList({
|
|
5642
5801
|
items,
|
|
5643
5802
|
multi,
|
|
5644
5803
|
selected,
|
|
5645
|
-
|
|
5804
|
+
focusedValue,
|
|
5805
|
+
showSelectAll,
|
|
5806
|
+
selectAllLabel,
|
|
5807
|
+
selectAllSelected,
|
|
5808
|
+
onSelectAll,
|
|
5809
|
+
onSelect,
|
|
5810
|
+
onHoverValue
|
|
5646
5811
|
}) {
|
|
5647
5812
|
const itemBase = cn(
|
|
5648
|
-
|
|
5649
|
-
"group flex cursor-pointer select-none items-center gap-[8px] text-[12px] leading-[20px] outline-none",
|
|
5813
|
+
"group flex w-full cursor-pointer select-none items-center gap-[8px] border-none bg-transparent text-left text-[12px] leading-[20px] outline-none",
|
|
5650
5814
|
"text-[color:var(--cmp-listItem-content-default)]",
|
|
5651
|
-
|
|
5652
|
-
|
|
5653
|
-
);
|
|
5654
|
-
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
if (o.isGroup) {
|
|
5658
|
-
const isDepth1 = o.depth === 1;
|
|
5659
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5660
|
-
"div",
|
|
5661
|
-
{
|
|
5662
|
-
className: cn(
|
|
5663
|
-
"select-none py-[4px] pr-[12px] text-[12px] leading-[20px] text-[color:var(--cmp-listItem-content-default)]",
|
|
5664
|
-
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",
|
|
5665
|
-
// 하위가 전부 비활성이면(select.config 에서 bubble-up) 어미 그룹도 비활성 처리:
|
|
5666
|
-
// 텍스트는 회색(#888), depth1 그룹은 파란 배경 대신 회색(#EEE)으로 (depth2 는 #F6F6F6 유지)
|
|
5667
|
-
o.disabled && "cursor-not-allowed text-[color:var(--cmp-listItem-content-disabled)]",
|
|
5668
|
-
o.disabled && isDepth1 && "bg-[var(--cmp-listItem-depth1-bg-disabled)]"
|
|
5669
|
-
),
|
|
5670
|
-
style: { paddingLeft: padLeft },
|
|
5671
|
-
children: o.label
|
|
5672
|
-
},
|
|
5673
|
-
o.value
|
|
5674
|
-
);
|
|
5675
|
-
}
|
|
5676
|
-
const isSelected = selected.includes(o.value);
|
|
5677
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5678
|
-
Ariakit__namespace.SelectItem,
|
|
5815
|
+
"disabled:cursor-not-allowed disabled:text-[color:var(--cmp-listItem-content-disabled)]"
|
|
5816
|
+
);
|
|
5817
|
+
const activeClass = "hover:bg-[var(--cmp-listItem-bg-hover)] hover:text-[color:var(--cmp-listItem-content-hover)] focus:bg-[var(--cmp-listItem-bg-hover)] focus:text-[color:var(--cmp-listItem-content-hover)]";
|
|
5818
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "listbox", "aria-multiselectable": multi || void 0, children: [
|
|
5819
|
+
showSelectAll && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5820
|
+
"button",
|
|
5679
5821
|
{
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5822
|
+
type: "button",
|
|
5823
|
+
"data-select-focused": focusedValue === "__select_all__" ? "true" : void 0,
|
|
5824
|
+
"data-select-active": focusedValue === "__select_all__" ? "true" : void 0,
|
|
5683
5825
|
className: cn(
|
|
5684
5826
|
itemBase,
|
|
5685
|
-
|
|
5686
|
-
// Ariakit은 disabled 항목도 hover 시 active(data-active-item) 처리하므로,
|
|
5687
|
-
// 비활성 항목에는 hover 하이라이트를 적용하지 않아 회색 비활성 스타일을 유지한다.
|
|
5688
|
-
// (원본 Stencil의 `--focused...:not(--disabled)` 규칙과 동일한 의도)
|
|
5689
|
-
!o.disabled && activeClass
|
|
5827
|
+
focusedValue === "__select_all__" && "bg-[var(--cmp-listItem-bg-hover)] text-[color:var(--cmp-listItem-content-hover)]"
|
|
5690
5828
|
),
|
|
5691
|
-
style: { paddingTop: 4, paddingBottom: 4, paddingRight: 12, paddingLeft:
|
|
5692
|
-
|
|
5829
|
+
style: { paddingTop: 4, paddingBottom: 4, paddingRight: 12, paddingLeft: 12 },
|
|
5830
|
+
onMouseEnter: () => onHoverValue("__select_all__"),
|
|
5831
|
+
onClick: onSelectAll,
|
|
5693
5832
|
children: [
|
|
5694
|
-
multi && // hover(active) 시 checkbox inverse — 파란 hover 배경 위에서 checked/unchecked 모두 흰 테두리 + 투명 배경
|
|
5695
5833
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5696
5834
|
"span",
|
|
5697
5835
|
{
|
|
5698
5836
|
className: cn(
|
|
5699
5837
|
"flex h-[16px] w-[16px] flex-shrink-0 items-center justify-center rounded-[2px] border border-solid",
|
|
5700
|
-
|
|
5701
|
-
// 비활성: 회색 채움(#E1E1E1) + 회색 테두리(#CCCCCC)
|
|
5702
|
-
"cursor-not-allowed border-[color:var(--cmp-checkbox-border-disabled)] bg-[var(--cmp-checkbox-bg-disabled)]"
|
|
5703
|
-
) : cn(
|
|
5704
|
-
"group-data-[active-item]:border-[color:var(--cmp-checkbox-checked-border-inverse)]",
|
|
5705
|
-
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"
|
|
5706
|
-
)
|
|
5838
|
+
selectAllSelected ? focusedValue === "__select_all__" ? "border-[color:var(--cmp-checkbox-checked-border-inverse)] bg-[var(--cmp-checkbox-checked-bg-default)]" : "border-[color:var(--cmp-checkbox-checked-bg-default)] bg-[var(--cmp-checkbox-checked-bg-default)]" : "border-[color:var(--cmp-checkbox-unchecked-border-default)] bg-[var(--cmp-checkbox-unchecked-bg-default)]"
|
|
5707
5839
|
),
|
|
5708
|
-
children:
|
|
5840
|
+
children: selectAllSelected && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5709
5841
|
SIcon,
|
|
5710
5842
|
{
|
|
5711
5843
|
name: "checkboxCheck",
|
|
5712
5844
|
size: 12,
|
|
5713
|
-
color:
|
|
5845
|
+
color: "var(--cmp-checkbox-checked-icon-default)"
|
|
5714
5846
|
}
|
|
5715
5847
|
)
|
|
5716
5848
|
}
|
|
5717
5849
|
),
|
|
5718
|
-
|
|
5719
|
-
"span",
|
|
5720
|
-
{
|
|
5721
|
-
className: "flex-1 truncate",
|
|
5722
|
-
dangerouslySetInnerHTML: { __html: sanitizeInlineHtml(o.label) }
|
|
5723
|
-
}
|
|
5724
|
-
) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children: o.label })
|
|
5850
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children: selectAllLabel })
|
|
5725
5851
|
]
|
|
5726
|
-
}
|
|
5727
|
-
|
|
5728
|
-
)
|
|
5729
|
-
|
|
5852
|
+
}
|
|
5853
|
+
),
|
|
5854
|
+
items.map((o) => {
|
|
5855
|
+
const padLeft = o.depth === 1 ? 12 : o.depth === 2 ? 20 : 28;
|
|
5856
|
+
if (o.isGroup) {
|
|
5857
|
+
const isDepth1 = o.depth === 1;
|
|
5858
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5859
|
+
"div",
|
|
5860
|
+
{
|
|
5861
|
+
className: cn(
|
|
5862
|
+
"select-none py-[4px] pr-[12px] text-[12px] leading-[20px] text-[color:var(--cmp-listItem-content-default)]",
|
|
5863
|
+
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",
|
|
5864
|
+
// 하위가 전부 비활성이면(select.config 에서 bubble-up) 어미 그룹도 비활성 처리:
|
|
5865
|
+
// 텍스트는 회색(#888), depth1 그룹은 파란 배경 대신 회색(#EEE)으로 (depth2 는 #F6F6F6 유지)
|
|
5866
|
+
o.disabled && "cursor-not-allowed text-[color:var(--cmp-listItem-content-disabled)]",
|
|
5867
|
+
o.disabled && isDepth1 && "bg-[var(--cmp-listItem-depth1-bg-disabled)]"
|
|
5868
|
+
),
|
|
5869
|
+
style: { paddingLeft: padLeft },
|
|
5870
|
+
children: o.label
|
|
5871
|
+
},
|
|
5872
|
+
o.value
|
|
5873
|
+
);
|
|
5874
|
+
}
|
|
5875
|
+
const isSelected = selected.includes(o.value);
|
|
5876
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5877
|
+
"button",
|
|
5878
|
+
{
|
|
5879
|
+
type: "button",
|
|
5880
|
+
disabled: o.disabled,
|
|
5881
|
+
role: "option",
|
|
5882
|
+
"aria-selected": isSelected,
|
|
5883
|
+
"data-select-focused": focusedValue === o.value ? "true" : void 0,
|
|
5884
|
+
"data-select-active": focusedValue === o.value ? "true" : void 0,
|
|
5885
|
+
className: cn(
|
|
5886
|
+
itemBase,
|
|
5887
|
+
isSelected && !multi && "font-bold text-[color:var(--cmp-listItem-content-selected)]",
|
|
5888
|
+
focusedValue === o.value && "bg-[var(--cmp-listItem-bg-hover)] text-[color:var(--cmp-listItem-content-hover)]",
|
|
5889
|
+
activeClass
|
|
5890
|
+
),
|
|
5891
|
+
style: { paddingTop: 4, paddingBottom: 4, paddingRight: 12, paddingLeft: padLeft },
|
|
5892
|
+
onMouseEnter: () => onHoverValue(o.value),
|
|
5893
|
+
onClick: () => onSelect(o.value),
|
|
5894
|
+
children: [
|
|
5895
|
+
multi && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5896
|
+
"span",
|
|
5897
|
+
{
|
|
5898
|
+
className: cn(
|
|
5899
|
+
"flex h-[16px] w-[16px] flex-shrink-0 items-center justify-center rounded-[2px] border border-solid",
|
|
5900
|
+
o.disabled ? (
|
|
5901
|
+
// 비활성: 회색 채움(#E1E1E1) + 회색 테두리(#CCCCCC)
|
|
5902
|
+
"cursor-not-allowed border-[color:var(--cmp-checkbox-border-disabled)] bg-[var(--cmp-checkbox-bg-disabled)]"
|
|
5903
|
+
) : cn(
|
|
5904
|
+
isSelected ? focusedValue === o.value ? "border-[color:var(--cmp-checkbox-checked-border-inverse)] bg-[var(--cmp-checkbox-checked-bg-default)]" : "border-[color:var(--cmp-checkbox-checked-bg-default)] bg-[var(--cmp-checkbox-checked-bg-default)]" : "border-[color:var(--cmp-checkbox-unchecked-border-default)] bg-[var(--cmp-checkbox-unchecked-bg-default)]"
|
|
5905
|
+
)
|
|
5906
|
+
),
|
|
5907
|
+
children: isSelected && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5908
|
+
SIcon,
|
|
5909
|
+
{
|
|
5910
|
+
name: "checkboxCheck",
|
|
5911
|
+
size: 12,
|
|
5912
|
+
color: o.disabled ? "var(--cmp-checkbox-checked-icon-disabled)" : "var(--cmp-checkbox-checked-icon-default)"
|
|
5913
|
+
}
|
|
5914
|
+
)
|
|
5915
|
+
}
|
|
5916
|
+
),
|
|
5917
|
+
isHtmlLabel(o.label) ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5918
|
+
"span",
|
|
5919
|
+
{
|
|
5920
|
+
className: "flex-1 truncate",
|
|
5921
|
+
dangerouslySetInnerHTML: { __html: sanitizeInlineHtml(o.label) }
|
|
5922
|
+
}
|
|
5923
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children: o.label })
|
|
5924
|
+
]
|
|
5925
|
+
},
|
|
5926
|
+
o.value
|
|
5927
|
+
);
|
|
5928
|
+
})
|
|
5929
|
+
] });
|
|
5730
5930
|
}
|
|
5731
5931
|
var DEFAULT_ROW_HEIGHT = 44;
|
|
5732
5932
|
var DENSE_ROW_HEIGHT = 32;
|
|
@@ -6002,7 +6202,7 @@ var STable = react.forwardRef(function STable2({
|
|
|
6002
6202
|
};
|
|
6003
6203
|
const radiusClass = radius === "full" ? "rounded-none" : radius === "useTop" ? "rounded-b-[var(--cmp-table-radius)] rounded-t-none" : "rounded-[var(--cmp-table-radius)]";
|
|
6004
6204
|
const cellPadY = dense ? "var(--cmp-table-body-paddingY-dense)" : "var(--cmp-table-body-paddingY-default)";
|
|
6005
|
-
const cellPadX =
|
|
6205
|
+
const cellPadX = "var(--cmp-table-body-paddingX-wide)";
|
|
6006
6206
|
const rowH = dense ? "var(--cmp-table-body-dense-height)" : "var(--cmp-table-body-default-height)";
|
|
6007
6207
|
const totalColSpan = visibleCols.length + (selectable ? 1 : 0);
|
|
6008
6208
|
const stickyInfo = (i) => {
|
|
@@ -6249,6 +6449,7 @@ var SInput = react.forwardRef(function SInput2({
|
|
|
6249
6449
|
type = "text",
|
|
6250
6450
|
size = "sm",
|
|
6251
6451
|
icon,
|
|
6452
|
+
iconColor,
|
|
6252
6453
|
prefix,
|
|
6253
6454
|
suffix,
|
|
6254
6455
|
clearable = false,
|
|
@@ -6302,6 +6503,7 @@ var SInput = react.forwardRef(function SInput2({
|
|
|
6302
6503
|
labelTooltip,
|
|
6303
6504
|
labelTooltipProps,
|
|
6304
6505
|
icon,
|
|
6506
|
+
iconColor,
|
|
6305
6507
|
size,
|
|
6306
6508
|
hint,
|
|
6307
6509
|
error: resolvedError,
|
|
@@ -6403,6 +6605,7 @@ var STextarea = react.forwardRef(function STextarea2({
|
|
|
6403
6605
|
label,
|
|
6404
6606
|
labelWidth,
|
|
6405
6607
|
icon,
|
|
6608
|
+
iconColor,
|
|
6406
6609
|
labelTooltip,
|
|
6407
6610
|
labelTooltipProps,
|
|
6408
6611
|
addonLabel,
|
|
@@ -6439,6 +6642,7 @@ var STextarea = react.forwardRef(function STextarea2({
|
|
|
6439
6642
|
label,
|
|
6440
6643
|
labelWidth,
|
|
6441
6644
|
icon,
|
|
6645
|
+
iconColor,
|
|
6442
6646
|
labelTooltip,
|
|
6443
6647
|
labelTooltipProps,
|
|
6444
6648
|
addonLabel,
|
|
@@ -6571,6 +6775,7 @@ var SNumberInput = react.forwardRef(function SNumberInput2({
|
|
|
6571
6775
|
label,
|
|
6572
6776
|
labelWidth,
|
|
6573
6777
|
icon,
|
|
6778
|
+
iconColor,
|
|
6574
6779
|
labelTooltip,
|
|
6575
6780
|
labelTooltipProps,
|
|
6576
6781
|
addonLabel,
|
|
@@ -6729,6 +6934,7 @@ var SNumberInput = react.forwardRef(function SNumberInput2({
|
|
|
6729
6934
|
label,
|
|
6730
6935
|
labelWidth,
|
|
6731
6936
|
icon,
|
|
6937
|
+
iconColor,
|
|
6732
6938
|
labelTooltip,
|
|
6733
6939
|
labelTooltipProps,
|
|
6734
6940
|
addonLabel,
|
|
@@ -7204,6 +7410,7 @@ function SDatePicker({
|
|
|
7204
7410
|
label,
|
|
7205
7411
|
labelWidth,
|
|
7206
7412
|
icon,
|
|
7413
|
+
iconColor,
|
|
7207
7414
|
labelTooltip,
|
|
7208
7415
|
labelTooltipProps,
|
|
7209
7416
|
addonLabel,
|
|
@@ -7242,6 +7449,7 @@ function SDatePicker({
|
|
|
7242
7449
|
label,
|
|
7243
7450
|
labelWidth,
|
|
7244
7451
|
icon,
|
|
7452
|
+
iconColor,
|
|
7245
7453
|
labelTooltip,
|
|
7246
7454
|
labelTooltipProps,
|
|
7247
7455
|
addonLabel,
|
|
@@ -7510,6 +7718,7 @@ function SDateRangePicker({
|
|
|
7510
7718
|
label,
|
|
7511
7719
|
labelWidth,
|
|
7512
7720
|
icon,
|
|
7721
|
+
iconColor,
|
|
7513
7722
|
labelTooltip,
|
|
7514
7723
|
labelTooltipProps,
|
|
7515
7724
|
addonLabel,
|
|
@@ -7552,6 +7761,7 @@ function SDateRangePicker({
|
|
|
7552
7761
|
label,
|
|
7553
7762
|
labelWidth,
|
|
7554
7763
|
icon,
|
|
7764
|
+
iconColor,
|
|
7555
7765
|
labelTooltip,
|
|
7556
7766
|
labelTooltipProps,
|
|
7557
7767
|
addonLabel,
|
|
@@ -7813,6 +8023,7 @@ function SFilePicker({
|
|
|
7813
8023
|
label,
|
|
7814
8024
|
labelWidth,
|
|
7815
8025
|
icon,
|
|
8026
|
+
iconColor,
|
|
7816
8027
|
labelTooltip,
|
|
7817
8028
|
labelTooltipProps,
|
|
7818
8029
|
addonLabel,
|
|
@@ -7982,7 +8193,7 @@ function SFilePicker({
|
|
|
7982
8193
|
unmountOnHide: true,
|
|
7983
8194
|
getAnchorRect: () => contentBoxRef.current?.getBoundingClientRect() ?? null,
|
|
7984
8195
|
style: { minWidth: contentBoxRef.current?.offsetWidth },
|
|
7985
|
-
className: "z-50 box-border flex flex-col items-
|
|
8196
|
+
className: "z-50 box-border flex flex-col items-start gap-[8px] rounded-[var(--cmp-listBox-radius)] bg-[var(--cmp-listBox-bg)] p-[8px] shadow-[2px_2px_12px_2px_rgba(0,0,0,0.1)]",
|
|
7986
8197
|
children: filesArr.map((f, i) => /* @__PURE__ */ jsxRuntime.jsx(SChip, { value: f.name, editable: false, onRemove: () => removeChip(i) }, i))
|
|
7987
8198
|
}
|
|
7988
8199
|
)
|
|
@@ -7996,6 +8207,7 @@ function SFilePicker({
|
|
|
7996
8207
|
label,
|
|
7997
8208
|
labelWidth,
|
|
7998
8209
|
icon,
|
|
8210
|
+
iconColor,
|
|
7999
8211
|
labelTooltip,
|
|
8000
8212
|
labelTooltipProps,
|
|
8001
8213
|
addonLabel,
|
|
@@ -8018,21 +8230,26 @@ function SFilePicker({
|
|
|
8018
8230
|
var cssLen2 = (v) => v == null ? void 0 : typeof v === "number" ? `${v}px` : v;
|
|
8019
8231
|
function SKeyValueTable({
|
|
8020
8232
|
fields = [],
|
|
8233
|
+
values = {},
|
|
8021
8234
|
search = false,
|
|
8022
8235
|
radius = "default",
|
|
8023
|
-
dense = false,
|
|
8024
8236
|
onChange,
|
|
8025
8237
|
onSearch,
|
|
8026
8238
|
className,
|
|
8027
8239
|
style
|
|
8028
8240
|
}) {
|
|
8029
8241
|
if (fields.length === 0) return null;
|
|
8030
|
-
const emit2 = (name, value) => onChange?.({
|
|
8031
|
-
|
|
8032
|
-
|
|
8242
|
+
const emit2 = (name, value) => onChange?.({
|
|
8243
|
+
name,
|
|
8244
|
+
value,
|
|
8245
|
+
values: { ...values, [name]: value }
|
|
8246
|
+
});
|
|
8247
|
+
const cellHeight = "var(--cmp-table-keyValue-height)";
|
|
8248
|
+
const cellPadY = "var(--cmp-table-keyValue-body-paddingY)";
|
|
8033
8249
|
const renderField = (f) => {
|
|
8034
8250
|
if (f.render) return f.render;
|
|
8035
|
-
const opt = f.options ?? {};
|
|
8251
|
+
const opt = { ...f.options ?? {} };
|
|
8252
|
+
if (Object.prototype.hasOwnProperty.call(values, f.name)) opt.value = values[f.name];
|
|
8036
8253
|
const up = (v) => emit2(f.name, v);
|
|
8037
8254
|
switch (f.type) {
|
|
8038
8255
|
case "input":
|
|
@@ -8144,7 +8361,10 @@ function SKeyValueTable({
|
|
|
8144
8361
|
rowSpan: f.tdRowSpan && f.tdRowSpan > 1 ? f.tdRowSpan : void 0,
|
|
8145
8362
|
colSpan: f.tdColSpan && f.tdColSpan > 1 ? f.tdColSpan : void 0,
|
|
8146
8363
|
className: cn(
|
|
8147
|
-
"box-border bg-[var(--sys-color-bg-frame)]
|
|
8364
|
+
"box-border bg-[var(--sys-color-bg-frame)] align-middle",
|
|
8365
|
+
// text 타입(및 미지정 기본값)은 읽기 전용 콘텐츠라 넓은 paddingX(wide),
|
|
8366
|
+
// 폼 필드 셀은 default paddingX 유지
|
|
8367
|
+
f.type == null || f.type === "text" ? "px-[var(--cmp-table-keyValue-body-paddingX-wide)]" : "px-[var(--cmp-table-keyValue-body-paddingX-default)]",
|
|
8148
8368
|
cellBorder,
|
|
8149
8369
|
f.tdClass
|
|
8150
8370
|
),
|
|
@@ -8637,6 +8857,7 @@ var SChipInput = react.forwardRef(function SChipInput2({
|
|
|
8637
8857
|
error,
|
|
8638
8858
|
useReset = false,
|
|
8639
8859
|
maxCount,
|
|
8860
|
+
metaPlacement = "end",
|
|
8640
8861
|
duplicateLabel,
|
|
8641
8862
|
suggestions = [],
|
|
8642
8863
|
loadingSuggestions = false,
|
|
@@ -8650,6 +8871,7 @@ var SChipInput = react.forwardRef(function SChipInput2({
|
|
|
8650
8871
|
width,
|
|
8651
8872
|
status,
|
|
8652
8873
|
icon,
|
|
8874
|
+
iconColor,
|
|
8653
8875
|
labelTooltip,
|
|
8654
8876
|
labelTooltipProps,
|
|
8655
8877
|
className,
|
|
@@ -8784,6 +9006,7 @@ var SChipInput = react.forwardRef(function SChipInput2({
|
|
|
8784
9006
|
labelWidth,
|
|
8785
9007
|
labelHeight: `calc(var(--cmp-chipInput-${size}-minHeight) + 2px)`,
|
|
8786
9008
|
icon,
|
|
9009
|
+
iconColor,
|
|
8787
9010
|
labelTooltip,
|
|
8788
9011
|
labelTooltipProps,
|
|
8789
9012
|
size,
|
|
@@ -8931,7 +9154,11 @@ var SChipInput = react.forwardRef(function SChipInput2({
|
|
|
8931
9154
|
showMetaInfo && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8932
9155
|
"div",
|
|
8933
9156
|
{
|
|
8934
|
-
className:
|
|
9157
|
+
className: cn(
|
|
9158
|
+
"s-chip-input__meta flex items-center gap-8",
|
|
9159
|
+
metaPlacement === "end" && "ml-auto"
|
|
9160
|
+
),
|
|
9161
|
+
"data-placement": metaPlacement,
|
|
8935
9162
|
onMouseDown: (e) => e.preventDefault(),
|
|
8936
9163
|
children: [
|
|
8937
9164
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -9071,6 +9298,7 @@ var SBarcodeInput = react.forwardRef(
|
|
|
9071
9298
|
label,
|
|
9072
9299
|
labelWidth,
|
|
9073
9300
|
icon,
|
|
9301
|
+
iconColor,
|
|
9074
9302
|
labelTooltip,
|
|
9075
9303
|
labelTooltipProps,
|
|
9076
9304
|
addonLabel,
|
|
@@ -9102,6 +9330,7 @@ var SBarcodeInput = react.forwardRef(
|
|
|
9102
9330
|
label,
|
|
9103
9331
|
labelWidth,
|
|
9104
9332
|
icon,
|
|
9333
|
+
iconColor,
|
|
9105
9334
|
labelTooltip,
|
|
9106
9335
|
labelTooltipProps,
|
|
9107
9336
|
addonLabel,
|
|
@@ -9213,7 +9442,6 @@ exports.SLinearProgress = SLinearProgress;
|
|
|
9213
9442
|
exports.SLoadingContainer = SLoadingContainer;
|
|
9214
9443
|
exports.SLoadingModal = SLoadingModal;
|
|
9215
9444
|
exports.SLoadingViewport = SLoadingViewport;
|
|
9216
|
-
exports.SModalContainer = SModalContainer;
|
|
9217
9445
|
exports.SNumberInput = SNumberInput;
|
|
9218
9446
|
exports.SPagination = SPagination;
|
|
9219
9447
|
exports.SPopover = SPopover;
|