@almadar/ui 5.29.0 → 5.31.0
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/avl/index.cjs +933 -6749
- package/dist/avl/index.js +934 -6750
- package/dist/components/core/atoms/Card.d.ts +2 -0
- package/dist/components/core/atoms/Input.d.ts +2 -0
- package/dist/components/core/atoms/Select.d.ts +18 -6
- package/dist/components/core/atoms/Spinner.d.ts +2 -0
- package/dist/components/core/atoms/index.d.ts +1 -1
- package/dist/components/core/molecules/DocumentViewer.d.ts +0 -2
- package/dist/components/core/molecules/Header.d.ts +0 -4
- package/dist/components/core/molecules/JsonTreeEditor.d.ts +3 -8
- package/dist/components/core/molecules/Menu.d.ts +4 -0
- package/dist/components/core/molecules/Navigation.d.ts +0 -2
- package/dist/components/core/molecules/PageHeader.d.ts +0 -2
- package/dist/components/core/molecules/PropertyInspector.d.ts +8 -1
- package/dist/components/core/molecules/index.d.ts +1 -1
- package/dist/components/core/organisms/index.d.ts +0 -1
- package/dist/components/core/templates/index.d.ts +0 -3
- package/dist/components/game/molecules/index.d.ts +0 -1
- package/dist/components/game/molecules/three/index.cjs +27 -2
- package/dist/components/game/molecules/three/index.js +27 -2
- package/dist/components/game/molecules/three/patterns.d.ts +20 -0
- package/dist/components/game/organisms/TraitSlot.d.ts +3 -1
- package/dist/components/game/organisms/types/isometric.d.ts +2 -0
- package/dist/components/index.cjs +1198 -1062
- package/dist/components/index.js +1201 -1064
- package/dist/docs/index.cjs +205 -172
- package/dist/docs/index.d.cts +4 -0
- package/dist/docs/index.js +146 -113
- package/dist/marketing/index.cjs +91 -54
- package/dist/marketing/index.d.cts +2 -0
- package/dist/marketing/index.js +58 -21
- package/dist/providers/index.cjs +563 -275
- package/dist/providers/index.js +563 -275
- package/dist/renderer/pattern-resolver.d.ts +2 -5
- package/dist/runtime/index.cjs +563 -275
- package/dist/runtime/index.js +563 -275
- package/package.json +16 -2
package/dist/providers/index.cjs
CHANGED
|
@@ -3476,6 +3476,8 @@ var init_Input = __esm({
|
|
|
3476
3476
|
className,
|
|
3477
3477
|
inputType,
|
|
3478
3478
|
type: htmlType,
|
|
3479
|
+
label,
|
|
3480
|
+
helperText,
|
|
3479
3481
|
error,
|
|
3480
3482
|
leftIcon,
|
|
3481
3483
|
rightIcon,
|
|
@@ -3531,82 +3533,95 @@ var init_Input = __esm({
|
|
|
3531
3533
|
onClear?.();
|
|
3532
3534
|
}
|
|
3533
3535
|
};
|
|
3536
|
+
const wrapField = (field) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", children: [
|
|
3537
|
+
label && /* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-sm font-medium text-foreground mb-1", children: label }),
|
|
3538
|
+
field,
|
|
3539
|
+
(helperText || error) && /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("mt-1 text-xs", error ? "text-error" : "text-muted-foreground"), children: error ?? helperText })
|
|
3540
|
+
] });
|
|
3534
3541
|
if (type === "select") {
|
|
3535
|
-
return
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3542
|
+
return wrapField(
|
|
3543
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full", children: [
|
|
3544
|
+
resolvedLeftIcon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none text-muted-foreground", children: resolvedLeftIcon }),
|
|
3545
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3546
|
+
"select",
|
|
3547
|
+
{
|
|
3548
|
+
ref,
|
|
3549
|
+
value,
|
|
3550
|
+
onChange: handleChange,
|
|
3551
|
+
className: cn(baseClassName, "appearance-none pr-10", className),
|
|
3552
|
+
...props,
|
|
3553
|
+
children: [
|
|
3554
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: t("form.selectPlaceholder", { label: "" }) }),
|
|
3555
|
+
options?.map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: opt.value, children: opt.label }, opt.value))
|
|
3556
|
+
]
|
|
3557
|
+
}
|
|
3558
|
+
),
|
|
3559
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "chevron-down", className: "h-icon-default w-icon-default" }) })
|
|
3560
|
+
] })
|
|
3561
|
+
);
|
|
3562
|
+
}
|
|
3563
|
+
if (type === "textarea") {
|
|
3564
|
+
return wrapField(
|
|
3565
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3566
|
+
"textarea",
|
|
3539
3567
|
{
|
|
3540
3568
|
ref,
|
|
3541
3569
|
value,
|
|
3542
3570
|
onChange: handleChange,
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: t("form.selectPlaceholder", { label: "" }) }),
|
|
3547
|
-
options?.map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: opt.value, children: opt.label }, opt.value))
|
|
3548
|
-
]
|
|
3571
|
+
rows: rows2,
|
|
3572
|
+
className: baseClassName,
|
|
3573
|
+
...props
|
|
3549
3574
|
}
|
|
3550
|
-
)
|
|
3551
|
-
|
|
3552
|
-
] });
|
|
3553
|
-
}
|
|
3554
|
-
if (type === "textarea") {
|
|
3555
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3556
|
-
"textarea",
|
|
3557
|
-
{
|
|
3558
|
-
ref,
|
|
3559
|
-
value,
|
|
3560
|
-
onChange: handleChange,
|
|
3561
|
-
rows: rows2,
|
|
3562
|
-
className: baseClassName,
|
|
3563
|
-
...props
|
|
3564
|
-
}
|
|
3565
|
-
) });
|
|
3575
|
+
) })
|
|
3576
|
+
);
|
|
3566
3577
|
}
|
|
3567
3578
|
if (type === "checkbox") {
|
|
3568
|
-
return
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3579
|
+
return wrapField(
|
|
3580
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3581
|
+
"input",
|
|
3582
|
+
{
|
|
3583
|
+
ref,
|
|
3584
|
+
type: "checkbox",
|
|
3585
|
+
checked: props.checked,
|
|
3586
|
+
onChange: handleChange,
|
|
3587
|
+
className: cn(
|
|
3588
|
+
"h-icon-default w-icon-default rounded-sm",
|
|
3589
|
+
"border-border",
|
|
3590
|
+
"text-primary focus:ring-ring",
|
|
3591
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
3592
|
+
className
|
|
3593
|
+
),
|
|
3594
|
+
...props
|
|
3595
|
+
}
|
|
3596
|
+
)
|
|
3584
3597
|
);
|
|
3585
3598
|
}
|
|
3586
|
-
return
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3599
|
+
return wrapField(
|
|
3600
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full", children: [
|
|
3601
|
+
resolvedLeftIcon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none text-muted-foreground", children: resolvedLeftIcon }),
|
|
3602
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3603
|
+
"input",
|
|
3604
|
+
{
|
|
3605
|
+
ref,
|
|
3606
|
+
type,
|
|
3607
|
+
value,
|
|
3608
|
+
onChange: handleChange,
|
|
3609
|
+
className: baseClassName,
|
|
3610
|
+
...props
|
|
3611
|
+
}
|
|
3612
|
+
),
|
|
3613
|
+
showClearButton && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3614
|
+
"button",
|
|
3615
|
+
{
|
|
3616
|
+
type: "button",
|
|
3617
|
+
onClick: handleClear,
|
|
3618
|
+
className: "absolute inset-y-0 right-0 pr-3 flex items-center text-muted-foreground hover:text-foreground",
|
|
3619
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "x", className: "h-icon-default w-icon-default" })
|
|
3620
|
+
}
|
|
3621
|
+
),
|
|
3622
|
+
rightIcon && !showClearButton && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-y-0 right-0 pr-3 flex items-center text-muted-foreground", children: resolveIconNode(rightIcon, iconCls) })
|
|
3623
|
+
] })
|
|
3624
|
+
);
|
|
3610
3625
|
}
|
|
3611
3626
|
);
|
|
3612
3627
|
Input.displayName = "Input";
|
|
@@ -3677,6 +3692,190 @@ var init_Textarea = __esm({
|
|
|
3677
3692
|
Textarea.displayName = "Textarea";
|
|
3678
3693
|
}
|
|
3679
3694
|
});
|
|
3695
|
+
function flatOptions(opts, groups) {
|
|
3696
|
+
const flat = opts ?? [];
|
|
3697
|
+
const grp = (groups ?? []).flatMap((g) => g.options);
|
|
3698
|
+
return [...flat, ...grp];
|
|
3699
|
+
}
|
|
3700
|
+
function NativeSelect({
|
|
3701
|
+
className,
|
|
3702
|
+
options,
|
|
3703
|
+
groups,
|
|
3704
|
+
placeholder,
|
|
3705
|
+
error,
|
|
3706
|
+
onChange,
|
|
3707
|
+
value,
|
|
3708
|
+
...props
|
|
3709
|
+
}) {
|
|
3710
|
+
const eventBus = useEventBus();
|
|
3711
|
+
const handleChange = (e) => {
|
|
3712
|
+
if (typeof onChange === "string") {
|
|
3713
|
+
eventBus.emit(`UI:${onChange}`, { value: e.target.value });
|
|
3714
|
+
} else {
|
|
3715
|
+
onChange?.(e.target.value);
|
|
3716
|
+
}
|
|
3717
|
+
};
|
|
3718
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
3719
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3720
|
+
"select",
|
|
3721
|
+
{
|
|
3722
|
+
onChange: handleChange,
|
|
3723
|
+
value,
|
|
3724
|
+
className: cn(
|
|
3725
|
+
"block w-full border-[length:var(--border-width)] shadow-sm appearance-none",
|
|
3726
|
+
"px-3 py-2 pr-10 text-sm text-foreground font-medium",
|
|
3727
|
+
"bg-card",
|
|
3728
|
+
"focus:outline-none focus:ring-2 focus:ring-offset-0 focus:ring-ring",
|
|
3729
|
+
"disabled:bg-muted disabled:text-muted-foreground disabled:cursor-not-allowed",
|
|
3730
|
+
error ? "border-error focus:border-error" : "border-border focus:border-primary",
|
|
3731
|
+
className
|
|
3732
|
+
),
|
|
3733
|
+
...props,
|
|
3734
|
+
children: [
|
|
3735
|
+
placeholder && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, children: placeholder }),
|
|
3736
|
+
options?.map((option) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: option.value, disabled: option.disabled, children: option.label }, option.value)),
|
|
3737
|
+
groups?.map((group) => /* @__PURE__ */ jsxRuntime.jsx("optgroup", { label: group.label, children: group.options.map((option) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: option.value, disabled: option.disabled, children: option.label }, option.value)) }, group.label))
|
|
3738
|
+
]
|
|
3739
|
+
}
|
|
3740
|
+
),
|
|
3741
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "chevron-down", className: "h-icon-default w-icon-default text-foreground" }) })
|
|
3742
|
+
] });
|
|
3743
|
+
}
|
|
3744
|
+
function RichSelect({
|
|
3745
|
+
className,
|
|
3746
|
+
options,
|
|
3747
|
+
groups,
|
|
3748
|
+
placeholder,
|
|
3749
|
+
error,
|
|
3750
|
+
onChange,
|
|
3751
|
+
value,
|
|
3752
|
+
multiple,
|
|
3753
|
+
searchable,
|
|
3754
|
+
clearable,
|
|
3755
|
+
disabled
|
|
3756
|
+
}) {
|
|
3757
|
+
const eventBus = useEventBus();
|
|
3758
|
+
const [open, setOpen] = React80.useState(false);
|
|
3759
|
+
const [search, setSearch] = React80.useState("");
|
|
3760
|
+
const containerRef = React80.useRef(null);
|
|
3761
|
+
const selected = multiple ? Array.isArray(value) ? value : value ? [value] : [] : value ? [value] : [];
|
|
3762
|
+
const all = flatOptions(options, groups);
|
|
3763
|
+
const filtered = searchable && search ? all.filter((o) => o.label.toLowerCase().includes(search.toLowerCase())) : all;
|
|
3764
|
+
const toggle = (optValue) => {
|
|
3765
|
+
let next;
|
|
3766
|
+
if (multiple) {
|
|
3767
|
+
next = selected.includes(optValue) ? selected.filter((v) => v !== optValue) : [...selected, optValue];
|
|
3768
|
+
} else {
|
|
3769
|
+
next = optValue;
|
|
3770
|
+
setOpen(false);
|
|
3771
|
+
}
|
|
3772
|
+
if (typeof onChange === "string") {
|
|
3773
|
+
eventBus.emit(`UI:${onChange}`, { value: next });
|
|
3774
|
+
} else {
|
|
3775
|
+
onChange?.(next);
|
|
3776
|
+
}
|
|
3777
|
+
};
|
|
3778
|
+
const clear = (e) => {
|
|
3779
|
+
e.stopPropagation();
|
|
3780
|
+
const next = multiple ? [] : "";
|
|
3781
|
+
if (typeof onChange === "string") {
|
|
3782
|
+
eventBus.emit(`UI:${onChange}`, { value: next });
|
|
3783
|
+
} else {
|
|
3784
|
+
onChange?.(next);
|
|
3785
|
+
}
|
|
3786
|
+
};
|
|
3787
|
+
React80.useEffect(() => {
|
|
3788
|
+
const handler = (e) => {
|
|
3789
|
+
if (containerRef.current && !containerRef.current.contains(e.target)) {
|
|
3790
|
+
setOpen(false);
|
|
3791
|
+
setSearch("");
|
|
3792
|
+
}
|
|
3793
|
+
};
|
|
3794
|
+
document.addEventListener("mousedown", handler);
|
|
3795
|
+
return () => document.removeEventListener("mousedown", handler);
|
|
3796
|
+
}, []);
|
|
3797
|
+
const displayLabel = selected.length === 0 ? placeholder ?? "" : multiple ? `${selected.length} selected` : all.find((o) => o.value === selected[0])?.label ?? selected[0];
|
|
3798
|
+
const hasValue = selected.length > 0;
|
|
3799
|
+
const renderOptions = (opts) => opts.map((opt) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3800
|
+
"button",
|
|
3801
|
+
{
|
|
3802
|
+
type: "button",
|
|
3803
|
+
disabled: opt.disabled,
|
|
3804
|
+
onClick: () => !opt.disabled && toggle(opt.value),
|
|
3805
|
+
className: cn(
|
|
3806
|
+
"w-full flex items-center justify-between px-3 py-1.5 text-sm text-start",
|
|
3807
|
+
"hover:bg-muted transition-colors",
|
|
3808
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
3809
|
+
selected.includes(opt.value) && "text-primary font-medium"
|
|
3810
|
+
),
|
|
3811
|
+
children: [
|
|
3812
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: opt.label }),
|
|
3813
|
+
selected.includes(opt.value) && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "check", className: "h-icon-default w-icon-default" })
|
|
3814
|
+
]
|
|
3815
|
+
},
|
|
3816
|
+
opt.value
|
|
3817
|
+
));
|
|
3818
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className: cn("relative w-full", className), children: [
|
|
3819
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3820
|
+
"button",
|
|
3821
|
+
{
|
|
3822
|
+
type: "button",
|
|
3823
|
+
disabled,
|
|
3824
|
+
onClick: () => !disabled && setOpen((o) => !o),
|
|
3825
|
+
className: cn(
|
|
3826
|
+
"block w-full border-[length:var(--border-width)] shadow-sm",
|
|
3827
|
+
"px-3 py-2 pr-10 text-sm text-start font-medium",
|
|
3828
|
+
"bg-card rounded-sm",
|
|
3829
|
+
"focus:outline-none focus:ring-2 focus:ring-offset-0 focus:ring-ring",
|
|
3830
|
+
"disabled:bg-muted disabled:text-muted-foreground disabled:cursor-not-allowed",
|
|
3831
|
+
error ? "border-error focus:border-error" : "border-border focus:border-primary",
|
|
3832
|
+
!hasValue && "text-muted-foreground"
|
|
3833
|
+
),
|
|
3834
|
+
children: displayLabel
|
|
3835
|
+
}
|
|
3836
|
+
),
|
|
3837
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-y-0 right-0 pr-3 flex items-center gap-1 pointer-events-none", children: [
|
|
3838
|
+
clearable && hasValue && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3839
|
+
"button",
|
|
3840
|
+
{
|
|
3841
|
+
type: "button",
|
|
3842
|
+
onClick: clear,
|
|
3843
|
+
className: "pointer-events-auto text-muted-foreground hover:text-foreground",
|
|
3844
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "x", className: "h-icon-default w-icon-default" })
|
|
3845
|
+
}
|
|
3846
|
+
),
|
|
3847
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "chevron-down", className: "h-icon-default w-icon-default text-foreground" })
|
|
3848
|
+
] }),
|
|
3849
|
+
open && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(
|
|
3850
|
+
"absolute z-50 mt-1 w-full",
|
|
3851
|
+
"bg-card border-[length:var(--border-width)] border-border",
|
|
3852
|
+
"rounded-sm shadow-elevation-popover py-1 max-h-60 overflow-y-auto"
|
|
3853
|
+
), children: [
|
|
3854
|
+
searchable && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 pb-1 border-b border-border", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3855
|
+
"input",
|
|
3856
|
+
{
|
|
3857
|
+
autoFocus: true,
|
|
3858
|
+
type: "text",
|
|
3859
|
+
value: search,
|
|
3860
|
+
onChange: (e) => setSearch(e.target.value),
|
|
3861
|
+
placeholder: "Search\u2026",
|
|
3862
|
+
className: cn(
|
|
3863
|
+
"w-full px-2 py-1 text-sm bg-transparent",
|
|
3864
|
+
"focus:outline-none text-foreground placeholder:text-muted-foreground"
|
|
3865
|
+
)
|
|
3866
|
+
}
|
|
3867
|
+
) }),
|
|
3868
|
+
groups && groups.length > 0 ? groups.map((g) => {
|
|
3869
|
+
const groupFiltered = searchable && search ? g.options.filter((o) => o.label.toLowerCase().includes(search.toLowerCase())) : g.options;
|
|
3870
|
+
if (groupFiltered.length === 0) return null;
|
|
3871
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
3872
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-1 text-xs font-semibold text-muted-foreground uppercase tracking-wide", children: g.label }),
|
|
3873
|
+
renderOptions(groupFiltered)
|
|
3874
|
+
] }, g.label);
|
|
3875
|
+
}) : renderOptions(filtered)
|
|
3876
|
+
] })
|
|
3877
|
+
] });
|
|
3878
|
+
}
|
|
3680
3879
|
var Select;
|
|
3681
3880
|
var init_Select = __esm({
|
|
3682
3881
|
"components/core/atoms/Select.tsx"() {
|
|
@@ -3684,47 +3883,12 @@ var init_Select = __esm({
|
|
|
3684
3883
|
init_Icon();
|
|
3685
3884
|
init_useEventBus();
|
|
3686
3885
|
Select = React80__namespace.default.forwardRef(
|
|
3687
|
-
(
|
|
3688
|
-
const
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
onChange?.(e);
|
|
3694
|
-
}
|
|
3695
|
-
};
|
|
3696
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
3697
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3698
|
-
"select",
|
|
3699
|
-
{
|
|
3700
|
-
ref,
|
|
3701
|
-
onChange: handleChange,
|
|
3702
|
-
className: cn(
|
|
3703
|
-
"block w-full border-[length:var(--border-width)] shadow-sm appearance-none",
|
|
3704
|
-
"px-3 py-2 pr-10 text-sm text-foreground font-medium",
|
|
3705
|
-
"bg-card",
|
|
3706
|
-
"focus:outline-none focus:ring-2 focus:ring-offset-0 focus:ring-ring",
|
|
3707
|
-
"disabled:bg-muted disabled:text-muted-foreground disabled:cursor-not-allowed",
|
|
3708
|
-
error ? "border-error focus:border-error" : "border-border focus:border-primary",
|
|
3709
|
-
className
|
|
3710
|
-
),
|
|
3711
|
-
...props,
|
|
3712
|
-
children: [
|
|
3713
|
-
placeholder && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, children: placeholder }),
|
|
3714
|
-
options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3715
|
-
"option",
|
|
3716
|
-
{
|
|
3717
|
-
value: option.value,
|
|
3718
|
-
disabled: option.disabled,
|
|
3719
|
-
children: option.label
|
|
3720
|
-
},
|
|
3721
|
-
option.value
|
|
3722
|
-
))
|
|
3723
|
-
]
|
|
3724
|
-
}
|
|
3725
|
-
),
|
|
3726
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "chevron-down", className: "h-icon-default w-icon-default text-foreground" }) })
|
|
3727
|
-
] });
|
|
3886
|
+
(props, _ref) => {
|
|
3887
|
+
const { multiple, searchable, clearable } = props;
|
|
3888
|
+
if (multiple || searchable || clearable) {
|
|
3889
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RichSelect, { ...props });
|
|
3890
|
+
}
|
|
3891
|
+
return /* @__PURE__ */ jsxRuntime.jsx(NativeSelect, { ...props });
|
|
3728
3892
|
}
|
|
3729
3893
|
);
|
|
3730
3894
|
Select.displayName = "Select";
|
|
@@ -3778,11 +3942,54 @@ var init_Checkbox = __esm({
|
|
|
3778
3942
|
Checkbox.displayName = "Checkbox";
|
|
3779
3943
|
}
|
|
3780
3944
|
});
|
|
3945
|
+
var sizeStyles3, Spinner;
|
|
3946
|
+
var init_Spinner = __esm({
|
|
3947
|
+
"components/core/atoms/Spinner.tsx"() {
|
|
3948
|
+
init_cn();
|
|
3949
|
+
init_Icon();
|
|
3950
|
+
sizeStyles3 = {
|
|
3951
|
+
xs: "h-3 w-3",
|
|
3952
|
+
sm: "h-icon-default w-icon-default",
|
|
3953
|
+
md: "h-6 w-6",
|
|
3954
|
+
lg: "h-8 w-8"
|
|
3955
|
+
};
|
|
3956
|
+
Spinner = React80__namespace.default.forwardRef(
|
|
3957
|
+
({ className, size = "md", overlay, ...props }, ref) => {
|
|
3958
|
+
if (overlay) {
|
|
3959
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3960
|
+
"div",
|
|
3961
|
+
{
|
|
3962
|
+
ref,
|
|
3963
|
+
className: cn(
|
|
3964
|
+
"absolute inset-0 z-10 flex items-center justify-center",
|
|
3965
|
+
"bg-background/60 backdrop-blur-sm",
|
|
3966
|
+
className
|
|
3967
|
+
),
|
|
3968
|
+
...props,
|
|
3969
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "loader", className: cn("animate-spin text-foreground", sizeStyles3[size]) })
|
|
3970
|
+
}
|
|
3971
|
+
);
|
|
3972
|
+
}
|
|
3973
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3974
|
+
"div",
|
|
3975
|
+
{
|
|
3976
|
+
ref,
|
|
3977
|
+
className: cn("text-foreground", className),
|
|
3978
|
+
...props,
|
|
3979
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "loader", className: cn("animate-spin", sizeStyles3[size]) })
|
|
3980
|
+
}
|
|
3981
|
+
);
|
|
3982
|
+
}
|
|
3983
|
+
);
|
|
3984
|
+
Spinner.displayName = "Spinner";
|
|
3985
|
+
}
|
|
3986
|
+
});
|
|
3781
3987
|
var variantStyles4, paddingStyles2, shadowStyles2, lookStyles2, Card, CardHeader, CardTitle, CardContent, CardBody, CardFooter;
|
|
3782
3988
|
var init_Card = __esm({
|
|
3783
3989
|
"components/core/atoms/Card.tsx"() {
|
|
3784
3990
|
init_cn();
|
|
3785
3991
|
init_useEventBus();
|
|
3992
|
+
init_Spinner();
|
|
3786
3993
|
variantStyles4 = {
|
|
3787
3994
|
default: [
|
|
3788
3995
|
"bg-card",
|
|
@@ -3847,6 +4054,7 @@ var init_Card = __esm({
|
|
|
3847
4054
|
look = "elevated",
|
|
3848
4055
|
children,
|
|
3849
4056
|
action,
|
|
4057
|
+
loading,
|
|
3850
4058
|
onClick,
|
|
3851
4059
|
...props
|
|
3852
4060
|
}, ref) => {
|
|
@@ -3860,7 +4068,7 @@ var init_Card = __esm({
|
|
|
3860
4068
|
{
|
|
3861
4069
|
ref,
|
|
3862
4070
|
className: cn(
|
|
3863
|
-
"rounded-container",
|
|
4071
|
+
"rounded-container relative",
|
|
3864
4072
|
"transition-all duration-[var(--transition-normal)]",
|
|
3865
4073
|
variantStyles4[variant],
|
|
3866
4074
|
paddingStyles2[padding],
|
|
@@ -3871,6 +4079,7 @@ var init_Card = __esm({
|
|
|
3871
4079
|
onClick: handleClick,
|
|
3872
4080
|
...props,
|
|
3873
4081
|
children: [
|
|
4082
|
+
loading && /* @__PURE__ */ jsxRuntime.jsx(Spinner, { overlay: true, size: "md" }),
|
|
3874
4083
|
(title || subtitle) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4", children: [
|
|
3875
4084
|
title && /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg text-card-foreground font-bold", children: title }),
|
|
3876
4085
|
subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-1", children: subtitle })
|
|
@@ -3912,7 +4121,7 @@ var init_Card = __esm({
|
|
|
3912
4121
|
CardFooter.displayName = "CardFooter";
|
|
3913
4122
|
}
|
|
3914
4123
|
});
|
|
3915
|
-
var variantStyles5,
|
|
4124
|
+
var variantStyles5, sizeStyles4, iconSizes, FilterPill;
|
|
3916
4125
|
var init_FilterPill = __esm({
|
|
3917
4126
|
"components/core/atoms/FilterPill.tsx"() {
|
|
3918
4127
|
init_cn();
|
|
@@ -3946,7 +4155,7 @@ var init_FilterPill = __esm({
|
|
|
3946
4155
|
"border-[length:var(--border-width-thin)] border-border"
|
|
3947
4156
|
].join(" ")
|
|
3948
4157
|
};
|
|
3949
|
-
|
|
4158
|
+
sizeStyles4 = {
|
|
3950
4159
|
sm: "px-2 py-0.5 text-xs",
|
|
3951
4160
|
md: "px-2.5 py-1 text-sm",
|
|
3952
4161
|
lg: "px-3 py-1.5 text-base"
|
|
@@ -3990,7 +4199,7 @@ var init_FilterPill = __esm({
|
|
|
3990
4199
|
className: cn(
|
|
3991
4200
|
"inline-flex items-center gap-1 font-bold rounded-pill",
|
|
3992
4201
|
variantStyles5[variant],
|
|
3993
|
-
|
|
4202
|
+
sizeStyles4[size],
|
|
3994
4203
|
(onClick || clickEvent) && "cursor-pointer",
|
|
3995
4204
|
className
|
|
3996
4205
|
),
|
|
@@ -4022,33 +4231,6 @@ var init_FilterPill = __esm({
|
|
|
4022
4231
|
FilterPill.displayName = "FilterPill";
|
|
4023
4232
|
}
|
|
4024
4233
|
});
|
|
4025
|
-
var sizeStyles4, Spinner;
|
|
4026
|
-
var init_Spinner = __esm({
|
|
4027
|
-
"components/core/atoms/Spinner.tsx"() {
|
|
4028
|
-
init_cn();
|
|
4029
|
-
init_Icon();
|
|
4030
|
-
sizeStyles4 = {
|
|
4031
|
-
xs: "h-3 w-3",
|
|
4032
|
-
sm: "h-icon-default w-icon-default",
|
|
4033
|
-
md: "h-6 w-6",
|
|
4034
|
-
lg: "h-8 w-8"
|
|
4035
|
-
};
|
|
4036
|
-
Spinner = React80__namespace.default.forwardRef(
|
|
4037
|
-
({ className, size = "md", ...props }, ref) => {
|
|
4038
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4039
|
-
"div",
|
|
4040
|
-
{
|
|
4041
|
-
ref,
|
|
4042
|
-
className: cn("text-foreground", className),
|
|
4043
|
-
...props,
|
|
4044
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "loader", className: cn("animate-spin", sizeStyles4[size]) })
|
|
4045
|
-
}
|
|
4046
|
-
);
|
|
4047
|
-
}
|
|
4048
|
-
);
|
|
4049
|
-
Spinner.displayName = "Spinner";
|
|
4050
|
-
}
|
|
4051
|
-
});
|
|
4052
4234
|
function generateInitials(name) {
|
|
4053
4235
|
const parts = name.trim().split(/\s+/);
|
|
4054
4236
|
if (parts.length === 1) {
|
|
@@ -16515,30 +16697,30 @@ var init_BranchingLogicBuilder = __esm({
|
|
|
16515
16697
|
if (!sourceQuestion?.optionValues) return [];
|
|
16516
16698
|
return sourceQuestion.optionValues.map((v) => ({ value: v, label: v }));
|
|
16517
16699
|
}, [sourceQuestion]);
|
|
16518
|
-
const handleSource = (
|
|
16519
|
-
onChange({ ...rule, sourceQuestionId:
|
|
16700
|
+
const handleSource = (v) => {
|
|
16701
|
+
onChange({ ...rule, sourceQuestionId: v });
|
|
16520
16702
|
};
|
|
16521
|
-
const handleOperator = (
|
|
16522
|
-
const next =
|
|
16703
|
+
const handleOperator = (v) => {
|
|
16704
|
+
const next = v;
|
|
16523
16705
|
const nextValue = next === "in" && !Array.isArray(rule.value) ? rule.value ? [rule.value] : [] : next !== "in" && Array.isArray(rule.value) ? rule.value[0] ?? "" : rule.value;
|
|
16524
16706
|
onChange({ ...rule, operator: next, value: nextValue });
|
|
16525
16707
|
};
|
|
16526
16708
|
const handleScalarValue = (e) => {
|
|
16527
16709
|
onChange({ ...rule, value: e.target.value });
|
|
16528
16710
|
};
|
|
16529
|
-
const handleAddChip = (
|
|
16530
|
-
const
|
|
16531
|
-
if (!
|
|
16711
|
+
const handleAddChip = (v) => {
|
|
16712
|
+
const val = v;
|
|
16713
|
+
if (!val) return;
|
|
16532
16714
|
const current = Array.isArray(rule.value) ? rule.value : [];
|
|
16533
|
-
if (current.includes(
|
|
16534
|
-
onChange({ ...rule, value: [...current,
|
|
16715
|
+
if (current.includes(val)) return;
|
|
16716
|
+
onChange({ ...rule, value: [...current, val] });
|
|
16535
16717
|
};
|
|
16536
16718
|
const handleRemoveChip = (chip) => {
|
|
16537
16719
|
const current = Array.isArray(rule.value) ? rule.value : [];
|
|
16538
16720
|
onChange({ ...rule, value: current.filter((c) => c !== chip) });
|
|
16539
16721
|
};
|
|
16540
|
-
const handleTarget = (
|
|
16541
|
-
onChange({ ...rule, targetQuestionId:
|
|
16722
|
+
const handleTarget = (v) => {
|
|
16723
|
+
onChange({ ...rule, targetQuestionId: v });
|
|
16542
16724
|
};
|
|
16543
16725
|
const isMulti = rule.operator === "in";
|
|
16544
16726
|
const chips = Array.isArray(rule.value) ? rule.value : [];
|
|
@@ -16619,7 +16801,7 @@ var init_BranchingLogicBuilder = __esm({
|
|
|
16619
16801
|
options: valueOptions,
|
|
16620
16802
|
value: scalarValue,
|
|
16621
16803
|
placeholder: t("branchingLogic.selectValue"),
|
|
16622
|
-
onChange: (
|
|
16804
|
+
onChange: (v) => onChange({ ...rule, value: v }),
|
|
16623
16805
|
disabled: readOnly
|
|
16624
16806
|
}
|
|
16625
16807
|
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -19051,7 +19233,7 @@ var init_Pagination = __esm({
|
|
|
19051
19233
|
Select,
|
|
19052
19234
|
{
|
|
19053
19235
|
value: String(pageSize),
|
|
19054
|
-
onChange: (
|
|
19236
|
+
onChange: (v) => handlePageSizeChange(Number(v)),
|
|
19055
19237
|
options: pageSizeOptions.map((size) => ({
|
|
19056
19238
|
value: String(size),
|
|
19057
19239
|
label: String(size)
|
|
@@ -21977,7 +22159,84 @@ var init_DashboardLayout = __esm({
|
|
|
21977
22159
|
NavLinkBottom.displayName = "NavLinkBottom";
|
|
21978
22160
|
}
|
|
21979
22161
|
});
|
|
21980
|
-
|
|
22162
|
+
function computeMenuStyle(position, triggerRect) {
|
|
22163
|
+
const isTop = position.startsWith("top");
|
|
22164
|
+
const isRight = position.endsWith("right") || position.endsWith("end");
|
|
22165
|
+
if (isTop) {
|
|
22166
|
+
return {
|
|
22167
|
+
top: triggerRect.top - MENU_GAP,
|
|
22168
|
+
transform: "translateY(-100%)",
|
|
22169
|
+
...isRight ? { right: window.innerWidth - triggerRect.right } : { left: triggerRect.left }
|
|
22170
|
+
};
|
|
22171
|
+
}
|
|
22172
|
+
return {
|
|
22173
|
+
top: triggerRect.bottom + MENU_GAP,
|
|
22174
|
+
...isRight ? { right: window.innerWidth - triggerRect.right } : { left: triggerRect.left }
|
|
22175
|
+
};
|
|
22176
|
+
}
|
|
22177
|
+
function SubMenu({
|
|
22178
|
+
items,
|
|
22179
|
+
itemRef,
|
|
22180
|
+
direction,
|
|
22181
|
+
eventBus
|
|
22182
|
+
}) {
|
|
22183
|
+
const [rect, setRect] = React80.useState(null);
|
|
22184
|
+
React80.useEffect(() => {
|
|
22185
|
+
if (itemRef) {
|
|
22186
|
+
setRect(itemRef.getBoundingClientRect());
|
|
22187
|
+
}
|
|
22188
|
+
}, [itemRef]);
|
|
22189
|
+
if (!rect) return null;
|
|
22190
|
+
const isRtl = direction === "rtl";
|
|
22191
|
+
const style = {
|
|
22192
|
+
top: rect.top,
|
|
22193
|
+
...isRtl ? { right: window.innerWidth - rect.left } : { left: rect.right }
|
|
22194
|
+
};
|
|
22195
|
+
const panel = /* @__PURE__ */ jsxRuntime.jsx(
|
|
22196
|
+
"div",
|
|
22197
|
+
{
|
|
22198
|
+
className: cn("fixed z-50", menuContainerStyles),
|
|
22199
|
+
style,
|
|
22200
|
+
children: items.map((item, index) => {
|
|
22201
|
+
const isDivider = item.id === "divider" || item.label === "divider";
|
|
22202
|
+
const itemId = item.id ?? `item-${item.label.toLowerCase().replace(/\s+/g, "-")}-${index}`;
|
|
22203
|
+
const isDanger = item.variant === "danger";
|
|
22204
|
+
if (isDivider) {
|
|
22205
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Divider, { className: "my-1" }, `divider-${index}`);
|
|
22206
|
+
}
|
|
22207
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
22208
|
+
Box,
|
|
22209
|
+
{
|
|
22210
|
+
as: "button",
|
|
22211
|
+
onClick: () => {
|
|
22212
|
+
if (item.disabled) return;
|
|
22213
|
+
if (item.event) eventBus.emit(`UI:${item.event}`, { itemId, label: item.label });
|
|
22214
|
+
item.onClick?.();
|
|
22215
|
+
},
|
|
22216
|
+
"aria-disabled": item.disabled || void 0,
|
|
22217
|
+
"data-testid": item.event ? `action-${item.event}` : void 0,
|
|
22218
|
+
className: cn(
|
|
22219
|
+
"w-full flex items-center gap-3 px-4 py-2 text-start",
|
|
22220
|
+
"text-sm transition-colors",
|
|
22221
|
+
"hover:bg-muted focus:outline-none focus:bg-muted",
|
|
22222
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
22223
|
+
item.disabled && "cursor-not-allowed",
|
|
22224
|
+
isDanger && "text-error hover:bg-error/10"
|
|
22225
|
+
),
|
|
22226
|
+
children: [
|
|
22227
|
+
item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: item.icon, size: "sm", className: "flex-shrink-0" }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: item.icon, size: "sm", className: "flex-shrink-0" })),
|
|
22228
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", className: cn("flex-1", isDanger && "text-red-600"), children: item.label }),
|
|
22229
|
+
item.badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto text-xs font-medium", children: item.badge })
|
|
22230
|
+
]
|
|
22231
|
+
},
|
|
22232
|
+
itemId
|
|
22233
|
+
);
|
|
22234
|
+
})
|
|
22235
|
+
}
|
|
22236
|
+
);
|
|
22237
|
+
return typeof document !== "undefined" ? reactDom.createPortal(panel, document.body) : panel;
|
|
22238
|
+
}
|
|
22239
|
+
var MENU_GAP, menuContainerStyles, Menu;
|
|
21981
22240
|
var init_Menu = __esm({
|
|
21982
22241
|
"components/core/molecules/Menu.tsx"() {
|
|
21983
22242
|
"use client";
|
|
@@ -21988,16 +22247,27 @@ var init_Menu = __esm({
|
|
|
21988
22247
|
init_Badge();
|
|
21989
22248
|
init_cn();
|
|
21990
22249
|
init_useEventBus();
|
|
22250
|
+
MENU_GAP = 4;
|
|
22251
|
+
menuContainerStyles = cn(
|
|
22252
|
+
"bg-card",
|
|
22253
|
+
"border-[length:var(--border-width)] border-border",
|
|
22254
|
+
"shadow-elevation-popover",
|
|
22255
|
+
"rounded-sm",
|
|
22256
|
+
"min-w-0 sm:min-w-[200px] max-w-[calc(100vw-1rem)] py-1"
|
|
22257
|
+
);
|
|
21991
22258
|
Menu = ({
|
|
21992
22259
|
trigger,
|
|
21993
22260
|
items,
|
|
21994
22261
|
position = "bottom-left",
|
|
21995
|
-
className
|
|
22262
|
+
className,
|
|
22263
|
+
header,
|
|
22264
|
+
footer
|
|
21996
22265
|
}) => {
|
|
21997
22266
|
const eventBus = useEventBus();
|
|
21998
|
-
const {
|
|
22267
|
+
const { direction } = hooks.useTranslate();
|
|
21999
22268
|
const [isOpen, setIsOpen] = React80.useState(false);
|
|
22000
22269
|
const [activeSubMenu, setActiveSubMenu] = React80.useState(null);
|
|
22270
|
+
const [activeSubMenuRef, setActiveSubMenuRef] = React80.useState(null);
|
|
22001
22271
|
const [triggerRect, setTriggerRect] = React80.useState(null);
|
|
22002
22272
|
const triggerRef = React80.useRef(null);
|
|
22003
22273
|
const menuRef = React80.useRef(null);
|
|
@@ -22012,13 +22282,14 @@ var init_Menu = __esm({
|
|
|
22012
22282
|
}
|
|
22013
22283
|
setIsOpen(!isOpen);
|
|
22014
22284
|
setActiveSubMenu(null);
|
|
22285
|
+
setActiveSubMenuRef(null);
|
|
22015
22286
|
};
|
|
22016
|
-
const handleItemClick = (item) => {
|
|
22287
|
+
const handleItemClick = (item, itemId) => {
|
|
22017
22288
|
if (item.disabled) return;
|
|
22018
22289
|
if (item.subMenu && item.subMenu.length > 0) {
|
|
22019
|
-
setActiveSubMenu(
|
|
22290
|
+
setActiveSubMenu(itemId);
|
|
22020
22291
|
} else {
|
|
22021
|
-
if (item.event) eventBus.emit(`UI:${item.event}`, { itemId
|
|
22292
|
+
if (item.event) eventBus.emit(`UI:${item.event}`, { itemId, label: item.label });
|
|
22022
22293
|
item.onClick?.();
|
|
22023
22294
|
setIsOpen(false);
|
|
22024
22295
|
}
|
|
@@ -22033,22 +22304,12 @@ var init_Menu = __esm({
|
|
|
22033
22304
|
if (isOpen && menuRef.current && !menuRef.current.contains(e.target) && triggerRef.current && !triggerRef.current.contains(e.target)) {
|
|
22034
22305
|
setIsOpen(false);
|
|
22035
22306
|
setActiveSubMenu(null);
|
|
22307
|
+
setActiveSubMenuRef(null);
|
|
22036
22308
|
}
|
|
22037
22309
|
};
|
|
22038
22310
|
document.addEventListener("mousedown", handleClickOutside);
|
|
22039
22311
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
22040
22312
|
}, [isOpen]);
|
|
22041
|
-
const positionClasses = {
|
|
22042
|
-
"top-left": "bottom-full left-0 mb-2",
|
|
22043
|
-
"top-right": "bottom-full right-0 mb-2",
|
|
22044
|
-
"bottom-left": "top-full left-0 mt-2",
|
|
22045
|
-
"bottom-right": "top-full right-0 mt-2",
|
|
22046
|
-
// Aliases for pattern compatibility
|
|
22047
|
-
"top-start": "bottom-full left-0 mb-2",
|
|
22048
|
-
"top-end": "bottom-full right-0 mb-2",
|
|
22049
|
-
"bottom-start": "top-full left-0 mt-2",
|
|
22050
|
-
"bottom-end": "top-full right-0 mt-2"
|
|
22051
|
-
};
|
|
22052
22313
|
const rtlMirror = {
|
|
22053
22314
|
"top-left": "top-right",
|
|
22054
22315
|
"top-right": "top-left",
|
|
@@ -22060,7 +22321,6 @@ var init_Menu = __esm({
|
|
|
22060
22321
|
"bottom-end": "bottom-start"
|
|
22061
22322
|
};
|
|
22062
22323
|
const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
|
|
22063
|
-
const subMenuSideClass = direction === "rtl" ? "right-full mr-2" : "left-full ml-2";
|
|
22064
22324
|
const triggerChild = React80__namespace.default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", as: "span", children: trigger });
|
|
22065
22325
|
const triggerElement = React80__namespace.default.cloneElement(
|
|
22066
22326
|
triggerChild,
|
|
@@ -22069,94 +22329,87 @@ var init_Menu = __esm({
|
|
|
22069
22329
|
onClick: handleToggle
|
|
22070
22330
|
}
|
|
22071
22331
|
);
|
|
22072
|
-
const
|
|
22073
|
-
"
|
|
22074
|
-
"border-[length:var(--border-width)] border-border",
|
|
22075
|
-
"shadow-elevation-popover",
|
|
22076
|
-
"rounded-sm",
|
|
22077
|
-
"min-w-0 sm:min-w-[200px] max-w-[calc(100vw-1rem)] py-1"
|
|
22078
|
-
);
|
|
22079
|
-
const renderMenuItem = (item, hasSubMenu, index) => {
|
|
22332
|
+
const renderMenuItems = (menuItems) => menuItems.map((item, index) => {
|
|
22333
|
+
const isDivider = item.id === "divider" || item.label === "divider";
|
|
22080
22334
|
const itemId = item.id ?? `item-${item.label.toLowerCase().replace(/\s+/g, "-")}-${index}`;
|
|
22335
|
+
const hasSubMenu = !!(item.subMenu && item.subMenu.length > 0);
|
|
22081
22336
|
const isDanger = item.variant === "danger";
|
|
22082
|
-
|
|
22083
|
-
|
|
22084
|
-
|
|
22085
|
-
|
|
22086
|
-
|
|
22087
|
-
|
|
22088
|
-
|
|
22089
|
-
|
|
22090
|
-
|
|
22091
|
-
"
|
|
22092
|
-
|
|
22093
|
-
|
|
22094
|
-
|
|
22095
|
-
|
|
22096
|
-
item.disabled && "cursor-not-allowed",
|
|
22097
|
-
isDanger && "text-error hover:bg-error/10"
|
|
22098
|
-
),
|
|
22099
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "flex items-center gap-3 flex-1 min-w-0", children: [
|
|
22100
|
-
item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: item.icon, size: "sm", className: "flex-shrink-0" }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: item.icon, size: "sm", className: "flex-shrink-0" })),
|
|
22101
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22102
|
-
Typography,
|
|
22103
|
-
{
|
|
22104
|
-
variant: "small",
|
|
22105
|
-
className: cn("flex-1", isDanger && "text-red-600"),
|
|
22106
|
-
children: item.label
|
|
22337
|
+
if (isDivider) {
|
|
22338
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Divider, { className: "my-1" }, `divider-${index}`);
|
|
22339
|
+
}
|
|
22340
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Box, { children: [
|
|
22341
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22342
|
+
Box,
|
|
22343
|
+
{
|
|
22344
|
+
as: "button",
|
|
22345
|
+
onClick: () => handleItemClick({ ...item, id: itemId }, itemId),
|
|
22346
|
+
"aria-disabled": item.disabled || void 0,
|
|
22347
|
+
onMouseEnter: (e) => {
|
|
22348
|
+
if (hasSubMenu) {
|
|
22349
|
+
setActiveSubMenu(itemId);
|
|
22350
|
+
setActiveSubMenuRef(e.currentTarget);
|
|
22107
22351
|
}
|
|
22352
|
+
},
|
|
22353
|
+
"data-testid": item.event ? `action-${item.event}` : void 0,
|
|
22354
|
+
className: cn(
|
|
22355
|
+
"w-full flex items-center justify-between gap-3 px-4 py-2 text-start",
|
|
22356
|
+
"text-sm transition-colors",
|
|
22357
|
+
"hover:bg-muted",
|
|
22358
|
+
"focus:outline-none focus:bg-muted",
|
|
22359
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
22360
|
+
item.disabled && "cursor-not-allowed",
|
|
22361
|
+
isDanger && "text-error hover:bg-error/10"
|
|
22108
22362
|
),
|
|
22109
|
-
|
|
22110
|
-
|
|
22111
|
-
|
|
22112
|
-
|
|
22113
|
-
|
|
22114
|
-
|
|
22115
|
-
|
|
22116
|
-
|
|
22117
|
-
|
|
22118
|
-
const hasSubMenu = item.subMenu && item.subMenu.length > 0;
|
|
22119
|
-
const isDivider = item.id === "divider" || item.label === "divider";
|
|
22120
|
-
const itemId = item.id ?? `item-${item.label.toLowerCase().replace(/\s+/g, "-")}-${index}`;
|
|
22121
|
-
if (isDivider) {
|
|
22122
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Divider, { className: "my-1" }, `divider-${index}`);
|
|
22123
|
-
}
|
|
22124
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(Box, { children: [
|
|
22125
|
-
renderMenuItem(item, !!hasSubMenu, index),
|
|
22126
|
-
hasSubMenu && activeSubMenu === itemId && item.subMenu && /* @__PURE__ */ jsxRuntime.jsx(
|
|
22127
|
-
Box,
|
|
22128
|
-
{
|
|
22129
|
-
className: cn(
|
|
22130
|
-
"absolute top-0 z-50",
|
|
22131
|
-
subMenuSideClass,
|
|
22132
|
-
menuContainerStyles
|
|
22363
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "flex items-center gap-3 flex-1 min-w-0", children: [
|
|
22364
|
+
item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: item.icon, size: "sm", className: "flex-shrink-0" }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: item.icon, size: "sm", className: "flex-shrink-0" })),
|
|
22365
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22366
|
+
Typography,
|
|
22367
|
+
{
|
|
22368
|
+
variant: "small",
|
|
22369
|
+
className: cn("flex-1", isDanger && "text-red-600"),
|
|
22370
|
+
children: item.label
|
|
22371
|
+
}
|
|
22133
22372
|
),
|
|
22134
|
-
children:
|
|
22135
|
-
|
|
22136
|
-
|
|
22137
|
-
|
|
22138
|
-
|
|
22139
|
-
|
|
22140
|
-
|
|
22373
|
+
item.badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "default", size: "sm", children: item.badge }),
|
|
22374
|
+
hasSubMenu && /* @__PURE__ */ jsxRuntime.jsx(
|
|
22375
|
+
Icon,
|
|
22376
|
+
{
|
|
22377
|
+
name: direction === "rtl" ? "chevron-left" : "chevron-right",
|
|
22378
|
+
size: "sm",
|
|
22379
|
+
className: "flex-shrink-0"
|
|
22380
|
+
}
|
|
22381
|
+
)
|
|
22382
|
+
] })
|
|
22383
|
+
}
|
|
22384
|
+
),
|
|
22385
|
+
hasSubMenu && activeSubMenu === itemId && item.subMenu && /* @__PURE__ */ jsxRuntime.jsx(
|
|
22386
|
+
SubMenu,
|
|
22387
|
+
{
|
|
22388
|
+
items: item.subMenu,
|
|
22389
|
+
itemRef: activeSubMenuRef,
|
|
22390
|
+
direction,
|
|
22391
|
+
eventBus
|
|
22392
|
+
}
|
|
22393
|
+
)
|
|
22394
|
+
] }, itemId);
|
|
22395
|
+
});
|
|
22396
|
+
const panel = isOpen && triggerRect ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
22397
|
+
"div",
|
|
22398
|
+
{
|
|
22399
|
+
ref: menuRef,
|
|
22400
|
+
className: cn("fixed z-50", menuContainerStyles, className),
|
|
22401
|
+
style: computeMenuStyle(effectivePosition, triggerRect),
|
|
22402
|
+
role: "menu",
|
|
22403
|
+
children: [
|
|
22404
|
+
header && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-2 border-b border-border", children: header }),
|
|
22405
|
+
renderMenuItems(items),
|
|
22406
|
+
footer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-2 border-t border-border", children: footer })
|
|
22407
|
+
]
|
|
22408
|
+
}
|
|
22409
|
+
) : null;
|
|
22410
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
22141
22411
|
triggerElement,
|
|
22142
|
-
|
|
22143
|
-
Box,
|
|
22144
|
-
{
|
|
22145
|
-
ref: menuRef,
|
|
22146
|
-
className: cn(
|
|
22147
|
-
"absolute z-50",
|
|
22148
|
-
menuContainerStyles,
|
|
22149
|
-
positionClasses[effectivePosition],
|
|
22150
|
-
className
|
|
22151
|
-
),
|
|
22152
|
-
style: {
|
|
22153
|
-
left: effectivePosition.includes("left") ? 0 : "auto",
|
|
22154
|
-
right: effectivePosition.includes("right") ? 0 : "auto"
|
|
22155
|
-
},
|
|
22156
|
-
role: "menu",
|
|
22157
|
-
children: renderMenuItems(items)
|
|
22158
|
-
}
|
|
22159
|
-
)
|
|
22412
|
+
panel && typeof document !== "undefined" ? reactDom.createPortal(panel, document.body) : panel
|
|
22160
22413
|
] });
|
|
22161
22414
|
};
|
|
22162
22415
|
Menu.displayName = "Menu";
|
|
@@ -23910,7 +24163,7 @@ var init_FilterGroup = __esm({
|
|
|
23910
24163
|
Select,
|
|
23911
24164
|
{
|
|
23912
24165
|
value: selectedValues[filter.field] || "all",
|
|
23913
|
-
onChange: (
|
|
24166
|
+
onChange: (v) => handleFilterSelect(filter.field, v),
|
|
23914
24167
|
options: [
|
|
23915
24168
|
{ value: "all", label: t("filterGroup.all") },
|
|
23916
24169
|
...filter.options?.map((opt) => ({
|
|
@@ -23993,7 +24246,7 @@ var init_FilterGroup = __esm({
|
|
|
23993
24246
|
Select,
|
|
23994
24247
|
{
|
|
23995
24248
|
value: selectedValues[filter.field] || "all",
|
|
23996
|
-
onChange: (
|
|
24249
|
+
onChange: (v) => handleFilterSelect(filter.field, v),
|
|
23997
24250
|
options: [
|
|
23998
24251
|
{ value: "all", label: t("filterGroup.allOf", { label: filter.label }) },
|
|
23999
24252
|
...filter.options?.map((opt) => ({
|
|
@@ -24111,7 +24364,7 @@ var init_FilterGroup = __esm({
|
|
|
24111
24364
|
Select,
|
|
24112
24365
|
{
|
|
24113
24366
|
value: selectedValues[filter.field] || "all",
|
|
24114
|
-
onChange: (
|
|
24367
|
+
onChange: (v) => handleFilterSelect(filter.field, v),
|
|
24115
24368
|
options: [
|
|
24116
24369
|
{ value: "all", label: t("filterGroup.all") },
|
|
24117
24370
|
...filter.options?.map((opt) => ({
|
|
@@ -28293,13 +28546,13 @@ var init_MapView = __esm({
|
|
|
28293
28546
|
shadowSize: [41, 41]
|
|
28294
28547
|
});
|
|
28295
28548
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
28296
|
-
const { useEffect:
|
|
28549
|
+
const { useEffect: useEffect72, useRef: useRef67, useCallback: useCallback112, useState: useState100 } = React80__namespace.default;
|
|
28297
28550
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
28298
28551
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
28299
28552
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
28300
28553
|
const map = useMap();
|
|
28301
|
-
const prevRef =
|
|
28302
|
-
|
|
28554
|
+
const prevRef = useRef67({ centerLat, centerLng, zoom });
|
|
28555
|
+
useEffect72(() => {
|
|
28303
28556
|
const prev = prevRef.current;
|
|
28304
28557
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
28305
28558
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -28310,7 +28563,7 @@ var init_MapView = __esm({
|
|
|
28310
28563
|
}
|
|
28311
28564
|
function MapClickHandler({ onMapClick }) {
|
|
28312
28565
|
const map = useMap();
|
|
28313
|
-
|
|
28566
|
+
useEffect72(() => {
|
|
28314
28567
|
if (!onMapClick) return;
|
|
28315
28568
|
const handler = (e) => {
|
|
28316
28569
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -28338,7 +28591,7 @@ var init_MapView = __esm({
|
|
|
28338
28591
|
showAttribution = true
|
|
28339
28592
|
}) {
|
|
28340
28593
|
const eventBus = useEventBus2();
|
|
28341
|
-
const [clickedPosition, setClickedPosition] =
|
|
28594
|
+
const [clickedPosition, setClickedPosition] = useState100(null);
|
|
28342
28595
|
const handleMapClick = useCallback112((lat, lng) => {
|
|
28343
28596
|
if (showClickedPin) {
|
|
28344
28597
|
setClickedPosition({ lat, lng });
|
|
@@ -33774,8 +34027,8 @@ var init_VersionDiff = __esm({
|
|
|
33774
34027
|
return { added, removed };
|
|
33775
34028
|
}, [diff]);
|
|
33776
34029
|
const handleBeforeChange = React80.useCallback(
|
|
33777
|
-
(
|
|
33778
|
-
const id =
|
|
34030
|
+
(v) => {
|
|
34031
|
+
const id = v;
|
|
33779
34032
|
setInternalBefore(id);
|
|
33780
34033
|
onSelectBefore?.(id);
|
|
33781
34034
|
if (selectBeforeEvent) eventBus.emit(`UI:${selectBeforeEvent}`, { id });
|
|
@@ -33783,8 +34036,8 @@ var init_VersionDiff = __esm({
|
|
|
33783
34036
|
[onSelectBefore, selectBeforeEvent, eventBus]
|
|
33784
34037
|
);
|
|
33785
34038
|
const handleAfterChange = React80.useCallback(
|
|
33786
|
-
(
|
|
33787
|
-
const id =
|
|
34039
|
+
(v) => {
|
|
34040
|
+
const id = v;
|
|
33788
34041
|
setInternalAfter(id);
|
|
33789
34042
|
onSelectAfter?.(id);
|
|
33790
34043
|
if (selectAfterEvent) eventBus.emit(`UI:${selectAfterEvent}`, { id });
|
|
@@ -36562,7 +36815,6 @@ var init_DocumentViewer = __esm({
|
|
|
36562
36815
|
showPrint = false,
|
|
36563
36816
|
actions,
|
|
36564
36817
|
documents,
|
|
36565
|
-
entity,
|
|
36566
36818
|
isLoading = false,
|
|
36567
36819
|
error,
|
|
36568
36820
|
className
|
|
@@ -38411,11 +38663,11 @@ function RuleEditor({
|
|
|
38411
38663
|
className
|
|
38412
38664
|
}) {
|
|
38413
38665
|
const { t } = hooks.useTranslate();
|
|
38414
|
-
const handleWhenChange = React80.useCallback((
|
|
38415
|
-
onChange({ ...rule, whenEvent:
|
|
38666
|
+
const handleWhenChange = React80.useCallback((v) => {
|
|
38667
|
+
onChange({ ...rule, whenEvent: v });
|
|
38416
38668
|
}, [rule, onChange]);
|
|
38417
|
-
const handleThenChange = React80.useCallback((
|
|
38418
|
-
onChange({ ...rule, thenAction:
|
|
38669
|
+
const handleThenChange = React80.useCallback((v) => {
|
|
38670
|
+
onChange({ ...rule, thenAction: v });
|
|
38419
38671
|
}, [rule, onChange]);
|
|
38420
38672
|
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { className: cn("items-center p-2 rounded-lg bg-muted/50 border border-border", className), gap: "sm", children: [
|
|
38421
38673
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-primary font-bold whitespace-nowrap", children: t("eventHandler.when") }),
|
|
@@ -39491,7 +39743,7 @@ var init_Form = __esm({
|
|
|
39491
39743
|
...commonProps,
|
|
39492
39744
|
options,
|
|
39493
39745
|
value: String(currentValue),
|
|
39494
|
-
onChange: (
|
|
39746
|
+
onChange: (v) => handleChange(fieldName, v),
|
|
39495
39747
|
placeholder: field.placeholder || `Select ${label}...`
|
|
39496
39748
|
}
|
|
39497
39749
|
);
|
|
@@ -43358,7 +43610,7 @@ function TraitSlot({
|
|
|
43358
43610
|
size = "md",
|
|
43359
43611
|
showTooltip = true,
|
|
43360
43612
|
categoryColors,
|
|
43361
|
-
tooltipFrameUrl,
|
|
43613
|
+
tooltipFrameUrl = "",
|
|
43362
43614
|
className,
|
|
43363
43615
|
feedback,
|
|
43364
43616
|
onItemDrop,
|
|
@@ -46259,18 +46511,32 @@ var init_WorldMapTemplate = __esm({
|
|
|
46259
46511
|
}
|
|
46260
46512
|
});
|
|
46261
46513
|
function lazyThree(name, loader) {
|
|
46262
|
-
const Lazy = React80__namespace.default.lazy(
|
|
46514
|
+
const Lazy = React80__namespace.default.lazy(
|
|
46515
|
+
() => loader().then((m) => {
|
|
46516
|
+
const Resolved = m[name];
|
|
46517
|
+
if (!Resolved) {
|
|
46518
|
+
throw new Error(
|
|
46519
|
+
`[@almadar/ui] 3D component "${name}" was not found in the three subpath bundle.`
|
|
46520
|
+
);
|
|
46521
|
+
}
|
|
46522
|
+
return { default: Resolved };
|
|
46523
|
+
})
|
|
46524
|
+
);
|
|
46263
46525
|
function ThreeWrapper(props) {
|
|
46264
46526
|
return React80__namespace.default.createElement(
|
|
46265
|
-
|
|
46266
|
-
{
|
|
46267
|
-
React80__namespace.default.createElement(
|
|
46527
|
+
ThreeBoundary,
|
|
46528
|
+
{ name },
|
|
46529
|
+
React80__namespace.default.createElement(
|
|
46530
|
+
React80__namespace.default.Suspense,
|
|
46531
|
+
{ fallback: null },
|
|
46532
|
+
React80__namespace.default.createElement(Lazy, props)
|
|
46533
|
+
)
|
|
46268
46534
|
);
|
|
46269
46535
|
}
|
|
46270
46536
|
ThreeWrapper.displayName = `Lazy(${name})`;
|
|
46271
46537
|
return ThreeWrapper;
|
|
46272
46538
|
}
|
|
46273
|
-
var FeatureRenderer, GameCanvas3D, GameCanvas3DBattleTemplate, GameCanvas3DCastleTemplate, GameCanvas3DWorldMapTemplate, COMPONENT_REGISTRY;
|
|
46539
|
+
var ThreeBoundary, FeatureRenderer, GameCanvas3D, GameCanvas3DBattleTemplate, GameCanvas3DCastleTemplate, GameCanvas3DWorldMapTemplate, COMPONENT_REGISTRY;
|
|
46274
46540
|
var init_component_registry_generated = __esm({
|
|
46275
46541
|
"components/core/organisms/component-registry.generated.ts"() {
|
|
46276
46542
|
init_AboutPageTemplate();
|
|
@@ -46556,6 +46822,28 @@ var init_component_registry_generated = __esm({
|
|
|
46556
46822
|
init_WorldMapBoard();
|
|
46557
46823
|
init_WorldMapTemplate();
|
|
46558
46824
|
init_XPBar();
|
|
46825
|
+
ThreeBoundary = class extends React80__namespace.default.Component {
|
|
46826
|
+
constructor() {
|
|
46827
|
+
super(...arguments);
|
|
46828
|
+
__publicField(this, "state", { failed: false });
|
|
46829
|
+
}
|
|
46830
|
+
static getDerivedStateFromError() {
|
|
46831
|
+
return { failed: true };
|
|
46832
|
+
}
|
|
46833
|
+
render() {
|
|
46834
|
+
if (this.state.failed) {
|
|
46835
|
+
return React80__namespace.default.createElement(
|
|
46836
|
+
"div",
|
|
46837
|
+
{
|
|
46838
|
+
"data-testid": "three-unavailable",
|
|
46839
|
+
style: { padding: 16, fontSize: 13, lineHeight: 1.5, opacity: 0.7 }
|
|
46840
|
+
},
|
|
46841
|
+
`3D pattern "${this.props.name}" requires three.js. Install the optional peers three + @react-three/fiber + @react-three/drei (matching the host React major) to render it.`
|
|
46842
|
+
);
|
|
46843
|
+
}
|
|
46844
|
+
return this.props.children;
|
|
46845
|
+
}
|
|
46846
|
+
};
|
|
46559
46847
|
FeatureRenderer = lazyThree("FeatureRenderer", () => import('@almadar/ui/components/molecules/game/three'));
|
|
46560
46848
|
GameCanvas3D = lazyThree("GameCanvas3D", () => import('@almadar/ui/components/molecules/game/three'));
|
|
46561
46849
|
GameCanvas3DBattleTemplate = lazyThree("GameCanvas3DBattleTemplate", () => import('@almadar/ui/components/molecules/game/three'));
|