sellmate-design-system-react 0.1.9 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +16 -3
- package/dist/components/SBarcodeInput/SBarcodeInput.cjs.map +1 -1
- package/dist/components/SBarcodeInput/SBarcodeInput.d.ts +3 -1
- package/dist/components/SBarcodeInput/SBarcodeInput.js +16 -3
- 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 +22 -4
- package/dist/components/SChipInput/SChipInput.cjs.map +1 -1
- package/dist/components/SChipInput/SChipInput.d.ts +5 -0
- package/dist/components/SChipInput/SChipInput.js +22 -4
- package/dist/components/SChipInput/SChipInput.js.map +1 -1
- package/dist/components/SChipInput/index.d.ts +1 -1
- package/dist/components/SCircleProgress/SCircleProgress.cjs +69 -50
- package/dist/components/SCircleProgress/SCircleProgress.cjs.map +1 -1
- package/dist/components/SCircleProgress/SCircleProgress.d.ts +2 -0
- package/dist/components/SCircleProgress/SCircleProgress.js +69 -50
- package/dist/components/SCircleProgress/SCircleProgress.js.map +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 +16 -3
- package/dist/components/SDatePicker/SDatePicker.cjs.map +1 -1
- package/dist/components/SDatePicker/SDatePicker.d.ts +3 -1
- package/dist/components/SDatePicker/SDatePicker.js +16 -3
- package/dist/components/SDatePicker/SDatePicker.js.map +1 -1
- package/dist/components/SDateRangePicker/SDateRangePicker.cjs +16 -3
- package/dist/components/SDateRangePicker/SDateRangePicker.cjs.map +1 -1
- package/dist/components/SDateRangePicker/SDateRangePicker.d.ts +3 -1
- package/dist/components/SDateRangePicker/SDateRangePicker.js +16 -3
- 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 +14 -3
- package/dist/components/SField/SField.cjs.map +1 -1
- package/dist/components/SField/SField.d.ts +4 -1
- package/dist/components/SField/SField.js +14 -3
- package/dist/components/SField/SField.js.map +1 -1
- package/dist/components/SFilePicker/SFilePicker.cjs +51 -19
- package/dist/components/SFilePicker/SFilePicker.cjs.map +1 -1
- package/dist/components/SFilePicker/SFilePicker.d.ts +4 -2
- package/dist/components/SFilePicker/SFilePicker.js +50 -19
- 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 +16 -3
- package/dist/components/SInput/SInput.cjs.map +1 -1
- package/dist/components/SInput/SInput.d.ts +4 -1
- package/dist/components/SInput/SInput.js +16 -3
- package/dist/components/SInput/SInput.js.map +1 -1
- package/dist/components/SKeyValueTable/SKeyValueTable.cjs +530 -219
- package/dist/components/SKeyValueTable/SKeyValueTable.cjs.map +1 -1
- package/dist/components/SKeyValueTable/SKeyValueTable.d.ts +27 -6
- package/dist/components/SKeyValueTable/SKeyValueTable.js +529 -218
- package/dist/components/SKeyValueTable/SKeyValueTable.js.map +1 -1
- package/dist/components/SLoadingContainer/SLoadingContainer.cjs +69 -50
- package/dist/components/SLoadingContainer/SLoadingContainer.cjs.map +1 -1
- package/dist/components/SLoadingContainer/SLoadingContainer.js +69 -50
- package/dist/components/SLoadingContainer/SLoadingContainer.js.map +1 -1
- package/dist/components/SLoadingContainer/loading.cjs +69 -50
- package/dist/components/SLoadingContainer/loading.cjs.map +1 -1
- package/dist/components/SLoadingContainer/loading.js +69 -50
- package/dist/components/SLoadingContainer/loading.js.map +1 -1
- package/dist/components/SLoadingModal/SLoadingModal.cjs +75 -51
- package/dist/components/SLoadingModal/SLoadingModal.cjs.map +1 -1
- package/dist/components/SLoadingModal/SLoadingModal.d.ts +3 -1
- package/dist/components/SLoadingModal/SLoadingModal.js +75 -51
- 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 +16 -3
- package/dist/components/SNumberInput/SNumberInput.cjs.map +1 -1
- package/dist/components/SNumberInput/SNumberInput.d.ts +2 -0
- package/dist/components/SNumberInput/SNumberInput.js +16 -3
- 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/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 +530 -258
- 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 -258
- package/dist/components/SSelect/SSelect.js.map +1 -1
- package/dist/components/STable/STable.cjs +603 -309
- package/dist/components/STable/STable.cjs.map +1 -1
- package/dist/components/STable/STable.js +604 -309
- 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 +16 -3
- package/dist/components/STextarea/STextarea.cjs.map +1 -1
- package/dist/components/STextarea/STextarea.d.ts +2 -0
- package/dist/components/STextarea/STextarea.js +16 -3
- 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 +3 -1
- package/dist/components/STooltip/STooltip.cjs.map +1 -1
- package/dist/components/STooltip/STooltip.js +3 -1
- package/dist/components/STooltip/STooltip.js.map +1 -1
- package/dist/index.cjs +522 -248
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +523 -248
- package/dist/index.js.map +1 -1
- package/dist/lib/portal-container.d.ts +7 -0
- package/dist/styles.css +123 -58
- package/dist/theme.css +45 -21
- package/package.json +1 -1
|
@@ -6,8 +6,8 @@ var clsx = require('clsx');
|
|
|
6
6
|
var tailwindMerge = require('tailwind-merge');
|
|
7
7
|
var jsxRuntime = require('react/jsx-runtime');
|
|
8
8
|
var RPopover2 = require('@radix-ui/react-popover');
|
|
9
|
-
var Ariakit = require('@ariakit/react');
|
|
10
9
|
var RCheckbox = require('@radix-ui/react-checkbox');
|
|
10
|
+
var Ariakit = require('@ariakit/react');
|
|
11
11
|
|
|
12
12
|
function _interopNamespace(e) {
|
|
13
13
|
if (e && e.__esModule) return e;
|
|
@@ -28,8 +28,8 @@ function _interopNamespace(e) {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
var RPopover2__namespace = /*#__PURE__*/_interopNamespace(RPopover2);
|
|
31
|
-
var Ariakit__namespace = /*#__PURE__*/_interopNamespace(Ariakit);
|
|
32
31
|
var RCheckbox__namespace = /*#__PURE__*/_interopNamespace(RCheckbox);
|
|
32
|
+
var Ariakit__namespace = /*#__PURE__*/_interopNamespace(Ariakit);
|
|
33
33
|
|
|
34
34
|
var twMerge = tailwindMerge.extendTailwindMerge({
|
|
35
35
|
extend: {
|
|
@@ -2897,10 +2897,15 @@ var FLOATING_SLIDE_ANIM = [
|
|
|
2897
2897
|
"data-[state=closed]:data-[side=right]:animate-floating-out-right"
|
|
2898
2898
|
].join(" ");
|
|
2899
2899
|
var PortalContainerContext = react.createContext(null);
|
|
2900
|
+
var InsideModalContext = react.createContext(false);
|
|
2900
2901
|
PortalContainerContext.Provider;
|
|
2902
|
+
InsideModalContext.Provider;
|
|
2901
2903
|
function usePortalContainer() {
|
|
2902
2904
|
return react.useContext(PortalContainerContext) ?? void 0;
|
|
2903
2905
|
}
|
|
2906
|
+
function useInsideModal() {
|
|
2907
|
+
return react.useContext(InsideModalContext);
|
|
2908
|
+
}
|
|
2904
2909
|
|
|
2905
2910
|
// src/components/STag/tag.config.ts
|
|
2906
2911
|
var TAG_SIZE_CONFIG = {
|
|
@@ -3152,7 +3157,7 @@ var STooltip = react.forwardRef(function STooltip2({
|
|
|
3152
3157
|
if (disabled || body == null) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: triggerNode });
|
|
3153
3158
|
const isHover = trigger === "hover";
|
|
3154
3159
|
const contentClass = cn(
|
|
3155
|
-
"z-50 max-w-xs rounded-[6px] px-[16px] py-[12px] text-[12px] leading-[20px]
|
|
3160
|
+
"z-50 max-w-xs rounded-[6px] px-[16px] py-[12px] text-[12px] leading-[20px]",
|
|
3156
3161
|
FLOATING_SLIDE_ANIM,
|
|
3157
3162
|
className
|
|
3158
3163
|
);
|
|
@@ -3424,6 +3429,7 @@ var SField = react.forwardRef(function SField2({
|
|
|
3424
3429
|
name,
|
|
3425
3430
|
label = "",
|
|
3426
3431
|
icon,
|
|
3432
|
+
iconColor,
|
|
3427
3433
|
labelTooltip = "",
|
|
3428
3434
|
labelTooltipProps,
|
|
3429
3435
|
labelWidth,
|
|
@@ -3501,7 +3507,15 @@ var SField = react.forwardRef(function SField2({
|
|
|
3501
3507
|
lineHeight: `${s.lineHeight}px`
|
|
3502
3508
|
},
|
|
3503
3509
|
children: [
|
|
3504
|
-
icon && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3510
|
+
icon && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3511
|
+
SIcon,
|
|
3512
|
+
{
|
|
3513
|
+
name: icon,
|
|
3514
|
+
size: s.icon,
|
|
3515
|
+
color: iconColor,
|
|
3516
|
+
style: { marginRight: s.labelGap }
|
|
3517
|
+
}
|
|
3518
|
+
),
|
|
3505
3519
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 overflow-hidden text-ellipsis whitespace-nowrap", children: label }),
|
|
3506
3520
|
(labelTooltip !== "" || labelTooltipProps) && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0", style: { marginLeft: s.labelGap }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3507
3521
|
STooltip,
|
|
@@ -3551,7 +3565,7 @@ var SField = react.forwardRef(function SField2({
|
|
|
3551
3565
|
borderBottomLeftRadius: s.radius - 1
|
|
3552
3566
|
},
|
|
3553
3567
|
children: [
|
|
3554
|
-
icon && !label && /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: icon, size: s.icon }),
|
|
3568
|
+
icon && !label && /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: icon, size: s.icon, color: iconColor }),
|
|
3555
3569
|
effectiveAddonLabel
|
|
3556
3570
|
]
|
|
3557
3571
|
}
|
|
@@ -3577,6 +3591,7 @@ var SInput = react.forwardRef(function SInput2({
|
|
|
3577
3591
|
type = "text",
|
|
3578
3592
|
size = "sm",
|
|
3579
3593
|
icon,
|
|
3594
|
+
iconColor,
|
|
3580
3595
|
prefix,
|
|
3581
3596
|
suffix,
|
|
3582
3597
|
clearable = false,
|
|
@@ -3630,6 +3645,7 @@ var SInput = react.forwardRef(function SInput2({
|
|
|
3630
3645
|
labelTooltip,
|
|
3631
3646
|
labelTooltipProps,
|
|
3632
3647
|
icon,
|
|
3648
|
+
iconColor,
|
|
3633
3649
|
size,
|
|
3634
3650
|
hint,
|
|
3635
3651
|
error: resolvedError,
|
|
@@ -3731,6 +3747,7 @@ var STextarea = react.forwardRef(function STextarea2({
|
|
|
3731
3747
|
label,
|
|
3732
3748
|
labelWidth,
|
|
3733
3749
|
icon,
|
|
3750
|
+
iconColor,
|
|
3734
3751
|
labelTooltip,
|
|
3735
3752
|
labelTooltipProps,
|
|
3736
3753
|
addonLabel,
|
|
@@ -3767,6 +3784,7 @@ var STextarea = react.forwardRef(function STextarea2({
|
|
|
3767
3784
|
label,
|
|
3768
3785
|
labelWidth,
|
|
3769
3786
|
icon,
|
|
3787
|
+
iconColor,
|
|
3770
3788
|
labelTooltip,
|
|
3771
3789
|
labelTooltipProps,
|
|
3772
3790
|
addonLabel,
|
|
@@ -3899,6 +3917,7 @@ var SNumberInput = react.forwardRef(function SNumberInput2({
|
|
|
3899
3917
|
label,
|
|
3900
3918
|
labelWidth,
|
|
3901
3919
|
icon,
|
|
3920
|
+
iconColor,
|
|
3902
3921
|
labelTooltip,
|
|
3903
3922
|
labelTooltipProps,
|
|
3904
3923
|
addonLabel,
|
|
@@ -4057,6 +4076,7 @@ var SNumberInput = react.forwardRef(function SNumberInput2({
|
|
|
4057
4076
|
label,
|
|
4058
4077
|
labelWidth,
|
|
4059
4078
|
icon,
|
|
4079
|
+
iconColor,
|
|
4060
4080
|
labelTooltip,
|
|
4061
4081
|
labelTooltipProps,
|
|
4062
4082
|
addonLabel,
|
|
@@ -4142,40 +4162,6 @@ var SNumberInput = react.forwardRef(function SNumberInput2({
|
|
|
4142
4162
|
);
|
|
4143
4163
|
});
|
|
4144
4164
|
|
|
4145
|
-
// src/components/SSelect/select.config.ts
|
|
4146
|
-
function flattenOptions(options, depth = 1) {
|
|
4147
|
-
const out = [];
|
|
4148
|
-
for (const o of options) {
|
|
4149
|
-
const hasChildren = Array.isArray(o.children) && o.children.length > 0;
|
|
4150
|
-
if (hasChildren) {
|
|
4151
|
-
const childFlat = flattenOptions(o.children, depth + 1);
|
|
4152
|
-
const allChildrenDisabled = childFlat.every((c) => c.disabled);
|
|
4153
|
-
out.push({
|
|
4154
|
-
value: String(o.value),
|
|
4155
|
-
label: o.label,
|
|
4156
|
-
disabled: !!o.disabled || allChildrenDisabled,
|
|
4157
|
-
depth,
|
|
4158
|
-
isGroup: true,
|
|
4159
|
-
raw: o.value
|
|
4160
|
-
});
|
|
4161
|
-
out.push(...childFlat);
|
|
4162
|
-
} else {
|
|
4163
|
-
out.push({
|
|
4164
|
-
value: String(o.value),
|
|
4165
|
-
label: o.label,
|
|
4166
|
-
disabled: !!o.disabled,
|
|
4167
|
-
depth,
|
|
4168
|
-
isGroup: false,
|
|
4169
|
-
raw: o.value
|
|
4170
|
-
});
|
|
4171
|
-
}
|
|
4172
|
-
}
|
|
4173
|
-
return out;
|
|
4174
|
-
}
|
|
4175
|
-
var selectableOptions = (flat) => flat.filter((o) => !o.isGroup && !o.disabled);
|
|
4176
|
-
var isHtmlLabel = (label) => /<[a-z][\s\S]*>/i.test(label);
|
|
4177
|
-
var extractText = (html) => html.replace(/<[^>]*>/g, "");
|
|
4178
|
-
|
|
4179
4165
|
// src/lib/sanitize-inline-html.ts
|
|
4180
4166
|
var ALLOWED_INLINE_TAGS = /* @__PURE__ */ new Set(["A", "B", "STRONG", "I", "EM", "BR", "SPAN"]);
|
|
4181
4167
|
var ALLOWED_ATTRS_BY_TAG = {
|
|
@@ -4244,6 +4230,111 @@ var sanitizeInlineHtml = (value) => {
|
|
|
4244
4230
|
Array.from(template.content.childNodes).forEach((child) => sanitizeNode(child));
|
|
4245
4231
|
return template.innerHTML;
|
|
4246
4232
|
};
|
|
4233
|
+
function SPortal({
|
|
4234
|
+
open,
|
|
4235
|
+
onClose,
|
|
4236
|
+
onOpenChange,
|
|
4237
|
+
anchorRef,
|
|
4238
|
+
placement = "bottom",
|
|
4239
|
+
align = "start",
|
|
4240
|
+
offset = 4,
|
|
4241
|
+
alignOffset = 0,
|
|
4242
|
+
fit = false,
|
|
4243
|
+
maxHeight,
|
|
4244
|
+
autoClose = false,
|
|
4245
|
+
persistent = false,
|
|
4246
|
+
viewportPadding = 0,
|
|
4247
|
+
onOpenAutoFocus,
|
|
4248
|
+
onCloseAutoFocus,
|
|
4249
|
+
children,
|
|
4250
|
+
className,
|
|
4251
|
+
style,
|
|
4252
|
+
ariaLabel
|
|
4253
|
+
}) {
|
|
4254
|
+
const portalContainer = usePortalContainer();
|
|
4255
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4256
|
+
RPopover2__namespace.Root,
|
|
4257
|
+
{
|
|
4258
|
+
open,
|
|
4259
|
+
onOpenChange: (next) => {
|
|
4260
|
+
onOpenChange?.(next);
|
|
4261
|
+
if (!next) onClose?.();
|
|
4262
|
+
},
|
|
4263
|
+
children: [
|
|
4264
|
+
/* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Anchor, { virtualRef: anchorRef }),
|
|
4265
|
+
/* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4266
|
+
RPopover2__namespace.Content,
|
|
4267
|
+
{
|
|
4268
|
+
side: placement,
|
|
4269
|
+
align,
|
|
4270
|
+
sideOffset: offset,
|
|
4271
|
+
alignOffset,
|
|
4272
|
+
collisionPadding: viewportPadding,
|
|
4273
|
+
"aria-label": ariaLabel,
|
|
4274
|
+
onPointerDownOutside: (e) => {
|
|
4275
|
+
if (persistent || anchorRef.current?.contains(e.target)) {
|
|
4276
|
+
e.preventDefault();
|
|
4277
|
+
}
|
|
4278
|
+
},
|
|
4279
|
+
onFocusOutside: (e) => {
|
|
4280
|
+
if (persistent || anchorRef.current?.contains(e.target)) {
|
|
4281
|
+
e.preventDefault();
|
|
4282
|
+
}
|
|
4283
|
+
},
|
|
4284
|
+
onEscapeKeyDown: persistent ? (e) => e.preventDefault() : void 0,
|
|
4285
|
+
onOpenAutoFocus,
|
|
4286
|
+
onCloseAutoFocus,
|
|
4287
|
+
onClick: autoClose ? () => onClose?.() : void 0,
|
|
4288
|
+
className: cn(
|
|
4289
|
+
"z-50 overflow-hidden rounded-(--cmp-listBox-radius) bg-(--cmp-listBox-bg) py-4 shadow-normal-sm",
|
|
4290
|
+
maxHeight != null && "overflow-y-auto",
|
|
4291
|
+
fit && "min-w-(--radix-popover-trigger-width)",
|
|
4292
|
+
FLOATING_SLIDE_ANIM,
|
|
4293
|
+
className
|
|
4294
|
+
),
|
|
4295
|
+
style: { maxHeight, ...style },
|
|
4296
|
+
children
|
|
4297
|
+
}
|
|
4298
|
+
) })
|
|
4299
|
+
]
|
|
4300
|
+
}
|
|
4301
|
+
);
|
|
4302
|
+
}
|
|
4303
|
+
SPortal.displayName = "SPortal";
|
|
4304
|
+
|
|
4305
|
+
// src/components/SSelect/select.config.ts
|
|
4306
|
+
function flattenOptions(options, depth = 1) {
|
|
4307
|
+
const out = [];
|
|
4308
|
+
for (const o of options) {
|
|
4309
|
+
const hasChildren = Array.isArray(o.children) && o.children.length > 0;
|
|
4310
|
+
if (hasChildren) {
|
|
4311
|
+
const childFlat = flattenOptions(o.children, depth + 1);
|
|
4312
|
+
const allChildrenDisabled = childFlat.every((c) => c.disabled);
|
|
4313
|
+
out.push({
|
|
4314
|
+
value: String(o.value),
|
|
4315
|
+
label: o.label,
|
|
4316
|
+
disabled: !!o.disabled || allChildrenDisabled,
|
|
4317
|
+
depth,
|
|
4318
|
+
isGroup: true,
|
|
4319
|
+
raw: o.value
|
|
4320
|
+
});
|
|
4321
|
+
out.push(...childFlat);
|
|
4322
|
+
} else {
|
|
4323
|
+
out.push({
|
|
4324
|
+
value: String(o.value),
|
|
4325
|
+
label: o.label,
|
|
4326
|
+
disabled: !!o.disabled,
|
|
4327
|
+
depth,
|
|
4328
|
+
isGroup: false,
|
|
4329
|
+
raw: o.value
|
|
4330
|
+
});
|
|
4331
|
+
}
|
|
4332
|
+
}
|
|
4333
|
+
return out;
|
|
4334
|
+
}
|
|
4335
|
+
var selectableOptions = (flat) => flat.filter((o) => !o.isGroup && !o.disabled);
|
|
4336
|
+
var isHtmlLabel = (label) => /<[a-z][\s\S]*>/i.test(label);
|
|
4337
|
+
var extractText = (html) => html.replace(/<[^>]*>/g, "");
|
|
4247
4338
|
var SEARCH_THRESHOLD = 11;
|
|
4248
4339
|
var SSelect = react.forwardRef(function SSelect2({
|
|
4249
4340
|
value,
|
|
@@ -4267,6 +4358,7 @@ var SSelect = react.forwardRef(function SSelect2({
|
|
|
4267
4358
|
label,
|
|
4268
4359
|
labelWidth,
|
|
4269
4360
|
icon,
|
|
4361
|
+
iconColor,
|
|
4270
4362
|
labelTooltip,
|
|
4271
4363
|
addonLabel,
|
|
4272
4364
|
addonAlign,
|
|
@@ -4278,18 +4370,15 @@ var SSelect = react.forwardRef(function SSelect2({
|
|
|
4278
4370
|
}, ref) {
|
|
4279
4371
|
const multi = type === "multi" || type === "multi_depth";
|
|
4280
4372
|
const portalContainer = usePortalContainer();
|
|
4373
|
+
const insideModal = useInsideModal();
|
|
4281
4374
|
const [search, setSearch] = react.useState("");
|
|
4282
4375
|
const [ruleError, setRuleError] = react.useState("");
|
|
4283
4376
|
const [open, setOpen] = react.useState(false);
|
|
4377
|
+
const [pendingOpen, setPendingOpen] = react.useState(false);
|
|
4378
|
+
const [focusedIndex, setFocusedIndex] = react.useState(-1);
|
|
4284
4379
|
const triggerRef = react.useRef(null);
|
|
4285
|
-
react.
|
|
4286
|
-
|
|
4287
|
-
() => ({
|
|
4288
|
-
focus: () => triggerRef.current?.focus(),
|
|
4289
|
-
open: () => setOpen(true)
|
|
4290
|
-
}),
|
|
4291
|
-
[]
|
|
4292
|
-
);
|
|
4380
|
+
const searchInputRef = react.useRef(null);
|
|
4381
|
+
const listRef = react.useRef(null);
|
|
4293
4382
|
const flat = react.useMemo(() => flattenOptions(options), [options]);
|
|
4294
4383
|
const selectable = react.useMemo(() => selectableOptions(flat), [flat]);
|
|
4295
4384
|
const hasLeaf = react.useMemo(() => flat.some((o) => !o.isGroup), [flat]);
|
|
@@ -4307,6 +4396,46 @@ var SSelect = react.forwardRef(function SSelect2({
|
|
|
4307
4396
|
const arr = Array.isArray(value) ? value : [value];
|
|
4308
4397
|
return arr.map((v) => v != null && typeof v === "object" ? v.value : v).filter((v) => v != null && v !== "").map(String);
|
|
4309
4398
|
}, [value]);
|
|
4399
|
+
const selectedRef = react.useRef(selected);
|
|
4400
|
+
selectedRef.current = selected;
|
|
4401
|
+
const emit = (next) => {
|
|
4402
|
+
if (!onValueChange) return;
|
|
4403
|
+
const mapped = next.map(
|
|
4404
|
+
(v) => emitValue ? rawByValue.get(v) ?? v : optionByValue.get(v) ?? { value: v, label: v }
|
|
4405
|
+
);
|
|
4406
|
+
onValueChange(multi ? mapped : mapped[0] ?? (emitValue ? "" : null));
|
|
4407
|
+
};
|
|
4408
|
+
const commitOpen = (next) => {
|
|
4409
|
+
setOpen(next);
|
|
4410
|
+
onOpenChange?.(next);
|
|
4411
|
+
if (!next) {
|
|
4412
|
+
setPendingOpen(false);
|
|
4413
|
+
setSearch("");
|
|
4414
|
+
if (rules && rules.length > 0) {
|
|
4415
|
+
setRuleError(runRules(multi ? selectedRef.current : selectedRef.current[0] ?? "", rules));
|
|
4416
|
+
}
|
|
4417
|
+
}
|
|
4418
|
+
};
|
|
4419
|
+
const requestOpen = (next) => {
|
|
4420
|
+
if (next && insideModal && portalContainer == null) {
|
|
4421
|
+
setPendingOpen(true);
|
|
4422
|
+
return;
|
|
4423
|
+
}
|
|
4424
|
+
commitOpen(next);
|
|
4425
|
+
};
|
|
4426
|
+
react.useEffect(() => {
|
|
4427
|
+
if (!insideModal || portalContainer == null || !pendingOpen) return;
|
|
4428
|
+
setPendingOpen(false);
|
|
4429
|
+
commitOpen(true);
|
|
4430
|
+
}, [insideModal, pendingOpen, portalContainer]);
|
|
4431
|
+
react.useImperativeHandle(
|
|
4432
|
+
ref,
|
|
4433
|
+
() => ({
|
|
4434
|
+
focus: () => triggerRef.current?.focus(),
|
|
4435
|
+
open: () => requestOpen(true)
|
|
4436
|
+
}),
|
|
4437
|
+
[insideModal, portalContainer]
|
|
4438
|
+
);
|
|
4310
4439
|
useFormField({
|
|
4311
4440
|
name,
|
|
4312
4441
|
validate: () => {
|
|
@@ -4316,13 +4445,6 @@ var SSelect = react.forwardRef(function SSelect2({
|
|
|
4316
4445
|
},
|
|
4317
4446
|
resetValidation: () => setRuleError("")
|
|
4318
4447
|
});
|
|
4319
|
-
const emit = (next) => {
|
|
4320
|
-
if (!onValueChange) return;
|
|
4321
|
-
const mapped = next.map(
|
|
4322
|
-
(v) => emitValue ? rawByValue.get(v) ?? v : optionByValue.get(v) ?? { value: v, label: v }
|
|
4323
|
-
);
|
|
4324
|
-
onValueChange(multi ? mapped : mapped[0] ?? (emitValue ? "" : null));
|
|
4325
|
-
};
|
|
4326
4448
|
const filtered = react.useMemo(() => {
|
|
4327
4449
|
if (!showSearch || search.trim() === "") return flat;
|
|
4328
4450
|
const q = search.trim().toLowerCase();
|
|
@@ -4333,6 +4455,16 @@ var SSelect = react.forwardRef(function SSelect2({
|
|
|
4333
4455
|
const allValues = selectable.map((o) => o.value);
|
|
4334
4456
|
const allSelected = allValues.length > 0 && allValues.every((v) => selected.includes(v));
|
|
4335
4457
|
const hasItems = filtered.some((o) => !o.isGroup);
|
|
4458
|
+
const navigableItems = react.useMemo(() => {
|
|
4459
|
+
const items = [];
|
|
4460
|
+
if (multi && useSelectAll && allValues.length > 0) {
|
|
4461
|
+
items.push({ value: "__select_all__", isSelectAll: true });
|
|
4462
|
+
}
|
|
4463
|
+
filtered.forEach((o) => {
|
|
4464
|
+
if (!o.isGroup && !o.disabled) items.push({ value: o.value });
|
|
4465
|
+
});
|
|
4466
|
+
return items;
|
|
4467
|
+
}, [allValues.length, filtered, multi, useSelectAll]);
|
|
4336
4468
|
const triggerText = (() => {
|
|
4337
4469
|
if (selected.length === 0) return placeholder;
|
|
4338
4470
|
if (multi) {
|
|
@@ -4342,26 +4474,119 @@ var SSelect = react.forwardRef(function SSelect2({
|
|
|
4342
4474
|
return labelByValue.get(selected[0]) ?? selected[0];
|
|
4343
4475
|
})();
|
|
4344
4476
|
const isPlaceholder = selected.length === 0;
|
|
4345
|
-
const
|
|
4346
|
-
|
|
4477
|
+
const handleSelect = (nextValue) => {
|
|
4478
|
+
if (multi) {
|
|
4479
|
+
const next = selected.includes(nextValue) ? selected.filter((v) => v !== nextValue) : [...selected, nextValue];
|
|
4480
|
+
emit(next);
|
|
4481
|
+
return;
|
|
4482
|
+
}
|
|
4483
|
+
emit([nextValue]);
|
|
4484
|
+
commitOpen(false);
|
|
4485
|
+
};
|
|
4486
|
+
const handleSelectAll = () => {
|
|
4487
|
+
emit(allSelected ? [] : allValues);
|
|
4488
|
+
};
|
|
4489
|
+
react.useEffect(() => {
|
|
4490
|
+
if (!open) {
|
|
4491
|
+
setFocusedIndex(-1);
|
|
4492
|
+
return;
|
|
4493
|
+
}
|
|
4494
|
+
setFocusedIndex(navigableItems.length > 0 ? 0 : -1);
|
|
4495
|
+
}, [open, navigableItems.length]);
|
|
4496
|
+
react.useEffect(() => {
|
|
4497
|
+
if (!open) return;
|
|
4498
|
+
setFocusedIndex(navigableItems.length > 0 ? 0 : -1);
|
|
4499
|
+
}, [search, open, navigableItems.length]);
|
|
4500
|
+
react.useEffect(() => {
|
|
4501
|
+
if (!open || focusedIndex < 0) return;
|
|
4502
|
+
const list = listRef.current;
|
|
4503
|
+
const focusedEl = list?.querySelector('[data-select-focused="true"]');
|
|
4504
|
+
if (!list || !focusedEl) return;
|
|
4505
|
+
const listRect = list.getBoundingClientRect();
|
|
4506
|
+
const itemRect = focusedEl.getBoundingClientRect();
|
|
4507
|
+
if (itemRect.top < listRect.top) {
|
|
4508
|
+
list.scrollTop += itemRect.top - listRect.top;
|
|
4509
|
+
} else if (itemRect.bottom > listRect.bottom) {
|
|
4510
|
+
list.scrollTop += itemRect.bottom - listRect.bottom;
|
|
4511
|
+
}
|
|
4512
|
+
}, [focusedIndex, open]);
|
|
4513
|
+
const moveFocusedIndex = (direction) => {
|
|
4514
|
+
if (!open || navigableItems.length === 0) return;
|
|
4515
|
+
setFocusedIndex((current) => {
|
|
4516
|
+
if (direction === "next") {
|
|
4517
|
+
return current < 0 ? 0 : (current + 1) % navigableItems.length;
|
|
4518
|
+
}
|
|
4519
|
+
return current <= 0 ? navigableItems.length - 1 : current - 1;
|
|
4520
|
+
});
|
|
4521
|
+
};
|
|
4522
|
+
const selectFocusedItem = () => {
|
|
4523
|
+
if (focusedIndex < 0 || focusedIndex >= navigableItems.length) return;
|
|
4524
|
+
const focused = navigableItems[focusedIndex];
|
|
4525
|
+
if (focused.isSelectAll) {
|
|
4526
|
+
handleSelectAll();
|
|
4527
|
+
return;
|
|
4528
|
+
}
|
|
4529
|
+
handleSelect(focused.value);
|
|
4530
|
+
};
|
|
4531
|
+
const handleKeyDown = (event) => {
|
|
4532
|
+
if (!open) {
|
|
4533
|
+
if ((event.key === "ArrowDown" || event.key === "ArrowUp") && !effectiveDisabled) {
|
|
4534
|
+
event.preventDefault();
|
|
4535
|
+
requestOpen(true);
|
|
4536
|
+
}
|
|
4537
|
+
return;
|
|
4538
|
+
}
|
|
4539
|
+
if (event.key === "ArrowDown") {
|
|
4540
|
+
event.preventDefault();
|
|
4541
|
+
moveFocusedIndex("next");
|
|
4542
|
+
return;
|
|
4543
|
+
}
|
|
4544
|
+
if (event.key === "ArrowUp") {
|
|
4545
|
+
event.preventDefault();
|
|
4546
|
+
moveFocusedIndex("prev");
|
|
4547
|
+
return;
|
|
4548
|
+
}
|
|
4549
|
+
if (event.key === "Enter") {
|
|
4550
|
+
event.preventDefault();
|
|
4551
|
+
selectFocusedItem();
|
|
4552
|
+
return;
|
|
4553
|
+
}
|
|
4554
|
+
if (event.key === "Escape") {
|
|
4555
|
+
event.preventDefault();
|
|
4556
|
+
commitOpen(false);
|
|
4557
|
+
}
|
|
4558
|
+
};
|
|
4559
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4560
|
+
SField,
|
|
4347
4561
|
{
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4562
|
+
label,
|
|
4563
|
+
labelWidth,
|
|
4564
|
+
icon,
|
|
4565
|
+
iconColor,
|
|
4566
|
+
labelTooltip,
|
|
4567
|
+
labelTooltipProps,
|
|
4568
|
+
addonLabel,
|
|
4569
|
+
addonAlign,
|
|
4570
|
+
hint,
|
|
4571
|
+
error: error || ruleError !== "",
|
|
4572
|
+
status: rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0,
|
|
4573
|
+
errorMessage: ruleError !== "" ? ruleError : errorMessage,
|
|
4574
|
+
disabled: effectiveDisabled,
|
|
4575
|
+
width,
|
|
4576
|
+
className,
|
|
4577
|
+
style,
|
|
4359
4578
|
children: [
|
|
4579
|
+
name && /* @__PURE__ */ jsxRuntime.jsx("input", { type: "hidden", name, value: selected.join(",") }),
|
|
4360
4580
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4361
|
-
|
|
4581
|
+
"button",
|
|
4362
4582
|
{
|
|
4363
4583
|
ref: triggerRef,
|
|
4584
|
+
type: "button",
|
|
4364
4585
|
disabled: effectiveDisabled,
|
|
4586
|
+
"aria-haspopup": "listbox",
|
|
4587
|
+
"aria-expanded": open,
|
|
4588
|
+
onClick: () => requestOpen(!open),
|
|
4589
|
+
onKeyDown: handleKeyDown,
|
|
4365
4590
|
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",
|
|
4366
4591
|
style: {
|
|
4367
4592
|
color: effectiveDisabled ? "var(--cmp-select-text-disabled)" : isPlaceholder ? "var(--cmp-select-icon-default)" : "var(--cmp-select-text-default)"
|
|
@@ -4386,174 +4611,229 @@ var SSelect = react.forwardRef(function SSelect2({
|
|
|
4386
4611
|
]
|
|
4387
4612
|
}
|
|
4388
4613
|
),
|
|
4389
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4390
|
-
|
|
4614
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4615
|
+
SPortal,
|
|
4391
4616
|
{
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4617
|
+
open,
|
|
4618
|
+
onClose: () => commitOpen(false),
|
|
4619
|
+
onOpenChange: (next) => {
|
|
4620
|
+
if (next) requestOpen(true);
|
|
4621
|
+
},
|
|
4622
|
+
anchorRef: triggerRef,
|
|
4623
|
+
placement: "bottom",
|
|
4624
|
+
align: "start",
|
|
4625
|
+
offset: 4,
|
|
4626
|
+
fit: !dropdownWidth,
|
|
4627
|
+
onOpenAutoFocus: (event) => {
|
|
4628
|
+
if (!showSearch) {
|
|
4629
|
+
event.preventDefault();
|
|
4630
|
+
return;
|
|
4631
|
+
}
|
|
4632
|
+
event.preventDefault();
|
|
4633
|
+
requestAnimationFrame(() => searchInputRef.current?.focus());
|
|
4634
|
+
},
|
|
4635
|
+
onCloseAutoFocus: (event) => {
|
|
4636
|
+
event.preventDefault();
|
|
4637
|
+
triggerRef.current?.focus();
|
|
4638
|
+
},
|
|
4639
|
+
className: "rounded-[var(--cmp-listBox-radius)] bg-[var(--cmp-listBox-bg)] py-[4px] shadow-[2px_2px_12px_2px_rgba(0,0,0,0.1)]",
|
|
4397
4640
|
style: {
|
|
4398
|
-
maxHeight: dropdownHeight,
|
|
4399
4641
|
...dropdownWidth ? { width: dropdownWidth } : {},
|
|
4400
4642
|
maxWidth: maxDropdownWidth
|
|
4401
4643
|
},
|
|
4402
|
-
children:
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4644
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4645
|
+
"div",
|
|
4646
|
+
{
|
|
4647
|
+
ref: listRef,
|
|
4648
|
+
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)]",
|
|
4649
|
+
style: { maxHeight: dropdownHeight },
|
|
4650
|
+
onMouseLeave: () => setFocusedIndex(-1),
|
|
4651
|
+
children: [
|
|
4652
|
+
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: [
|
|
4653
|
+
/* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: "search", size: 16, color: "var(--color-grey-70)", className: "shrink-0" }),
|
|
4654
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4655
|
+
"input",
|
|
4656
|
+
{
|
|
4657
|
+
ref: searchInputRef,
|
|
4658
|
+
value: search,
|
|
4659
|
+
onChange: (e) => setSearch(e.target.value),
|
|
4660
|
+
onKeyDown: handleKeyDown,
|
|
4661
|
+
placeholder: "\uAC80\uC0C9",
|
|
4662
|
+
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)]"
|
|
4663
|
+
}
|
|
4664
|
+
),
|
|
4665
|
+
search !== "" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4666
|
+
SGhostButton,
|
|
4667
|
+
{
|
|
4668
|
+
icon: "close",
|
|
4669
|
+
size: "xxs",
|
|
4670
|
+
intent: "default",
|
|
4671
|
+
ariaLabel: "\uAC80\uC0C9\uC5B4 \uC9C0\uC6B0\uAE30",
|
|
4672
|
+
onClick: () => setSearch(""),
|
|
4673
|
+
className: "shrink-0"
|
|
4674
|
+
}
|
|
4675
|
+
)
|
|
4676
|
+
] }) }),
|
|
4677
|
+
hasItems ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4678
|
+
ItemList,
|
|
4679
|
+
{
|
|
4680
|
+
items: filtered,
|
|
4681
|
+
multi,
|
|
4682
|
+
selected,
|
|
4683
|
+
focusedValue: navigableItems[focusedIndex]?.isSelectAll ? "__select_all__" : navigableItems[focusedIndex]?.value,
|
|
4684
|
+
showSelectAll: multi && useSelectAll && allValues.length > 0,
|
|
4685
|
+
selectAllLabel: allSelectedLabel,
|
|
4686
|
+
selectAllSelected: allSelected,
|
|
4687
|
+
onSelectAll: handleSelectAll,
|
|
4688
|
+
onSelect: handleSelect,
|
|
4689
|
+
onHoverValue: (value2) => {
|
|
4690
|
+
const index = navigableItems.findIndex(
|
|
4691
|
+
(item) => item.isSelectAll ? value2 === "__select_all__" : item.value === value2
|
|
4692
|
+
);
|
|
4693
|
+
if (index >= 0) setFocusedIndex(index);
|
|
4694
|
+
}
|
|
4695
|
+
}
|
|
4696
|
+
) : /* @__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." })
|
|
4697
|
+
]
|
|
4698
|
+
}
|
|
4699
|
+
)
|
|
4440
4700
|
}
|
|
4441
4701
|
)
|
|
4442
4702
|
]
|
|
4443
4703
|
}
|
|
4444
4704
|
);
|
|
4445
|
-
const control = showSearch ? /* @__PURE__ */ jsxRuntime.jsx(Ariakit__namespace.ComboboxProvider, { value: search, setValue: setSearch, resetValueOnHide: true, children: selectStore }) : selectStore;
|
|
4446
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4447
|
-
SField,
|
|
4448
|
-
{
|
|
4449
|
-
label,
|
|
4450
|
-
labelWidth,
|
|
4451
|
-
icon,
|
|
4452
|
-
labelTooltip,
|
|
4453
|
-
labelTooltipProps,
|
|
4454
|
-
addonLabel,
|
|
4455
|
-
addonAlign,
|
|
4456
|
-
hint,
|
|
4457
|
-
error: error || ruleError !== "",
|
|
4458
|
-
status: rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0,
|
|
4459
|
-
errorMessage: ruleError !== "" ? ruleError : errorMessage,
|
|
4460
|
-
disabled: effectiveDisabled,
|
|
4461
|
-
width,
|
|
4462
|
-
className,
|
|
4463
|
-
style,
|
|
4464
|
-
children: [
|
|
4465
|
-
name && /* @__PURE__ */ jsxRuntime.jsx("input", { type: "hidden", name, value: selected.join(",") }),
|
|
4466
|
-
control
|
|
4467
|
-
]
|
|
4468
|
-
}
|
|
4469
|
-
);
|
|
4470
4705
|
});
|
|
4471
4706
|
SSelect.displayName = "SSelect";
|
|
4472
4707
|
function ItemList({
|
|
4473
4708
|
items,
|
|
4474
4709
|
multi,
|
|
4475
4710
|
selected,
|
|
4476
|
-
|
|
4711
|
+
focusedValue,
|
|
4712
|
+
showSelectAll,
|
|
4713
|
+
selectAllLabel,
|
|
4714
|
+
selectAllSelected,
|
|
4715
|
+
onSelectAll,
|
|
4716
|
+
onSelect,
|
|
4717
|
+
onHoverValue
|
|
4477
4718
|
}) {
|
|
4478
4719
|
const itemBase = cn(
|
|
4479
|
-
|
|
4480
|
-
"group flex cursor-pointer select-none items-center gap-[8px] text-[12px] leading-[20px] outline-none",
|
|
4720
|
+
"group flex w-full cursor-pointer select-none items-center gap-[8px] border-none bg-transparent text-left text-[12px] leading-[20px] outline-none",
|
|
4481
4721
|
"text-[color:var(--cmp-listItem-content-default)]",
|
|
4482
|
-
|
|
4483
|
-
"aria-disabled:cursor-not-allowed aria-disabled:text-[color:var(--cmp-listItem-content-disabled)]"
|
|
4722
|
+
"disabled:cursor-not-allowed disabled:text-[color:var(--cmp-listItem-content-disabled)]"
|
|
4484
4723
|
);
|
|
4485
|
-
const activeClass = "
|
|
4486
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
const isDepth1 = o.depth === 1;
|
|
4490
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4491
|
-
"div",
|
|
4492
|
-
{
|
|
4493
|
-
className: cn(
|
|
4494
|
-
"select-none py-[4px] pr-[12px] text-[12px] leading-[20px] text-[color:var(--cmp-listItem-content-default)]",
|
|
4495
|
-
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",
|
|
4496
|
-
// 하위가 전부 비활성이면(select.config 에서 bubble-up) 어미 그룹도 비활성 처리:
|
|
4497
|
-
// 텍스트는 회색(#888), depth1 그룹은 파란 배경 대신 회색(#EEE)으로 (depth2 는 #F6F6F6 유지)
|
|
4498
|
-
o.disabled && "text-[color:var(--cmp-listItem-content-disabled)]",
|
|
4499
|
-
o.disabled && isDepth1 && "bg-[var(--cmp-listItem-depth1-bg-disabled)]"
|
|
4500
|
-
),
|
|
4501
|
-
style: { paddingLeft: padLeft },
|
|
4502
|
-
children: o.label
|
|
4503
|
-
},
|
|
4504
|
-
o.value
|
|
4505
|
-
);
|
|
4506
|
-
}
|
|
4507
|
-
const isSelected = selected.includes(o.value);
|
|
4508
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4509
|
-
Ariakit__namespace.SelectItem,
|
|
4724
|
+
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)]";
|
|
4725
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "listbox", "aria-multiselectable": multi || void 0, children: [
|
|
4726
|
+
showSelectAll && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4727
|
+
"button",
|
|
4510
4728
|
{
|
|
4511
|
-
|
|
4512
|
-
|
|
4729
|
+
type: "button",
|
|
4730
|
+
"data-select-focused": focusedValue === "__select_all__" ? "true" : void 0,
|
|
4731
|
+
"data-select-active": focusedValue === "__select_all__" ? "true" : void 0,
|
|
4513
4732
|
className: cn(
|
|
4514
4733
|
itemBase,
|
|
4515
|
-
|
|
4516
|
-
activeClass
|
|
4734
|
+
focusedValue === "__select_all__" && "bg-[var(--cmp-listItem-bg-hover)] text-[color:var(--cmp-listItem-content-hover)]"
|
|
4517
4735
|
),
|
|
4518
|
-
style: { paddingTop: 4, paddingBottom: 4, paddingRight: 12, paddingLeft:
|
|
4519
|
-
|
|
4736
|
+
style: { paddingTop: 4, paddingBottom: 4, paddingRight: 12, paddingLeft: 12 },
|
|
4737
|
+
onMouseEnter: () => onHoverValue("__select_all__"),
|
|
4738
|
+
onClick: onSelectAll,
|
|
4520
4739
|
children: [
|
|
4521
|
-
multi && // hover(active) 시 checkbox inverse — 파란 hover 배경 위에서 checked/unchecked 모두 흰 테두리 + 투명 배경
|
|
4522
4740
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4523
4741
|
"span",
|
|
4524
4742
|
{
|
|
4525
4743
|
className: cn(
|
|
4526
4744
|
"flex h-[16px] w-[16px] flex-shrink-0 items-center justify-center rounded-[2px] border border-solid",
|
|
4527
|
-
|
|
4528
|
-
// 비활성: 회색 채움(#E1E1E1) + 회색 테두리(#CCCCCC)
|
|
4529
|
-
"border-[color:var(--cmp-checkbox-border-disabled)] bg-[var(--cmp-checkbox-bg-disabled)]"
|
|
4530
|
-
) : cn(
|
|
4531
|
-
"group-data-[active-item]:border-[color:var(--cmp-checkbox-checked-border-inverse)]",
|
|
4532
|
-
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"
|
|
4533
|
-
)
|
|
4745
|
+
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)]"
|
|
4534
4746
|
),
|
|
4535
|
-
children:
|
|
4747
|
+
children: selectAllSelected && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4536
4748
|
SIcon,
|
|
4537
4749
|
{
|
|
4538
4750
|
name: "checkboxCheck",
|
|
4539
4751
|
size: 12,
|
|
4540
|
-
color:
|
|
4752
|
+
color: "var(--cmp-checkbox-checked-icon-default)"
|
|
4541
4753
|
}
|
|
4542
4754
|
)
|
|
4543
4755
|
}
|
|
4544
4756
|
),
|
|
4545
|
-
|
|
4546
|
-
"span",
|
|
4547
|
-
{
|
|
4548
|
-
className: "flex-1 truncate",
|
|
4549
|
-
dangerouslySetInnerHTML: { __html: sanitizeInlineHtml(o.label) }
|
|
4550
|
-
}
|
|
4551
|
-
) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children: o.label })
|
|
4757
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children: selectAllLabel })
|
|
4552
4758
|
]
|
|
4553
|
-
}
|
|
4554
|
-
|
|
4555
|
-
)
|
|
4556
|
-
|
|
4759
|
+
}
|
|
4760
|
+
),
|
|
4761
|
+
items.map((o) => {
|
|
4762
|
+
const padLeft = o.depth === 1 ? 12 : o.depth === 2 ? 20 : 28;
|
|
4763
|
+
if (o.isGroup) {
|
|
4764
|
+
const isDepth1 = o.depth === 1;
|
|
4765
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4766
|
+
"div",
|
|
4767
|
+
{
|
|
4768
|
+
className: cn(
|
|
4769
|
+
"select-none py-[4px] pr-[12px] text-[12px] leading-[20px] text-[color:var(--cmp-listItem-content-default)]",
|
|
4770
|
+
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",
|
|
4771
|
+
// 하위가 전부 비활성이면(select.config 에서 bubble-up) 어미 그룹도 비활성 처리:
|
|
4772
|
+
// 텍스트는 회색(#888), depth1 그룹은 파란 배경 대신 회색(#EEE)으로 (depth2 는 #F6F6F6 유지)
|
|
4773
|
+
o.disabled && "cursor-not-allowed text-[color:var(--cmp-listItem-content-disabled)]",
|
|
4774
|
+
o.disabled && isDepth1 && "bg-[var(--cmp-listItem-depth1-bg-disabled)]"
|
|
4775
|
+
),
|
|
4776
|
+
style: { paddingLeft: padLeft },
|
|
4777
|
+
children: o.label
|
|
4778
|
+
},
|
|
4779
|
+
o.value
|
|
4780
|
+
);
|
|
4781
|
+
}
|
|
4782
|
+
const isSelected = selected.includes(o.value);
|
|
4783
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4784
|
+
"button",
|
|
4785
|
+
{
|
|
4786
|
+
type: "button",
|
|
4787
|
+
disabled: o.disabled,
|
|
4788
|
+
role: "option",
|
|
4789
|
+
"aria-selected": isSelected,
|
|
4790
|
+
"data-select-focused": focusedValue === o.value ? "true" : void 0,
|
|
4791
|
+
"data-select-active": focusedValue === o.value ? "true" : void 0,
|
|
4792
|
+
className: cn(
|
|
4793
|
+
itemBase,
|
|
4794
|
+
isSelected && !multi && "font-bold text-[color:var(--cmp-listItem-content-selected)]",
|
|
4795
|
+
focusedValue === o.value && "bg-[var(--cmp-listItem-bg-hover)] text-[color:var(--cmp-listItem-content-hover)]",
|
|
4796
|
+
activeClass
|
|
4797
|
+
),
|
|
4798
|
+
style: { paddingTop: 4, paddingBottom: 4, paddingRight: 12, paddingLeft: padLeft },
|
|
4799
|
+
onMouseEnter: () => onHoverValue(o.value),
|
|
4800
|
+
onClick: () => onSelect(o.value),
|
|
4801
|
+
children: [
|
|
4802
|
+
multi && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4803
|
+
"span",
|
|
4804
|
+
{
|
|
4805
|
+
className: cn(
|
|
4806
|
+
"flex h-[16px] w-[16px] flex-shrink-0 items-center justify-center rounded-[2px] border border-solid",
|
|
4807
|
+
o.disabled ? (
|
|
4808
|
+
// 비활성: 회색 채움(#E1E1E1) + 회색 테두리(#CCCCCC)
|
|
4809
|
+
"cursor-not-allowed border-[color:var(--cmp-checkbox-border-disabled)] bg-[var(--cmp-checkbox-bg-disabled)]"
|
|
4810
|
+
) : cn(
|
|
4811
|
+
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)]"
|
|
4812
|
+
)
|
|
4813
|
+
),
|
|
4814
|
+
children: isSelected && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4815
|
+
SIcon,
|
|
4816
|
+
{
|
|
4817
|
+
name: "checkboxCheck",
|
|
4818
|
+
size: 12,
|
|
4819
|
+
color: o.disabled ? "var(--cmp-checkbox-checked-icon-disabled)" : "var(--cmp-checkbox-checked-icon-default)"
|
|
4820
|
+
}
|
|
4821
|
+
)
|
|
4822
|
+
}
|
|
4823
|
+
),
|
|
4824
|
+
isHtmlLabel(o.label) ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4825
|
+
"span",
|
|
4826
|
+
{
|
|
4827
|
+
className: "flex-1 truncate",
|
|
4828
|
+
dangerouslySetInnerHTML: { __html: sanitizeInlineHtml(o.label) }
|
|
4829
|
+
}
|
|
4830
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children: o.label })
|
|
4831
|
+
]
|
|
4832
|
+
},
|
|
4833
|
+
o.value
|
|
4834
|
+
);
|
|
4835
|
+
})
|
|
4836
|
+
] });
|
|
4557
4837
|
}
|
|
4558
4838
|
function SRadio({
|
|
4559
4839
|
val,
|
|
@@ -4661,7 +4941,7 @@ function SRadioGroup({
|
|
|
4661
4941
|
role: "radiogroup",
|
|
4662
4942
|
className: cn(
|
|
4663
4943
|
"inline-flex",
|
|
4664
|
-
direction === "vertical" ? "flex-col gap-[
|
|
4944
|
+
direction === "vertical" ? "flex-col gap-[var(--cmp-radio-group-gap-vertical)]" : "flex-row gap-[var(--cmp-radio-group-gap-horizontal)]",
|
|
4665
4945
|
className
|
|
4666
4946
|
),
|
|
4667
4947
|
style,
|
|
@@ -5016,6 +5296,7 @@ function SDatePicker({
|
|
|
5016
5296
|
label,
|
|
5017
5297
|
labelWidth,
|
|
5018
5298
|
icon,
|
|
5299
|
+
iconColor,
|
|
5019
5300
|
labelTooltip,
|
|
5020
5301
|
labelTooltipProps,
|
|
5021
5302
|
addonLabel,
|
|
@@ -5054,6 +5335,7 @@ function SDatePicker({
|
|
|
5054
5335
|
label,
|
|
5055
5336
|
labelWidth,
|
|
5056
5337
|
icon,
|
|
5338
|
+
iconColor,
|
|
5057
5339
|
labelTooltip,
|
|
5058
5340
|
labelTooltipProps,
|
|
5059
5341
|
addonLabel,
|
|
@@ -5322,6 +5604,7 @@ function SDateRangePicker({
|
|
|
5322
5604
|
label,
|
|
5323
5605
|
labelWidth,
|
|
5324
5606
|
icon,
|
|
5607
|
+
iconColor,
|
|
5325
5608
|
labelTooltip,
|
|
5326
5609
|
labelTooltipProps,
|
|
5327
5610
|
addonLabel,
|
|
@@ -5364,6 +5647,7 @@ function SDateRangePicker({
|
|
|
5364
5647
|
label,
|
|
5365
5648
|
labelWidth,
|
|
5366
5649
|
icon,
|
|
5650
|
+
iconColor,
|
|
5367
5651
|
labelTooltip,
|
|
5368
5652
|
labelTooltipProps,
|
|
5369
5653
|
addonLabel,
|
|
@@ -5625,6 +5909,7 @@ function SFilePicker({
|
|
|
5625
5909
|
label,
|
|
5626
5910
|
labelWidth,
|
|
5627
5911
|
icon,
|
|
5912
|
+
iconColor,
|
|
5628
5913
|
labelTooltip,
|
|
5629
5914
|
labelTooltipProps,
|
|
5630
5915
|
addonLabel,
|
|
@@ -5639,7 +5924,10 @@ function SFilePicker({
|
|
|
5639
5924
|
const autoId = react.useId();
|
|
5640
5925
|
const resolvedName = name ?? autoId;
|
|
5641
5926
|
const inputRef = react.useRef(null);
|
|
5927
|
+
const contentBoxRef = react.useRef(null);
|
|
5642
5928
|
const [ruleError, setRuleError] = react.useState("");
|
|
5929
|
+
const [listOpen, setListOpen] = react.useState(false);
|
|
5930
|
+
const portalContainer = usePortalContainer();
|
|
5643
5931
|
const files = multiple ? Array.isArray(value) ? value : [] : value && !Array.isArray(value) ? value : null;
|
|
5644
5932
|
const hasFiles = multiple ? files.length > 0 : !!files;
|
|
5645
5933
|
const displayText = !hasFiles ? placeholder : multiple ? files.map((f) => f.name).join(", ") : files.name;
|
|
@@ -5693,10 +5981,12 @@ function SFilePicker({
|
|
|
5693
5981
|
e.stopPropagation();
|
|
5694
5982
|
if (disabled) return;
|
|
5695
5983
|
onValueChange?.(multiple ? [] : null);
|
|
5984
|
+
setListOpen(false);
|
|
5696
5985
|
};
|
|
5697
5986
|
const removeChip = (i) => {
|
|
5698
5987
|
const next = files.filter((_, idx) => idx !== i);
|
|
5699
5988
|
onValueChange?.(next);
|
|
5989
|
+
if (next.length === 0) setListOpen(false);
|
|
5700
5990
|
};
|
|
5701
5991
|
const open = () => {
|
|
5702
5992
|
if (!disabled) inputRef.current?.click();
|
|
@@ -5707,9 +5997,12 @@ function SFilePicker({
|
|
|
5707
5997
|
const iconSize = size === "md" ? 20 : 16;
|
|
5708
5998
|
const gapCls = size === "md" ? "gap-[var(--cmp-filepicker-md-gap)]" : "gap-[var(--cmp-filepicker-sm-gap)]";
|
|
5709
5999
|
const inlinePlaceholder = inline && !disabled && !hasFiles;
|
|
5710
|
-
const
|
|
6000
|
+
const showListbox = multiple && useMultipleListBox;
|
|
6001
|
+
const filesArr = multiple ? files : [];
|
|
6002
|
+
const contentInner = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5711
6003
|
"div",
|
|
5712
6004
|
{
|
|
6005
|
+
ref: contentBoxRef,
|
|
5713
6006
|
className: cn("group/filepicker flex h-full w-full items-center", gapCls),
|
|
5714
6007
|
style: { padding: inline ? 0 : `0 ${padX}` },
|
|
5715
6008
|
children: [
|
|
@@ -5764,25 +6057,34 @@ function SFilePicker({
|
|
|
5764
6057
|
]
|
|
5765
6058
|
}
|
|
5766
6059
|
),
|
|
6060
|
+
showListbox && hasFiles && !disabled && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6061
|
+
Ariakit__namespace.PopoverDisclosure,
|
|
6062
|
+
{
|
|
6063
|
+
render: /* @__PURE__ */ jsxRuntime.jsx(SGhostButton, { icon: "caretDown", size: "xxs", ariaLabel: "toggle file list" }),
|
|
6064
|
+
className: cn("shrink-0 transition-transform duration-150", listOpen && "rotate-180")
|
|
6065
|
+
}
|
|
6066
|
+
),
|
|
5767
6067
|
!disabled && hasFiles && /* @__PURE__ */ jsxRuntime.jsx(SGhostButton, { icon: "close", size: "xxs", ariaLabel: "clear", onClick: clear })
|
|
5768
6068
|
]
|
|
5769
6069
|
}
|
|
5770
6070
|
);
|
|
5771
|
-
const
|
|
5772
|
-
|
|
5773
|
-
|
|
5774
|
-
|
|
5775
|
-
|
|
5776
|
-
|
|
5777
|
-
|
|
5778
|
-
|
|
5779
|
-
|
|
5780
|
-
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
6071
|
+
const content = showListbox ? /* @__PURE__ */ jsxRuntime.jsxs(Ariakit__namespace.PopoverProvider, { open: listOpen, setOpen: setListOpen, placement: "bottom-start", children: [
|
|
6072
|
+
contentInner,
|
|
6073
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6074
|
+
Ariakit__namespace.Popover,
|
|
6075
|
+
{
|
|
6076
|
+
portal: true,
|
|
6077
|
+
portalElement: portalContainer,
|
|
6078
|
+
gutter: 4,
|
|
6079
|
+
unmountOnHide: true,
|
|
6080
|
+
getAnchorRect: () => contentBoxRef.current?.getBoundingClientRect() ?? null,
|
|
6081
|
+
style: { minWidth: contentBoxRef.current?.offsetWidth },
|
|
6082
|
+
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)]",
|
|
6083
|
+
children: filesArr.map((f, i) => /* @__PURE__ */ jsxRuntime.jsx(SChip, { value: f.name, editable: false, onRemove: () => removeChip(i) }, i))
|
|
6084
|
+
}
|
|
6085
|
+
)
|
|
6086
|
+
] }) : contentInner;
|
|
6087
|
+
const chips = multiple && !useMultipleListBox && filesArr.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-[8px] flex flex-wrap gap-[8px]", children: filesArr.map((f, i) => /* @__PURE__ */ jsxRuntime.jsx(SChip, { value: f.name, editable: false, onRemove: () => removeChip(i) }, i)) });
|
|
5786
6088
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style, children: [
|
|
5787
6089
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5788
6090
|
SField,
|
|
@@ -5791,6 +6093,7 @@ function SFilePicker({
|
|
|
5791
6093
|
label,
|
|
5792
6094
|
labelWidth,
|
|
5793
6095
|
icon,
|
|
6096
|
+
iconColor,
|
|
5794
6097
|
labelTooltip,
|
|
5795
6098
|
labelTooltipProps,
|
|
5796
6099
|
addonLabel,
|
|
@@ -5813,21 +6116,26 @@ function SFilePicker({
|
|
|
5813
6116
|
var cssLen2 = (v) => v == null ? void 0 : typeof v === "number" ? `${v}px` : v;
|
|
5814
6117
|
function SKeyValueTable({
|
|
5815
6118
|
fields = [],
|
|
6119
|
+
values = {},
|
|
5816
6120
|
search = false,
|
|
5817
6121
|
radius = "default",
|
|
5818
|
-
dense = false,
|
|
5819
6122
|
onChange,
|
|
5820
6123
|
onSearch,
|
|
5821
6124
|
className,
|
|
5822
6125
|
style
|
|
5823
6126
|
}) {
|
|
5824
6127
|
if (fields.length === 0) return null;
|
|
5825
|
-
const emit = (name, value) => onChange?.({
|
|
5826
|
-
|
|
5827
|
-
|
|
6128
|
+
const emit = (name, value) => onChange?.({
|
|
6129
|
+
name,
|
|
6130
|
+
value,
|
|
6131
|
+
values: { ...values, [name]: value }
|
|
6132
|
+
});
|
|
6133
|
+
const cellHeight = "var(--cmp-table-keyValue-height)";
|
|
6134
|
+
const cellPadY = "var(--cmp-table-keyValue-body-paddingY)";
|
|
5828
6135
|
const renderField = (f) => {
|
|
5829
6136
|
if (f.render) return f.render;
|
|
5830
|
-
const opt = f.options ?? {};
|
|
6137
|
+
const opt = { ...f.options ?? {} };
|
|
6138
|
+
if (Object.prototype.hasOwnProperty.call(values, f.name)) opt.value = values[f.name];
|
|
5831
6139
|
const up = (v) => emit(f.name, v);
|
|
5832
6140
|
switch (f.type) {
|
|
5833
6141
|
case "input":
|
|
@@ -5939,7 +6247,10 @@ function SKeyValueTable({
|
|
|
5939
6247
|
rowSpan: f.tdRowSpan && f.tdRowSpan > 1 ? f.tdRowSpan : void 0,
|
|
5940
6248
|
colSpan: f.tdColSpan && f.tdColSpan > 1 ? f.tdColSpan : void 0,
|
|
5941
6249
|
className: cn(
|
|
5942
|
-
"box-border bg-[var(--sys-color-bg-frame)]
|
|
6250
|
+
"box-border bg-[var(--sys-color-bg-frame)] align-middle",
|
|
6251
|
+
// text 타입(및 미지정 기본값)은 읽기 전용 콘텐츠라 넓은 paddingX(wide),
|
|
6252
|
+
// 폼 필드 셀은 default paddingX 유지
|
|
6253
|
+
f.type == null || f.type === "text" ? "px-[var(--cmp-table-keyValue-body-paddingX-wide)]" : "px-[var(--cmp-table-keyValue-body-paddingX-default)]",
|
|
5943
6254
|
cellBorder,
|
|
5944
6255
|
f.tdClass
|
|
5945
6256
|
),
|