@almadar/ui 5.65.0 → 5.67.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.
@@ -48,7 +48,7 @@ import { GLTFLoader as GLTFLoader$1 } from 'three/examples/jsm/loaders/GLTFLoade
48
48
  import { clone } from 'three/examples/jsm/utils/SkeletonUtils';
49
49
  import { Canvas, useLoader, useFrame, useThree } from '@react-three/fiber';
50
50
  import { Billboard, Grid as Grid$1, OrbitControls } from '@react-three/drei';
51
- import { getPatternDefinition, getComponentForPattern as getComponentForPattern$1 } from '@almadar/patterns';
51
+ import { getPatternDefinition, getComponentForPattern } from '@almadar/patterns';
52
52
  import { StateMachineManager, collectDeclaredConfigDefaults, createServerEffectHandlers, EffectExecutor, createContextFromBindings, InMemoryPersistence } from '@almadar/runtime';
53
53
  import { OrbitalServerRuntime } from '@almadar/runtime/OrbitalServerRuntime';
54
54
 
@@ -8016,6 +8016,8 @@ var init_DialogueBubble = __esm({
8016
8016
  function ChoiceButton({
8017
8017
  text = "Charge forward into the fray",
8018
8018
  index,
8019
+ assetUrl,
8020
+ icon,
8019
8021
  disabled = false,
8020
8022
  selected = false,
8021
8023
  onClick,
@@ -8048,6 +8050,23 @@ function ChoiceButton({
8048
8050
  ]
8049
8051
  }
8050
8052
  ),
8053
+ assetUrl ? /* @__PURE__ */ jsx(
8054
+ "img",
8055
+ {
8056
+ src: assetUrl,
8057
+ alt: "",
8058
+ width: 16,
8059
+ height: 16,
8060
+ style: { imageRendering: "pixelated", objectFit: "contain" },
8061
+ className: "flex-shrink-0"
8062
+ }
8063
+ ) : icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 text-sm", children: typeof icon === "string" ? (() => {
8064
+ const I = resolveIcon(icon);
8065
+ return I ? /* @__PURE__ */ jsx(I, { className: "w-4 h-4" }) : null;
8066
+ })() : /* @__PURE__ */ (() => {
8067
+ const I = icon;
8068
+ return /* @__PURE__ */ jsx(I, { className: "w-4 h-4" });
8069
+ })() }) : null,
8051
8070
  /* @__PURE__ */ jsx("span", { className: "text-sm leading-snug", children: text })
8052
8071
  ]
8053
8072
  }
@@ -8056,6 +8075,7 @@ function ChoiceButton({
8056
8075
  var init_ChoiceButton = __esm({
8057
8076
  "components/game/atoms/ChoiceButton.tsx"() {
8058
8077
  init_cn();
8078
+ init_Icon();
8059
8079
  ChoiceButton.displayName = "ChoiceButton";
8060
8080
  }
8061
8081
  });
@@ -11204,7 +11224,8 @@ function IsometricCanvas({
11204
11224
  const minX = Math.min(...allScreenPos.map((p2) => p2.x));
11205
11225
  const maxX = Math.max(...allScreenPos.map((p2) => p2.x + scaledTileWidth));
11206
11226
  const minY = Math.min(...allScreenPos.map((p2) => p2.y));
11207
- const maxY = Math.max(...allScreenPos.map((p2) => p2.y + scaledTileHeight));
11227
+ const tileBottomExtent = tileLayout === "hex" ? scaledTileWidth : scaledTileHeight;
11228
+ const maxY = Math.max(...allScreenPos.map((p2) => p2.y + tileBottomExtent));
11208
11229
  const worldW = maxX - minX;
11209
11230
  const worldH = maxY - minY;
11210
11231
  const scaleM = Math.min(mW / worldW, mH / worldH) * 0.9;
@@ -11296,7 +11317,7 @@ function IsometricCanvas({
11296
11317
  const drawW = scaledTileWidth;
11297
11318
  const drawH = scaledTileWidth * (img.naturalHeight / img.naturalWidth);
11298
11319
  const drawX = pos.x;
11299
- const drawY = pos.y + scaledTileHeight - drawH;
11320
+ const drawY = tileLayout === "hex" ? pos.y : pos.y + scaledTileHeight - drawH;
11300
11321
  ctx.drawImage(img, drawX, drawY, drawW, drawH);
11301
11322
  }
11302
11323
  } else {
@@ -28048,6 +28069,7 @@ function PowerupSlots({
28048
28069
  /* @__PURE__ */ jsx(
28049
28070
  ItemSlot,
28050
28071
  {
28072
+ assetUrl: powerup.assetUrl,
28051
28073
  icon: powerup.icon,
28052
28074
  label: powerup.label,
28053
28075
  rarity: "uncommon",
@@ -28297,13 +28319,26 @@ function HealthPanel({
28297
28319
  )
28298
28320
  }
28299
28321
  ),
28300
- effects && effects.length > 0 && /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-1 flex-wrap", children: effects.map((effect, i) => /* @__PURE__ */ jsx(
28322
+ effects && effects.length > 0 && /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-1 flex-wrap", children: effects.map((effect, i) => /* @__PURE__ */ jsxs(
28301
28323
  Badge,
28302
28324
  {
28303
28325
  variant: effectVariantMap[effect.variant ?? "neutral"],
28304
28326
  size: "sm",
28305
- icon: effect.icon,
28306
- children: effect.label
28327
+ icon: effect.assetUrl ? void 0 : effect.icon,
28328
+ children: [
28329
+ effect.assetUrl && /* @__PURE__ */ jsx(
28330
+ "img",
28331
+ {
28332
+ src: effect.assetUrl,
28333
+ alt: "",
28334
+ width: 12,
28335
+ height: 12,
28336
+ style: { imageRendering: "pixelated", objectFit: "contain" },
28337
+ className: "flex-shrink-0 inline-block"
28338
+ }
28339
+ ),
28340
+ effect.label
28341
+ ]
28307
28342
  },
28308
28343
  i
28309
28344
  )) })
@@ -28486,15 +28521,28 @@ function TurnPanel({
28486
28521
  activeTeam
28487
28522
  }
28488
28523
  ),
28489
- actions && actions.length > 0 && /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-1.5 ml-auto", children: actions.map((action, i) => /* @__PURE__ */ jsx(
28524
+ actions && actions.length > 0 && /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-1.5 ml-auto", children: actions.map((action, i) => /* @__PURE__ */ jsxs(
28490
28525
  Button,
28491
28526
  {
28492
28527
  variant: "ghost",
28493
28528
  size: "sm",
28494
28529
  disabled: action.disabled,
28495
- leftIcon: action.icon,
28530
+ leftIcon: action.assetUrl ? void 0 : action.icon,
28496
28531
  onClick: () => handleAction(action.event),
28497
- children: action.label
28532
+ children: [
28533
+ action.assetUrl && /* @__PURE__ */ jsx(
28534
+ "img",
28535
+ {
28536
+ src: action.assetUrl,
28537
+ alt: "",
28538
+ width: 14,
28539
+ height: 14,
28540
+ style: { imageRendering: "pixelated", objectFit: "contain" },
28541
+ className: "flex-shrink-0"
28542
+ }
28543
+ ),
28544
+ action.label
28545
+ ]
28498
28546
  },
28499
28547
  i
28500
28548
  )) })
@@ -43410,9 +43458,9 @@ var init_GameCanvas3D2 = __esm({
43410
43458
  const color = unit.faction === "player" ? 4491519 : unit.faction === "enemy" ? 16729156 : 16777028;
43411
43459
  const hasAtlas = unitAtlasUrl(unit) !== null;
43412
43460
  const initialFrame = hasAtlas ? resolveUnitFrame(unit.id) : null;
43413
- const modelScale = UNIT_BASE_MODEL_SCALE * unitScale;
43414
- const billboardHeight = UNIT_BASE_BILLBOARD_HEIGHT * unitScale;
43415
- const primitiveRadius = UNIT_BASE_PRIMITIVE_RADIUS * unitScale;
43461
+ const modelScale = UNIT_BASE_MODEL_SCALE * unitScale * gridConfig.cellSize;
43462
+ const billboardHeight = UNIT_BASE_BILLBOARD_HEIGHT * unitScale * gridConfig.cellSize;
43463
+ const primitiveRadius = UNIT_BASE_PRIMITIVE_RADIUS * unitScale * gridConfig.cellSize;
43416
43464
  return /* @__PURE__ */ jsxs(
43417
43465
  "group",
43418
43466
  {
@@ -43459,7 +43507,7 @@ var init_GameCanvas3D2 = __esm({
43459
43507
  /* @__PURE__ */ jsx("meshStandardMaterial", { color })
43460
43508
  ] })
43461
43509
  ] }),
43462
- unit.health !== void 0 && unit.maxHealth !== void 0 && /* @__PURE__ */ jsxs("group", { position: [0, 1.2, 0], children: [
43510
+ unit.health !== void 0 && unit.maxHealth !== void 0 && /* @__PURE__ */ jsxs("group", { position: [0, billboardHeight, 0], children: [
43463
43511
  /* @__PURE__ */ jsxs("mesh", { position: [-0.25, 0, 0], children: [
43464
43512
  /* @__PURE__ */ jsx("planeGeometry", { args: [0.5, 0.05] }),
43465
43513
  /* @__PURE__ */ jsx("meshBasicMaterial", { color: 3355443 })
@@ -43488,7 +43536,7 @@ var init_GameCanvas3D2 = __esm({
43488
43536
  }
43489
43537
  );
43490
43538
  },
43491
- [selectedUnitId, handleUnitClick, resolveUnitFrame, unitScale]
43539
+ [selectedUnitId, handleUnitClick, resolveUnitFrame, unitScale, gridConfig]
43492
43540
  );
43493
43541
  const DefaultFeatureRenderer = useCallback(
43494
43542
  ({
@@ -43576,7 +43624,7 @@ var init_GameCanvas3D2 = __esm({
43576
43624
  {
43577
43625
  ref: containerRef,
43578
43626
  className: cn("game-canvas-3d relative w-full overflow-hidden", className),
43579
- style: { height: "85vh" },
43627
+ style: { flex: "1 1 0", minHeight: "400px" },
43580
43628
  "data-orientation": orientation,
43581
43629
  "data-camera-mode": cameraMode,
43582
43630
  "data-overlay": overlay,
@@ -43876,13 +43924,39 @@ var init_GameBoard3D = __esm({
43876
43924
  GameBoard3D.displayName = "GameBoard3D";
43877
43925
  }
43878
43926
  });
43879
- var GameShell;
43927
+ function getSlotContentRenderer2() {
43928
+ if (_scr) return _scr;
43929
+ const mod = (init_UISlotRenderer(), __toCommonJS(UISlotRenderer_exports));
43930
+ _scr = mod.SlotContentRenderer;
43931
+ return _scr;
43932
+ }
43933
+ function resolveDescriptor(value, idPrefix) {
43934
+ if (value === null || value === void 0) return value;
43935
+ if (React84__default.isValidElement(value)) return value;
43936
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
43937
+ if (Array.isArray(value)) {
43938
+ return value.map((item, i) => /* @__PURE__ */ jsx(React84__default.Fragment, { children: resolveDescriptor(item, `${idPrefix}-${i}`) }, i));
43939
+ }
43940
+ if (typeof value === "object") {
43941
+ const rec = value;
43942
+ if (typeof rec.type === "string" && getComponentForPattern(rec.type) !== null) {
43943
+ const { type, props: nestedProps, _id, ...flatProps } = rec;
43944
+ const resolvedProps = nestedProps !== void 0 ? nestedProps : flatProps;
43945
+ const content = { id: _id ?? idPrefix, pattern: type, props: resolvedProps, priority: 0 };
43946
+ const SCR = getSlotContentRenderer2();
43947
+ return /* @__PURE__ */ jsx(SCR, { content, onDismiss: () => void 0 });
43948
+ }
43949
+ }
43950
+ return null;
43951
+ }
43952
+ var _scr, GameShell;
43880
43953
  var init_GameShell = __esm({
43881
43954
  "components/game/templates/GameShell.tsx"() {
43882
43955
  init_cn();
43883
43956
  init_Box();
43884
43957
  init_Stack();
43885
43958
  init_Typography();
43959
+ _scr = null;
43886
43960
  GameShell = ({
43887
43961
  appName = "Game",
43888
43962
  hud,
@@ -43931,7 +44005,7 @@ var init_GameShell = __esm({
43931
44005
  children: appName
43932
44006
  }
43933
44007
  ),
43934
- hud && /* @__PURE__ */ jsx(Box, { className: "game-shell__hud", children: hud })
44008
+ hud && /* @__PURE__ */ jsx(Box, { className: "game-shell__hud", children: resolveDescriptor(hud, "gs-hud") })
43935
44009
  ]
43936
44010
  }
43937
44011
  ),
@@ -43944,7 +44018,7 @@ var init_GameShell = __esm({
43944
44018
  overflow: "hidden",
43945
44019
  position: "relative"
43946
44020
  },
43947
- children
44021
+ children: resolveDescriptor(children, "gs-children")
43948
44022
  }
43949
44023
  )
43950
44024
  ]
@@ -43954,7 +44028,32 @@ var init_GameShell = __esm({
43954
44028
  GameShell.displayName = "GameShell";
43955
44029
  }
43956
44030
  });
43957
- var GameTemplate;
44031
+ function getSlotContentRenderer3() {
44032
+ if (_scr2) return _scr2;
44033
+ const mod = (init_UISlotRenderer(), __toCommonJS(UISlotRenderer_exports));
44034
+ _scr2 = mod.SlotContentRenderer;
44035
+ return _scr2;
44036
+ }
44037
+ function resolveDescriptor2(value, idPrefix) {
44038
+ if (value === null || value === void 0) return value;
44039
+ if (React84__default.isValidElement(value)) return value;
44040
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
44041
+ if (Array.isArray(value)) {
44042
+ return value.map((item, i) => /* @__PURE__ */ jsx(React84__default.Fragment, { children: resolveDescriptor2(item, `${idPrefix}-${i}`) }, i));
44043
+ }
44044
+ if (typeof value === "object") {
44045
+ const rec = value;
44046
+ if (typeof rec.type === "string" && getComponentForPattern(rec.type) !== null) {
44047
+ const { type, props: nestedProps, _id, ...flatProps } = rec;
44048
+ const resolvedProps = nestedProps !== void 0 ? nestedProps : flatProps;
44049
+ const content = { id: _id ?? idPrefix, pattern: type, props: resolvedProps, priority: 0 };
44050
+ const SCR = getSlotContentRenderer3();
44051
+ return /* @__PURE__ */ jsx(SCR, { content, onDismiss: () => void 0 });
44052
+ }
44053
+ }
44054
+ return null;
44055
+ }
44056
+ var _scr2, GameTemplate;
43958
44057
  var init_GameTemplate = __esm({
43959
44058
  "components/game/templates/GameTemplate.tsx"() {
43960
44059
  init_cn();
@@ -43962,6 +44061,7 @@ var init_GameTemplate = __esm({
43962
44061
  init_Stack();
43963
44062
  init_Typography();
43964
44063
  init_Button();
44064
+ _scr2 = null;
43965
44065
  GameTemplate = ({
43966
44066
  entity,
43967
44067
  title = "Game",
@@ -44029,13 +44129,13 @@ var init_GameTemplate = __esm({
44029
44129
  fullWidth: true,
44030
44130
  className: "flex-1 bg-muted",
44031
44131
  children: [
44032
- children,
44132
+ resolveDescriptor2(children, "gt-children"),
44033
44133
  hud && /* @__PURE__ */ jsx(
44034
44134
  Box,
44035
44135
  {
44036
44136
  position: "absolute",
44037
44137
  className: "top-0 left-0 right-0 pointer-events-none",
44038
- children: /* @__PURE__ */ jsx(Box, { padding: "md", className: "pointer-events-auto w-fit", children: hud })
44138
+ children: /* @__PURE__ */ jsx(Box, { padding: "md", className: "pointer-events-auto w-fit", children: resolveDescriptor2(hud, "gt-hud") })
44039
44139
  }
44040
44140
  )
44041
44141
  ]
@@ -44060,7 +44160,7 @@ var init_GameTemplate = __esm({
44060
44160
  children: /* @__PURE__ */ jsx(Typography, { variant: "h6", children: "Debug Panel" })
44061
44161
  }
44062
44162
  ),
44063
- /* @__PURE__ */ jsx(Box, { padding: "md", children: debugPanel })
44163
+ /* @__PURE__ */ jsx(Box, { padding: "md", children: resolveDescriptor2(debugPanel, "gt-debug") })
44064
44164
  ]
44065
44165
  }
44066
44166
  )
@@ -52639,8 +52739,8 @@ function getSlotFallback(slot, config) {
52639
52739
  const variant = SLOT_SKELETON_MAP[slot] ?? "text";
52640
52740
  return /* @__PURE__ */ jsx(Skeleton, { variant });
52641
52741
  }
52642
- function getComponentForPattern(patternType) {
52643
- const mapping = getComponentForPattern$1(patternType);
52742
+ function getComponentForPattern3(patternType) {
52743
+ const mapping = getComponentForPattern(patternType);
52644
52744
  if (!mapping) {
52645
52745
  return null;
52646
52746
  }
@@ -53162,7 +53262,7 @@ function isPatternConfig(value) {
53162
53262
  if (value instanceof Date) return false;
53163
53263
  if (typeof value === "function") return false;
53164
53264
  const record = value;
53165
- return "type" in record && typeof record.type === "string" && getComponentForPattern$1(record.type) !== null;
53265
+ return "type" in record && typeof record.type === "string" && getComponentForPattern(record.type) !== null;
53166
53266
  }
53167
53267
  function isPlainConfigObject(value) {
53168
53268
  if (React84__default.isValidElement(value)) return false;
@@ -53270,7 +53370,8 @@ function SlotContentRenderer({
53270
53370
  entityDef = schemaCtx.entities.get(linkedEntity);
53271
53371
  }
53272
53372
  }
53273
- const PatternComponent = getComponentForPattern(content.pattern);
53373
+ const orbitalName = schemaCtx && content.sourceTrait !== void 0 ? schemaCtx.orbitalsByTrait.get(content.sourceTrait) : void 0;
53374
+ const PatternComponent = getComponentForPattern3(content.pattern);
53274
53375
  if (PatternComponent) {
53275
53376
  const childrenConfig = content.props.children;
53276
53377
  const isSingleChild = typeof childrenConfig === "string" || typeof childrenConfig === "object" && childrenConfig !== null && !Array.isArray(childrenConfig) && "type" in childrenConfig;
@@ -53368,6 +53469,7 @@ function SlotContentRenderer({
53368
53469
  "data-orb-entity": content.entity,
53369
53470
  "data-orb-path": myPath,
53370
53471
  "data-orb-pattern": content.pattern,
53472
+ "data-orb-orbital": orbitalName,
53371
53473
  children: renderedChildren !== void 0 ? /* @__PURE__ */ jsx(PatternComponent, { ...finalProps, children: renderedChildren }) : /* @__PURE__ */ jsx(PatternComponent, { ...finalProps })
53372
53474
  }
53373
53475
  );
@@ -53387,6 +53489,7 @@ function SlotContentRenderer({
53387
53489
  "data-orb-entity": content.entity,
53388
53490
  "data-orb-path": patternPath ?? "root",
53389
53491
  "data-orb-pattern": content.pattern,
53492
+ "data-orb-orbital": orbitalName,
53390
53493
  children: content.props.children ?? /* @__PURE__ */ jsxs(Box, { className: "p-4 text-sm text-muted-foreground border border-dashed border-border rounded", children: [
53391
53494
  "Unknown pattern: ",
53392
53495
  content.pattern,
@@ -53636,7 +53739,7 @@ function resolveLambdaBindings(body, params, item, index) {
53636
53739
  return body;
53637
53740
  }
53638
53741
  var _slotContentRenderer2 = null;
53639
- function getSlotContentRenderer2() {
53742
+ function getSlotContentRenderer4() {
53640
53743
  if (_slotContentRenderer2) return _slotContentRenderer2;
53641
53744
  const mod = (init_UISlotRenderer(), __toCommonJS(UISlotRenderer_exports));
53642
53745
  _slotContentRenderer2 = mod.SlotContentRenderer;
@@ -53652,7 +53755,7 @@ function makeLambdaFn(params, lambdaBody, callerKey) {
53652
53755
  if (typeof record.type !== "string") {
53653
53756
  return null;
53654
53757
  }
53655
- const SlotContentRenderer2 = getSlotContentRenderer2();
53758
+ const SlotContentRenderer2 = getSlotContentRenderer4();
53656
53759
  const rawChildProps = {};
53657
53760
  for (const [k, v] of Object.entries(record)) {
53658
53761
  if (k !== "type") rawChildProps[k] = v;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "5.65.0",
3
+ "version": "5.67.0",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -134,7 +134,7 @@
134
134
  "typecheck": "tsc --noEmit"
135
135
  },
136
136
  "dependencies": {
137
- "@almadar/core": "^10.5.0",
137
+ "@almadar/core": "^10.6.0",
138
138
  "@almadar/evaluator": ">=2.9.2",
139
139
  "@almadar/logger": "^1.3.0",
140
140
  "@almadar/patterns": ">=2.35.0",