@almadar/ui 5.28.5 → 5.30.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 +178 -113
- package/dist/avl/index.js +178 -113
- 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/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/organisms/index.d.ts +1 -1
- package/dist/components/core/templates/index.d.ts +3 -0
- package/dist/components/game/{organisms → molecules}/GameCanvas3D.d.ts +1 -3
- package/dist/components/game/molecules/index.d.ts +1 -0
- package/dist/components/game/{organisms → molecules}/three/hooks/useGameCanvas3DEvents.d.ts +1 -1
- package/dist/components/game/{organisms → molecules}/three/index.cjs +29 -4
- package/dist/components/game/{organisms → molecules}/three/index.css +3 -3
- package/dist/components/game/{organisms → molecules}/three/index.js +29 -4
- package/dist/components/game/{organisms → molecules}/three/renderers/FeatureRenderer.d.ts +1 -1
- package/dist/components/game/{organisms → molecules}/three/renderers/FeatureRenderer3D.d.ts +1 -1
- package/dist/components/game/{organisms → molecules}/three/renderers/TileRenderer.d.ts +1 -1
- package/dist/components/game/{organisms → molecules}/three/renderers/UnitRenderer.d.ts +1 -1
- package/dist/components/game/organisms/TraitSlot.d.ts +3 -1
- package/dist/components/game/organisms/index.d.ts +0 -9
- package/dist/components/game/organisms/types/isometric.d.ts +2 -0
- package/dist/components/index.cjs +786 -692
- package/dist/components/index.js +788 -694
- package/dist/providers/index.cjs +178 -113
- package/dist/providers/index.js +178 -113
- package/dist/renderer/pattern-resolver.d.ts +2 -5
- package/dist/runtime/index.cjs +178 -113
- package/dist/runtime/index.js +178 -113
- package/package.json +9 -4
- package/dist/components/game/organisms/CombatLog.d.ts +0 -2
- package/dist/components/game/organisms/DialogueBox.d.ts +0 -2
- package/dist/components/game/organisms/GameHud.d.ts +0 -2
- package/dist/components/game/organisms/GameMenu.d.ts +0 -2
- package/dist/components/game/organisms/GameOverScreen.d.ts +0 -2
- package/dist/components/game/organisms/InventoryPanel.d.ts +0 -2
- package/dist/components/game/organisms/IsometricCanvas.d.ts +0 -3
- package/dist/components/game/organisms/PlatformerCanvas.d.ts +0 -2
- /package/dist/components/game/{organisms → molecules}/three/Camera3D.d.ts +0 -0
- /package/dist/components/game/{organisms → molecules}/three/Lighting3D.d.ts +0 -0
- /package/dist/components/game/{organisms → molecules}/three/Scene3D.d.ts +0 -0
- /package/dist/components/game/{organisms → molecules}/three/components/Canvas3DErrorBoundary.d.ts +0 -0
- /package/dist/components/game/{organisms → molecules}/three/components/Canvas3DLoadingState.d.ts +0 -0
- /package/dist/components/game/{organisms → molecules}/three/components/ModelLoader.d.ts +0 -0
- /package/dist/components/game/{organisms → molecules}/three/components/PhysicsObject3D.d.ts +0 -0
- /package/dist/components/game/{organisms → molecules}/three/components/index.d.ts +0 -0
- /package/dist/components/game/{organisms → molecules}/three/hooks/useAssetLoader.d.ts +0 -0
- /package/dist/components/game/{organisms → molecules}/three/hooks/useRaycaster.d.ts +0 -0
- /package/dist/components/game/{organisms → molecules}/three/hooks/useSceneGraph.d.ts +0 -0
- /package/dist/components/game/{organisms → molecules}/three/hooks/useThree.d.ts +0 -0
- /package/dist/components/game/{organisms → molecules}/three/index.d.ts +0 -0
- /package/dist/components/game/{organisms → molecules}/three/loaders/AssetLoader.d.ts +0 -0
- /package/dist/components/game/{organisms → molecules}/three/renderers/index.d.ts +0 -0
- /package/dist/components/game/{organisms → molecules}/three/utils/culling.d.ts +0 -0
- /package/dist/components/game/{organisms → molecules}/three/utils/grid3D.d.ts +0 -0
|
@@ -7129,11 +7129,15 @@ var init_Skeleton = __esm({
|
|
|
7129
7129
|
function getKnownPatterns() {
|
|
7130
7130
|
return Object.keys(componentMapping);
|
|
7131
7131
|
}
|
|
7132
|
-
|
|
7132
|
+
function getPatternDefinition(type) {
|
|
7133
|
+
return patternRegistry[type];
|
|
7134
|
+
}
|
|
7135
|
+
var componentMapping, patternRegistry;
|
|
7133
7136
|
var init_pattern_resolver = __esm({
|
|
7134
7137
|
"renderer/pattern-resolver.ts"() {
|
|
7135
7138
|
logger.createLogger("almadar:ui:pattern-resolver");
|
|
7136
7139
|
componentMapping = {};
|
|
7140
|
+
patternRegistry = {};
|
|
7137
7141
|
}
|
|
7138
7142
|
});
|
|
7139
7143
|
|
|
@@ -10046,13 +10050,6 @@ var init_IsometricCanvas = __esm({
|
|
|
10046
10050
|
}
|
|
10047
10051
|
});
|
|
10048
10052
|
|
|
10049
|
-
// components/game/organisms/IsometricCanvas.tsx
|
|
10050
|
-
var init_IsometricCanvas2 = __esm({
|
|
10051
|
-
"components/game/organisms/IsometricCanvas.tsx"() {
|
|
10052
|
-
init_IsometricCanvas();
|
|
10053
|
-
}
|
|
10054
|
-
});
|
|
10055
|
-
|
|
10056
10053
|
// components/game/organisms/boardEntity.ts
|
|
10057
10054
|
function boardEntity(entity) {
|
|
10058
10055
|
if (!entity) return void 0;
|
|
@@ -10448,7 +10445,7 @@ var init_BattleBoard = __esm({
|
|
|
10448
10445
|
init_Button();
|
|
10449
10446
|
init_Typography();
|
|
10450
10447
|
init_Stack();
|
|
10451
|
-
|
|
10448
|
+
init_IsometricCanvas();
|
|
10452
10449
|
init_boardEntity();
|
|
10453
10450
|
init_isometric();
|
|
10454
10451
|
BattleBoard.displayName = "BattleBoard";
|
|
@@ -18363,7 +18360,7 @@ var init_CastleBoard = __esm({
|
|
|
18363
18360
|
"use client";
|
|
18364
18361
|
init_cn();
|
|
18365
18362
|
init_useEventBus();
|
|
18366
|
-
|
|
18363
|
+
init_IsometricCanvas();
|
|
18367
18364
|
init_boardEntity();
|
|
18368
18365
|
init_isometric();
|
|
18369
18366
|
CastleBoard.displayName = "CastleBoard";
|
|
@@ -20765,7 +20762,84 @@ var init_DashboardLayout = __esm({
|
|
|
20765
20762
|
NavLinkBottom.displayName = "NavLinkBottom";
|
|
20766
20763
|
}
|
|
20767
20764
|
});
|
|
20768
|
-
|
|
20765
|
+
function computeMenuStyle(position, triggerRect) {
|
|
20766
|
+
const isTop = position.startsWith("top");
|
|
20767
|
+
const isRight = position.endsWith("right") || position.endsWith("end");
|
|
20768
|
+
if (isTop) {
|
|
20769
|
+
return {
|
|
20770
|
+
top: triggerRect.top - MENU_GAP,
|
|
20771
|
+
transform: "translateY(-100%)",
|
|
20772
|
+
...isRight ? { right: window.innerWidth - triggerRect.right } : { left: triggerRect.left }
|
|
20773
|
+
};
|
|
20774
|
+
}
|
|
20775
|
+
return {
|
|
20776
|
+
top: triggerRect.bottom + MENU_GAP,
|
|
20777
|
+
...isRight ? { right: window.innerWidth - triggerRect.right } : { left: triggerRect.left }
|
|
20778
|
+
};
|
|
20779
|
+
}
|
|
20780
|
+
function SubMenu({
|
|
20781
|
+
items,
|
|
20782
|
+
itemRef,
|
|
20783
|
+
direction,
|
|
20784
|
+
eventBus
|
|
20785
|
+
}) {
|
|
20786
|
+
const [rect, setRect] = React74.useState(null);
|
|
20787
|
+
React74.useEffect(() => {
|
|
20788
|
+
if (itemRef) {
|
|
20789
|
+
setRect(itemRef.getBoundingClientRect());
|
|
20790
|
+
}
|
|
20791
|
+
}, [itemRef]);
|
|
20792
|
+
if (!rect) return null;
|
|
20793
|
+
const isRtl = direction === "rtl";
|
|
20794
|
+
const style = {
|
|
20795
|
+
top: rect.top,
|
|
20796
|
+
...isRtl ? { right: window.innerWidth - rect.left } : { left: rect.right }
|
|
20797
|
+
};
|
|
20798
|
+
const panel = /* @__PURE__ */ jsxRuntime.jsx(
|
|
20799
|
+
"div",
|
|
20800
|
+
{
|
|
20801
|
+
className: cn("fixed z-50", menuContainerStyles),
|
|
20802
|
+
style,
|
|
20803
|
+
children: items.map((item, index) => {
|
|
20804
|
+
const isDivider = item.id === "divider" || item.label === "divider";
|
|
20805
|
+
const itemId = item.id ?? `item-${item.label.toLowerCase().replace(/\s+/g, "-")}-${index}`;
|
|
20806
|
+
const isDanger = item.variant === "danger";
|
|
20807
|
+
if (isDivider) {
|
|
20808
|
+
return /* @__PURE__ */ jsxRuntime.jsx(exports.Divider, { className: "my-1" }, `divider-${index}`);
|
|
20809
|
+
}
|
|
20810
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
20811
|
+
exports.Box,
|
|
20812
|
+
{
|
|
20813
|
+
as: "button",
|
|
20814
|
+
onClick: () => {
|
|
20815
|
+
if (item.disabled) return;
|
|
20816
|
+
if (item.event) eventBus.emit(`UI:${item.event}`, { itemId, label: item.label });
|
|
20817
|
+
item.onClick?.();
|
|
20818
|
+
},
|
|
20819
|
+
"aria-disabled": item.disabled || void 0,
|
|
20820
|
+
"data-testid": item.event ? `action-${item.event}` : void 0,
|
|
20821
|
+
className: cn(
|
|
20822
|
+
"w-full flex items-center gap-3 px-4 py-2 text-start",
|
|
20823
|
+
"text-sm transition-colors",
|
|
20824
|
+
"hover:bg-muted focus:outline-none focus:bg-muted",
|
|
20825
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
20826
|
+
item.disabled && "cursor-not-allowed",
|
|
20827
|
+
isDanger && "text-error hover:bg-error/10"
|
|
20828
|
+
),
|
|
20829
|
+
children: [
|
|
20830
|
+
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" })),
|
|
20831
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "small", className: cn("flex-1", isDanger && "text-red-600"), children: item.label }),
|
|
20832
|
+
item.badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto text-xs font-medium", children: item.badge })
|
|
20833
|
+
]
|
|
20834
|
+
},
|
|
20835
|
+
itemId
|
|
20836
|
+
);
|
|
20837
|
+
})
|
|
20838
|
+
}
|
|
20839
|
+
);
|
|
20840
|
+
return typeof document !== "undefined" ? reactDom.createPortal(panel, document.body) : panel;
|
|
20841
|
+
}
|
|
20842
|
+
var MENU_GAP, menuContainerStyles; exports.Menu = void 0;
|
|
20769
20843
|
var init_Menu = __esm({
|
|
20770
20844
|
"components/core/molecules/Menu.tsx"() {
|
|
20771
20845
|
"use client";
|
|
@@ -20776,6 +20850,14 @@ var init_Menu = __esm({
|
|
|
20776
20850
|
init_Badge();
|
|
20777
20851
|
init_cn();
|
|
20778
20852
|
init_useEventBus();
|
|
20853
|
+
MENU_GAP = 4;
|
|
20854
|
+
menuContainerStyles = cn(
|
|
20855
|
+
"bg-card",
|
|
20856
|
+
"border-[length:var(--border-width)] border-border",
|
|
20857
|
+
"shadow-elevation-popover",
|
|
20858
|
+
"rounded-sm",
|
|
20859
|
+
"min-w-0 sm:min-w-[200px] max-w-[calc(100vw-1rem)] py-1"
|
|
20860
|
+
);
|
|
20779
20861
|
exports.Menu = ({
|
|
20780
20862
|
trigger,
|
|
20781
20863
|
items,
|
|
@@ -20783,9 +20865,10 @@ var init_Menu = __esm({
|
|
|
20783
20865
|
className
|
|
20784
20866
|
}) => {
|
|
20785
20867
|
const eventBus = useEventBus();
|
|
20786
|
-
const {
|
|
20868
|
+
const { direction } = hooks.useTranslate();
|
|
20787
20869
|
const [isOpen, setIsOpen] = React74.useState(false);
|
|
20788
20870
|
const [activeSubMenu, setActiveSubMenu] = React74.useState(null);
|
|
20871
|
+
const [activeSubMenuRef, setActiveSubMenuRef] = React74.useState(null);
|
|
20789
20872
|
const [triggerRect, setTriggerRect] = React74.useState(null);
|
|
20790
20873
|
const triggerRef = React74.useRef(null);
|
|
20791
20874
|
const menuRef = React74.useRef(null);
|
|
@@ -20800,13 +20883,14 @@ var init_Menu = __esm({
|
|
|
20800
20883
|
}
|
|
20801
20884
|
setIsOpen(!isOpen);
|
|
20802
20885
|
setActiveSubMenu(null);
|
|
20886
|
+
setActiveSubMenuRef(null);
|
|
20803
20887
|
};
|
|
20804
|
-
const handleItemClick = (item) => {
|
|
20888
|
+
const handleItemClick = (item, itemId) => {
|
|
20805
20889
|
if (item.disabled) return;
|
|
20806
20890
|
if (item.subMenu && item.subMenu.length > 0) {
|
|
20807
|
-
setActiveSubMenu(
|
|
20891
|
+
setActiveSubMenu(itemId);
|
|
20808
20892
|
} else {
|
|
20809
|
-
if (item.event) eventBus.emit(`UI:${item.event}`, { itemId
|
|
20893
|
+
if (item.event) eventBus.emit(`UI:${item.event}`, { itemId, label: item.label });
|
|
20810
20894
|
item.onClick?.();
|
|
20811
20895
|
setIsOpen(false);
|
|
20812
20896
|
}
|
|
@@ -20821,22 +20905,12 @@ var init_Menu = __esm({
|
|
|
20821
20905
|
if (isOpen && menuRef.current && !menuRef.current.contains(e.target) && triggerRef.current && !triggerRef.current.contains(e.target)) {
|
|
20822
20906
|
setIsOpen(false);
|
|
20823
20907
|
setActiveSubMenu(null);
|
|
20908
|
+
setActiveSubMenuRef(null);
|
|
20824
20909
|
}
|
|
20825
20910
|
};
|
|
20826
20911
|
document.addEventListener("mousedown", handleClickOutside);
|
|
20827
20912
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
20828
20913
|
}, [isOpen]);
|
|
20829
|
-
const positionClasses = {
|
|
20830
|
-
"top-left": "bottom-full left-0 mb-2",
|
|
20831
|
-
"top-right": "bottom-full right-0 mb-2",
|
|
20832
|
-
"bottom-left": "top-full left-0 mt-2",
|
|
20833
|
-
"bottom-right": "top-full right-0 mt-2",
|
|
20834
|
-
// Aliases for pattern compatibility
|
|
20835
|
-
"top-start": "bottom-full left-0 mb-2",
|
|
20836
|
-
"top-end": "bottom-full right-0 mb-2",
|
|
20837
|
-
"bottom-start": "top-full left-0 mt-2",
|
|
20838
|
-
"bottom-end": "top-full right-0 mt-2"
|
|
20839
|
-
};
|
|
20840
20914
|
const rtlMirror = {
|
|
20841
20915
|
"top-left": "top-right",
|
|
20842
20916
|
"top-right": "top-left",
|
|
@@ -20848,7 +20922,6 @@ var init_Menu = __esm({
|
|
|
20848
20922
|
"bottom-end": "bottom-start"
|
|
20849
20923
|
};
|
|
20850
20924
|
const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
|
|
20851
|
-
const subMenuSideClass = direction === "rtl" ? "right-full mr-2" : "left-full ml-2";
|
|
20852
20925
|
const triggerChild = React74__namespace.default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "small", as: "span", children: trigger });
|
|
20853
20926
|
const triggerElement = React74__namespace.default.cloneElement(
|
|
20854
20927
|
triggerChild,
|
|
@@ -20857,94 +20930,83 @@ var init_Menu = __esm({
|
|
|
20857
20930
|
onClick: handleToggle
|
|
20858
20931
|
}
|
|
20859
20932
|
);
|
|
20860
|
-
const
|
|
20861
|
-
"
|
|
20862
|
-
"border-[length:var(--border-width)] border-border",
|
|
20863
|
-
"shadow-elevation-popover",
|
|
20864
|
-
"rounded-sm",
|
|
20865
|
-
"min-w-0 sm:min-w-[200px] max-w-[calc(100vw-1rem)] py-1"
|
|
20866
|
-
);
|
|
20867
|
-
const renderMenuItem = (item, hasSubMenu, index) => {
|
|
20933
|
+
const renderMenuItems = (menuItems) => menuItems.map((item, index) => {
|
|
20934
|
+
const isDivider = item.id === "divider" || item.label === "divider";
|
|
20868
20935
|
const itemId = item.id ?? `item-${item.label.toLowerCase().replace(/\s+/g, "-")}-${index}`;
|
|
20936
|
+
const hasSubMenu = !!(item.subMenu && item.subMenu.length > 0);
|
|
20869
20937
|
const isDanger = item.variant === "danger";
|
|
20870
|
-
|
|
20871
|
-
exports.
|
|
20872
|
-
|
|
20873
|
-
|
|
20874
|
-
|
|
20875
|
-
|
|
20876
|
-
|
|
20877
|
-
|
|
20878
|
-
|
|
20879
|
-
"
|
|
20880
|
-
|
|
20881
|
-
|
|
20882
|
-
|
|
20883
|
-
|
|
20884
|
-
item.disabled && "cursor-not-allowed",
|
|
20885
|
-
isDanger && "text-error hover:bg-error/10"
|
|
20886
|
-
),
|
|
20887
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: "flex items-center gap-3 flex-1 min-w-0", children: [
|
|
20888
|
-
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" })),
|
|
20889
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
20890
|
-
exports.Typography,
|
|
20891
|
-
{
|
|
20892
|
-
variant: "small",
|
|
20893
|
-
className: cn("flex-1", isDanger && "text-red-600"),
|
|
20894
|
-
children: item.label
|
|
20938
|
+
if (isDivider) {
|
|
20939
|
+
return /* @__PURE__ */ jsxRuntime.jsx(exports.Divider, { className: "my-1" }, `divider-${index}`);
|
|
20940
|
+
}
|
|
20941
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { children: [
|
|
20942
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
20943
|
+
exports.Box,
|
|
20944
|
+
{
|
|
20945
|
+
as: "button",
|
|
20946
|
+
onClick: () => handleItemClick({ ...item, id: itemId }, itemId),
|
|
20947
|
+
"aria-disabled": item.disabled || void 0,
|
|
20948
|
+
onMouseEnter: (e) => {
|
|
20949
|
+
if (hasSubMenu) {
|
|
20950
|
+
setActiveSubMenu(itemId);
|
|
20951
|
+
setActiveSubMenuRef(e.currentTarget);
|
|
20895
20952
|
}
|
|
20953
|
+
},
|
|
20954
|
+
"data-testid": item.event ? `action-${item.event}` : void 0,
|
|
20955
|
+
className: cn(
|
|
20956
|
+
"w-full flex items-center justify-between gap-3 px-4 py-2 text-start",
|
|
20957
|
+
"text-sm transition-colors",
|
|
20958
|
+
"hover:bg-muted",
|
|
20959
|
+
"focus:outline-none focus:bg-muted",
|
|
20960
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
20961
|
+
item.disabled && "cursor-not-allowed",
|
|
20962
|
+
isDanger && "text-error hover:bg-error/10"
|
|
20896
20963
|
),
|
|
20897
|
-
|
|
20898
|
-
|
|
20899
|
-
|
|
20900
|
-
|
|
20901
|
-
|
|
20902
|
-
|
|
20903
|
-
|
|
20904
|
-
|
|
20905
|
-
|
|
20906
|
-
const hasSubMenu = item.subMenu && item.subMenu.length > 0;
|
|
20907
|
-
const isDivider = item.id === "divider" || item.label === "divider";
|
|
20908
|
-
const itemId = item.id ?? `item-${item.label.toLowerCase().replace(/\s+/g, "-")}-${index}`;
|
|
20909
|
-
if (isDivider) {
|
|
20910
|
-
return /* @__PURE__ */ jsxRuntime.jsx(exports.Divider, { className: "my-1" }, `divider-${index}`);
|
|
20911
|
-
}
|
|
20912
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { children: [
|
|
20913
|
-
renderMenuItem(item, !!hasSubMenu, index),
|
|
20914
|
-
hasSubMenu && activeSubMenu === itemId && item.subMenu && /* @__PURE__ */ jsxRuntime.jsx(
|
|
20915
|
-
exports.Box,
|
|
20916
|
-
{
|
|
20917
|
-
className: cn(
|
|
20918
|
-
"absolute top-0 z-50",
|
|
20919
|
-
subMenuSideClass,
|
|
20920
|
-
menuContainerStyles
|
|
20964
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: "flex items-center gap-3 flex-1 min-w-0", children: [
|
|
20965
|
+
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" })),
|
|
20966
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
20967
|
+
exports.Typography,
|
|
20968
|
+
{
|
|
20969
|
+
variant: "small",
|
|
20970
|
+
className: cn("flex-1", isDanger && "text-red-600"),
|
|
20971
|
+
children: item.label
|
|
20972
|
+
}
|
|
20921
20973
|
),
|
|
20922
|
-
children:
|
|
20923
|
-
|
|
20924
|
-
|
|
20925
|
-
|
|
20926
|
-
|
|
20927
|
-
|
|
20928
|
-
|
|
20974
|
+
item.badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { variant: "default", size: "sm", children: item.badge }),
|
|
20975
|
+
hasSubMenu && /* @__PURE__ */ jsxRuntime.jsx(
|
|
20976
|
+
exports.Icon,
|
|
20977
|
+
{
|
|
20978
|
+
name: direction === "rtl" ? "chevron-left" : "chevron-right",
|
|
20979
|
+
size: "sm",
|
|
20980
|
+
className: "flex-shrink-0"
|
|
20981
|
+
}
|
|
20982
|
+
)
|
|
20983
|
+
] })
|
|
20984
|
+
}
|
|
20985
|
+
),
|
|
20986
|
+
hasSubMenu && activeSubMenu === itemId && item.subMenu && /* @__PURE__ */ jsxRuntime.jsx(
|
|
20987
|
+
SubMenu,
|
|
20988
|
+
{
|
|
20989
|
+
items: item.subMenu,
|
|
20990
|
+
itemRef: activeSubMenuRef,
|
|
20991
|
+
direction,
|
|
20992
|
+
eventBus
|
|
20993
|
+
}
|
|
20994
|
+
)
|
|
20995
|
+
] }, itemId);
|
|
20996
|
+
});
|
|
20997
|
+
const panel = isOpen && triggerRect ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
20998
|
+
"div",
|
|
20999
|
+
{
|
|
21000
|
+
ref: menuRef,
|
|
21001
|
+
className: cn("fixed z-50", menuContainerStyles, className),
|
|
21002
|
+
style: computeMenuStyle(effectivePosition, triggerRect),
|
|
21003
|
+
role: "menu",
|
|
21004
|
+
children: renderMenuItems(items)
|
|
21005
|
+
}
|
|
21006
|
+
) : null;
|
|
21007
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
20929
21008
|
triggerElement,
|
|
20930
|
-
|
|
20931
|
-
exports.Box,
|
|
20932
|
-
{
|
|
20933
|
-
ref: menuRef,
|
|
20934
|
-
className: cn(
|
|
20935
|
-
"absolute z-50",
|
|
20936
|
-
menuContainerStyles,
|
|
20937
|
-
positionClasses[effectivePosition],
|
|
20938
|
-
className
|
|
20939
|
-
),
|
|
20940
|
-
style: {
|
|
20941
|
-
left: effectivePosition.includes("left") ? 0 : "auto",
|
|
20942
|
-
right: effectivePosition.includes("right") ? 0 : "auto"
|
|
20943
|
-
},
|
|
20944
|
-
role: "menu",
|
|
20945
|
-
children: renderMenuItems(items)
|
|
20946
|
-
}
|
|
20947
|
-
)
|
|
21009
|
+
panel && typeof document !== "undefined" ? reactDom.createPortal(panel, document.body) : panel
|
|
20948
21010
|
] });
|
|
20949
21011
|
};
|
|
20950
21012
|
exports.Menu.displayName = "Menu";
|
|
@@ -22531,6 +22593,583 @@ var init_JsonTreeEditor = __esm({
|
|
|
22531
22593
|
};
|
|
22532
22594
|
}
|
|
22533
22595
|
});
|
|
22596
|
+
exports.FormSection = void 0; exports.FormLayout = void 0; exports.FormActions = void 0;
|
|
22597
|
+
var init_FormSection = __esm({
|
|
22598
|
+
"components/core/molecules/FormSection.tsx"() {
|
|
22599
|
+
"use client";
|
|
22600
|
+
init_cn();
|
|
22601
|
+
init_atoms2();
|
|
22602
|
+
init_Box();
|
|
22603
|
+
init_Typography();
|
|
22604
|
+
init_Button();
|
|
22605
|
+
init_Stack();
|
|
22606
|
+
init_Icon();
|
|
22607
|
+
init_useEventBus();
|
|
22608
|
+
exports.FormSection = ({
|
|
22609
|
+
title,
|
|
22610
|
+
description,
|
|
22611
|
+
children,
|
|
22612
|
+
collapsible = false,
|
|
22613
|
+
defaultCollapsed = false,
|
|
22614
|
+
card = false,
|
|
22615
|
+
columns = 1,
|
|
22616
|
+
className
|
|
22617
|
+
}) => {
|
|
22618
|
+
const [collapsed, setCollapsed] = React74__namespace.default.useState(defaultCollapsed);
|
|
22619
|
+
const { t } = hooks.useTranslate();
|
|
22620
|
+
const eventBus = useEventBus();
|
|
22621
|
+
const gridClass = {
|
|
22622
|
+
1: "grid-cols-1",
|
|
22623
|
+
2: "grid-cols-1 md:grid-cols-2",
|
|
22624
|
+
3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
|
|
22625
|
+
}[columns];
|
|
22626
|
+
React74__namespace.default.useCallback(() => {
|
|
22627
|
+
if (collapsible) {
|
|
22628
|
+
setCollapsed((prev) => !prev);
|
|
22629
|
+
eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
|
|
22630
|
+
}
|
|
22631
|
+
}, [collapsible, collapsed, eventBus]);
|
|
22632
|
+
const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
22633
|
+
(title || description) && /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", className: "mb-4", children: [
|
|
22634
|
+
title && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
22635
|
+
exports.HStack,
|
|
22636
|
+
{
|
|
22637
|
+
justify: "between",
|
|
22638
|
+
align: "center",
|
|
22639
|
+
className: cn(collapsible && "cursor-pointer"),
|
|
22640
|
+
action: collapsible ? "TOGGLE_COLLAPSE" : void 0,
|
|
22641
|
+
children: [
|
|
22642
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h3", weight: "semibold", children: title }),
|
|
22643
|
+
collapsible && /* @__PURE__ */ jsxRuntime.jsx(
|
|
22644
|
+
exports.Button,
|
|
22645
|
+
{
|
|
22646
|
+
variant: "ghost",
|
|
22647
|
+
size: "sm",
|
|
22648
|
+
action: "TOGGLE_COLLAPSE",
|
|
22649
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
22650
|
+
exports.Icon,
|
|
22651
|
+
{
|
|
22652
|
+
icon: LucideIcons2.ChevronDown,
|
|
22653
|
+
size: "sm",
|
|
22654
|
+
className: cn(
|
|
22655
|
+
"text-muted-foreground transition-transform",
|
|
22656
|
+
collapsed && "rotate-180"
|
|
22657
|
+
)
|
|
22658
|
+
}
|
|
22659
|
+
)
|
|
22660
|
+
}
|
|
22661
|
+
)
|
|
22662
|
+
]
|
|
22663
|
+
}
|
|
22664
|
+
),
|
|
22665
|
+
description && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "small", color: "secondary", children: description })
|
|
22666
|
+
] }),
|
|
22667
|
+
(!collapsible || !collapsed) && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: cn("grid gap-4", gridClass), children })
|
|
22668
|
+
] });
|
|
22669
|
+
if (card) {
|
|
22670
|
+
return /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className: cn("p-6", className), children: content });
|
|
22671
|
+
}
|
|
22672
|
+
return /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className, children: content });
|
|
22673
|
+
};
|
|
22674
|
+
exports.FormSection.displayName = "FormSection";
|
|
22675
|
+
exports.FormLayout = ({
|
|
22676
|
+
children,
|
|
22677
|
+
dividers = true,
|
|
22678
|
+
className
|
|
22679
|
+
}) => {
|
|
22680
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22681
|
+
exports.VStack,
|
|
22682
|
+
{
|
|
22683
|
+
gap: "lg",
|
|
22684
|
+
className: cn(
|
|
22685
|
+
dividers && "[&>*+*]:pt-8 [&>*+*]:border-t [&>*+*]:border-border",
|
|
22686
|
+
className
|
|
22687
|
+
),
|
|
22688
|
+
children
|
|
22689
|
+
}
|
|
22690
|
+
);
|
|
22691
|
+
};
|
|
22692
|
+
exports.FormLayout.displayName = "FormLayout";
|
|
22693
|
+
exports.FormActions = ({
|
|
22694
|
+
children,
|
|
22695
|
+
sticky = false,
|
|
22696
|
+
align = "right",
|
|
22697
|
+
className
|
|
22698
|
+
}) => {
|
|
22699
|
+
const alignClass2 = {
|
|
22700
|
+
left: "justify-start",
|
|
22701
|
+
right: "justify-end",
|
|
22702
|
+
between: "justify-between",
|
|
22703
|
+
center: "justify-center"
|
|
22704
|
+
}[align];
|
|
22705
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22706
|
+
exports.HStack,
|
|
22707
|
+
{
|
|
22708
|
+
gap: "sm",
|
|
22709
|
+
align: "center",
|
|
22710
|
+
className: cn(
|
|
22711
|
+
"pt-6 border-t border-border",
|
|
22712
|
+
alignClass2,
|
|
22713
|
+
sticky && "sticky bottom-0 bg-card py-4 -mx-6 px-6 shadow-[0_-4px_6px_-1px_rgb(0,0,0,0.05)]",
|
|
22714
|
+
className
|
|
22715
|
+
),
|
|
22716
|
+
children
|
|
22717
|
+
}
|
|
22718
|
+
);
|
|
22719
|
+
};
|
|
22720
|
+
exports.FormActions.displayName = "FormActions";
|
|
22721
|
+
}
|
|
22722
|
+
});
|
|
22723
|
+
var ALL_CATEGORY; exports.GridPicker = void 0;
|
|
22724
|
+
var init_GridPicker = __esm({
|
|
22725
|
+
"components/core/molecules/GridPicker.tsx"() {
|
|
22726
|
+
"use client";
|
|
22727
|
+
init_cn();
|
|
22728
|
+
init_Input();
|
|
22729
|
+
init_Badge();
|
|
22730
|
+
init_Stack();
|
|
22731
|
+
ALL_CATEGORY = "__all__";
|
|
22732
|
+
exports.GridPicker = ({
|
|
22733
|
+
items,
|
|
22734
|
+
value,
|
|
22735
|
+
onChange,
|
|
22736
|
+
categories,
|
|
22737
|
+
searchPlaceholder,
|
|
22738
|
+
renderThumbnail,
|
|
22739
|
+
cellSize = 32,
|
|
22740
|
+
className
|
|
22741
|
+
}) => {
|
|
22742
|
+
const [search, setSearch] = React74.useState("");
|
|
22743
|
+
const [activeCategory, setActiveCategory] = React74.useState(ALL_CATEGORY);
|
|
22744
|
+
const gridRef = React74.useRef(null);
|
|
22745
|
+
const categoryChips = React74.useMemo(() => {
|
|
22746
|
+
if (categories !== void 0) return categories;
|
|
22747
|
+
const seen = [];
|
|
22748
|
+
for (const item of items) {
|
|
22749
|
+
if (!seen.includes(item.category)) seen.push(item.category);
|
|
22750
|
+
}
|
|
22751
|
+
return seen;
|
|
22752
|
+
}, [categories, items]);
|
|
22753
|
+
const filtered = React74.useMemo(() => {
|
|
22754
|
+
const needle = search.trim().toLowerCase();
|
|
22755
|
+
return items.filter((item) => {
|
|
22756
|
+
const matchesCategory = activeCategory === ALL_CATEGORY || item.category === activeCategory;
|
|
22757
|
+
const matchesSearch = needle === "" || item.label.toLowerCase().includes(needle);
|
|
22758
|
+
return matchesCategory && matchesSearch;
|
|
22759
|
+
});
|
|
22760
|
+
}, [items, search, activeCategory]);
|
|
22761
|
+
const select = React74.useCallback(
|
|
22762
|
+
(item) => {
|
|
22763
|
+
onChange(item.id);
|
|
22764
|
+
},
|
|
22765
|
+
[onChange]
|
|
22766
|
+
);
|
|
22767
|
+
const handleKeyDown = React74.useCallback(
|
|
22768
|
+
(e, index) => {
|
|
22769
|
+
const cells = gridRef.current?.querySelectorAll(
|
|
22770
|
+
"[data-gridpicker-cell]"
|
|
22771
|
+
);
|
|
22772
|
+
if (cells === void 0 || cells.length === 0) return;
|
|
22773
|
+
const columns = (() => {
|
|
22774
|
+
const grid = gridRef.current;
|
|
22775
|
+
if (grid === null) return 1;
|
|
22776
|
+
const style = window.getComputedStyle(grid);
|
|
22777
|
+
const cols = style.gridTemplateColumns.split(" ").filter(Boolean).length;
|
|
22778
|
+
return cols > 0 ? cols : 1;
|
|
22779
|
+
})();
|
|
22780
|
+
let next = -1;
|
|
22781
|
+
if (e.key === "ArrowRight") next = index + 1;
|
|
22782
|
+
else if (e.key === "ArrowLeft") next = index - 1;
|
|
22783
|
+
else if (e.key === "ArrowDown") next = index + columns;
|
|
22784
|
+
else if (e.key === "ArrowUp") next = index - columns;
|
|
22785
|
+
else if (e.key === "Enter" || e.key === " ") {
|
|
22786
|
+
e.preventDefault();
|
|
22787
|
+
select(filtered[index]);
|
|
22788
|
+
return;
|
|
22789
|
+
} else {
|
|
22790
|
+
return;
|
|
22791
|
+
}
|
|
22792
|
+
e.preventDefault();
|
|
22793
|
+
if (next >= 0 && next < cells.length) {
|
|
22794
|
+
cells[next].focus();
|
|
22795
|
+
}
|
|
22796
|
+
},
|
|
22797
|
+
[filtered, select]
|
|
22798
|
+
);
|
|
22799
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", className: cn("w-full", className), children: [
|
|
22800
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22801
|
+
exports.Input,
|
|
22802
|
+
{
|
|
22803
|
+
type: "search",
|
|
22804
|
+
icon: "search",
|
|
22805
|
+
value: search,
|
|
22806
|
+
placeholder: searchPlaceholder,
|
|
22807
|
+
clearable: true,
|
|
22808
|
+
onClear: () => setSearch(""),
|
|
22809
|
+
onChange: (e) => setSearch(e.target.value)
|
|
22810
|
+
}
|
|
22811
|
+
),
|
|
22812
|
+
categoryChips.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", wrap: true, children: [
|
|
22813
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22814
|
+
exports.Badge,
|
|
22815
|
+
{
|
|
22816
|
+
variant: activeCategory === ALL_CATEGORY ? "primary" : "neutral",
|
|
22817
|
+
size: "sm",
|
|
22818
|
+
role: "button",
|
|
22819
|
+
tabIndex: 0,
|
|
22820
|
+
"aria-pressed": activeCategory === ALL_CATEGORY,
|
|
22821
|
+
className: "cursor-pointer",
|
|
22822
|
+
onClick: () => setActiveCategory(ALL_CATEGORY),
|
|
22823
|
+
onKeyDown: (e) => {
|
|
22824
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
22825
|
+
e.preventDefault();
|
|
22826
|
+
setActiveCategory(ALL_CATEGORY);
|
|
22827
|
+
}
|
|
22828
|
+
},
|
|
22829
|
+
children: "All"
|
|
22830
|
+
}
|
|
22831
|
+
),
|
|
22832
|
+
categoryChips.map((category) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
22833
|
+
exports.Badge,
|
|
22834
|
+
{
|
|
22835
|
+
variant: activeCategory === category ? "primary" : "neutral",
|
|
22836
|
+
size: "sm",
|
|
22837
|
+
role: "button",
|
|
22838
|
+
tabIndex: 0,
|
|
22839
|
+
"aria-pressed": activeCategory === category,
|
|
22840
|
+
className: "cursor-pointer",
|
|
22841
|
+
onClick: () => setActiveCategory(category),
|
|
22842
|
+
onKeyDown: (e) => {
|
|
22843
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
22844
|
+
e.preventDefault();
|
|
22845
|
+
setActiveCategory(category);
|
|
22846
|
+
}
|
|
22847
|
+
},
|
|
22848
|
+
children: category
|
|
22849
|
+
},
|
|
22850
|
+
category
|
|
22851
|
+
))
|
|
22852
|
+
] }),
|
|
22853
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22854
|
+
"div",
|
|
22855
|
+
{
|
|
22856
|
+
ref: gridRef,
|
|
22857
|
+
role: "listbox",
|
|
22858
|
+
className: "grid gap-1 overflow-y-auto max-h-64 p-1",
|
|
22859
|
+
style: {
|
|
22860
|
+
gridTemplateColumns: `repeat(auto-fill, minmax(${cellSize}px, 1fr))`
|
|
22861
|
+
},
|
|
22862
|
+
children: filtered.map((item, index) => {
|
|
22863
|
+
const selected = item.id === value;
|
|
22864
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22865
|
+
"button",
|
|
22866
|
+
{
|
|
22867
|
+
type: "button",
|
|
22868
|
+
role: "option",
|
|
22869
|
+
"aria-selected": selected,
|
|
22870
|
+
"aria-label": item.label,
|
|
22871
|
+
title: item.label,
|
|
22872
|
+
"data-gridpicker-cell": true,
|
|
22873
|
+
tabIndex: selected || value === void 0 && index === 0 ? 0 : -1,
|
|
22874
|
+
onClick: () => select(item),
|
|
22875
|
+
onKeyDown: (e) => handleKeyDown(e, index),
|
|
22876
|
+
className: cn(
|
|
22877
|
+
"flex items-center justify-center rounded-sm",
|
|
22878
|
+
"transition-colors hover:bg-muted",
|
|
22879
|
+
"focus:outline-none focus:ring-1 focus:ring-ring",
|
|
22880
|
+
selected && "bg-primary/10 ring-1 ring-primary"
|
|
22881
|
+
),
|
|
22882
|
+
style: { width: cellSize, height: cellSize },
|
|
22883
|
+
children: renderThumbnail(item)
|
|
22884
|
+
},
|
|
22885
|
+
item.id
|
|
22886
|
+
);
|
|
22887
|
+
})
|
|
22888
|
+
}
|
|
22889
|
+
)
|
|
22890
|
+
] });
|
|
22891
|
+
};
|
|
22892
|
+
exports.GridPicker.displayName = "GridPicker";
|
|
22893
|
+
}
|
|
22894
|
+
});
|
|
22895
|
+
function pascalToKebab(name) {
|
|
22896
|
+
return name.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z][a-z])/g, "$1-$2").toLowerCase();
|
|
22897
|
+
}
|
|
22898
|
+
function kebabToPascal3(name) {
|
|
22899
|
+
return name.split("-").map((part) => /^\d+$/.test(part) ? part : part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
22900
|
+
}
|
|
22901
|
+
var ICON_ITEMS; exports.IconPicker = void 0;
|
|
22902
|
+
var init_IconPicker = __esm({
|
|
22903
|
+
"components/core/molecules/IconPicker.tsx"() {
|
|
22904
|
+
"use client";
|
|
22905
|
+
init_Icon();
|
|
22906
|
+
init_GridPicker();
|
|
22907
|
+
ICON_ITEMS = (() => {
|
|
22908
|
+
const items = [];
|
|
22909
|
+
for (const [exportName, candidate] of Object.entries(LucideIcons2__namespace)) {
|
|
22910
|
+
if (!/^[A-Z]/.test(exportName)) continue;
|
|
22911
|
+
if (exportName.endsWith("Icon")) continue;
|
|
22912
|
+
if (exportName.startsWith("Lucide")) continue;
|
|
22913
|
+
const isComponent = candidate !== null && (typeof candidate === "object" || typeof candidate === "function") && "$$typeof" in candidate;
|
|
22914
|
+
if (!isComponent) continue;
|
|
22915
|
+
const kebab = pascalToKebab(exportName);
|
|
22916
|
+
if (kebabToPascal3(kebab) !== exportName) continue;
|
|
22917
|
+
items.push({ id: kebab, label: kebab, category: "icons" });
|
|
22918
|
+
}
|
|
22919
|
+
return items;
|
|
22920
|
+
})();
|
|
22921
|
+
exports.IconPicker = ({ value, onChange, className }) => {
|
|
22922
|
+
const items = React74.useMemo(() => ICON_ITEMS, []);
|
|
22923
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22924
|
+
exports.GridPicker,
|
|
22925
|
+
{
|
|
22926
|
+
items,
|
|
22927
|
+
value,
|
|
22928
|
+
onChange,
|
|
22929
|
+
searchPlaceholder: "Search icons\u2026",
|
|
22930
|
+
renderThumbnail: (it) => /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: it.id }),
|
|
22931
|
+
cellSize: 32,
|
|
22932
|
+
className
|
|
22933
|
+
}
|
|
22934
|
+
);
|
|
22935
|
+
};
|
|
22936
|
+
exports.IconPicker.displayName = "IconPicker";
|
|
22937
|
+
}
|
|
22938
|
+
});
|
|
22939
|
+
function iconForKind(kind) {
|
|
22940
|
+
if (kind === "audio") return "music";
|
|
22941
|
+
if (kind === "model") return "box";
|
|
22942
|
+
return "file";
|
|
22943
|
+
}
|
|
22944
|
+
var THUMB_PX, IMAGE_KINDS; exports.AssetPicker = void 0;
|
|
22945
|
+
var init_AssetPicker = __esm({
|
|
22946
|
+
"components/core/molecules/AssetPicker.tsx"() {
|
|
22947
|
+
"use client";
|
|
22948
|
+
init_GridPicker();
|
|
22949
|
+
init_Icon();
|
|
22950
|
+
THUMB_PX = 32;
|
|
22951
|
+
IMAGE_KINDS = /* @__PURE__ */ new Set([
|
|
22952
|
+
"image",
|
|
22953
|
+
"spritesheet",
|
|
22954
|
+
"scene",
|
|
22955
|
+
"portrait"
|
|
22956
|
+
]);
|
|
22957
|
+
exports.AssetPicker = ({
|
|
22958
|
+
assets,
|
|
22959
|
+
value,
|
|
22960
|
+
onChange,
|
|
22961
|
+
className
|
|
22962
|
+
}) => {
|
|
22963
|
+
const byUrl = React74.useMemo(() => {
|
|
22964
|
+
const map = /* @__PURE__ */ new Map();
|
|
22965
|
+
for (const entry of assets) map.set(entry.url, entry);
|
|
22966
|
+
return map;
|
|
22967
|
+
}, [assets]);
|
|
22968
|
+
const items = React74.useMemo(
|
|
22969
|
+
() => assets.map((entry) => ({
|
|
22970
|
+
id: entry.url,
|
|
22971
|
+
label: entry.name,
|
|
22972
|
+
category: entry.category
|
|
22973
|
+
})),
|
|
22974
|
+
[assets]
|
|
22975
|
+
);
|
|
22976
|
+
const categories = React74.useMemo(() => {
|
|
22977
|
+
const seen = [];
|
|
22978
|
+
for (const entry of assets) {
|
|
22979
|
+
if (!seen.includes(entry.category)) seen.push(entry.category);
|
|
22980
|
+
}
|
|
22981
|
+
return seen;
|
|
22982
|
+
}, [assets]);
|
|
22983
|
+
const renderThumbnail = React74.useCallback(
|
|
22984
|
+
(item) => {
|
|
22985
|
+
const entry = byUrl.get(item.id);
|
|
22986
|
+
if (entry === void 0) return null;
|
|
22987
|
+
if (IMAGE_KINDS.has(entry.kind)) {
|
|
22988
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22989
|
+
"img",
|
|
22990
|
+
{
|
|
22991
|
+
src: entry.thumbnailUrl ?? entry.url,
|
|
22992
|
+
alt: entry.name,
|
|
22993
|
+
loading: "lazy",
|
|
22994
|
+
width: THUMB_PX,
|
|
22995
|
+
height: THUMB_PX,
|
|
22996
|
+
style: { width: THUMB_PX, height: THUMB_PX, objectFit: "cover" }
|
|
22997
|
+
}
|
|
22998
|
+
);
|
|
22999
|
+
}
|
|
23000
|
+
return /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: iconForKind(entry.kind), size: "sm" });
|
|
23001
|
+
},
|
|
23002
|
+
[byUrl]
|
|
23003
|
+
);
|
|
23004
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
23005
|
+
exports.GridPicker,
|
|
23006
|
+
{
|
|
23007
|
+
items,
|
|
23008
|
+
value,
|
|
23009
|
+
onChange,
|
|
23010
|
+
categories,
|
|
23011
|
+
renderThumbnail,
|
|
23012
|
+
cellSize: THUMB_PX,
|
|
23013
|
+
className
|
|
23014
|
+
}
|
|
23015
|
+
);
|
|
23016
|
+
};
|
|
23017
|
+
exports.AssetPicker.displayName = "AssetPicker";
|
|
23018
|
+
}
|
|
23019
|
+
});
|
|
23020
|
+
function currentValue(decl, override) {
|
|
23021
|
+
return override !== void 0 ? override : decl.default;
|
|
23022
|
+
}
|
|
23023
|
+
function TextLikeControl({
|
|
23024
|
+
field,
|
|
23025
|
+
numeric,
|
|
23026
|
+
value,
|
|
23027
|
+
onCommit
|
|
23028
|
+
}) {
|
|
23029
|
+
const initial = value === void 0 || value === null ? "" : String(value);
|
|
23030
|
+
const [draft, setDraft] = React74__namespace.default.useState(initial);
|
|
23031
|
+
React74__namespace.default.useEffect(() => setDraft(initial), [initial]);
|
|
23032
|
+
const commit = () => {
|
|
23033
|
+
if (numeric) {
|
|
23034
|
+
const n = draft.trim() === "" ? 0 : Number(draft);
|
|
23035
|
+
onCommit(field, Number.isNaN(n) ? 0 : n);
|
|
23036
|
+
} else {
|
|
23037
|
+
onCommit(field, draft);
|
|
23038
|
+
}
|
|
23039
|
+
};
|
|
23040
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
23041
|
+
exports.Input,
|
|
23042
|
+
{
|
|
23043
|
+
inputType: numeric ? "number" : "text",
|
|
23044
|
+
value: draft,
|
|
23045
|
+
onChange: (e) => setDraft(e.target.value),
|
|
23046
|
+
onBlur: commit,
|
|
23047
|
+
onKeyDown: (e) => {
|
|
23048
|
+
if (e.key === "Enter") commit();
|
|
23049
|
+
}
|
|
23050
|
+
}
|
|
23051
|
+
);
|
|
23052
|
+
}
|
|
23053
|
+
function isTraitConfigObject(v) {
|
|
23054
|
+
return v !== null && v !== void 0 && typeof v === "object" && !Array.isArray(v);
|
|
23055
|
+
}
|
|
23056
|
+
function FieldControl({
|
|
23057
|
+
name,
|
|
23058
|
+
decl,
|
|
23059
|
+
value,
|
|
23060
|
+
onChange,
|
|
23061
|
+
assets
|
|
23062
|
+
}) {
|
|
23063
|
+
let control;
|
|
23064
|
+
const stringValue = typeof value === "string" ? value : void 0;
|
|
23065
|
+
const effectiveValue = value ?? decl.default;
|
|
23066
|
+
if (decl.type === "icon") {
|
|
23067
|
+
control = /* @__PURE__ */ jsxRuntime.jsx(exports.IconPicker, { value: stringValue, onChange: (icon) => onChange(name, icon) });
|
|
23068
|
+
} else if (decl.type === "asset") {
|
|
23069
|
+
control = /* @__PURE__ */ jsxRuntime.jsx(
|
|
23070
|
+
exports.AssetPicker,
|
|
23071
|
+
{
|
|
23072
|
+
assets: assets ?? [],
|
|
23073
|
+
value: stringValue,
|
|
23074
|
+
onChange: (url) => onChange(name, url)
|
|
23075
|
+
}
|
|
23076
|
+
);
|
|
23077
|
+
} else if (decl.type === "boolean") {
|
|
23078
|
+
control = /* @__PURE__ */ jsxRuntime.jsx(exports.Switch, { checked: value === true, onChange: (c) => onChange(name, c) });
|
|
23079
|
+
} else if (decl.type === "string" && decl.values !== void 0 && decl.values.length > 0) {
|
|
23080
|
+
control = /* @__PURE__ */ jsxRuntime.jsx(
|
|
23081
|
+
exports.Select,
|
|
23082
|
+
{
|
|
23083
|
+
options: decl.values.map((v) => ({ value: v, label: v })),
|
|
23084
|
+
value: typeof value === "string" ? value : "",
|
|
23085
|
+
onChange: (e) => onChange(name, e.target.value)
|
|
23086
|
+
}
|
|
23087
|
+
);
|
|
23088
|
+
} else if (decl.type === "number") {
|
|
23089
|
+
control = /* @__PURE__ */ jsxRuntime.jsx(TextLikeControl, { field: name, numeric: true, value, onCommit: onChange });
|
|
23090
|
+
} else if (decl.type === "string") {
|
|
23091
|
+
control = /* @__PURE__ */ jsxRuntime.jsx(TextLikeControl, { field: name, numeric: false, value, onCommit: onChange });
|
|
23092
|
+
} else if (decl.type === "node") {
|
|
23093
|
+
control = /* @__PURE__ */ jsxRuntime.jsx(exports.NodeSlotEditor, { value: effectiveValue, onChange: (next) => onChange(name, next) });
|
|
23094
|
+
} else if (decl.type.startsWith("[") || Array.isArray(effectiveValue)) {
|
|
23095
|
+
const arr = Array.isArray(effectiveValue) ? effectiveValue : [];
|
|
23096
|
+
control = /* @__PURE__ */ jsxRuntime.jsx(exports.JsonTreeEditor, { value: arr, onChange: (next) => onChange(name, next) });
|
|
23097
|
+
} else if (decl.type === "object" || decl.type.startsWith("Map ") || !SCALAR_TYPES.has(decl.type) && isTraitConfigObject(effectiveValue)) {
|
|
23098
|
+
const obj = isTraitConfigObject(effectiveValue) ? effectiveValue : {};
|
|
23099
|
+
control = /* @__PURE__ */ jsxRuntime.jsx(exports.JsonTreeEditor, { value: obj, onChange: (next) => onChange(name, next) });
|
|
23100
|
+
} else {
|
|
23101
|
+
control = /* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { variant: "caption", color: "muted", children: [
|
|
23102
|
+
decl.type,
|
|
23103
|
+
" \u2014 edit in source"
|
|
23104
|
+
] });
|
|
23105
|
+
}
|
|
23106
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", children: [
|
|
23107
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "label", children: decl.label ?? name }),
|
|
23108
|
+
control,
|
|
23109
|
+
decl.description !== void 0 && decl.description !== "" && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", color: "muted", children: decl.description })
|
|
23110
|
+
] });
|
|
23111
|
+
}
|
|
23112
|
+
var TIER_ORDER, SCALAR_TYPES; exports.PropertyInspector = void 0;
|
|
23113
|
+
var init_PropertyInspector = __esm({
|
|
23114
|
+
"components/core/molecules/PropertyInspector.tsx"() {
|
|
23115
|
+
"use client";
|
|
23116
|
+
init_cn();
|
|
23117
|
+
init_Stack();
|
|
23118
|
+
init_Typography();
|
|
23119
|
+
init_Button();
|
|
23120
|
+
init_Switch();
|
|
23121
|
+
init_Select();
|
|
23122
|
+
init_Input();
|
|
23123
|
+
init_FormSection();
|
|
23124
|
+
init_IconPicker();
|
|
23125
|
+
init_AssetPicker();
|
|
23126
|
+
init_JsonTreeEditor();
|
|
23127
|
+
init_NodeSlotEditor();
|
|
23128
|
+
TIER_ORDER = ["presentation", "domain", "policy", "infra", "internal"];
|
|
23129
|
+
SCALAR_TYPES = /* @__PURE__ */ new Set(["string", "number", "boolean", "icon", "asset"]);
|
|
23130
|
+
exports.PropertyInspector = ({
|
|
23131
|
+
config,
|
|
23132
|
+
values,
|
|
23133
|
+
onChange,
|
|
23134
|
+
onReset,
|
|
23135
|
+
title,
|
|
23136
|
+
className,
|
|
23137
|
+
assets
|
|
23138
|
+
}) => {
|
|
23139
|
+
const fields = Object.entries(config);
|
|
23140
|
+
const byTier = /* @__PURE__ */ new Map();
|
|
23141
|
+
for (const [name, decl] of fields) {
|
|
23142
|
+
const tier = decl.tier ?? "presentation";
|
|
23143
|
+
const arr = byTier.get(tier) ?? [];
|
|
23144
|
+
arr.push([name, decl]);
|
|
23145
|
+
byTier.set(tier, arr);
|
|
23146
|
+
}
|
|
23147
|
+
const tiers = [...byTier.keys()].sort((a, b) => {
|
|
23148
|
+
const ia = TIER_ORDER.indexOf(a);
|
|
23149
|
+
const ib = TIER_ORDER.indexOf(b);
|
|
23150
|
+
return (ia === -1 ? 99 : ia) - (ib === -1 ? 99 : ib);
|
|
23151
|
+
});
|
|
23152
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", className: cn("w-full", className), children: [
|
|
23153
|
+
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { justify: "between", align: "center", children: [
|
|
23154
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", weight: "bold", children: title ?? "Config" }),
|
|
23155
|
+
onReset !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(exports.Button, { variant: "ghost", size: "sm", icon: "rotate-ccw", label: "Reset", onClick: onReset })
|
|
23156
|
+
] }),
|
|
23157
|
+
fields.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", color: "muted", children: "No configurable properties." }),
|
|
23158
|
+
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(
|
|
23159
|
+
FieldControl,
|
|
23160
|
+
{
|
|
23161
|
+
name,
|
|
23162
|
+
decl,
|
|
23163
|
+
value: currentValue(decl, values?.[name]),
|
|
23164
|
+
onChange,
|
|
23165
|
+
assets
|
|
23166
|
+
},
|
|
23167
|
+
name
|
|
23168
|
+
)) }) }, tier))
|
|
23169
|
+
] });
|
|
23170
|
+
};
|
|
23171
|
+
}
|
|
23172
|
+
});
|
|
22534
23173
|
function normalize(value) {
|
|
22535
23174
|
const wasArray = Array.isArray(value);
|
|
22536
23175
|
const pattern = wasArray ? value[0] : value;
|
|
@@ -22549,6 +23188,7 @@ var init_NodeSlotEditor = __esm({
|
|
|
22549
23188
|
init_Select();
|
|
22550
23189
|
init_Typography();
|
|
22551
23190
|
init_JsonTreeEditor();
|
|
23191
|
+
init_PropertyInspector();
|
|
22552
23192
|
init_pattern_resolver();
|
|
22553
23193
|
init_cn();
|
|
22554
23194
|
isObj2 = (v) => v !== null && v !== void 0 && typeof v === "object" && !Array.isArray(v);
|
|
@@ -22573,6 +23213,21 @@ var init_NodeSlotEditor = __esm({
|
|
|
22573
23213
|
const pattern = { type: nextType, ...nextProps };
|
|
22574
23214
|
onChange(wasArray || value === void 0 ? [pattern] : pattern);
|
|
22575
23215
|
};
|
|
23216
|
+
const schemaEntries = React74__namespace.default.useMemo(() => {
|
|
23217
|
+
if (!type) return [];
|
|
23218
|
+
const def = getPatternDefinition(type);
|
|
23219
|
+
if (!def?.propsSchema) return [];
|
|
23220
|
+
return Object.entries(def.propsSchema).map(([propName, propDef]) => {
|
|
23221
|
+
const decl = {
|
|
23222
|
+
type: propDef.types?.[0] ?? "string",
|
|
23223
|
+
description: propDef.description,
|
|
23224
|
+
label: propName,
|
|
23225
|
+
...propDef.enumValues && propDef.enumValues.length > 0 ? { values: propDef.enumValues } : {}
|
|
23226
|
+
};
|
|
23227
|
+
return [propName, decl];
|
|
23228
|
+
});
|
|
23229
|
+
}, [type]);
|
|
23230
|
+
const hasSchema = schemaEntries.length > 0;
|
|
22576
23231
|
return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", className: cn("w-full", className), children: [
|
|
22577
23232
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22578
23233
|
exports.Select,
|
|
@@ -22584,7 +23239,16 @@ var init_NodeSlotEditor = __esm({
|
|
|
22584
23239
|
),
|
|
22585
23240
|
type !== "" && /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "none", className: "pl-1", children: [
|
|
22586
23241
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", color: "muted", children: "props" }),
|
|
22587
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.
|
|
23242
|
+
hasSchema ? /* @__PURE__ */ jsxRuntime.jsx(exports.VStack, { gap: "xs", children: schemaEntries.map(([propName, decl]) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
23243
|
+
FieldControl,
|
|
23244
|
+
{
|
|
23245
|
+
name: propName,
|
|
23246
|
+
decl,
|
|
23247
|
+
value: props[propName],
|
|
23248
|
+
onChange: (field, val) => emit(type, { ...props, [field]: val })
|
|
23249
|
+
},
|
|
23250
|
+
propName
|
|
23251
|
+
)) }) : /* @__PURE__ */ jsxRuntime.jsx(exports.JsonTreeEditor, { value: props, onChange: (next) => emit(type, isObj2(next) ? next : {}) })
|
|
22588
23252
|
] })
|
|
22589
23253
|
] });
|
|
22590
23254
|
};
|
|
@@ -25167,303 +25831,6 @@ var init_FlipCard = __esm({
|
|
|
25167
25831
|
exports.FlipCard.displayName = "FlipCard";
|
|
25168
25832
|
}
|
|
25169
25833
|
});
|
|
25170
|
-
var ALL_CATEGORY; exports.GridPicker = void 0;
|
|
25171
|
-
var init_GridPicker = __esm({
|
|
25172
|
-
"components/core/molecules/GridPicker.tsx"() {
|
|
25173
|
-
"use client";
|
|
25174
|
-
init_cn();
|
|
25175
|
-
init_Input();
|
|
25176
|
-
init_Badge();
|
|
25177
|
-
init_Stack();
|
|
25178
|
-
ALL_CATEGORY = "__all__";
|
|
25179
|
-
exports.GridPicker = ({
|
|
25180
|
-
items,
|
|
25181
|
-
value,
|
|
25182
|
-
onChange,
|
|
25183
|
-
categories,
|
|
25184
|
-
searchPlaceholder,
|
|
25185
|
-
renderThumbnail,
|
|
25186
|
-
cellSize = 32,
|
|
25187
|
-
className
|
|
25188
|
-
}) => {
|
|
25189
|
-
const [search, setSearch] = React74.useState("");
|
|
25190
|
-
const [activeCategory, setActiveCategory] = React74.useState(ALL_CATEGORY);
|
|
25191
|
-
const gridRef = React74.useRef(null);
|
|
25192
|
-
const categoryChips = React74.useMemo(() => {
|
|
25193
|
-
if (categories !== void 0) return categories;
|
|
25194
|
-
const seen = [];
|
|
25195
|
-
for (const item of items) {
|
|
25196
|
-
if (!seen.includes(item.category)) seen.push(item.category);
|
|
25197
|
-
}
|
|
25198
|
-
return seen;
|
|
25199
|
-
}, [categories, items]);
|
|
25200
|
-
const filtered = React74.useMemo(() => {
|
|
25201
|
-
const needle = search.trim().toLowerCase();
|
|
25202
|
-
return items.filter((item) => {
|
|
25203
|
-
const matchesCategory = activeCategory === ALL_CATEGORY || item.category === activeCategory;
|
|
25204
|
-
const matchesSearch = needle === "" || item.label.toLowerCase().includes(needle);
|
|
25205
|
-
return matchesCategory && matchesSearch;
|
|
25206
|
-
});
|
|
25207
|
-
}, [items, search, activeCategory]);
|
|
25208
|
-
const select = React74.useCallback(
|
|
25209
|
-
(item) => {
|
|
25210
|
-
onChange(item.id);
|
|
25211
|
-
},
|
|
25212
|
-
[onChange]
|
|
25213
|
-
);
|
|
25214
|
-
const handleKeyDown = React74.useCallback(
|
|
25215
|
-
(e, index) => {
|
|
25216
|
-
const cells = gridRef.current?.querySelectorAll(
|
|
25217
|
-
"[data-gridpicker-cell]"
|
|
25218
|
-
);
|
|
25219
|
-
if (cells === void 0 || cells.length === 0) return;
|
|
25220
|
-
const columns = (() => {
|
|
25221
|
-
const grid = gridRef.current;
|
|
25222
|
-
if (grid === null) return 1;
|
|
25223
|
-
const style = window.getComputedStyle(grid);
|
|
25224
|
-
const cols = style.gridTemplateColumns.split(" ").filter(Boolean).length;
|
|
25225
|
-
return cols > 0 ? cols : 1;
|
|
25226
|
-
})();
|
|
25227
|
-
let next = -1;
|
|
25228
|
-
if (e.key === "ArrowRight") next = index + 1;
|
|
25229
|
-
else if (e.key === "ArrowLeft") next = index - 1;
|
|
25230
|
-
else if (e.key === "ArrowDown") next = index + columns;
|
|
25231
|
-
else if (e.key === "ArrowUp") next = index - columns;
|
|
25232
|
-
else if (e.key === "Enter" || e.key === " ") {
|
|
25233
|
-
e.preventDefault();
|
|
25234
|
-
select(filtered[index]);
|
|
25235
|
-
return;
|
|
25236
|
-
} else {
|
|
25237
|
-
return;
|
|
25238
|
-
}
|
|
25239
|
-
e.preventDefault();
|
|
25240
|
-
if (next >= 0 && next < cells.length) {
|
|
25241
|
-
cells[next].focus();
|
|
25242
|
-
}
|
|
25243
|
-
},
|
|
25244
|
-
[filtered, select]
|
|
25245
|
-
);
|
|
25246
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", className: cn("w-full", className), children: [
|
|
25247
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
25248
|
-
exports.Input,
|
|
25249
|
-
{
|
|
25250
|
-
type: "search",
|
|
25251
|
-
icon: "search",
|
|
25252
|
-
value: search,
|
|
25253
|
-
placeholder: searchPlaceholder,
|
|
25254
|
-
clearable: true,
|
|
25255
|
-
onClear: () => setSearch(""),
|
|
25256
|
-
onChange: (e) => setSearch(e.target.value)
|
|
25257
|
-
}
|
|
25258
|
-
),
|
|
25259
|
-
categoryChips.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", wrap: true, children: [
|
|
25260
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
25261
|
-
exports.Badge,
|
|
25262
|
-
{
|
|
25263
|
-
variant: activeCategory === ALL_CATEGORY ? "primary" : "neutral",
|
|
25264
|
-
size: "sm",
|
|
25265
|
-
role: "button",
|
|
25266
|
-
tabIndex: 0,
|
|
25267
|
-
"aria-pressed": activeCategory === ALL_CATEGORY,
|
|
25268
|
-
className: "cursor-pointer",
|
|
25269
|
-
onClick: () => setActiveCategory(ALL_CATEGORY),
|
|
25270
|
-
onKeyDown: (e) => {
|
|
25271
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
25272
|
-
e.preventDefault();
|
|
25273
|
-
setActiveCategory(ALL_CATEGORY);
|
|
25274
|
-
}
|
|
25275
|
-
},
|
|
25276
|
-
children: "All"
|
|
25277
|
-
}
|
|
25278
|
-
),
|
|
25279
|
-
categoryChips.map((category) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
25280
|
-
exports.Badge,
|
|
25281
|
-
{
|
|
25282
|
-
variant: activeCategory === category ? "primary" : "neutral",
|
|
25283
|
-
size: "sm",
|
|
25284
|
-
role: "button",
|
|
25285
|
-
tabIndex: 0,
|
|
25286
|
-
"aria-pressed": activeCategory === category,
|
|
25287
|
-
className: "cursor-pointer",
|
|
25288
|
-
onClick: () => setActiveCategory(category),
|
|
25289
|
-
onKeyDown: (e) => {
|
|
25290
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
25291
|
-
e.preventDefault();
|
|
25292
|
-
setActiveCategory(category);
|
|
25293
|
-
}
|
|
25294
|
-
},
|
|
25295
|
-
children: category
|
|
25296
|
-
},
|
|
25297
|
-
category
|
|
25298
|
-
))
|
|
25299
|
-
] }),
|
|
25300
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
25301
|
-
"div",
|
|
25302
|
-
{
|
|
25303
|
-
ref: gridRef,
|
|
25304
|
-
role: "listbox",
|
|
25305
|
-
className: "grid gap-1 overflow-y-auto max-h-64 p-1",
|
|
25306
|
-
style: {
|
|
25307
|
-
gridTemplateColumns: `repeat(auto-fill, minmax(${cellSize}px, 1fr))`
|
|
25308
|
-
},
|
|
25309
|
-
children: filtered.map((item, index) => {
|
|
25310
|
-
const selected = item.id === value;
|
|
25311
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
25312
|
-
"button",
|
|
25313
|
-
{
|
|
25314
|
-
type: "button",
|
|
25315
|
-
role: "option",
|
|
25316
|
-
"aria-selected": selected,
|
|
25317
|
-
"aria-label": item.label,
|
|
25318
|
-
title: item.label,
|
|
25319
|
-
"data-gridpicker-cell": true,
|
|
25320
|
-
tabIndex: selected || value === void 0 && index === 0 ? 0 : -1,
|
|
25321
|
-
onClick: () => select(item),
|
|
25322
|
-
onKeyDown: (e) => handleKeyDown(e, index),
|
|
25323
|
-
className: cn(
|
|
25324
|
-
"flex items-center justify-center rounded-sm",
|
|
25325
|
-
"transition-colors hover:bg-muted",
|
|
25326
|
-
"focus:outline-none focus:ring-1 focus:ring-ring",
|
|
25327
|
-
selected && "bg-primary/10 ring-1 ring-primary"
|
|
25328
|
-
),
|
|
25329
|
-
style: { width: cellSize, height: cellSize },
|
|
25330
|
-
children: renderThumbnail(item)
|
|
25331
|
-
},
|
|
25332
|
-
item.id
|
|
25333
|
-
);
|
|
25334
|
-
})
|
|
25335
|
-
}
|
|
25336
|
-
)
|
|
25337
|
-
] });
|
|
25338
|
-
};
|
|
25339
|
-
exports.GridPicker.displayName = "GridPicker";
|
|
25340
|
-
}
|
|
25341
|
-
});
|
|
25342
|
-
function iconForKind(kind) {
|
|
25343
|
-
if (kind === "audio") return "music";
|
|
25344
|
-
if (kind === "model") return "box";
|
|
25345
|
-
return "file";
|
|
25346
|
-
}
|
|
25347
|
-
var THUMB_PX, IMAGE_KINDS; exports.AssetPicker = void 0;
|
|
25348
|
-
var init_AssetPicker = __esm({
|
|
25349
|
-
"components/core/molecules/AssetPicker.tsx"() {
|
|
25350
|
-
"use client";
|
|
25351
|
-
init_GridPicker();
|
|
25352
|
-
init_Icon();
|
|
25353
|
-
THUMB_PX = 32;
|
|
25354
|
-
IMAGE_KINDS = /* @__PURE__ */ new Set([
|
|
25355
|
-
"image",
|
|
25356
|
-
"spritesheet",
|
|
25357
|
-
"scene",
|
|
25358
|
-
"portrait"
|
|
25359
|
-
]);
|
|
25360
|
-
exports.AssetPicker = ({
|
|
25361
|
-
assets,
|
|
25362
|
-
value,
|
|
25363
|
-
onChange,
|
|
25364
|
-
className
|
|
25365
|
-
}) => {
|
|
25366
|
-
const byUrl = React74.useMemo(() => {
|
|
25367
|
-
const map = /* @__PURE__ */ new Map();
|
|
25368
|
-
for (const entry of assets) map.set(entry.url, entry);
|
|
25369
|
-
return map;
|
|
25370
|
-
}, [assets]);
|
|
25371
|
-
const items = React74.useMemo(
|
|
25372
|
-
() => assets.map((entry) => ({
|
|
25373
|
-
id: entry.url,
|
|
25374
|
-
label: entry.name,
|
|
25375
|
-
category: entry.category
|
|
25376
|
-
})),
|
|
25377
|
-
[assets]
|
|
25378
|
-
);
|
|
25379
|
-
const categories = React74.useMemo(() => {
|
|
25380
|
-
const seen = [];
|
|
25381
|
-
for (const entry of assets) {
|
|
25382
|
-
if (!seen.includes(entry.category)) seen.push(entry.category);
|
|
25383
|
-
}
|
|
25384
|
-
return seen;
|
|
25385
|
-
}, [assets]);
|
|
25386
|
-
const renderThumbnail = React74.useCallback(
|
|
25387
|
-
(item) => {
|
|
25388
|
-
const entry = byUrl.get(item.id);
|
|
25389
|
-
if (entry === void 0) return null;
|
|
25390
|
-
if (IMAGE_KINDS.has(entry.kind)) {
|
|
25391
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
25392
|
-
"img",
|
|
25393
|
-
{
|
|
25394
|
-
src: entry.thumbnailUrl ?? entry.url,
|
|
25395
|
-
alt: entry.name,
|
|
25396
|
-
loading: "lazy",
|
|
25397
|
-
width: THUMB_PX,
|
|
25398
|
-
height: THUMB_PX,
|
|
25399
|
-
style: { width: THUMB_PX, height: THUMB_PX, objectFit: "cover" }
|
|
25400
|
-
}
|
|
25401
|
-
);
|
|
25402
|
-
}
|
|
25403
|
-
return /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: iconForKind(entry.kind), size: "sm" });
|
|
25404
|
-
},
|
|
25405
|
-
[byUrl]
|
|
25406
|
-
);
|
|
25407
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
25408
|
-
exports.GridPicker,
|
|
25409
|
-
{
|
|
25410
|
-
items,
|
|
25411
|
-
value,
|
|
25412
|
-
onChange,
|
|
25413
|
-
categories,
|
|
25414
|
-
renderThumbnail,
|
|
25415
|
-
cellSize: THUMB_PX,
|
|
25416
|
-
className
|
|
25417
|
-
}
|
|
25418
|
-
);
|
|
25419
|
-
};
|
|
25420
|
-
exports.AssetPicker.displayName = "AssetPicker";
|
|
25421
|
-
}
|
|
25422
|
-
});
|
|
25423
|
-
function pascalToKebab(name) {
|
|
25424
|
-
return name.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z][a-z])/g, "$1-$2").toLowerCase();
|
|
25425
|
-
}
|
|
25426
|
-
function kebabToPascal3(name) {
|
|
25427
|
-
return name.split("-").map((part) => /^\d+$/.test(part) ? part : part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
25428
|
-
}
|
|
25429
|
-
var ICON_ITEMS; exports.IconPicker = void 0;
|
|
25430
|
-
var init_IconPicker = __esm({
|
|
25431
|
-
"components/core/molecules/IconPicker.tsx"() {
|
|
25432
|
-
"use client";
|
|
25433
|
-
init_Icon();
|
|
25434
|
-
init_GridPicker();
|
|
25435
|
-
ICON_ITEMS = (() => {
|
|
25436
|
-
const items = [];
|
|
25437
|
-
for (const [exportName, candidate] of Object.entries(LucideIcons2__namespace)) {
|
|
25438
|
-
if (!/^[A-Z]/.test(exportName)) continue;
|
|
25439
|
-
if (exportName.endsWith("Icon")) continue;
|
|
25440
|
-
if (exportName.startsWith("Lucide")) continue;
|
|
25441
|
-
const isComponent = candidate !== null && (typeof candidate === "object" || typeof candidate === "function") && "$$typeof" in candidate;
|
|
25442
|
-
if (!isComponent) continue;
|
|
25443
|
-
const kebab = pascalToKebab(exportName);
|
|
25444
|
-
if (kebabToPascal3(kebab) !== exportName) continue;
|
|
25445
|
-
items.push({ id: kebab, label: kebab, category: "icons" });
|
|
25446
|
-
}
|
|
25447
|
-
return items;
|
|
25448
|
-
})();
|
|
25449
|
-
exports.IconPicker = ({ value, onChange, className }) => {
|
|
25450
|
-
const items = React74.useMemo(() => ICON_ITEMS, []);
|
|
25451
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
25452
|
-
exports.GridPicker,
|
|
25453
|
-
{
|
|
25454
|
-
items,
|
|
25455
|
-
value,
|
|
25456
|
-
onChange,
|
|
25457
|
-
searchPlaceholder: "Search icons\u2026",
|
|
25458
|
-
renderThumbnail: (it) => /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: it.id }),
|
|
25459
|
-
cellSize: 32,
|
|
25460
|
-
className
|
|
25461
|
-
}
|
|
25462
|
-
);
|
|
25463
|
-
};
|
|
25464
|
-
exports.IconPicker.displayName = "IconPicker";
|
|
25465
|
-
}
|
|
25466
|
-
});
|
|
25467
25834
|
function toISODate(d) {
|
|
25468
25835
|
return d.toISOString().slice(0, 10);
|
|
25469
25836
|
}
|
|
@@ -35154,286 +35521,6 @@ var init_PageHeader = __esm({
|
|
|
35154
35521
|
exports.PageHeader.displayName = "PageHeader";
|
|
35155
35522
|
}
|
|
35156
35523
|
});
|
|
35157
|
-
exports.FormSection = void 0; exports.FormLayout = void 0; exports.FormActions = void 0;
|
|
35158
|
-
var init_FormSection = __esm({
|
|
35159
|
-
"components/core/molecules/FormSection.tsx"() {
|
|
35160
|
-
"use client";
|
|
35161
|
-
init_cn();
|
|
35162
|
-
init_atoms2();
|
|
35163
|
-
init_Box();
|
|
35164
|
-
init_Typography();
|
|
35165
|
-
init_Button();
|
|
35166
|
-
init_Stack();
|
|
35167
|
-
init_Icon();
|
|
35168
|
-
init_useEventBus();
|
|
35169
|
-
exports.FormSection = ({
|
|
35170
|
-
title,
|
|
35171
|
-
description,
|
|
35172
|
-
children,
|
|
35173
|
-
collapsible = false,
|
|
35174
|
-
defaultCollapsed = false,
|
|
35175
|
-
card = false,
|
|
35176
|
-
columns = 1,
|
|
35177
|
-
className
|
|
35178
|
-
}) => {
|
|
35179
|
-
const [collapsed, setCollapsed] = React74__namespace.default.useState(defaultCollapsed);
|
|
35180
|
-
const { t } = hooks.useTranslate();
|
|
35181
|
-
const eventBus = useEventBus();
|
|
35182
|
-
const gridClass = {
|
|
35183
|
-
1: "grid-cols-1",
|
|
35184
|
-
2: "grid-cols-1 md:grid-cols-2",
|
|
35185
|
-
3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
|
|
35186
|
-
}[columns];
|
|
35187
|
-
React74__namespace.default.useCallback(() => {
|
|
35188
|
-
if (collapsible) {
|
|
35189
|
-
setCollapsed((prev) => !prev);
|
|
35190
|
-
eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
|
|
35191
|
-
}
|
|
35192
|
-
}, [collapsible, collapsed, eventBus]);
|
|
35193
|
-
const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
35194
|
-
(title || description) && /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", className: "mb-4", children: [
|
|
35195
|
-
title && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
35196
|
-
exports.HStack,
|
|
35197
|
-
{
|
|
35198
|
-
justify: "between",
|
|
35199
|
-
align: "center",
|
|
35200
|
-
className: cn(collapsible && "cursor-pointer"),
|
|
35201
|
-
action: collapsible ? "TOGGLE_COLLAPSE" : void 0,
|
|
35202
|
-
children: [
|
|
35203
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h3", weight: "semibold", children: title }),
|
|
35204
|
-
collapsible && /* @__PURE__ */ jsxRuntime.jsx(
|
|
35205
|
-
exports.Button,
|
|
35206
|
-
{
|
|
35207
|
-
variant: "ghost",
|
|
35208
|
-
size: "sm",
|
|
35209
|
-
action: "TOGGLE_COLLAPSE",
|
|
35210
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
35211
|
-
exports.Icon,
|
|
35212
|
-
{
|
|
35213
|
-
icon: LucideIcons2.ChevronDown,
|
|
35214
|
-
size: "sm",
|
|
35215
|
-
className: cn(
|
|
35216
|
-
"text-muted-foreground transition-transform",
|
|
35217
|
-
collapsed && "rotate-180"
|
|
35218
|
-
)
|
|
35219
|
-
}
|
|
35220
|
-
)
|
|
35221
|
-
}
|
|
35222
|
-
)
|
|
35223
|
-
]
|
|
35224
|
-
}
|
|
35225
|
-
),
|
|
35226
|
-
description && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "small", color: "secondary", children: description })
|
|
35227
|
-
] }),
|
|
35228
|
-
(!collapsible || !collapsed) && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: cn("grid gap-4", gridClass), children })
|
|
35229
|
-
] });
|
|
35230
|
-
if (card) {
|
|
35231
|
-
return /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className: cn("p-6", className), children: content });
|
|
35232
|
-
}
|
|
35233
|
-
return /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className, children: content });
|
|
35234
|
-
};
|
|
35235
|
-
exports.FormSection.displayName = "FormSection";
|
|
35236
|
-
exports.FormLayout = ({
|
|
35237
|
-
children,
|
|
35238
|
-
dividers = true,
|
|
35239
|
-
className
|
|
35240
|
-
}) => {
|
|
35241
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
35242
|
-
exports.VStack,
|
|
35243
|
-
{
|
|
35244
|
-
gap: "lg",
|
|
35245
|
-
className: cn(
|
|
35246
|
-
dividers && "[&>*+*]:pt-8 [&>*+*]:border-t [&>*+*]:border-border",
|
|
35247
|
-
className
|
|
35248
|
-
),
|
|
35249
|
-
children
|
|
35250
|
-
}
|
|
35251
|
-
);
|
|
35252
|
-
};
|
|
35253
|
-
exports.FormLayout.displayName = "FormLayout";
|
|
35254
|
-
exports.FormActions = ({
|
|
35255
|
-
children,
|
|
35256
|
-
sticky = false,
|
|
35257
|
-
align = "right",
|
|
35258
|
-
className
|
|
35259
|
-
}) => {
|
|
35260
|
-
const alignClass2 = {
|
|
35261
|
-
left: "justify-start",
|
|
35262
|
-
right: "justify-end",
|
|
35263
|
-
between: "justify-between",
|
|
35264
|
-
center: "justify-center"
|
|
35265
|
-
}[align];
|
|
35266
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
35267
|
-
exports.HStack,
|
|
35268
|
-
{
|
|
35269
|
-
gap: "sm",
|
|
35270
|
-
align: "center",
|
|
35271
|
-
className: cn(
|
|
35272
|
-
"pt-6 border-t border-border",
|
|
35273
|
-
alignClass2,
|
|
35274
|
-
sticky && "sticky bottom-0 bg-card py-4 -mx-6 px-6 shadow-[0_-4px_6px_-1px_rgb(0,0,0,0.05)]",
|
|
35275
|
-
className
|
|
35276
|
-
),
|
|
35277
|
-
children
|
|
35278
|
-
}
|
|
35279
|
-
);
|
|
35280
|
-
};
|
|
35281
|
-
exports.FormActions.displayName = "FormActions";
|
|
35282
|
-
}
|
|
35283
|
-
});
|
|
35284
|
-
function currentValue(decl, override) {
|
|
35285
|
-
return override !== void 0 ? override : decl.default;
|
|
35286
|
-
}
|
|
35287
|
-
function TextLikeControl({
|
|
35288
|
-
field,
|
|
35289
|
-
numeric,
|
|
35290
|
-
value,
|
|
35291
|
-
onCommit
|
|
35292
|
-
}) {
|
|
35293
|
-
const initial = value === void 0 || value === null ? "" : String(value);
|
|
35294
|
-
const [draft, setDraft] = React74__namespace.default.useState(initial);
|
|
35295
|
-
React74__namespace.default.useEffect(() => setDraft(initial), [initial]);
|
|
35296
|
-
const commit = () => {
|
|
35297
|
-
if (numeric) {
|
|
35298
|
-
const n = draft.trim() === "" ? 0 : Number(draft);
|
|
35299
|
-
onCommit(field, Number.isNaN(n) ? 0 : n);
|
|
35300
|
-
} else {
|
|
35301
|
-
onCommit(field, draft);
|
|
35302
|
-
}
|
|
35303
|
-
};
|
|
35304
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
35305
|
-
exports.Input,
|
|
35306
|
-
{
|
|
35307
|
-
inputType: numeric ? "number" : "text",
|
|
35308
|
-
value: draft,
|
|
35309
|
-
onChange: (e) => setDraft(e.target.value),
|
|
35310
|
-
onBlur: commit,
|
|
35311
|
-
onKeyDown: (e) => {
|
|
35312
|
-
if (e.key === "Enter") commit();
|
|
35313
|
-
}
|
|
35314
|
-
}
|
|
35315
|
-
);
|
|
35316
|
-
}
|
|
35317
|
-
function isTraitConfigObject(v) {
|
|
35318
|
-
return v !== null && v !== void 0 && typeof v === "object" && !Array.isArray(v);
|
|
35319
|
-
}
|
|
35320
|
-
function FieldControl({
|
|
35321
|
-
name,
|
|
35322
|
-
decl,
|
|
35323
|
-
value,
|
|
35324
|
-
onChange,
|
|
35325
|
-
assets
|
|
35326
|
-
}) {
|
|
35327
|
-
let control;
|
|
35328
|
-
const stringValue = typeof value === "string" ? value : void 0;
|
|
35329
|
-
const effectiveValue = value ?? decl.default;
|
|
35330
|
-
if (decl.type === "icon") {
|
|
35331
|
-
control = /* @__PURE__ */ jsxRuntime.jsx(exports.IconPicker, { value: stringValue, onChange: (icon) => onChange(name, icon) });
|
|
35332
|
-
} else if (decl.type === "asset") {
|
|
35333
|
-
control = /* @__PURE__ */ jsxRuntime.jsx(
|
|
35334
|
-
exports.AssetPicker,
|
|
35335
|
-
{
|
|
35336
|
-
assets: assets ?? [],
|
|
35337
|
-
value: stringValue,
|
|
35338
|
-
onChange: (url) => onChange(name, url)
|
|
35339
|
-
}
|
|
35340
|
-
);
|
|
35341
|
-
} else if (decl.type === "boolean") {
|
|
35342
|
-
control = /* @__PURE__ */ jsxRuntime.jsx(exports.Switch, { checked: value === true, onChange: (c) => onChange(name, c) });
|
|
35343
|
-
} else if (decl.type === "string" && decl.values !== void 0 && decl.values.length > 0) {
|
|
35344
|
-
control = /* @__PURE__ */ jsxRuntime.jsx(
|
|
35345
|
-
exports.Select,
|
|
35346
|
-
{
|
|
35347
|
-
options: decl.values.map((v) => ({ value: v, label: v })),
|
|
35348
|
-
value: typeof value === "string" ? value : "",
|
|
35349
|
-
onChange: (e) => onChange(name, e.target.value)
|
|
35350
|
-
}
|
|
35351
|
-
);
|
|
35352
|
-
} else if (decl.type === "number") {
|
|
35353
|
-
control = /* @__PURE__ */ jsxRuntime.jsx(TextLikeControl, { field: name, numeric: true, value, onCommit: onChange });
|
|
35354
|
-
} else if (decl.type === "string") {
|
|
35355
|
-
control = /* @__PURE__ */ jsxRuntime.jsx(TextLikeControl, { field: name, numeric: false, value, onCommit: onChange });
|
|
35356
|
-
} else if (decl.type === "node") {
|
|
35357
|
-
control = /* @__PURE__ */ jsxRuntime.jsx(exports.NodeSlotEditor, { value: effectiveValue, onChange: (next) => onChange(name, next) });
|
|
35358
|
-
} else if (decl.type.startsWith("[") || Array.isArray(effectiveValue)) {
|
|
35359
|
-
const arr = Array.isArray(effectiveValue) ? effectiveValue : [];
|
|
35360
|
-
control = /* @__PURE__ */ jsxRuntime.jsx(exports.JsonTreeEditor, { value: arr, onChange: (next) => onChange(name, next) });
|
|
35361
|
-
} else if (decl.type === "object" || decl.type.startsWith("Map ") || !SCALAR_TYPES.has(decl.type) && isTraitConfigObject(effectiveValue)) {
|
|
35362
|
-
const obj = isTraitConfigObject(effectiveValue) ? effectiveValue : {};
|
|
35363
|
-
control = /* @__PURE__ */ jsxRuntime.jsx(exports.JsonTreeEditor, { value: obj, onChange: (next) => onChange(name, next) });
|
|
35364
|
-
} else {
|
|
35365
|
-
control = /* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { variant: "caption", color: "muted", children: [
|
|
35366
|
-
decl.type,
|
|
35367
|
-
" \u2014 edit in source"
|
|
35368
|
-
] });
|
|
35369
|
-
}
|
|
35370
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", children: [
|
|
35371
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "label", children: decl.label ?? name }),
|
|
35372
|
-
control,
|
|
35373
|
-
decl.description !== void 0 && decl.description !== "" && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", color: "muted", children: decl.description })
|
|
35374
|
-
] });
|
|
35375
|
-
}
|
|
35376
|
-
var TIER_ORDER, SCALAR_TYPES; exports.PropertyInspector = void 0;
|
|
35377
|
-
var init_PropertyInspector = __esm({
|
|
35378
|
-
"components/core/molecules/PropertyInspector.tsx"() {
|
|
35379
|
-
"use client";
|
|
35380
|
-
init_cn();
|
|
35381
|
-
init_Stack();
|
|
35382
|
-
init_Typography();
|
|
35383
|
-
init_Button();
|
|
35384
|
-
init_Switch();
|
|
35385
|
-
init_Select();
|
|
35386
|
-
init_Input();
|
|
35387
|
-
init_FormSection();
|
|
35388
|
-
init_IconPicker();
|
|
35389
|
-
init_AssetPicker();
|
|
35390
|
-
init_JsonTreeEditor();
|
|
35391
|
-
init_NodeSlotEditor();
|
|
35392
|
-
TIER_ORDER = ["presentation", "domain", "policy", "infra", "internal"];
|
|
35393
|
-
SCALAR_TYPES = /* @__PURE__ */ new Set(["string", "number", "boolean", "icon", "asset"]);
|
|
35394
|
-
exports.PropertyInspector = ({
|
|
35395
|
-
config,
|
|
35396
|
-
values,
|
|
35397
|
-
onChange,
|
|
35398
|
-
onReset,
|
|
35399
|
-
title,
|
|
35400
|
-
className,
|
|
35401
|
-
assets
|
|
35402
|
-
}) => {
|
|
35403
|
-
const fields = Object.entries(config);
|
|
35404
|
-
const byTier = /* @__PURE__ */ new Map();
|
|
35405
|
-
for (const [name, decl] of fields) {
|
|
35406
|
-
const tier = decl.tier ?? "presentation";
|
|
35407
|
-
const arr = byTier.get(tier) ?? [];
|
|
35408
|
-
arr.push([name, decl]);
|
|
35409
|
-
byTier.set(tier, arr);
|
|
35410
|
-
}
|
|
35411
|
-
const tiers = [...byTier.keys()].sort((a, b) => {
|
|
35412
|
-
const ia = TIER_ORDER.indexOf(a);
|
|
35413
|
-
const ib = TIER_ORDER.indexOf(b);
|
|
35414
|
-
return (ia === -1 ? 99 : ia) - (ib === -1 ? 99 : ib);
|
|
35415
|
-
});
|
|
35416
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", className: cn("w-full", className), children: [
|
|
35417
|
-
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { justify: "between", align: "center", children: [
|
|
35418
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", weight: "bold", children: title ?? "Config" }),
|
|
35419
|
-
onReset !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(exports.Button, { variant: "ghost", size: "sm", icon: "rotate-ccw", label: "Reset", onClick: onReset })
|
|
35420
|
-
] }),
|
|
35421
|
-
fields.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", color: "muted", children: "No configurable properties." }),
|
|
35422
|
-
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(
|
|
35423
|
-
FieldControl,
|
|
35424
|
-
{
|
|
35425
|
-
name,
|
|
35426
|
-
decl,
|
|
35427
|
-
value: currentValue(decl, values?.[name]),
|
|
35428
|
-
onChange,
|
|
35429
|
-
assets
|
|
35430
|
-
},
|
|
35431
|
-
name
|
|
35432
|
-
)) }) }, tier))
|
|
35433
|
-
] });
|
|
35434
|
-
};
|
|
35435
|
-
}
|
|
35436
|
-
});
|
|
35437
35524
|
var lookStyles8; exports.Header = void 0;
|
|
35438
35525
|
var init_Header = __esm({
|
|
35439
35526
|
"components/core/molecules/Header.tsx"() {
|
|
@@ -36789,7 +36876,6 @@ var init_DocumentViewer = __esm({
|
|
|
36789
36876
|
showPrint = false,
|
|
36790
36877
|
actions,
|
|
36791
36878
|
documents,
|
|
36792
|
-
entity,
|
|
36793
36879
|
isLoading = false,
|
|
36794
36880
|
error,
|
|
36795
36881
|
className
|
|
@@ -43959,7 +44045,7 @@ function TraitSlot({
|
|
|
43959
44045
|
size = "md",
|
|
43960
44046
|
showTooltip = true,
|
|
43961
44047
|
categoryColors,
|
|
43962
|
-
tooltipFrameUrl,
|
|
44048
|
+
tooltipFrameUrl = "",
|
|
43963
44049
|
className,
|
|
43964
44050
|
feedback,
|
|
43965
44051
|
onItemDrop,
|
|
@@ -47048,7 +47134,7 @@ var init_WorldMapBoard = __esm({
|
|
|
47048
47134
|
init_useEventBus();
|
|
47049
47135
|
init_Stack();
|
|
47050
47136
|
init_LoadingState();
|
|
47051
|
-
|
|
47137
|
+
init_IsometricCanvas();
|
|
47052
47138
|
init_boardEntity();
|
|
47053
47139
|
init_isometric();
|
|
47054
47140
|
WorldMapBoard.displayName = "WorldMapBoard";
|
|
@@ -47188,7 +47274,7 @@ function lazyThree(name, loader) {
|
|
|
47188
47274
|
ThreeWrapper.displayName = `Lazy(${name})`;
|
|
47189
47275
|
return ThreeWrapper;
|
|
47190
47276
|
}
|
|
47191
|
-
var FeatureRenderer, COMPONENT_REGISTRY;
|
|
47277
|
+
var FeatureRenderer, GameCanvas3D, GameCanvas3DBattleTemplate, GameCanvas3DCastleTemplate, GameCanvas3DWorldMapTemplate, COMPONENT_REGISTRY;
|
|
47192
47278
|
var init_component_registry_generated = __esm({
|
|
47193
47279
|
"components/core/organisms/component-registry.generated.ts"() {
|
|
47194
47280
|
init_AboutPageTemplate();
|
|
@@ -47474,7 +47560,11 @@ var init_component_registry_generated = __esm({
|
|
|
47474
47560
|
init_WorldMapBoard();
|
|
47475
47561
|
init_WorldMapTemplate();
|
|
47476
47562
|
init_XPBar();
|
|
47477
|
-
FeatureRenderer = lazyThree("FeatureRenderer", () => import('@almadar/ui/components/
|
|
47563
|
+
FeatureRenderer = lazyThree("FeatureRenderer", () => import('@almadar/ui/components/molecules/game/three'));
|
|
47564
|
+
GameCanvas3D = lazyThree("GameCanvas3D", () => import('@almadar/ui/components/molecules/game/three'));
|
|
47565
|
+
GameCanvas3DBattleTemplate = lazyThree("GameCanvas3DBattleTemplate", () => import('@almadar/ui/components/molecules/game/three'));
|
|
47566
|
+
GameCanvas3DCastleTemplate = lazyThree("GameCanvas3DCastleTemplate", () => import('@almadar/ui/components/molecules/game/three'));
|
|
47567
|
+
GameCanvas3DWorldMapTemplate = lazyThree("GameCanvas3DWorldMapTemplate", () => import('@almadar/ui/components/molecules/game/three'));
|
|
47478
47568
|
COMPONENT_REGISTRY = {
|
|
47479
47569
|
"AboutPageTemplate": exports.AboutPageTemplate,
|
|
47480
47570
|
"Accordion": exports.Accordion,
|
|
@@ -47587,6 +47677,10 @@ var init_component_registry_generated = __esm({
|
|
|
47587
47677
|
"GameAudioProvider": GameAudioProvider,
|
|
47588
47678
|
"GameAudioToggle": GameAudioToggle,
|
|
47589
47679
|
"GameCanvas2D": GameCanvas2D,
|
|
47680
|
+
"GameCanvas3D": GameCanvas3D,
|
|
47681
|
+
"GameCanvas3DBattleTemplate": GameCanvas3DBattleTemplate,
|
|
47682
|
+
"GameCanvas3DCastleTemplate": GameCanvas3DCastleTemplate,
|
|
47683
|
+
"GameCanvas3DWorldMapTemplate": GameCanvas3DWorldMapTemplate,
|
|
47590
47684
|
"GameHud": GameHud,
|
|
47591
47685
|
"GameMenu": GameMenu,
|
|
47592
47686
|
"GameOverScreen": GameOverScreen,
|