@almadar/ui 5.47.0 → 5.49.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 +2998 -443
- package/dist/avl/index.css +504 -0
- package/dist/avl/index.js +2998 -444
- package/dist/components/core/templates/index.d.ts +3 -0
- package/dist/components/game/atoms/ActionButton.d.ts +4 -1
- package/dist/components/game/atoms/ComboCounter.d.ts +4 -1
- package/dist/components/game/atoms/ControlButton.d.ts +4 -2
- package/dist/components/game/atoms/DamageNumber.d.ts +4 -1
- package/dist/components/game/atoms/ResourceCounter.d.ts +4 -1
- package/dist/components/game/atoms/ScoreDisplay.d.ts +4 -1
- package/dist/components/game/atoms/StateIndicator.d.ts +4 -7
- package/dist/components/game/atoms/StatusEffect.d.ts +4 -1
- package/dist/components/game/atoms/TurnIndicator.d.ts +4 -1
- package/dist/components/game/atoms/WaypointMarker.d.ts +4 -1
- package/dist/components/game/molecules/EnemyPlate.d.ts +4 -1
- package/dist/components/game/molecules/StatBadge.d.ts +4 -1
- package/dist/components/game/molecules/three/index.cjs +1428 -346
- package/dist/components/game/molecules/three/index.css +0 -5
- package/dist/components/game/molecules/three/index.js +1429 -347
- package/dist/components/game/organisms/CastleBoard.d.ts +10 -1
- package/dist/components/game/organisms/GameBoard3D.d.ts +62 -0
- package/dist/components/game/organisms/PlatformerBoard.d.ts +51 -0
- package/dist/components/game/organisms/RoguelikeBoard.d.ts +59 -0
- package/dist/components/game/organisms/TowerDefenseBoard.d.ts +64 -0
- package/dist/components/game/organisms/index.d.ts +4 -0
- package/dist/components/game/organisms/puzzles/event-handler/EventHandlerBoard.d.ts +9 -1
- package/dist/components/game/organisms/puzzles/state-architect/StateArchitectBoard.d.ts +14 -1
- package/dist/components/game/templates/GameCanvas3DBattleTemplate.d.ts +22 -35
- package/dist/components/game/templates/GameCanvas3DCastleTemplate.d.ts +23 -23
- package/dist/components/game/templates/GameCanvas3DWorldMapTemplate.d.ts +27 -29
- package/dist/components/game/templates/PlatformerTemplate.d.ts +26 -0
- package/dist/components/game/templates/RoguelikeTemplate.d.ts +23 -0
- package/dist/components/game/templates/TowerDefenseTemplate.d.ts +43 -0
- package/dist/components/index.cjs +2991 -422
- package/dist/components/index.css +504 -0
- package/dist/components/index.js +2985 -424
- package/dist/docs/index.css +504 -0
- package/dist/providers/index.cjs +2981 -426
- package/dist/providers/index.css +504 -0
- package/dist/providers/index.js +2981 -427
- package/dist/runtime/index.cjs +2982 -427
- package/dist/runtime/index.css +504 -0
- package/dist/runtime/index.js +2982 -428
- package/package.json +1 -1
- package/tailwind-preset.cjs +1 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React11, { forwardRef, useRef, useEffect, useImperativeHandle, useState, useMemo, useCallback, createContext, Component, useContext, useReducer } from 'react';
|
|
1
|
+
import React11, { forwardRef, useRef, useEffect, useImperativeHandle, useState, useMemo, useCallback, createContext, Component, useContext, useSyncExternalStore, useReducer } from 'react';
|
|
2
2
|
import { useThree, useFrame, Canvas, context } from '@react-three/fiber';
|
|
3
3
|
import * as THREE6 from 'three';
|
|
4
4
|
import { Vector3, QuadraticBezierCurve3, MathUtils, Quaternion } from 'three';
|
|
@@ -12,6 +12,8 @@ import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js';
|
|
|
12
12
|
import { EventBusContext, useTraitScope } from '@almadar/ui/providers';
|
|
13
13
|
import { clsx } from 'clsx';
|
|
14
14
|
import { twMerge } from 'tailwind-merge';
|
|
15
|
+
import * as LucideIcons from 'lucide-react';
|
|
16
|
+
import { Loader2 } from 'lucide-react';
|
|
15
17
|
import { EffectComposer, Bloom, DepthOfField, Vignette } from '@react-three/postprocessing';
|
|
16
18
|
import { useTranslate } from '@almadar/ui/hooks';
|
|
17
19
|
|
|
@@ -2256,6 +2258,9 @@ function preloadFeatures(urls) {
|
|
|
2256
2258
|
}
|
|
2257
2259
|
});
|
|
2258
2260
|
}
|
|
2261
|
+
function cn(...inputs) {
|
|
2262
|
+
return twMerge(clsx(inputs));
|
|
2263
|
+
}
|
|
2259
2264
|
var DEFAULT_GRID_CONFIG = {
|
|
2260
2265
|
cellSize: 1,
|
|
2261
2266
|
offsetX: 0,
|
|
@@ -2689,11 +2694,10 @@ var GameCanvas3D = forwardRef(
|
|
|
2689
2694
|
"div",
|
|
2690
2695
|
{
|
|
2691
2696
|
ref: containerRef,
|
|
2692
|
-
className:
|
|
2697
|
+
className: cn("game-canvas-3d relative w-full h-full min-h-[85vh] overflow-hidden", className),
|
|
2693
2698
|
"data-orientation": orientation,
|
|
2694
2699
|
"data-camera-mode": cameraMode,
|
|
2695
2700
|
"data-overlay": overlay,
|
|
2696
|
-
style: { position: "relative", width: "100%", height: "100%", minHeight: "85vh", overflow: "hidden" },
|
|
2697
2701
|
children: [
|
|
2698
2702
|
/* @__PURE__ */ jsxs(
|
|
2699
2703
|
Canvas,
|
|
@@ -2807,276 +2811,940 @@ var GameCanvas3D = forwardRef(
|
|
|
2807
2811
|
}
|
|
2808
2812
|
);
|
|
2809
2813
|
GameCanvas3D.displayName = "GameCanvas3D";
|
|
2810
|
-
|
|
2811
|
-
|
|
2814
|
+
var DEFAULT_FAMILY = "lucide";
|
|
2815
|
+
var VALID_FAMILIES = [
|
|
2816
|
+
"lucide",
|
|
2817
|
+
"phosphor-outline",
|
|
2818
|
+
"phosphor-fill",
|
|
2819
|
+
"phosphor-duotone",
|
|
2820
|
+
"tabler",
|
|
2821
|
+
"fa-solid"
|
|
2822
|
+
];
|
|
2823
|
+
function getCurrentIconFamily() {
|
|
2824
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
2825
|
+
return DEFAULT_FAMILY;
|
|
2826
|
+
}
|
|
2827
|
+
const raw = getComputedStyle(document.documentElement).getPropertyValue("--icon-family").trim().replace(/^["']|["']$/g, "");
|
|
2828
|
+
return VALID_FAMILIES.includes(raw) ? raw : DEFAULT_FAMILY;
|
|
2812
2829
|
}
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
var
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
}
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2830
|
+
var cachedFamily = null;
|
|
2831
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
2832
|
+
var observer = null;
|
|
2833
|
+
function ensureObserver() {
|
|
2834
|
+
if (typeof window === "undefined" || observer) return;
|
|
2835
|
+
observer = new MutationObserver(() => {
|
|
2836
|
+
const next = getCurrentIconFamily();
|
|
2837
|
+
if (next !== cachedFamily) {
|
|
2838
|
+
cachedFamily = next;
|
|
2839
|
+
listeners.forEach((fn) => fn());
|
|
2840
|
+
}
|
|
2841
|
+
});
|
|
2842
|
+
observer.observe(document.documentElement, {
|
|
2843
|
+
attributes: true,
|
|
2844
|
+
attributeFilter: ["data-theme", "style"]
|
|
2845
|
+
});
|
|
2846
|
+
cachedFamily = getCurrentIconFamily();
|
|
2847
|
+
}
|
|
2848
|
+
function subscribeIconFamily(notify) {
|
|
2849
|
+
ensureObserver();
|
|
2850
|
+
listeners.add(notify);
|
|
2851
|
+
return () => {
|
|
2852
|
+
listeners.delete(notify);
|
|
2853
|
+
};
|
|
2854
|
+
}
|
|
2855
|
+
function getIconFamilySnapshot() {
|
|
2856
|
+
if (cachedFamily !== null) return cachedFamily;
|
|
2857
|
+
cachedFamily = getCurrentIconFamily();
|
|
2858
|
+
return cachedFamily;
|
|
2859
|
+
}
|
|
2860
|
+
function getIconFamilyServerSnapshot() {
|
|
2861
|
+
return DEFAULT_FAMILY;
|
|
2862
|
+
}
|
|
2863
|
+
function useIconFamily() {
|
|
2864
|
+
return useSyncExternalStore(
|
|
2865
|
+
subscribeIconFamily,
|
|
2866
|
+
getIconFamilySnapshot,
|
|
2867
|
+
getIconFamilyServerSnapshot
|
|
2868
|
+
);
|
|
2869
|
+
}
|
|
2870
|
+
function kebabToPascal(name) {
|
|
2871
|
+
return name.split("-").map((part) => {
|
|
2872
|
+
if (/^\d+$/.test(part)) return part;
|
|
2873
|
+
return part.charAt(0).toUpperCase() + part.slice(1);
|
|
2874
|
+
}).join("");
|
|
2875
|
+
}
|
|
2876
|
+
var libPromises = /* @__PURE__ */ new Map();
|
|
2877
|
+
function loadLib(key, importer) {
|
|
2878
|
+
let p = libPromises.get(key);
|
|
2879
|
+
if (!p) {
|
|
2880
|
+
p = importer().then((m) => m);
|
|
2881
|
+
libPromises.set(key, p);
|
|
2882
|
+
}
|
|
2883
|
+
return p;
|
|
2884
|
+
}
|
|
2885
|
+
function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
|
|
2886
|
+
const Lazy = React11.lazy(async () => {
|
|
2887
|
+
const lib = await loadLib(libKey, importer);
|
|
2888
|
+
const Comp = pick(lib);
|
|
2889
|
+
if (!Comp) {
|
|
2890
|
+
warnFallback(fallbackName, family);
|
|
2891
|
+
return { default: makeLucideAdapter(fallbackName, true) };
|
|
2892
|
+
}
|
|
2893
|
+
return { default: Comp };
|
|
2894
|
+
});
|
|
2895
|
+
const Wrapped = (props) => /* @__PURE__ */ jsx(
|
|
2896
|
+
React11.Suspense,
|
|
2897
|
+
{
|
|
2898
|
+
fallback: /* @__PURE__ */ jsx(
|
|
2899
|
+
"span",
|
|
2900
|
+
{
|
|
2901
|
+
"aria-hidden": true,
|
|
2902
|
+
className: props.className,
|
|
2903
|
+
style: { display: "inline-block", ...props.style }
|
|
2904
|
+
}
|
|
2905
|
+
),
|
|
2906
|
+
children: /* @__PURE__ */ jsx(Lazy, { ...props })
|
|
2907
|
+
}
|
|
2908
|
+
);
|
|
2909
|
+
Wrapped.displayName = `Lazy.${libKey}.${fallbackName}`;
|
|
2910
|
+
return Wrapped;
|
|
2911
|
+
}
|
|
2912
|
+
var lucideAliases = {
|
|
2913
|
+
close: LucideIcons.X,
|
|
2914
|
+
trash: LucideIcons.Trash2,
|
|
2915
|
+
loader: LucideIcons.Loader2,
|
|
2916
|
+
stop: LucideIcons.Square,
|
|
2917
|
+
volume: LucideIcons.Volume2,
|
|
2918
|
+
"volume-off": LucideIcons.VolumeX,
|
|
2919
|
+
refresh: LucideIcons.RefreshCw,
|
|
2920
|
+
share: LucideIcons.Share2,
|
|
2921
|
+
"sort-asc": LucideIcons.ArrowUpNarrowWide,
|
|
2922
|
+
"sort-desc": LucideIcons.ArrowDownNarrowWide
|
|
2832
2923
|
};
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
"
|
|
2924
|
+
function resolveLucide(name) {
|
|
2925
|
+
if (lucideAliases[name]) return lucideAliases[name];
|
|
2926
|
+
const pascal = kebabToPascal(name);
|
|
2927
|
+
const lucideMap = LucideIcons;
|
|
2928
|
+
const direct = lucideMap[pascal];
|
|
2929
|
+
if (direct && typeof direct === "object") return direct;
|
|
2930
|
+
const asIs = lucideMap[name];
|
|
2931
|
+
if (asIs && typeof asIs === "object") return asIs;
|
|
2932
|
+
return LucideIcons.HelpCircle;
|
|
2933
|
+
}
|
|
2934
|
+
var phosphorAliases = {
|
|
2935
|
+
// lucide name → phosphor PascalCase name
|
|
2936
|
+
// Actions
|
|
2937
|
+
plus: "Plus",
|
|
2938
|
+
minus: "Minus",
|
|
2939
|
+
x: "X",
|
|
2940
|
+
check: "Check",
|
|
2941
|
+
close: "X",
|
|
2942
|
+
edit: "PencilSimple",
|
|
2943
|
+
pencil: "PencilSimple",
|
|
2944
|
+
trash: "Trash",
|
|
2945
|
+
save: "FloppyDisk",
|
|
2946
|
+
copy: "Copy",
|
|
2947
|
+
share: "Share",
|
|
2948
|
+
send: "PaperPlaneRight",
|
|
2949
|
+
download: "DownloadSimple",
|
|
2950
|
+
upload: "UploadSimple",
|
|
2951
|
+
archive: "Archive",
|
|
2952
|
+
refresh: "ArrowsClockwise",
|
|
2953
|
+
loader: "CircleNotch",
|
|
2954
|
+
link: "Link",
|
|
2955
|
+
paperclip: "Paperclip",
|
|
2956
|
+
// Navigation
|
|
2957
|
+
"chevron-down": "CaretDown",
|
|
2958
|
+
"chevron-up": "CaretUp",
|
|
2959
|
+
"chevron-left": "CaretLeft",
|
|
2960
|
+
"chevron-right": "CaretRight",
|
|
2961
|
+
"arrow-up": "ArrowUp",
|
|
2962
|
+
"arrow-down": "ArrowDown",
|
|
2963
|
+
"arrow-left": "ArrowLeft",
|
|
2964
|
+
"arrow-right": "ArrowRight",
|
|
2965
|
+
menu: "List",
|
|
2966
|
+
more: "DotsThree",
|
|
2967
|
+
"more-vertical": "DotsThreeVertical",
|
|
2968
|
+
"more-horizontal": "DotsThree",
|
|
2969
|
+
external: "ArrowSquareOut",
|
|
2970
|
+
"external-link": "ArrowSquareOut",
|
|
2971
|
+
// Files
|
|
2972
|
+
file: "File",
|
|
2973
|
+
"file-text": "FileText",
|
|
2974
|
+
"file-plus": "FilePlus",
|
|
2975
|
+
"file-minus": "FileMinus",
|
|
2976
|
+
folder: "Folder",
|
|
2977
|
+
"folder-open": "FolderOpen",
|
|
2978
|
+
document: "FileText",
|
|
2979
|
+
// Charts
|
|
2980
|
+
"bar-chart": "ChartBar",
|
|
2981
|
+
"bar-chart-2": "ChartBar",
|
|
2982
|
+
"bar-chart-3": "ChartBar",
|
|
2983
|
+
"line-chart": "ChartLine",
|
|
2984
|
+
"pie-chart": "ChartPie",
|
|
2985
|
+
activity: "Pulse",
|
|
2986
|
+
"trending-up": "TrendUp",
|
|
2987
|
+
"trending-down": "TrendDown",
|
|
2988
|
+
// Messages
|
|
2989
|
+
message: "ChatCircle",
|
|
2990
|
+
"message-circle": "ChatCircle",
|
|
2991
|
+
"message-square": "ChatText",
|
|
2992
|
+
"messages-square": "ChatsCircle",
|
|
2993
|
+
comment: "ChatCircle",
|
|
2994
|
+
comments: "ChatsCircle",
|
|
2995
|
+
inbox: "Tray",
|
|
2996
|
+
mail: "Envelope",
|
|
2997
|
+
envelope: "Envelope",
|
|
2998
|
+
// Status
|
|
2999
|
+
"alert-circle": "WarningCircle",
|
|
3000
|
+
"alert-triangle": "Warning",
|
|
3001
|
+
"check-circle": "CheckCircle",
|
|
3002
|
+
"x-circle": "XCircle",
|
|
3003
|
+
info: "Info",
|
|
3004
|
+
"help-circle": "Question",
|
|
3005
|
+
"life-buoy": "Lifebuoy",
|
|
3006
|
+
lifebuoy: "Lifebuoy",
|
|
3007
|
+
warning: "Warning",
|
|
3008
|
+
error: "WarningCircle",
|
|
3009
|
+
// Media
|
|
3010
|
+
image: "Image",
|
|
3011
|
+
video: "VideoCamera",
|
|
3012
|
+
film: "FilmStrip",
|
|
3013
|
+
camera: "Camera",
|
|
3014
|
+
music: "MusicNote",
|
|
3015
|
+
play: "Play",
|
|
3016
|
+
pause: "Pause",
|
|
3017
|
+
stop: "Stop",
|
|
3018
|
+
"skip-forward": "SkipForward",
|
|
3019
|
+
"skip-back": "SkipBack",
|
|
3020
|
+
volume: "SpeakerHigh",
|
|
3021
|
+
"volume-2": "SpeakerHigh",
|
|
3022
|
+
"volume-x": "SpeakerX",
|
|
3023
|
+
mic: "Microphone",
|
|
3024
|
+
"mic-off": "MicrophoneSlash",
|
|
3025
|
+
// People
|
|
3026
|
+
user: "User",
|
|
3027
|
+
users: "Users",
|
|
3028
|
+
"user-plus": "UserPlus",
|
|
3029
|
+
"user-check": "UserCheck",
|
|
3030
|
+
// Time
|
|
3031
|
+
calendar: "Calendar",
|
|
3032
|
+
clock: "Clock",
|
|
3033
|
+
timer: "Timer",
|
|
3034
|
+
// Location
|
|
3035
|
+
map: "MapTrifold",
|
|
3036
|
+
"map-pin": "MapPin",
|
|
3037
|
+
navigation: "NavigationArrow",
|
|
3038
|
+
compass: "Compass",
|
|
3039
|
+
globe: "Globe",
|
|
3040
|
+
target: "Target",
|
|
3041
|
+
// Project / layout
|
|
3042
|
+
kanban: "Kanban",
|
|
3043
|
+
list: "List",
|
|
3044
|
+
table: "Table",
|
|
3045
|
+
grid: "GridFour",
|
|
3046
|
+
layout: "Layout",
|
|
3047
|
+
columns: "Columns",
|
|
3048
|
+
rows: "Rows",
|
|
3049
|
+
// Misc
|
|
3050
|
+
bell: "Bell",
|
|
3051
|
+
bookmark: "Bookmark",
|
|
3052
|
+
briefcase: "Briefcase",
|
|
3053
|
+
flag: "Flag",
|
|
3054
|
+
tag: "Tag",
|
|
3055
|
+
tags: "Tag",
|
|
3056
|
+
star: "Star",
|
|
3057
|
+
heart: "Heart",
|
|
3058
|
+
home: "House",
|
|
3059
|
+
settings: "Gear",
|
|
3060
|
+
eye: "Eye",
|
|
3061
|
+
"eye-off": "EyeSlash",
|
|
3062
|
+
lock: "Lock",
|
|
3063
|
+
unlock: "LockOpen",
|
|
3064
|
+
key: "Key",
|
|
3065
|
+
shield: "Shield",
|
|
3066
|
+
search: "MagnifyingGlass",
|
|
3067
|
+
filter: "Funnel",
|
|
3068
|
+
"sort-asc": "SortAscending",
|
|
3069
|
+
"sort-desc": "SortDescending",
|
|
3070
|
+
zap: "Lightning",
|
|
3071
|
+
sparkles: "Sparkle",
|
|
3072
|
+
// Code
|
|
3073
|
+
code: "Code",
|
|
3074
|
+
terminal: "Terminal",
|
|
3075
|
+
database: "Database",
|
|
3076
|
+
server: "HardDrives",
|
|
3077
|
+
cloud: "Cloud",
|
|
3078
|
+
wifi: "WifiHigh",
|
|
3079
|
+
package: "Package",
|
|
3080
|
+
box: "Package",
|
|
3081
|
+
// Theme
|
|
3082
|
+
sun: "Sun",
|
|
3083
|
+
moon: "Moon",
|
|
3084
|
+
// Phone
|
|
3085
|
+
phone: "Phone",
|
|
3086
|
+
printer: "Printer",
|
|
3087
|
+
// Hierarchy
|
|
3088
|
+
tree: "Tree",
|
|
3089
|
+
network: "Network"
|
|
2841
3090
|
};
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
3091
|
+
function resolvePhosphor(name, weight, family) {
|
|
3092
|
+
const target = phosphorAliases[name] ?? kebabToPascal(name);
|
|
3093
|
+
return lazyFamilyIcon(
|
|
3094
|
+
"phosphor",
|
|
3095
|
+
() => import('@phosphor-icons/react'),
|
|
3096
|
+
(lib) => {
|
|
3097
|
+
const PhosphorComp = lib[target];
|
|
3098
|
+
if (!PhosphorComp || typeof PhosphorComp !== "object") return null;
|
|
3099
|
+
const Component2 = PhosphorComp;
|
|
3100
|
+
const Adapter = (props) => /* @__PURE__ */ jsx(
|
|
3101
|
+
Component2,
|
|
3102
|
+
{
|
|
3103
|
+
weight,
|
|
3104
|
+
className: props.className,
|
|
3105
|
+
style: props.style,
|
|
3106
|
+
size: props.size ?? "1em"
|
|
3107
|
+
}
|
|
3108
|
+
);
|
|
3109
|
+
Adapter.displayName = `Phosphor.${target}.${weight}`;
|
|
3110
|
+
return Adapter;
|
|
3111
|
+
},
|
|
3112
|
+
name,
|
|
3113
|
+
family
|
|
3114
|
+
);
|
|
3115
|
+
}
|
|
3116
|
+
var tablerAliases = {
|
|
3117
|
+
// lucide name → tabler suffix (after the `Icon` prefix)
|
|
3118
|
+
// Actions
|
|
3119
|
+
plus: "Plus",
|
|
3120
|
+
minus: "Minus",
|
|
3121
|
+
x: "X",
|
|
3122
|
+
check: "Check",
|
|
3123
|
+
close: "X",
|
|
3124
|
+
edit: "Pencil",
|
|
3125
|
+
pencil: "Pencil",
|
|
3126
|
+
trash: "Trash",
|
|
3127
|
+
save: "DeviceFloppy",
|
|
3128
|
+
copy: "Copy",
|
|
3129
|
+
share: "Share",
|
|
3130
|
+
send: "Send",
|
|
3131
|
+
download: "Download",
|
|
3132
|
+
upload: "Upload",
|
|
3133
|
+
archive: "Archive",
|
|
3134
|
+
refresh: "Refresh",
|
|
3135
|
+
loader: "Loader2",
|
|
3136
|
+
link: "Link",
|
|
3137
|
+
paperclip: "Paperclip",
|
|
3138
|
+
external: "ExternalLink",
|
|
3139
|
+
"external-link": "ExternalLink",
|
|
3140
|
+
// Navigation
|
|
3141
|
+
"chevron-down": "ChevronDown",
|
|
3142
|
+
"chevron-up": "ChevronUp",
|
|
3143
|
+
"chevron-left": "ChevronLeft",
|
|
3144
|
+
"chevron-right": "ChevronRight",
|
|
3145
|
+
"arrow-down": "ArrowDown",
|
|
3146
|
+
"arrow-up": "ArrowUp",
|
|
3147
|
+
"arrow-left": "ArrowLeft",
|
|
3148
|
+
"arrow-right": "ArrowRight",
|
|
3149
|
+
menu: "Menu2",
|
|
3150
|
+
more: "Dots",
|
|
3151
|
+
"more-vertical": "DotsVertical",
|
|
3152
|
+
// Files
|
|
3153
|
+
file: "File",
|
|
3154
|
+
"file-text": "FileText",
|
|
3155
|
+
"file-plus": "FilePlus",
|
|
3156
|
+
"file-check": "FileCheck",
|
|
3157
|
+
"file-minus": "FileMinus",
|
|
3158
|
+
folder: "Folder",
|
|
3159
|
+
"folder-open": "FolderOpen",
|
|
3160
|
+
document: "FileText",
|
|
3161
|
+
// Charts
|
|
3162
|
+
"bar-chart": "ChartBar",
|
|
3163
|
+
"bar-chart-2": "ChartBar",
|
|
3164
|
+
"bar-chart-3": "ChartBar",
|
|
3165
|
+
"line-chart": "ChartLine",
|
|
3166
|
+
"pie-chart": "ChartPie",
|
|
3167
|
+
activity: "Activity",
|
|
3168
|
+
"trending-up": "TrendingUp",
|
|
3169
|
+
"trending-down": "TrendingDown",
|
|
3170
|
+
// Messages
|
|
3171
|
+
message: "Message",
|
|
3172
|
+
"message-circle": "MessageCircle",
|
|
3173
|
+
"message-square": "Message2",
|
|
3174
|
+
"messages-square": "Messages",
|
|
3175
|
+
comment: "Message",
|
|
3176
|
+
comments: "Messages",
|
|
3177
|
+
inbox: "Inbox",
|
|
3178
|
+
mail: "Mail",
|
|
3179
|
+
envelope: "Mail",
|
|
3180
|
+
// Status
|
|
3181
|
+
"alert-circle": "AlertCircle",
|
|
3182
|
+
"alert-triangle": "AlertTriangle",
|
|
3183
|
+
"check-circle": "CircleCheck",
|
|
3184
|
+
"x-circle": "CircleX",
|
|
3185
|
+
info: "InfoCircle",
|
|
3186
|
+
"help-circle": "HelpCircle",
|
|
3187
|
+
"life-buoy": "Lifebuoy",
|
|
3188
|
+
warning: "AlertTriangle",
|
|
3189
|
+
error: "AlertOctagon",
|
|
3190
|
+
// Media
|
|
3191
|
+
image: "Photo",
|
|
3192
|
+
video: "Video",
|
|
3193
|
+
camera: "Camera",
|
|
3194
|
+
music: "Music",
|
|
3195
|
+
play: "PlayerPlay",
|
|
3196
|
+
pause: "PlayerPause",
|
|
3197
|
+
stop: "PlayerStop",
|
|
3198
|
+
"skip-forward": "PlayerSkipForward",
|
|
3199
|
+
"skip-back": "PlayerSkipBack",
|
|
3200
|
+
volume: "Volume",
|
|
3201
|
+
"volume-2": "Volume",
|
|
3202
|
+
"volume-x": "VolumeOff",
|
|
3203
|
+
mic: "Microphone",
|
|
3204
|
+
"mic-off": "MicrophoneOff",
|
|
3205
|
+
// People
|
|
3206
|
+
user: "User",
|
|
3207
|
+
users: "Users",
|
|
3208
|
+
"user-plus": "UserPlus",
|
|
3209
|
+
"user-check": "UserCheck",
|
|
3210
|
+
// Time
|
|
3211
|
+
calendar: "Calendar",
|
|
3212
|
+
clock: "Clock",
|
|
3213
|
+
timer: "Hourglass",
|
|
3214
|
+
// Location
|
|
3215
|
+
map: "Map",
|
|
3216
|
+
"map-pin": "MapPin",
|
|
3217
|
+
navigation: "Navigation",
|
|
3218
|
+
compass: "Compass",
|
|
3219
|
+
globe: "World",
|
|
3220
|
+
target: "Target",
|
|
3221
|
+
// Project / layout
|
|
3222
|
+
kanban: "LayoutKanban",
|
|
3223
|
+
list: "List",
|
|
3224
|
+
table: "Table",
|
|
3225
|
+
grid: "LayoutGrid",
|
|
3226
|
+
layout: "Layout",
|
|
3227
|
+
columns: "LayoutColumns",
|
|
3228
|
+
rows: "LayoutRows",
|
|
3229
|
+
// Misc
|
|
3230
|
+
bell: "Bell",
|
|
3231
|
+
bookmark: "Bookmark",
|
|
3232
|
+
briefcase: "Briefcase",
|
|
3233
|
+
flag: "Flag",
|
|
3234
|
+
tag: "Tag",
|
|
3235
|
+
tags: "Tags",
|
|
3236
|
+
star: "Star",
|
|
3237
|
+
heart: "Heart",
|
|
3238
|
+
home: "Home",
|
|
3239
|
+
settings: "Settings",
|
|
3240
|
+
eye: "Eye",
|
|
3241
|
+
"eye-off": "EyeOff",
|
|
3242
|
+
lock: "Lock",
|
|
3243
|
+
unlock: "LockOpen",
|
|
3244
|
+
key: "Key",
|
|
3245
|
+
shield: "Shield",
|
|
3246
|
+
search: "Search",
|
|
3247
|
+
filter: "Filter",
|
|
3248
|
+
"sort-asc": "SortAscending",
|
|
3249
|
+
"sort-desc": "SortDescending",
|
|
3250
|
+
zap: "Bolt",
|
|
3251
|
+
sparkles: "Sparkles",
|
|
3252
|
+
// Code / data
|
|
3253
|
+
code: "Code",
|
|
3254
|
+
terminal: "Terminal",
|
|
3255
|
+
database: "Database",
|
|
3256
|
+
server: "Server",
|
|
3257
|
+
cloud: "Cloud",
|
|
3258
|
+
wifi: "Wifi",
|
|
3259
|
+
package: "Package",
|
|
3260
|
+
box: "Box",
|
|
3261
|
+
// Theme
|
|
3262
|
+
sun: "Sun",
|
|
3263
|
+
moon: "Moon",
|
|
3264
|
+
// Phone
|
|
3265
|
+
phone: "Phone",
|
|
3266
|
+
printer: "Printer",
|
|
3267
|
+
// Hierarchy
|
|
3268
|
+
tree: "Hierarchy",
|
|
3269
|
+
network: "Network"
|
|
2851
3270
|
};
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
3271
|
+
function resolveTabler(name, family) {
|
|
3272
|
+
const suffix = tablerAliases[name] ?? kebabToPascal(name);
|
|
3273
|
+
const target = `Icon${suffix}`;
|
|
3274
|
+
return lazyFamilyIcon(
|
|
3275
|
+
"tabler",
|
|
3276
|
+
() => import('@tabler/icons-react'),
|
|
3277
|
+
(lib) => {
|
|
3278
|
+
const TablerComp = lib[target];
|
|
3279
|
+
if (!TablerComp || typeof TablerComp !== "object") return null;
|
|
3280
|
+
const Component2 = TablerComp;
|
|
3281
|
+
const Adapter = (props) => /* @__PURE__ */ jsx(
|
|
3282
|
+
Component2,
|
|
3283
|
+
{
|
|
3284
|
+
stroke: props.strokeWidth ?? 1.5,
|
|
3285
|
+
className: props.className,
|
|
3286
|
+
style: props.style,
|
|
3287
|
+
size: props.size ?? 24
|
|
3288
|
+
}
|
|
3289
|
+
);
|
|
3290
|
+
Adapter.displayName = `Tabler.${target}`;
|
|
3291
|
+
return Adapter;
|
|
3292
|
+
},
|
|
3293
|
+
name,
|
|
3294
|
+
family
|
|
3295
|
+
);
|
|
3296
|
+
}
|
|
3297
|
+
var faAliases = {
|
|
3298
|
+
// lucide name → fa-solid suffix (after the `Fa` prefix).
|
|
3299
|
+
// react-icons/fa ships FontAwesome 5 — names like `FaFileText` don't exist
|
|
3300
|
+
// (FA renamed to `FaFileAlt`). When you see a console.warn from
|
|
3301
|
+
// [iconFamily] about an unmapped lucide name in this family, add the
|
|
3302
|
+
// closest FA5 sibling here so the fallback stays in-family.
|
|
3303
|
+
search: "Search",
|
|
3304
|
+
close: "Times",
|
|
3305
|
+
x: "Times",
|
|
3306
|
+
loader: "Spinner",
|
|
3307
|
+
refresh: "Sync",
|
|
3308
|
+
"sort-asc": "SortAmountUp",
|
|
3309
|
+
"sort-desc": "SortAmountDown",
|
|
3310
|
+
"chevron-down": "ChevronDown",
|
|
3311
|
+
"chevron-up": "ChevronUp",
|
|
3312
|
+
"chevron-left": "ChevronLeft",
|
|
3313
|
+
"chevron-right": "ChevronRight",
|
|
3314
|
+
"help-circle": "QuestionCircle",
|
|
3315
|
+
"alert-triangle": "ExclamationTriangle",
|
|
3316
|
+
"alert-circle": "ExclamationCircle",
|
|
3317
|
+
"check-circle": "CheckCircle",
|
|
3318
|
+
"x-circle": "TimesCircle",
|
|
3319
|
+
edit: "Edit",
|
|
3320
|
+
pencil: "PencilAlt",
|
|
3321
|
+
trash: "Trash",
|
|
3322
|
+
send: "PaperPlane",
|
|
3323
|
+
share: "ShareAlt",
|
|
3324
|
+
external: "ExternalLinkAlt",
|
|
3325
|
+
plus: "Plus",
|
|
3326
|
+
minus: "Minus",
|
|
3327
|
+
check: "Check",
|
|
3328
|
+
star: "Star",
|
|
3329
|
+
heart: "Heart",
|
|
3330
|
+
home: "Home",
|
|
3331
|
+
user: "User",
|
|
3332
|
+
users: "Users",
|
|
3333
|
+
"user-plus": "UserPlus",
|
|
3334
|
+
"user-check": "UserCheck",
|
|
3335
|
+
settings: "Cog",
|
|
3336
|
+
menu: "Bars",
|
|
3337
|
+
"arrow-up": "ArrowUp",
|
|
3338
|
+
"arrow-down": "ArrowDown",
|
|
3339
|
+
"arrow-left": "ArrowLeft",
|
|
3340
|
+
"arrow-right": "ArrowRight",
|
|
3341
|
+
copy: "Copy",
|
|
3342
|
+
download: "Download",
|
|
3343
|
+
upload: "Upload",
|
|
3344
|
+
filter: "Filter",
|
|
3345
|
+
calendar: "Calendar",
|
|
3346
|
+
clock: "Clock",
|
|
3347
|
+
bell: "Bell",
|
|
3348
|
+
mail: "Envelope",
|
|
3349
|
+
envelope: "Envelope",
|
|
3350
|
+
lock: "Lock",
|
|
3351
|
+
unlock: "LockOpen",
|
|
3352
|
+
eye: "Eye",
|
|
3353
|
+
"eye-off": "EyeSlash",
|
|
3354
|
+
more: "EllipsisH",
|
|
3355
|
+
"more-vertical": "EllipsisV",
|
|
3356
|
+
info: "InfoCircle",
|
|
3357
|
+
warning: "ExclamationTriangle",
|
|
3358
|
+
error: "ExclamationCircle",
|
|
3359
|
+
// Time
|
|
3360
|
+
timer: "Hourglass",
|
|
3361
|
+
// Files (FA renamed FileText → FileAlt)
|
|
3362
|
+
file: "File",
|
|
3363
|
+
"file-text": "FileAlt",
|
|
3364
|
+
"file-plus": "FileMedical",
|
|
3365
|
+
"file-minus": "FileExcel",
|
|
3366
|
+
"file-check": "FileSignature",
|
|
3367
|
+
document: "FileAlt",
|
|
3368
|
+
// Charts (lucide BarChart2 / BarChart3 → FA ChartBar)
|
|
3369
|
+
"bar-chart": "ChartBar",
|
|
3370
|
+
"bar-chart-2": "ChartBar",
|
|
3371
|
+
"bar-chart-3": "ChartBar",
|
|
3372
|
+
"line-chart": "ChartLine",
|
|
3373
|
+
"pie-chart": "ChartPie",
|
|
3374
|
+
activity: "ChartLine",
|
|
3375
|
+
"trending-up": "ChartLine",
|
|
3376
|
+
"trending-down": "ChartLine",
|
|
3377
|
+
// Messages (lucide MessageCircle/MessageSquare → FA CommentDots/CommentAlt)
|
|
3378
|
+
message: "Comment",
|
|
3379
|
+
"message-circle": "CommentDots",
|
|
3380
|
+
"message-square": "CommentAlt",
|
|
3381
|
+
"messages-square": "Comments",
|
|
3382
|
+
comment: "Comment",
|
|
3383
|
+
comments: "Comments",
|
|
3384
|
+
inbox: "Inbox",
|
|
3385
|
+
// Support / help
|
|
3386
|
+
"life-buoy": "LifeRing",
|
|
3387
|
+
lifebuoy: "LifeRing",
|
|
3388
|
+
// Project / kanban (FA has no kanban; closest semantic is Tasks/Columns)
|
|
3389
|
+
kanban: "Tasks",
|
|
3390
|
+
columns: "Columns",
|
|
3391
|
+
rows: "Bars",
|
|
3392
|
+
layout: "ThLarge",
|
|
3393
|
+
grid: "Th",
|
|
3394
|
+
list: "List",
|
|
3395
|
+
table: "Table",
|
|
3396
|
+
// Storage / folders
|
|
3397
|
+
folder: "Folder",
|
|
3398
|
+
"folder-open": "FolderOpen",
|
|
3399
|
+
archive: "Archive",
|
|
3400
|
+
bookmark: "Bookmark",
|
|
3401
|
+
briefcase: "Briefcase",
|
|
3402
|
+
package: "Box",
|
|
3403
|
+
box: "Box",
|
|
3404
|
+
// Map / location
|
|
3405
|
+
map: "Map",
|
|
3406
|
+
"map-pin": "MapMarkerAlt",
|
|
3407
|
+
navigation: "LocationArrow",
|
|
3408
|
+
compass: "Compass",
|
|
3409
|
+
globe: "Globe",
|
|
3410
|
+
target: "Bullseye",
|
|
3411
|
+
// Media
|
|
3412
|
+
image: "Image",
|
|
3413
|
+
video: "Video",
|
|
3414
|
+
film: "Film",
|
|
3415
|
+
camera: "Camera",
|
|
3416
|
+
music: "Music",
|
|
3417
|
+
play: "Play",
|
|
3418
|
+
pause: "Pause",
|
|
3419
|
+
stop: "Stop",
|
|
3420
|
+
"skip-forward": "Forward",
|
|
3421
|
+
"skip-back": "Backward",
|
|
3422
|
+
volume: "VolumeUp",
|
|
3423
|
+
"volume-2": "VolumeUp",
|
|
3424
|
+
"volume-x": "VolumeMute",
|
|
3425
|
+
mic: "Microphone",
|
|
3426
|
+
"mic-off": "MicrophoneSlash",
|
|
3427
|
+
phone: "Phone",
|
|
3428
|
+
// Code / data
|
|
3429
|
+
code: "Code",
|
|
3430
|
+
terminal: "Terminal",
|
|
3431
|
+
database: "Database",
|
|
3432
|
+
server: "Server",
|
|
3433
|
+
cloud: "Cloud",
|
|
3434
|
+
wifi: "Wifi",
|
|
3435
|
+
// Security
|
|
3436
|
+
shield: "ShieldAlt",
|
|
3437
|
+
key: "Key",
|
|
3438
|
+
// Misc actions
|
|
3439
|
+
printer: "Print",
|
|
3440
|
+
save: "Save",
|
|
3441
|
+
link: "Link",
|
|
3442
|
+
unlink: "Unlink",
|
|
3443
|
+
paperclip: "Paperclip",
|
|
3444
|
+
flag: "Flag",
|
|
3445
|
+
tag: "Tag",
|
|
3446
|
+
tags: "Tags",
|
|
3447
|
+
zap: "Bolt",
|
|
3448
|
+
sparkles: "Magic",
|
|
3449
|
+
// Theme
|
|
3450
|
+
sun: "Sun",
|
|
3451
|
+
moon: "Moon",
|
|
3452
|
+
// Hierarchy (FA has no Tree icon for hierarchies; Sitemap is the org-chart icon)
|
|
3453
|
+
tree: "Sitemap",
|
|
3454
|
+
network: "NetworkWired"
|
|
2861
3455
|
};
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
3456
|
+
function resolveFa(name, family) {
|
|
3457
|
+
const suffix = faAliases[name] ?? kebabToPascal(name);
|
|
3458
|
+
const target = `Fa${suffix}`;
|
|
3459
|
+
return lazyFamilyIcon(
|
|
3460
|
+
"fa",
|
|
3461
|
+
() => import('react-icons/fa'),
|
|
3462
|
+
(lib) => {
|
|
3463
|
+
const FaComp = lib[target];
|
|
3464
|
+
if (!FaComp || typeof FaComp !== "function") return null;
|
|
3465
|
+
const Component2 = FaComp;
|
|
3466
|
+
const Adapter = (props) => /* @__PURE__ */ jsx(
|
|
3467
|
+
Component2,
|
|
3468
|
+
{
|
|
3469
|
+
className: props.className,
|
|
3470
|
+
style: props.style,
|
|
3471
|
+
size: props.size ?? "1em"
|
|
3472
|
+
}
|
|
3473
|
+
);
|
|
3474
|
+
Adapter.displayName = `Fa.${target}`;
|
|
3475
|
+
return Adapter;
|
|
3476
|
+
},
|
|
3477
|
+
name,
|
|
3478
|
+
family
|
|
3479
|
+
);
|
|
3480
|
+
}
|
|
3481
|
+
var warned = /* @__PURE__ */ new Set();
|
|
3482
|
+
function warnFallback(name, family) {
|
|
3483
|
+
const key = `${family}::${name}`;
|
|
3484
|
+
if (warned.has(key)) return;
|
|
3485
|
+
warned.add(key);
|
|
3486
|
+
if (typeof console !== "undefined") {
|
|
3487
|
+
console.warn(
|
|
3488
|
+
`[iconFamily] No '${name}' mapping in family '${family}'; falling back to lucide. Add an alias in lib/iconFamily.ts.`
|
|
3489
|
+
);
|
|
3490
|
+
}
|
|
3491
|
+
}
|
|
3492
|
+
function makeLucideAdapter(name, isFallback = false) {
|
|
3493
|
+
const LucideComp = resolveLucide(name);
|
|
3494
|
+
const Adapter = (props) => {
|
|
3495
|
+
const stroke = props.strokeWidth ?? (isFallback ? 2 : void 0);
|
|
3496
|
+
const style = isFallback ? { ...props.style ?? {}, strokeWidth: stroke ?? 2 } : props.style;
|
|
3497
|
+
return /* @__PURE__ */ jsx(
|
|
3498
|
+
LucideComp,
|
|
3499
|
+
{
|
|
3500
|
+
className: props.className,
|
|
3501
|
+
strokeWidth: stroke,
|
|
3502
|
+
style,
|
|
3503
|
+
size: props.size
|
|
3504
|
+
}
|
|
3505
|
+
);
|
|
3506
|
+
};
|
|
3507
|
+
Adapter.displayName = `Lucide.${name}${isFallback ? ".fallback" : ""}`;
|
|
3508
|
+
return Adapter;
|
|
3509
|
+
}
|
|
3510
|
+
function resolveIconForFamily(name, family) {
|
|
3511
|
+
switch (family) {
|
|
3512
|
+
case "lucide":
|
|
3513
|
+
return makeLucideAdapter(name, false);
|
|
3514
|
+
// Non-lucide families resolve to a lazy, Suspense-wrapped component that
|
|
3515
|
+
// dynamic-imports the library on first render and falls back to lucide
|
|
3516
|
+
// internally when the family lacks the icon (see lazyFamilyIcon).
|
|
3517
|
+
case "phosphor-outline":
|
|
3518
|
+
return resolvePhosphor(name, "regular", family);
|
|
3519
|
+
case "phosphor-fill":
|
|
3520
|
+
return resolvePhosphor(name, "fill", family);
|
|
3521
|
+
case "phosphor-duotone":
|
|
3522
|
+
return resolvePhosphor(name, "duotone", family);
|
|
3523
|
+
case "tabler":
|
|
3524
|
+
return resolveTabler(name, family);
|
|
3525
|
+
case "fa-solid":
|
|
3526
|
+
return resolveFa(name, family);
|
|
3527
|
+
}
|
|
3528
|
+
}
|
|
3529
|
+
var colorTokenClasses = {
|
|
3530
|
+
primary: "text-primary",
|
|
3531
|
+
secondary: "text-secondary",
|
|
3532
|
+
success: "text-success",
|
|
3533
|
+
warning: "text-warning",
|
|
3534
|
+
error: "text-error",
|
|
3535
|
+
muted: "text-muted-foreground"
|
|
2871
3536
|
};
|
|
2872
|
-
var
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
surface: "bg-card",
|
|
2879
|
-
overlay: "bg-card/80 backdrop-blur-sm"
|
|
3537
|
+
var sizeClasses = {
|
|
3538
|
+
xs: "w-3 h-3",
|
|
3539
|
+
sm: "w-4 h-4",
|
|
3540
|
+
md: "h-icon-default w-icon-default",
|
|
3541
|
+
lg: "w-6 h-6",
|
|
3542
|
+
xl: "w-8 h-8"
|
|
2880
3543
|
};
|
|
2881
|
-
var
|
|
2882
|
-
none: "
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
lg: "rounded-lg",
|
|
2886
|
-
xl: "rounded-xl",
|
|
2887
|
-
"2xl": "rounded-xl",
|
|
2888
|
-
full: "rounded-full"
|
|
3544
|
+
var animationClasses = {
|
|
3545
|
+
none: "",
|
|
3546
|
+
spin: "animate-spin",
|
|
3547
|
+
pulse: "animate-pulse"
|
|
2889
3548
|
};
|
|
2890
|
-
var
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
3549
|
+
var Icon = ({
|
|
3550
|
+
icon,
|
|
3551
|
+
name,
|
|
3552
|
+
size = "md",
|
|
3553
|
+
color,
|
|
3554
|
+
animation = "none",
|
|
3555
|
+
className,
|
|
3556
|
+
strokeWidth,
|
|
3557
|
+
style
|
|
3558
|
+
}) => {
|
|
3559
|
+
const directIcon = typeof icon === "string" ? void 0 : icon;
|
|
3560
|
+
const effectiveName = typeof icon === "string" ? icon : name;
|
|
3561
|
+
const family = useIconFamily();
|
|
3562
|
+
const RenderedComponent = React11.useMemo(() => {
|
|
3563
|
+
if (directIcon) return null;
|
|
3564
|
+
return effectiveName ? resolveIconForFamily(effectiveName, family) : null;
|
|
3565
|
+
}, [directIcon, effectiveName, family]);
|
|
3566
|
+
const effectiveStrokeWidth = strokeWidth ?? void 0;
|
|
3567
|
+
const inlineStyle = {
|
|
3568
|
+
...effectiveStrokeWidth === void 0 ? { strokeWidth: "var(--icon-stroke-width, 2)" } : {},
|
|
3569
|
+
...style
|
|
3570
|
+
};
|
|
3571
|
+
const resolvedColor = color ? color in colorTokenClasses ? colorTokenClasses[color] : color : "text-current";
|
|
3572
|
+
const composedClassName = cn(
|
|
3573
|
+
sizeClasses[size],
|
|
3574
|
+
animationClasses[animation],
|
|
3575
|
+
resolvedColor,
|
|
3576
|
+
className
|
|
3577
|
+
);
|
|
3578
|
+
if (directIcon) {
|
|
3579
|
+
const Direct = directIcon;
|
|
3580
|
+
return /* @__PURE__ */ jsx(
|
|
3581
|
+
Direct,
|
|
3582
|
+
{
|
|
3583
|
+
className: composedClassName,
|
|
3584
|
+
strokeWidth: effectiveStrokeWidth,
|
|
3585
|
+
style: inlineStyle
|
|
3586
|
+
}
|
|
3587
|
+
);
|
|
3588
|
+
}
|
|
3589
|
+
if (RenderedComponent) {
|
|
3590
|
+
return /* @__PURE__ */ jsx(
|
|
3591
|
+
RenderedComponent,
|
|
3592
|
+
{
|
|
3593
|
+
className: composedClassName,
|
|
3594
|
+
strokeWidth: effectiveStrokeWidth,
|
|
3595
|
+
style: inlineStyle
|
|
3596
|
+
}
|
|
3597
|
+
);
|
|
3598
|
+
}
|
|
3599
|
+
const Fallback = LucideIcons.HelpCircle;
|
|
3600
|
+
return /* @__PURE__ */ jsx(
|
|
3601
|
+
Fallback,
|
|
3602
|
+
{
|
|
3603
|
+
className: composedClassName,
|
|
3604
|
+
strokeWidth: effectiveStrokeWidth,
|
|
3605
|
+
style: inlineStyle
|
|
3606
|
+
}
|
|
3607
|
+
);
|
|
2896
3608
|
};
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
3609
|
+
Icon.displayName = "Icon";
|
|
3610
|
+
var variantStyles = {
|
|
3611
|
+
primary: [
|
|
3612
|
+
"bg-primary text-primary-foreground",
|
|
3613
|
+
"border-none",
|
|
3614
|
+
"shadow-sm",
|
|
3615
|
+
"hover:bg-primary-hover hover:shadow-lg",
|
|
3616
|
+
"active:scale-[var(--active-scale)] active:shadow-sm"
|
|
3617
|
+
].join(" "),
|
|
3618
|
+
secondary: [
|
|
3619
|
+
"bg-transparent text-accent",
|
|
3620
|
+
"border border-accent",
|
|
3621
|
+
"hover:bg-accent hover:text-white hover:border-accent",
|
|
3622
|
+
"active:scale-[var(--active-scale)]"
|
|
3623
|
+
].join(" "),
|
|
3624
|
+
ghost: [
|
|
3625
|
+
"bg-transparent text-muted-foreground",
|
|
3626
|
+
"border border-transparent",
|
|
3627
|
+
"hover:text-primary-foreground hover:bg-primary hover:border-primary",
|
|
3628
|
+
"active:scale-[var(--active-scale)]"
|
|
3629
|
+
].join(" "),
|
|
3630
|
+
danger: [
|
|
3631
|
+
"bg-surface text-error",
|
|
3632
|
+
"border-[length:var(--border-width)] border-error",
|
|
3633
|
+
"shadow-sm",
|
|
3634
|
+
"hover:bg-error hover:text-error-foreground hover:shadow-lg",
|
|
3635
|
+
"active:scale-[var(--active-scale)] active:shadow-sm"
|
|
3636
|
+
].join(" "),
|
|
3637
|
+
success: [
|
|
3638
|
+
"bg-surface text-success",
|
|
3639
|
+
"border-[length:var(--border-width)] border-success",
|
|
3640
|
+
"shadow-sm",
|
|
3641
|
+
"hover:bg-success hover:text-success-foreground hover:shadow-lg",
|
|
3642
|
+
"active:scale-[var(--active-scale)] active:shadow-sm"
|
|
3643
|
+
].join(" "),
|
|
3644
|
+
warning: [
|
|
3645
|
+
"bg-surface text-warning",
|
|
3646
|
+
"border-[length:var(--border-width)] border-warning",
|
|
3647
|
+
"shadow-sm",
|
|
3648
|
+
"hover:bg-warning hover:text-warning-foreground hover:shadow-lg",
|
|
3649
|
+
"active:scale-[var(--active-scale)] active:shadow-sm"
|
|
3650
|
+
].join(" "),
|
|
3651
|
+
// "default" is an alias for secondary
|
|
3652
|
+
default: [
|
|
3653
|
+
"bg-secondary text-secondary-foreground",
|
|
3654
|
+
"border-[length:var(--border-width-thin)] border-border",
|
|
3655
|
+
"hover:bg-secondary-hover",
|
|
3656
|
+
"active:scale-[var(--active-scale)]"
|
|
3657
|
+
].join(" ")
|
|
2904
3658
|
};
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
3659
|
+
variantStyles.destructive = variantStyles.danger;
|
|
3660
|
+
var sizeStyles = {
|
|
3661
|
+
sm: "h-button-sm px-3 text-sm",
|
|
3662
|
+
md: "h-button-md px-4 text-sm",
|
|
3663
|
+
lg: "h-button-lg px-6 text-base"
|
|
2910
3664
|
};
|
|
2911
|
-
var
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
sticky: "sticky"
|
|
3665
|
+
var iconSizeStyles = {
|
|
3666
|
+
sm: "h-icon-default w-icon-default",
|
|
3667
|
+
md: "h-icon-default w-icon-default",
|
|
3668
|
+
lg: "h-icon-default w-icon-default"
|
|
2916
3669
|
};
|
|
2917
|
-
|
|
3670
|
+
function resolveIconProp(value, sizeClass) {
|
|
3671
|
+
if (!value) return null;
|
|
3672
|
+
if (typeof value === "string") {
|
|
3673
|
+
return /* @__PURE__ */ jsx(Icon, { name: value, className: sizeClass });
|
|
3674
|
+
}
|
|
3675
|
+
if (typeof value === "function") {
|
|
3676
|
+
const IconComp = value;
|
|
3677
|
+
return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
|
|
3678
|
+
}
|
|
3679
|
+
if (React11.isValidElement(value)) {
|
|
3680
|
+
return value;
|
|
3681
|
+
}
|
|
3682
|
+
if (typeof value === "object" && value !== null && "render" in value) {
|
|
3683
|
+
const IconComp = value;
|
|
3684
|
+
return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
|
|
3685
|
+
}
|
|
3686
|
+
return value;
|
|
3687
|
+
}
|
|
3688
|
+
var Button = React11.forwardRef(
|
|
2918
3689
|
({
|
|
2919
|
-
padding,
|
|
2920
|
-
paddingX,
|
|
2921
|
-
paddingY,
|
|
2922
|
-
margin,
|
|
2923
|
-
marginX,
|
|
2924
|
-
marginY,
|
|
2925
|
-
bg = "transparent",
|
|
2926
|
-
border = false,
|
|
2927
|
-
rounded = "none",
|
|
2928
|
-
shadow = "none",
|
|
2929
|
-
display,
|
|
2930
|
-
fullWidth = false,
|
|
2931
|
-
fullHeight = false,
|
|
2932
|
-
overflow,
|
|
2933
|
-
position,
|
|
2934
3690
|
className,
|
|
2935
|
-
|
|
2936
|
-
|
|
3691
|
+
variant = "primary",
|
|
3692
|
+
size = "md",
|
|
3693
|
+
isLoading = false,
|
|
3694
|
+
disabled,
|
|
3695
|
+
leftIcon,
|
|
3696
|
+
rightIcon,
|
|
3697
|
+
icon: iconProp,
|
|
3698
|
+
iconRight: iconRightProp,
|
|
2937
3699
|
action,
|
|
2938
3700
|
actionPayload,
|
|
2939
|
-
|
|
2940
|
-
|
|
3701
|
+
label,
|
|
3702
|
+
children,
|
|
2941
3703
|
onClick,
|
|
2942
|
-
|
|
2943
|
-
onMouseLeave,
|
|
2944
|
-
...rest
|
|
3704
|
+
...props
|
|
2945
3705
|
}, ref) => {
|
|
2946
3706
|
const eventBus = useEventBus();
|
|
2947
|
-
const
|
|
3707
|
+
const leftIconValue = leftIcon || iconProp;
|
|
3708
|
+
const rightIconValue = rightIcon || iconRightProp;
|
|
3709
|
+
const resolvedLeftIcon = resolveIconProp(leftIconValue, iconSizeStyles[size]);
|
|
3710
|
+
const resolvedRightIcon = resolveIconProp(rightIconValue, iconSizeStyles[size]);
|
|
3711
|
+
const handleClick = (e) => {
|
|
2948
3712
|
if (action) {
|
|
2949
|
-
e.stopPropagation();
|
|
2950
3713
|
eventBus.emit(`UI:${action}`, actionPayload ?? {});
|
|
2951
3714
|
}
|
|
2952
3715
|
onClick?.(e);
|
|
2953
|
-
}
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
eventBus.emit(`UI:${hoverEvent}`, { hovered: true });
|
|
2957
|
-
}
|
|
2958
|
-
onMouseEnter?.(e);
|
|
2959
|
-
}, [hoverEvent, eventBus, onMouseEnter]);
|
|
2960
|
-
const handleMouseLeave = useCallback((e) => {
|
|
2961
|
-
if (hoverEvent) {
|
|
2962
|
-
eventBus.emit(`UI:${hoverEvent}`, { hovered: false });
|
|
2963
|
-
}
|
|
2964
|
-
onMouseLeave?.(e);
|
|
2965
|
-
}, [hoverEvent, eventBus, onMouseLeave]);
|
|
2966
|
-
const isClickable = action || onClick;
|
|
2967
|
-
return React11.createElement(
|
|
2968
|
-
Component2,
|
|
3716
|
+
};
|
|
3717
|
+
return /* @__PURE__ */ jsxs(
|
|
3718
|
+
"button",
|
|
2969
3719
|
{
|
|
2970
3720
|
ref,
|
|
3721
|
+
disabled: disabled || isLoading,
|
|
2971
3722
|
className: cn(
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
shadowStyles[shadow],
|
|
2982
|
-
display && displayStyles[display],
|
|
2983
|
-
fullWidth && "w-full",
|
|
2984
|
-
fullHeight && "h-full",
|
|
2985
|
-
overflow && overflowStyles[overflow],
|
|
2986
|
-
position && positionStyles[position],
|
|
2987
|
-
isClickable && "cursor-pointer",
|
|
3723
|
+
"inline-flex items-center justify-center gap-2",
|
|
3724
|
+
"font-medium",
|
|
3725
|
+
"rounded-sm",
|
|
3726
|
+
"cursor-pointer",
|
|
3727
|
+
"transition-all duration-[var(--transition-normal)]",
|
|
3728
|
+
"focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-ring focus:ring-offset-[length:var(--focus-ring-offset)]",
|
|
3729
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
3730
|
+
variantStyles[variant],
|
|
3731
|
+
sizeStyles[size],
|
|
2988
3732
|
className
|
|
2989
3733
|
),
|
|
2990
|
-
onClick:
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
3734
|
+
onClick: handleClick,
|
|
3735
|
+
...props,
|
|
3736
|
+
"data-testid": props["data-testid"] ?? (action ? `action-${action}` : void 0),
|
|
3737
|
+
children: [
|
|
3738
|
+
isLoading ? /* @__PURE__ */ jsx(Loader2, { className: "h-icon-default w-icon-default animate-spin" }) : resolvedLeftIcon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: resolvedLeftIcon }),
|
|
3739
|
+
children || label,
|
|
3740
|
+
resolvedRightIcon && !isLoading && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: resolvedRightIcon })
|
|
3741
|
+
]
|
|
3742
|
+
}
|
|
2997
3743
|
);
|
|
2998
3744
|
}
|
|
2999
3745
|
);
|
|
3000
|
-
|
|
3001
|
-
var
|
|
3002
|
-
none: "gap-0",
|
|
3003
|
-
xs: "gap-1",
|
|
3004
|
-
sm: "gap-2",
|
|
3005
|
-
md: "gap-4",
|
|
3006
|
-
lg: "gap-6",
|
|
3007
|
-
xl: "gap-8",
|
|
3008
|
-
"2xl": "gap-12"
|
|
3009
|
-
};
|
|
3010
|
-
var alignStyles = {
|
|
3011
|
-
start: "items-start",
|
|
3012
|
-
center: "items-center",
|
|
3013
|
-
end: "items-end",
|
|
3014
|
-
stretch: "items-stretch",
|
|
3015
|
-
baseline: "items-baseline"
|
|
3016
|
-
};
|
|
3017
|
-
var justifyStyles = {
|
|
3018
|
-
start: "justify-start",
|
|
3019
|
-
center: "justify-center",
|
|
3020
|
-
end: "justify-end",
|
|
3021
|
-
between: "justify-between",
|
|
3022
|
-
around: "justify-around",
|
|
3023
|
-
evenly: "justify-evenly"
|
|
3024
|
-
};
|
|
3025
|
-
var Stack = ({
|
|
3026
|
-
direction = "vertical",
|
|
3027
|
-
gap = "md",
|
|
3028
|
-
align = "stretch",
|
|
3029
|
-
justify = "start",
|
|
3030
|
-
wrap = false,
|
|
3031
|
-
reverse = false,
|
|
3032
|
-
flex = false,
|
|
3033
|
-
className,
|
|
3034
|
-
style,
|
|
3035
|
-
children,
|
|
3036
|
-
as: Component2 = "div",
|
|
3037
|
-
onClick,
|
|
3038
|
-
onKeyDown,
|
|
3039
|
-
role,
|
|
3040
|
-
tabIndex,
|
|
3041
|
-
action,
|
|
3042
|
-
actionPayload,
|
|
3043
|
-
responsive = false
|
|
3044
|
-
}) => {
|
|
3045
|
-
const eventBus = useEventBus();
|
|
3046
|
-
const handleClick = (e) => {
|
|
3047
|
-
if (action) {
|
|
3048
|
-
eventBus.emit(`UI:${action}`, actionPayload ?? {});
|
|
3049
|
-
}
|
|
3050
|
-
onClick?.(e);
|
|
3051
|
-
};
|
|
3052
|
-
const isHorizontal = direction === "horizontal";
|
|
3053
|
-
const directionClass = responsive && isHorizontal ? reverse ? "flex-col-reverse md:flex-row-reverse" : "flex-col md:flex-row" : isHorizontal ? reverse ? "flex-row-reverse" : "flex-row" : reverse ? "flex-col-reverse" : "flex-col";
|
|
3054
|
-
const Comp = Component2;
|
|
3055
|
-
return /* @__PURE__ */ jsx(
|
|
3056
|
-
Comp,
|
|
3057
|
-
{
|
|
3058
|
-
className: cn(
|
|
3059
|
-
"flex",
|
|
3060
|
-
directionClass,
|
|
3061
|
-
gapStyles[gap],
|
|
3062
|
-
alignStyles[align],
|
|
3063
|
-
justifyStyles[justify],
|
|
3064
|
-
wrap && "flex-wrap",
|
|
3065
|
-
flex && "flex-1",
|
|
3066
|
-
className
|
|
3067
|
-
),
|
|
3068
|
-
style,
|
|
3069
|
-
onClick: action || onClick ? handleClick : void 0,
|
|
3070
|
-
onKeyDown,
|
|
3071
|
-
role,
|
|
3072
|
-
tabIndex,
|
|
3073
|
-
children
|
|
3074
|
-
}
|
|
3075
|
-
);
|
|
3076
|
-
};
|
|
3077
|
-
var VStack = (props) => /* @__PURE__ */ jsx(Stack, { direction: "vertical", ...props });
|
|
3078
|
-
var HStack = (props) => /* @__PURE__ */ jsx(Stack, { direction: "horizontal", ...props });
|
|
3079
|
-
var variantStyles = {
|
|
3746
|
+
Button.displayName = "Button";
|
|
3747
|
+
var variantStyles2 = {
|
|
3080
3748
|
h1: "text-4xl font-bold tracking-tight text-foreground",
|
|
3081
3749
|
h2: "text-3xl font-bold tracking-tight text-foreground",
|
|
3082
3750
|
h3: "text-2xl font-bold text-foreground",
|
|
@@ -3137,7 +3805,7 @@ var typographySizeStyles = {
|
|
|
3137
3805
|
"2xl": "text-2xl",
|
|
3138
3806
|
"3xl": "text-3xl"
|
|
3139
3807
|
};
|
|
3140
|
-
var
|
|
3808
|
+
var overflowStyles = {
|
|
3141
3809
|
visible: "overflow-visible",
|
|
3142
3810
|
hidden: "overflow-hidden",
|
|
3143
3811
|
wrap: "break-words overflow-hidden",
|
|
@@ -3168,13 +3836,13 @@ var Typography = ({
|
|
|
3168
3836
|
{
|
|
3169
3837
|
id,
|
|
3170
3838
|
className: cn(
|
|
3171
|
-
|
|
3839
|
+
variantStyles2[variant],
|
|
3172
3840
|
colorStyles[color],
|
|
3173
3841
|
weight && weightStyles[weight],
|
|
3174
3842
|
size && typographySizeStyles[size],
|
|
3175
3843
|
align && `text-${align}`,
|
|
3176
3844
|
truncate && "truncate overflow-hidden text-ellipsis",
|
|
3177
|
-
overflow &&
|
|
3845
|
+
overflow && overflowStyles[overflow],
|
|
3178
3846
|
className
|
|
3179
3847
|
),
|
|
3180
3848
|
style,
|
|
@@ -3183,6 +3851,459 @@ var Typography = ({
|
|
|
3183
3851
|
);
|
|
3184
3852
|
};
|
|
3185
3853
|
Typography.displayName = "Typography";
|
|
3854
|
+
var gapStyles = {
|
|
3855
|
+
none: "gap-0",
|
|
3856
|
+
xs: "gap-1",
|
|
3857
|
+
sm: "gap-2",
|
|
3858
|
+
md: "gap-4",
|
|
3859
|
+
lg: "gap-6",
|
|
3860
|
+
xl: "gap-8",
|
|
3861
|
+
"2xl": "gap-12"
|
|
3862
|
+
};
|
|
3863
|
+
var alignStyles = {
|
|
3864
|
+
start: "items-start",
|
|
3865
|
+
center: "items-center",
|
|
3866
|
+
end: "items-end",
|
|
3867
|
+
stretch: "items-stretch",
|
|
3868
|
+
baseline: "items-baseline"
|
|
3869
|
+
};
|
|
3870
|
+
var justifyStyles = {
|
|
3871
|
+
start: "justify-start",
|
|
3872
|
+
center: "justify-center",
|
|
3873
|
+
end: "justify-end",
|
|
3874
|
+
between: "justify-between",
|
|
3875
|
+
around: "justify-around",
|
|
3876
|
+
evenly: "justify-evenly"
|
|
3877
|
+
};
|
|
3878
|
+
var Stack = ({
|
|
3879
|
+
direction = "vertical",
|
|
3880
|
+
gap = "md",
|
|
3881
|
+
align = "stretch",
|
|
3882
|
+
justify = "start",
|
|
3883
|
+
wrap = false,
|
|
3884
|
+
reverse = false,
|
|
3885
|
+
flex = false,
|
|
3886
|
+
className,
|
|
3887
|
+
style,
|
|
3888
|
+
children,
|
|
3889
|
+
as: Component2 = "div",
|
|
3890
|
+
onClick,
|
|
3891
|
+
onKeyDown,
|
|
3892
|
+
role,
|
|
3893
|
+
tabIndex,
|
|
3894
|
+
action,
|
|
3895
|
+
actionPayload,
|
|
3896
|
+
responsive = false
|
|
3897
|
+
}) => {
|
|
3898
|
+
const eventBus = useEventBus();
|
|
3899
|
+
const handleClick = (e) => {
|
|
3900
|
+
if (action) {
|
|
3901
|
+
eventBus.emit(`UI:${action}`, actionPayload ?? {});
|
|
3902
|
+
}
|
|
3903
|
+
onClick?.(e);
|
|
3904
|
+
};
|
|
3905
|
+
const isHorizontal = direction === "horizontal";
|
|
3906
|
+
const directionClass = responsive && isHorizontal ? reverse ? "flex-col-reverse md:flex-row-reverse" : "flex-col md:flex-row" : isHorizontal ? reverse ? "flex-row-reverse" : "flex-row" : reverse ? "flex-col-reverse" : "flex-col";
|
|
3907
|
+
const Comp = Component2;
|
|
3908
|
+
return /* @__PURE__ */ jsx(
|
|
3909
|
+
Comp,
|
|
3910
|
+
{
|
|
3911
|
+
className: cn(
|
|
3912
|
+
"flex",
|
|
3913
|
+
directionClass,
|
|
3914
|
+
gapStyles[gap],
|
|
3915
|
+
alignStyles[align],
|
|
3916
|
+
justifyStyles[justify],
|
|
3917
|
+
wrap && "flex-wrap",
|
|
3918
|
+
flex && "flex-1",
|
|
3919
|
+
className
|
|
3920
|
+
),
|
|
3921
|
+
style,
|
|
3922
|
+
onClick: action || onClick ? handleClick : void 0,
|
|
3923
|
+
onKeyDown,
|
|
3924
|
+
role,
|
|
3925
|
+
tabIndex,
|
|
3926
|
+
children
|
|
3927
|
+
}
|
|
3928
|
+
);
|
|
3929
|
+
};
|
|
3930
|
+
var VStack = (props) => /* @__PURE__ */ jsx(Stack, { direction: "vertical", ...props });
|
|
3931
|
+
var HStack = (props) => /* @__PURE__ */ jsx(Stack, { direction: "horizontal", ...props });
|
|
3932
|
+
|
|
3933
|
+
// components/game/organisms/boardEntity.ts
|
|
3934
|
+
function boardEntity(entity) {
|
|
3935
|
+
if (!entity) return void 0;
|
|
3936
|
+
return Array.isArray(entity) ? entity[0] : entity;
|
|
3937
|
+
}
|
|
3938
|
+
function str(v) {
|
|
3939
|
+
return v == null ? "" : String(v);
|
|
3940
|
+
}
|
|
3941
|
+
function num(v, fallback = 0) {
|
|
3942
|
+
const n = Number(v);
|
|
3943
|
+
return Number.isFinite(n) ? n : fallback;
|
|
3944
|
+
}
|
|
3945
|
+
function rows(v) {
|
|
3946
|
+
return Array.isArray(v) ? v : [];
|
|
3947
|
+
}
|
|
3948
|
+
function vec2(v) {
|
|
3949
|
+
const o = v ?? {};
|
|
3950
|
+
return { x: num(o.x), y: num(o.y) };
|
|
3951
|
+
}
|
|
3952
|
+
function unitPosition(u) {
|
|
3953
|
+
return vec2(u.position);
|
|
3954
|
+
}
|
|
3955
|
+
function unitTeam(u) {
|
|
3956
|
+
return str(u.team);
|
|
3957
|
+
}
|
|
3958
|
+
function unitHealth(u) {
|
|
3959
|
+
return num(u.health);
|
|
3960
|
+
}
|
|
3961
|
+
function GameBoard3D({
|
|
3962
|
+
entity,
|
|
3963
|
+
tiles = [],
|
|
3964
|
+
features = [],
|
|
3965
|
+
cameraMode = "perspective",
|
|
3966
|
+
backgroundColor = "#2a1a1a",
|
|
3967
|
+
tileClickEvent,
|
|
3968
|
+
unitClickEvent,
|
|
3969
|
+
attackEvent,
|
|
3970
|
+
endTurnEvent,
|
|
3971
|
+
cancelEvent,
|
|
3972
|
+
playAgainEvent,
|
|
3973
|
+
gameEndEvent,
|
|
3974
|
+
className
|
|
3975
|
+
}) {
|
|
3976
|
+
const row = boardEntity(entity);
|
|
3977
|
+
const eventBus = useEventBus();
|
|
3978
|
+
const entityUnits = row ? rows(row.units) : [];
|
|
3979
|
+
const units = entityUnits;
|
|
3980
|
+
const selectedUnitId = row ? str(row.selectedUnitId) || null : null;
|
|
3981
|
+
const phase = row ? str(row.phase) : "observation";
|
|
3982
|
+
const result = row ? str(row.result) : "none";
|
|
3983
|
+
const validMoves = row && Array.isArray(row.validMoves) ? row.validMoves : [];
|
|
3984
|
+
const attackTargets = row && Array.isArray(row.attackTargets) ? row.attackTargets : [];
|
|
3985
|
+
const turn = row ? num(row.turn) : 0;
|
|
3986
|
+
const currentTeam = row ? str(row.currentTeam) : "player";
|
|
3987
|
+
const isGameOver = result !== "none";
|
|
3988
|
+
const gameEndEmittedRef = useRef(false);
|
|
3989
|
+
useEffect(() => {
|
|
3990
|
+
if ((result === "victory" || result === "defeat") && gameEndEvent) {
|
|
3991
|
+
if (!gameEndEmittedRef.current) {
|
|
3992
|
+
gameEndEmittedRef.current = true;
|
|
3993
|
+
eventBus.emit(`UI:${gameEndEvent}`, { result });
|
|
3994
|
+
}
|
|
3995
|
+
} else {
|
|
3996
|
+
gameEndEmittedRef.current = false;
|
|
3997
|
+
}
|
|
3998
|
+
}, [result, gameEndEvent, eventBus]);
|
|
3999
|
+
const checkGameEnd = useCallback(() => {
|
|
4000
|
+
const alivePlayer = entityUnits.filter((u) => unitTeam(u) === "player" && unitHealth(u) > 0);
|
|
4001
|
+
const aliveEnemy = entityUnits.filter((u) => unitTeam(u) === "enemy" && unitHealth(u) > 0);
|
|
4002
|
+
if (alivePlayer.length === 0 && gameEndEvent) {
|
|
4003
|
+
eventBus.emit(`UI:${gameEndEvent}`, { result: "defeat" });
|
|
4004
|
+
} else if (aliveEnemy.length === 0 && gameEndEvent) {
|
|
4005
|
+
eventBus.emit(`UI:${gameEndEvent}`, { result: "victory" });
|
|
4006
|
+
}
|
|
4007
|
+
}, [entityUnits, gameEndEvent, eventBus]);
|
|
4008
|
+
const handleUnitClickCallback = useCallback((isoUnit) => {
|
|
4009
|
+
if (phase !== "action" || !selectedUnitId || !attackEvent) return;
|
|
4010
|
+
const attackerRow = entityUnits.find((u) => str(u.id) === selectedUnitId);
|
|
4011
|
+
const targetRow = entityUnits.find((u) => str(u.id) === isoUnit.id);
|
|
4012
|
+
if (!attackerRow || !targetRow) return;
|
|
4013
|
+
if (unitTeam(targetRow) !== "enemy" || unitHealth(targetRow) <= 0) return;
|
|
4014
|
+
const ap = unitPosition(attackerRow);
|
|
4015
|
+
const tp = unitPosition(targetRow);
|
|
4016
|
+
const dx = Math.abs(ap.x - tp.x);
|
|
4017
|
+
const dy = Math.abs(ap.y - tp.y);
|
|
4018
|
+
if (dx <= 1 && dy <= 1 && dx + dy > 0) {
|
|
4019
|
+
const damage = Math.max(1, num(attackerRow.attack) - num(targetRow.defense));
|
|
4020
|
+
eventBus.emit(`UI:${attackEvent}`, {
|
|
4021
|
+
attackerId: str(attackerRow.id),
|
|
4022
|
+
targetId: str(targetRow.id),
|
|
4023
|
+
damage
|
|
4024
|
+
});
|
|
4025
|
+
setTimeout(checkGameEnd, 100);
|
|
4026
|
+
}
|
|
4027
|
+
}, [phase, selectedUnitId, entityUnits, attackEvent, eventBus, checkGameEnd]);
|
|
4028
|
+
const handleEndTurn = useCallback(() => {
|
|
4029
|
+
if (endTurnEvent) eventBus.emit(`UI:${endTurnEvent}`, {});
|
|
4030
|
+
}, [endTurnEvent, eventBus]);
|
|
4031
|
+
const handleCancel = useCallback(() => {
|
|
4032
|
+
if (cancelEvent) eventBus.emit(`UI:${cancelEvent}`, {});
|
|
4033
|
+
}, [cancelEvent, eventBus]);
|
|
4034
|
+
const handlePlayAgain = useCallback(() => {
|
|
4035
|
+
if (playAgainEvent) eventBus.emit(`UI:${playAgainEvent}`, {});
|
|
4036
|
+
}, [playAgainEvent, eventBus]);
|
|
4037
|
+
return /* @__PURE__ */ jsxs(VStack, { className: cn("game-board-3d block w-full min-h-[85vh] relative", className), children: [
|
|
4038
|
+
/* @__PURE__ */ jsxs("div", { className: "game-board-3d__status absolute top-3 left-3 z-10 flex gap-2 items-center", children: [
|
|
4039
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", className: "status__phase capitalize", children: phase.replace("_", " ") }),
|
|
4040
|
+
currentTeam && !isGameOver && /* @__PURE__ */ jsxs(Typography, { variant: "small", color: "muted", className: "status__team", children: [
|
|
4041
|
+
"\u2014 ",
|
|
4042
|
+
currentTeam === "player" ? "Your Turn" : "Enemy's Turn"
|
|
4043
|
+
] }),
|
|
4044
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "small", color: "muted", className: "status__turn", children: [
|
|
4045
|
+
"Turn ",
|
|
4046
|
+
turn
|
|
4047
|
+
] })
|
|
4048
|
+
] }),
|
|
4049
|
+
/* @__PURE__ */ jsx(
|
|
4050
|
+
GameCanvas3D,
|
|
4051
|
+
{
|
|
4052
|
+
tiles,
|
|
4053
|
+
units,
|
|
4054
|
+
features,
|
|
4055
|
+
cameraMode,
|
|
4056
|
+
showGrid: true,
|
|
4057
|
+
showCoordinates: false,
|
|
4058
|
+
showTileInfo: false,
|
|
4059
|
+
shadows: true,
|
|
4060
|
+
backgroundColor,
|
|
4061
|
+
tileClickEvent,
|
|
4062
|
+
unitClickEvent,
|
|
4063
|
+
onUnitClick: handleUnitClickCallback,
|
|
4064
|
+
selectedUnitId,
|
|
4065
|
+
validMoves,
|
|
4066
|
+
attackTargets,
|
|
4067
|
+
className: "game-board-3d__canvas w-full min-h-[85vh]"
|
|
4068
|
+
}
|
|
4069
|
+
),
|
|
4070
|
+
!isGameOver && /* @__PURE__ */ jsxs(HStack, { className: "fixed bottom-6 right-6 z-50", gap: "sm", children: [
|
|
4071
|
+
(phase === "selection" || phase === "movement" || phase === "action") && /* @__PURE__ */ jsx(
|
|
4072
|
+
Button,
|
|
4073
|
+
{
|
|
4074
|
+
variant: "secondary",
|
|
4075
|
+
className: "shadow-xl",
|
|
4076
|
+
onClick: handleCancel,
|
|
4077
|
+
children: "Cancel"
|
|
4078
|
+
}
|
|
4079
|
+
),
|
|
4080
|
+
phase !== "enemy_turn" && /* @__PURE__ */ jsx(
|
|
4081
|
+
Button,
|
|
4082
|
+
{
|
|
4083
|
+
variant: "primary",
|
|
4084
|
+
className: "shadow-xl",
|
|
4085
|
+
onClick: handleEndTurn,
|
|
4086
|
+
children: "End Turn"
|
|
4087
|
+
}
|
|
4088
|
+
)
|
|
4089
|
+
] }),
|
|
4090
|
+
isGameOver && /* @__PURE__ */ jsx("div", { className: "game-board-3d__overlay absolute inset-0 z-20 flex items-center justify-center bg-black/60", children: /* @__PURE__ */ jsxs(VStack, { align: "center", gap: "md", className: "overlay__card p-8 rounded-xl bg-gray-900/90 shadow-2xl", children: [
|
|
4091
|
+
/* @__PURE__ */ jsx(
|
|
4092
|
+
Typography,
|
|
4093
|
+
{
|
|
4094
|
+
variant: "h2",
|
|
4095
|
+
className: cn(
|
|
4096
|
+
"overlay__result",
|
|
4097
|
+
result === "victory" ? "text-yellow-400" : "text-red-500"
|
|
4098
|
+
),
|
|
4099
|
+
children: result === "victory" ? "Victory!" : "Defeat"
|
|
4100
|
+
}
|
|
4101
|
+
),
|
|
4102
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "body", color: "muted", className: "overlay__turn-count", children: [
|
|
4103
|
+
"Completed in ",
|
|
4104
|
+
turn,
|
|
4105
|
+
" turn",
|
|
4106
|
+
turn !== 1 ? "s" : ""
|
|
4107
|
+
] }),
|
|
4108
|
+
/* @__PURE__ */ jsx(
|
|
4109
|
+
Button,
|
|
4110
|
+
{
|
|
4111
|
+
variant: "primary",
|
|
4112
|
+
className: "px-8 py-3 font-semibold",
|
|
4113
|
+
onClick: handlePlayAgain,
|
|
4114
|
+
children: "Play Again"
|
|
4115
|
+
}
|
|
4116
|
+
)
|
|
4117
|
+
] }) })
|
|
4118
|
+
] });
|
|
4119
|
+
}
|
|
4120
|
+
GameBoard3D.displayName = "GameBoard3D";
|
|
4121
|
+
var paddingStyles = {
|
|
4122
|
+
none: "p-0",
|
|
4123
|
+
xs: "p-1",
|
|
4124
|
+
sm: "p-2",
|
|
4125
|
+
md: "p-4",
|
|
4126
|
+
lg: "p-6",
|
|
4127
|
+
xl: "p-8",
|
|
4128
|
+
"2xl": "p-12"
|
|
4129
|
+
};
|
|
4130
|
+
var paddingXStyles = {
|
|
4131
|
+
none: "px-0",
|
|
4132
|
+
xs: "px-1",
|
|
4133
|
+
sm: "px-2",
|
|
4134
|
+
md: "px-4",
|
|
4135
|
+
lg: "px-6",
|
|
4136
|
+
xl: "px-8",
|
|
4137
|
+
"2xl": "px-12"
|
|
4138
|
+
};
|
|
4139
|
+
var paddingYStyles = {
|
|
4140
|
+
none: "py-0",
|
|
4141
|
+
xs: "py-1",
|
|
4142
|
+
sm: "py-2",
|
|
4143
|
+
md: "py-4",
|
|
4144
|
+
lg: "py-6",
|
|
4145
|
+
xl: "py-8",
|
|
4146
|
+
"2xl": "py-12"
|
|
4147
|
+
};
|
|
4148
|
+
var marginStyles = {
|
|
4149
|
+
none: "m-0",
|
|
4150
|
+
xs: "m-1",
|
|
4151
|
+
sm: "m-2",
|
|
4152
|
+
md: "m-4",
|
|
4153
|
+
lg: "m-6",
|
|
4154
|
+
xl: "m-8",
|
|
4155
|
+
"2xl": "m-12",
|
|
4156
|
+
auto: "m-auto"
|
|
4157
|
+
};
|
|
4158
|
+
var marginXStyles = {
|
|
4159
|
+
none: "mx-0",
|
|
4160
|
+
xs: "mx-1",
|
|
4161
|
+
sm: "mx-2",
|
|
4162
|
+
md: "mx-4",
|
|
4163
|
+
lg: "mx-6",
|
|
4164
|
+
xl: "mx-8",
|
|
4165
|
+
"2xl": "mx-12",
|
|
4166
|
+
auto: "mx-auto"
|
|
4167
|
+
};
|
|
4168
|
+
var marginYStyles = {
|
|
4169
|
+
none: "my-0",
|
|
4170
|
+
xs: "my-1",
|
|
4171
|
+
sm: "my-2",
|
|
4172
|
+
md: "my-4",
|
|
4173
|
+
lg: "my-6",
|
|
4174
|
+
xl: "my-8",
|
|
4175
|
+
"2xl": "my-12",
|
|
4176
|
+
auto: "my-auto"
|
|
4177
|
+
};
|
|
4178
|
+
var bgStyles = {
|
|
4179
|
+
transparent: "bg-transparent",
|
|
4180
|
+
primary: "bg-primary text-primary-foreground",
|
|
4181
|
+
secondary: "bg-secondary text-secondary-foreground",
|
|
4182
|
+
muted: "bg-muted text-foreground",
|
|
4183
|
+
accent: "bg-accent text-accent-foreground",
|
|
4184
|
+
surface: "bg-card",
|
|
4185
|
+
overlay: "bg-card/80 backdrop-blur-sm"
|
|
4186
|
+
};
|
|
4187
|
+
var roundedStyles = {
|
|
4188
|
+
none: "rounded-none",
|
|
4189
|
+
sm: "rounded-sm",
|
|
4190
|
+
md: "rounded-md",
|
|
4191
|
+
lg: "rounded-lg",
|
|
4192
|
+
xl: "rounded-xl",
|
|
4193
|
+
"2xl": "rounded-xl",
|
|
4194
|
+
full: "rounded-full"
|
|
4195
|
+
};
|
|
4196
|
+
var shadowStyles = {
|
|
4197
|
+
none: "shadow-none",
|
|
4198
|
+
sm: "shadow-sm",
|
|
4199
|
+
md: "shadow",
|
|
4200
|
+
lg: "shadow-lg",
|
|
4201
|
+
xl: "shadow-lg"
|
|
4202
|
+
};
|
|
4203
|
+
var displayStyles = {
|
|
4204
|
+
block: "block",
|
|
4205
|
+
inline: "inline",
|
|
4206
|
+
"inline-block": "inline-block",
|
|
4207
|
+
flex: "flex",
|
|
4208
|
+
"inline-flex": "inline-flex",
|
|
4209
|
+
grid: "grid"
|
|
4210
|
+
};
|
|
4211
|
+
var overflowStyles2 = {
|
|
4212
|
+
auto: "overflow-auto",
|
|
4213
|
+
hidden: "overflow-hidden",
|
|
4214
|
+
visible: "overflow-visible",
|
|
4215
|
+
scroll: "overflow-scroll"
|
|
4216
|
+
};
|
|
4217
|
+
var positionStyles = {
|
|
4218
|
+
relative: "relative",
|
|
4219
|
+
absolute: "absolute",
|
|
4220
|
+
fixed: "fixed",
|
|
4221
|
+
sticky: "sticky"
|
|
4222
|
+
};
|
|
4223
|
+
var Box = React11.forwardRef(
|
|
4224
|
+
({
|
|
4225
|
+
padding,
|
|
4226
|
+
paddingX,
|
|
4227
|
+
paddingY,
|
|
4228
|
+
margin,
|
|
4229
|
+
marginX,
|
|
4230
|
+
marginY,
|
|
4231
|
+
bg = "transparent",
|
|
4232
|
+
border = false,
|
|
4233
|
+
rounded = "none",
|
|
4234
|
+
shadow = "none",
|
|
4235
|
+
display,
|
|
4236
|
+
fullWidth = false,
|
|
4237
|
+
fullHeight = false,
|
|
4238
|
+
overflow,
|
|
4239
|
+
position,
|
|
4240
|
+
className,
|
|
4241
|
+
children,
|
|
4242
|
+
as: Component2 = "div",
|
|
4243
|
+
action,
|
|
4244
|
+
actionPayload,
|
|
4245
|
+
hoverEvent,
|
|
4246
|
+
maxWidth,
|
|
4247
|
+
onClick,
|
|
4248
|
+
onMouseEnter,
|
|
4249
|
+
onMouseLeave,
|
|
4250
|
+
...rest
|
|
4251
|
+
}, ref) => {
|
|
4252
|
+
const eventBus = useEventBus();
|
|
4253
|
+
const handleClick = useCallback((e) => {
|
|
4254
|
+
if (action) {
|
|
4255
|
+
e.stopPropagation();
|
|
4256
|
+
eventBus.emit(`UI:${action}`, actionPayload ?? {});
|
|
4257
|
+
}
|
|
4258
|
+
onClick?.(e);
|
|
4259
|
+
}, [action, actionPayload, eventBus, onClick]);
|
|
4260
|
+
const handleMouseEnter = useCallback((e) => {
|
|
4261
|
+
if (hoverEvent) {
|
|
4262
|
+
eventBus.emit(`UI:${hoverEvent}`, { hovered: true });
|
|
4263
|
+
}
|
|
4264
|
+
onMouseEnter?.(e);
|
|
4265
|
+
}, [hoverEvent, eventBus, onMouseEnter]);
|
|
4266
|
+
const handleMouseLeave = useCallback((e) => {
|
|
4267
|
+
if (hoverEvent) {
|
|
4268
|
+
eventBus.emit(`UI:${hoverEvent}`, { hovered: false });
|
|
4269
|
+
}
|
|
4270
|
+
onMouseLeave?.(e);
|
|
4271
|
+
}, [hoverEvent, eventBus, onMouseLeave]);
|
|
4272
|
+
const isClickable = action || onClick;
|
|
4273
|
+
return React11.createElement(
|
|
4274
|
+
Component2,
|
|
4275
|
+
{
|
|
4276
|
+
ref,
|
|
4277
|
+
className: cn(
|
|
4278
|
+
padding && paddingStyles[padding],
|
|
4279
|
+
paddingX && paddingXStyles[paddingX],
|
|
4280
|
+
paddingY && paddingYStyles[paddingY],
|
|
4281
|
+
margin && marginStyles[margin],
|
|
4282
|
+
marginX && marginXStyles[marginX],
|
|
4283
|
+
marginY && marginYStyles[marginY],
|
|
4284
|
+
bgStyles[bg],
|
|
4285
|
+
border && "border-[length:var(--border-width)] border-border",
|
|
4286
|
+
roundedStyles[rounded],
|
|
4287
|
+
shadowStyles[shadow],
|
|
4288
|
+
display && displayStyles[display],
|
|
4289
|
+
fullWidth && "w-full",
|
|
4290
|
+
fullHeight && "h-full",
|
|
4291
|
+
overflow && overflowStyles2[overflow],
|
|
4292
|
+
position && positionStyles[position],
|
|
4293
|
+
isClickable && "cursor-pointer",
|
|
4294
|
+
className
|
|
4295
|
+
),
|
|
4296
|
+
onClick: isClickable ? handleClick : void 0,
|
|
4297
|
+
onMouseEnter: hoverEvent || onMouseEnter ? handleMouseEnter : void 0,
|
|
4298
|
+
onMouseLeave: hoverEvent || onMouseLeave ? handleMouseLeave : void 0,
|
|
4299
|
+
style: maxWidth ? { maxWidth, ...rest.style } : rest.style,
|
|
4300
|
+
...rest
|
|
4301
|
+
},
|
|
4302
|
+
children
|
|
4303
|
+
);
|
|
4304
|
+
}
|
|
4305
|
+
);
|
|
4306
|
+
Box.displayName = "Box";
|
|
3186
4307
|
var DEFAULT_3D_BATTLE_TILES = [
|
|
3187
4308
|
{ id: "t00", x: 0, y: 0, z: 0, type: "stone", passable: false },
|
|
3188
4309
|
{ id: "t10", x: 1, y: 0, z: 0, type: "stone", passable: false },
|
|
@@ -3210,10 +4331,6 @@ var DEFAULT_3D_BATTLE_TILES = [
|
|
|
3210
4331
|
{ id: "t34", x: 3, y: 4, z: 4, type: "stone", passable: false },
|
|
3211
4332
|
{ id: "t44", x: 4, y: 4, z: 4, type: "stone", passable: false }
|
|
3212
4333
|
];
|
|
3213
|
-
var DEFAULT_3D_BATTLE_UNITS = [
|
|
3214
|
-
{ id: "u1", x: 1, y: 1, z: 1, unitType: "warrior", name: "Worker", faction: "player", health: 10, maxHealth: 10 },
|
|
3215
|
-
{ id: "u2", x: 3, y: 3, z: 3, unitType: "enemy", name: "Guardian", faction: "enemy", health: 8, maxHealth: 10 }
|
|
3216
|
-
];
|
|
3217
4334
|
var DEFAULT_3D_BATTLE_FEATURES = [
|
|
3218
4335
|
{ id: "f1", x: 2, y: 2, z: 2, type: "gold_mine", color: "#f4c542" },
|
|
3219
4336
|
{ id: "f2", x: 3, y: 1, z: 1, type: "portal", color: "#8b5cf6" }
|
|
@@ -3221,53 +4338,44 @@ var DEFAULT_3D_BATTLE_FEATURES = [
|
|
|
3221
4338
|
function GameCanvas3DBattleTemplate({
|
|
3222
4339
|
entity,
|
|
3223
4340
|
tiles: propTiles = DEFAULT_3D_BATTLE_TILES,
|
|
3224
|
-
units: propUnits = DEFAULT_3D_BATTLE_UNITS,
|
|
3225
4341
|
features: propFeatures = DEFAULT_3D_BATTLE_FEATURES,
|
|
3226
4342
|
cameraMode = "perspective",
|
|
3227
|
-
showGrid = true,
|
|
3228
|
-
shadows = true,
|
|
3229
4343
|
backgroundColor = "#2a1a1a",
|
|
3230
4344
|
tileClickEvent,
|
|
3231
4345
|
unitClickEvent,
|
|
3232
|
-
unitAttackEvent,
|
|
3233
|
-
unitMoveEvent,
|
|
3234
4346
|
endTurnEvent,
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
4347
|
+
cancelEvent,
|
|
4348
|
+
attackEvent,
|
|
4349
|
+
playAgainEvent,
|
|
4350
|
+
gameEndEvent,
|
|
3239
4351
|
className
|
|
3240
4352
|
}) {
|
|
3241
4353
|
const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
|
|
3242
4354
|
const tiles = resolved ? Array.isArray(resolved.tiles) ? resolved.tiles : [] : propTiles;
|
|
3243
|
-
const units = resolved ? Array.isArray(resolved.units) ? resolved.units : [] : propUnits;
|
|
3244
4355
|
const features = resolved ? Array.isArray(resolved.features) ? resolved.features : [] : propFeatures;
|
|
3245
|
-
const currentTurn = resolved?.
|
|
3246
|
-
const round = resolved?.
|
|
4356
|
+
const currentTurn = resolved?.currentTeam;
|
|
4357
|
+
const round = resolved?.turn == null ? void 0 : Number(resolved.turn);
|
|
3247
4358
|
return /* @__PURE__ */ jsxs(
|
|
3248
4359
|
Box,
|
|
3249
4360
|
{
|
|
3250
|
-
className: cn("game-canvas-3d-battle-template", className),
|
|
3251
|
-
style: { display: "block", position: "relative", width: "100%", minHeight: "85vh" },
|
|
4361
|
+
className: cn("game-canvas-3d-battle-template block relative w-full min-h-[85vh]", className),
|
|
3252
4362
|
children: [
|
|
3253
4363
|
/* @__PURE__ */ jsx(
|
|
3254
|
-
|
|
4364
|
+
GameBoard3D,
|
|
3255
4365
|
{
|
|
4366
|
+
entity,
|
|
3256
4367
|
tiles,
|
|
3257
|
-
units,
|
|
3258
4368
|
features,
|
|
3259
4369
|
cameraMode,
|
|
3260
|
-
showGrid,
|
|
3261
|
-
showCoordinates: false,
|
|
3262
|
-
showTileInfo: false,
|
|
3263
|
-
shadows,
|
|
3264
4370
|
backgroundColor,
|
|
3265
4371
|
tileClickEvent,
|
|
3266
4372
|
unitClickEvent,
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
4373
|
+
endTurnEvent,
|
|
4374
|
+
cancelEvent,
|
|
4375
|
+
attackEvent,
|
|
4376
|
+
playAgainEvent,
|
|
4377
|
+
gameEndEvent,
|
|
4378
|
+
className: "game-canvas-3d-battle-template__board"
|
|
3271
4379
|
}
|
|
3272
4380
|
),
|
|
3273
4381
|
currentTurn && /* @__PURE__ */ jsxs(
|
|
@@ -3275,8 +4383,7 @@ function GameCanvas3DBattleTemplate({
|
|
|
3275
4383
|
{
|
|
3276
4384
|
gap: "sm",
|
|
3277
4385
|
align: "center",
|
|
3278
|
-
className: cn("battle-template__turn-indicator", `battle-template__turn-indicator--${currentTurn}`),
|
|
3279
|
-
style: { position: "absolute", top: "12px", right: "12px", zIndex: 10 },
|
|
4386
|
+
className: cn("battle-template__turn-indicator absolute top-3 right-3 z-10", `battle-template__turn-indicator--${currentTurn}`),
|
|
3280
4387
|
children: [
|
|
3281
4388
|
/* @__PURE__ */ jsx(Typography, { variant: "body", className: "turn-indicator__label", children: currentTurn === "player" ? "Your Turn" : "Enemy's Turn" }),
|
|
3282
4389
|
round != null && /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "turn-indicator__round", children: [
|
|
@@ -3318,10 +4425,6 @@ var DEFAULT_3D_CASTLE_TILES = [
|
|
|
3318
4425
|
{ id: "t34", x: 3, y: 4, z: 4, type: "wall", passable: false },
|
|
3319
4426
|
{ id: "t44", x: 4, y: 4, z: 4, type: "wall", passable: false }
|
|
3320
4427
|
];
|
|
3321
|
-
var DEFAULT_3D_CASTLE_UNITS = [
|
|
3322
|
-
{ id: "u1", x: 1, y: 1, z: 1, unitType: "worker", name: "Worker", faction: "player", health: 10, maxHealth: 10 },
|
|
3323
|
-
{ id: "u2", x: 3, y: 3, z: 3, unitType: "guardian", name: "Guardian", faction: "player", health: 10, maxHealth: 10 }
|
|
3324
|
-
];
|
|
3325
4428
|
var DEFAULT_3D_CASTLE_FEATURES = [
|
|
3326
4429
|
{ id: "f1", x: 2, y: 2, z: 2, type: "chest", color: "#f4c542" },
|
|
3327
4430
|
{ id: "f2", x: 3, y: 1, z: 1, type: "crystal", color: "#8b5cf6" }
|
|
@@ -3329,35 +4432,30 @@ var DEFAULT_3D_CASTLE_FEATURES = [
|
|
|
3329
4432
|
function GameCanvas3DCastleTemplate({
|
|
3330
4433
|
entity,
|
|
3331
4434
|
tiles: propTiles = DEFAULT_3D_CASTLE_TILES,
|
|
3332
|
-
units: propUnits = DEFAULT_3D_CASTLE_UNITS,
|
|
3333
4435
|
features: propFeatures = DEFAULT_3D_CASTLE_FEATURES,
|
|
3334
4436
|
cameraMode = "isometric",
|
|
3335
|
-
showGrid = true,
|
|
3336
|
-
shadows = true,
|
|
3337
4437
|
backgroundColor = "#1e1e2e",
|
|
3338
4438
|
buildingClickEvent,
|
|
3339
4439
|
unitClickEvent,
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
availableBuildSites,
|
|
4440
|
+
endTurnEvent,
|
|
4441
|
+
cancelEvent,
|
|
4442
|
+
attackEvent,
|
|
4443
|
+
playAgainEvent,
|
|
4444
|
+
gameEndEvent,
|
|
3346
4445
|
showHeader = true,
|
|
3347
4446
|
className
|
|
3348
4447
|
}) {
|
|
3349
4448
|
const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
|
|
3350
4449
|
const tiles = resolved ? Array.isArray(resolved.tiles) ? resolved.tiles : [] : propTiles;
|
|
3351
|
-
const units = resolved ? Array.isArray(resolved.units) ? resolved.units : [] : propUnits;
|
|
3352
4450
|
const features = resolved ? Array.isArray(resolved.features) ? resolved.features : [] : propFeatures;
|
|
3353
4451
|
const name = resolved?.name == null ? void 0 : String(resolved.name);
|
|
3354
4452
|
const level = resolved?.level == null ? void 0 : Number(resolved.level);
|
|
3355
4453
|
const owner = resolved?.owner == null ? void 0 : String(resolved.owner);
|
|
4454
|
+
const unitCount = resolved && Array.isArray(resolved.units) ? resolved.units.length : 0;
|
|
3356
4455
|
return /* @__PURE__ */ jsxs(
|
|
3357
4456
|
VStack,
|
|
3358
4457
|
{
|
|
3359
|
-
className: cn("game-canvas-3d-castle-template", className),
|
|
3360
|
-
style: { display: "block", width: "100%", minHeight: "85vh" },
|
|
4458
|
+
className: cn("game-canvas-3d-castle-template block w-full min-h-[85vh]", className),
|
|
3361
4459
|
children: [
|
|
3362
4460
|
showHeader && name && /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "center", className: "castle-template__header", children: [
|
|
3363
4461
|
/* @__PURE__ */ jsx(Typography, { variant: "h2", className: "header__name", children: name }),
|
|
@@ -3368,28 +4466,27 @@ function GameCanvas3DCastleTemplate({
|
|
|
3368
4466
|
owner && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", className: "header__owner", children: owner })
|
|
3369
4467
|
] }),
|
|
3370
4468
|
/* @__PURE__ */ jsx(
|
|
3371
|
-
|
|
4469
|
+
GameBoard3D,
|
|
3372
4470
|
{
|
|
4471
|
+
entity,
|
|
3373
4472
|
tiles,
|
|
3374
|
-
units,
|
|
3375
4473
|
features,
|
|
3376
4474
|
cameraMode,
|
|
3377
|
-
showGrid,
|
|
3378
|
-
showCoordinates: false,
|
|
3379
|
-
showTileInfo: false,
|
|
3380
|
-
shadows,
|
|
3381
4475
|
backgroundColor,
|
|
3382
|
-
|
|
4476
|
+
tileClickEvent: buildingClickEvent,
|
|
3383
4477
|
unitClickEvent,
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
4478
|
+
endTurnEvent,
|
|
4479
|
+
cancelEvent,
|
|
4480
|
+
attackEvent,
|
|
4481
|
+
playAgainEvent,
|
|
4482
|
+
gameEndEvent,
|
|
4483
|
+
className: "game-canvas-3d-castle-template__board"
|
|
3387
4484
|
}
|
|
3388
4485
|
),
|
|
3389
|
-
|
|
4486
|
+
unitCount > 0 && /* @__PURE__ */ jsxs(HStack, { gap: "sm", align: "center", className: "castle-template__garrison-info", children: [
|
|
3390
4487
|
/* @__PURE__ */ jsx(Typography, { variant: "small", className: "garrison-info__label", children: "Garrison:" }),
|
|
3391
4488
|
/* @__PURE__ */ jsxs(Typography, { variant: "small", weight: "bold", className: "garrison-info__count", children: [
|
|
3392
|
-
|
|
4489
|
+
unitCount,
|
|
3393
4490
|
" units"
|
|
3394
4491
|
] })
|
|
3395
4492
|
] })
|
|
@@ -3425,10 +4522,6 @@ var DEFAULT_3D_WORLDMAP_TILES = [
|
|
|
3425
4522
|
{ id: "t34", x: 3, y: 4, z: 4, type: "mountain", passable: false },
|
|
3426
4523
|
{ id: "t44", x: 4, y: 4, z: 4, type: "mountain", passable: false }
|
|
3427
4524
|
];
|
|
3428
|
-
var DEFAULT_3D_WORLDMAP_UNITS = [
|
|
3429
|
-
{ id: "h1", x: 1, y: 1, z: 1, unitType: "hero", name: "Amir", faction: "player", health: 10, maxHealth: 10 },
|
|
3430
|
-
{ id: "h2", x: 3, y: 3, z: 3, unitType: "scout", name: "Archivist", faction: "player", health: 10, maxHealth: 10 }
|
|
3431
|
-
];
|
|
3432
4525
|
var DEFAULT_3D_WORLDMAP_FEATURES = [
|
|
3433
4526
|
{ id: "f1", x: 2, y: 2, z: 2, type: "capital", color: "#f4c542" },
|
|
3434
4527
|
{ id: "f2", x: 4, y: 2, z: 2, type: "power_node", color: "#8b5cf6" }
|
|
@@ -3436,52 +4529,41 @@ var DEFAULT_3D_WORLDMAP_FEATURES = [
|
|
|
3436
4529
|
function GameCanvas3DWorldMapTemplate({
|
|
3437
4530
|
entity,
|
|
3438
4531
|
tiles: propTiles = DEFAULT_3D_WORLDMAP_TILES,
|
|
3439
|
-
units: propUnits = DEFAULT_3D_WORLDMAP_UNITS,
|
|
3440
4532
|
features: propFeatures = DEFAULT_3D_WORLDMAP_FEATURES,
|
|
3441
4533
|
cameraMode = "isometric",
|
|
3442
|
-
showGrid = true,
|
|
3443
|
-
showCoordinates = true,
|
|
3444
|
-
showTileInfo = true,
|
|
3445
|
-
shadows = true,
|
|
3446
4534
|
backgroundColor = "#1a1a2e",
|
|
3447
4535
|
tileClickEvent,
|
|
3448
4536
|
unitClickEvent,
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
validMoves,
|
|
3455
|
-
attackTargets,
|
|
4537
|
+
endTurnEvent,
|
|
4538
|
+
cancelEvent,
|
|
4539
|
+
attackEvent,
|
|
4540
|
+
playAgainEvent,
|
|
4541
|
+
gameEndEvent,
|
|
3456
4542
|
className
|
|
3457
4543
|
}) {
|
|
3458
4544
|
const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
|
|
3459
4545
|
const tiles = resolved ? Array.isArray(resolved.tiles) ? resolved.tiles : [] : propTiles;
|
|
3460
|
-
const units = resolved ? Array.isArray(resolved.units) ? resolved.units : [] : propUnits;
|
|
3461
4546
|
const features = resolved ? Array.isArray(resolved.features) ? resolved.features : [] : propFeatures;
|
|
3462
|
-
return
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
attackTargets,
|
|
3483
|
-
className
|
|
3484
|
-
}
|
|
4547
|
+
return (
|
|
4548
|
+
/* GameBoard3D reads selectedUnitId/validMoves/attackTargets from entity */
|
|
4549
|
+
/* @__PURE__ */ jsx(
|
|
4550
|
+
GameBoard3D,
|
|
4551
|
+
{
|
|
4552
|
+
entity,
|
|
4553
|
+
tiles,
|
|
4554
|
+
features,
|
|
4555
|
+
cameraMode,
|
|
4556
|
+
backgroundColor,
|
|
4557
|
+
tileClickEvent,
|
|
4558
|
+
unitClickEvent,
|
|
4559
|
+
endTurnEvent,
|
|
4560
|
+
cancelEvent,
|
|
4561
|
+
attackEvent,
|
|
4562
|
+
playAgainEvent,
|
|
4563
|
+
gameEndEvent,
|
|
4564
|
+
className
|
|
4565
|
+
}
|
|
4566
|
+
)
|
|
3485
4567
|
);
|
|
3486
4568
|
}
|
|
3487
4569
|
GameCanvas3DWorldMapTemplate.displayName = "GameCanvas3DWorldMapTemplate";
|
|
@@ -3673,10 +4755,10 @@ function parseApplicationLevel(schema) {
|
|
|
3673
4755
|
}
|
|
3674
4756
|
const count = schema.orbitals.length;
|
|
3675
4757
|
const cols = Math.ceil(Math.sqrt(count));
|
|
3676
|
-
const
|
|
4758
|
+
const rows2 = Math.ceil(count / cols);
|
|
3677
4759
|
const spacing = 200;
|
|
3678
4760
|
const gridW = cols * spacing;
|
|
3679
|
-
const gridH =
|
|
4761
|
+
const gridH = rows2 * spacing;
|
|
3680
4762
|
const originX = (600 - gridW) / 2 + spacing / 2;
|
|
3681
4763
|
const originY = (400 - gridH) / 2 + spacing / 2;
|
|
3682
4764
|
schema.orbitals.forEach((orbital, i) => {
|
|
@@ -4208,7 +5290,7 @@ Avl3DLabel.displayName = "Avl3DLabel";
|
|
|
4208
5290
|
var Avl3DTooltip = ({
|
|
4209
5291
|
position,
|
|
4210
5292
|
title,
|
|
4211
|
-
rows,
|
|
5293
|
+
rows: rows2,
|
|
4212
5294
|
accentColor = "#5b9bd5"
|
|
4213
5295
|
}) => {
|
|
4214
5296
|
return /* @__PURE__ */ jsx(
|
|
@@ -4246,7 +5328,7 @@ var Avl3DTooltip = ({
|
|
|
4246
5328
|
children: title
|
|
4247
5329
|
}
|
|
4248
5330
|
),
|
|
4249
|
-
|
|
5331
|
+
rows2.map((row) => /* @__PURE__ */ jsxs(
|
|
4250
5332
|
Box,
|
|
4251
5333
|
{
|
|
4252
5334
|
style: {
|