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
|
@@ -4,8 +4,8 @@ import { clsx } from 'clsx';
|
|
|
4
4
|
import { extendTailwindMerge } from 'tailwind-merge';
|
|
5
5
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
6
6
|
import * as RPopover2 from '@radix-ui/react-popover';
|
|
7
|
-
import * as Ariakit from '@ariakit/react';
|
|
8
7
|
import * as RCheckbox from '@radix-ui/react-checkbox';
|
|
8
|
+
import * as Ariakit from '@ariakit/react';
|
|
9
9
|
|
|
10
10
|
var twMerge = extendTailwindMerge({
|
|
11
11
|
extend: {
|
|
@@ -2873,10 +2873,15 @@ var FLOATING_SLIDE_ANIM = [
|
|
|
2873
2873
|
"data-[state=closed]:data-[side=right]:animate-floating-out-right"
|
|
2874
2874
|
].join(" ");
|
|
2875
2875
|
var PortalContainerContext = createContext(null);
|
|
2876
|
+
var InsideModalContext = createContext(false);
|
|
2876
2877
|
PortalContainerContext.Provider;
|
|
2878
|
+
InsideModalContext.Provider;
|
|
2877
2879
|
function usePortalContainer() {
|
|
2878
2880
|
return useContext(PortalContainerContext) ?? void 0;
|
|
2879
2881
|
}
|
|
2882
|
+
function useInsideModal() {
|
|
2883
|
+
return useContext(InsideModalContext);
|
|
2884
|
+
}
|
|
2880
2885
|
|
|
2881
2886
|
// src/components/STag/tag.config.ts
|
|
2882
2887
|
var TAG_SIZE_CONFIG = {
|
|
@@ -3400,6 +3405,7 @@ var SField = forwardRef(function SField2({
|
|
|
3400
3405
|
name,
|
|
3401
3406
|
label = "",
|
|
3402
3407
|
icon,
|
|
3408
|
+
iconColor,
|
|
3403
3409
|
labelTooltip = "",
|
|
3404
3410
|
labelTooltipProps,
|
|
3405
3411
|
labelWidth,
|
|
@@ -3477,7 +3483,15 @@ var SField = forwardRef(function SField2({
|
|
|
3477
3483
|
lineHeight: `${s.lineHeight}px`
|
|
3478
3484
|
},
|
|
3479
3485
|
children: [
|
|
3480
|
-
icon && /* @__PURE__ */ jsx(
|
|
3486
|
+
icon && /* @__PURE__ */ jsx(
|
|
3487
|
+
SIcon,
|
|
3488
|
+
{
|
|
3489
|
+
name: icon,
|
|
3490
|
+
size: s.icon,
|
|
3491
|
+
color: iconColor,
|
|
3492
|
+
style: { marginRight: s.labelGap }
|
|
3493
|
+
}
|
|
3494
|
+
),
|
|
3481
3495
|
/* @__PURE__ */ jsx("span", { className: "min-w-0 overflow-hidden text-ellipsis whitespace-nowrap", children: label }),
|
|
3482
3496
|
(labelTooltip !== "" || labelTooltipProps) && /* @__PURE__ */ jsx("span", { className: "shrink-0", style: { marginLeft: s.labelGap }, children: /* @__PURE__ */ jsx(
|
|
3483
3497
|
STooltip,
|
|
@@ -3527,7 +3541,7 @@ var SField = forwardRef(function SField2({
|
|
|
3527
3541
|
borderBottomLeftRadius: s.radius - 1
|
|
3528
3542
|
},
|
|
3529
3543
|
children: [
|
|
3530
|
-
icon && !label && /* @__PURE__ */ jsx(SIcon, { name: icon, size: s.icon }),
|
|
3544
|
+
icon && !label && /* @__PURE__ */ jsx(SIcon, { name: icon, size: s.icon, color: iconColor }),
|
|
3531
3545
|
effectiveAddonLabel
|
|
3532
3546
|
]
|
|
3533
3547
|
}
|
|
@@ -3553,6 +3567,7 @@ var SInput = forwardRef(function SInput2({
|
|
|
3553
3567
|
type = "text",
|
|
3554
3568
|
size = "sm",
|
|
3555
3569
|
icon,
|
|
3570
|
+
iconColor,
|
|
3556
3571
|
prefix,
|
|
3557
3572
|
suffix,
|
|
3558
3573
|
clearable = false,
|
|
@@ -3606,6 +3621,7 @@ var SInput = forwardRef(function SInput2({
|
|
|
3606
3621
|
labelTooltip,
|
|
3607
3622
|
labelTooltipProps,
|
|
3608
3623
|
icon,
|
|
3624
|
+
iconColor,
|
|
3609
3625
|
size,
|
|
3610
3626
|
hint,
|
|
3611
3627
|
error: resolvedError,
|
|
@@ -3707,6 +3723,7 @@ var STextarea = forwardRef(function STextarea2({
|
|
|
3707
3723
|
label,
|
|
3708
3724
|
labelWidth,
|
|
3709
3725
|
icon,
|
|
3726
|
+
iconColor,
|
|
3710
3727
|
labelTooltip,
|
|
3711
3728
|
labelTooltipProps,
|
|
3712
3729
|
addonLabel,
|
|
@@ -3743,6 +3760,7 @@ var STextarea = forwardRef(function STextarea2({
|
|
|
3743
3760
|
label,
|
|
3744
3761
|
labelWidth,
|
|
3745
3762
|
icon,
|
|
3763
|
+
iconColor,
|
|
3746
3764
|
labelTooltip,
|
|
3747
3765
|
labelTooltipProps,
|
|
3748
3766
|
addonLabel,
|
|
@@ -3875,6 +3893,7 @@ var SNumberInput = forwardRef(function SNumberInput2({
|
|
|
3875
3893
|
label,
|
|
3876
3894
|
labelWidth,
|
|
3877
3895
|
icon,
|
|
3896
|
+
iconColor,
|
|
3878
3897
|
labelTooltip,
|
|
3879
3898
|
labelTooltipProps,
|
|
3880
3899
|
addonLabel,
|
|
@@ -4033,6 +4052,7 @@ var SNumberInput = forwardRef(function SNumberInput2({
|
|
|
4033
4052
|
label,
|
|
4034
4053
|
labelWidth,
|
|
4035
4054
|
icon,
|
|
4055
|
+
iconColor,
|
|
4036
4056
|
labelTooltip,
|
|
4037
4057
|
labelTooltipProps,
|
|
4038
4058
|
addonLabel,
|
|
@@ -4118,40 +4138,6 @@ var SNumberInput = forwardRef(function SNumberInput2({
|
|
|
4118
4138
|
);
|
|
4119
4139
|
});
|
|
4120
4140
|
|
|
4121
|
-
// src/components/SSelect/select.config.ts
|
|
4122
|
-
function flattenOptions(options, depth = 1) {
|
|
4123
|
-
const out = [];
|
|
4124
|
-
for (const o of options) {
|
|
4125
|
-
const hasChildren = Array.isArray(o.children) && o.children.length > 0;
|
|
4126
|
-
if (hasChildren) {
|
|
4127
|
-
const childFlat = flattenOptions(o.children, depth + 1);
|
|
4128
|
-
const allChildrenDisabled = childFlat.every((c) => c.disabled);
|
|
4129
|
-
out.push({
|
|
4130
|
-
value: String(o.value),
|
|
4131
|
-
label: o.label,
|
|
4132
|
-
disabled: !!o.disabled || allChildrenDisabled,
|
|
4133
|
-
depth,
|
|
4134
|
-
isGroup: true,
|
|
4135
|
-
raw: o.value
|
|
4136
|
-
});
|
|
4137
|
-
out.push(...childFlat);
|
|
4138
|
-
} else {
|
|
4139
|
-
out.push({
|
|
4140
|
-
value: String(o.value),
|
|
4141
|
-
label: o.label,
|
|
4142
|
-
disabled: !!o.disabled,
|
|
4143
|
-
depth,
|
|
4144
|
-
isGroup: false,
|
|
4145
|
-
raw: o.value
|
|
4146
|
-
});
|
|
4147
|
-
}
|
|
4148
|
-
}
|
|
4149
|
-
return out;
|
|
4150
|
-
}
|
|
4151
|
-
var selectableOptions = (flat) => flat.filter((o) => !o.isGroup && !o.disabled);
|
|
4152
|
-
var isHtmlLabel = (label) => /<[a-z][\s\S]*>/i.test(label);
|
|
4153
|
-
var extractText = (html) => html.replace(/<[^>]*>/g, "");
|
|
4154
|
-
|
|
4155
4141
|
// src/lib/sanitize-inline-html.ts
|
|
4156
4142
|
var ALLOWED_INLINE_TAGS = /* @__PURE__ */ new Set(["A", "B", "STRONG", "I", "EM", "BR", "SPAN"]);
|
|
4157
4143
|
var ALLOWED_ATTRS_BY_TAG = {
|
|
@@ -4220,6 +4206,111 @@ var sanitizeInlineHtml = (value) => {
|
|
|
4220
4206
|
Array.from(template.content.childNodes).forEach((child) => sanitizeNode(child));
|
|
4221
4207
|
return template.innerHTML;
|
|
4222
4208
|
};
|
|
4209
|
+
function SPortal({
|
|
4210
|
+
open,
|
|
4211
|
+
onClose,
|
|
4212
|
+
onOpenChange,
|
|
4213
|
+
anchorRef,
|
|
4214
|
+
placement = "bottom",
|
|
4215
|
+
align = "start",
|
|
4216
|
+
offset = 4,
|
|
4217
|
+
alignOffset = 0,
|
|
4218
|
+
fit = false,
|
|
4219
|
+
maxHeight,
|
|
4220
|
+
autoClose = false,
|
|
4221
|
+
persistent = false,
|
|
4222
|
+
viewportPadding = 0,
|
|
4223
|
+
onOpenAutoFocus,
|
|
4224
|
+
onCloseAutoFocus,
|
|
4225
|
+
children,
|
|
4226
|
+
className,
|
|
4227
|
+
style,
|
|
4228
|
+
ariaLabel
|
|
4229
|
+
}) {
|
|
4230
|
+
const portalContainer = usePortalContainer();
|
|
4231
|
+
return /* @__PURE__ */ jsxs(
|
|
4232
|
+
RPopover2.Root,
|
|
4233
|
+
{
|
|
4234
|
+
open,
|
|
4235
|
+
onOpenChange: (next) => {
|
|
4236
|
+
onOpenChange?.(next);
|
|
4237
|
+
if (!next) onClose?.();
|
|
4238
|
+
},
|
|
4239
|
+
children: [
|
|
4240
|
+
/* @__PURE__ */ jsx(RPopover2.Anchor, { virtualRef: anchorRef }),
|
|
4241
|
+
/* @__PURE__ */ jsx(RPopover2.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
|
|
4242
|
+
RPopover2.Content,
|
|
4243
|
+
{
|
|
4244
|
+
side: placement,
|
|
4245
|
+
align,
|
|
4246
|
+
sideOffset: offset,
|
|
4247
|
+
alignOffset,
|
|
4248
|
+
collisionPadding: viewportPadding,
|
|
4249
|
+
"aria-label": ariaLabel,
|
|
4250
|
+
onPointerDownOutside: (e) => {
|
|
4251
|
+
if (persistent || anchorRef.current?.contains(e.target)) {
|
|
4252
|
+
e.preventDefault();
|
|
4253
|
+
}
|
|
4254
|
+
},
|
|
4255
|
+
onFocusOutside: (e) => {
|
|
4256
|
+
if (persistent || anchorRef.current?.contains(e.target)) {
|
|
4257
|
+
e.preventDefault();
|
|
4258
|
+
}
|
|
4259
|
+
},
|
|
4260
|
+
onEscapeKeyDown: persistent ? (e) => e.preventDefault() : void 0,
|
|
4261
|
+
onOpenAutoFocus,
|
|
4262
|
+
onCloseAutoFocus,
|
|
4263
|
+
onClick: autoClose ? () => onClose?.() : void 0,
|
|
4264
|
+
className: cn(
|
|
4265
|
+
"z-50 overflow-hidden rounded-(--cmp-listBox-radius) bg-(--cmp-listBox-bg) py-4 shadow-normal-sm",
|
|
4266
|
+
maxHeight != null && "overflow-y-auto",
|
|
4267
|
+
fit && "min-w-(--radix-popover-trigger-width)",
|
|
4268
|
+
FLOATING_SLIDE_ANIM,
|
|
4269
|
+
className
|
|
4270
|
+
),
|
|
4271
|
+
style: { maxHeight, ...style },
|
|
4272
|
+
children
|
|
4273
|
+
}
|
|
4274
|
+
) })
|
|
4275
|
+
]
|
|
4276
|
+
}
|
|
4277
|
+
);
|
|
4278
|
+
}
|
|
4279
|
+
SPortal.displayName = "SPortal";
|
|
4280
|
+
|
|
4281
|
+
// src/components/SSelect/select.config.ts
|
|
4282
|
+
function flattenOptions(options, depth = 1) {
|
|
4283
|
+
const out = [];
|
|
4284
|
+
for (const o of options) {
|
|
4285
|
+
const hasChildren = Array.isArray(o.children) && o.children.length > 0;
|
|
4286
|
+
if (hasChildren) {
|
|
4287
|
+
const childFlat = flattenOptions(o.children, depth + 1);
|
|
4288
|
+
const allChildrenDisabled = childFlat.every((c) => c.disabled);
|
|
4289
|
+
out.push({
|
|
4290
|
+
value: String(o.value),
|
|
4291
|
+
label: o.label,
|
|
4292
|
+
disabled: !!o.disabled || allChildrenDisabled,
|
|
4293
|
+
depth,
|
|
4294
|
+
isGroup: true,
|
|
4295
|
+
raw: o.value
|
|
4296
|
+
});
|
|
4297
|
+
out.push(...childFlat);
|
|
4298
|
+
} else {
|
|
4299
|
+
out.push({
|
|
4300
|
+
value: String(o.value),
|
|
4301
|
+
label: o.label,
|
|
4302
|
+
disabled: !!o.disabled,
|
|
4303
|
+
depth,
|
|
4304
|
+
isGroup: false,
|
|
4305
|
+
raw: o.value
|
|
4306
|
+
});
|
|
4307
|
+
}
|
|
4308
|
+
}
|
|
4309
|
+
return out;
|
|
4310
|
+
}
|
|
4311
|
+
var selectableOptions = (flat) => flat.filter((o) => !o.isGroup && !o.disabled);
|
|
4312
|
+
var isHtmlLabel = (label) => /<[a-z][\s\S]*>/i.test(label);
|
|
4313
|
+
var extractText = (html) => html.replace(/<[^>]*>/g, "");
|
|
4223
4314
|
var SEARCH_THRESHOLD = 11;
|
|
4224
4315
|
var SSelect = forwardRef(function SSelect2({
|
|
4225
4316
|
value,
|
|
@@ -4243,6 +4334,7 @@ var SSelect = forwardRef(function SSelect2({
|
|
|
4243
4334
|
label,
|
|
4244
4335
|
labelWidth,
|
|
4245
4336
|
icon,
|
|
4337
|
+
iconColor,
|
|
4246
4338
|
labelTooltip,
|
|
4247
4339
|
addonLabel,
|
|
4248
4340
|
addonAlign,
|
|
@@ -4254,18 +4346,15 @@ var SSelect = forwardRef(function SSelect2({
|
|
|
4254
4346
|
}, ref) {
|
|
4255
4347
|
const multi = type === "multi" || type === "multi_depth";
|
|
4256
4348
|
const portalContainer = usePortalContainer();
|
|
4349
|
+
const insideModal = useInsideModal();
|
|
4257
4350
|
const [search, setSearch] = useState("");
|
|
4258
4351
|
const [ruleError, setRuleError] = useState("");
|
|
4259
4352
|
const [open, setOpen] = useState(false);
|
|
4353
|
+
const [pendingOpen, setPendingOpen] = useState(false);
|
|
4354
|
+
const [focusedIndex, setFocusedIndex] = useState(-1);
|
|
4260
4355
|
const triggerRef = useRef(null);
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
() => ({
|
|
4264
|
-
focus: () => triggerRef.current?.focus(),
|
|
4265
|
-
open: () => setOpen(true)
|
|
4266
|
-
}),
|
|
4267
|
-
[]
|
|
4268
|
-
);
|
|
4356
|
+
const searchInputRef = useRef(null);
|
|
4357
|
+
const listRef = useRef(null);
|
|
4269
4358
|
const flat = useMemo(() => flattenOptions(options), [options]);
|
|
4270
4359
|
const selectable = useMemo(() => selectableOptions(flat), [flat]);
|
|
4271
4360
|
const hasLeaf = useMemo(() => flat.some((o) => !o.isGroup), [flat]);
|
|
@@ -4283,6 +4372,46 @@ var SSelect = forwardRef(function SSelect2({
|
|
|
4283
4372
|
const arr = Array.isArray(value) ? value : [value];
|
|
4284
4373
|
return arr.map((v) => v != null && typeof v === "object" ? v.value : v).filter((v) => v != null && v !== "").map(String);
|
|
4285
4374
|
}, [value]);
|
|
4375
|
+
const selectedRef = useRef(selected);
|
|
4376
|
+
selectedRef.current = selected;
|
|
4377
|
+
const emit = (next) => {
|
|
4378
|
+
if (!onValueChange) return;
|
|
4379
|
+
const mapped = next.map(
|
|
4380
|
+
(v) => emitValue ? rawByValue.get(v) ?? v : optionByValue.get(v) ?? { value: v, label: v }
|
|
4381
|
+
);
|
|
4382
|
+
onValueChange(multi ? mapped : mapped[0] ?? (emitValue ? "" : null));
|
|
4383
|
+
};
|
|
4384
|
+
const commitOpen = (next) => {
|
|
4385
|
+
setOpen(next);
|
|
4386
|
+
onOpenChange?.(next);
|
|
4387
|
+
if (!next) {
|
|
4388
|
+
setPendingOpen(false);
|
|
4389
|
+
setSearch("");
|
|
4390
|
+
if (rules && rules.length > 0) {
|
|
4391
|
+
setRuleError(runRules(multi ? selectedRef.current : selectedRef.current[0] ?? "", rules));
|
|
4392
|
+
}
|
|
4393
|
+
}
|
|
4394
|
+
};
|
|
4395
|
+
const requestOpen = (next) => {
|
|
4396
|
+
if (next && insideModal && portalContainer == null) {
|
|
4397
|
+
setPendingOpen(true);
|
|
4398
|
+
return;
|
|
4399
|
+
}
|
|
4400
|
+
commitOpen(next);
|
|
4401
|
+
};
|
|
4402
|
+
useEffect(() => {
|
|
4403
|
+
if (!insideModal || portalContainer == null || !pendingOpen) return;
|
|
4404
|
+
setPendingOpen(false);
|
|
4405
|
+
commitOpen(true);
|
|
4406
|
+
}, [insideModal, pendingOpen, portalContainer]);
|
|
4407
|
+
useImperativeHandle(
|
|
4408
|
+
ref,
|
|
4409
|
+
() => ({
|
|
4410
|
+
focus: () => triggerRef.current?.focus(),
|
|
4411
|
+
open: () => requestOpen(true)
|
|
4412
|
+
}),
|
|
4413
|
+
[insideModal, portalContainer]
|
|
4414
|
+
);
|
|
4286
4415
|
useFormField({
|
|
4287
4416
|
name,
|
|
4288
4417
|
validate: () => {
|
|
@@ -4292,13 +4421,6 @@ var SSelect = forwardRef(function SSelect2({
|
|
|
4292
4421
|
},
|
|
4293
4422
|
resetValidation: () => setRuleError("")
|
|
4294
4423
|
});
|
|
4295
|
-
const emit = (next) => {
|
|
4296
|
-
if (!onValueChange) return;
|
|
4297
|
-
const mapped = next.map(
|
|
4298
|
-
(v) => emitValue ? rawByValue.get(v) ?? v : optionByValue.get(v) ?? { value: v, label: v }
|
|
4299
|
-
);
|
|
4300
|
-
onValueChange(multi ? mapped : mapped[0] ?? (emitValue ? "" : null));
|
|
4301
|
-
};
|
|
4302
4424
|
const filtered = useMemo(() => {
|
|
4303
4425
|
if (!showSearch || search.trim() === "") return flat;
|
|
4304
4426
|
const q = search.trim().toLowerCase();
|
|
@@ -4309,6 +4431,16 @@ var SSelect = forwardRef(function SSelect2({
|
|
|
4309
4431
|
const allValues = selectable.map((o) => o.value);
|
|
4310
4432
|
const allSelected = allValues.length > 0 && allValues.every((v) => selected.includes(v));
|
|
4311
4433
|
const hasItems = filtered.some((o) => !o.isGroup);
|
|
4434
|
+
const navigableItems = useMemo(() => {
|
|
4435
|
+
const items = [];
|
|
4436
|
+
if (multi && useSelectAll && allValues.length > 0) {
|
|
4437
|
+
items.push({ value: "__select_all__", isSelectAll: true });
|
|
4438
|
+
}
|
|
4439
|
+
filtered.forEach((o) => {
|
|
4440
|
+
if (!o.isGroup && !o.disabled) items.push({ value: o.value });
|
|
4441
|
+
});
|
|
4442
|
+
return items;
|
|
4443
|
+
}, [allValues.length, filtered, multi, useSelectAll]);
|
|
4312
4444
|
const triggerText = (() => {
|
|
4313
4445
|
if (selected.length === 0) return placeholder;
|
|
4314
4446
|
if (multi) {
|
|
@@ -4318,26 +4450,119 @@ var SSelect = forwardRef(function SSelect2({
|
|
|
4318
4450
|
return labelByValue.get(selected[0]) ?? selected[0];
|
|
4319
4451
|
})();
|
|
4320
4452
|
const isPlaceholder = selected.length === 0;
|
|
4321
|
-
const
|
|
4322
|
-
|
|
4453
|
+
const handleSelect = (nextValue) => {
|
|
4454
|
+
if (multi) {
|
|
4455
|
+
const next = selected.includes(nextValue) ? selected.filter((v) => v !== nextValue) : [...selected, nextValue];
|
|
4456
|
+
emit(next);
|
|
4457
|
+
return;
|
|
4458
|
+
}
|
|
4459
|
+
emit([nextValue]);
|
|
4460
|
+
commitOpen(false);
|
|
4461
|
+
};
|
|
4462
|
+
const handleSelectAll = () => {
|
|
4463
|
+
emit(allSelected ? [] : allValues);
|
|
4464
|
+
};
|
|
4465
|
+
useEffect(() => {
|
|
4466
|
+
if (!open) {
|
|
4467
|
+
setFocusedIndex(-1);
|
|
4468
|
+
return;
|
|
4469
|
+
}
|
|
4470
|
+
setFocusedIndex(navigableItems.length > 0 ? 0 : -1);
|
|
4471
|
+
}, [open, navigableItems.length]);
|
|
4472
|
+
useEffect(() => {
|
|
4473
|
+
if (!open) return;
|
|
4474
|
+
setFocusedIndex(navigableItems.length > 0 ? 0 : -1);
|
|
4475
|
+
}, [search, open, navigableItems.length]);
|
|
4476
|
+
useEffect(() => {
|
|
4477
|
+
if (!open || focusedIndex < 0) return;
|
|
4478
|
+
const list = listRef.current;
|
|
4479
|
+
const focusedEl = list?.querySelector('[data-select-focused="true"]');
|
|
4480
|
+
if (!list || !focusedEl) return;
|
|
4481
|
+
const listRect = list.getBoundingClientRect();
|
|
4482
|
+
const itemRect = focusedEl.getBoundingClientRect();
|
|
4483
|
+
if (itemRect.top < listRect.top) {
|
|
4484
|
+
list.scrollTop += itemRect.top - listRect.top;
|
|
4485
|
+
} else if (itemRect.bottom > listRect.bottom) {
|
|
4486
|
+
list.scrollTop += itemRect.bottom - listRect.bottom;
|
|
4487
|
+
}
|
|
4488
|
+
}, [focusedIndex, open]);
|
|
4489
|
+
const moveFocusedIndex = (direction) => {
|
|
4490
|
+
if (!open || navigableItems.length === 0) return;
|
|
4491
|
+
setFocusedIndex((current) => {
|
|
4492
|
+
if (direction === "next") {
|
|
4493
|
+
return current < 0 ? 0 : (current + 1) % navigableItems.length;
|
|
4494
|
+
}
|
|
4495
|
+
return current <= 0 ? navigableItems.length - 1 : current - 1;
|
|
4496
|
+
});
|
|
4497
|
+
};
|
|
4498
|
+
const selectFocusedItem = () => {
|
|
4499
|
+
if (focusedIndex < 0 || focusedIndex >= navigableItems.length) return;
|
|
4500
|
+
const focused = navigableItems[focusedIndex];
|
|
4501
|
+
if (focused.isSelectAll) {
|
|
4502
|
+
handleSelectAll();
|
|
4503
|
+
return;
|
|
4504
|
+
}
|
|
4505
|
+
handleSelect(focused.value);
|
|
4506
|
+
};
|
|
4507
|
+
const handleKeyDown = (event) => {
|
|
4508
|
+
if (!open) {
|
|
4509
|
+
if ((event.key === "ArrowDown" || event.key === "ArrowUp") && !effectiveDisabled) {
|
|
4510
|
+
event.preventDefault();
|
|
4511
|
+
requestOpen(true);
|
|
4512
|
+
}
|
|
4513
|
+
return;
|
|
4514
|
+
}
|
|
4515
|
+
if (event.key === "ArrowDown") {
|
|
4516
|
+
event.preventDefault();
|
|
4517
|
+
moveFocusedIndex("next");
|
|
4518
|
+
return;
|
|
4519
|
+
}
|
|
4520
|
+
if (event.key === "ArrowUp") {
|
|
4521
|
+
event.preventDefault();
|
|
4522
|
+
moveFocusedIndex("prev");
|
|
4523
|
+
return;
|
|
4524
|
+
}
|
|
4525
|
+
if (event.key === "Enter") {
|
|
4526
|
+
event.preventDefault();
|
|
4527
|
+
selectFocusedItem();
|
|
4528
|
+
return;
|
|
4529
|
+
}
|
|
4530
|
+
if (event.key === "Escape") {
|
|
4531
|
+
event.preventDefault();
|
|
4532
|
+
commitOpen(false);
|
|
4533
|
+
}
|
|
4534
|
+
};
|
|
4535
|
+
return /* @__PURE__ */ jsxs(
|
|
4536
|
+
SField,
|
|
4323
4537
|
{
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4538
|
+
label,
|
|
4539
|
+
labelWidth,
|
|
4540
|
+
icon,
|
|
4541
|
+
iconColor,
|
|
4542
|
+
labelTooltip,
|
|
4543
|
+
labelTooltipProps,
|
|
4544
|
+
addonLabel,
|
|
4545
|
+
addonAlign,
|
|
4546
|
+
hint,
|
|
4547
|
+
error: error || ruleError !== "",
|
|
4548
|
+
status: rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0,
|
|
4549
|
+
errorMessage: ruleError !== "" ? ruleError : errorMessage,
|
|
4550
|
+
disabled: effectiveDisabled,
|
|
4551
|
+
width,
|
|
4552
|
+
className,
|
|
4553
|
+
style,
|
|
4335
4554
|
children: [
|
|
4555
|
+
name && /* @__PURE__ */ jsx("input", { type: "hidden", name, value: selected.join(",") }),
|
|
4336
4556
|
/* @__PURE__ */ jsxs(
|
|
4337
|
-
|
|
4557
|
+
"button",
|
|
4338
4558
|
{
|
|
4339
4559
|
ref: triggerRef,
|
|
4560
|
+
type: "button",
|
|
4340
4561
|
disabled: effectiveDisabled,
|
|
4562
|
+
"aria-haspopup": "listbox",
|
|
4563
|
+
"aria-expanded": open,
|
|
4564
|
+
onClick: () => requestOpen(!open),
|
|
4565
|
+
onKeyDown: handleKeyDown,
|
|
4341
4566
|
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",
|
|
4342
4567
|
style: {
|
|
4343
4568
|
color: effectiveDisabled ? "var(--cmp-select-text-disabled)" : isPlaceholder ? "var(--cmp-select-icon-default)" : "var(--cmp-select-text-default)"
|
|
@@ -4362,178 +4587,229 @@ var SSelect = forwardRef(function SSelect2({
|
|
|
4362
4587
|
]
|
|
4363
4588
|
}
|
|
4364
4589
|
),
|
|
4365
|
-
/* @__PURE__ */
|
|
4366
|
-
|
|
4590
|
+
/* @__PURE__ */ jsx(
|
|
4591
|
+
SPortal,
|
|
4367
4592
|
{
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
4593
|
+
open,
|
|
4594
|
+
onClose: () => commitOpen(false),
|
|
4595
|
+
onOpenChange: (next) => {
|
|
4596
|
+
if (next) requestOpen(true);
|
|
4597
|
+
},
|
|
4598
|
+
anchorRef: triggerRef,
|
|
4599
|
+
placement: "bottom",
|
|
4600
|
+
align: "start",
|
|
4601
|
+
offset: 4,
|
|
4602
|
+
fit: !dropdownWidth,
|
|
4603
|
+
onOpenAutoFocus: (event) => {
|
|
4604
|
+
if (!showSearch) {
|
|
4605
|
+
event.preventDefault();
|
|
4606
|
+
return;
|
|
4607
|
+
}
|
|
4608
|
+
event.preventDefault();
|
|
4609
|
+
requestAnimationFrame(() => searchInputRef.current?.focus());
|
|
4610
|
+
},
|
|
4611
|
+
onCloseAutoFocus: (event) => {
|
|
4612
|
+
event.preventDefault();
|
|
4613
|
+
triggerRef.current?.focus();
|
|
4614
|
+
},
|
|
4615
|
+
className: "rounded-[var(--cmp-listBox-radius)] bg-[var(--cmp-listBox-bg)] py-[4px] shadow-[2px_2px_12px_2px_rgba(0,0,0,0.1)]",
|
|
4373
4616
|
style: {
|
|
4374
|
-
maxHeight: dropdownHeight,
|
|
4375
4617
|
...dropdownWidth ? { width: dropdownWidth } : {},
|
|
4376
4618
|
maxWidth: maxDropdownWidth
|
|
4377
4619
|
},
|
|
4378
|
-
children:
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4620
|
+
children: /* @__PURE__ */ jsxs(
|
|
4621
|
+
"div",
|
|
4622
|
+
{
|
|
4623
|
+
ref: listRef,
|
|
4624
|
+
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)]",
|
|
4625
|
+
style: { maxHeight: dropdownHeight },
|
|
4626
|
+
onMouseLeave: () => setFocusedIndex(-1),
|
|
4627
|
+
children: [
|
|
4628
|
+
showSearch && /* @__PURE__ */ jsx("div", { className: "sticky top-0 z-[1] bg-[var(--cmp-listBox-bg)] px-[8px] py-[4px]", children: /* @__PURE__ */ 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: [
|
|
4629
|
+
/* @__PURE__ */ jsx(SIcon, { name: "search", size: 16, color: "var(--color-grey-70)", className: "shrink-0" }),
|
|
4630
|
+
/* @__PURE__ */ jsx(
|
|
4631
|
+
"input",
|
|
4632
|
+
{
|
|
4633
|
+
ref: searchInputRef,
|
|
4634
|
+
value: search,
|
|
4635
|
+
onChange: (e) => setSearch(e.target.value),
|
|
4636
|
+
onKeyDown: handleKeyDown,
|
|
4637
|
+
placeholder: "\uAC80\uC0C9",
|
|
4638
|
+
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)]"
|
|
4639
|
+
}
|
|
4640
|
+
),
|
|
4641
|
+
search !== "" && /* @__PURE__ */ jsx(
|
|
4642
|
+
SGhostButton,
|
|
4643
|
+
{
|
|
4644
|
+
icon: "close",
|
|
4645
|
+
size: "xxs",
|
|
4646
|
+
intent: "default",
|
|
4647
|
+
ariaLabel: "\uAC80\uC0C9\uC5B4 \uC9C0\uC6B0\uAE30",
|
|
4648
|
+
onClick: () => setSearch(""),
|
|
4649
|
+
className: "shrink-0"
|
|
4650
|
+
}
|
|
4651
|
+
)
|
|
4652
|
+
] }) }),
|
|
4653
|
+
hasItems ? /* @__PURE__ */ jsx(
|
|
4654
|
+
ItemList,
|
|
4655
|
+
{
|
|
4656
|
+
items: filtered,
|
|
4657
|
+
multi,
|
|
4658
|
+
selected,
|
|
4659
|
+
focusedValue: navigableItems[focusedIndex]?.isSelectAll ? "__select_all__" : navigableItems[focusedIndex]?.value,
|
|
4660
|
+
showSelectAll: multi && useSelectAll && allValues.length > 0,
|
|
4661
|
+
selectAllLabel: allSelectedLabel,
|
|
4662
|
+
selectAllSelected: allSelected,
|
|
4663
|
+
onSelectAll: handleSelectAll,
|
|
4664
|
+
onSelect: handleSelect,
|
|
4665
|
+
onHoverValue: (value2) => {
|
|
4666
|
+
const index = navigableItems.findIndex(
|
|
4667
|
+
(item) => item.isSelectAll ? value2 === "__select_all__" : item.value === value2
|
|
4668
|
+
);
|
|
4669
|
+
if (index >= 0) setFocusedIndex(index);
|
|
4670
|
+
}
|
|
4671
|
+
}
|
|
4672
|
+
) : /* @__PURE__ */ jsx("div", { className: "px-[12px] py-[12px] text-left text-[12px] leading-[20px] text-[color:var(--cmp-listItem-content-disabled)]", children: "\uD45C\uC2DC\uD560 \uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4." })
|
|
4673
|
+
]
|
|
4674
|
+
}
|
|
4675
|
+
)
|
|
4416
4676
|
}
|
|
4417
4677
|
)
|
|
4418
4678
|
]
|
|
4419
4679
|
}
|
|
4420
4680
|
);
|
|
4421
|
-
const control = showSearch ? /* @__PURE__ */ jsx(Ariakit.ComboboxProvider, { value: search, setValue: setSearch, resetValueOnHide: true, children: selectStore }) : selectStore;
|
|
4422
|
-
return /* @__PURE__ */ jsxs(
|
|
4423
|
-
SField,
|
|
4424
|
-
{
|
|
4425
|
-
label,
|
|
4426
|
-
labelWidth,
|
|
4427
|
-
icon,
|
|
4428
|
-
labelTooltip,
|
|
4429
|
-
labelTooltipProps,
|
|
4430
|
-
addonLabel,
|
|
4431
|
-
addonAlign,
|
|
4432
|
-
hint,
|
|
4433
|
-
error: error || ruleError !== "",
|
|
4434
|
-
status: rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0,
|
|
4435
|
-
errorMessage: ruleError !== "" ? ruleError : errorMessage,
|
|
4436
|
-
disabled: effectiveDisabled,
|
|
4437
|
-
width,
|
|
4438
|
-
className,
|
|
4439
|
-
style,
|
|
4440
|
-
children: [
|
|
4441
|
-
name && /* @__PURE__ */ jsx("input", { type: "hidden", name, value: selected.join(",") }),
|
|
4442
|
-
control
|
|
4443
|
-
]
|
|
4444
|
-
}
|
|
4445
|
-
);
|
|
4446
4681
|
});
|
|
4447
4682
|
SSelect.displayName = "SSelect";
|
|
4448
4683
|
function ItemList({
|
|
4449
4684
|
items,
|
|
4450
4685
|
multi,
|
|
4451
4686
|
selected,
|
|
4452
|
-
|
|
4687
|
+
focusedValue,
|
|
4688
|
+
showSelectAll,
|
|
4689
|
+
selectAllLabel,
|
|
4690
|
+
selectAllSelected,
|
|
4691
|
+
onSelectAll,
|
|
4692
|
+
onSelect,
|
|
4693
|
+
onHoverValue
|
|
4453
4694
|
}) {
|
|
4454
4695
|
const itemBase = cn(
|
|
4455
|
-
|
|
4456
|
-
"group flex cursor-pointer select-none items-center gap-[8px] text-[12px] leading-[20px] outline-none",
|
|
4696
|
+
"group flex w-full cursor-pointer select-none items-center gap-[8px] border-none bg-transparent text-left text-[12px] leading-[20px] outline-none",
|
|
4457
4697
|
"text-[color:var(--cmp-listItem-content-default)]",
|
|
4458
|
-
|
|
4459
|
-
"aria-disabled:cursor-not-allowed aria-disabled:text-[color:var(--cmp-listItem-content-disabled)]"
|
|
4698
|
+
"disabled:cursor-not-allowed disabled:text-[color:var(--cmp-listItem-content-disabled)]"
|
|
4460
4699
|
);
|
|
4461
|
-
const activeClass = "
|
|
4462
|
-
return /* @__PURE__ */
|
|
4463
|
-
|
|
4464
|
-
|
|
4465
|
-
const isDepth1 = o.depth === 1;
|
|
4466
|
-
return /* @__PURE__ */ jsx(
|
|
4467
|
-
"div",
|
|
4468
|
-
{
|
|
4469
|
-
className: cn(
|
|
4470
|
-
"select-none py-[4px] pr-[12px] text-[12px] leading-[20px] text-[color:var(--cmp-listItem-content-default)]",
|
|
4471
|
-
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",
|
|
4472
|
-
// 하위가 전부 비활성이면(select.config 에서 bubble-up) 어미 그룹도 비활성 처리:
|
|
4473
|
-
// 텍스트는 회색(#888), depth1 그룹은 파란 배경 대신 회색(#EEE)으로 (depth2 는 #F6F6F6 유지)
|
|
4474
|
-
o.disabled && "cursor-not-allowed text-[color:var(--cmp-listItem-content-disabled)]",
|
|
4475
|
-
o.disabled && isDepth1 && "bg-[var(--cmp-listItem-depth1-bg-disabled)]"
|
|
4476
|
-
),
|
|
4477
|
-
style: { paddingLeft: padLeft },
|
|
4478
|
-
children: o.label
|
|
4479
|
-
},
|
|
4480
|
-
o.value
|
|
4481
|
-
);
|
|
4482
|
-
}
|
|
4483
|
-
const isSelected = selected.includes(o.value);
|
|
4484
|
-
return /* @__PURE__ */ jsxs(
|
|
4485
|
-
Ariakit.SelectItem,
|
|
4700
|
+
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)]";
|
|
4701
|
+
return /* @__PURE__ */ jsxs("div", { role: "listbox", "aria-multiselectable": multi || void 0, children: [
|
|
4702
|
+
showSelectAll && /* @__PURE__ */ jsxs(
|
|
4703
|
+
"button",
|
|
4486
4704
|
{
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4705
|
+
type: "button",
|
|
4706
|
+
"data-select-focused": focusedValue === "__select_all__" ? "true" : void 0,
|
|
4707
|
+
"data-select-active": focusedValue === "__select_all__" ? "true" : void 0,
|
|
4490
4708
|
className: cn(
|
|
4491
4709
|
itemBase,
|
|
4492
|
-
|
|
4493
|
-
// Ariakit은 disabled 항목도 hover 시 active(data-active-item) 처리하므로,
|
|
4494
|
-
// 비활성 항목에는 hover 하이라이트를 적용하지 않아 회색 비활성 스타일을 유지한다.
|
|
4495
|
-
// (원본 Stencil의 `--focused...:not(--disabled)` 규칙과 동일한 의도)
|
|
4496
|
-
!o.disabled && activeClass
|
|
4710
|
+
focusedValue === "__select_all__" && "bg-[var(--cmp-listItem-bg-hover)] text-[color:var(--cmp-listItem-content-hover)]"
|
|
4497
4711
|
),
|
|
4498
|
-
style: { paddingTop: 4, paddingBottom: 4, paddingRight: 12, paddingLeft:
|
|
4499
|
-
|
|
4712
|
+
style: { paddingTop: 4, paddingBottom: 4, paddingRight: 12, paddingLeft: 12 },
|
|
4713
|
+
onMouseEnter: () => onHoverValue("__select_all__"),
|
|
4714
|
+
onClick: onSelectAll,
|
|
4500
4715
|
children: [
|
|
4501
|
-
multi && // hover(active) 시 checkbox inverse — 파란 hover 배경 위에서 checked/unchecked 모두 흰 테두리 + 투명 배경
|
|
4502
4716
|
/* @__PURE__ */ jsx(
|
|
4503
4717
|
"span",
|
|
4504
4718
|
{
|
|
4505
4719
|
className: cn(
|
|
4506
4720
|
"flex h-[16px] w-[16px] flex-shrink-0 items-center justify-center rounded-[2px] border border-solid",
|
|
4507
|
-
|
|
4508
|
-
// 비활성: 회색 채움(#E1E1E1) + 회색 테두리(#CCCCCC)
|
|
4509
|
-
"cursor-not-allowed border-[color:var(--cmp-checkbox-border-disabled)] bg-[var(--cmp-checkbox-bg-disabled)]"
|
|
4510
|
-
) : cn(
|
|
4511
|
-
"group-data-[active-item]:border-[color:var(--cmp-checkbox-checked-border-inverse)]",
|
|
4512
|
-
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"
|
|
4513
|
-
)
|
|
4721
|
+
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)]"
|
|
4514
4722
|
),
|
|
4515
|
-
children:
|
|
4723
|
+
children: selectAllSelected && /* @__PURE__ */ jsx(
|
|
4516
4724
|
SIcon,
|
|
4517
4725
|
{
|
|
4518
4726
|
name: "checkboxCheck",
|
|
4519
4727
|
size: 12,
|
|
4520
|
-
color:
|
|
4728
|
+
color: "var(--cmp-checkbox-checked-icon-default)"
|
|
4521
4729
|
}
|
|
4522
4730
|
)
|
|
4523
4731
|
}
|
|
4524
4732
|
),
|
|
4525
|
-
|
|
4526
|
-
"span",
|
|
4527
|
-
{
|
|
4528
|
-
className: "flex-1 truncate",
|
|
4529
|
-
dangerouslySetInnerHTML: { __html: sanitizeInlineHtml(o.label) }
|
|
4530
|
-
}
|
|
4531
|
-
) : /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: o.label })
|
|
4733
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: selectAllLabel })
|
|
4532
4734
|
]
|
|
4533
|
-
}
|
|
4534
|
-
|
|
4535
|
-
)
|
|
4536
|
-
|
|
4735
|
+
}
|
|
4736
|
+
),
|
|
4737
|
+
items.map((o) => {
|
|
4738
|
+
const padLeft = o.depth === 1 ? 12 : o.depth === 2 ? 20 : 28;
|
|
4739
|
+
if (o.isGroup) {
|
|
4740
|
+
const isDepth1 = o.depth === 1;
|
|
4741
|
+
return /* @__PURE__ */ jsx(
|
|
4742
|
+
"div",
|
|
4743
|
+
{
|
|
4744
|
+
className: cn(
|
|
4745
|
+
"select-none py-[4px] pr-[12px] text-[12px] leading-[20px] text-[color:var(--cmp-listItem-content-default)]",
|
|
4746
|
+
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",
|
|
4747
|
+
// 하위가 전부 비활성이면(select.config 에서 bubble-up) 어미 그룹도 비활성 처리:
|
|
4748
|
+
// 텍스트는 회색(#888), depth1 그룹은 파란 배경 대신 회색(#EEE)으로 (depth2 는 #F6F6F6 유지)
|
|
4749
|
+
o.disabled && "cursor-not-allowed text-[color:var(--cmp-listItem-content-disabled)]",
|
|
4750
|
+
o.disabled && isDepth1 && "bg-[var(--cmp-listItem-depth1-bg-disabled)]"
|
|
4751
|
+
),
|
|
4752
|
+
style: { paddingLeft: padLeft },
|
|
4753
|
+
children: o.label
|
|
4754
|
+
},
|
|
4755
|
+
o.value
|
|
4756
|
+
);
|
|
4757
|
+
}
|
|
4758
|
+
const isSelected = selected.includes(o.value);
|
|
4759
|
+
return /* @__PURE__ */ jsxs(
|
|
4760
|
+
"button",
|
|
4761
|
+
{
|
|
4762
|
+
type: "button",
|
|
4763
|
+
disabled: o.disabled,
|
|
4764
|
+
role: "option",
|
|
4765
|
+
"aria-selected": isSelected,
|
|
4766
|
+
"data-select-focused": focusedValue === o.value ? "true" : void 0,
|
|
4767
|
+
"data-select-active": focusedValue === o.value ? "true" : void 0,
|
|
4768
|
+
className: cn(
|
|
4769
|
+
itemBase,
|
|
4770
|
+
isSelected && !multi && "font-bold text-[color:var(--cmp-listItem-content-selected)]",
|
|
4771
|
+
focusedValue === o.value && "bg-[var(--cmp-listItem-bg-hover)] text-[color:var(--cmp-listItem-content-hover)]",
|
|
4772
|
+
activeClass
|
|
4773
|
+
),
|
|
4774
|
+
style: { paddingTop: 4, paddingBottom: 4, paddingRight: 12, paddingLeft: padLeft },
|
|
4775
|
+
onMouseEnter: () => onHoverValue(o.value),
|
|
4776
|
+
onClick: () => onSelect(o.value),
|
|
4777
|
+
children: [
|
|
4778
|
+
multi && /* @__PURE__ */ jsx(
|
|
4779
|
+
"span",
|
|
4780
|
+
{
|
|
4781
|
+
className: cn(
|
|
4782
|
+
"flex h-[16px] w-[16px] flex-shrink-0 items-center justify-center rounded-[2px] border border-solid",
|
|
4783
|
+
o.disabled ? (
|
|
4784
|
+
// 비활성: 회색 채움(#E1E1E1) + 회색 테두리(#CCCCCC)
|
|
4785
|
+
"cursor-not-allowed border-[color:var(--cmp-checkbox-border-disabled)] bg-[var(--cmp-checkbox-bg-disabled)]"
|
|
4786
|
+
) : cn(
|
|
4787
|
+
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)]"
|
|
4788
|
+
)
|
|
4789
|
+
),
|
|
4790
|
+
children: isSelected && /* @__PURE__ */ jsx(
|
|
4791
|
+
SIcon,
|
|
4792
|
+
{
|
|
4793
|
+
name: "checkboxCheck",
|
|
4794
|
+
size: 12,
|
|
4795
|
+
color: o.disabled ? "var(--cmp-checkbox-checked-icon-disabled)" : "var(--cmp-checkbox-checked-icon-default)"
|
|
4796
|
+
}
|
|
4797
|
+
)
|
|
4798
|
+
}
|
|
4799
|
+
),
|
|
4800
|
+
isHtmlLabel(o.label) ? /* @__PURE__ */ jsx(
|
|
4801
|
+
"span",
|
|
4802
|
+
{
|
|
4803
|
+
className: "flex-1 truncate",
|
|
4804
|
+
dangerouslySetInnerHTML: { __html: sanitizeInlineHtml(o.label) }
|
|
4805
|
+
}
|
|
4806
|
+
) : /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: o.label })
|
|
4807
|
+
]
|
|
4808
|
+
},
|
|
4809
|
+
o.value
|
|
4810
|
+
);
|
|
4811
|
+
})
|
|
4812
|
+
] });
|
|
4537
4813
|
}
|
|
4538
4814
|
function SRadio({
|
|
4539
4815
|
val,
|
|
@@ -4996,6 +5272,7 @@ function SDatePicker({
|
|
|
4996
5272
|
label,
|
|
4997
5273
|
labelWidth,
|
|
4998
5274
|
icon,
|
|
5275
|
+
iconColor,
|
|
4999
5276
|
labelTooltip,
|
|
5000
5277
|
labelTooltipProps,
|
|
5001
5278
|
addonLabel,
|
|
@@ -5034,6 +5311,7 @@ function SDatePicker({
|
|
|
5034
5311
|
label,
|
|
5035
5312
|
labelWidth,
|
|
5036
5313
|
icon,
|
|
5314
|
+
iconColor,
|
|
5037
5315
|
labelTooltip,
|
|
5038
5316
|
labelTooltipProps,
|
|
5039
5317
|
addonLabel,
|
|
@@ -5302,6 +5580,7 @@ function SDateRangePicker({
|
|
|
5302
5580
|
label,
|
|
5303
5581
|
labelWidth,
|
|
5304
5582
|
icon,
|
|
5583
|
+
iconColor,
|
|
5305
5584
|
labelTooltip,
|
|
5306
5585
|
labelTooltipProps,
|
|
5307
5586
|
addonLabel,
|
|
@@ -5344,6 +5623,7 @@ function SDateRangePicker({
|
|
|
5344
5623
|
label,
|
|
5345
5624
|
labelWidth,
|
|
5346
5625
|
icon,
|
|
5626
|
+
iconColor,
|
|
5347
5627
|
labelTooltip,
|
|
5348
5628
|
labelTooltipProps,
|
|
5349
5629
|
addonLabel,
|
|
@@ -5605,6 +5885,7 @@ function SFilePicker({
|
|
|
5605
5885
|
label,
|
|
5606
5886
|
labelWidth,
|
|
5607
5887
|
icon,
|
|
5888
|
+
iconColor,
|
|
5608
5889
|
labelTooltip,
|
|
5609
5890
|
labelTooltipProps,
|
|
5610
5891
|
addonLabel,
|
|
@@ -5774,7 +6055,7 @@ function SFilePicker({
|
|
|
5774
6055
|
unmountOnHide: true,
|
|
5775
6056
|
getAnchorRect: () => contentBoxRef.current?.getBoundingClientRect() ?? null,
|
|
5776
6057
|
style: { minWidth: contentBoxRef.current?.offsetWidth },
|
|
5777
|
-
className: "z-50 box-border flex flex-col items-
|
|
6058
|
+
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)]",
|
|
5778
6059
|
children: filesArr.map((f, i) => /* @__PURE__ */ jsx(SChip, { value: f.name, editable: false, onRemove: () => removeChip(i) }, i))
|
|
5779
6060
|
}
|
|
5780
6061
|
)
|
|
@@ -5788,6 +6069,7 @@ function SFilePicker({
|
|
|
5788
6069
|
label,
|
|
5789
6070
|
labelWidth,
|
|
5790
6071
|
icon,
|
|
6072
|
+
iconColor,
|
|
5791
6073
|
labelTooltip,
|
|
5792
6074
|
labelTooltipProps,
|
|
5793
6075
|
addonLabel,
|
|
@@ -5810,21 +6092,26 @@ function SFilePicker({
|
|
|
5810
6092
|
var cssLen2 = (v) => v == null ? void 0 : typeof v === "number" ? `${v}px` : v;
|
|
5811
6093
|
function SKeyValueTable({
|
|
5812
6094
|
fields = [],
|
|
6095
|
+
values = {},
|
|
5813
6096
|
search = false,
|
|
5814
6097
|
radius = "default",
|
|
5815
|
-
dense = false,
|
|
5816
6098
|
onChange,
|
|
5817
6099
|
onSearch,
|
|
5818
6100
|
className,
|
|
5819
6101
|
style
|
|
5820
6102
|
}) {
|
|
5821
6103
|
if (fields.length === 0) return null;
|
|
5822
|
-
const emit = (name, value) => onChange?.({
|
|
5823
|
-
|
|
5824
|
-
|
|
6104
|
+
const emit = (name, value) => onChange?.({
|
|
6105
|
+
name,
|
|
6106
|
+
value,
|
|
6107
|
+
values: { ...values, [name]: value }
|
|
6108
|
+
});
|
|
6109
|
+
const cellHeight = "var(--cmp-table-keyValue-height)";
|
|
6110
|
+
const cellPadY = "var(--cmp-table-keyValue-body-paddingY)";
|
|
5825
6111
|
const renderField = (f) => {
|
|
5826
6112
|
if (f.render) return f.render;
|
|
5827
|
-
const opt = f.options ?? {};
|
|
6113
|
+
const opt = { ...f.options ?? {} };
|
|
6114
|
+
if (Object.prototype.hasOwnProperty.call(values, f.name)) opt.value = values[f.name];
|
|
5828
6115
|
const up = (v) => emit(f.name, v);
|
|
5829
6116
|
switch (f.type) {
|
|
5830
6117
|
case "input":
|
|
@@ -5936,7 +6223,10 @@ function SKeyValueTable({
|
|
|
5936
6223
|
rowSpan: f.tdRowSpan && f.tdRowSpan > 1 ? f.tdRowSpan : void 0,
|
|
5937
6224
|
colSpan: f.tdColSpan && f.tdColSpan > 1 ? f.tdColSpan : void 0,
|
|
5938
6225
|
className: cn(
|
|
5939
|
-
"box-border bg-[var(--sys-color-bg-frame)]
|
|
6226
|
+
"box-border bg-[var(--sys-color-bg-frame)] align-middle",
|
|
6227
|
+
// text 타입(및 미지정 기본값)은 읽기 전용 콘텐츠라 넓은 paddingX(wide),
|
|
6228
|
+
// 폼 필드 셀은 default paddingX 유지
|
|
6229
|
+
f.type == null || f.type === "text" ? "px-[var(--cmp-table-keyValue-body-paddingX-wide)]" : "px-[var(--cmp-table-keyValue-body-paddingX-default)]",
|
|
5940
6230
|
cellBorder,
|
|
5941
6231
|
f.tdClass
|
|
5942
6232
|
),
|