@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/runtime/index.cjs
CHANGED
|
@@ -3212,6 +3212,8 @@ var init_Input = __esm({
|
|
|
3212
3212
|
className,
|
|
3213
3213
|
inputType,
|
|
3214
3214
|
type: htmlType,
|
|
3215
|
+
label,
|
|
3216
|
+
helperText,
|
|
3215
3217
|
error,
|
|
3216
3218
|
leftIcon,
|
|
3217
3219
|
rightIcon,
|
|
@@ -3267,82 +3269,95 @@ var init_Input = __esm({
|
|
|
3267
3269
|
onClear?.();
|
|
3268
3270
|
}
|
|
3269
3271
|
};
|
|
3272
|
+
const wrapField = (field) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", children: [
|
|
3273
|
+
label && /* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-sm font-medium text-foreground mb-1", children: label }),
|
|
3274
|
+
field,
|
|
3275
|
+
(helperText || error) && /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("mt-1 text-xs", error ? "text-error" : "text-muted-foreground"), children: error ?? helperText })
|
|
3276
|
+
] });
|
|
3270
3277
|
if (type === "select") {
|
|
3271
|
-
return
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3278
|
+
return wrapField(
|
|
3279
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full", children: [
|
|
3280
|
+
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 }),
|
|
3281
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3282
|
+
"select",
|
|
3283
|
+
{
|
|
3284
|
+
ref,
|
|
3285
|
+
value,
|
|
3286
|
+
onChange: handleChange,
|
|
3287
|
+
className: cn(baseClassName, "appearance-none pr-10", className),
|
|
3288
|
+
...props,
|
|
3289
|
+
children: [
|
|
3290
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: t("form.selectPlaceholder", { label: "" }) }),
|
|
3291
|
+
options?.map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: opt.value, children: opt.label }, opt.value))
|
|
3292
|
+
]
|
|
3293
|
+
}
|
|
3294
|
+
),
|
|
3295
|
+
/* @__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" }) })
|
|
3296
|
+
] })
|
|
3297
|
+
);
|
|
3298
|
+
}
|
|
3299
|
+
if (type === "textarea") {
|
|
3300
|
+
return wrapField(
|
|
3301
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3302
|
+
"textarea",
|
|
3275
3303
|
{
|
|
3276
3304
|
ref,
|
|
3277
3305
|
value,
|
|
3278
3306
|
onChange: handleChange,
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: t("form.selectPlaceholder", { label: "" }) }),
|
|
3283
|
-
options?.map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: opt.value, children: opt.label }, opt.value))
|
|
3284
|
-
]
|
|
3307
|
+
rows: rows2,
|
|
3308
|
+
className: baseClassName,
|
|
3309
|
+
...props
|
|
3285
3310
|
}
|
|
3286
|
-
)
|
|
3287
|
-
|
|
3288
|
-
] });
|
|
3289
|
-
}
|
|
3290
|
-
if (type === "textarea") {
|
|
3291
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3292
|
-
"textarea",
|
|
3293
|
-
{
|
|
3294
|
-
ref,
|
|
3295
|
-
value,
|
|
3296
|
-
onChange: handleChange,
|
|
3297
|
-
rows: rows2,
|
|
3298
|
-
className: baseClassName,
|
|
3299
|
-
...props
|
|
3300
|
-
}
|
|
3301
|
-
) });
|
|
3311
|
+
) })
|
|
3312
|
+
);
|
|
3302
3313
|
}
|
|
3303
3314
|
if (type === "checkbox") {
|
|
3304
|
-
return
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3315
|
+
return wrapField(
|
|
3316
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3317
|
+
"input",
|
|
3318
|
+
{
|
|
3319
|
+
ref,
|
|
3320
|
+
type: "checkbox",
|
|
3321
|
+
checked: props.checked,
|
|
3322
|
+
onChange: handleChange,
|
|
3323
|
+
className: cn(
|
|
3324
|
+
"h-icon-default w-icon-default rounded-sm",
|
|
3325
|
+
"border-border",
|
|
3326
|
+
"text-primary focus:ring-ring",
|
|
3327
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
3328
|
+
className
|
|
3329
|
+
),
|
|
3330
|
+
...props
|
|
3331
|
+
}
|
|
3332
|
+
)
|
|
3320
3333
|
);
|
|
3321
3334
|
}
|
|
3322
|
-
return
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3335
|
+
return wrapField(
|
|
3336
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full", children: [
|
|
3337
|
+
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 }),
|
|
3338
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3339
|
+
"input",
|
|
3340
|
+
{
|
|
3341
|
+
ref,
|
|
3342
|
+
type,
|
|
3343
|
+
value,
|
|
3344
|
+
onChange: handleChange,
|
|
3345
|
+
className: baseClassName,
|
|
3346
|
+
...props
|
|
3347
|
+
}
|
|
3348
|
+
),
|
|
3349
|
+
showClearButton && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3350
|
+
"button",
|
|
3351
|
+
{
|
|
3352
|
+
type: "button",
|
|
3353
|
+
onClick: handleClear,
|
|
3354
|
+
className: "absolute inset-y-0 right-0 pr-3 flex items-center text-muted-foreground hover:text-foreground",
|
|
3355
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "x", className: "h-icon-default w-icon-default" })
|
|
3356
|
+
}
|
|
3357
|
+
),
|
|
3358
|
+
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) })
|
|
3359
|
+
] })
|
|
3360
|
+
);
|
|
3346
3361
|
}
|
|
3347
3362
|
);
|
|
3348
3363
|
Input.displayName = "Input";
|
|
@@ -3413,6 +3428,190 @@ var init_Textarea = __esm({
|
|
|
3413
3428
|
Textarea.displayName = "Textarea";
|
|
3414
3429
|
}
|
|
3415
3430
|
});
|
|
3431
|
+
function flatOptions(opts, groups) {
|
|
3432
|
+
const flat = opts ?? [];
|
|
3433
|
+
const grp = (groups ?? []).flatMap((g) => g.options);
|
|
3434
|
+
return [...flat, ...grp];
|
|
3435
|
+
}
|
|
3436
|
+
function NativeSelect({
|
|
3437
|
+
className,
|
|
3438
|
+
options,
|
|
3439
|
+
groups,
|
|
3440
|
+
placeholder,
|
|
3441
|
+
error,
|
|
3442
|
+
onChange,
|
|
3443
|
+
value,
|
|
3444
|
+
...props
|
|
3445
|
+
}) {
|
|
3446
|
+
const eventBus = useEventBus();
|
|
3447
|
+
const handleChange = (e) => {
|
|
3448
|
+
if (typeof onChange === "string") {
|
|
3449
|
+
eventBus.emit(`UI:${onChange}`, { value: e.target.value });
|
|
3450
|
+
} else {
|
|
3451
|
+
onChange?.(e.target.value);
|
|
3452
|
+
}
|
|
3453
|
+
};
|
|
3454
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
3455
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3456
|
+
"select",
|
|
3457
|
+
{
|
|
3458
|
+
onChange: handleChange,
|
|
3459
|
+
value,
|
|
3460
|
+
className: cn(
|
|
3461
|
+
"block w-full border-[length:var(--border-width)] shadow-sm appearance-none",
|
|
3462
|
+
"px-3 py-2 pr-10 text-sm text-foreground font-medium",
|
|
3463
|
+
"bg-card",
|
|
3464
|
+
"focus:outline-none focus:ring-2 focus:ring-offset-0 focus:ring-ring",
|
|
3465
|
+
"disabled:bg-muted disabled:text-muted-foreground disabled:cursor-not-allowed",
|
|
3466
|
+
error ? "border-error focus:border-error" : "border-border focus:border-primary",
|
|
3467
|
+
className
|
|
3468
|
+
),
|
|
3469
|
+
...props,
|
|
3470
|
+
children: [
|
|
3471
|
+
placeholder && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, children: placeholder }),
|
|
3472
|
+
options?.map((option) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: option.value, disabled: option.disabled, children: option.label }, option.value)),
|
|
3473
|
+
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))
|
|
3474
|
+
]
|
|
3475
|
+
}
|
|
3476
|
+
),
|
|
3477
|
+
/* @__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" }) })
|
|
3478
|
+
] });
|
|
3479
|
+
}
|
|
3480
|
+
function RichSelect({
|
|
3481
|
+
className,
|
|
3482
|
+
options,
|
|
3483
|
+
groups,
|
|
3484
|
+
placeholder,
|
|
3485
|
+
error,
|
|
3486
|
+
onChange,
|
|
3487
|
+
value,
|
|
3488
|
+
multiple,
|
|
3489
|
+
searchable,
|
|
3490
|
+
clearable,
|
|
3491
|
+
disabled
|
|
3492
|
+
}) {
|
|
3493
|
+
const eventBus = useEventBus();
|
|
3494
|
+
const [open, setOpen] = React79.useState(false);
|
|
3495
|
+
const [search, setSearch] = React79.useState("");
|
|
3496
|
+
const containerRef = React79.useRef(null);
|
|
3497
|
+
const selected = multiple ? Array.isArray(value) ? value : value ? [value] : [] : value ? [value] : [];
|
|
3498
|
+
const all = flatOptions(options, groups);
|
|
3499
|
+
const filtered = searchable && search ? all.filter((o) => o.label.toLowerCase().includes(search.toLowerCase())) : all;
|
|
3500
|
+
const toggle = (optValue) => {
|
|
3501
|
+
let next;
|
|
3502
|
+
if (multiple) {
|
|
3503
|
+
next = selected.includes(optValue) ? selected.filter((v) => v !== optValue) : [...selected, optValue];
|
|
3504
|
+
} else {
|
|
3505
|
+
next = optValue;
|
|
3506
|
+
setOpen(false);
|
|
3507
|
+
}
|
|
3508
|
+
if (typeof onChange === "string") {
|
|
3509
|
+
eventBus.emit(`UI:${onChange}`, { value: next });
|
|
3510
|
+
} else {
|
|
3511
|
+
onChange?.(next);
|
|
3512
|
+
}
|
|
3513
|
+
};
|
|
3514
|
+
const clear = (e) => {
|
|
3515
|
+
e.stopPropagation();
|
|
3516
|
+
const next = multiple ? [] : "";
|
|
3517
|
+
if (typeof onChange === "string") {
|
|
3518
|
+
eventBus.emit(`UI:${onChange}`, { value: next });
|
|
3519
|
+
} else {
|
|
3520
|
+
onChange?.(next);
|
|
3521
|
+
}
|
|
3522
|
+
};
|
|
3523
|
+
React79.useEffect(() => {
|
|
3524
|
+
const handler = (e) => {
|
|
3525
|
+
if (containerRef.current && !containerRef.current.contains(e.target)) {
|
|
3526
|
+
setOpen(false);
|
|
3527
|
+
setSearch("");
|
|
3528
|
+
}
|
|
3529
|
+
};
|
|
3530
|
+
document.addEventListener("mousedown", handler);
|
|
3531
|
+
return () => document.removeEventListener("mousedown", handler);
|
|
3532
|
+
}, []);
|
|
3533
|
+
const displayLabel = selected.length === 0 ? placeholder ?? "" : multiple ? `${selected.length} selected` : all.find((o) => o.value === selected[0])?.label ?? selected[0];
|
|
3534
|
+
const hasValue = selected.length > 0;
|
|
3535
|
+
const renderOptions = (opts) => opts.map((opt) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3536
|
+
"button",
|
|
3537
|
+
{
|
|
3538
|
+
type: "button",
|
|
3539
|
+
disabled: opt.disabled,
|
|
3540
|
+
onClick: () => !opt.disabled && toggle(opt.value),
|
|
3541
|
+
className: cn(
|
|
3542
|
+
"w-full flex items-center justify-between px-3 py-1.5 text-sm text-start",
|
|
3543
|
+
"hover:bg-muted transition-colors",
|
|
3544
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
3545
|
+
selected.includes(opt.value) && "text-primary font-medium"
|
|
3546
|
+
),
|
|
3547
|
+
children: [
|
|
3548
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: opt.label }),
|
|
3549
|
+
selected.includes(opt.value) && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "check", className: "h-icon-default w-icon-default" })
|
|
3550
|
+
]
|
|
3551
|
+
},
|
|
3552
|
+
opt.value
|
|
3553
|
+
));
|
|
3554
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className: cn("relative w-full", className), children: [
|
|
3555
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3556
|
+
"button",
|
|
3557
|
+
{
|
|
3558
|
+
type: "button",
|
|
3559
|
+
disabled,
|
|
3560
|
+
onClick: () => !disabled && setOpen((o) => !o),
|
|
3561
|
+
className: cn(
|
|
3562
|
+
"block w-full border-[length:var(--border-width)] shadow-sm",
|
|
3563
|
+
"px-3 py-2 pr-10 text-sm text-start font-medium",
|
|
3564
|
+
"bg-card rounded-sm",
|
|
3565
|
+
"focus:outline-none focus:ring-2 focus:ring-offset-0 focus:ring-ring",
|
|
3566
|
+
"disabled:bg-muted disabled:text-muted-foreground disabled:cursor-not-allowed",
|
|
3567
|
+
error ? "border-error focus:border-error" : "border-border focus:border-primary",
|
|
3568
|
+
!hasValue && "text-muted-foreground"
|
|
3569
|
+
),
|
|
3570
|
+
children: displayLabel
|
|
3571
|
+
}
|
|
3572
|
+
),
|
|
3573
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-y-0 right-0 pr-3 flex items-center gap-1 pointer-events-none", children: [
|
|
3574
|
+
clearable && hasValue && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3575
|
+
"button",
|
|
3576
|
+
{
|
|
3577
|
+
type: "button",
|
|
3578
|
+
onClick: clear,
|
|
3579
|
+
className: "pointer-events-auto text-muted-foreground hover:text-foreground",
|
|
3580
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "x", className: "h-icon-default w-icon-default" })
|
|
3581
|
+
}
|
|
3582
|
+
),
|
|
3583
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "chevron-down", className: "h-icon-default w-icon-default text-foreground" })
|
|
3584
|
+
] }),
|
|
3585
|
+
open && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(
|
|
3586
|
+
"absolute z-50 mt-1 w-full",
|
|
3587
|
+
"bg-card border-[length:var(--border-width)] border-border",
|
|
3588
|
+
"rounded-sm shadow-elevation-popover py-1 max-h-60 overflow-y-auto"
|
|
3589
|
+
), children: [
|
|
3590
|
+
searchable && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 pb-1 border-b border-border", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3591
|
+
"input",
|
|
3592
|
+
{
|
|
3593
|
+
autoFocus: true,
|
|
3594
|
+
type: "text",
|
|
3595
|
+
value: search,
|
|
3596
|
+
onChange: (e) => setSearch(e.target.value),
|
|
3597
|
+
placeholder: "Search\u2026",
|
|
3598
|
+
className: cn(
|
|
3599
|
+
"w-full px-2 py-1 text-sm bg-transparent",
|
|
3600
|
+
"focus:outline-none text-foreground placeholder:text-muted-foreground"
|
|
3601
|
+
)
|
|
3602
|
+
}
|
|
3603
|
+
) }),
|
|
3604
|
+
groups && groups.length > 0 ? groups.map((g) => {
|
|
3605
|
+
const groupFiltered = searchable && search ? g.options.filter((o) => o.label.toLowerCase().includes(search.toLowerCase())) : g.options;
|
|
3606
|
+
if (groupFiltered.length === 0) return null;
|
|
3607
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
3608
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-1 text-xs font-semibold text-muted-foreground uppercase tracking-wide", children: g.label }),
|
|
3609
|
+
renderOptions(groupFiltered)
|
|
3610
|
+
] }, g.label);
|
|
3611
|
+
}) : renderOptions(filtered)
|
|
3612
|
+
] })
|
|
3613
|
+
] });
|
|
3614
|
+
}
|
|
3416
3615
|
var Select;
|
|
3417
3616
|
var init_Select = __esm({
|
|
3418
3617
|
"components/core/atoms/Select.tsx"() {
|
|
@@ -3420,47 +3619,12 @@ var init_Select = __esm({
|
|
|
3420
3619
|
init_Icon();
|
|
3421
3620
|
init_useEventBus();
|
|
3422
3621
|
Select = React79__namespace.default.forwardRef(
|
|
3423
|
-
(
|
|
3424
|
-
const
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
onChange?.(e);
|
|
3430
|
-
}
|
|
3431
|
-
};
|
|
3432
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
3433
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3434
|
-
"select",
|
|
3435
|
-
{
|
|
3436
|
-
ref,
|
|
3437
|
-
onChange: handleChange,
|
|
3438
|
-
className: cn(
|
|
3439
|
-
"block w-full border-[length:var(--border-width)] shadow-sm appearance-none",
|
|
3440
|
-
"px-3 py-2 pr-10 text-sm text-foreground font-medium",
|
|
3441
|
-
"bg-card",
|
|
3442
|
-
"focus:outline-none focus:ring-2 focus:ring-offset-0 focus:ring-ring",
|
|
3443
|
-
"disabled:bg-muted disabled:text-muted-foreground disabled:cursor-not-allowed",
|
|
3444
|
-
error ? "border-error focus:border-error" : "border-border focus:border-primary",
|
|
3445
|
-
className
|
|
3446
|
-
),
|
|
3447
|
-
...props,
|
|
3448
|
-
children: [
|
|
3449
|
-
placeholder && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, children: placeholder }),
|
|
3450
|
-
options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3451
|
-
"option",
|
|
3452
|
-
{
|
|
3453
|
-
value: option.value,
|
|
3454
|
-
disabled: option.disabled,
|
|
3455
|
-
children: option.label
|
|
3456
|
-
},
|
|
3457
|
-
option.value
|
|
3458
|
-
))
|
|
3459
|
-
]
|
|
3460
|
-
}
|
|
3461
|
-
),
|
|
3462
|
-
/* @__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" }) })
|
|
3463
|
-
] });
|
|
3622
|
+
(props, _ref) => {
|
|
3623
|
+
const { multiple, searchable, clearable } = props;
|
|
3624
|
+
if (multiple || searchable || clearable) {
|
|
3625
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RichSelect, { ...props });
|
|
3626
|
+
}
|
|
3627
|
+
return /* @__PURE__ */ jsxRuntime.jsx(NativeSelect, { ...props });
|
|
3464
3628
|
}
|
|
3465
3629
|
);
|
|
3466
3630
|
Select.displayName = "Select";
|
|
@@ -3514,11 +3678,54 @@ var init_Checkbox = __esm({
|
|
|
3514
3678
|
Checkbox.displayName = "Checkbox";
|
|
3515
3679
|
}
|
|
3516
3680
|
});
|
|
3681
|
+
var sizeStyles3, Spinner;
|
|
3682
|
+
var init_Spinner = __esm({
|
|
3683
|
+
"components/core/atoms/Spinner.tsx"() {
|
|
3684
|
+
init_cn();
|
|
3685
|
+
init_Icon();
|
|
3686
|
+
sizeStyles3 = {
|
|
3687
|
+
xs: "h-3 w-3",
|
|
3688
|
+
sm: "h-icon-default w-icon-default",
|
|
3689
|
+
md: "h-6 w-6",
|
|
3690
|
+
lg: "h-8 w-8"
|
|
3691
|
+
};
|
|
3692
|
+
Spinner = React79__namespace.default.forwardRef(
|
|
3693
|
+
({ className, size = "md", overlay, ...props }, ref) => {
|
|
3694
|
+
if (overlay) {
|
|
3695
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3696
|
+
"div",
|
|
3697
|
+
{
|
|
3698
|
+
ref,
|
|
3699
|
+
className: cn(
|
|
3700
|
+
"absolute inset-0 z-10 flex items-center justify-center",
|
|
3701
|
+
"bg-background/60 backdrop-blur-sm",
|
|
3702
|
+
className
|
|
3703
|
+
),
|
|
3704
|
+
...props,
|
|
3705
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "loader", className: cn("animate-spin text-foreground", sizeStyles3[size]) })
|
|
3706
|
+
}
|
|
3707
|
+
);
|
|
3708
|
+
}
|
|
3709
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3710
|
+
"div",
|
|
3711
|
+
{
|
|
3712
|
+
ref,
|
|
3713
|
+
className: cn("text-foreground", className),
|
|
3714
|
+
...props,
|
|
3715
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "loader", className: cn("animate-spin", sizeStyles3[size]) })
|
|
3716
|
+
}
|
|
3717
|
+
);
|
|
3718
|
+
}
|
|
3719
|
+
);
|
|
3720
|
+
Spinner.displayName = "Spinner";
|
|
3721
|
+
}
|
|
3722
|
+
});
|
|
3517
3723
|
var variantStyles4, paddingStyles2, shadowStyles2, lookStyles2, Card, CardHeader, CardTitle, CardContent, CardBody, CardFooter;
|
|
3518
3724
|
var init_Card = __esm({
|
|
3519
3725
|
"components/core/atoms/Card.tsx"() {
|
|
3520
3726
|
init_cn();
|
|
3521
3727
|
init_useEventBus();
|
|
3728
|
+
init_Spinner();
|
|
3522
3729
|
variantStyles4 = {
|
|
3523
3730
|
default: [
|
|
3524
3731
|
"bg-card",
|
|
@@ -3583,6 +3790,7 @@ var init_Card = __esm({
|
|
|
3583
3790
|
look = "elevated",
|
|
3584
3791
|
children,
|
|
3585
3792
|
action,
|
|
3793
|
+
loading,
|
|
3586
3794
|
onClick,
|
|
3587
3795
|
...props
|
|
3588
3796
|
}, ref) => {
|
|
@@ -3596,7 +3804,7 @@ var init_Card = __esm({
|
|
|
3596
3804
|
{
|
|
3597
3805
|
ref,
|
|
3598
3806
|
className: cn(
|
|
3599
|
-
"rounded-container",
|
|
3807
|
+
"rounded-container relative",
|
|
3600
3808
|
"transition-all duration-[var(--transition-normal)]",
|
|
3601
3809
|
variantStyles4[variant],
|
|
3602
3810
|
paddingStyles2[padding],
|
|
@@ -3607,6 +3815,7 @@ var init_Card = __esm({
|
|
|
3607
3815
|
onClick: handleClick,
|
|
3608
3816
|
...props,
|
|
3609
3817
|
children: [
|
|
3818
|
+
loading && /* @__PURE__ */ jsxRuntime.jsx(Spinner, { overlay: true, size: "md" }),
|
|
3610
3819
|
(title || subtitle) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4", children: [
|
|
3611
3820
|
title && /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg text-card-foreground font-bold", children: title }),
|
|
3612
3821
|
subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-1", children: subtitle })
|
|
@@ -3648,7 +3857,7 @@ var init_Card = __esm({
|
|
|
3648
3857
|
CardFooter.displayName = "CardFooter";
|
|
3649
3858
|
}
|
|
3650
3859
|
});
|
|
3651
|
-
var variantStyles5,
|
|
3860
|
+
var variantStyles5, sizeStyles4, iconSizes, FilterPill;
|
|
3652
3861
|
var init_FilterPill = __esm({
|
|
3653
3862
|
"components/core/atoms/FilterPill.tsx"() {
|
|
3654
3863
|
init_cn();
|
|
@@ -3682,7 +3891,7 @@ var init_FilterPill = __esm({
|
|
|
3682
3891
|
"border-[length:var(--border-width-thin)] border-border"
|
|
3683
3892
|
].join(" ")
|
|
3684
3893
|
};
|
|
3685
|
-
|
|
3894
|
+
sizeStyles4 = {
|
|
3686
3895
|
sm: "px-2 py-0.5 text-xs",
|
|
3687
3896
|
md: "px-2.5 py-1 text-sm",
|
|
3688
3897
|
lg: "px-3 py-1.5 text-base"
|
|
@@ -3726,7 +3935,7 @@ var init_FilterPill = __esm({
|
|
|
3726
3935
|
className: cn(
|
|
3727
3936
|
"inline-flex items-center gap-1 font-bold rounded-pill",
|
|
3728
3937
|
variantStyles5[variant],
|
|
3729
|
-
|
|
3938
|
+
sizeStyles4[size],
|
|
3730
3939
|
(onClick || clickEvent) && "cursor-pointer",
|
|
3731
3940
|
className
|
|
3732
3941
|
),
|
|
@@ -3758,33 +3967,6 @@ var init_FilterPill = __esm({
|
|
|
3758
3967
|
FilterPill.displayName = "FilterPill";
|
|
3759
3968
|
}
|
|
3760
3969
|
});
|
|
3761
|
-
var sizeStyles4, Spinner;
|
|
3762
|
-
var init_Spinner = __esm({
|
|
3763
|
-
"components/core/atoms/Spinner.tsx"() {
|
|
3764
|
-
init_cn();
|
|
3765
|
-
init_Icon();
|
|
3766
|
-
sizeStyles4 = {
|
|
3767
|
-
xs: "h-3 w-3",
|
|
3768
|
-
sm: "h-icon-default w-icon-default",
|
|
3769
|
-
md: "h-6 w-6",
|
|
3770
|
-
lg: "h-8 w-8"
|
|
3771
|
-
};
|
|
3772
|
-
Spinner = React79__namespace.default.forwardRef(
|
|
3773
|
-
({ className, size = "md", ...props }, ref) => {
|
|
3774
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3775
|
-
"div",
|
|
3776
|
-
{
|
|
3777
|
-
ref,
|
|
3778
|
-
className: cn("text-foreground", className),
|
|
3779
|
-
...props,
|
|
3780
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "loader", className: cn("animate-spin", sizeStyles4[size]) })
|
|
3781
|
-
}
|
|
3782
|
-
);
|
|
3783
|
-
}
|
|
3784
|
-
);
|
|
3785
|
-
Spinner.displayName = "Spinner";
|
|
3786
|
-
}
|
|
3787
|
-
});
|
|
3788
3970
|
function generateInitials(name) {
|
|
3789
3971
|
const parts = name.trim().split(/\s+/);
|
|
3790
3972
|
if (parts.length === 1) {
|
|
@@ -16082,30 +16264,30 @@ var init_BranchingLogicBuilder = __esm({
|
|
|
16082
16264
|
if (!sourceQuestion?.optionValues) return [];
|
|
16083
16265
|
return sourceQuestion.optionValues.map((v) => ({ value: v, label: v }));
|
|
16084
16266
|
}, [sourceQuestion]);
|
|
16085
|
-
const handleSource = (
|
|
16086
|
-
onChange({ ...rule, sourceQuestionId:
|
|
16267
|
+
const handleSource = (v) => {
|
|
16268
|
+
onChange({ ...rule, sourceQuestionId: v });
|
|
16087
16269
|
};
|
|
16088
|
-
const handleOperator = (
|
|
16089
|
-
const next =
|
|
16270
|
+
const handleOperator = (v) => {
|
|
16271
|
+
const next = v;
|
|
16090
16272
|
const nextValue = next === "in" && !Array.isArray(rule.value) ? rule.value ? [rule.value] : [] : next !== "in" && Array.isArray(rule.value) ? rule.value[0] ?? "" : rule.value;
|
|
16091
16273
|
onChange({ ...rule, operator: next, value: nextValue });
|
|
16092
16274
|
};
|
|
16093
16275
|
const handleScalarValue = (e) => {
|
|
16094
16276
|
onChange({ ...rule, value: e.target.value });
|
|
16095
16277
|
};
|
|
16096
|
-
const handleAddChip = (
|
|
16097
|
-
const
|
|
16098
|
-
if (!
|
|
16278
|
+
const handleAddChip = (v) => {
|
|
16279
|
+
const val = v;
|
|
16280
|
+
if (!val) return;
|
|
16099
16281
|
const current = Array.isArray(rule.value) ? rule.value : [];
|
|
16100
|
-
if (current.includes(
|
|
16101
|
-
onChange({ ...rule, value: [...current,
|
|
16282
|
+
if (current.includes(val)) return;
|
|
16283
|
+
onChange({ ...rule, value: [...current, val] });
|
|
16102
16284
|
};
|
|
16103
16285
|
const handleRemoveChip = (chip) => {
|
|
16104
16286
|
const current = Array.isArray(rule.value) ? rule.value : [];
|
|
16105
16287
|
onChange({ ...rule, value: current.filter((c) => c !== chip) });
|
|
16106
16288
|
};
|
|
16107
|
-
const handleTarget = (
|
|
16108
|
-
onChange({ ...rule, targetQuestionId:
|
|
16289
|
+
const handleTarget = (v) => {
|
|
16290
|
+
onChange({ ...rule, targetQuestionId: v });
|
|
16109
16291
|
};
|
|
16110
16292
|
const isMulti = rule.operator === "in";
|
|
16111
16293
|
const chips = Array.isArray(rule.value) ? rule.value : [];
|
|
@@ -16186,7 +16368,7 @@ var init_BranchingLogicBuilder = __esm({
|
|
|
16186
16368
|
options: valueOptions,
|
|
16187
16369
|
value: scalarValue,
|
|
16188
16370
|
placeholder: t("branchingLogic.selectValue"),
|
|
16189
|
-
onChange: (
|
|
16371
|
+
onChange: (v) => onChange({ ...rule, value: v }),
|
|
16190
16372
|
disabled: readOnly
|
|
16191
16373
|
}
|
|
16192
16374
|
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -18618,7 +18800,7 @@ var init_Pagination = __esm({
|
|
|
18618
18800
|
Select,
|
|
18619
18801
|
{
|
|
18620
18802
|
value: String(pageSize),
|
|
18621
|
-
onChange: (
|
|
18803
|
+
onChange: (v) => handlePageSizeChange(Number(v)),
|
|
18622
18804
|
options: pageSizeOptions.map((size) => ({
|
|
18623
18805
|
value: String(size),
|
|
18624
18806
|
label: String(size)
|
|
@@ -21544,7 +21726,84 @@ var init_DashboardLayout = __esm({
|
|
|
21544
21726
|
NavLinkBottom.displayName = "NavLinkBottom";
|
|
21545
21727
|
}
|
|
21546
21728
|
});
|
|
21547
|
-
|
|
21729
|
+
function computeMenuStyle(position, triggerRect) {
|
|
21730
|
+
const isTop = position.startsWith("top");
|
|
21731
|
+
const isRight = position.endsWith("right") || position.endsWith("end");
|
|
21732
|
+
if (isTop) {
|
|
21733
|
+
return {
|
|
21734
|
+
top: triggerRect.top - MENU_GAP,
|
|
21735
|
+
transform: "translateY(-100%)",
|
|
21736
|
+
...isRight ? { right: window.innerWidth - triggerRect.right } : { left: triggerRect.left }
|
|
21737
|
+
};
|
|
21738
|
+
}
|
|
21739
|
+
return {
|
|
21740
|
+
top: triggerRect.bottom + MENU_GAP,
|
|
21741
|
+
...isRight ? { right: window.innerWidth - triggerRect.right } : { left: triggerRect.left }
|
|
21742
|
+
};
|
|
21743
|
+
}
|
|
21744
|
+
function SubMenu({
|
|
21745
|
+
items,
|
|
21746
|
+
itemRef,
|
|
21747
|
+
direction,
|
|
21748
|
+
eventBus
|
|
21749
|
+
}) {
|
|
21750
|
+
const [rect, setRect] = React79.useState(null);
|
|
21751
|
+
React79.useEffect(() => {
|
|
21752
|
+
if (itemRef) {
|
|
21753
|
+
setRect(itemRef.getBoundingClientRect());
|
|
21754
|
+
}
|
|
21755
|
+
}, [itemRef]);
|
|
21756
|
+
if (!rect) return null;
|
|
21757
|
+
const isRtl = direction === "rtl";
|
|
21758
|
+
const style = {
|
|
21759
|
+
top: rect.top,
|
|
21760
|
+
...isRtl ? { right: window.innerWidth - rect.left } : { left: rect.right }
|
|
21761
|
+
};
|
|
21762
|
+
const panel = /* @__PURE__ */ jsxRuntime.jsx(
|
|
21763
|
+
"div",
|
|
21764
|
+
{
|
|
21765
|
+
className: cn("fixed z-50", menuContainerStyles),
|
|
21766
|
+
style,
|
|
21767
|
+
children: items.map((item, index) => {
|
|
21768
|
+
const isDivider = item.id === "divider" || item.label === "divider";
|
|
21769
|
+
const itemId = item.id ?? `item-${item.label.toLowerCase().replace(/\s+/g, "-")}-${index}`;
|
|
21770
|
+
const isDanger = item.variant === "danger";
|
|
21771
|
+
if (isDivider) {
|
|
21772
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Divider, { className: "my-1" }, `divider-${index}`);
|
|
21773
|
+
}
|
|
21774
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
21775
|
+
Box,
|
|
21776
|
+
{
|
|
21777
|
+
as: "button",
|
|
21778
|
+
onClick: () => {
|
|
21779
|
+
if (item.disabled) return;
|
|
21780
|
+
if (item.event) eventBus.emit(`UI:${item.event}`, { itemId, label: item.label });
|
|
21781
|
+
item.onClick?.();
|
|
21782
|
+
},
|
|
21783
|
+
"aria-disabled": item.disabled || void 0,
|
|
21784
|
+
"data-testid": item.event ? `action-${item.event}` : void 0,
|
|
21785
|
+
className: cn(
|
|
21786
|
+
"w-full flex items-center gap-3 px-4 py-2 text-start",
|
|
21787
|
+
"text-sm transition-colors",
|
|
21788
|
+
"hover:bg-muted focus:outline-none focus:bg-muted",
|
|
21789
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
21790
|
+
item.disabled && "cursor-not-allowed",
|
|
21791
|
+
isDanger && "text-error hover:bg-error/10"
|
|
21792
|
+
),
|
|
21793
|
+
children: [
|
|
21794
|
+
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" })),
|
|
21795
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", className: cn("flex-1", isDanger && "text-red-600"), children: item.label }),
|
|
21796
|
+
item.badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto text-xs font-medium", children: item.badge })
|
|
21797
|
+
]
|
|
21798
|
+
},
|
|
21799
|
+
itemId
|
|
21800
|
+
);
|
|
21801
|
+
})
|
|
21802
|
+
}
|
|
21803
|
+
);
|
|
21804
|
+
return typeof document !== "undefined" ? reactDom.createPortal(panel, document.body) : panel;
|
|
21805
|
+
}
|
|
21806
|
+
var MENU_GAP, menuContainerStyles, Menu;
|
|
21548
21807
|
var init_Menu = __esm({
|
|
21549
21808
|
"components/core/molecules/Menu.tsx"() {
|
|
21550
21809
|
"use client";
|
|
@@ -21555,16 +21814,27 @@ var init_Menu = __esm({
|
|
|
21555
21814
|
init_Badge();
|
|
21556
21815
|
init_cn();
|
|
21557
21816
|
init_useEventBus();
|
|
21817
|
+
MENU_GAP = 4;
|
|
21818
|
+
menuContainerStyles = cn(
|
|
21819
|
+
"bg-card",
|
|
21820
|
+
"border-[length:var(--border-width)] border-border",
|
|
21821
|
+
"shadow-elevation-popover",
|
|
21822
|
+
"rounded-sm",
|
|
21823
|
+
"min-w-0 sm:min-w-[200px] max-w-[calc(100vw-1rem)] py-1"
|
|
21824
|
+
);
|
|
21558
21825
|
Menu = ({
|
|
21559
21826
|
trigger,
|
|
21560
21827
|
items,
|
|
21561
21828
|
position = "bottom-left",
|
|
21562
|
-
className
|
|
21829
|
+
className,
|
|
21830
|
+
header,
|
|
21831
|
+
footer
|
|
21563
21832
|
}) => {
|
|
21564
21833
|
const eventBus = useEventBus();
|
|
21565
|
-
const {
|
|
21834
|
+
const { direction } = hooks.useTranslate();
|
|
21566
21835
|
const [isOpen, setIsOpen] = React79.useState(false);
|
|
21567
21836
|
const [activeSubMenu, setActiveSubMenu] = React79.useState(null);
|
|
21837
|
+
const [activeSubMenuRef, setActiveSubMenuRef] = React79.useState(null);
|
|
21568
21838
|
const [triggerRect, setTriggerRect] = React79.useState(null);
|
|
21569
21839
|
const triggerRef = React79.useRef(null);
|
|
21570
21840
|
const menuRef = React79.useRef(null);
|
|
@@ -21579,13 +21849,14 @@ var init_Menu = __esm({
|
|
|
21579
21849
|
}
|
|
21580
21850
|
setIsOpen(!isOpen);
|
|
21581
21851
|
setActiveSubMenu(null);
|
|
21852
|
+
setActiveSubMenuRef(null);
|
|
21582
21853
|
};
|
|
21583
|
-
const handleItemClick = (item) => {
|
|
21854
|
+
const handleItemClick = (item, itemId) => {
|
|
21584
21855
|
if (item.disabled) return;
|
|
21585
21856
|
if (item.subMenu && item.subMenu.length > 0) {
|
|
21586
|
-
setActiveSubMenu(
|
|
21857
|
+
setActiveSubMenu(itemId);
|
|
21587
21858
|
} else {
|
|
21588
|
-
if (item.event) eventBus.emit(`UI:${item.event}`, { itemId
|
|
21859
|
+
if (item.event) eventBus.emit(`UI:${item.event}`, { itemId, label: item.label });
|
|
21589
21860
|
item.onClick?.();
|
|
21590
21861
|
setIsOpen(false);
|
|
21591
21862
|
}
|
|
@@ -21600,22 +21871,12 @@ var init_Menu = __esm({
|
|
|
21600
21871
|
if (isOpen && menuRef.current && !menuRef.current.contains(e.target) && triggerRef.current && !triggerRef.current.contains(e.target)) {
|
|
21601
21872
|
setIsOpen(false);
|
|
21602
21873
|
setActiveSubMenu(null);
|
|
21874
|
+
setActiveSubMenuRef(null);
|
|
21603
21875
|
}
|
|
21604
21876
|
};
|
|
21605
21877
|
document.addEventListener("mousedown", handleClickOutside);
|
|
21606
21878
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
21607
21879
|
}, [isOpen]);
|
|
21608
|
-
const positionClasses = {
|
|
21609
|
-
"top-left": "bottom-full left-0 mb-2",
|
|
21610
|
-
"top-right": "bottom-full right-0 mb-2",
|
|
21611
|
-
"bottom-left": "top-full left-0 mt-2",
|
|
21612
|
-
"bottom-right": "top-full right-0 mt-2",
|
|
21613
|
-
// Aliases for pattern compatibility
|
|
21614
|
-
"top-start": "bottom-full left-0 mb-2",
|
|
21615
|
-
"top-end": "bottom-full right-0 mb-2",
|
|
21616
|
-
"bottom-start": "top-full left-0 mt-2",
|
|
21617
|
-
"bottom-end": "top-full right-0 mt-2"
|
|
21618
|
-
};
|
|
21619
21880
|
const rtlMirror = {
|
|
21620
21881
|
"top-left": "top-right",
|
|
21621
21882
|
"top-right": "top-left",
|
|
@@ -21627,7 +21888,6 @@ var init_Menu = __esm({
|
|
|
21627
21888
|
"bottom-end": "bottom-start"
|
|
21628
21889
|
};
|
|
21629
21890
|
const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
|
|
21630
|
-
const subMenuSideClass = direction === "rtl" ? "right-full mr-2" : "left-full ml-2";
|
|
21631
21891
|
const triggerChild = React79__namespace.default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", as: "span", children: trigger });
|
|
21632
21892
|
const triggerElement = React79__namespace.default.cloneElement(
|
|
21633
21893
|
triggerChild,
|
|
@@ -21636,94 +21896,87 @@ var init_Menu = __esm({
|
|
|
21636
21896
|
onClick: handleToggle
|
|
21637
21897
|
}
|
|
21638
21898
|
);
|
|
21639
|
-
const
|
|
21640
|
-
"
|
|
21641
|
-
"border-[length:var(--border-width)] border-border",
|
|
21642
|
-
"shadow-elevation-popover",
|
|
21643
|
-
"rounded-sm",
|
|
21644
|
-
"min-w-0 sm:min-w-[200px] max-w-[calc(100vw-1rem)] py-1"
|
|
21645
|
-
);
|
|
21646
|
-
const renderMenuItem = (item, hasSubMenu, index) => {
|
|
21899
|
+
const renderMenuItems = (menuItems) => menuItems.map((item, index) => {
|
|
21900
|
+
const isDivider = item.id === "divider" || item.label === "divider";
|
|
21647
21901
|
const itemId = item.id ?? `item-${item.label.toLowerCase().replace(/\s+/g, "-")}-${index}`;
|
|
21902
|
+
const hasSubMenu = !!(item.subMenu && item.subMenu.length > 0);
|
|
21648
21903
|
const isDanger = item.variant === "danger";
|
|
21649
|
-
|
|
21650
|
-
|
|
21651
|
-
|
|
21652
|
-
|
|
21653
|
-
|
|
21654
|
-
|
|
21655
|
-
|
|
21656
|
-
|
|
21657
|
-
|
|
21658
|
-
"
|
|
21659
|
-
|
|
21660
|
-
|
|
21661
|
-
|
|
21662
|
-
|
|
21663
|
-
item.disabled && "cursor-not-allowed",
|
|
21664
|
-
isDanger && "text-error hover:bg-error/10"
|
|
21665
|
-
),
|
|
21666
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "flex items-center gap-3 flex-1 min-w-0", children: [
|
|
21667
|
-
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" })),
|
|
21668
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21669
|
-
Typography,
|
|
21670
|
-
{
|
|
21671
|
-
variant: "small",
|
|
21672
|
-
className: cn("flex-1", isDanger && "text-red-600"),
|
|
21673
|
-
children: item.label
|
|
21904
|
+
if (isDivider) {
|
|
21905
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Divider, { className: "my-1" }, `divider-${index}`);
|
|
21906
|
+
}
|
|
21907
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Box, { children: [
|
|
21908
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21909
|
+
Box,
|
|
21910
|
+
{
|
|
21911
|
+
as: "button",
|
|
21912
|
+
onClick: () => handleItemClick({ ...item, id: itemId }, itemId),
|
|
21913
|
+
"aria-disabled": item.disabled || void 0,
|
|
21914
|
+
onMouseEnter: (e) => {
|
|
21915
|
+
if (hasSubMenu) {
|
|
21916
|
+
setActiveSubMenu(itemId);
|
|
21917
|
+
setActiveSubMenuRef(e.currentTarget);
|
|
21674
21918
|
}
|
|
21919
|
+
},
|
|
21920
|
+
"data-testid": item.event ? `action-${item.event}` : void 0,
|
|
21921
|
+
className: cn(
|
|
21922
|
+
"w-full flex items-center justify-between gap-3 px-4 py-2 text-start",
|
|
21923
|
+
"text-sm transition-colors",
|
|
21924
|
+
"hover:bg-muted",
|
|
21925
|
+
"focus:outline-none focus:bg-muted",
|
|
21926
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
21927
|
+
item.disabled && "cursor-not-allowed",
|
|
21928
|
+
isDanger && "text-error hover:bg-error/10"
|
|
21675
21929
|
),
|
|
21676
|
-
|
|
21677
|
-
|
|
21678
|
-
|
|
21679
|
-
|
|
21680
|
-
|
|
21681
|
-
|
|
21682
|
-
|
|
21683
|
-
|
|
21684
|
-
|
|
21685
|
-
const hasSubMenu = item.subMenu && item.subMenu.length > 0;
|
|
21686
|
-
const isDivider = item.id === "divider" || item.label === "divider";
|
|
21687
|
-
const itemId = item.id ?? `item-${item.label.toLowerCase().replace(/\s+/g, "-")}-${index}`;
|
|
21688
|
-
if (isDivider) {
|
|
21689
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Divider, { className: "my-1" }, `divider-${index}`);
|
|
21690
|
-
}
|
|
21691
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(Box, { children: [
|
|
21692
|
-
renderMenuItem(item, !!hasSubMenu, index),
|
|
21693
|
-
hasSubMenu && activeSubMenu === itemId && item.subMenu && /* @__PURE__ */ jsxRuntime.jsx(
|
|
21694
|
-
Box,
|
|
21695
|
-
{
|
|
21696
|
-
className: cn(
|
|
21697
|
-
"absolute top-0 z-50",
|
|
21698
|
-
subMenuSideClass,
|
|
21699
|
-
menuContainerStyles
|
|
21930
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "flex items-center gap-3 flex-1 min-w-0", children: [
|
|
21931
|
+
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" })),
|
|
21932
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21933
|
+
Typography,
|
|
21934
|
+
{
|
|
21935
|
+
variant: "small",
|
|
21936
|
+
className: cn("flex-1", isDanger && "text-red-600"),
|
|
21937
|
+
children: item.label
|
|
21938
|
+
}
|
|
21700
21939
|
),
|
|
21701
|
-
children:
|
|
21702
|
-
|
|
21703
|
-
|
|
21704
|
-
|
|
21705
|
-
|
|
21706
|
-
|
|
21707
|
-
|
|
21940
|
+
item.badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "default", size: "sm", children: item.badge }),
|
|
21941
|
+
hasSubMenu && /* @__PURE__ */ jsxRuntime.jsx(
|
|
21942
|
+
Icon,
|
|
21943
|
+
{
|
|
21944
|
+
name: direction === "rtl" ? "chevron-left" : "chevron-right",
|
|
21945
|
+
size: "sm",
|
|
21946
|
+
className: "flex-shrink-0"
|
|
21947
|
+
}
|
|
21948
|
+
)
|
|
21949
|
+
] })
|
|
21950
|
+
}
|
|
21951
|
+
),
|
|
21952
|
+
hasSubMenu && activeSubMenu === itemId && item.subMenu && /* @__PURE__ */ jsxRuntime.jsx(
|
|
21953
|
+
SubMenu,
|
|
21954
|
+
{
|
|
21955
|
+
items: item.subMenu,
|
|
21956
|
+
itemRef: activeSubMenuRef,
|
|
21957
|
+
direction,
|
|
21958
|
+
eventBus
|
|
21959
|
+
}
|
|
21960
|
+
)
|
|
21961
|
+
] }, itemId);
|
|
21962
|
+
});
|
|
21963
|
+
const panel = isOpen && triggerRect ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
21964
|
+
"div",
|
|
21965
|
+
{
|
|
21966
|
+
ref: menuRef,
|
|
21967
|
+
className: cn("fixed z-50", menuContainerStyles, className),
|
|
21968
|
+
style: computeMenuStyle(effectivePosition, triggerRect),
|
|
21969
|
+
role: "menu",
|
|
21970
|
+
children: [
|
|
21971
|
+
header && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-2 border-b border-border", children: header }),
|
|
21972
|
+
renderMenuItems(items),
|
|
21973
|
+
footer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-2 border-t border-border", children: footer })
|
|
21974
|
+
]
|
|
21975
|
+
}
|
|
21976
|
+
) : null;
|
|
21977
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
21708
21978
|
triggerElement,
|
|
21709
|
-
|
|
21710
|
-
Box,
|
|
21711
|
-
{
|
|
21712
|
-
ref: menuRef,
|
|
21713
|
-
className: cn(
|
|
21714
|
-
"absolute z-50",
|
|
21715
|
-
menuContainerStyles,
|
|
21716
|
-
positionClasses[effectivePosition],
|
|
21717
|
-
className
|
|
21718
|
-
),
|
|
21719
|
-
style: {
|
|
21720
|
-
left: effectivePosition.includes("left") ? 0 : "auto",
|
|
21721
|
-
right: effectivePosition.includes("right") ? 0 : "auto"
|
|
21722
|
-
},
|
|
21723
|
-
role: "menu",
|
|
21724
|
-
children: renderMenuItems(items)
|
|
21725
|
-
}
|
|
21726
|
-
)
|
|
21979
|
+
panel && typeof document !== "undefined" ? reactDom.createPortal(panel, document.body) : panel
|
|
21727
21980
|
] });
|
|
21728
21981
|
};
|
|
21729
21982
|
Menu.displayName = "Menu";
|
|
@@ -23477,7 +23730,7 @@ var init_FilterGroup = __esm({
|
|
|
23477
23730
|
Select,
|
|
23478
23731
|
{
|
|
23479
23732
|
value: selectedValues[filter.field] || "all",
|
|
23480
|
-
onChange: (
|
|
23733
|
+
onChange: (v) => handleFilterSelect(filter.field, v),
|
|
23481
23734
|
options: [
|
|
23482
23735
|
{ value: "all", label: t("filterGroup.all") },
|
|
23483
23736
|
...filter.options?.map((opt) => ({
|
|
@@ -23560,7 +23813,7 @@ var init_FilterGroup = __esm({
|
|
|
23560
23813
|
Select,
|
|
23561
23814
|
{
|
|
23562
23815
|
value: selectedValues[filter.field] || "all",
|
|
23563
|
-
onChange: (
|
|
23816
|
+
onChange: (v) => handleFilterSelect(filter.field, v),
|
|
23564
23817
|
options: [
|
|
23565
23818
|
{ value: "all", label: t("filterGroup.allOf", { label: filter.label }) },
|
|
23566
23819
|
...filter.options?.map((opt) => ({
|
|
@@ -23678,7 +23931,7 @@ var init_FilterGroup = __esm({
|
|
|
23678
23931
|
Select,
|
|
23679
23932
|
{
|
|
23680
23933
|
value: selectedValues[filter.field] || "all",
|
|
23681
|
-
onChange: (
|
|
23934
|
+
onChange: (v) => handleFilterSelect(filter.field, v),
|
|
23682
23935
|
options: [
|
|
23683
23936
|
{ value: "all", label: t("filterGroup.all") },
|
|
23684
23937
|
...filter.options?.map((opt) => ({
|
|
@@ -27860,13 +28113,13 @@ var init_MapView = __esm({
|
|
|
27860
28113
|
shadowSize: [41, 41]
|
|
27861
28114
|
});
|
|
27862
28115
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
27863
|
-
const { useEffect:
|
|
28116
|
+
const { useEffect: useEffect73, useRef: useRef67, useCallback: useCallback112, useState: useState103 } = React79__namespace.default;
|
|
27864
28117
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
27865
28118
|
const { useEventBus: useEventBus3 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
27866
28119
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
27867
28120
|
const map = useMap();
|
|
27868
|
-
const prevRef =
|
|
27869
|
-
|
|
28121
|
+
const prevRef = useRef67({ centerLat, centerLng, zoom });
|
|
28122
|
+
useEffect73(() => {
|
|
27870
28123
|
const prev = prevRef.current;
|
|
27871
28124
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
27872
28125
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -27877,7 +28130,7 @@ var init_MapView = __esm({
|
|
|
27877
28130
|
}
|
|
27878
28131
|
function MapClickHandler({ onMapClick }) {
|
|
27879
28132
|
const map = useMap();
|
|
27880
|
-
|
|
28133
|
+
useEffect73(() => {
|
|
27881
28134
|
if (!onMapClick) return;
|
|
27882
28135
|
const handler = (e) => {
|
|
27883
28136
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -27905,7 +28158,7 @@ var init_MapView = __esm({
|
|
|
27905
28158
|
showAttribution = true
|
|
27906
28159
|
}) {
|
|
27907
28160
|
const eventBus = useEventBus3();
|
|
27908
|
-
const [clickedPosition, setClickedPosition] =
|
|
28161
|
+
const [clickedPosition, setClickedPosition] = useState103(null);
|
|
27909
28162
|
const handleMapClick = useCallback112((lat, lng) => {
|
|
27910
28163
|
if (showClickedPin) {
|
|
27911
28164
|
setClickedPosition({ lat, lng });
|
|
@@ -33341,8 +33594,8 @@ var init_VersionDiff = __esm({
|
|
|
33341
33594
|
return { added, removed };
|
|
33342
33595
|
}, [diff]);
|
|
33343
33596
|
const handleBeforeChange = React79.useCallback(
|
|
33344
|
-
(
|
|
33345
|
-
const id =
|
|
33597
|
+
(v) => {
|
|
33598
|
+
const id = v;
|
|
33346
33599
|
setInternalBefore(id);
|
|
33347
33600
|
onSelectBefore?.(id);
|
|
33348
33601
|
if (selectBeforeEvent) eventBus.emit(`UI:${selectBeforeEvent}`, { id });
|
|
@@ -33350,8 +33603,8 @@ var init_VersionDiff = __esm({
|
|
|
33350
33603
|
[onSelectBefore, selectBeforeEvent, eventBus]
|
|
33351
33604
|
);
|
|
33352
33605
|
const handleAfterChange = React79.useCallback(
|
|
33353
|
-
(
|
|
33354
|
-
const id =
|
|
33606
|
+
(v) => {
|
|
33607
|
+
const id = v;
|
|
33355
33608
|
setInternalAfter(id);
|
|
33356
33609
|
onSelectAfter?.(id);
|
|
33357
33610
|
if (selectAfterEvent) eventBus.emit(`UI:${selectAfterEvent}`, { id });
|
|
@@ -36129,7 +36382,6 @@ var init_DocumentViewer = __esm({
|
|
|
36129
36382
|
showPrint = false,
|
|
36130
36383
|
actions,
|
|
36131
36384
|
documents,
|
|
36132
|
-
entity,
|
|
36133
36385
|
isLoading = false,
|
|
36134
36386
|
error,
|
|
36135
36387
|
className
|
|
@@ -37978,11 +38230,11 @@ function RuleEditor({
|
|
|
37978
38230
|
className
|
|
37979
38231
|
}) {
|
|
37980
38232
|
const { t } = hooks.useTranslate();
|
|
37981
|
-
const handleWhenChange = React79.useCallback((
|
|
37982
|
-
onChange({ ...rule, whenEvent:
|
|
38233
|
+
const handleWhenChange = React79.useCallback((v) => {
|
|
38234
|
+
onChange({ ...rule, whenEvent: v });
|
|
37983
38235
|
}, [rule, onChange]);
|
|
37984
|
-
const handleThenChange = React79.useCallback((
|
|
37985
|
-
onChange({ ...rule, thenAction:
|
|
38236
|
+
const handleThenChange = React79.useCallback((v) => {
|
|
38237
|
+
onChange({ ...rule, thenAction: v });
|
|
37986
38238
|
}, [rule, onChange]);
|
|
37987
38239
|
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { className: cn("items-center p-2 rounded-lg bg-muted/50 border border-border", className), gap: "sm", children: [
|
|
37988
38240
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-primary font-bold whitespace-nowrap", children: t("eventHandler.when") }),
|
|
@@ -39058,7 +39310,7 @@ var init_Form = __esm({
|
|
|
39058
39310
|
...commonProps,
|
|
39059
39311
|
options,
|
|
39060
39312
|
value: String(currentValue),
|
|
39061
|
-
onChange: (
|
|
39313
|
+
onChange: (v) => handleChange(fieldName, v),
|
|
39062
39314
|
placeholder: field.placeholder || `Select ${label}...`
|
|
39063
39315
|
}
|
|
39064
39316
|
);
|
|
@@ -42944,7 +43196,7 @@ function TraitSlot({
|
|
|
42944
43196
|
size = "md",
|
|
42945
43197
|
showTooltip = true,
|
|
42946
43198
|
categoryColors,
|
|
42947
|
-
tooltipFrameUrl,
|
|
43199
|
+
tooltipFrameUrl = "",
|
|
42948
43200
|
className,
|
|
42949
43201
|
feedback,
|
|
42950
43202
|
onItemDrop,
|
|
@@ -45845,18 +46097,32 @@ var init_WorldMapTemplate = __esm({
|
|
|
45845
46097
|
}
|
|
45846
46098
|
});
|
|
45847
46099
|
function lazyThree(name, loader) {
|
|
45848
|
-
const Lazy = React79__namespace.default.lazy(
|
|
46100
|
+
const Lazy = React79__namespace.default.lazy(
|
|
46101
|
+
() => loader().then((m) => {
|
|
46102
|
+
const Resolved = m[name];
|
|
46103
|
+
if (!Resolved) {
|
|
46104
|
+
throw new Error(
|
|
46105
|
+
`[@almadar/ui] 3D component "${name}" was not found in the three subpath bundle.`
|
|
46106
|
+
);
|
|
46107
|
+
}
|
|
46108
|
+
return { default: Resolved };
|
|
46109
|
+
})
|
|
46110
|
+
);
|
|
45849
46111
|
function ThreeWrapper(props) {
|
|
45850
46112
|
return React79__namespace.default.createElement(
|
|
45851
|
-
|
|
45852
|
-
{
|
|
45853
|
-
React79__namespace.default.createElement(
|
|
46113
|
+
ThreeBoundary,
|
|
46114
|
+
{ name },
|
|
46115
|
+
React79__namespace.default.createElement(
|
|
46116
|
+
React79__namespace.default.Suspense,
|
|
46117
|
+
{ fallback: null },
|
|
46118
|
+
React79__namespace.default.createElement(Lazy, props)
|
|
46119
|
+
)
|
|
45854
46120
|
);
|
|
45855
46121
|
}
|
|
45856
46122
|
ThreeWrapper.displayName = `Lazy(${name})`;
|
|
45857
46123
|
return ThreeWrapper;
|
|
45858
46124
|
}
|
|
45859
|
-
var FeatureRenderer, GameCanvas3D, GameCanvas3DBattleTemplate, GameCanvas3DCastleTemplate, GameCanvas3DWorldMapTemplate, COMPONENT_REGISTRY;
|
|
46125
|
+
var ThreeBoundary, FeatureRenderer, GameCanvas3D, GameCanvas3DBattleTemplate, GameCanvas3DCastleTemplate, GameCanvas3DWorldMapTemplate, COMPONENT_REGISTRY;
|
|
45860
46126
|
var init_component_registry_generated = __esm({
|
|
45861
46127
|
"components/core/organisms/component-registry.generated.ts"() {
|
|
45862
46128
|
init_AboutPageTemplate();
|
|
@@ -46142,6 +46408,28 @@ var init_component_registry_generated = __esm({
|
|
|
46142
46408
|
init_WorldMapBoard();
|
|
46143
46409
|
init_WorldMapTemplate();
|
|
46144
46410
|
init_XPBar();
|
|
46411
|
+
ThreeBoundary = class extends React79__namespace.default.Component {
|
|
46412
|
+
constructor() {
|
|
46413
|
+
super(...arguments);
|
|
46414
|
+
__publicField(this, "state", { failed: false });
|
|
46415
|
+
}
|
|
46416
|
+
static getDerivedStateFromError() {
|
|
46417
|
+
return { failed: true };
|
|
46418
|
+
}
|
|
46419
|
+
render() {
|
|
46420
|
+
if (this.state.failed) {
|
|
46421
|
+
return React79__namespace.default.createElement(
|
|
46422
|
+
"div",
|
|
46423
|
+
{
|
|
46424
|
+
"data-testid": "three-unavailable",
|
|
46425
|
+
style: { padding: 16, fontSize: 13, lineHeight: 1.5, opacity: 0.7 }
|
|
46426
|
+
},
|
|
46427
|
+
`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.`
|
|
46428
|
+
);
|
|
46429
|
+
}
|
|
46430
|
+
return this.props.children;
|
|
46431
|
+
}
|
|
46432
|
+
};
|
|
46145
46433
|
FeatureRenderer = lazyThree("FeatureRenderer", () => import('@almadar/ui/components/molecules/game/three'));
|
|
46146
46434
|
GameCanvas3D = lazyThree("GameCanvas3D", () => import('@almadar/ui/components/molecules/game/three'));
|
|
46147
46435
|
GameCanvas3DBattleTemplate = lazyThree("GameCanvas3DBattleTemplate", () => import('@almadar/ui/components/molecules/game/three'));
|