@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
|
@@ -45,7 +45,6 @@ var utilities = require('@dnd-kit/utilities');
|
|
|
45
45
|
var react = require('@xyflow/react');
|
|
46
46
|
var context = require('@almadar/ui/context');
|
|
47
47
|
var patterns = require('@almadar/patterns');
|
|
48
|
-
var fiber = require('@react-three/fiber');
|
|
49
48
|
|
|
50
49
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
51
50
|
|
|
@@ -2187,6 +2186,8 @@ var init_Input = __esm({
|
|
|
2187
2186
|
className,
|
|
2188
2187
|
inputType,
|
|
2189
2188
|
type: htmlType,
|
|
2189
|
+
label,
|
|
2190
|
+
helperText,
|
|
2190
2191
|
error,
|
|
2191
2192
|
leftIcon,
|
|
2192
2193
|
rightIcon,
|
|
@@ -2242,82 +2243,95 @@ var init_Input = __esm({
|
|
|
2242
2243
|
onClear?.();
|
|
2243
2244
|
}
|
|
2244
2245
|
};
|
|
2246
|
+
const wrapField = (field) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", children: [
|
|
2247
|
+
label && /* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-sm font-medium text-foreground mb-1", children: label }),
|
|
2248
|
+
field,
|
|
2249
|
+
(helperText || error) && /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("mt-1 text-xs", error ? "text-error" : "text-muted-foreground"), children: error ?? helperText })
|
|
2250
|
+
] });
|
|
2245
2251
|
if (type === "select") {
|
|
2246
|
-
return
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2252
|
+
return wrapField(
|
|
2253
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full", children: [
|
|
2254
|
+
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 }),
|
|
2255
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2256
|
+
"select",
|
|
2257
|
+
{
|
|
2258
|
+
ref,
|
|
2259
|
+
value,
|
|
2260
|
+
onChange: handleChange,
|
|
2261
|
+
className: cn(baseClassName, "appearance-none pr-10", className),
|
|
2262
|
+
...props,
|
|
2263
|
+
children: [
|
|
2264
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: t("form.selectPlaceholder", { label: "" }) }),
|
|
2265
|
+
options?.map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: opt.value, children: opt.label }, opt.value))
|
|
2266
|
+
]
|
|
2267
|
+
}
|
|
2268
|
+
),
|
|
2269
|
+
/* @__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(exports.Icon, { name: "chevron-down", className: "h-icon-default w-icon-default" }) })
|
|
2270
|
+
] })
|
|
2271
|
+
);
|
|
2272
|
+
}
|
|
2273
|
+
if (type === "textarea") {
|
|
2274
|
+
return wrapField(
|
|
2275
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2276
|
+
"textarea",
|
|
2250
2277
|
{
|
|
2251
2278
|
ref,
|
|
2252
2279
|
value,
|
|
2253
2280
|
onChange: handleChange,
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: t("form.selectPlaceholder", { label: "" }) }),
|
|
2258
|
-
options?.map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: opt.value, children: opt.label }, opt.value))
|
|
2259
|
-
]
|
|
2281
|
+
rows: rows2,
|
|
2282
|
+
className: baseClassName,
|
|
2283
|
+
...props
|
|
2260
2284
|
}
|
|
2261
|
-
)
|
|
2262
|
-
|
|
2263
|
-
] });
|
|
2264
|
-
}
|
|
2265
|
-
if (type === "textarea") {
|
|
2266
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2267
|
-
"textarea",
|
|
2268
|
-
{
|
|
2269
|
-
ref,
|
|
2270
|
-
value,
|
|
2271
|
-
onChange: handleChange,
|
|
2272
|
-
rows: rows2,
|
|
2273
|
-
className: baseClassName,
|
|
2274
|
-
...props
|
|
2275
|
-
}
|
|
2276
|
-
) });
|
|
2285
|
+
) })
|
|
2286
|
+
);
|
|
2277
2287
|
}
|
|
2278
2288
|
if (type === "checkbox") {
|
|
2279
|
-
return
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2289
|
+
return wrapField(
|
|
2290
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2291
|
+
"input",
|
|
2292
|
+
{
|
|
2293
|
+
ref,
|
|
2294
|
+
type: "checkbox",
|
|
2295
|
+
checked: props.checked,
|
|
2296
|
+
onChange: handleChange,
|
|
2297
|
+
className: cn(
|
|
2298
|
+
"h-icon-default w-icon-default rounded-sm",
|
|
2299
|
+
"border-border",
|
|
2300
|
+
"text-primary focus:ring-ring",
|
|
2301
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
2302
|
+
className
|
|
2303
|
+
),
|
|
2304
|
+
...props
|
|
2305
|
+
}
|
|
2306
|
+
)
|
|
2295
2307
|
);
|
|
2296
2308
|
}
|
|
2297
|
-
return
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2309
|
+
return wrapField(
|
|
2310
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full", children: [
|
|
2311
|
+
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 }),
|
|
2312
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2313
|
+
"input",
|
|
2314
|
+
{
|
|
2315
|
+
ref,
|
|
2316
|
+
type,
|
|
2317
|
+
value,
|
|
2318
|
+
onChange: handleChange,
|
|
2319
|
+
className: baseClassName,
|
|
2320
|
+
...props
|
|
2321
|
+
}
|
|
2322
|
+
),
|
|
2323
|
+
showClearButton && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2324
|
+
"button",
|
|
2325
|
+
{
|
|
2326
|
+
type: "button",
|
|
2327
|
+
onClick: handleClear,
|
|
2328
|
+
className: "absolute inset-y-0 right-0 pr-3 flex items-center text-muted-foreground hover:text-foreground",
|
|
2329
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "x", className: "h-icon-default w-icon-default" })
|
|
2330
|
+
}
|
|
2331
|
+
),
|
|
2332
|
+
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) })
|
|
2333
|
+
] })
|
|
2334
|
+
);
|
|
2321
2335
|
}
|
|
2322
2336
|
);
|
|
2323
2337
|
exports.Input.displayName = "Input";
|
|
@@ -2388,6 +2402,190 @@ var init_Textarea = __esm({
|
|
|
2388
2402
|
exports.Textarea.displayName = "Textarea";
|
|
2389
2403
|
}
|
|
2390
2404
|
});
|
|
2405
|
+
function flatOptions(opts, groups) {
|
|
2406
|
+
const flat = opts ?? [];
|
|
2407
|
+
const grp = (groups ?? []).flatMap((g) => g.options);
|
|
2408
|
+
return [...flat, ...grp];
|
|
2409
|
+
}
|
|
2410
|
+
function NativeSelect({
|
|
2411
|
+
className,
|
|
2412
|
+
options,
|
|
2413
|
+
groups,
|
|
2414
|
+
placeholder,
|
|
2415
|
+
error,
|
|
2416
|
+
onChange,
|
|
2417
|
+
value,
|
|
2418
|
+
...props
|
|
2419
|
+
}) {
|
|
2420
|
+
const eventBus = useEventBus();
|
|
2421
|
+
const handleChange = (e) => {
|
|
2422
|
+
if (typeof onChange === "string") {
|
|
2423
|
+
eventBus.emit(`UI:${onChange}`, { value: e.target.value });
|
|
2424
|
+
} else {
|
|
2425
|
+
onChange?.(e.target.value);
|
|
2426
|
+
}
|
|
2427
|
+
};
|
|
2428
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
2429
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2430
|
+
"select",
|
|
2431
|
+
{
|
|
2432
|
+
onChange: handleChange,
|
|
2433
|
+
value,
|
|
2434
|
+
className: cn(
|
|
2435
|
+
"block w-full border-[length:var(--border-width)] shadow-sm appearance-none",
|
|
2436
|
+
"px-3 py-2 pr-10 text-sm text-foreground font-medium",
|
|
2437
|
+
"bg-card",
|
|
2438
|
+
"focus:outline-none focus:ring-2 focus:ring-offset-0 focus:ring-ring",
|
|
2439
|
+
"disabled:bg-muted disabled:text-muted-foreground disabled:cursor-not-allowed",
|
|
2440
|
+
error ? "border-error focus:border-error" : "border-border focus:border-primary",
|
|
2441
|
+
className
|
|
2442
|
+
),
|
|
2443
|
+
...props,
|
|
2444
|
+
children: [
|
|
2445
|
+
placeholder && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, children: placeholder }),
|
|
2446
|
+
options?.map((option) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: option.value, disabled: option.disabled, children: option.label }, option.value)),
|
|
2447
|
+
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))
|
|
2448
|
+
]
|
|
2449
|
+
}
|
|
2450
|
+
),
|
|
2451
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "chevron-down", className: "h-icon-default w-icon-default text-foreground" }) })
|
|
2452
|
+
] });
|
|
2453
|
+
}
|
|
2454
|
+
function RichSelect({
|
|
2455
|
+
className,
|
|
2456
|
+
options,
|
|
2457
|
+
groups,
|
|
2458
|
+
placeholder,
|
|
2459
|
+
error,
|
|
2460
|
+
onChange,
|
|
2461
|
+
value,
|
|
2462
|
+
multiple,
|
|
2463
|
+
searchable,
|
|
2464
|
+
clearable,
|
|
2465
|
+
disabled
|
|
2466
|
+
}) {
|
|
2467
|
+
const eventBus = useEventBus();
|
|
2468
|
+
const [open, setOpen] = React74.useState(false);
|
|
2469
|
+
const [search, setSearch] = React74.useState("");
|
|
2470
|
+
const containerRef = React74.useRef(null);
|
|
2471
|
+
const selected = multiple ? Array.isArray(value) ? value : value ? [value] : [] : value ? [value] : [];
|
|
2472
|
+
const all = flatOptions(options, groups);
|
|
2473
|
+
const filtered = searchable && search ? all.filter((o) => o.label.toLowerCase().includes(search.toLowerCase())) : all;
|
|
2474
|
+
const toggle = (optValue) => {
|
|
2475
|
+
let next;
|
|
2476
|
+
if (multiple) {
|
|
2477
|
+
next = selected.includes(optValue) ? selected.filter((v) => v !== optValue) : [...selected, optValue];
|
|
2478
|
+
} else {
|
|
2479
|
+
next = optValue;
|
|
2480
|
+
setOpen(false);
|
|
2481
|
+
}
|
|
2482
|
+
if (typeof onChange === "string") {
|
|
2483
|
+
eventBus.emit(`UI:${onChange}`, { value: next });
|
|
2484
|
+
} else {
|
|
2485
|
+
onChange?.(next);
|
|
2486
|
+
}
|
|
2487
|
+
};
|
|
2488
|
+
const clear = (e) => {
|
|
2489
|
+
e.stopPropagation();
|
|
2490
|
+
const next = multiple ? [] : "";
|
|
2491
|
+
if (typeof onChange === "string") {
|
|
2492
|
+
eventBus.emit(`UI:${onChange}`, { value: next });
|
|
2493
|
+
} else {
|
|
2494
|
+
onChange?.(next);
|
|
2495
|
+
}
|
|
2496
|
+
};
|
|
2497
|
+
React74.useEffect(() => {
|
|
2498
|
+
const handler = (e) => {
|
|
2499
|
+
if (containerRef.current && !containerRef.current.contains(e.target)) {
|
|
2500
|
+
setOpen(false);
|
|
2501
|
+
setSearch("");
|
|
2502
|
+
}
|
|
2503
|
+
};
|
|
2504
|
+
document.addEventListener("mousedown", handler);
|
|
2505
|
+
return () => document.removeEventListener("mousedown", handler);
|
|
2506
|
+
}, []);
|
|
2507
|
+
const displayLabel = selected.length === 0 ? placeholder ?? "" : multiple ? `${selected.length} selected` : all.find((o) => o.value === selected[0])?.label ?? selected[0];
|
|
2508
|
+
const hasValue = selected.length > 0;
|
|
2509
|
+
const renderOptions = (opts) => opts.map((opt) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2510
|
+
"button",
|
|
2511
|
+
{
|
|
2512
|
+
type: "button",
|
|
2513
|
+
disabled: opt.disabled,
|
|
2514
|
+
onClick: () => !opt.disabled && toggle(opt.value),
|
|
2515
|
+
className: cn(
|
|
2516
|
+
"w-full flex items-center justify-between px-3 py-1.5 text-sm text-start",
|
|
2517
|
+
"hover:bg-muted transition-colors",
|
|
2518
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
2519
|
+
selected.includes(opt.value) && "text-primary font-medium"
|
|
2520
|
+
),
|
|
2521
|
+
children: [
|
|
2522
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: opt.label }),
|
|
2523
|
+
selected.includes(opt.value) && /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "check", className: "h-icon-default w-icon-default" })
|
|
2524
|
+
]
|
|
2525
|
+
},
|
|
2526
|
+
opt.value
|
|
2527
|
+
));
|
|
2528
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className: cn("relative w-full", className), children: [
|
|
2529
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2530
|
+
"button",
|
|
2531
|
+
{
|
|
2532
|
+
type: "button",
|
|
2533
|
+
disabled,
|
|
2534
|
+
onClick: () => !disabled && setOpen((o) => !o),
|
|
2535
|
+
className: cn(
|
|
2536
|
+
"block w-full border-[length:var(--border-width)] shadow-sm",
|
|
2537
|
+
"px-3 py-2 pr-10 text-sm text-start font-medium",
|
|
2538
|
+
"bg-card rounded-sm",
|
|
2539
|
+
"focus:outline-none focus:ring-2 focus:ring-offset-0 focus:ring-ring",
|
|
2540
|
+
"disabled:bg-muted disabled:text-muted-foreground disabled:cursor-not-allowed",
|
|
2541
|
+
error ? "border-error focus:border-error" : "border-border focus:border-primary",
|
|
2542
|
+
!hasValue && "text-muted-foreground"
|
|
2543
|
+
),
|
|
2544
|
+
children: displayLabel
|
|
2545
|
+
}
|
|
2546
|
+
),
|
|
2547
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-y-0 right-0 pr-3 flex items-center gap-1 pointer-events-none", children: [
|
|
2548
|
+
clearable && hasValue && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2549
|
+
"button",
|
|
2550
|
+
{
|
|
2551
|
+
type: "button",
|
|
2552
|
+
onClick: clear,
|
|
2553
|
+
className: "pointer-events-auto text-muted-foreground hover:text-foreground",
|
|
2554
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "x", className: "h-icon-default w-icon-default" })
|
|
2555
|
+
}
|
|
2556
|
+
),
|
|
2557
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "chevron-down", className: "h-icon-default w-icon-default text-foreground" })
|
|
2558
|
+
] }),
|
|
2559
|
+
open && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(
|
|
2560
|
+
"absolute z-50 mt-1 w-full",
|
|
2561
|
+
"bg-card border-[length:var(--border-width)] border-border",
|
|
2562
|
+
"rounded-sm shadow-elevation-popover py-1 max-h-60 overflow-y-auto"
|
|
2563
|
+
), children: [
|
|
2564
|
+
searchable && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 pb-1 border-b border-border", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2565
|
+
"input",
|
|
2566
|
+
{
|
|
2567
|
+
autoFocus: true,
|
|
2568
|
+
type: "text",
|
|
2569
|
+
value: search,
|
|
2570
|
+
onChange: (e) => setSearch(e.target.value),
|
|
2571
|
+
placeholder: "Search\u2026",
|
|
2572
|
+
className: cn(
|
|
2573
|
+
"w-full px-2 py-1 text-sm bg-transparent",
|
|
2574
|
+
"focus:outline-none text-foreground placeholder:text-muted-foreground"
|
|
2575
|
+
)
|
|
2576
|
+
}
|
|
2577
|
+
) }),
|
|
2578
|
+
groups && groups.length > 0 ? groups.map((g) => {
|
|
2579
|
+
const groupFiltered = searchable && search ? g.options.filter((o) => o.label.toLowerCase().includes(search.toLowerCase())) : g.options;
|
|
2580
|
+
if (groupFiltered.length === 0) return null;
|
|
2581
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2582
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-1 text-xs font-semibold text-muted-foreground uppercase tracking-wide", children: g.label }),
|
|
2583
|
+
renderOptions(groupFiltered)
|
|
2584
|
+
] }, g.label);
|
|
2585
|
+
}) : renderOptions(filtered)
|
|
2586
|
+
] })
|
|
2587
|
+
] });
|
|
2588
|
+
}
|
|
2391
2589
|
exports.Select = void 0;
|
|
2392
2590
|
var init_Select = __esm({
|
|
2393
2591
|
"components/core/atoms/Select.tsx"() {
|
|
@@ -2395,47 +2593,12 @@ var init_Select = __esm({
|
|
|
2395
2593
|
init_Icon();
|
|
2396
2594
|
init_useEventBus();
|
|
2397
2595
|
exports.Select = React74__namespace.default.forwardRef(
|
|
2398
|
-
(
|
|
2399
|
-
const
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
onChange?.(e);
|
|
2405
|
-
}
|
|
2406
|
-
};
|
|
2407
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
2408
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2409
|
-
"select",
|
|
2410
|
-
{
|
|
2411
|
-
ref,
|
|
2412
|
-
onChange: handleChange,
|
|
2413
|
-
className: cn(
|
|
2414
|
-
"block w-full border-[length:var(--border-width)] shadow-sm appearance-none",
|
|
2415
|
-
"px-3 py-2 pr-10 text-sm text-foreground font-medium",
|
|
2416
|
-
"bg-card",
|
|
2417
|
-
"focus:outline-none focus:ring-2 focus:ring-offset-0 focus:ring-ring",
|
|
2418
|
-
"disabled:bg-muted disabled:text-muted-foreground disabled:cursor-not-allowed",
|
|
2419
|
-
error ? "border-error focus:border-error" : "border-border focus:border-primary",
|
|
2420
|
-
className
|
|
2421
|
-
),
|
|
2422
|
-
...props,
|
|
2423
|
-
children: [
|
|
2424
|
-
placeholder && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, children: placeholder }),
|
|
2425
|
-
options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2426
|
-
"option",
|
|
2427
|
-
{
|
|
2428
|
-
value: option.value,
|
|
2429
|
-
disabled: option.disabled,
|
|
2430
|
-
children: option.label
|
|
2431
|
-
},
|
|
2432
|
-
option.value
|
|
2433
|
-
))
|
|
2434
|
-
]
|
|
2435
|
-
}
|
|
2436
|
-
),
|
|
2437
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "chevron-down", className: "h-icon-default w-icon-default text-foreground" }) })
|
|
2438
|
-
] });
|
|
2596
|
+
(props, _ref) => {
|
|
2597
|
+
const { multiple, searchable, clearable } = props;
|
|
2598
|
+
if (multiple || searchable || clearable) {
|
|
2599
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RichSelect, { ...props });
|
|
2600
|
+
}
|
|
2601
|
+
return /* @__PURE__ */ jsxRuntime.jsx(NativeSelect, { ...props });
|
|
2439
2602
|
}
|
|
2440
2603
|
);
|
|
2441
2604
|
exports.Select.displayName = "Select";
|
|
@@ -2489,11 +2652,54 @@ var init_Checkbox = __esm({
|
|
|
2489
2652
|
exports.Checkbox.displayName = "Checkbox";
|
|
2490
2653
|
}
|
|
2491
2654
|
});
|
|
2655
|
+
var sizeStyles2; exports.Spinner = void 0;
|
|
2656
|
+
var init_Spinner = __esm({
|
|
2657
|
+
"components/core/atoms/Spinner.tsx"() {
|
|
2658
|
+
init_cn();
|
|
2659
|
+
init_Icon();
|
|
2660
|
+
sizeStyles2 = {
|
|
2661
|
+
xs: "h-3 w-3",
|
|
2662
|
+
sm: "h-icon-default w-icon-default",
|
|
2663
|
+
md: "h-6 w-6",
|
|
2664
|
+
lg: "h-8 w-8"
|
|
2665
|
+
};
|
|
2666
|
+
exports.Spinner = React74__namespace.default.forwardRef(
|
|
2667
|
+
({ className, size = "md", overlay, ...props }, ref) => {
|
|
2668
|
+
if (overlay) {
|
|
2669
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2670
|
+
"div",
|
|
2671
|
+
{
|
|
2672
|
+
ref,
|
|
2673
|
+
className: cn(
|
|
2674
|
+
"absolute inset-0 z-10 flex items-center justify-center",
|
|
2675
|
+
"bg-background/60 backdrop-blur-sm",
|
|
2676
|
+
className
|
|
2677
|
+
),
|
|
2678
|
+
...props,
|
|
2679
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "loader", className: cn("animate-spin text-foreground", sizeStyles2[size]) })
|
|
2680
|
+
}
|
|
2681
|
+
);
|
|
2682
|
+
}
|
|
2683
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2684
|
+
"div",
|
|
2685
|
+
{
|
|
2686
|
+
ref,
|
|
2687
|
+
className: cn("text-foreground", className),
|
|
2688
|
+
...props,
|
|
2689
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "loader", className: cn("animate-spin", sizeStyles2[size]) })
|
|
2690
|
+
}
|
|
2691
|
+
);
|
|
2692
|
+
}
|
|
2693
|
+
);
|
|
2694
|
+
exports.Spinner.displayName = "Spinner";
|
|
2695
|
+
}
|
|
2696
|
+
});
|
|
2492
2697
|
var variantStyles2, paddingStyles, shadowStyles, lookStyles; exports.Card = void 0; exports.CardHeader = void 0; exports.CardTitle = void 0; exports.CardContent = void 0; exports.CardBody = void 0; exports.CardFooter = void 0;
|
|
2493
2698
|
var init_Card = __esm({
|
|
2494
2699
|
"components/core/atoms/Card.tsx"() {
|
|
2495
2700
|
init_cn();
|
|
2496
2701
|
init_useEventBus();
|
|
2702
|
+
init_Spinner();
|
|
2497
2703
|
variantStyles2 = {
|
|
2498
2704
|
default: [
|
|
2499
2705
|
"bg-card",
|
|
@@ -2558,6 +2764,7 @@ var init_Card = __esm({
|
|
|
2558
2764
|
look = "elevated",
|
|
2559
2765
|
children,
|
|
2560
2766
|
action,
|
|
2767
|
+
loading,
|
|
2561
2768
|
onClick,
|
|
2562
2769
|
...props
|
|
2563
2770
|
}, ref) => {
|
|
@@ -2571,7 +2778,7 @@ var init_Card = __esm({
|
|
|
2571
2778
|
{
|
|
2572
2779
|
ref,
|
|
2573
2780
|
className: cn(
|
|
2574
|
-
"rounded-container",
|
|
2781
|
+
"rounded-container relative",
|
|
2575
2782
|
"transition-all duration-[var(--transition-normal)]",
|
|
2576
2783
|
variantStyles2[variant],
|
|
2577
2784
|
paddingStyles[padding],
|
|
@@ -2582,6 +2789,7 @@ var init_Card = __esm({
|
|
|
2582
2789
|
onClick: handleClick,
|
|
2583
2790
|
...props,
|
|
2584
2791
|
children: [
|
|
2792
|
+
loading && /* @__PURE__ */ jsxRuntime.jsx(exports.Spinner, { overlay: true, size: "md" }),
|
|
2585
2793
|
(title || subtitle) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4", children: [
|
|
2586
2794
|
title && /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg text-card-foreground font-bold", children: title }),
|
|
2587
2795
|
subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-1", children: subtitle })
|
|
@@ -2623,7 +2831,7 @@ var init_Card = __esm({
|
|
|
2623
2831
|
exports.CardFooter.displayName = "CardFooter";
|
|
2624
2832
|
}
|
|
2625
2833
|
});
|
|
2626
|
-
var variantStyles3,
|
|
2834
|
+
var variantStyles3, sizeStyles3; exports.Badge = void 0;
|
|
2627
2835
|
var init_Badge = __esm({
|
|
2628
2836
|
"components/core/atoms/Badge.tsx"() {
|
|
2629
2837
|
init_cn();
|
|
@@ -2660,7 +2868,7 @@ var init_Badge = __esm({
|
|
|
2660
2868
|
"border-[length:var(--border-width-thin)] border-border"
|
|
2661
2869
|
].join(" ")
|
|
2662
2870
|
};
|
|
2663
|
-
|
|
2871
|
+
sizeStyles3 = {
|
|
2664
2872
|
sm: "px-2 py-0.5 text-xs",
|
|
2665
2873
|
md: "px-2.5 py-1 text-sm",
|
|
2666
2874
|
lg: "px-3 py-1.5 text-base"
|
|
@@ -2680,7 +2888,7 @@ var init_Badge = __esm({
|
|
|
2680
2888
|
className: cn(
|
|
2681
2889
|
"inline-flex items-center gap-1 font-bold rounded-sm",
|
|
2682
2890
|
variantStyles3[variant],
|
|
2683
|
-
|
|
2891
|
+
sizeStyles3[size],
|
|
2684
2892
|
onRemove && "pr-1",
|
|
2685
2893
|
className
|
|
2686
2894
|
),
|
|
@@ -2714,7 +2922,7 @@ var init_Badge = __esm({
|
|
|
2714
2922
|
exports.Badge.displayName = "Badge";
|
|
2715
2923
|
}
|
|
2716
2924
|
});
|
|
2717
|
-
var variantStyles4,
|
|
2925
|
+
var variantStyles4, sizeStyles4, iconSizes; exports.FilterPill = void 0;
|
|
2718
2926
|
var init_FilterPill = __esm({
|
|
2719
2927
|
"components/core/atoms/FilterPill.tsx"() {
|
|
2720
2928
|
init_cn();
|
|
@@ -2748,7 +2956,7 @@ var init_FilterPill = __esm({
|
|
|
2748
2956
|
"border-[length:var(--border-width-thin)] border-border"
|
|
2749
2957
|
].join(" ")
|
|
2750
2958
|
};
|
|
2751
|
-
|
|
2959
|
+
sizeStyles4 = {
|
|
2752
2960
|
sm: "px-2 py-0.5 text-xs",
|
|
2753
2961
|
md: "px-2.5 py-1 text-sm",
|
|
2754
2962
|
lg: "px-3 py-1.5 text-base"
|
|
@@ -2792,7 +3000,7 @@ var init_FilterPill = __esm({
|
|
|
2792
3000
|
className: cn(
|
|
2793
3001
|
"inline-flex items-center gap-1 font-bold rounded-pill",
|
|
2794
3002
|
variantStyles4[variant],
|
|
2795
|
-
|
|
3003
|
+
sizeStyles4[size],
|
|
2796
3004
|
(onClick || clickEvent) && "cursor-pointer",
|
|
2797
3005
|
className
|
|
2798
3006
|
),
|
|
@@ -2824,33 +3032,6 @@ var init_FilterPill = __esm({
|
|
|
2824
3032
|
exports.FilterPill.displayName = "FilterPill";
|
|
2825
3033
|
}
|
|
2826
3034
|
});
|
|
2827
|
-
var sizeStyles4; exports.Spinner = void 0;
|
|
2828
|
-
var init_Spinner = __esm({
|
|
2829
|
-
"components/core/atoms/Spinner.tsx"() {
|
|
2830
|
-
init_cn();
|
|
2831
|
-
init_Icon();
|
|
2832
|
-
sizeStyles4 = {
|
|
2833
|
-
xs: "h-3 w-3",
|
|
2834
|
-
sm: "h-icon-default w-icon-default",
|
|
2835
|
-
md: "h-6 w-6",
|
|
2836
|
-
lg: "h-8 w-8"
|
|
2837
|
-
};
|
|
2838
|
-
exports.Spinner = React74__namespace.default.forwardRef(
|
|
2839
|
-
({ className, size = "md", ...props }, ref) => {
|
|
2840
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2841
|
-
"div",
|
|
2842
|
-
{
|
|
2843
|
-
ref,
|
|
2844
|
-
className: cn("text-foreground", className),
|
|
2845
|
-
...props,
|
|
2846
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "loader", className: cn("animate-spin", sizeStyles4[size]) })
|
|
2847
|
-
}
|
|
2848
|
-
);
|
|
2849
|
-
}
|
|
2850
|
-
);
|
|
2851
|
-
exports.Spinner.displayName = "Spinner";
|
|
2852
|
-
}
|
|
2853
|
-
});
|
|
2854
3035
|
function generateInitials(name) {
|
|
2855
3036
|
const parts = name.trim().split(/\s+/);
|
|
2856
3037
|
if (parts.length === 1) {
|
|
@@ -7129,11 +7310,15 @@ var init_Skeleton = __esm({
|
|
|
7129
7310
|
function getKnownPatterns() {
|
|
7130
7311
|
return Object.keys(componentMapping);
|
|
7131
7312
|
}
|
|
7132
|
-
|
|
7313
|
+
function getPatternDefinition(type) {
|
|
7314
|
+
return patternRegistry[type];
|
|
7315
|
+
}
|
|
7316
|
+
var componentMapping, patternRegistry;
|
|
7133
7317
|
var init_pattern_resolver = __esm({
|
|
7134
7318
|
"renderer/pattern-resolver.ts"() {
|
|
7135
7319
|
logger.createLogger("almadar:ui:pattern-resolver");
|
|
7136
7320
|
componentMapping = {};
|
|
7321
|
+
patternRegistry = {};
|
|
7137
7322
|
}
|
|
7138
7323
|
});
|
|
7139
7324
|
|
|
@@ -15068,30 +15253,30 @@ var init_BranchingLogicBuilder = __esm({
|
|
|
15068
15253
|
if (!sourceQuestion?.optionValues) return [];
|
|
15069
15254
|
return sourceQuestion.optionValues.map((v) => ({ value: v, label: v }));
|
|
15070
15255
|
}, [sourceQuestion]);
|
|
15071
|
-
const handleSource = (
|
|
15072
|
-
onChange({ ...rule, sourceQuestionId:
|
|
15256
|
+
const handleSource = (v) => {
|
|
15257
|
+
onChange({ ...rule, sourceQuestionId: v });
|
|
15073
15258
|
};
|
|
15074
|
-
const handleOperator = (
|
|
15075
|
-
const next =
|
|
15259
|
+
const handleOperator = (v) => {
|
|
15260
|
+
const next = v;
|
|
15076
15261
|
const nextValue = next === "in" && !Array.isArray(rule.value) ? rule.value ? [rule.value] : [] : next !== "in" && Array.isArray(rule.value) ? rule.value[0] ?? "" : rule.value;
|
|
15077
15262
|
onChange({ ...rule, operator: next, value: nextValue });
|
|
15078
15263
|
};
|
|
15079
15264
|
const handleScalarValue = (e) => {
|
|
15080
15265
|
onChange({ ...rule, value: e.target.value });
|
|
15081
15266
|
};
|
|
15082
|
-
const handleAddChip = (
|
|
15083
|
-
const
|
|
15084
|
-
if (!
|
|
15267
|
+
const handleAddChip = (v) => {
|
|
15268
|
+
const val = v;
|
|
15269
|
+
if (!val) return;
|
|
15085
15270
|
const current = Array.isArray(rule.value) ? rule.value : [];
|
|
15086
|
-
if (current.includes(
|
|
15087
|
-
onChange({ ...rule, value: [...current,
|
|
15271
|
+
if (current.includes(val)) return;
|
|
15272
|
+
onChange({ ...rule, value: [...current, val] });
|
|
15088
15273
|
};
|
|
15089
15274
|
const handleRemoveChip = (chip) => {
|
|
15090
15275
|
const current = Array.isArray(rule.value) ? rule.value : [];
|
|
15091
15276
|
onChange({ ...rule, value: current.filter((c) => c !== chip) });
|
|
15092
15277
|
};
|
|
15093
|
-
const handleTarget = (
|
|
15094
|
-
onChange({ ...rule, targetQuestionId:
|
|
15278
|
+
const handleTarget = (v) => {
|
|
15279
|
+
onChange({ ...rule, targetQuestionId: v });
|
|
15095
15280
|
};
|
|
15096
15281
|
const isMulti = rule.operator === "in";
|
|
15097
15282
|
const chips = Array.isArray(rule.value) ? rule.value : [];
|
|
@@ -15172,7 +15357,7 @@ var init_BranchingLogicBuilder = __esm({
|
|
|
15172
15357
|
options: valueOptions,
|
|
15173
15358
|
value: scalarValue,
|
|
15174
15359
|
placeholder: t("branchingLogic.selectValue"),
|
|
15175
|
-
onChange: (
|
|
15360
|
+
onChange: (v) => onChange({ ...rule, value: v }),
|
|
15176
15361
|
disabled: readOnly
|
|
15177
15362
|
}
|
|
15178
15363
|
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -17604,7 +17789,7 @@ var init_Pagination = __esm({
|
|
|
17604
17789
|
exports.Select,
|
|
17605
17790
|
{
|
|
17606
17791
|
value: String(pageSize),
|
|
17607
|
-
onChange: (
|
|
17792
|
+
onChange: (v) => handlePageSizeChange(Number(v)),
|
|
17608
17793
|
options: pageSizeOptions.map((size) => ({
|
|
17609
17794
|
value: String(size),
|
|
17610
17795
|
label: String(size)
|
|
@@ -20758,7 +20943,84 @@ var init_DashboardLayout = __esm({
|
|
|
20758
20943
|
NavLinkBottom.displayName = "NavLinkBottom";
|
|
20759
20944
|
}
|
|
20760
20945
|
});
|
|
20761
|
-
|
|
20946
|
+
function computeMenuStyle(position, triggerRect) {
|
|
20947
|
+
const isTop = position.startsWith("top");
|
|
20948
|
+
const isRight = position.endsWith("right") || position.endsWith("end");
|
|
20949
|
+
if (isTop) {
|
|
20950
|
+
return {
|
|
20951
|
+
top: triggerRect.top - MENU_GAP,
|
|
20952
|
+
transform: "translateY(-100%)",
|
|
20953
|
+
...isRight ? { right: window.innerWidth - triggerRect.right } : { left: triggerRect.left }
|
|
20954
|
+
};
|
|
20955
|
+
}
|
|
20956
|
+
return {
|
|
20957
|
+
top: triggerRect.bottom + MENU_GAP,
|
|
20958
|
+
...isRight ? { right: window.innerWidth - triggerRect.right } : { left: triggerRect.left }
|
|
20959
|
+
};
|
|
20960
|
+
}
|
|
20961
|
+
function SubMenu({
|
|
20962
|
+
items,
|
|
20963
|
+
itemRef,
|
|
20964
|
+
direction,
|
|
20965
|
+
eventBus
|
|
20966
|
+
}) {
|
|
20967
|
+
const [rect, setRect] = React74.useState(null);
|
|
20968
|
+
React74.useEffect(() => {
|
|
20969
|
+
if (itemRef) {
|
|
20970
|
+
setRect(itemRef.getBoundingClientRect());
|
|
20971
|
+
}
|
|
20972
|
+
}, [itemRef]);
|
|
20973
|
+
if (!rect) return null;
|
|
20974
|
+
const isRtl = direction === "rtl";
|
|
20975
|
+
const style = {
|
|
20976
|
+
top: rect.top,
|
|
20977
|
+
...isRtl ? { right: window.innerWidth - rect.left } : { left: rect.right }
|
|
20978
|
+
};
|
|
20979
|
+
const panel = /* @__PURE__ */ jsxRuntime.jsx(
|
|
20980
|
+
"div",
|
|
20981
|
+
{
|
|
20982
|
+
className: cn("fixed z-50", menuContainerStyles),
|
|
20983
|
+
style,
|
|
20984
|
+
children: items.map((item, index) => {
|
|
20985
|
+
const isDivider = item.id === "divider" || item.label === "divider";
|
|
20986
|
+
const itemId = item.id ?? `item-${item.label.toLowerCase().replace(/\s+/g, "-")}-${index}`;
|
|
20987
|
+
const isDanger = item.variant === "danger";
|
|
20988
|
+
if (isDivider) {
|
|
20989
|
+
return /* @__PURE__ */ jsxRuntime.jsx(exports.Divider, { className: "my-1" }, `divider-${index}`);
|
|
20990
|
+
}
|
|
20991
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
20992
|
+
exports.Box,
|
|
20993
|
+
{
|
|
20994
|
+
as: "button",
|
|
20995
|
+
onClick: () => {
|
|
20996
|
+
if (item.disabled) return;
|
|
20997
|
+
if (item.event) eventBus.emit(`UI:${item.event}`, { itemId, label: item.label });
|
|
20998
|
+
item.onClick?.();
|
|
20999
|
+
},
|
|
21000
|
+
"aria-disabled": item.disabled || void 0,
|
|
21001
|
+
"data-testid": item.event ? `action-${item.event}` : void 0,
|
|
21002
|
+
className: cn(
|
|
21003
|
+
"w-full flex items-center gap-3 px-4 py-2 text-start",
|
|
21004
|
+
"text-sm transition-colors",
|
|
21005
|
+
"hover:bg-muted focus:outline-none focus:bg-muted",
|
|
21006
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
21007
|
+
item.disabled && "cursor-not-allowed",
|
|
21008
|
+
isDanger && "text-error hover:bg-error/10"
|
|
21009
|
+
),
|
|
21010
|
+
children: [
|
|
21011
|
+
item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: item.icon, size: "sm", className: "flex-shrink-0" }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon: item.icon, size: "sm", className: "flex-shrink-0" })),
|
|
21012
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "small", className: cn("flex-1", isDanger && "text-red-600"), children: item.label }),
|
|
21013
|
+
item.badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto text-xs font-medium", children: item.badge })
|
|
21014
|
+
]
|
|
21015
|
+
},
|
|
21016
|
+
itemId
|
|
21017
|
+
);
|
|
21018
|
+
})
|
|
21019
|
+
}
|
|
21020
|
+
);
|
|
21021
|
+
return typeof document !== "undefined" ? reactDom.createPortal(panel, document.body) : panel;
|
|
21022
|
+
}
|
|
21023
|
+
var MENU_GAP, menuContainerStyles; exports.Menu = void 0;
|
|
20762
21024
|
var init_Menu = __esm({
|
|
20763
21025
|
"components/core/molecules/Menu.tsx"() {
|
|
20764
21026
|
"use client";
|
|
@@ -20769,16 +21031,27 @@ var init_Menu = __esm({
|
|
|
20769
21031
|
init_Badge();
|
|
20770
21032
|
init_cn();
|
|
20771
21033
|
init_useEventBus();
|
|
21034
|
+
MENU_GAP = 4;
|
|
21035
|
+
menuContainerStyles = cn(
|
|
21036
|
+
"bg-card",
|
|
21037
|
+
"border-[length:var(--border-width)] border-border",
|
|
21038
|
+
"shadow-elevation-popover",
|
|
21039
|
+
"rounded-sm",
|
|
21040
|
+
"min-w-0 sm:min-w-[200px] max-w-[calc(100vw-1rem)] py-1"
|
|
21041
|
+
);
|
|
20772
21042
|
exports.Menu = ({
|
|
20773
21043
|
trigger,
|
|
20774
21044
|
items,
|
|
20775
21045
|
position = "bottom-left",
|
|
20776
|
-
className
|
|
21046
|
+
className,
|
|
21047
|
+
header,
|
|
21048
|
+
footer
|
|
20777
21049
|
}) => {
|
|
20778
21050
|
const eventBus = useEventBus();
|
|
20779
|
-
const {
|
|
21051
|
+
const { direction } = hooks.useTranslate();
|
|
20780
21052
|
const [isOpen, setIsOpen] = React74.useState(false);
|
|
20781
21053
|
const [activeSubMenu, setActiveSubMenu] = React74.useState(null);
|
|
21054
|
+
const [activeSubMenuRef, setActiveSubMenuRef] = React74.useState(null);
|
|
20782
21055
|
const [triggerRect, setTriggerRect] = React74.useState(null);
|
|
20783
21056
|
const triggerRef = React74.useRef(null);
|
|
20784
21057
|
const menuRef = React74.useRef(null);
|
|
@@ -20793,13 +21066,14 @@ var init_Menu = __esm({
|
|
|
20793
21066
|
}
|
|
20794
21067
|
setIsOpen(!isOpen);
|
|
20795
21068
|
setActiveSubMenu(null);
|
|
21069
|
+
setActiveSubMenuRef(null);
|
|
20796
21070
|
};
|
|
20797
|
-
const handleItemClick = (item) => {
|
|
21071
|
+
const handleItemClick = (item, itemId) => {
|
|
20798
21072
|
if (item.disabled) return;
|
|
20799
21073
|
if (item.subMenu && item.subMenu.length > 0) {
|
|
20800
|
-
setActiveSubMenu(
|
|
21074
|
+
setActiveSubMenu(itemId);
|
|
20801
21075
|
} else {
|
|
20802
|
-
if (item.event) eventBus.emit(`UI:${item.event}`, { itemId
|
|
21076
|
+
if (item.event) eventBus.emit(`UI:${item.event}`, { itemId, label: item.label });
|
|
20803
21077
|
item.onClick?.();
|
|
20804
21078
|
setIsOpen(false);
|
|
20805
21079
|
}
|
|
@@ -20814,22 +21088,12 @@ var init_Menu = __esm({
|
|
|
20814
21088
|
if (isOpen && menuRef.current && !menuRef.current.contains(e.target) && triggerRef.current && !triggerRef.current.contains(e.target)) {
|
|
20815
21089
|
setIsOpen(false);
|
|
20816
21090
|
setActiveSubMenu(null);
|
|
21091
|
+
setActiveSubMenuRef(null);
|
|
20817
21092
|
}
|
|
20818
21093
|
};
|
|
20819
21094
|
document.addEventListener("mousedown", handleClickOutside);
|
|
20820
21095
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
20821
21096
|
}, [isOpen]);
|
|
20822
|
-
const positionClasses = {
|
|
20823
|
-
"top-left": "bottom-full left-0 mb-2",
|
|
20824
|
-
"top-right": "bottom-full right-0 mb-2",
|
|
20825
|
-
"bottom-left": "top-full left-0 mt-2",
|
|
20826
|
-
"bottom-right": "top-full right-0 mt-2",
|
|
20827
|
-
// Aliases for pattern compatibility
|
|
20828
|
-
"top-start": "bottom-full left-0 mb-2",
|
|
20829
|
-
"top-end": "bottom-full right-0 mb-2",
|
|
20830
|
-
"bottom-start": "top-full left-0 mt-2",
|
|
20831
|
-
"bottom-end": "top-full right-0 mt-2"
|
|
20832
|
-
};
|
|
20833
21097
|
const rtlMirror = {
|
|
20834
21098
|
"top-left": "top-right",
|
|
20835
21099
|
"top-right": "top-left",
|
|
@@ -20841,7 +21105,6 @@ var init_Menu = __esm({
|
|
|
20841
21105
|
"bottom-end": "bottom-start"
|
|
20842
21106
|
};
|
|
20843
21107
|
const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
|
|
20844
|
-
const subMenuSideClass = direction === "rtl" ? "right-full mr-2" : "left-full ml-2";
|
|
20845
21108
|
const triggerChild = React74__namespace.default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "small", as: "span", children: trigger });
|
|
20846
21109
|
const triggerElement = React74__namespace.default.cloneElement(
|
|
20847
21110
|
triggerChild,
|
|
@@ -20850,94 +21113,87 @@ var init_Menu = __esm({
|
|
|
20850
21113
|
onClick: handleToggle
|
|
20851
21114
|
}
|
|
20852
21115
|
);
|
|
20853
|
-
const
|
|
20854
|
-
"
|
|
20855
|
-
"border-[length:var(--border-width)] border-border",
|
|
20856
|
-
"shadow-elevation-popover",
|
|
20857
|
-
"rounded-sm",
|
|
20858
|
-
"min-w-0 sm:min-w-[200px] max-w-[calc(100vw-1rem)] py-1"
|
|
20859
|
-
);
|
|
20860
|
-
const renderMenuItem = (item, hasSubMenu, index) => {
|
|
21116
|
+
const renderMenuItems = (menuItems) => menuItems.map((item, index) => {
|
|
21117
|
+
const isDivider = item.id === "divider" || item.label === "divider";
|
|
20861
21118
|
const itemId = item.id ?? `item-${item.label.toLowerCase().replace(/\s+/g, "-")}-${index}`;
|
|
21119
|
+
const hasSubMenu = !!(item.subMenu && item.subMenu.length > 0);
|
|
20862
21120
|
const isDanger = item.variant === "danger";
|
|
20863
|
-
|
|
20864
|
-
exports.
|
|
20865
|
-
|
|
20866
|
-
|
|
20867
|
-
|
|
20868
|
-
|
|
20869
|
-
|
|
20870
|
-
|
|
20871
|
-
|
|
20872
|
-
"
|
|
20873
|
-
|
|
20874
|
-
|
|
20875
|
-
|
|
20876
|
-
|
|
20877
|
-
item.disabled && "cursor-not-allowed",
|
|
20878
|
-
isDanger && "text-error hover:bg-error/10"
|
|
20879
|
-
),
|
|
20880
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: "flex items-center gap-3 flex-1 min-w-0", children: [
|
|
20881
|
-
item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: item.icon, size: "sm", className: "flex-shrink-0" }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon: item.icon, size: "sm", className: "flex-shrink-0" })),
|
|
20882
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
20883
|
-
exports.Typography,
|
|
20884
|
-
{
|
|
20885
|
-
variant: "small",
|
|
20886
|
-
className: cn("flex-1", isDanger && "text-red-600"),
|
|
20887
|
-
children: item.label
|
|
21121
|
+
if (isDivider) {
|
|
21122
|
+
return /* @__PURE__ */ jsxRuntime.jsx(exports.Divider, { className: "my-1" }, `divider-${index}`);
|
|
21123
|
+
}
|
|
21124
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { children: [
|
|
21125
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21126
|
+
exports.Box,
|
|
21127
|
+
{
|
|
21128
|
+
as: "button",
|
|
21129
|
+
onClick: () => handleItemClick({ ...item, id: itemId }, itemId),
|
|
21130
|
+
"aria-disabled": item.disabled || void 0,
|
|
21131
|
+
onMouseEnter: (e) => {
|
|
21132
|
+
if (hasSubMenu) {
|
|
21133
|
+
setActiveSubMenu(itemId);
|
|
21134
|
+
setActiveSubMenuRef(e.currentTarget);
|
|
20888
21135
|
}
|
|
21136
|
+
},
|
|
21137
|
+
"data-testid": item.event ? `action-${item.event}` : void 0,
|
|
21138
|
+
className: cn(
|
|
21139
|
+
"w-full flex items-center justify-between gap-3 px-4 py-2 text-start",
|
|
21140
|
+
"text-sm transition-colors",
|
|
21141
|
+
"hover:bg-muted",
|
|
21142
|
+
"focus:outline-none focus:bg-muted",
|
|
21143
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
21144
|
+
item.disabled && "cursor-not-allowed",
|
|
21145
|
+
isDanger && "text-error hover:bg-error/10"
|
|
20889
21146
|
),
|
|
20890
|
-
|
|
20891
|
-
|
|
20892
|
-
|
|
20893
|
-
|
|
20894
|
-
|
|
20895
|
-
|
|
20896
|
-
|
|
20897
|
-
|
|
20898
|
-
|
|
20899
|
-
const hasSubMenu = item.subMenu && item.subMenu.length > 0;
|
|
20900
|
-
const isDivider = item.id === "divider" || item.label === "divider";
|
|
20901
|
-
const itemId = item.id ?? `item-${item.label.toLowerCase().replace(/\s+/g, "-")}-${index}`;
|
|
20902
|
-
if (isDivider) {
|
|
20903
|
-
return /* @__PURE__ */ jsxRuntime.jsx(exports.Divider, { className: "my-1" }, `divider-${index}`);
|
|
20904
|
-
}
|
|
20905
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { children: [
|
|
20906
|
-
renderMenuItem(item, !!hasSubMenu, index),
|
|
20907
|
-
hasSubMenu && activeSubMenu === itemId && item.subMenu && /* @__PURE__ */ jsxRuntime.jsx(
|
|
20908
|
-
exports.Box,
|
|
20909
|
-
{
|
|
20910
|
-
className: cn(
|
|
20911
|
-
"absolute top-0 z-50",
|
|
20912
|
-
subMenuSideClass,
|
|
20913
|
-
menuContainerStyles
|
|
21147
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: "flex items-center gap-3 flex-1 min-w-0", children: [
|
|
21148
|
+
item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: item.icon, size: "sm", className: "flex-shrink-0" }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon: item.icon, size: "sm", className: "flex-shrink-0" })),
|
|
21149
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21150
|
+
exports.Typography,
|
|
21151
|
+
{
|
|
21152
|
+
variant: "small",
|
|
21153
|
+
className: cn("flex-1", isDanger && "text-red-600"),
|
|
21154
|
+
children: item.label
|
|
21155
|
+
}
|
|
20914
21156
|
),
|
|
20915
|
-
children:
|
|
20916
|
-
|
|
20917
|
-
|
|
20918
|
-
|
|
20919
|
-
|
|
20920
|
-
|
|
20921
|
-
|
|
21157
|
+
item.badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { variant: "default", size: "sm", children: item.badge }),
|
|
21158
|
+
hasSubMenu && /* @__PURE__ */ jsxRuntime.jsx(
|
|
21159
|
+
exports.Icon,
|
|
21160
|
+
{
|
|
21161
|
+
name: direction === "rtl" ? "chevron-left" : "chevron-right",
|
|
21162
|
+
size: "sm",
|
|
21163
|
+
className: "flex-shrink-0"
|
|
21164
|
+
}
|
|
21165
|
+
)
|
|
21166
|
+
] })
|
|
21167
|
+
}
|
|
21168
|
+
),
|
|
21169
|
+
hasSubMenu && activeSubMenu === itemId && item.subMenu && /* @__PURE__ */ jsxRuntime.jsx(
|
|
21170
|
+
SubMenu,
|
|
21171
|
+
{
|
|
21172
|
+
items: item.subMenu,
|
|
21173
|
+
itemRef: activeSubMenuRef,
|
|
21174
|
+
direction,
|
|
21175
|
+
eventBus
|
|
21176
|
+
}
|
|
21177
|
+
)
|
|
21178
|
+
] }, itemId);
|
|
21179
|
+
});
|
|
21180
|
+
const panel = isOpen && triggerRect ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
21181
|
+
"div",
|
|
21182
|
+
{
|
|
21183
|
+
ref: menuRef,
|
|
21184
|
+
className: cn("fixed z-50", menuContainerStyles, className),
|
|
21185
|
+
style: computeMenuStyle(effectivePosition, triggerRect),
|
|
21186
|
+
role: "menu",
|
|
21187
|
+
children: [
|
|
21188
|
+
header && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-2 border-b border-border", children: header }),
|
|
21189
|
+
renderMenuItems(items),
|
|
21190
|
+
footer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-2 border-t border-border", children: footer })
|
|
21191
|
+
]
|
|
21192
|
+
}
|
|
21193
|
+
) : null;
|
|
21194
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
20922
21195
|
triggerElement,
|
|
20923
|
-
|
|
20924
|
-
exports.Box,
|
|
20925
|
-
{
|
|
20926
|
-
ref: menuRef,
|
|
20927
|
-
className: cn(
|
|
20928
|
-
"absolute z-50",
|
|
20929
|
-
menuContainerStyles,
|
|
20930
|
-
positionClasses[effectivePosition],
|
|
20931
|
-
className
|
|
20932
|
-
),
|
|
20933
|
-
style: {
|
|
20934
|
-
left: effectivePosition.includes("left") ? 0 : "auto",
|
|
20935
|
-
right: effectivePosition.includes("right") ? 0 : "auto"
|
|
20936
|
-
},
|
|
20937
|
-
role: "menu",
|
|
20938
|
-
children: renderMenuItems(items)
|
|
20939
|
-
}
|
|
20940
|
-
)
|
|
21196
|
+
panel && typeof document !== "undefined" ? reactDom.createPortal(panel, document.body) : panel
|
|
20941
21197
|
] });
|
|
20942
21198
|
};
|
|
20943
21199
|
exports.Menu.displayName = "Menu";
|
|
@@ -22347,11 +22603,15 @@ function KindSelect({
|
|
|
22347
22603
|
function ValueNode({
|
|
22348
22604
|
value,
|
|
22349
22605
|
onChange,
|
|
22350
|
-
depth
|
|
22606
|
+
depth,
|
|
22607
|
+
readonly
|
|
22351
22608
|
}) {
|
|
22352
22609
|
const kind = kindOf(value);
|
|
22353
22610
|
if (kind === "object" || kind === "array") {
|
|
22354
|
-
return /* @__PURE__ */ jsxRuntime.jsx(ContainerNode, { value, onChange, depth });
|
|
22611
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ContainerNode, { value, onChange, depth, readonly });
|
|
22612
|
+
}
|
|
22613
|
+
if (readonly) {
|
|
22614
|
+
return /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", className: "font-mono text-foreground", children: value === null ? "null" : String(value) });
|
|
22355
22615
|
}
|
|
22356
22616
|
return /* @__PURE__ */ jsxRuntime.jsx(ScalarControl, { value, onChange });
|
|
22357
22617
|
}
|
|
@@ -22363,15 +22623,19 @@ function Row({
|
|
|
22363
22623
|
onValue,
|
|
22364
22624
|
onRenameKey,
|
|
22365
22625
|
onChangeKind,
|
|
22366
|
-
onRemove
|
|
22626
|
+
onRemove,
|
|
22627
|
+
readonly
|
|
22367
22628
|
}) {
|
|
22368
22629
|
const [keyDraft, setKeyDraft] = React74__namespace.default.useState(rowKey);
|
|
22369
22630
|
React74__namespace.default.useEffect(() => setKeyDraft(rowKey), [rowKey]);
|
|
22370
22631
|
const container = isObj(value) || isArr(value);
|
|
22371
22632
|
return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "none", className: "group w-max min-w-full", children: [
|
|
22372
22633
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", align: "center", className: "py-0.5 w-max", children: [
|
|
22373
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22374
|
-
|
|
22634
|
+
readonly ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
|
|
22635
|
+
"h-6 rounded-sm bg-muted text-muted-foreground text-[10px] font-mono px-1 flex items-center",
|
|
22636
|
+
"border-[length:var(--border-width-thin)] border-border"
|
|
22637
|
+
), children: TYPE_LABEL[kindOf(value)] }) : /* @__PURE__ */ jsxRuntime.jsx(KindSelect, { kind: kindOf(value), onChange: onChangeKind }),
|
|
22638
|
+
isArrayItem ? /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", color: "muted", className: "w-6 shrink-0 font-mono", children: rowKey }) : readonly ? /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", color: "muted", className: "w-20 shrink-0 font-mono truncate", children: rowKey }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-20 shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
22375
22639
|
exports.Input,
|
|
22376
22640
|
{
|
|
22377
22641
|
inputType: "text",
|
|
@@ -22384,8 +22648,8 @@ function Row({
|
|
|
22384
22648
|
className: "font-mono"
|
|
22385
22649
|
}
|
|
22386
22650
|
) }),
|
|
22387
|
-
!container && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-48 shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(ValueNode, { value, onChange: onValue, depth: depth + 1 }) }),
|
|
22388
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22651
|
+
!container && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-48 shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(ValueNode, { value, onChange: onValue, depth: depth + 1, readonly }) }),
|
|
22652
|
+
!readonly && /* @__PURE__ */ jsxRuntime.jsx(
|
|
22389
22653
|
exports.Button,
|
|
22390
22654
|
{
|
|
22391
22655
|
variant: "ghost",
|
|
@@ -22397,13 +22661,14 @@ function Row({
|
|
|
22397
22661
|
}
|
|
22398
22662
|
)
|
|
22399
22663
|
] }),
|
|
22400
|
-
container && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pl-2", children: /* @__PURE__ */ jsxRuntime.jsx(ValueNode, { value, onChange: onValue, depth: depth + 1 }) })
|
|
22664
|
+
container && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pl-2", children: /* @__PURE__ */ jsxRuntime.jsx(ValueNode, { value, onChange: onValue, depth: depth + 1, readonly }) })
|
|
22401
22665
|
] });
|
|
22402
22666
|
}
|
|
22403
22667
|
function ContainerNode({
|
|
22404
22668
|
value,
|
|
22405
22669
|
onChange,
|
|
22406
|
-
depth
|
|
22670
|
+
depth,
|
|
22671
|
+
readonly
|
|
22407
22672
|
}) {
|
|
22408
22673
|
const [open, setOpen] = React74__namespace.default.useState(depth < 2);
|
|
22409
22674
|
const array = isArr(value);
|
|
@@ -22476,11 +22741,12 @@ function ContainerNode({
|
|
|
22476
22741
|
onValue: (next) => array ? setArrValue(idx, next) : setObjValue(k, next),
|
|
22477
22742
|
onRenameKey: (nk) => renameKey(k, nk),
|
|
22478
22743
|
onChangeKind: (kind) => array ? changeArrKind(idx, kind) : changeObjKind(k, kind),
|
|
22479
|
-
onRemove: () => array ? removeArrIdx(idx) : removeObjKey(k)
|
|
22744
|
+
onRemove: () => array ? removeArrIdx(idx) : removeObjKey(k),
|
|
22745
|
+
readonly
|
|
22480
22746
|
},
|
|
22481
22747
|
array ? idx : k
|
|
22482
22748
|
)),
|
|
22483
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22749
|
+
!readonly && /* @__PURE__ */ jsxRuntime.jsx(
|
|
22484
22750
|
exports.Button,
|
|
22485
22751
|
{
|
|
22486
22752
|
variant: "ghost",
|
|
@@ -22518,9 +22784,586 @@ var init_JsonTreeEditor = __esm({
|
|
|
22518
22784
|
null: "\u2014"
|
|
22519
22785
|
};
|
|
22520
22786
|
KIND_OPTIONS = ["string", "number", "boolean", "object", "array"];
|
|
22521
|
-
exports.JsonTreeEditor = ({ value, onChange, className }) => {
|
|
22787
|
+
exports.JsonTreeEditor = ({ value, onChange, className, readonly }) => {
|
|
22522
22788
|
const root = value ?? "";
|
|
22523
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("w-full overflow-x-auto rounded-sm bg-card/40 p-2 border-[length:var(--border-width-thin)] border-border", className), children: /* @__PURE__ */ jsxRuntime.jsx(ValueNode, { value: root, onChange, depth: 0 }) });
|
|
22789
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("w-full overflow-x-auto rounded-sm bg-card/40 p-2 border-[length:var(--border-width-thin)] border-border", className), children: /* @__PURE__ */ jsxRuntime.jsx(ValueNode, { value: root, onChange, depth: 0, readonly }) });
|
|
22790
|
+
};
|
|
22791
|
+
}
|
|
22792
|
+
});
|
|
22793
|
+
exports.FormSection = void 0; exports.FormLayout = void 0; exports.FormActions = void 0;
|
|
22794
|
+
var init_FormSection = __esm({
|
|
22795
|
+
"components/core/molecules/FormSection.tsx"() {
|
|
22796
|
+
"use client";
|
|
22797
|
+
init_cn();
|
|
22798
|
+
init_atoms2();
|
|
22799
|
+
init_Box();
|
|
22800
|
+
init_Typography();
|
|
22801
|
+
init_Button();
|
|
22802
|
+
init_Stack();
|
|
22803
|
+
init_Icon();
|
|
22804
|
+
init_useEventBus();
|
|
22805
|
+
exports.FormSection = ({
|
|
22806
|
+
title,
|
|
22807
|
+
description,
|
|
22808
|
+
children,
|
|
22809
|
+
collapsible = false,
|
|
22810
|
+
defaultCollapsed = false,
|
|
22811
|
+
card = false,
|
|
22812
|
+
columns = 1,
|
|
22813
|
+
className
|
|
22814
|
+
}) => {
|
|
22815
|
+
const [collapsed, setCollapsed] = React74__namespace.default.useState(defaultCollapsed);
|
|
22816
|
+
const { t } = hooks.useTranslate();
|
|
22817
|
+
const eventBus = useEventBus();
|
|
22818
|
+
const gridClass = {
|
|
22819
|
+
1: "grid-cols-1",
|
|
22820
|
+
2: "grid-cols-1 md:grid-cols-2",
|
|
22821
|
+
3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
|
|
22822
|
+
}[columns];
|
|
22823
|
+
React74__namespace.default.useCallback(() => {
|
|
22824
|
+
if (collapsible) {
|
|
22825
|
+
setCollapsed((prev) => !prev);
|
|
22826
|
+
eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
|
|
22827
|
+
}
|
|
22828
|
+
}, [collapsible, collapsed, eventBus]);
|
|
22829
|
+
const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
22830
|
+
(title || description) && /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", className: "mb-4", children: [
|
|
22831
|
+
title && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
22832
|
+
exports.HStack,
|
|
22833
|
+
{
|
|
22834
|
+
justify: "between",
|
|
22835
|
+
align: "center",
|
|
22836
|
+
className: cn(collapsible && "cursor-pointer"),
|
|
22837
|
+
action: collapsible ? "TOGGLE_COLLAPSE" : void 0,
|
|
22838
|
+
children: [
|
|
22839
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h3", weight: "semibold", children: title }),
|
|
22840
|
+
collapsible && /* @__PURE__ */ jsxRuntime.jsx(
|
|
22841
|
+
exports.Button,
|
|
22842
|
+
{
|
|
22843
|
+
variant: "ghost",
|
|
22844
|
+
size: "sm",
|
|
22845
|
+
action: "TOGGLE_COLLAPSE",
|
|
22846
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
22847
|
+
exports.Icon,
|
|
22848
|
+
{
|
|
22849
|
+
icon: LucideIcons2.ChevronDown,
|
|
22850
|
+
size: "sm",
|
|
22851
|
+
className: cn(
|
|
22852
|
+
"text-muted-foreground transition-transform",
|
|
22853
|
+
collapsed && "rotate-180"
|
|
22854
|
+
)
|
|
22855
|
+
}
|
|
22856
|
+
)
|
|
22857
|
+
}
|
|
22858
|
+
)
|
|
22859
|
+
]
|
|
22860
|
+
}
|
|
22861
|
+
),
|
|
22862
|
+
description && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "small", color: "secondary", children: description })
|
|
22863
|
+
] }),
|
|
22864
|
+
(!collapsible || !collapsed) && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: cn("grid gap-4", gridClass), children })
|
|
22865
|
+
] });
|
|
22866
|
+
if (card) {
|
|
22867
|
+
return /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className: cn("p-6", className), children: content });
|
|
22868
|
+
}
|
|
22869
|
+
return /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className, children: content });
|
|
22870
|
+
};
|
|
22871
|
+
exports.FormSection.displayName = "FormSection";
|
|
22872
|
+
exports.FormLayout = ({
|
|
22873
|
+
children,
|
|
22874
|
+
dividers = true,
|
|
22875
|
+
className
|
|
22876
|
+
}) => {
|
|
22877
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22878
|
+
exports.VStack,
|
|
22879
|
+
{
|
|
22880
|
+
gap: "lg",
|
|
22881
|
+
className: cn(
|
|
22882
|
+
dividers && "[&>*+*]:pt-8 [&>*+*]:border-t [&>*+*]:border-border",
|
|
22883
|
+
className
|
|
22884
|
+
),
|
|
22885
|
+
children
|
|
22886
|
+
}
|
|
22887
|
+
);
|
|
22888
|
+
};
|
|
22889
|
+
exports.FormLayout.displayName = "FormLayout";
|
|
22890
|
+
exports.FormActions = ({
|
|
22891
|
+
children,
|
|
22892
|
+
sticky = false,
|
|
22893
|
+
align = "right",
|
|
22894
|
+
className
|
|
22895
|
+
}) => {
|
|
22896
|
+
const alignClass2 = {
|
|
22897
|
+
left: "justify-start",
|
|
22898
|
+
right: "justify-end",
|
|
22899
|
+
between: "justify-between",
|
|
22900
|
+
center: "justify-center"
|
|
22901
|
+
}[align];
|
|
22902
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22903
|
+
exports.HStack,
|
|
22904
|
+
{
|
|
22905
|
+
gap: "sm",
|
|
22906
|
+
align: "center",
|
|
22907
|
+
className: cn(
|
|
22908
|
+
"pt-6 border-t border-border",
|
|
22909
|
+
alignClass2,
|
|
22910
|
+
sticky && "sticky bottom-0 bg-card py-4 -mx-6 px-6 shadow-[0_-4px_6px_-1px_rgb(0,0,0,0.05)]",
|
|
22911
|
+
className
|
|
22912
|
+
),
|
|
22913
|
+
children
|
|
22914
|
+
}
|
|
22915
|
+
);
|
|
22916
|
+
};
|
|
22917
|
+
exports.FormActions.displayName = "FormActions";
|
|
22918
|
+
}
|
|
22919
|
+
});
|
|
22920
|
+
var ALL_CATEGORY; exports.GridPicker = void 0;
|
|
22921
|
+
var init_GridPicker = __esm({
|
|
22922
|
+
"components/core/molecules/GridPicker.tsx"() {
|
|
22923
|
+
"use client";
|
|
22924
|
+
init_cn();
|
|
22925
|
+
init_Input();
|
|
22926
|
+
init_Badge();
|
|
22927
|
+
init_Stack();
|
|
22928
|
+
ALL_CATEGORY = "__all__";
|
|
22929
|
+
exports.GridPicker = ({
|
|
22930
|
+
items,
|
|
22931
|
+
value,
|
|
22932
|
+
onChange,
|
|
22933
|
+
categories,
|
|
22934
|
+
searchPlaceholder,
|
|
22935
|
+
renderThumbnail,
|
|
22936
|
+
cellSize = 32,
|
|
22937
|
+
className
|
|
22938
|
+
}) => {
|
|
22939
|
+
const [search, setSearch] = React74.useState("");
|
|
22940
|
+
const [activeCategory, setActiveCategory] = React74.useState(ALL_CATEGORY);
|
|
22941
|
+
const gridRef = React74.useRef(null);
|
|
22942
|
+
const categoryChips = React74.useMemo(() => {
|
|
22943
|
+
if (categories !== void 0) return categories;
|
|
22944
|
+
const seen = [];
|
|
22945
|
+
for (const item of items) {
|
|
22946
|
+
if (!seen.includes(item.category)) seen.push(item.category);
|
|
22947
|
+
}
|
|
22948
|
+
return seen;
|
|
22949
|
+
}, [categories, items]);
|
|
22950
|
+
const filtered = React74.useMemo(() => {
|
|
22951
|
+
const needle = search.trim().toLowerCase();
|
|
22952
|
+
return items.filter((item) => {
|
|
22953
|
+
const matchesCategory = activeCategory === ALL_CATEGORY || item.category === activeCategory;
|
|
22954
|
+
const matchesSearch = needle === "" || item.label.toLowerCase().includes(needle);
|
|
22955
|
+
return matchesCategory && matchesSearch;
|
|
22956
|
+
});
|
|
22957
|
+
}, [items, search, activeCategory]);
|
|
22958
|
+
const select = React74.useCallback(
|
|
22959
|
+
(item) => {
|
|
22960
|
+
onChange(item.id);
|
|
22961
|
+
},
|
|
22962
|
+
[onChange]
|
|
22963
|
+
);
|
|
22964
|
+
const handleKeyDown = React74.useCallback(
|
|
22965
|
+
(e, index) => {
|
|
22966
|
+
const cells = gridRef.current?.querySelectorAll(
|
|
22967
|
+
"[data-gridpicker-cell]"
|
|
22968
|
+
);
|
|
22969
|
+
if (cells === void 0 || cells.length === 0) return;
|
|
22970
|
+
const columns = (() => {
|
|
22971
|
+
const grid = gridRef.current;
|
|
22972
|
+
if (grid === null) return 1;
|
|
22973
|
+
const style = window.getComputedStyle(grid);
|
|
22974
|
+
const cols = style.gridTemplateColumns.split(" ").filter(Boolean).length;
|
|
22975
|
+
return cols > 0 ? cols : 1;
|
|
22976
|
+
})();
|
|
22977
|
+
let next = -1;
|
|
22978
|
+
if (e.key === "ArrowRight") next = index + 1;
|
|
22979
|
+
else if (e.key === "ArrowLeft") next = index - 1;
|
|
22980
|
+
else if (e.key === "ArrowDown") next = index + columns;
|
|
22981
|
+
else if (e.key === "ArrowUp") next = index - columns;
|
|
22982
|
+
else if (e.key === "Enter" || e.key === " ") {
|
|
22983
|
+
e.preventDefault();
|
|
22984
|
+
select(filtered[index]);
|
|
22985
|
+
return;
|
|
22986
|
+
} else {
|
|
22987
|
+
return;
|
|
22988
|
+
}
|
|
22989
|
+
e.preventDefault();
|
|
22990
|
+
if (next >= 0 && next < cells.length) {
|
|
22991
|
+
cells[next].focus();
|
|
22992
|
+
}
|
|
22993
|
+
},
|
|
22994
|
+
[filtered, select]
|
|
22995
|
+
);
|
|
22996
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", className: cn("w-full", className), children: [
|
|
22997
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22998
|
+
exports.Input,
|
|
22999
|
+
{
|
|
23000
|
+
type: "search",
|
|
23001
|
+
icon: "search",
|
|
23002
|
+
value: search,
|
|
23003
|
+
placeholder: searchPlaceholder,
|
|
23004
|
+
clearable: true,
|
|
23005
|
+
onClear: () => setSearch(""),
|
|
23006
|
+
onChange: (e) => setSearch(e.target.value)
|
|
23007
|
+
}
|
|
23008
|
+
),
|
|
23009
|
+
categoryChips.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", wrap: true, children: [
|
|
23010
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
23011
|
+
exports.Badge,
|
|
23012
|
+
{
|
|
23013
|
+
variant: activeCategory === ALL_CATEGORY ? "primary" : "neutral",
|
|
23014
|
+
size: "sm",
|
|
23015
|
+
role: "button",
|
|
23016
|
+
tabIndex: 0,
|
|
23017
|
+
"aria-pressed": activeCategory === ALL_CATEGORY,
|
|
23018
|
+
className: "cursor-pointer",
|
|
23019
|
+
onClick: () => setActiveCategory(ALL_CATEGORY),
|
|
23020
|
+
onKeyDown: (e) => {
|
|
23021
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
23022
|
+
e.preventDefault();
|
|
23023
|
+
setActiveCategory(ALL_CATEGORY);
|
|
23024
|
+
}
|
|
23025
|
+
},
|
|
23026
|
+
children: "All"
|
|
23027
|
+
}
|
|
23028
|
+
),
|
|
23029
|
+
categoryChips.map((category) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
23030
|
+
exports.Badge,
|
|
23031
|
+
{
|
|
23032
|
+
variant: activeCategory === category ? "primary" : "neutral",
|
|
23033
|
+
size: "sm",
|
|
23034
|
+
role: "button",
|
|
23035
|
+
tabIndex: 0,
|
|
23036
|
+
"aria-pressed": activeCategory === category,
|
|
23037
|
+
className: "cursor-pointer",
|
|
23038
|
+
onClick: () => setActiveCategory(category),
|
|
23039
|
+
onKeyDown: (e) => {
|
|
23040
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
23041
|
+
e.preventDefault();
|
|
23042
|
+
setActiveCategory(category);
|
|
23043
|
+
}
|
|
23044
|
+
},
|
|
23045
|
+
children: category
|
|
23046
|
+
},
|
|
23047
|
+
category
|
|
23048
|
+
))
|
|
23049
|
+
] }),
|
|
23050
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
23051
|
+
"div",
|
|
23052
|
+
{
|
|
23053
|
+
ref: gridRef,
|
|
23054
|
+
role: "listbox",
|
|
23055
|
+
className: "grid gap-1 overflow-y-auto max-h-64 p-1",
|
|
23056
|
+
style: {
|
|
23057
|
+
gridTemplateColumns: `repeat(auto-fill, minmax(${cellSize}px, 1fr))`
|
|
23058
|
+
},
|
|
23059
|
+
children: filtered.map((item, index) => {
|
|
23060
|
+
const selected = item.id === value;
|
|
23061
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
23062
|
+
"button",
|
|
23063
|
+
{
|
|
23064
|
+
type: "button",
|
|
23065
|
+
role: "option",
|
|
23066
|
+
"aria-selected": selected,
|
|
23067
|
+
"aria-label": item.label,
|
|
23068
|
+
title: item.label,
|
|
23069
|
+
"data-gridpicker-cell": true,
|
|
23070
|
+
tabIndex: selected || value === void 0 && index === 0 ? 0 : -1,
|
|
23071
|
+
onClick: () => select(item),
|
|
23072
|
+
onKeyDown: (e) => handleKeyDown(e, index),
|
|
23073
|
+
className: cn(
|
|
23074
|
+
"flex items-center justify-center rounded-sm",
|
|
23075
|
+
"transition-colors hover:bg-muted",
|
|
23076
|
+
"focus:outline-none focus:ring-1 focus:ring-ring",
|
|
23077
|
+
selected && "bg-primary/10 ring-1 ring-primary"
|
|
23078
|
+
),
|
|
23079
|
+
style: { width: cellSize, height: cellSize },
|
|
23080
|
+
children: renderThumbnail(item)
|
|
23081
|
+
},
|
|
23082
|
+
item.id
|
|
23083
|
+
);
|
|
23084
|
+
})
|
|
23085
|
+
}
|
|
23086
|
+
)
|
|
23087
|
+
] });
|
|
23088
|
+
};
|
|
23089
|
+
exports.GridPicker.displayName = "GridPicker";
|
|
23090
|
+
}
|
|
23091
|
+
});
|
|
23092
|
+
function pascalToKebab(name) {
|
|
23093
|
+
return name.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z][a-z])/g, "$1-$2").toLowerCase();
|
|
23094
|
+
}
|
|
23095
|
+
function kebabToPascal3(name) {
|
|
23096
|
+
return name.split("-").map((part) => /^\d+$/.test(part) ? part : part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
23097
|
+
}
|
|
23098
|
+
var ICON_ITEMS; exports.IconPicker = void 0;
|
|
23099
|
+
var init_IconPicker = __esm({
|
|
23100
|
+
"components/core/molecules/IconPicker.tsx"() {
|
|
23101
|
+
"use client";
|
|
23102
|
+
init_Icon();
|
|
23103
|
+
init_GridPicker();
|
|
23104
|
+
ICON_ITEMS = (() => {
|
|
23105
|
+
const items = [];
|
|
23106
|
+
for (const [exportName, candidate] of Object.entries(LucideIcons2__namespace)) {
|
|
23107
|
+
if (!/^[A-Z]/.test(exportName)) continue;
|
|
23108
|
+
if (exportName.endsWith("Icon")) continue;
|
|
23109
|
+
if (exportName.startsWith("Lucide")) continue;
|
|
23110
|
+
const isComponent = candidate !== null && (typeof candidate === "object" || typeof candidate === "function") && "$$typeof" in candidate;
|
|
23111
|
+
if (!isComponent) continue;
|
|
23112
|
+
const kebab = pascalToKebab(exportName);
|
|
23113
|
+
if (kebabToPascal3(kebab) !== exportName) continue;
|
|
23114
|
+
items.push({ id: kebab, label: kebab, category: "icons" });
|
|
23115
|
+
}
|
|
23116
|
+
return items;
|
|
23117
|
+
})();
|
|
23118
|
+
exports.IconPicker = ({ value, onChange, className }) => {
|
|
23119
|
+
const items = React74.useMemo(() => ICON_ITEMS, []);
|
|
23120
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
23121
|
+
exports.GridPicker,
|
|
23122
|
+
{
|
|
23123
|
+
items,
|
|
23124
|
+
value,
|
|
23125
|
+
onChange,
|
|
23126
|
+
searchPlaceholder: "Search icons\u2026",
|
|
23127
|
+
renderThumbnail: (it) => /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: it.id }),
|
|
23128
|
+
cellSize: 32,
|
|
23129
|
+
className
|
|
23130
|
+
}
|
|
23131
|
+
);
|
|
23132
|
+
};
|
|
23133
|
+
exports.IconPicker.displayName = "IconPicker";
|
|
23134
|
+
}
|
|
23135
|
+
});
|
|
23136
|
+
function iconForKind(kind) {
|
|
23137
|
+
if (kind === "audio") return "music";
|
|
23138
|
+
if (kind === "model") return "box";
|
|
23139
|
+
return "file";
|
|
23140
|
+
}
|
|
23141
|
+
var THUMB_PX, IMAGE_KINDS; exports.AssetPicker = void 0;
|
|
23142
|
+
var init_AssetPicker = __esm({
|
|
23143
|
+
"components/core/molecules/AssetPicker.tsx"() {
|
|
23144
|
+
"use client";
|
|
23145
|
+
init_GridPicker();
|
|
23146
|
+
init_Icon();
|
|
23147
|
+
THUMB_PX = 32;
|
|
23148
|
+
IMAGE_KINDS = /* @__PURE__ */ new Set([
|
|
23149
|
+
"image",
|
|
23150
|
+
"spritesheet",
|
|
23151
|
+
"scene",
|
|
23152
|
+
"portrait"
|
|
23153
|
+
]);
|
|
23154
|
+
exports.AssetPicker = ({
|
|
23155
|
+
assets,
|
|
23156
|
+
value,
|
|
23157
|
+
onChange,
|
|
23158
|
+
className
|
|
23159
|
+
}) => {
|
|
23160
|
+
const byUrl = React74.useMemo(() => {
|
|
23161
|
+
const map = /* @__PURE__ */ new Map();
|
|
23162
|
+
for (const entry of assets) map.set(entry.url, entry);
|
|
23163
|
+
return map;
|
|
23164
|
+
}, [assets]);
|
|
23165
|
+
const items = React74.useMemo(
|
|
23166
|
+
() => assets.map((entry) => ({
|
|
23167
|
+
id: entry.url,
|
|
23168
|
+
label: entry.name,
|
|
23169
|
+
category: entry.category
|
|
23170
|
+
})),
|
|
23171
|
+
[assets]
|
|
23172
|
+
);
|
|
23173
|
+
const categories = React74.useMemo(() => {
|
|
23174
|
+
const seen = [];
|
|
23175
|
+
for (const entry of assets) {
|
|
23176
|
+
if (!seen.includes(entry.category)) seen.push(entry.category);
|
|
23177
|
+
}
|
|
23178
|
+
return seen;
|
|
23179
|
+
}, [assets]);
|
|
23180
|
+
const renderThumbnail = React74.useCallback(
|
|
23181
|
+
(item) => {
|
|
23182
|
+
const entry = byUrl.get(item.id);
|
|
23183
|
+
if (entry === void 0) return null;
|
|
23184
|
+
if (IMAGE_KINDS.has(entry.kind)) {
|
|
23185
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
23186
|
+
"img",
|
|
23187
|
+
{
|
|
23188
|
+
src: entry.thumbnailUrl ?? entry.url,
|
|
23189
|
+
alt: entry.name,
|
|
23190
|
+
loading: "lazy",
|
|
23191
|
+
width: THUMB_PX,
|
|
23192
|
+
height: THUMB_PX,
|
|
23193
|
+
style: { width: THUMB_PX, height: THUMB_PX, objectFit: "cover" }
|
|
23194
|
+
}
|
|
23195
|
+
);
|
|
23196
|
+
}
|
|
23197
|
+
return /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: iconForKind(entry.kind), size: "sm" });
|
|
23198
|
+
},
|
|
23199
|
+
[byUrl]
|
|
23200
|
+
);
|
|
23201
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
23202
|
+
exports.GridPicker,
|
|
23203
|
+
{
|
|
23204
|
+
items,
|
|
23205
|
+
value,
|
|
23206
|
+
onChange,
|
|
23207
|
+
categories,
|
|
23208
|
+
renderThumbnail,
|
|
23209
|
+
cellSize: THUMB_PX,
|
|
23210
|
+
className
|
|
23211
|
+
}
|
|
23212
|
+
);
|
|
23213
|
+
};
|
|
23214
|
+
exports.AssetPicker.displayName = "AssetPicker";
|
|
23215
|
+
}
|
|
23216
|
+
});
|
|
23217
|
+
function currentValue(decl, override) {
|
|
23218
|
+
return override !== void 0 ? override : decl.default;
|
|
23219
|
+
}
|
|
23220
|
+
function TextLikeControl({
|
|
23221
|
+
field,
|
|
23222
|
+
numeric,
|
|
23223
|
+
value,
|
|
23224
|
+
onCommit
|
|
23225
|
+
}) {
|
|
23226
|
+
const initial = value === void 0 || value === null ? "" : String(value);
|
|
23227
|
+
const [draft, setDraft] = React74__namespace.default.useState(initial);
|
|
23228
|
+
React74__namespace.default.useEffect(() => setDraft(initial), [initial]);
|
|
23229
|
+
const commit = () => {
|
|
23230
|
+
if (numeric) {
|
|
23231
|
+
const n = draft.trim() === "" ? 0 : Number(draft);
|
|
23232
|
+
onCommit(field, Number.isNaN(n) ? 0 : n);
|
|
23233
|
+
} else {
|
|
23234
|
+
onCommit(field, draft);
|
|
23235
|
+
}
|
|
23236
|
+
};
|
|
23237
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
23238
|
+
exports.Input,
|
|
23239
|
+
{
|
|
23240
|
+
inputType: numeric ? "number" : "text",
|
|
23241
|
+
value: draft,
|
|
23242
|
+
onChange: (e) => setDraft(e.target.value),
|
|
23243
|
+
onBlur: commit,
|
|
23244
|
+
onKeyDown: (e) => {
|
|
23245
|
+
if (e.key === "Enter") commit();
|
|
23246
|
+
}
|
|
23247
|
+
}
|
|
23248
|
+
);
|
|
23249
|
+
}
|
|
23250
|
+
function isTraitConfigObject(v) {
|
|
23251
|
+
return v !== null && v !== void 0 && typeof v === "object" && !Array.isArray(v);
|
|
23252
|
+
}
|
|
23253
|
+
function FieldControl({
|
|
23254
|
+
name,
|
|
23255
|
+
decl,
|
|
23256
|
+
value,
|
|
23257
|
+
onChange,
|
|
23258
|
+
assets
|
|
23259
|
+
}) {
|
|
23260
|
+
let control;
|
|
23261
|
+
const stringValue = typeof value === "string" ? value : void 0;
|
|
23262
|
+
const effectiveValue = value ?? decl.default;
|
|
23263
|
+
if (decl.type === "icon") {
|
|
23264
|
+
control = /* @__PURE__ */ jsxRuntime.jsx(exports.IconPicker, { value: stringValue, onChange: (icon) => onChange(name, icon) });
|
|
23265
|
+
} else if (decl.type === "asset") {
|
|
23266
|
+
control = /* @__PURE__ */ jsxRuntime.jsx(
|
|
23267
|
+
exports.AssetPicker,
|
|
23268
|
+
{
|
|
23269
|
+
assets: assets ?? [],
|
|
23270
|
+
value: stringValue,
|
|
23271
|
+
onChange: (url) => onChange(name, url)
|
|
23272
|
+
}
|
|
23273
|
+
);
|
|
23274
|
+
} else if (decl.type === "boolean") {
|
|
23275
|
+
control = /* @__PURE__ */ jsxRuntime.jsx(exports.Switch, { checked: value === true, onChange: (c) => onChange(name, c) });
|
|
23276
|
+
} else if (decl.type === "string" && decl.values !== void 0 && decl.values.length > 0) {
|
|
23277
|
+
control = /* @__PURE__ */ jsxRuntime.jsx(
|
|
23278
|
+
exports.Select,
|
|
23279
|
+
{
|
|
23280
|
+
options: decl.values.map((v) => ({ value: v, label: v })),
|
|
23281
|
+
value: typeof value === "string" ? value : "",
|
|
23282
|
+
onChange: (v) => onChange(name, v)
|
|
23283
|
+
}
|
|
23284
|
+
);
|
|
23285
|
+
} else if (decl.type === "number") {
|
|
23286
|
+
control = /* @__PURE__ */ jsxRuntime.jsx(TextLikeControl, { field: name, numeric: true, value, onCommit: onChange });
|
|
23287
|
+
} else if (decl.type === "string") {
|
|
23288
|
+
control = /* @__PURE__ */ jsxRuntime.jsx(TextLikeControl, { field: name, numeric: false, value, onCommit: onChange });
|
|
23289
|
+
} else if (decl.type === "node") {
|
|
23290
|
+
control = /* @__PURE__ */ jsxRuntime.jsx(exports.NodeSlotEditor, { value: effectiveValue, onChange: (next) => onChange(name, next) });
|
|
23291
|
+
} else if (decl.type.startsWith("[") || Array.isArray(effectiveValue)) {
|
|
23292
|
+
const arr = Array.isArray(effectiveValue) ? effectiveValue : [];
|
|
23293
|
+
control = /* @__PURE__ */ jsxRuntime.jsx(exports.JsonTreeEditor, { value: arr, onChange: (next) => onChange(name, next) });
|
|
23294
|
+
} else if (decl.type === "object" || decl.type.startsWith("Map ") || !SCALAR_TYPES.has(decl.type) && isTraitConfigObject(effectiveValue)) {
|
|
23295
|
+
const obj = isTraitConfigObject(effectiveValue) ? effectiveValue : {};
|
|
23296
|
+
control = /* @__PURE__ */ jsxRuntime.jsx(exports.JsonTreeEditor, { value: obj, onChange: (next) => onChange(name, next) });
|
|
23297
|
+
} else {
|
|
23298
|
+
control = /* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { variant: "caption", color: "muted", children: [
|
|
23299
|
+
decl.type,
|
|
23300
|
+
" \u2014 edit in source"
|
|
23301
|
+
] });
|
|
23302
|
+
}
|
|
23303
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", children: [
|
|
23304
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "label", children: decl.label ?? name }),
|
|
23305
|
+
control,
|
|
23306
|
+
decl.description !== void 0 && decl.description !== "" && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", color: "muted", children: decl.description })
|
|
23307
|
+
] });
|
|
23308
|
+
}
|
|
23309
|
+
var TIER_ORDER, SCALAR_TYPES; exports.PropertyInspector = void 0;
|
|
23310
|
+
var init_PropertyInspector = __esm({
|
|
23311
|
+
"components/core/molecules/PropertyInspector.tsx"() {
|
|
23312
|
+
"use client";
|
|
23313
|
+
init_cn();
|
|
23314
|
+
init_Stack();
|
|
23315
|
+
init_Typography();
|
|
23316
|
+
init_Button();
|
|
23317
|
+
init_Switch();
|
|
23318
|
+
init_Select();
|
|
23319
|
+
init_Input();
|
|
23320
|
+
init_FormSection();
|
|
23321
|
+
init_IconPicker();
|
|
23322
|
+
init_AssetPicker();
|
|
23323
|
+
init_JsonTreeEditor();
|
|
23324
|
+
init_NodeSlotEditor();
|
|
23325
|
+
TIER_ORDER = ["presentation", "domain", "policy", "infra", "internal"];
|
|
23326
|
+
SCALAR_TYPES = /* @__PURE__ */ new Set(["string", "number", "boolean", "icon", "asset"]);
|
|
23327
|
+
exports.PropertyInspector = ({
|
|
23328
|
+
config,
|
|
23329
|
+
values,
|
|
23330
|
+
onChange,
|
|
23331
|
+
onReset,
|
|
23332
|
+
title,
|
|
23333
|
+
className,
|
|
23334
|
+
assets
|
|
23335
|
+
}) => {
|
|
23336
|
+
const fields = Object.entries(config);
|
|
23337
|
+
const byTier = /* @__PURE__ */ new Map();
|
|
23338
|
+
for (const [name, decl] of fields) {
|
|
23339
|
+
const tier = decl.tier ?? "presentation";
|
|
23340
|
+
const arr = byTier.get(tier) ?? [];
|
|
23341
|
+
arr.push([name, decl]);
|
|
23342
|
+
byTier.set(tier, arr);
|
|
23343
|
+
}
|
|
23344
|
+
const tiers = [...byTier.keys()].sort((a, b) => {
|
|
23345
|
+
const ia = TIER_ORDER.indexOf(a);
|
|
23346
|
+
const ib = TIER_ORDER.indexOf(b);
|
|
23347
|
+
return (ia === -1 ? 99 : ia) - (ib === -1 ? 99 : ib);
|
|
23348
|
+
});
|
|
23349
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", className: cn("w-full", className), children: [
|
|
23350
|
+
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { justify: "between", align: "center", children: [
|
|
23351
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", weight: "bold", children: title ?? "Config" }),
|
|
23352
|
+
onReset !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(exports.Button, { variant: "ghost", size: "sm", icon: "rotate-ccw", label: "Reset", onClick: onReset })
|
|
23353
|
+
] }),
|
|
23354
|
+
fields.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", color: "muted", children: "No configurable properties." }),
|
|
23355
|
+
tiers.map((tier) => /* @__PURE__ */ jsxRuntime.jsx(exports.FormSection, { title: tier, collapsible: true, defaultCollapsed: tier !== "presentation", children: /* @__PURE__ */ jsxRuntime.jsx(exports.VStack, { gap: "sm", children: byTier.get(tier)?.map(([name, decl]) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
23356
|
+
FieldControl,
|
|
23357
|
+
{
|
|
23358
|
+
name,
|
|
23359
|
+
decl,
|
|
23360
|
+
value: currentValue(decl, values?.[name]),
|
|
23361
|
+
onChange,
|
|
23362
|
+
assets
|
|
23363
|
+
},
|
|
23364
|
+
name
|
|
23365
|
+
)) }) }, tier))
|
|
23366
|
+
] });
|
|
22524
23367
|
};
|
|
22525
23368
|
}
|
|
22526
23369
|
});
|
|
@@ -22542,6 +23385,7 @@ var init_NodeSlotEditor = __esm({
|
|
|
22542
23385
|
init_Select();
|
|
22543
23386
|
init_Typography();
|
|
22544
23387
|
init_JsonTreeEditor();
|
|
23388
|
+
init_PropertyInspector();
|
|
22545
23389
|
init_pattern_resolver();
|
|
22546
23390
|
init_cn();
|
|
22547
23391
|
isObj2 = (v) => v !== null && v !== void 0 && typeof v === "object" && !Array.isArray(v);
|
|
@@ -22566,18 +23410,42 @@ var init_NodeSlotEditor = __esm({
|
|
|
22566
23410
|
const pattern = { type: nextType, ...nextProps };
|
|
22567
23411
|
onChange(wasArray || value === void 0 ? [pattern] : pattern);
|
|
22568
23412
|
};
|
|
23413
|
+
const schemaEntries = React74__namespace.default.useMemo(() => {
|
|
23414
|
+
if (!type) return [];
|
|
23415
|
+
const def = getPatternDefinition(type);
|
|
23416
|
+
if (!def?.propsSchema) return [];
|
|
23417
|
+
return Object.entries(def.propsSchema).map(([propName, propDef]) => {
|
|
23418
|
+
const decl = {
|
|
23419
|
+
type: propDef.types?.[0] ?? "string",
|
|
23420
|
+
description: propDef.description,
|
|
23421
|
+
label: propName,
|
|
23422
|
+
...propDef.enumValues && propDef.enumValues.length > 0 ? { values: propDef.enumValues } : {}
|
|
23423
|
+
};
|
|
23424
|
+
return [propName, decl];
|
|
23425
|
+
});
|
|
23426
|
+
}, [type]);
|
|
23427
|
+
const hasSchema = schemaEntries.length > 0;
|
|
22569
23428
|
return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", className: cn("w-full", className), children: [
|
|
22570
23429
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22571
23430
|
exports.Select,
|
|
22572
23431
|
{
|
|
22573
23432
|
options,
|
|
22574
23433
|
value: type,
|
|
22575
|
-
onChange: (
|
|
23434
|
+
onChange: (v) => emit(v, props)
|
|
22576
23435
|
}
|
|
22577
23436
|
),
|
|
22578
23437
|
type !== "" && /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "none", className: "pl-1", children: [
|
|
22579
23438
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", color: "muted", children: "props" }),
|
|
22580
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.
|
|
23439
|
+
hasSchema ? /* @__PURE__ */ jsxRuntime.jsx(exports.VStack, { gap: "xs", children: schemaEntries.map(([propName, decl]) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
23440
|
+
FieldControl,
|
|
23441
|
+
{
|
|
23442
|
+
name: propName,
|
|
23443
|
+
decl,
|
|
23444
|
+
value: props[propName],
|
|
23445
|
+
onChange: (field, val) => emit(type, { ...props, [field]: val })
|
|
23446
|
+
},
|
|
23447
|
+
propName
|
|
23448
|
+
)) }) : /* @__PURE__ */ jsxRuntime.jsx(exports.JsonTreeEditor, { value: props, onChange: (next) => emit(type, isObj2(next) ? next : {}) })
|
|
22581
23449
|
] })
|
|
22582
23450
|
] });
|
|
22583
23451
|
};
|
|
@@ -23017,7 +23885,7 @@ var init_FilterGroup = __esm({
|
|
|
23017
23885
|
exports.Select,
|
|
23018
23886
|
{
|
|
23019
23887
|
value: selectedValues[filter.field] || "all",
|
|
23020
|
-
onChange: (
|
|
23888
|
+
onChange: (v) => handleFilterSelect(filter.field, v),
|
|
23021
23889
|
options: [
|
|
23022
23890
|
{ value: "all", label: t("filterGroup.all") },
|
|
23023
23891
|
...filter.options?.map((opt) => ({
|
|
@@ -23100,7 +23968,7 @@ var init_FilterGroup = __esm({
|
|
|
23100
23968
|
exports.Select,
|
|
23101
23969
|
{
|
|
23102
23970
|
value: selectedValues[filter.field] || "all",
|
|
23103
|
-
onChange: (
|
|
23971
|
+
onChange: (v) => handleFilterSelect(filter.field, v),
|
|
23104
23972
|
options: [
|
|
23105
23973
|
{ value: "all", label: t("filterGroup.allOf", { label: filter.label }) },
|
|
23106
23974
|
...filter.options?.map((opt) => ({
|
|
@@ -23218,7 +24086,7 @@ var init_FilterGroup = __esm({
|
|
|
23218
24086
|
exports.Select,
|
|
23219
24087
|
{
|
|
23220
24088
|
value: selectedValues[filter.field] || "all",
|
|
23221
|
-
onChange: (
|
|
24089
|
+
onChange: (v) => handleFilterSelect(filter.field, v),
|
|
23222
24090
|
options: [
|
|
23223
24091
|
{ value: "all", label: t("filterGroup.all") },
|
|
23224
24092
|
...filter.options?.map((opt) => ({
|
|
@@ -25160,303 +26028,6 @@ var init_FlipCard = __esm({
|
|
|
25160
26028
|
exports.FlipCard.displayName = "FlipCard";
|
|
25161
26029
|
}
|
|
25162
26030
|
});
|
|
25163
|
-
var ALL_CATEGORY; exports.GridPicker = void 0;
|
|
25164
|
-
var init_GridPicker = __esm({
|
|
25165
|
-
"components/core/molecules/GridPicker.tsx"() {
|
|
25166
|
-
"use client";
|
|
25167
|
-
init_cn();
|
|
25168
|
-
init_Input();
|
|
25169
|
-
init_Badge();
|
|
25170
|
-
init_Stack();
|
|
25171
|
-
ALL_CATEGORY = "__all__";
|
|
25172
|
-
exports.GridPicker = ({
|
|
25173
|
-
items,
|
|
25174
|
-
value,
|
|
25175
|
-
onChange,
|
|
25176
|
-
categories,
|
|
25177
|
-
searchPlaceholder,
|
|
25178
|
-
renderThumbnail,
|
|
25179
|
-
cellSize = 32,
|
|
25180
|
-
className
|
|
25181
|
-
}) => {
|
|
25182
|
-
const [search, setSearch] = React74.useState("");
|
|
25183
|
-
const [activeCategory, setActiveCategory] = React74.useState(ALL_CATEGORY);
|
|
25184
|
-
const gridRef = React74.useRef(null);
|
|
25185
|
-
const categoryChips = React74.useMemo(() => {
|
|
25186
|
-
if (categories !== void 0) return categories;
|
|
25187
|
-
const seen = [];
|
|
25188
|
-
for (const item of items) {
|
|
25189
|
-
if (!seen.includes(item.category)) seen.push(item.category);
|
|
25190
|
-
}
|
|
25191
|
-
return seen;
|
|
25192
|
-
}, [categories, items]);
|
|
25193
|
-
const filtered = React74.useMemo(() => {
|
|
25194
|
-
const needle = search.trim().toLowerCase();
|
|
25195
|
-
return items.filter((item) => {
|
|
25196
|
-
const matchesCategory = activeCategory === ALL_CATEGORY || item.category === activeCategory;
|
|
25197
|
-
const matchesSearch = needle === "" || item.label.toLowerCase().includes(needle);
|
|
25198
|
-
return matchesCategory && matchesSearch;
|
|
25199
|
-
});
|
|
25200
|
-
}, [items, search, activeCategory]);
|
|
25201
|
-
const select = React74.useCallback(
|
|
25202
|
-
(item) => {
|
|
25203
|
-
onChange(item.id);
|
|
25204
|
-
},
|
|
25205
|
-
[onChange]
|
|
25206
|
-
);
|
|
25207
|
-
const handleKeyDown = React74.useCallback(
|
|
25208
|
-
(e, index) => {
|
|
25209
|
-
const cells = gridRef.current?.querySelectorAll(
|
|
25210
|
-
"[data-gridpicker-cell]"
|
|
25211
|
-
);
|
|
25212
|
-
if (cells === void 0 || cells.length === 0) return;
|
|
25213
|
-
const columns = (() => {
|
|
25214
|
-
const grid = gridRef.current;
|
|
25215
|
-
if (grid === null) return 1;
|
|
25216
|
-
const style = window.getComputedStyle(grid);
|
|
25217
|
-
const cols = style.gridTemplateColumns.split(" ").filter(Boolean).length;
|
|
25218
|
-
return cols > 0 ? cols : 1;
|
|
25219
|
-
})();
|
|
25220
|
-
let next = -1;
|
|
25221
|
-
if (e.key === "ArrowRight") next = index + 1;
|
|
25222
|
-
else if (e.key === "ArrowLeft") next = index - 1;
|
|
25223
|
-
else if (e.key === "ArrowDown") next = index + columns;
|
|
25224
|
-
else if (e.key === "ArrowUp") next = index - columns;
|
|
25225
|
-
else if (e.key === "Enter" || e.key === " ") {
|
|
25226
|
-
e.preventDefault();
|
|
25227
|
-
select(filtered[index]);
|
|
25228
|
-
return;
|
|
25229
|
-
} else {
|
|
25230
|
-
return;
|
|
25231
|
-
}
|
|
25232
|
-
e.preventDefault();
|
|
25233
|
-
if (next >= 0 && next < cells.length) {
|
|
25234
|
-
cells[next].focus();
|
|
25235
|
-
}
|
|
25236
|
-
},
|
|
25237
|
-
[filtered, select]
|
|
25238
|
-
);
|
|
25239
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", className: cn("w-full", className), children: [
|
|
25240
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
25241
|
-
exports.Input,
|
|
25242
|
-
{
|
|
25243
|
-
type: "search",
|
|
25244
|
-
icon: "search",
|
|
25245
|
-
value: search,
|
|
25246
|
-
placeholder: searchPlaceholder,
|
|
25247
|
-
clearable: true,
|
|
25248
|
-
onClear: () => setSearch(""),
|
|
25249
|
-
onChange: (e) => setSearch(e.target.value)
|
|
25250
|
-
}
|
|
25251
|
-
),
|
|
25252
|
-
categoryChips.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", wrap: true, children: [
|
|
25253
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
25254
|
-
exports.Badge,
|
|
25255
|
-
{
|
|
25256
|
-
variant: activeCategory === ALL_CATEGORY ? "primary" : "neutral",
|
|
25257
|
-
size: "sm",
|
|
25258
|
-
role: "button",
|
|
25259
|
-
tabIndex: 0,
|
|
25260
|
-
"aria-pressed": activeCategory === ALL_CATEGORY,
|
|
25261
|
-
className: "cursor-pointer",
|
|
25262
|
-
onClick: () => setActiveCategory(ALL_CATEGORY),
|
|
25263
|
-
onKeyDown: (e) => {
|
|
25264
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
25265
|
-
e.preventDefault();
|
|
25266
|
-
setActiveCategory(ALL_CATEGORY);
|
|
25267
|
-
}
|
|
25268
|
-
},
|
|
25269
|
-
children: "All"
|
|
25270
|
-
}
|
|
25271
|
-
),
|
|
25272
|
-
categoryChips.map((category) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
25273
|
-
exports.Badge,
|
|
25274
|
-
{
|
|
25275
|
-
variant: activeCategory === category ? "primary" : "neutral",
|
|
25276
|
-
size: "sm",
|
|
25277
|
-
role: "button",
|
|
25278
|
-
tabIndex: 0,
|
|
25279
|
-
"aria-pressed": activeCategory === category,
|
|
25280
|
-
className: "cursor-pointer",
|
|
25281
|
-
onClick: () => setActiveCategory(category),
|
|
25282
|
-
onKeyDown: (e) => {
|
|
25283
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
25284
|
-
e.preventDefault();
|
|
25285
|
-
setActiveCategory(category);
|
|
25286
|
-
}
|
|
25287
|
-
},
|
|
25288
|
-
children: category
|
|
25289
|
-
},
|
|
25290
|
-
category
|
|
25291
|
-
))
|
|
25292
|
-
] }),
|
|
25293
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
25294
|
-
"div",
|
|
25295
|
-
{
|
|
25296
|
-
ref: gridRef,
|
|
25297
|
-
role: "listbox",
|
|
25298
|
-
className: "grid gap-1 overflow-y-auto max-h-64 p-1",
|
|
25299
|
-
style: {
|
|
25300
|
-
gridTemplateColumns: `repeat(auto-fill, minmax(${cellSize}px, 1fr))`
|
|
25301
|
-
},
|
|
25302
|
-
children: filtered.map((item, index) => {
|
|
25303
|
-
const selected = item.id === value;
|
|
25304
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
25305
|
-
"button",
|
|
25306
|
-
{
|
|
25307
|
-
type: "button",
|
|
25308
|
-
role: "option",
|
|
25309
|
-
"aria-selected": selected,
|
|
25310
|
-
"aria-label": item.label,
|
|
25311
|
-
title: item.label,
|
|
25312
|
-
"data-gridpicker-cell": true,
|
|
25313
|
-
tabIndex: selected || value === void 0 && index === 0 ? 0 : -1,
|
|
25314
|
-
onClick: () => select(item),
|
|
25315
|
-
onKeyDown: (e) => handleKeyDown(e, index),
|
|
25316
|
-
className: cn(
|
|
25317
|
-
"flex items-center justify-center rounded-sm",
|
|
25318
|
-
"transition-colors hover:bg-muted",
|
|
25319
|
-
"focus:outline-none focus:ring-1 focus:ring-ring",
|
|
25320
|
-
selected && "bg-primary/10 ring-1 ring-primary"
|
|
25321
|
-
),
|
|
25322
|
-
style: { width: cellSize, height: cellSize },
|
|
25323
|
-
children: renderThumbnail(item)
|
|
25324
|
-
},
|
|
25325
|
-
item.id
|
|
25326
|
-
);
|
|
25327
|
-
})
|
|
25328
|
-
}
|
|
25329
|
-
)
|
|
25330
|
-
] });
|
|
25331
|
-
};
|
|
25332
|
-
exports.GridPicker.displayName = "GridPicker";
|
|
25333
|
-
}
|
|
25334
|
-
});
|
|
25335
|
-
function iconForKind(kind) {
|
|
25336
|
-
if (kind === "audio") return "music";
|
|
25337
|
-
if (kind === "model") return "box";
|
|
25338
|
-
return "file";
|
|
25339
|
-
}
|
|
25340
|
-
var THUMB_PX, IMAGE_KINDS; exports.AssetPicker = void 0;
|
|
25341
|
-
var init_AssetPicker = __esm({
|
|
25342
|
-
"components/core/molecules/AssetPicker.tsx"() {
|
|
25343
|
-
"use client";
|
|
25344
|
-
init_GridPicker();
|
|
25345
|
-
init_Icon();
|
|
25346
|
-
THUMB_PX = 32;
|
|
25347
|
-
IMAGE_KINDS = /* @__PURE__ */ new Set([
|
|
25348
|
-
"image",
|
|
25349
|
-
"spritesheet",
|
|
25350
|
-
"scene",
|
|
25351
|
-
"portrait"
|
|
25352
|
-
]);
|
|
25353
|
-
exports.AssetPicker = ({
|
|
25354
|
-
assets,
|
|
25355
|
-
value,
|
|
25356
|
-
onChange,
|
|
25357
|
-
className
|
|
25358
|
-
}) => {
|
|
25359
|
-
const byUrl = React74.useMemo(() => {
|
|
25360
|
-
const map = /* @__PURE__ */ new Map();
|
|
25361
|
-
for (const entry of assets) map.set(entry.url, entry);
|
|
25362
|
-
return map;
|
|
25363
|
-
}, [assets]);
|
|
25364
|
-
const items = React74.useMemo(
|
|
25365
|
-
() => assets.map((entry) => ({
|
|
25366
|
-
id: entry.url,
|
|
25367
|
-
label: entry.name,
|
|
25368
|
-
category: entry.category
|
|
25369
|
-
})),
|
|
25370
|
-
[assets]
|
|
25371
|
-
);
|
|
25372
|
-
const categories = React74.useMemo(() => {
|
|
25373
|
-
const seen = [];
|
|
25374
|
-
for (const entry of assets) {
|
|
25375
|
-
if (!seen.includes(entry.category)) seen.push(entry.category);
|
|
25376
|
-
}
|
|
25377
|
-
return seen;
|
|
25378
|
-
}, [assets]);
|
|
25379
|
-
const renderThumbnail = React74.useCallback(
|
|
25380
|
-
(item) => {
|
|
25381
|
-
const entry = byUrl.get(item.id);
|
|
25382
|
-
if (entry === void 0) return null;
|
|
25383
|
-
if (IMAGE_KINDS.has(entry.kind)) {
|
|
25384
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
25385
|
-
"img",
|
|
25386
|
-
{
|
|
25387
|
-
src: entry.thumbnailUrl ?? entry.url,
|
|
25388
|
-
alt: entry.name,
|
|
25389
|
-
loading: "lazy",
|
|
25390
|
-
width: THUMB_PX,
|
|
25391
|
-
height: THUMB_PX,
|
|
25392
|
-
style: { width: THUMB_PX, height: THUMB_PX, objectFit: "cover" }
|
|
25393
|
-
}
|
|
25394
|
-
);
|
|
25395
|
-
}
|
|
25396
|
-
return /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: iconForKind(entry.kind), size: "sm" });
|
|
25397
|
-
},
|
|
25398
|
-
[byUrl]
|
|
25399
|
-
);
|
|
25400
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
25401
|
-
exports.GridPicker,
|
|
25402
|
-
{
|
|
25403
|
-
items,
|
|
25404
|
-
value,
|
|
25405
|
-
onChange,
|
|
25406
|
-
categories,
|
|
25407
|
-
renderThumbnail,
|
|
25408
|
-
cellSize: THUMB_PX,
|
|
25409
|
-
className
|
|
25410
|
-
}
|
|
25411
|
-
);
|
|
25412
|
-
};
|
|
25413
|
-
exports.AssetPicker.displayName = "AssetPicker";
|
|
25414
|
-
}
|
|
25415
|
-
});
|
|
25416
|
-
function pascalToKebab(name) {
|
|
25417
|
-
return name.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z][a-z])/g, "$1-$2").toLowerCase();
|
|
25418
|
-
}
|
|
25419
|
-
function kebabToPascal3(name) {
|
|
25420
|
-
return name.split("-").map((part) => /^\d+$/.test(part) ? part : part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
25421
|
-
}
|
|
25422
|
-
var ICON_ITEMS; exports.IconPicker = void 0;
|
|
25423
|
-
var init_IconPicker = __esm({
|
|
25424
|
-
"components/core/molecules/IconPicker.tsx"() {
|
|
25425
|
-
"use client";
|
|
25426
|
-
init_Icon();
|
|
25427
|
-
init_GridPicker();
|
|
25428
|
-
ICON_ITEMS = (() => {
|
|
25429
|
-
const items = [];
|
|
25430
|
-
for (const [exportName, candidate] of Object.entries(LucideIcons2__namespace)) {
|
|
25431
|
-
if (!/^[A-Z]/.test(exportName)) continue;
|
|
25432
|
-
if (exportName.endsWith("Icon")) continue;
|
|
25433
|
-
if (exportName.startsWith("Lucide")) continue;
|
|
25434
|
-
const isComponent = candidate !== null && (typeof candidate === "object" || typeof candidate === "function") && "$$typeof" in candidate;
|
|
25435
|
-
if (!isComponent) continue;
|
|
25436
|
-
const kebab = pascalToKebab(exportName);
|
|
25437
|
-
if (kebabToPascal3(kebab) !== exportName) continue;
|
|
25438
|
-
items.push({ id: kebab, label: kebab, category: "icons" });
|
|
25439
|
-
}
|
|
25440
|
-
return items;
|
|
25441
|
-
})();
|
|
25442
|
-
exports.IconPicker = ({ value, onChange, className }) => {
|
|
25443
|
-
const items = React74.useMemo(() => ICON_ITEMS, []);
|
|
25444
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
25445
|
-
exports.GridPicker,
|
|
25446
|
-
{
|
|
25447
|
-
items,
|
|
25448
|
-
value,
|
|
25449
|
-
onChange,
|
|
25450
|
-
searchPlaceholder: "Search icons\u2026",
|
|
25451
|
-
renderThumbnail: (it) => /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: it.id }),
|
|
25452
|
-
cellSize: 32,
|
|
25453
|
-
className
|
|
25454
|
-
}
|
|
25455
|
-
);
|
|
25456
|
-
};
|
|
25457
|
-
exports.IconPicker.displayName = "IconPicker";
|
|
25458
|
-
}
|
|
25459
|
-
});
|
|
25460
26031
|
function toISODate(d) {
|
|
25461
26032
|
return d.toISOString().slice(0, 10);
|
|
25462
26033
|
}
|
|
@@ -28233,13 +28804,13 @@ var init_MapView = __esm({
|
|
|
28233
28804
|
shadowSize: [41, 41]
|
|
28234
28805
|
});
|
|
28235
28806
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
28236
|
-
const { useEffect:
|
|
28807
|
+
const { useEffect: useEffect72, useRef: useRef69, useCallback: useCallback114, useState: useState101 } = React74__namespace.default;
|
|
28237
28808
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
28238
28809
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
28239
28810
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
28240
28811
|
const map = useMap();
|
|
28241
|
-
const prevRef =
|
|
28242
|
-
|
|
28812
|
+
const prevRef = useRef69({ centerLat, centerLng, zoom });
|
|
28813
|
+
useEffect72(() => {
|
|
28243
28814
|
const prev = prevRef.current;
|
|
28244
28815
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
28245
28816
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -28250,7 +28821,7 @@ var init_MapView = __esm({
|
|
|
28250
28821
|
}
|
|
28251
28822
|
function MapClickHandler({ onMapClick }) {
|
|
28252
28823
|
const map = useMap();
|
|
28253
|
-
|
|
28824
|
+
useEffect72(() => {
|
|
28254
28825
|
if (!onMapClick) return;
|
|
28255
28826
|
const handler = (e) => {
|
|
28256
28827
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -28278,7 +28849,7 @@ var init_MapView = __esm({
|
|
|
28278
28849
|
showAttribution = true
|
|
28279
28850
|
}) {
|
|
28280
28851
|
const eventBus = useEventBus2();
|
|
28281
|
-
const [clickedPosition, setClickedPosition] =
|
|
28852
|
+
const [clickedPosition, setClickedPosition] = useState101(null);
|
|
28282
28853
|
const handleMapClick = useCallback114((lat, lng) => {
|
|
28283
28854
|
if (showClickedPin) {
|
|
28284
28855
|
setClickedPosition({ lat, lng });
|
|
@@ -33714,8 +34285,8 @@ var init_VersionDiff = __esm({
|
|
|
33714
34285
|
return { added, removed };
|
|
33715
34286
|
}, [diff]);
|
|
33716
34287
|
const handleBeforeChange = React74.useCallback(
|
|
33717
|
-
(
|
|
33718
|
-
const id =
|
|
34288
|
+
(v) => {
|
|
34289
|
+
const id = v;
|
|
33719
34290
|
setInternalBefore(id);
|
|
33720
34291
|
onSelectBefore?.(id);
|
|
33721
34292
|
if (selectBeforeEvent) eventBus.emit(`UI:${selectBeforeEvent}`, { id });
|
|
@@ -33723,8 +34294,8 @@ var init_VersionDiff = __esm({
|
|
|
33723
34294
|
[onSelectBefore, selectBeforeEvent, eventBus]
|
|
33724
34295
|
);
|
|
33725
34296
|
const handleAfterChange = React74.useCallback(
|
|
33726
|
-
(
|
|
33727
|
-
const id =
|
|
34297
|
+
(v) => {
|
|
34298
|
+
const id = v;
|
|
33728
34299
|
setInternalAfter(id);
|
|
33729
34300
|
onSelectAfter?.(id);
|
|
33730
34301
|
if (selectAfterEvent) eventBus.emit(`UI:${selectAfterEvent}`, { id });
|
|
@@ -35147,286 +35718,6 @@ var init_PageHeader = __esm({
|
|
|
35147
35718
|
exports.PageHeader.displayName = "PageHeader";
|
|
35148
35719
|
}
|
|
35149
35720
|
});
|
|
35150
|
-
exports.FormSection = void 0; exports.FormLayout = void 0; exports.FormActions = void 0;
|
|
35151
|
-
var init_FormSection = __esm({
|
|
35152
|
-
"components/core/molecules/FormSection.tsx"() {
|
|
35153
|
-
"use client";
|
|
35154
|
-
init_cn();
|
|
35155
|
-
init_atoms2();
|
|
35156
|
-
init_Box();
|
|
35157
|
-
init_Typography();
|
|
35158
|
-
init_Button();
|
|
35159
|
-
init_Stack();
|
|
35160
|
-
init_Icon();
|
|
35161
|
-
init_useEventBus();
|
|
35162
|
-
exports.FormSection = ({
|
|
35163
|
-
title,
|
|
35164
|
-
description,
|
|
35165
|
-
children,
|
|
35166
|
-
collapsible = false,
|
|
35167
|
-
defaultCollapsed = false,
|
|
35168
|
-
card = false,
|
|
35169
|
-
columns = 1,
|
|
35170
|
-
className
|
|
35171
|
-
}) => {
|
|
35172
|
-
const [collapsed, setCollapsed] = React74__namespace.default.useState(defaultCollapsed);
|
|
35173
|
-
const { t } = hooks.useTranslate();
|
|
35174
|
-
const eventBus = useEventBus();
|
|
35175
|
-
const gridClass = {
|
|
35176
|
-
1: "grid-cols-1",
|
|
35177
|
-
2: "grid-cols-1 md:grid-cols-2",
|
|
35178
|
-
3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
|
|
35179
|
-
}[columns];
|
|
35180
|
-
React74__namespace.default.useCallback(() => {
|
|
35181
|
-
if (collapsible) {
|
|
35182
|
-
setCollapsed((prev) => !prev);
|
|
35183
|
-
eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
|
|
35184
|
-
}
|
|
35185
|
-
}, [collapsible, collapsed, eventBus]);
|
|
35186
|
-
const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
35187
|
-
(title || description) && /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", className: "mb-4", children: [
|
|
35188
|
-
title && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
35189
|
-
exports.HStack,
|
|
35190
|
-
{
|
|
35191
|
-
justify: "between",
|
|
35192
|
-
align: "center",
|
|
35193
|
-
className: cn(collapsible && "cursor-pointer"),
|
|
35194
|
-
action: collapsible ? "TOGGLE_COLLAPSE" : void 0,
|
|
35195
|
-
children: [
|
|
35196
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h3", weight: "semibold", children: title }),
|
|
35197
|
-
collapsible && /* @__PURE__ */ jsxRuntime.jsx(
|
|
35198
|
-
exports.Button,
|
|
35199
|
-
{
|
|
35200
|
-
variant: "ghost",
|
|
35201
|
-
size: "sm",
|
|
35202
|
-
action: "TOGGLE_COLLAPSE",
|
|
35203
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
35204
|
-
exports.Icon,
|
|
35205
|
-
{
|
|
35206
|
-
icon: LucideIcons2.ChevronDown,
|
|
35207
|
-
size: "sm",
|
|
35208
|
-
className: cn(
|
|
35209
|
-
"text-muted-foreground transition-transform",
|
|
35210
|
-
collapsed && "rotate-180"
|
|
35211
|
-
)
|
|
35212
|
-
}
|
|
35213
|
-
)
|
|
35214
|
-
}
|
|
35215
|
-
)
|
|
35216
|
-
]
|
|
35217
|
-
}
|
|
35218
|
-
),
|
|
35219
|
-
description && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "small", color: "secondary", children: description })
|
|
35220
|
-
] }),
|
|
35221
|
-
(!collapsible || !collapsed) && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: cn("grid gap-4", gridClass), children })
|
|
35222
|
-
] });
|
|
35223
|
-
if (card) {
|
|
35224
|
-
return /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className: cn("p-6", className), children: content });
|
|
35225
|
-
}
|
|
35226
|
-
return /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className, children: content });
|
|
35227
|
-
};
|
|
35228
|
-
exports.FormSection.displayName = "FormSection";
|
|
35229
|
-
exports.FormLayout = ({
|
|
35230
|
-
children,
|
|
35231
|
-
dividers = true,
|
|
35232
|
-
className
|
|
35233
|
-
}) => {
|
|
35234
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
35235
|
-
exports.VStack,
|
|
35236
|
-
{
|
|
35237
|
-
gap: "lg",
|
|
35238
|
-
className: cn(
|
|
35239
|
-
dividers && "[&>*+*]:pt-8 [&>*+*]:border-t [&>*+*]:border-border",
|
|
35240
|
-
className
|
|
35241
|
-
),
|
|
35242
|
-
children
|
|
35243
|
-
}
|
|
35244
|
-
);
|
|
35245
|
-
};
|
|
35246
|
-
exports.FormLayout.displayName = "FormLayout";
|
|
35247
|
-
exports.FormActions = ({
|
|
35248
|
-
children,
|
|
35249
|
-
sticky = false,
|
|
35250
|
-
align = "right",
|
|
35251
|
-
className
|
|
35252
|
-
}) => {
|
|
35253
|
-
const alignClass2 = {
|
|
35254
|
-
left: "justify-start",
|
|
35255
|
-
right: "justify-end",
|
|
35256
|
-
between: "justify-between",
|
|
35257
|
-
center: "justify-center"
|
|
35258
|
-
}[align];
|
|
35259
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
35260
|
-
exports.HStack,
|
|
35261
|
-
{
|
|
35262
|
-
gap: "sm",
|
|
35263
|
-
align: "center",
|
|
35264
|
-
className: cn(
|
|
35265
|
-
"pt-6 border-t border-border",
|
|
35266
|
-
alignClass2,
|
|
35267
|
-
sticky && "sticky bottom-0 bg-card py-4 -mx-6 px-6 shadow-[0_-4px_6px_-1px_rgb(0,0,0,0.05)]",
|
|
35268
|
-
className
|
|
35269
|
-
),
|
|
35270
|
-
children
|
|
35271
|
-
}
|
|
35272
|
-
);
|
|
35273
|
-
};
|
|
35274
|
-
exports.FormActions.displayName = "FormActions";
|
|
35275
|
-
}
|
|
35276
|
-
});
|
|
35277
|
-
function currentValue(decl, override) {
|
|
35278
|
-
return override !== void 0 ? override : decl.default;
|
|
35279
|
-
}
|
|
35280
|
-
function TextLikeControl({
|
|
35281
|
-
field,
|
|
35282
|
-
numeric,
|
|
35283
|
-
value,
|
|
35284
|
-
onCommit
|
|
35285
|
-
}) {
|
|
35286
|
-
const initial = value === void 0 || value === null ? "" : String(value);
|
|
35287
|
-
const [draft, setDraft] = React74__namespace.default.useState(initial);
|
|
35288
|
-
React74__namespace.default.useEffect(() => setDraft(initial), [initial]);
|
|
35289
|
-
const commit = () => {
|
|
35290
|
-
if (numeric) {
|
|
35291
|
-
const n = draft.trim() === "" ? 0 : Number(draft);
|
|
35292
|
-
onCommit(field, Number.isNaN(n) ? 0 : n);
|
|
35293
|
-
} else {
|
|
35294
|
-
onCommit(field, draft);
|
|
35295
|
-
}
|
|
35296
|
-
};
|
|
35297
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
35298
|
-
exports.Input,
|
|
35299
|
-
{
|
|
35300
|
-
inputType: numeric ? "number" : "text",
|
|
35301
|
-
value: draft,
|
|
35302
|
-
onChange: (e) => setDraft(e.target.value),
|
|
35303
|
-
onBlur: commit,
|
|
35304
|
-
onKeyDown: (e) => {
|
|
35305
|
-
if (e.key === "Enter") commit();
|
|
35306
|
-
}
|
|
35307
|
-
}
|
|
35308
|
-
);
|
|
35309
|
-
}
|
|
35310
|
-
function isTraitConfigObject(v) {
|
|
35311
|
-
return v !== null && v !== void 0 && typeof v === "object" && !Array.isArray(v);
|
|
35312
|
-
}
|
|
35313
|
-
function FieldControl({
|
|
35314
|
-
name,
|
|
35315
|
-
decl,
|
|
35316
|
-
value,
|
|
35317
|
-
onChange,
|
|
35318
|
-
assets
|
|
35319
|
-
}) {
|
|
35320
|
-
let control;
|
|
35321
|
-
const stringValue = typeof value === "string" ? value : void 0;
|
|
35322
|
-
const effectiveValue = value ?? decl.default;
|
|
35323
|
-
if (decl.type === "icon") {
|
|
35324
|
-
control = /* @__PURE__ */ jsxRuntime.jsx(exports.IconPicker, { value: stringValue, onChange: (icon) => onChange(name, icon) });
|
|
35325
|
-
} else if (decl.type === "asset") {
|
|
35326
|
-
control = /* @__PURE__ */ jsxRuntime.jsx(
|
|
35327
|
-
exports.AssetPicker,
|
|
35328
|
-
{
|
|
35329
|
-
assets: assets ?? [],
|
|
35330
|
-
value: stringValue,
|
|
35331
|
-
onChange: (url) => onChange(name, url)
|
|
35332
|
-
}
|
|
35333
|
-
);
|
|
35334
|
-
} else if (decl.type === "boolean") {
|
|
35335
|
-
control = /* @__PURE__ */ jsxRuntime.jsx(exports.Switch, { checked: value === true, onChange: (c) => onChange(name, c) });
|
|
35336
|
-
} else if (decl.type === "string" && decl.values !== void 0 && decl.values.length > 0) {
|
|
35337
|
-
control = /* @__PURE__ */ jsxRuntime.jsx(
|
|
35338
|
-
exports.Select,
|
|
35339
|
-
{
|
|
35340
|
-
options: decl.values.map((v) => ({ value: v, label: v })),
|
|
35341
|
-
value: typeof value === "string" ? value : "",
|
|
35342
|
-
onChange: (e) => onChange(name, e.target.value)
|
|
35343
|
-
}
|
|
35344
|
-
);
|
|
35345
|
-
} else if (decl.type === "number") {
|
|
35346
|
-
control = /* @__PURE__ */ jsxRuntime.jsx(TextLikeControl, { field: name, numeric: true, value, onCommit: onChange });
|
|
35347
|
-
} else if (decl.type === "string") {
|
|
35348
|
-
control = /* @__PURE__ */ jsxRuntime.jsx(TextLikeControl, { field: name, numeric: false, value, onCommit: onChange });
|
|
35349
|
-
} else if (decl.type === "node") {
|
|
35350
|
-
control = /* @__PURE__ */ jsxRuntime.jsx(exports.NodeSlotEditor, { value: effectiveValue, onChange: (next) => onChange(name, next) });
|
|
35351
|
-
} else if (decl.type.startsWith("[") || Array.isArray(effectiveValue)) {
|
|
35352
|
-
const arr = Array.isArray(effectiveValue) ? effectiveValue : [];
|
|
35353
|
-
control = /* @__PURE__ */ jsxRuntime.jsx(exports.JsonTreeEditor, { value: arr, onChange: (next) => onChange(name, next) });
|
|
35354
|
-
} else if (decl.type === "object" || decl.type.startsWith("Map ") || !SCALAR_TYPES.has(decl.type) && isTraitConfigObject(effectiveValue)) {
|
|
35355
|
-
const obj = isTraitConfigObject(effectiveValue) ? effectiveValue : {};
|
|
35356
|
-
control = /* @__PURE__ */ jsxRuntime.jsx(exports.JsonTreeEditor, { value: obj, onChange: (next) => onChange(name, next) });
|
|
35357
|
-
} else {
|
|
35358
|
-
control = /* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { variant: "caption", color: "muted", children: [
|
|
35359
|
-
decl.type,
|
|
35360
|
-
" \u2014 edit in source"
|
|
35361
|
-
] });
|
|
35362
|
-
}
|
|
35363
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", children: [
|
|
35364
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "label", children: decl.label ?? name }),
|
|
35365
|
-
control,
|
|
35366
|
-
decl.description !== void 0 && decl.description !== "" && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", color: "muted", children: decl.description })
|
|
35367
|
-
] });
|
|
35368
|
-
}
|
|
35369
|
-
var TIER_ORDER, SCALAR_TYPES; exports.PropertyInspector = void 0;
|
|
35370
|
-
var init_PropertyInspector = __esm({
|
|
35371
|
-
"components/core/molecules/PropertyInspector.tsx"() {
|
|
35372
|
-
"use client";
|
|
35373
|
-
init_cn();
|
|
35374
|
-
init_Stack();
|
|
35375
|
-
init_Typography();
|
|
35376
|
-
init_Button();
|
|
35377
|
-
init_Switch();
|
|
35378
|
-
init_Select();
|
|
35379
|
-
init_Input();
|
|
35380
|
-
init_FormSection();
|
|
35381
|
-
init_IconPicker();
|
|
35382
|
-
init_AssetPicker();
|
|
35383
|
-
init_JsonTreeEditor();
|
|
35384
|
-
init_NodeSlotEditor();
|
|
35385
|
-
TIER_ORDER = ["presentation", "domain", "policy", "infra", "internal"];
|
|
35386
|
-
SCALAR_TYPES = /* @__PURE__ */ new Set(["string", "number", "boolean", "icon", "asset"]);
|
|
35387
|
-
exports.PropertyInspector = ({
|
|
35388
|
-
config,
|
|
35389
|
-
values,
|
|
35390
|
-
onChange,
|
|
35391
|
-
onReset,
|
|
35392
|
-
title,
|
|
35393
|
-
className,
|
|
35394
|
-
assets
|
|
35395
|
-
}) => {
|
|
35396
|
-
const fields = Object.entries(config);
|
|
35397
|
-
const byTier = /* @__PURE__ */ new Map();
|
|
35398
|
-
for (const [name, decl] of fields) {
|
|
35399
|
-
const tier = decl.tier ?? "presentation";
|
|
35400
|
-
const arr = byTier.get(tier) ?? [];
|
|
35401
|
-
arr.push([name, decl]);
|
|
35402
|
-
byTier.set(tier, arr);
|
|
35403
|
-
}
|
|
35404
|
-
const tiers = [...byTier.keys()].sort((a, b) => {
|
|
35405
|
-
const ia = TIER_ORDER.indexOf(a);
|
|
35406
|
-
const ib = TIER_ORDER.indexOf(b);
|
|
35407
|
-
return (ia === -1 ? 99 : ia) - (ib === -1 ? 99 : ib);
|
|
35408
|
-
});
|
|
35409
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", className: cn("w-full", className), children: [
|
|
35410
|
-
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { justify: "between", align: "center", children: [
|
|
35411
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", weight: "bold", children: title ?? "Config" }),
|
|
35412
|
-
onReset !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(exports.Button, { variant: "ghost", size: "sm", icon: "rotate-ccw", label: "Reset", onClick: onReset })
|
|
35413
|
-
] }),
|
|
35414
|
-
fields.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", color: "muted", children: "No configurable properties." }),
|
|
35415
|
-
tiers.map((tier) => /* @__PURE__ */ jsxRuntime.jsx(exports.FormSection, { title: tier, collapsible: true, defaultCollapsed: tier !== "presentation", children: /* @__PURE__ */ jsxRuntime.jsx(exports.VStack, { gap: "sm", children: byTier.get(tier)?.map(([name, decl]) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
35416
|
-
FieldControl,
|
|
35417
|
-
{
|
|
35418
|
-
name,
|
|
35419
|
-
decl,
|
|
35420
|
-
value: currentValue(decl, values?.[name]),
|
|
35421
|
-
onChange,
|
|
35422
|
-
assets
|
|
35423
|
-
},
|
|
35424
|
-
name
|
|
35425
|
-
)) }) }, tier))
|
|
35426
|
-
] });
|
|
35427
|
-
};
|
|
35428
|
-
}
|
|
35429
|
-
});
|
|
35430
35721
|
var lookStyles8; exports.Header = void 0;
|
|
35431
35722
|
var init_Header = __esm({
|
|
35432
35723
|
"components/core/molecules/Header.tsx"() {
|
|
@@ -36782,7 +37073,6 @@ var init_DocumentViewer = __esm({
|
|
|
36782
37073
|
showPrint = false,
|
|
36783
37074
|
actions,
|
|
36784
37075
|
documents,
|
|
36785
|
-
entity,
|
|
36786
37076
|
isLoading = false,
|
|
36787
37077
|
error,
|
|
36788
37078
|
className
|
|
@@ -38851,11 +39141,11 @@ function RuleEditor({
|
|
|
38851
39141
|
className
|
|
38852
39142
|
}) {
|
|
38853
39143
|
const { t } = hooks.useTranslate();
|
|
38854
|
-
const handleWhenChange = React74.useCallback((
|
|
38855
|
-
onChange({ ...rule, whenEvent:
|
|
39144
|
+
const handleWhenChange = React74.useCallback((v) => {
|
|
39145
|
+
onChange({ ...rule, whenEvent: v });
|
|
38856
39146
|
}, [rule, onChange]);
|
|
38857
|
-
const handleThenChange = React74.useCallback((
|
|
38858
|
-
onChange({ ...rule, thenAction:
|
|
39147
|
+
const handleThenChange = React74.useCallback((v) => {
|
|
39148
|
+
onChange({ ...rule, thenAction: v });
|
|
38859
39149
|
}, [rule, onChange]);
|
|
38860
39150
|
return /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { className: cn("items-center p-2 rounded-lg bg-muted/50 border border-border", className), gap: "sm", children: [
|
|
38861
39151
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", className: "text-primary font-bold whitespace-nowrap", children: t("eventHandler.when") }),
|
|
@@ -39931,7 +40221,7 @@ var init_Form = __esm({
|
|
|
39931
40221
|
...commonProps,
|
|
39932
40222
|
options,
|
|
39933
40223
|
value: String(currentValue2),
|
|
39934
|
-
onChange: (
|
|
40224
|
+
onChange: (v) => handleChange(fieldName, v),
|
|
39935
40225
|
placeholder: field.placeholder || `Select ${label}...`
|
|
39936
40226
|
}
|
|
39937
40227
|
);
|
|
@@ -43952,7 +44242,7 @@ function TraitSlot({
|
|
|
43952
44242
|
size = "md",
|
|
43953
44243
|
showTooltip = true,
|
|
43954
44244
|
categoryColors,
|
|
43955
|
-
tooltipFrameUrl,
|
|
44245
|
+
tooltipFrameUrl = "",
|
|
43956
44246
|
className,
|
|
43957
44247
|
feedback,
|
|
43958
44248
|
onItemDrop,
|
|
@@ -47170,18 +47460,32 @@ var init_XPBar = __esm({
|
|
|
47170
47460
|
}
|
|
47171
47461
|
});
|
|
47172
47462
|
function lazyThree(name, loader) {
|
|
47173
|
-
const Lazy = React74__namespace.default.lazy(
|
|
47463
|
+
const Lazy = React74__namespace.default.lazy(
|
|
47464
|
+
() => loader().then((m) => {
|
|
47465
|
+
const Resolved = m[name];
|
|
47466
|
+
if (!Resolved) {
|
|
47467
|
+
throw new Error(
|
|
47468
|
+
`[@almadar/ui] 3D component "${name}" was not found in the three subpath bundle.`
|
|
47469
|
+
);
|
|
47470
|
+
}
|
|
47471
|
+
return { default: Resolved };
|
|
47472
|
+
})
|
|
47473
|
+
);
|
|
47174
47474
|
function ThreeWrapper(props) {
|
|
47175
47475
|
return React74__namespace.default.createElement(
|
|
47176
|
-
|
|
47177
|
-
{
|
|
47178
|
-
React74__namespace.default.createElement(
|
|
47476
|
+
ThreeBoundary,
|
|
47477
|
+
{ name },
|
|
47478
|
+
React74__namespace.default.createElement(
|
|
47479
|
+
React74__namespace.default.Suspense,
|
|
47480
|
+
{ fallback: null },
|
|
47481
|
+
React74__namespace.default.createElement(Lazy, props)
|
|
47482
|
+
)
|
|
47179
47483
|
);
|
|
47180
47484
|
}
|
|
47181
47485
|
ThreeWrapper.displayName = `Lazy(${name})`;
|
|
47182
47486
|
return ThreeWrapper;
|
|
47183
47487
|
}
|
|
47184
|
-
var FeatureRenderer, GameCanvas3D, GameCanvas3DBattleTemplate, GameCanvas3DCastleTemplate, GameCanvas3DWorldMapTemplate, COMPONENT_REGISTRY;
|
|
47488
|
+
var ThreeBoundary, FeatureRenderer, GameCanvas3D, GameCanvas3DBattleTemplate, GameCanvas3DCastleTemplate, GameCanvas3DWorldMapTemplate, COMPONENT_REGISTRY;
|
|
47185
47489
|
var init_component_registry_generated = __esm({
|
|
47186
47490
|
"components/core/organisms/component-registry.generated.ts"() {
|
|
47187
47491
|
init_AboutPageTemplate();
|
|
@@ -47467,6 +47771,28 @@ var init_component_registry_generated = __esm({
|
|
|
47467
47771
|
init_WorldMapBoard();
|
|
47468
47772
|
init_WorldMapTemplate();
|
|
47469
47773
|
init_XPBar();
|
|
47774
|
+
ThreeBoundary = class extends React74__namespace.default.Component {
|
|
47775
|
+
constructor() {
|
|
47776
|
+
super(...arguments);
|
|
47777
|
+
__publicField(this, "state", { failed: false });
|
|
47778
|
+
}
|
|
47779
|
+
static getDerivedStateFromError() {
|
|
47780
|
+
return { failed: true };
|
|
47781
|
+
}
|
|
47782
|
+
render() {
|
|
47783
|
+
if (this.state.failed) {
|
|
47784
|
+
return React74__namespace.default.createElement(
|
|
47785
|
+
"div",
|
|
47786
|
+
{
|
|
47787
|
+
"data-testid": "three-unavailable",
|
|
47788
|
+
style: { padding: 16, fontSize: 13, lineHeight: 1.5, opacity: 0.7 }
|
|
47789
|
+
},
|
|
47790
|
+
`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.`
|
|
47791
|
+
);
|
|
47792
|
+
}
|
|
47793
|
+
return this.props.children;
|
|
47794
|
+
}
|
|
47795
|
+
};
|
|
47470
47796
|
FeatureRenderer = lazyThree("FeatureRenderer", () => import('@almadar/ui/components/molecules/game/three'));
|
|
47471
47797
|
GameCanvas3D = lazyThree("GameCanvas3D", () => import('@almadar/ui/components/molecules/game/three'));
|
|
47472
47798
|
GameCanvas3DBattleTemplate = lazyThree("GameCanvas3DBattleTemplate", () => import('@almadar/ui/components/molecules/game/three'));
|
|
@@ -49749,195 +50075,6 @@ init_StepFlowOrganism();
|
|
|
49749
50075
|
init_ShowcaseOrganism();
|
|
49750
50076
|
init_TeamOrganism();
|
|
49751
50077
|
init_CaseStudyOrganism();
|
|
49752
|
-
var DEFAULT_FEATURE_CONFIGS = {
|
|
49753
|
-
tree: { color: 2263842, height: 1.5, scale: 1, geometry: "tree" },
|
|
49754
|
-
rock: { color: 8421504, height: 0.5, scale: 0.8, geometry: "rock" },
|
|
49755
|
-
bush: { color: 3329330, height: 0.4, scale: 0.6, geometry: "bush" },
|
|
49756
|
-
house: { color: 9127187, height: 1.2, scale: 1.2, geometry: "house" },
|
|
49757
|
-
tower: { color: 6908265, height: 2.5, scale: 1, geometry: "tower" },
|
|
49758
|
-
wall: { color: 8421504, height: 1, scale: 1, geometry: "wall" },
|
|
49759
|
-
mountain: { color: 5597999, height: 2, scale: 1.5, geometry: "mountain" },
|
|
49760
|
-
hill: { color: 7048739, height: 0.8, scale: 1.2, geometry: "hill" },
|
|
49761
|
-
water: { color: 4491468, height: 0.1, scale: 1, geometry: "water" },
|
|
49762
|
-
chest: { color: 16766720, height: 0.3, scale: 0.4, geometry: "chest" },
|
|
49763
|
-
sign: { color: 9127187, height: 0.8, scale: 0.3, geometry: "sign" },
|
|
49764
|
-
portal: { color: 10040012, height: 1.5, scale: 1, geometry: "portal" }
|
|
49765
|
-
};
|
|
49766
|
-
function TreeFeature({ height, color }) {
|
|
49767
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
49768
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, height * 0.3, 0], children: [
|
|
49769
|
-
/* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.08, 0.1, height * 0.6, 6] }),
|
|
49770
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: 9127187 })
|
|
49771
|
-
] }),
|
|
49772
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, height * 0.7, 0], children: [
|
|
49773
|
-
/* @__PURE__ */ jsxRuntime.jsx("coneGeometry", { args: [0.4, height * 0.5, 8] }),
|
|
49774
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color })
|
|
49775
|
-
] }),
|
|
49776
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, height * 0.9, 0], children: [
|
|
49777
|
-
/* @__PURE__ */ jsxRuntime.jsx("coneGeometry", { args: [0.3, height * 0.4, 8] }),
|
|
49778
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color })
|
|
49779
|
-
] }),
|
|
49780
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, height * 1.05, 0], children: [
|
|
49781
|
-
/* @__PURE__ */ jsxRuntime.jsx("coneGeometry", { args: [0.15, height * 0.25, 8] }),
|
|
49782
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color })
|
|
49783
|
-
] })
|
|
49784
|
-
] });
|
|
49785
|
-
}
|
|
49786
|
-
function RockFeature({ height, color }) {
|
|
49787
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, height * 0.4, 0], children: [
|
|
49788
|
-
/* @__PURE__ */ jsxRuntime.jsx("dodecahedronGeometry", { args: [height * 0.5, 0] }),
|
|
49789
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color, roughness: 0.9 })
|
|
49790
|
-
] });
|
|
49791
|
-
}
|
|
49792
|
-
function BushFeature({ height, color }) {
|
|
49793
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
49794
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, height * 0.3, 0], children: [
|
|
49795
|
-
/* @__PURE__ */ jsxRuntime.jsx("sphereGeometry", { args: [height * 0.4, 8, 8] }),
|
|
49796
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color })
|
|
49797
|
-
] }),
|
|
49798
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0.1, height * 0.4, 0.1], children: [
|
|
49799
|
-
/* @__PURE__ */ jsxRuntime.jsx("sphereGeometry", { args: [height * 0.25, 8, 8] }),
|
|
49800
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color })
|
|
49801
|
-
] })
|
|
49802
|
-
] });
|
|
49803
|
-
}
|
|
49804
|
-
function HouseFeature({ height, color }) {
|
|
49805
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
49806
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, height * 0.4, 0], children: [
|
|
49807
|
-
/* @__PURE__ */ jsxRuntime.jsx("boxGeometry", { args: [0.8, height * 0.8, 0.8] }),
|
|
49808
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: 13808780 })
|
|
49809
|
-
] }),
|
|
49810
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, height * 0.9, 0], children: [
|
|
49811
|
-
/* @__PURE__ */ jsxRuntime.jsx("coneGeometry", { args: [0.6, height * 0.4, 4] }),
|
|
49812
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color })
|
|
49813
|
-
] }),
|
|
49814
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, height * 0.25, 0.41], children: [
|
|
49815
|
-
/* @__PURE__ */ jsxRuntime.jsx("planeGeometry", { args: [0.25, height * 0.5] }),
|
|
49816
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: 4863784 })
|
|
49817
|
-
] })
|
|
49818
|
-
] });
|
|
49819
|
-
}
|
|
49820
|
-
function TowerFeature({ height, color }) {
|
|
49821
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
49822
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, height * 0.5, 0], children: [
|
|
49823
|
-
/* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.3, 0.35, height, 8] }),
|
|
49824
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color })
|
|
49825
|
-
] }),
|
|
49826
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, height + 0.05, 0], children: [
|
|
49827
|
-
/* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.35, 0.35, 0.1, 8] }),
|
|
49828
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color })
|
|
49829
|
-
] })
|
|
49830
|
-
] });
|
|
49831
|
-
}
|
|
49832
|
-
function ChestFeature({ height, color }) {
|
|
49833
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
49834
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, height * 0.5, 0], children: [
|
|
49835
|
-
/* @__PURE__ */ jsxRuntime.jsx("boxGeometry", { args: [0.3, height, 0.2] }),
|
|
49836
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color, metalness: 0.6, roughness: 0.3 })
|
|
49837
|
-
] }),
|
|
49838
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, height + 0.05, 0], children: [
|
|
49839
|
-
/* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.15, 0.15, 0.3, 8, 1, false, 0, Math.PI] }),
|
|
49840
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color, metalness: 0.6, roughness: 0.3 })
|
|
49841
|
-
] })
|
|
49842
|
-
] });
|
|
49843
|
-
}
|
|
49844
|
-
function DefaultFeature({ height, color }) {
|
|
49845
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, height * 0.5, 0], children: [
|
|
49846
|
-
/* @__PURE__ */ jsxRuntime.jsx("boxGeometry", { args: [0.5, height, 0.5] }),
|
|
49847
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color })
|
|
49848
|
-
] });
|
|
49849
|
-
}
|
|
49850
|
-
function FeatureVisual({
|
|
49851
|
-
feature,
|
|
49852
|
-
position,
|
|
49853
|
-
isSelected,
|
|
49854
|
-
onClick,
|
|
49855
|
-
onHover
|
|
49856
|
-
}) {
|
|
49857
|
-
const config = DEFAULT_FEATURE_CONFIGS[feature.type] || {
|
|
49858
|
-
color: 8947848,
|
|
49859
|
-
height: 0.5,
|
|
49860
|
-
scale: 1,
|
|
49861
|
-
geometry: "default"
|
|
49862
|
-
};
|
|
49863
|
-
const color = feature.color ? parseInt(feature.color.replace("#", ""), 16) : config.color;
|
|
49864
|
-
const renderGeometry = () => {
|
|
49865
|
-
switch (config.geometry) {
|
|
49866
|
-
case "tree":
|
|
49867
|
-
return /* @__PURE__ */ jsxRuntime.jsx(TreeFeature, { height: config.height, color });
|
|
49868
|
-
case "rock":
|
|
49869
|
-
return /* @__PURE__ */ jsxRuntime.jsx(RockFeature, { height: config.height, color });
|
|
49870
|
-
case "bush":
|
|
49871
|
-
return /* @__PURE__ */ jsxRuntime.jsx(BushFeature, { height: config.height, color });
|
|
49872
|
-
case "house":
|
|
49873
|
-
return /* @__PURE__ */ jsxRuntime.jsx(HouseFeature, { height: config.height, color });
|
|
49874
|
-
case "tower":
|
|
49875
|
-
return /* @__PURE__ */ jsxRuntime.jsx(TowerFeature, { height: config.height, color });
|
|
49876
|
-
case "chest":
|
|
49877
|
-
return /* @__PURE__ */ jsxRuntime.jsx(ChestFeature, { height: config.height, color });
|
|
49878
|
-
default:
|
|
49879
|
-
return /* @__PURE__ */ jsxRuntime.jsx(DefaultFeature, { height: config.height, color });
|
|
49880
|
-
}
|
|
49881
|
-
};
|
|
49882
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
49883
|
-
"group",
|
|
49884
|
-
{
|
|
49885
|
-
position,
|
|
49886
|
-
scale: config.scale,
|
|
49887
|
-
onClick,
|
|
49888
|
-
onPointerEnter: () => onHover(true),
|
|
49889
|
-
onPointerLeave: () => onHover(false),
|
|
49890
|
-
userData: { type: "feature", featureId: feature.id, featureType: feature.type },
|
|
49891
|
-
children: [
|
|
49892
|
-
isSelected && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.02, 0], rotation: [-Math.PI / 2, 0, 0], children: [
|
|
49893
|
-
/* @__PURE__ */ jsxRuntime.jsx("ringGeometry", { args: [0.4, 0.5, 32] }),
|
|
49894
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: "#ffff00", transparent: true, opacity: 0.8 })
|
|
49895
|
-
] }),
|
|
49896
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.01, 0], rotation: [-Math.PI / 2, 0, 0], children: [
|
|
49897
|
-
/* @__PURE__ */ jsxRuntime.jsx("circleGeometry", { args: [0.35, 16] }),
|
|
49898
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: "#000000", transparent: true, opacity: 0.2 })
|
|
49899
|
-
] }),
|
|
49900
|
-
renderGeometry()
|
|
49901
|
-
]
|
|
49902
|
-
}
|
|
49903
|
-
);
|
|
49904
|
-
}
|
|
49905
|
-
function FeatureGroup({
|
|
49906
|
-
features,
|
|
49907
|
-
cellSize = 1,
|
|
49908
|
-
offsetX = 0,
|
|
49909
|
-
offsetZ = 0,
|
|
49910
|
-
onFeatureClick,
|
|
49911
|
-
onFeatureHover,
|
|
49912
|
-
selectedFeatureIds = []
|
|
49913
|
-
}) {
|
|
49914
|
-
return /* @__PURE__ */ jsxRuntime.jsx("group", { children: features.map((feature) => {
|
|
49915
|
-
const x = (feature.x - offsetX) * cellSize;
|
|
49916
|
-
const z = ((feature.z ?? feature.y ?? 0) - offsetZ) * cellSize;
|
|
49917
|
-
const y = (feature.elevation ?? 0) * 0.1;
|
|
49918
|
-
const isSelected = feature.id ? selectedFeatureIds.includes(feature.id) : false;
|
|
49919
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
49920
|
-
FeatureVisual,
|
|
49921
|
-
{
|
|
49922
|
-
feature,
|
|
49923
|
-
position: [x, y, z],
|
|
49924
|
-
isSelected,
|
|
49925
|
-
onClick: () => onFeatureClick?.(feature),
|
|
49926
|
-
onHover: (hovered) => onFeatureHover?.(hovered ? feature : null)
|
|
49927
|
-
},
|
|
49928
|
-
feature.id ?? `feature-${feature.x}-${feature.y}`
|
|
49929
|
-
);
|
|
49930
|
-
}) });
|
|
49931
|
-
}
|
|
49932
|
-
function FeatureRenderer2(props) {
|
|
49933
|
-
const insideCanvas = React74.useContext(fiber.context) != null;
|
|
49934
|
-
if (insideCanvas) return /* @__PURE__ */ jsxRuntime.jsx(FeatureGroup, { ...props });
|
|
49935
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(fiber.Canvas, { camera: { position: [4, 4, 6], fov: 50 }, style: { width: "100%", height: 360 }, children: [
|
|
49936
|
-
/* @__PURE__ */ jsxRuntime.jsx("ambientLight", { intensity: 0.6 }),
|
|
49937
|
-
/* @__PURE__ */ jsxRuntime.jsx("directionalLight", { position: [5, 8, 5], intensity: 0.8 }),
|
|
49938
|
-
/* @__PURE__ */ jsxRuntime.jsx(FeatureGroup, { ...props })
|
|
49939
|
-
] });
|
|
49940
|
-
}
|
|
49941
50078
|
|
|
49942
50079
|
// components/core/templates/index.ts
|
|
49943
50080
|
init_DashboardLayout();
|
|
@@ -49997,7 +50134,6 @@ exports.EnemyPlate = EnemyPlate;
|
|
|
49997
50134
|
exports.EventHandlerBoard = EventHandlerBoard;
|
|
49998
50135
|
exports.EventLog = EventLog;
|
|
49999
50136
|
exports.FEATURE_TYPES = FEATURE_TYPES;
|
|
50000
|
-
exports.FeatureRenderer = FeatureRenderer2;
|
|
50001
50137
|
exports.GameAudioProvider = GameAudioProvider;
|
|
50002
50138
|
exports.GameAudioToggle = GameAudioToggle;
|
|
50003
50139
|
exports.GameCanvas2D = GameCanvas2D;
|