@almadar/ui 5.46.0 → 5.48.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.
@@ -1,4 +1,7 @@
1
+ import type { AssetUrl } from '@almadar/core';
1
2
  export interface ComboCounterProps {
3
+ /** Sprite image URL displayed alongside the combo number */
4
+ assetUrl?: AssetUrl;
2
5
  /** Current combo count */
3
6
  combo: number;
4
7
  /** Score multiplier */
@@ -10,7 +13,7 @@ export interface ComboCounterProps {
10
13
  /** Additional CSS classes */
11
14
  className?: string;
12
15
  }
13
- export declare function ComboCounter({ combo, multiplier, streak, size, className, }: ComboCounterProps): import("react/jsx-runtime").JSX.Element | null;
16
+ export declare function ComboCounter({ assetUrl, combo, multiplier, streak, size, className, }: ComboCounterProps): import("react/jsx-runtime").JSX.Element | null;
14
17
  export declare namespace ComboCounter {
15
18
  var displayName: string;
16
19
  }
@@ -1,6 +1,9 @@
1
1
  import type { ColorToken } from '../../core/atoms/types';
2
2
  import { type IconInput } from '../../core/atoms/Icon';
3
+ import type { AssetUrl } from '@almadar/core';
3
4
  export interface ResourceCounterProps {
5
+ /** Sprite image URL — takes precedence over icon when provided */
6
+ assetUrl?: AssetUrl;
4
7
  /** Icon component or emoji */
5
8
  icon?: IconInput;
6
9
  /** Resource label */
@@ -16,7 +19,7 @@ export interface ResourceCounterProps {
16
19
  /** Additional CSS classes */
17
20
  className?: string;
18
21
  }
19
- export declare function ResourceCounter({ icon, label, value, max, color, size, className, }: ResourceCounterProps): import("react/jsx-runtime").JSX.Element;
22
+ export declare function ResourceCounter({ assetUrl, icon, label, value, max, color, size, className, }: ResourceCounterProps): import("react/jsx-runtime").JSX.Element;
20
23
  export declare namespace ResourceCounter {
21
24
  var displayName: string;
22
25
  }
@@ -1,16 +1,13 @@
1
- /**
2
- * StateIndicator — animated game-entity state pill (distinct from core Badge atom).
3
- * Badge is a static text label. StateIndicator maps a state string (idle/active/
4
- * moving/…) to icon + bg colour + optional pulse via a style registry that callers
5
- * can extend. Use it in game HUDs where the entity state machine drives the display.
6
- */
7
1
  import React from 'react';
8
2
  import { type IconInput } from '../../core/atoms/Icon';
3
+ import type { AssetUrl } from '@almadar/core';
9
4
  export interface StateStyle {
10
5
  icon: IconInput;
11
6
  bgClass: string;
12
7
  }
13
8
  export interface StateIndicatorProps {
9
+ /** Sprite image URL — takes precedence over the state icon when provided */
10
+ assetUrl?: AssetUrl;
14
11
  /** The current state name */
15
12
  state: string;
16
13
  /** Optional label override (defaults to capitalized state name) */
@@ -24,7 +21,7 @@ export interface StateIndicatorProps {
24
21
  /** Additional CSS classes */
25
22
  className?: string;
26
23
  }
27
- export declare function StateIndicator({ state, label, size, animated, stateStyles, className, }: StateIndicatorProps): React.JSX.Element;
24
+ export declare function StateIndicator({ assetUrl, state, label, size, animated, stateStyles, className, }: StateIndicatorProps): React.JSX.Element;
28
25
  export declare namespace StateIndicator {
29
26
  var displayName: string;
30
27
  }
@@ -1,5 +1,8 @@
1
1
  import { type IconInput } from '../../core/atoms/Icon';
2
+ import type { AssetUrl } from '@almadar/core';
2
3
  export interface StatusEffectProps {
4
+ /** Sprite image URL — takes precedence over icon when provided */
5
+ assetUrl?: AssetUrl;
3
6
  /** Lucide icon name or component */
4
7
  icon: IconInput;
5
8
  /** Label describing the effect */
@@ -15,7 +18,7 @@ export interface StatusEffectProps {
15
18
  /** Additional CSS classes */
16
19
  className?: string;
17
20
  }
18
- export declare function StatusEffect({ icon, label, duration, stacks, variant, size, className, }: StatusEffectProps): import("react/jsx-runtime").JSX.Element;
21
+ export declare function StatusEffect({ assetUrl, icon, label, duration, stacks, variant, size, className, }: StatusEffectProps): import("react/jsx-runtime").JSX.Element;
19
22
  export declare namespace StatusEffect {
20
23
  var displayName: string;
21
24
  }
@@ -1,5 +1,8 @@
1
1
  import { type IconInput } from '../../core/atoms/Icon';
2
+ import type { AssetUrl } from '@almadar/core';
2
3
  export interface WaypointMarkerProps {
4
+ /** Sprite image URL — takes precedence over icon when provided */
5
+ assetUrl?: AssetUrl;
3
6
  /** Label text below the marker */
4
7
  label?: string;
5
8
  /** Custom icon to render inside the marker */
@@ -13,7 +16,7 @@ export interface WaypointMarkerProps {
13
16
  /** Additional CSS classes */
14
17
  className?: string;
15
18
  }
16
- export declare function WaypointMarker({ label, icon, active, completed, size, className, }: WaypointMarkerProps): import("react/jsx-runtime").JSX.Element;
19
+ export declare function WaypointMarker({ assetUrl, label, icon, active, completed, size, className, }: WaypointMarkerProps): import("react/jsx-runtime").JSX.Element;
17
20
  export declare namespace WaypointMarker {
18
21
  var displayName: string;
19
22
  }
@@ -2280,6 +2280,9 @@ function preloadFeatures(urls) {
2280
2280
  }
2281
2281
  });
2282
2282
  }
2283
+ function cn(...inputs) {
2284
+ return tailwindMerge.twMerge(clsx.clsx(inputs));
2285
+ }
2283
2286
  var DEFAULT_GRID_CONFIG = {
2284
2287
  cellSize: 1,
2285
2288
  offsetX: 0,
@@ -2713,11 +2716,10 @@ var GameCanvas3D = React11.forwardRef(
2713
2716
  "div",
2714
2717
  {
2715
2718
  ref: containerRef,
2716
- className: `game-canvas-3d ${className || ""}`,
2719
+ className: cn("game-canvas-3d relative w-full h-full min-h-[85vh] overflow-hidden", className),
2717
2720
  "data-orientation": orientation,
2718
2721
  "data-camera-mode": cameraMode,
2719
2722
  "data-overlay": overlay,
2720
- style: { position: "relative", width: "100%", height: "100%", minHeight: "85vh", overflow: "hidden" },
2721
2723
  children: [
2722
2724
  /* @__PURE__ */ jsxRuntime.jsxs(
2723
2725
  fiber.Canvas,
@@ -2831,11 +2833,6 @@ var GameCanvas3D = React11.forwardRef(
2831
2833
  }
2832
2834
  );
2833
2835
  GameCanvas3D.displayName = "GameCanvas3D";
2834
- function cn(...inputs) {
2835
- return tailwindMerge.twMerge(clsx.clsx(inputs));
2836
- }
2837
-
2838
- // components/core/atoms/Box.tsx
2839
2836
  var paddingStyles = {
2840
2837
  none: "p-0",
2841
2838
  xs: "p-1",
@@ -3268,43 +3265,49 @@ function GameCanvas3DBattleTemplate({
3268
3265
  const features = resolved ? Array.isArray(resolved.features) ? resolved.features : [] : propFeatures;
3269
3266
  const currentTurn = resolved?.currentTurn;
3270
3267
  const round = resolved?.round == null ? void 0 : Number(resolved.round);
3271
- return /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: cn("game-canvas-3d-battle-template", className), children: [
3272
- /* @__PURE__ */ jsxRuntime.jsx(
3273
- GameCanvas3D,
3274
- {
3275
- tiles,
3276
- units,
3277
- features,
3278
- cameraMode,
3279
- showGrid,
3280
- showCoordinates: false,
3281
- showTileInfo: false,
3282
- shadows,
3283
- backgroundColor,
3284
- tileClickEvent,
3285
- unitClickEvent,
3286
- selectedUnitId,
3287
- validMoves,
3288
- attackTargets,
3289
- className: "game-canvas-3d-battle-template__canvas"
3290
- }
3291
- ),
3292
- currentTurn && /* @__PURE__ */ jsxRuntime.jsxs(
3293
- HStack,
3294
- {
3295
- gap: "sm",
3296
- align: "center",
3297
- className: cn("battle-template__turn-indicator", `battle-template__turn-indicator--${currentTurn}`),
3298
- children: [
3299
- /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", className: "turn-indicator__label", children: currentTurn === "player" ? "Your Turn" : "Enemy's Turn" }),
3300
- round != null && /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "small", className: "turn-indicator__round", children: [
3301
- "Round ",
3302
- round
3303
- ] })
3304
- ]
3305
- }
3306
- )
3307
- ] });
3268
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3269
+ Box,
3270
+ {
3271
+ className: cn("game-canvas-3d-battle-template block relative w-full min-h-[85vh]", className),
3272
+ children: [
3273
+ /* @__PURE__ */ jsxRuntime.jsx(
3274
+ GameCanvas3D,
3275
+ {
3276
+ tiles,
3277
+ units,
3278
+ features,
3279
+ cameraMode,
3280
+ showGrid,
3281
+ showCoordinates: false,
3282
+ showTileInfo: false,
3283
+ shadows,
3284
+ backgroundColor,
3285
+ tileClickEvent,
3286
+ unitClickEvent,
3287
+ selectedUnitId,
3288
+ validMoves,
3289
+ attackTargets,
3290
+ className: "game-canvas-3d-battle-template__canvas"
3291
+ }
3292
+ ),
3293
+ currentTurn && /* @__PURE__ */ jsxRuntime.jsxs(
3294
+ HStack,
3295
+ {
3296
+ gap: "sm",
3297
+ align: "center",
3298
+ className: cn("battle-template__turn-indicator absolute top-3 right-3 z-10", `battle-template__turn-indicator--${currentTurn}`),
3299
+ children: [
3300
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", className: "turn-indicator__label", children: currentTurn === "player" ? "Your Turn" : "Enemy's Turn" }),
3301
+ round != null && /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "small", className: "turn-indicator__round", children: [
3302
+ "Round ",
3303
+ round
3304
+ ] })
3305
+ ]
3306
+ }
3307
+ )
3308
+ ]
3309
+ }
3310
+ );
3308
3311
  }
3309
3312
  GameCanvas3DBattleTemplate.displayName = "GameCanvas3DBattleTemplate";
3310
3313
  var DEFAULT_3D_CASTLE_TILES = [
@@ -3369,42 +3372,48 @@ function GameCanvas3DCastleTemplate({
3369
3372
  const name = resolved?.name == null ? void 0 : String(resolved.name);
3370
3373
  const level = resolved?.level == null ? void 0 : Number(resolved.level);
3371
3374
  const owner = resolved?.owner == null ? void 0 : String(resolved.owner);
3372
- return /* @__PURE__ */ jsxRuntime.jsxs(VStack, { className: cn("game-canvas-3d-castle-template", className), children: [
3373
- showHeader && name && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "md", align: "center", className: "castle-template__header", children: [
3374
- /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h2", className: "header__name", children: name }),
3375
- level != null && /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "small", className: "header__level", children: [
3376
- "Level ",
3377
- level
3378
- ] }),
3379
- owner && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "muted", className: "header__owner", children: owner })
3380
- ] }),
3381
- /* @__PURE__ */ jsxRuntime.jsx(
3382
- GameCanvas3D,
3383
- {
3384
- tiles,
3385
- units,
3386
- features,
3387
- cameraMode,
3388
- showGrid,
3389
- showCoordinates: false,
3390
- showTileInfo: false,
3391
- shadows,
3392
- backgroundColor,
3393
- featureClickEvent: buildingClickEvent,
3394
- unitClickEvent,
3395
- selectedTileIds,
3396
- validMoves: availableBuildSites,
3397
- className: "game-canvas-3d-castle-template__canvas"
3398
- }
3399
- ),
3400
- units.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", align: "center", className: "castle-template__garrison-info", children: [
3401
- /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", className: "garrison-info__label", children: "Garrison:" }),
3402
- /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "small", weight: "bold", className: "garrison-info__count", children: [
3403
- units.length,
3404
- " units"
3405
- ] })
3406
- ] })
3407
- ] });
3375
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3376
+ VStack,
3377
+ {
3378
+ className: cn("game-canvas-3d-castle-template block w-full min-h-[85vh]", className),
3379
+ children: [
3380
+ showHeader && name && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "md", align: "center", className: "castle-template__header", children: [
3381
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h2", className: "header__name", children: name }),
3382
+ level != null && /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "small", className: "header__level", children: [
3383
+ "Level ",
3384
+ level
3385
+ ] }),
3386
+ owner && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "muted", className: "header__owner", children: owner })
3387
+ ] }),
3388
+ /* @__PURE__ */ jsxRuntime.jsx(
3389
+ GameCanvas3D,
3390
+ {
3391
+ tiles,
3392
+ units,
3393
+ features,
3394
+ cameraMode,
3395
+ showGrid,
3396
+ showCoordinates: false,
3397
+ showTileInfo: false,
3398
+ shadows,
3399
+ backgroundColor,
3400
+ featureClickEvent: buildingClickEvent,
3401
+ unitClickEvent,
3402
+ selectedTileIds,
3403
+ validMoves: availableBuildSites,
3404
+ className: "game-canvas-3d-castle-template__canvas"
3405
+ }
3406
+ ),
3407
+ units.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", align: "center", className: "castle-template__garrison-info", children: [
3408
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", className: "garrison-info__label", children: "Garrison:" }),
3409
+ /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "small", weight: "bold", className: "garrison-info__count", children: [
3410
+ units.length,
3411
+ " units"
3412
+ ] })
3413
+ ] })
3414
+ ]
3415
+ }
3416
+ );
3408
3417
  }
3409
3418
  GameCanvas3DCastleTemplate.displayName = "GameCanvas3DCastleTemplate";
3410
3419
  var DEFAULT_3D_WORLDMAP_TILES = [
@@ -316,11 +316,6 @@
316
316
 
317
317
  /* components/game/molecules/GameCanvas3D.css */
318
318
  .game-canvas-3d {
319
- position: relative;
320
- width: 100%;
321
- height: 100%;
322
- min-height: 85vh;
323
- overflow: hidden;
324
319
  background: #1a1a2e;
325
320
  border-radius: 8px;
326
321
  }
@@ -2256,6 +2256,9 @@ function preloadFeatures(urls) {
2256
2256
  }
2257
2257
  });
2258
2258
  }
2259
+ function cn(...inputs) {
2260
+ return twMerge(clsx(inputs));
2261
+ }
2259
2262
  var DEFAULT_GRID_CONFIG = {
2260
2263
  cellSize: 1,
2261
2264
  offsetX: 0,
@@ -2689,11 +2692,10 @@ var GameCanvas3D = forwardRef(
2689
2692
  "div",
2690
2693
  {
2691
2694
  ref: containerRef,
2692
- className: `game-canvas-3d ${className || ""}`,
2695
+ className: cn("game-canvas-3d relative w-full h-full min-h-[85vh] overflow-hidden", className),
2693
2696
  "data-orientation": orientation,
2694
2697
  "data-camera-mode": cameraMode,
2695
2698
  "data-overlay": overlay,
2696
- style: { position: "relative", width: "100%", height: "100%", minHeight: "85vh", overflow: "hidden" },
2697
2699
  children: [
2698
2700
  /* @__PURE__ */ jsxs(
2699
2701
  Canvas,
@@ -2807,11 +2809,6 @@ var GameCanvas3D = forwardRef(
2807
2809
  }
2808
2810
  );
2809
2811
  GameCanvas3D.displayName = "GameCanvas3D";
2810
- function cn(...inputs) {
2811
- return twMerge(clsx(inputs));
2812
- }
2813
-
2814
- // components/core/atoms/Box.tsx
2815
2812
  var paddingStyles = {
2816
2813
  none: "p-0",
2817
2814
  xs: "p-1",
@@ -3244,43 +3241,49 @@ function GameCanvas3DBattleTemplate({
3244
3241
  const features = resolved ? Array.isArray(resolved.features) ? resolved.features : [] : propFeatures;
3245
3242
  const currentTurn = resolved?.currentTurn;
3246
3243
  const round = resolved?.round == null ? void 0 : Number(resolved.round);
3247
- return /* @__PURE__ */ jsxs(Box, { className: cn("game-canvas-3d-battle-template", className), children: [
3248
- /* @__PURE__ */ jsx(
3249
- GameCanvas3D,
3250
- {
3251
- tiles,
3252
- units,
3253
- features,
3254
- cameraMode,
3255
- showGrid,
3256
- showCoordinates: false,
3257
- showTileInfo: false,
3258
- shadows,
3259
- backgroundColor,
3260
- tileClickEvent,
3261
- unitClickEvent,
3262
- selectedUnitId,
3263
- validMoves,
3264
- attackTargets,
3265
- className: "game-canvas-3d-battle-template__canvas"
3266
- }
3267
- ),
3268
- currentTurn && /* @__PURE__ */ jsxs(
3269
- HStack,
3270
- {
3271
- gap: "sm",
3272
- align: "center",
3273
- className: cn("battle-template__turn-indicator", `battle-template__turn-indicator--${currentTurn}`),
3274
- children: [
3275
- /* @__PURE__ */ jsx(Typography, { variant: "body", className: "turn-indicator__label", children: currentTurn === "player" ? "Your Turn" : "Enemy's Turn" }),
3276
- round != null && /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "turn-indicator__round", children: [
3277
- "Round ",
3278
- round
3279
- ] })
3280
- ]
3281
- }
3282
- )
3283
- ] });
3244
+ return /* @__PURE__ */ jsxs(
3245
+ Box,
3246
+ {
3247
+ className: cn("game-canvas-3d-battle-template block relative w-full min-h-[85vh]", className),
3248
+ children: [
3249
+ /* @__PURE__ */ jsx(
3250
+ GameCanvas3D,
3251
+ {
3252
+ tiles,
3253
+ units,
3254
+ features,
3255
+ cameraMode,
3256
+ showGrid,
3257
+ showCoordinates: false,
3258
+ showTileInfo: false,
3259
+ shadows,
3260
+ backgroundColor,
3261
+ tileClickEvent,
3262
+ unitClickEvent,
3263
+ selectedUnitId,
3264
+ validMoves,
3265
+ attackTargets,
3266
+ className: "game-canvas-3d-battle-template__canvas"
3267
+ }
3268
+ ),
3269
+ currentTurn && /* @__PURE__ */ jsxs(
3270
+ HStack,
3271
+ {
3272
+ gap: "sm",
3273
+ align: "center",
3274
+ className: cn("battle-template__turn-indicator absolute top-3 right-3 z-10", `battle-template__turn-indicator--${currentTurn}`),
3275
+ children: [
3276
+ /* @__PURE__ */ jsx(Typography, { variant: "body", className: "turn-indicator__label", children: currentTurn === "player" ? "Your Turn" : "Enemy's Turn" }),
3277
+ round != null && /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "turn-indicator__round", children: [
3278
+ "Round ",
3279
+ round
3280
+ ] })
3281
+ ]
3282
+ }
3283
+ )
3284
+ ]
3285
+ }
3286
+ );
3284
3287
  }
3285
3288
  GameCanvas3DBattleTemplate.displayName = "GameCanvas3DBattleTemplate";
3286
3289
  var DEFAULT_3D_CASTLE_TILES = [
@@ -3345,42 +3348,48 @@ function GameCanvas3DCastleTemplate({
3345
3348
  const name = resolved?.name == null ? void 0 : String(resolved.name);
3346
3349
  const level = resolved?.level == null ? void 0 : Number(resolved.level);
3347
3350
  const owner = resolved?.owner == null ? void 0 : String(resolved.owner);
3348
- return /* @__PURE__ */ jsxs(VStack, { className: cn("game-canvas-3d-castle-template", className), children: [
3349
- showHeader && name && /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "center", className: "castle-template__header", children: [
3350
- /* @__PURE__ */ jsx(Typography, { variant: "h2", className: "header__name", children: name }),
3351
- level != null && /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "header__level", children: [
3352
- "Level ",
3353
- level
3354
- ] }),
3355
- owner && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", className: "header__owner", children: owner })
3356
- ] }),
3357
- /* @__PURE__ */ jsx(
3358
- GameCanvas3D,
3359
- {
3360
- tiles,
3361
- units,
3362
- features,
3363
- cameraMode,
3364
- showGrid,
3365
- showCoordinates: false,
3366
- showTileInfo: false,
3367
- shadows,
3368
- backgroundColor,
3369
- featureClickEvent: buildingClickEvent,
3370
- unitClickEvent,
3371
- selectedTileIds,
3372
- validMoves: availableBuildSites,
3373
- className: "game-canvas-3d-castle-template__canvas"
3374
- }
3375
- ),
3376
- units.length > 0 && /* @__PURE__ */ jsxs(HStack, { gap: "sm", align: "center", className: "castle-template__garrison-info", children: [
3377
- /* @__PURE__ */ jsx(Typography, { variant: "small", className: "garrison-info__label", children: "Garrison:" }),
3378
- /* @__PURE__ */ jsxs(Typography, { variant: "small", weight: "bold", className: "garrison-info__count", children: [
3379
- units.length,
3380
- " units"
3381
- ] })
3382
- ] })
3383
- ] });
3351
+ return /* @__PURE__ */ jsxs(
3352
+ VStack,
3353
+ {
3354
+ className: cn("game-canvas-3d-castle-template block w-full min-h-[85vh]", className),
3355
+ children: [
3356
+ showHeader && name && /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "center", className: "castle-template__header", children: [
3357
+ /* @__PURE__ */ jsx(Typography, { variant: "h2", className: "header__name", children: name }),
3358
+ level != null && /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "header__level", children: [
3359
+ "Level ",
3360
+ level
3361
+ ] }),
3362
+ owner && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", className: "header__owner", children: owner })
3363
+ ] }),
3364
+ /* @__PURE__ */ jsx(
3365
+ GameCanvas3D,
3366
+ {
3367
+ tiles,
3368
+ units,
3369
+ features,
3370
+ cameraMode,
3371
+ showGrid,
3372
+ showCoordinates: false,
3373
+ showTileInfo: false,
3374
+ shadows,
3375
+ backgroundColor,
3376
+ featureClickEvent: buildingClickEvent,
3377
+ unitClickEvent,
3378
+ selectedTileIds,
3379
+ validMoves: availableBuildSites,
3380
+ className: "game-canvas-3d-castle-template__canvas"
3381
+ }
3382
+ ),
3383
+ units.length > 0 && /* @__PURE__ */ jsxs(HStack, { gap: "sm", align: "center", className: "castle-template__garrison-info", children: [
3384
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "garrison-info__label", children: "Garrison:" }),
3385
+ /* @__PURE__ */ jsxs(Typography, { variant: "small", weight: "bold", className: "garrison-info__count", children: [
3386
+ units.length,
3387
+ " units"
3388
+ ] })
3389
+ ] })
3390
+ ]
3391
+ }
3392
+ );
3384
3393
  }
3385
3394
  GameCanvas3DCastleTemplate.displayName = "GameCanvas3DCastleTemplate";
3386
3395
  var DEFAULT_3D_WORLDMAP_TILES = [
@@ -44,6 +44,13 @@ export type CastleSlotContext = {
44
44
  };
45
45
  /** Canvas scale */
46
46
  scale: number;
47
+ gold: number;
48
+ health: number;
49
+ maxHealth: number;
50
+ wave: number;
51
+ tickCount: number;
52
+ buildings: readonly EntityRow[];
53
+ result: 'none' | 'victory' | 'defeat';
47
54
  };
48
55
  export interface CastleBoardProps {
49
56
  /** Castle board-state entity (single row or array). The board reads
@@ -89,9 +96,11 @@ export interface CastleBoardProps {
89
96
  x: number;
90
97
  y: number;
91
98
  }>;
99
+ /** Emits UI:{playAgainEvent} with {} on play again / reset */
100
+ playAgainEvent?: EventEmit<Record<string, never>>;
92
101
  className?: string;
93
102
  }
94
- export declare function CastleBoard({ entity, tiles: propTiles, units: propUnits, features: propFeatures, assetManifest: propAssetManifest, scale, header, sidePanel, overlay, footer, onFeatureClick, onUnitClick, onTileClick, featureClickEvent, unitClickEvent, tileClickEvent, className, }: CastleBoardProps): React.JSX.Element;
103
+ export declare function CastleBoard({ entity, tiles: propTiles, units: propUnits, features: propFeatures, assetManifest: propAssetManifest, scale, header, sidePanel, overlay, footer, onFeatureClick, onUnitClick, onTileClick, featureClickEvent, unitClickEvent, tileClickEvent, playAgainEvent, className, }: CastleBoardProps): React.JSX.Element;
95
104
  export declare namespace CastleBoard {
96
105
  var displayName: string;
97
106
  }
@@ -13,6 +13,7 @@
13
13
  import React from 'react';
14
14
  import type { EventEmit, EntityRow } from '@almadar/core';
15
15
  import type { DisplayStateProps } from '../../../../core/organisms/types';
16
+ import type { RuleDefinition } from './RuleEditor';
16
17
  export interface EventHandlerBoardProps extends DisplayStateProps {
17
18
  /** Puzzle board-state entity (single row or array). The board reads
18
19
  * `objects` / `triggerEvents` / `goalEvent` etc. off the row; the editable
@@ -26,8 +27,15 @@ export interface EventHandlerBoardProps extends DisplayStateProps {
26
27
  completeEvent?: EventEmit<{
27
28
  success: boolean;
28
29
  }>;
30
+ /** Emits UI:{editRuleEvent} with { objectId, rules } — model updates @entity.objects */
31
+ editRuleEvent?: EventEmit<{
32
+ objectId: string;
33
+ rules: RuleDefinition[];
34
+ }>;
35
+ /** Emits UI:{playAgainEvent} to reset the model */
36
+ playAgainEvent?: EventEmit<Record<string, never>>;
29
37
  }
30
- export declare function EventHandlerBoard({ entity, stepDurationMs, playEvent, completeEvent, className, }: EventHandlerBoardProps): React.JSX.Element | null;
38
+ export declare function EventHandlerBoard({ entity, stepDurationMs, playEvent, completeEvent, editRuleEvent, playAgainEvent, className, }: EventHandlerBoardProps): React.JSX.Element | null;
31
39
  export declare namespace EventHandlerBoard {
32
40
  var displayName: string;
33
41
  }
@@ -40,8 +40,21 @@ export interface StateArchitectBoardProps extends DisplayStateProps {
40
40
  success: boolean;
41
41
  passedTests: number;
42
42
  }>;
43
+ /** Emits UI:{addTransitionEvent} — lolo handles ADD_TRANSITION */
44
+ addTransitionEvent?: EventEmit<{
45
+ id: string;
46
+ from: string;
47
+ to: string;
48
+ event: string;
49
+ }>;
50
+ /** Emits UI:{removeTransitionEvent} — lolo handles REMOVE_TRANSITION */
51
+ removeTransitionEvent?: EventEmit<{
52
+ id: string;
53
+ }>;
54
+ /** Emits UI:{playAgainEvent} — lolo handles PLAY_AGAIN */
55
+ playAgainEvent?: EventEmit<Record<string, never>>;
43
56
  }
44
- export declare function StateArchitectBoard({ entity, stepDurationMs, testEvent, completeEvent, className, }: StateArchitectBoardProps): React.JSX.Element | null;
57
+ export declare function StateArchitectBoard({ entity, stepDurationMs, testEvent, completeEvent, addTransitionEvent, removeTransitionEvent, playAgainEvent, className, }: StateArchitectBoardProps): React.JSX.Element | null;
45
58
  export declare namespace StateArchitectBoard {
46
59
  var displayName: string;
47
60
  }