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
|
@@ -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 = {
|
|
@@ -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,178 +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 && "cursor-not-allowed 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
|
-
|
|
4513
|
-
|
|
4729
|
+
type: "button",
|
|
4730
|
+
"data-select-focused": focusedValue === "__select_all__" ? "true" : void 0,
|
|
4731
|
+
"data-select-active": focusedValue === "__select_all__" ? "true" : void 0,
|
|
4514
4732
|
className: cn(
|
|
4515
4733
|
itemBase,
|
|
4516
|
-
|
|
4517
|
-
// Ariakit은 disabled 항목도 hover 시 active(data-active-item) 처리하므로,
|
|
4518
|
-
// 비활성 항목에는 hover 하이라이트를 적용하지 않아 회색 비활성 스타일을 유지한다.
|
|
4519
|
-
// (원본 Stencil의 `--focused...:not(--disabled)` 규칙과 동일한 의도)
|
|
4520
|
-
!o.disabled && activeClass
|
|
4734
|
+
focusedValue === "__select_all__" && "bg-[var(--cmp-listItem-bg-hover)] text-[color:var(--cmp-listItem-content-hover)]"
|
|
4521
4735
|
),
|
|
4522
|
-
style: { paddingTop: 4, paddingBottom: 4, paddingRight: 12, paddingLeft:
|
|
4523
|
-
|
|
4736
|
+
style: { paddingTop: 4, paddingBottom: 4, paddingRight: 12, paddingLeft: 12 },
|
|
4737
|
+
onMouseEnter: () => onHoverValue("__select_all__"),
|
|
4738
|
+
onClick: onSelectAll,
|
|
4524
4739
|
children: [
|
|
4525
|
-
multi && // hover(active) 시 checkbox inverse — 파란 hover 배경 위에서 checked/unchecked 모두 흰 테두리 + 투명 배경
|
|
4526
4740
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4527
4741
|
"span",
|
|
4528
4742
|
{
|
|
4529
4743
|
className: cn(
|
|
4530
4744
|
"flex h-[16px] w-[16px] flex-shrink-0 items-center justify-center rounded-[2px] border border-solid",
|
|
4531
|
-
|
|
4532
|
-
// 비활성: 회색 채움(#E1E1E1) + 회색 테두리(#CCCCCC)
|
|
4533
|
-
"cursor-not-allowed border-[color:var(--cmp-checkbox-border-disabled)] bg-[var(--cmp-checkbox-bg-disabled)]"
|
|
4534
|
-
) : cn(
|
|
4535
|
-
"group-data-[active-item]:border-[color:var(--cmp-checkbox-checked-border-inverse)]",
|
|
4536
|
-
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"
|
|
4537
|
-
)
|
|
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)]"
|
|
4538
4746
|
),
|
|
4539
|
-
children:
|
|
4747
|
+
children: selectAllSelected && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4540
4748
|
SIcon,
|
|
4541
4749
|
{
|
|
4542
4750
|
name: "checkboxCheck",
|
|
4543
4751
|
size: 12,
|
|
4544
|
-
color:
|
|
4752
|
+
color: "var(--cmp-checkbox-checked-icon-default)"
|
|
4545
4753
|
}
|
|
4546
4754
|
)
|
|
4547
4755
|
}
|
|
4548
4756
|
),
|
|
4549
|
-
|
|
4550
|
-
"span",
|
|
4551
|
-
{
|
|
4552
|
-
className: "flex-1 truncate",
|
|
4553
|
-
dangerouslySetInnerHTML: { __html: sanitizeInlineHtml(o.label) }
|
|
4554
|
-
}
|
|
4555
|
-
) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children: o.label })
|
|
4757
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children: selectAllLabel })
|
|
4556
4758
|
]
|
|
4557
|
-
}
|
|
4558
|
-
|
|
4559
|
-
)
|
|
4560
|
-
|
|
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
|
+
] });
|
|
4561
4837
|
}
|
|
4562
4838
|
function SRadio({
|
|
4563
4839
|
val,
|
|
@@ -5020,6 +5296,7 @@ function SDatePicker({
|
|
|
5020
5296
|
label,
|
|
5021
5297
|
labelWidth,
|
|
5022
5298
|
icon,
|
|
5299
|
+
iconColor,
|
|
5023
5300
|
labelTooltip,
|
|
5024
5301
|
labelTooltipProps,
|
|
5025
5302
|
addonLabel,
|
|
@@ -5058,6 +5335,7 @@ function SDatePicker({
|
|
|
5058
5335
|
label,
|
|
5059
5336
|
labelWidth,
|
|
5060
5337
|
icon,
|
|
5338
|
+
iconColor,
|
|
5061
5339
|
labelTooltip,
|
|
5062
5340
|
labelTooltipProps,
|
|
5063
5341
|
addonLabel,
|
|
@@ -5326,6 +5604,7 @@ function SDateRangePicker({
|
|
|
5326
5604
|
label,
|
|
5327
5605
|
labelWidth,
|
|
5328
5606
|
icon,
|
|
5607
|
+
iconColor,
|
|
5329
5608
|
labelTooltip,
|
|
5330
5609
|
labelTooltipProps,
|
|
5331
5610
|
addonLabel,
|
|
@@ -5368,6 +5647,7 @@ function SDateRangePicker({
|
|
|
5368
5647
|
label,
|
|
5369
5648
|
labelWidth,
|
|
5370
5649
|
icon,
|
|
5650
|
+
iconColor,
|
|
5371
5651
|
labelTooltip,
|
|
5372
5652
|
labelTooltipProps,
|
|
5373
5653
|
addonLabel,
|
|
@@ -5629,6 +5909,7 @@ function SFilePicker({
|
|
|
5629
5909
|
label,
|
|
5630
5910
|
labelWidth,
|
|
5631
5911
|
icon,
|
|
5912
|
+
iconColor,
|
|
5632
5913
|
labelTooltip,
|
|
5633
5914
|
labelTooltipProps,
|
|
5634
5915
|
addonLabel,
|
|
@@ -5798,7 +6079,7 @@ function SFilePicker({
|
|
|
5798
6079
|
unmountOnHide: true,
|
|
5799
6080
|
getAnchorRect: () => contentBoxRef.current?.getBoundingClientRect() ?? null,
|
|
5800
6081
|
style: { minWidth: contentBoxRef.current?.offsetWidth },
|
|
5801
|
-
className: "z-50 box-border flex flex-col items-
|
|
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)]",
|
|
5802
6083
|
children: filesArr.map((f, i) => /* @__PURE__ */ jsxRuntime.jsx(SChip, { value: f.name, editable: false, onRemove: () => removeChip(i) }, i))
|
|
5803
6084
|
}
|
|
5804
6085
|
)
|
|
@@ -5812,6 +6093,7 @@ function SFilePicker({
|
|
|
5812
6093
|
label,
|
|
5813
6094
|
labelWidth,
|
|
5814
6095
|
icon,
|
|
6096
|
+
iconColor,
|
|
5815
6097
|
labelTooltip,
|
|
5816
6098
|
labelTooltipProps,
|
|
5817
6099
|
addonLabel,
|
|
@@ -5834,21 +6116,26 @@ function SFilePicker({
|
|
|
5834
6116
|
var cssLen2 = (v) => v == null ? void 0 : typeof v === "number" ? `${v}px` : v;
|
|
5835
6117
|
function SKeyValueTable({
|
|
5836
6118
|
fields = [],
|
|
6119
|
+
values = {},
|
|
5837
6120
|
search = false,
|
|
5838
6121
|
radius = "default",
|
|
5839
|
-
dense = false,
|
|
5840
6122
|
onChange,
|
|
5841
6123
|
onSearch,
|
|
5842
6124
|
className,
|
|
5843
6125
|
style
|
|
5844
6126
|
}) {
|
|
5845
6127
|
if (fields.length === 0) return null;
|
|
5846
|
-
const emit = (name, value) => onChange?.({
|
|
5847
|
-
|
|
5848
|
-
|
|
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)";
|
|
5849
6135
|
const renderField = (f) => {
|
|
5850
6136
|
if (f.render) return f.render;
|
|
5851
|
-
const opt = f.options ?? {};
|
|
6137
|
+
const opt = { ...f.options ?? {} };
|
|
6138
|
+
if (Object.prototype.hasOwnProperty.call(values, f.name)) opt.value = values[f.name];
|
|
5852
6139
|
const up = (v) => emit(f.name, v);
|
|
5853
6140
|
switch (f.type) {
|
|
5854
6141
|
case "input":
|
|
@@ -5960,7 +6247,10 @@ function SKeyValueTable({
|
|
|
5960
6247
|
rowSpan: f.tdRowSpan && f.tdRowSpan > 1 ? f.tdRowSpan : void 0,
|
|
5961
6248
|
colSpan: f.tdColSpan && f.tdColSpan > 1 ? f.tdColSpan : void 0,
|
|
5962
6249
|
className: cn(
|
|
5963
|
-
"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)]",
|
|
5964
6254
|
cellBorder,
|
|
5965
6255
|
f.tdClass
|
|
5966
6256
|
),
|