@almadar/ui 5.11.0 → 5.12.1

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.
@@ -14619,7 +14619,7 @@ var init_MapView = __esm({
14619
14619
  shadowSize: [41, 41]
14620
14620
  });
14621
14621
  L.Marker.prototype.options.icon = defaultIcon;
14622
- const { useEffect: useEffect89, useRef: useRef88, useCallback: useCallback130, useState: useState124 } = React98__namespace.default;
14622
+ const { useEffect: useEffect89, useRef: useRef88, useCallback: useCallback130, useState: useState125 } = React98__namespace.default;
14623
14623
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
14624
14624
  const { useEventBus: useEventBus3 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
14625
14625
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -14664,7 +14664,7 @@ var init_MapView = __esm({
14664
14664
  showAttribution = true
14665
14665
  }) {
14666
14666
  const eventBus = useEventBus3();
14667
- const [clickedPosition, setClickedPosition] = useState124(null);
14667
+ const [clickedPosition, setClickedPosition] = useState125(null);
14668
14668
  const handleMapClick = useCallback130((lat, lng) => {
14669
14669
  if (showClickedPin) {
14670
14670
  setClickedPosition({ lat, lng });
@@ -30441,8 +30441,16 @@ function GameCanvas2D({
30441
30441
  drawEventRef.current = drawEvent;
30442
30442
  const emitRef = React98__namespace.useRef(emit);
30443
30443
  emitRef.current = emit;
30444
+ const assetBaseUrlRef = React98__namespace.useRef(assetBaseUrl);
30445
+ assetBaseUrlRef.current = assetBaseUrl;
30446
+ const backgroundImageRef = React98__namespace.useRef(backgroundImage);
30447
+ backgroundImageRef.current = backgroundImage;
30448
+ const widthRef = React98__namespace.useRef(width);
30449
+ widthRef.current = width;
30450
+ const heightRef = React98__namespace.useRef(height);
30451
+ heightRef.current = height;
30444
30452
  const loadImage = React98__namespace.useCallback((url) => {
30445
- const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
30453
+ const fullUrl = url.startsWith("http") ? url : `${assetBaseUrlRef.current}${url}`;
30446
30454
  const cached = imageCache.current.get(fullUrl);
30447
30455
  if (cached?.complete && cached.naturalWidth > 0) return cached;
30448
30456
  if (!cached) {
@@ -30452,7 +30460,7 @@ function GameCanvas2D({
30452
30460
  imageCache.current.set(fullUrl, img);
30453
30461
  }
30454
30462
  return null;
30455
- }, [assetBaseUrl]);
30463
+ }, []);
30456
30464
  React98__namespace.useEffect(() => {
30457
30465
  const canvas = canvasRef.current;
30458
30466
  if (!canvas) return;
@@ -30474,10 +30482,10 @@ function GameCanvas2D({
30474
30482
  if (tickEventRef.current) {
30475
30483
  emitRef.current(tickEventRef.current, { dt, frame });
30476
30484
  }
30477
- if (backgroundImage) {
30478
- const bgImg = loadImage(backgroundImage);
30485
+ if (backgroundImageRef.current) {
30486
+ const bgImg = loadImage(backgroundImageRef.current);
30479
30487
  if (bgImg) {
30480
- ctx.drawImage(bgImg, 0, 0, width, height);
30488
+ ctx.drawImage(bgImg, 0, 0, widthRef.current, heightRef.current);
30481
30489
  }
30482
30490
  }
30483
30491
  onDrawRef.current?.(ctx, frame);
@@ -30493,7 +30501,7 @@ function GameCanvas2D({
30493
30501
  running = false;
30494
30502
  cancelAnimationFrame(rafRef.current);
30495
30503
  };
30496
- }, [fps]);
30504
+ }, [fps, loadImage]);
30497
30505
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: cn("inline-block", className), children: /* @__PURE__ */ jsxRuntime.jsx(
30498
30506
  "canvas",
30499
30507
  {
@@ -31635,15 +31643,22 @@ function PlatformerCanvas({
31635
31643
  const eventBus = useEventBus();
31636
31644
  const keysRef = React98.useRef(/* @__PURE__ */ new Set());
31637
31645
  const imageCache = React98.useRef(/* @__PURE__ */ new Map());
31646
+ const [loadedImages, setLoadedImages] = React98.useState(/* @__PURE__ */ new Set());
31638
31647
  const loadImage = React98.useCallback((url) => {
31639
31648
  const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
31640
31649
  const cached = imageCache.current.get(fullUrl);
31641
- if (cached?.complete && cached.naturalWidth > 0) return cached;
31650
+ if (cached?.complete && cached.naturalWidth > 0) {
31651
+ if (!loadedImages.has(fullUrl)) {
31652
+ setLoadedImages((prev) => new Set(prev).add(fullUrl));
31653
+ }
31654
+ return cached;
31655
+ }
31642
31656
  if (!cached) {
31643
31657
  const img = new Image();
31644
31658
  img.crossOrigin = "anonymous";
31645
31659
  img.src = fullUrl;
31646
31660
  img.onload = () => {
31661
+ setLoadedImages((prev) => new Set(prev).add(fullUrl));
31647
31662
  updateAssetStatus(fullUrl, "loaded");
31648
31663
  };
31649
31664
  img.onerror = () => {
@@ -31653,7 +31668,7 @@ function PlatformerCanvas({
31653
31668
  updateAssetStatus(fullUrl, "pending");
31654
31669
  }
31655
31670
  return null;
31656
- }, [assetBaseUrl]);
31671
+ }, [assetBaseUrl, loadedImages]);
31657
31672
  React98.useEffect(() => {
31658
31673
  if (typeof window === "undefined") return;
31659
31674
  const canvas = canvasRef.current;
@@ -31835,7 +31850,7 @@ function PlatformerCanvas({
31835
31850
  ctx.arc(ppx + eyeOffsetX + 7, eyeY, eyeSize, 0, Math.PI * 2);
31836
31851
  ctx.fill();
31837
31852
  }
31838
- });
31853
+ }, [player, platforms, worldWidth, worldHeight, canvasWidth, canvasHeight, followCamera, bgColor, playerSprite, tileSprites, backgroundImage, assetBaseUrl, loadedImages]);
31839
31854
  return /* @__PURE__ */ jsxRuntime.jsx(
31840
31855
  "canvas",
31841
31856
  {
@@ -33031,10 +33046,13 @@ function TableView({
33031
33046
  }
33032
33047
  const lk = LOOKS[look];
33033
33048
  const hasActions = Boolean(itemActions && itemActions.length > 0);
33049
+ const inlineActionCount = hasActions ? maxInlineActions != null ? Math.min(itemActions.length, maxInlineActions) : itemActions.length : 0;
33050
+ const hasOverflowActions = hasActions && maxInlineActions != null && itemActions.length > maxInlineActions;
33051
+ const actionsTrack = hasActions ? `${inlineActionCount * 6 + (hasOverflowActions ? 3 : 0)}rem` : null;
33034
33052
  const gridTemplateColumns = [
33035
33053
  selectable ? "auto" : null,
33036
33054
  ...colDefs.map((c) => c.width ?? "minmax(0, 1fr)"),
33037
- hasActions ? "auto" : null
33055
+ actionsTrack
33038
33056
  ].filter(Boolean).join(" ");
33039
33057
  const header = /* @__PURE__ */ jsxRuntime.jsxs(
33040
33058
  Box,
@@ -33121,7 +33139,7 @@ function TableView({
33121
33139
  }
33122
33140
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
33123
33141
  }),
33124
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: [
33142
+ itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "justify-end flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: [
33125
33143
  (maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions).map((action, i) => /* @__PURE__ */ jsxRuntime.jsxs(
33126
33144
  Button,
33127
33145
  {
package/dist/avl/index.js CHANGED
@@ -14570,7 +14570,7 @@ var init_MapView = __esm({
14570
14570
  shadowSize: [41, 41]
14571
14571
  });
14572
14572
  L.Marker.prototype.options.icon = defaultIcon;
14573
- const { useEffect: useEffect89, useRef: useRef88, useCallback: useCallback130, useState: useState124 } = React98__default;
14573
+ const { useEffect: useEffect89, useRef: useRef88, useCallback: useCallback130, useState: useState125 } = React98__default;
14574
14574
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
14575
14575
  const { useEventBus: useEventBus3 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
14576
14576
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -14615,7 +14615,7 @@ var init_MapView = __esm({
14615
14615
  showAttribution = true
14616
14616
  }) {
14617
14617
  const eventBus = useEventBus3();
14618
- const [clickedPosition, setClickedPosition] = useState124(null);
14618
+ const [clickedPosition, setClickedPosition] = useState125(null);
14619
14619
  const handleMapClick = useCallback130((lat, lng) => {
14620
14620
  if (showClickedPin) {
14621
14621
  setClickedPosition({ lat, lng });
@@ -30392,8 +30392,16 @@ function GameCanvas2D({
30392
30392
  drawEventRef.current = drawEvent;
30393
30393
  const emitRef = React98.useRef(emit);
30394
30394
  emitRef.current = emit;
30395
+ const assetBaseUrlRef = React98.useRef(assetBaseUrl);
30396
+ assetBaseUrlRef.current = assetBaseUrl;
30397
+ const backgroundImageRef = React98.useRef(backgroundImage);
30398
+ backgroundImageRef.current = backgroundImage;
30399
+ const widthRef = React98.useRef(width);
30400
+ widthRef.current = width;
30401
+ const heightRef = React98.useRef(height);
30402
+ heightRef.current = height;
30395
30403
  const loadImage = React98.useCallback((url) => {
30396
- const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
30404
+ const fullUrl = url.startsWith("http") ? url : `${assetBaseUrlRef.current}${url}`;
30397
30405
  const cached = imageCache.current.get(fullUrl);
30398
30406
  if (cached?.complete && cached.naturalWidth > 0) return cached;
30399
30407
  if (!cached) {
@@ -30403,7 +30411,7 @@ function GameCanvas2D({
30403
30411
  imageCache.current.set(fullUrl, img);
30404
30412
  }
30405
30413
  return null;
30406
- }, [assetBaseUrl]);
30414
+ }, []);
30407
30415
  React98.useEffect(() => {
30408
30416
  const canvas = canvasRef.current;
30409
30417
  if (!canvas) return;
@@ -30425,10 +30433,10 @@ function GameCanvas2D({
30425
30433
  if (tickEventRef.current) {
30426
30434
  emitRef.current(tickEventRef.current, { dt, frame });
30427
30435
  }
30428
- if (backgroundImage) {
30429
- const bgImg = loadImage(backgroundImage);
30436
+ if (backgroundImageRef.current) {
30437
+ const bgImg = loadImage(backgroundImageRef.current);
30430
30438
  if (bgImg) {
30431
- ctx.drawImage(bgImg, 0, 0, width, height);
30439
+ ctx.drawImage(bgImg, 0, 0, widthRef.current, heightRef.current);
30432
30440
  }
30433
30441
  }
30434
30442
  onDrawRef.current?.(ctx, frame);
@@ -30444,7 +30452,7 @@ function GameCanvas2D({
30444
30452
  running = false;
30445
30453
  cancelAnimationFrame(rafRef.current);
30446
30454
  };
30447
- }, [fps]);
30455
+ }, [fps, loadImage]);
30448
30456
  return /* @__PURE__ */ jsx(Box, { className: cn("inline-block", className), children: /* @__PURE__ */ jsx(
30449
30457
  "canvas",
30450
30458
  {
@@ -31586,15 +31594,22 @@ function PlatformerCanvas({
31586
31594
  const eventBus = useEventBus();
31587
31595
  const keysRef = useRef(/* @__PURE__ */ new Set());
31588
31596
  const imageCache = useRef(/* @__PURE__ */ new Map());
31597
+ const [loadedImages, setLoadedImages] = useState(/* @__PURE__ */ new Set());
31589
31598
  const loadImage = useCallback((url) => {
31590
31599
  const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
31591
31600
  const cached = imageCache.current.get(fullUrl);
31592
- if (cached?.complete && cached.naturalWidth > 0) return cached;
31601
+ if (cached?.complete && cached.naturalWidth > 0) {
31602
+ if (!loadedImages.has(fullUrl)) {
31603
+ setLoadedImages((prev) => new Set(prev).add(fullUrl));
31604
+ }
31605
+ return cached;
31606
+ }
31593
31607
  if (!cached) {
31594
31608
  const img = new Image();
31595
31609
  img.crossOrigin = "anonymous";
31596
31610
  img.src = fullUrl;
31597
31611
  img.onload = () => {
31612
+ setLoadedImages((prev) => new Set(prev).add(fullUrl));
31598
31613
  updateAssetStatus(fullUrl, "loaded");
31599
31614
  };
31600
31615
  img.onerror = () => {
@@ -31604,7 +31619,7 @@ function PlatformerCanvas({
31604
31619
  updateAssetStatus(fullUrl, "pending");
31605
31620
  }
31606
31621
  return null;
31607
- }, [assetBaseUrl]);
31622
+ }, [assetBaseUrl, loadedImages]);
31608
31623
  useEffect(() => {
31609
31624
  if (typeof window === "undefined") return;
31610
31625
  const canvas = canvasRef.current;
@@ -31786,7 +31801,7 @@ function PlatformerCanvas({
31786
31801
  ctx.arc(ppx + eyeOffsetX + 7, eyeY, eyeSize, 0, Math.PI * 2);
31787
31802
  ctx.fill();
31788
31803
  }
31789
- });
31804
+ }, [player, platforms, worldWidth, worldHeight, canvasWidth, canvasHeight, followCamera, bgColor, playerSprite, tileSprites, backgroundImage, assetBaseUrl, loadedImages]);
31790
31805
  return /* @__PURE__ */ jsx(
31791
31806
  "canvas",
31792
31807
  {
@@ -32982,10 +32997,13 @@ function TableView({
32982
32997
  }
32983
32998
  const lk = LOOKS[look];
32984
32999
  const hasActions = Boolean(itemActions && itemActions.length > 0);
33000
+ const inlineActionCount = hasActions ? maxInlineActions != null ? Math.min(itemActions.length, maxInlineActions) : itemActions.length : 0;
33001
+ const hasOverflowActions = hasActions && maxInlineActions != null && itemActions.length > maxInlineActions;
33002
+ const actionsTrack = hasActions ? `${inlineActionCount * 6 + (hasOverflowActions ? 3 : 0)}rem` : null;
32985
33003
  const gridTemplateColumns = [
32986
33004
  selectable ? "auto" : null,
32987
33005
  ...colDefs.map((c) => c.width ?? "minmax(0, 1fr)"),
32988
- hasActions ? "auto" : null
33006
+ actionsTrack
32989
33007
  ].filter(Boolean).join(" ");
32990
33008
  const header = /* @__PURE__ */ jsxs(
32991
33009
  Box,
@@ -33072,7 +33090,7 @@ function TableView({
33072
33090
  }
33073
33091
  return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
33074
33092
  }),
33075
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: [
33093
+ itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "justify-end flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: [
33076
33094
  (maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions).map((action, i) => /* @__PURE__ */ jsxs(
33077
33095
  Button,
33078
33096
  {
@@ -8676,7 +8676,7 @@ var init_MapView = __esm({
8676
8676
  shadowSize: [41, 41]
8677
8677
  });
8678
8678
  L.Marker.prototype.options.icon = defaultIcon;
8679
- const { useEffect: useEffect72, useRef: useRef66, useCallback: useCallback128, useState: useState110 } = React80__namespace.default;
8679
+ const { useEffect: useEffect72, useRef: useRef66, useCallback: useCallback128, useState: useState111 } = React80__namespace.default;
8680
8680
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
8681
8681
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
8682
8682
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -8721,7 +8721,7 @@ var init_MapView = __esm({
8721
8721
  showAttribution = true
8722
8722
  }) {
8723
8723
  const eventBus = useEventBus2();
8724
- const [clickedPosition, setClickedPosition] = useState110(null);
8724
+ const [clickedPosition, setClickedPosition] = useState111(null);
8725
8725
  const handleMapClick = useCallback128((lat, lng) => {
8726
8726
  if (showClickedPin) {
8727
8727
  setClickedPosition({ lat, lng });
@@ -25826,8 +25826,16 @@ function GameCanvas2D({
25826
25826
  drawEventRef.current = drawEvent;
25827
25827
  const emitRef = React80__namespace.useRef(emit);
25828
25828
  emitRef.current = emit;
25829
+ const assetBaseUrlRef = React80__namespace.useRef(assetBaseUrl);
25830
+ assetBaseUrlRef.current = assetBaseUrl;
25831
+ const backgroundImageRef = React80__namespace.useRef(backgroundImage);
25832
+ backgroundImageRef.current = backgroundImage;
25833
+ const widthRef = React80__namespace.useRef(width);
25834
+ widthRef.current = width;
25835
+ const heightRef = React80__namespace.useRef(height);
25836
+ heightRef.current = height;
25829
25837
  const loadImage = React80__namespace.useCallback((url) => {
25830
- const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
25838
+ const fullUrl = url.startsWith("http") ? url : `${assetBaseUrlRef.current}${url}`;
25831
25839
  const cached = imageCache.current.get(fullUrl);
25832
25840
  if (cached?.complete && cached.naturalWidth > 0) return cached;
25833
25841
  if (!cached) {
@@ -25837,7 +25845,7 @@ function GameCanvas2D({
25837
25845
  imageCache.current.set(fullUrl, img);
25838
25846
  }
25839
25847
  return null;
25840
- }, [assetBaseUrl]);
25848
+ }, []);
25841
25849
  React80__namespace.useEffect(() => {
25842
25850
  const canvas = canvasRef.current;
25843
25851
  if (!canvas) return;
@@ -25859,10 +25867,10 @@ function GameCanvas2D({
25859
25867
  if (tickEventRef.current) {
25860
25868
  emitRef.current(tickEventRef.current, { dt, frame });
25861
25869
  }
25862
- if (backgroundImage) {
25863
- const bgImg = loadImage(backgroundImage);
25870
+ if (backgroundImageRef.current) {
25871
+ const bgImg = loadImage(backgroundImageRef.current);
25864
25872
  if (bgImg) {
25865
- ctx.drawImage(bgImg, 0, 0, width, height);
25873
+ ctx.drawImage(bgImg, 0, 0, widthRef.current, heightRef.current);
25866
25874
  }
25867
25875
  }
25868
25876
  onDrawRef.current?.(ctx, frame);
@@ -25878,7 +25886,7 @@ function GameCanvas2D({
25878
25886
  running = false;
25879
25887
  cancelAnimationFrame(rafRef.current);
25880
25888
  };
25881
- }, [fps]);
25889
+ }, [fps, loadImage]);
25882
25890
  return /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: cn("inline-block", className), children: /* @__PURE__ */ jsxRuntime.jsx(
25883
25891
  "canvas",
25884
25892
  {
@@ -27072,15 +27080,22 @@ function PlatformerCanvas({
27072
27080
  const eventBus = useEventBus();
27073
27081
  const keysRef = React80.useRef(/* @__PURE__ */ new Set());
27074
27082
  const imageCache = React80.useRef(/* @__PURE__ */ new Map());
27083
+ const [loadedImages, setLoadedImages] = React80.useState(/* @__PURE__ */ new Set());
27075
27084
  const loadImage = React80.useCallback((url) => {
27076
27085
  const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
27077
27086
  const cached = imageCache.current.get(fullUrl);
27078
- if (cached?.complete && cached.naturalWidth > 0) return cached;
27087
+ if (cached?.complete && cached.naturalWidth > 0) {
27088
+ if (!loadedImages.has(fullUrl)) {
27089
+ setLoadedImages((prev) => new Set(prev).add(fullUrl));
27090
+ }
27091
+ return cached;
27092
+ }
27079
27093
  if (!cached) {
27080
27094
  const img = new Image();
27081
27095
  img.crossOrigin = "anonymous";
27082
27096
  img.src = fullUrl;
27083
27097
  img.onload = () => {
27098
+ setLoadedImages((prev) => new Set(prev).add(fullUrl));
27084
27099
  updateAssetStatus(fullUrl, "loaded");
27085
27100
  };
27086
27101
  img.onerror = () => {
@@ -27090,7 +27105,7 @@ function PlatformerCanvas({
27090
27105
  updateAssetStatus(fullUrl, "pending");
27091
27106
  }
27092
27107
  return null;
27093
- }, [assetBaseUrl]);
27108
+ }, [assetBaseUrl, loadedImages]);
27094
27109
  React80.useEffect(() => {
27095
27110
  if (typeof window === "undefined") return;
27096
27111
  const canvas = canvasRef.current;
@@ -27272,7 +27287,7 @@ function PlatformerCanvas({
27272
27287
  ctx.arc(ppx + eyeOffsetX + 7, eyeY, eyeSize, 0, Math.PI * 2);
27273
27288
  ctx.fill();
27274
27289
  }
27275
- });
27290
+ }, [player, platforms, worldWidth, worldHeight, canvasWidth, canvasHeight, followCamera, bgColor, playerSprite, tileSprites, backgroundImage, assetBaseUrl, loadedImages]);
27276
27291
  return /* @__PURE__ */ jsxRuntime.jsx(
27277
27292
  "canvas",
27278
27293
  {
@@ -28490,10 +28505,13 @@ function TableView({
28490
28505
  }
28491
28506
  const lk = LOOKS[look];
28492
28507
  const hasActions = Boolean(itemActions && itemActions.length > 0);
28508
+ const inlineActionCount = hasActions ? maxInlineActions != null ? Math.min(itemActions.length, maxInlineActions) : itemActions.length : 0;
28509
+ const hasOverflowActions = hasActions && maxInlineActions != null && itemActions.length > maxInlineActions;
28510
+ const actionsTrack = hasActions ? `${inlineActionCount * 6 + (hasOverflowActions ? 3 : 0)}rem` : null;
28493
28511
  const gridTemplateColumns = [
28494
28512
  selectable ? "auto" : null,
28495
28513
  ...colDefs.map((c) => c.width ?? "minmax(0, 1fr)"),
28496
- hasActions ? "auto" : null
28514
+ actionsTrack
28497
28515
  ].filter(Boolean).join(" ");
28498
28516
  const header = /* @__PURE__ */ jsxRuntime.jsxs(
28499
28517
  exports.Box,
@@ -28580,7 +28598,7 @@ function TableView({
28580
28598
  }
28581
28599
  return /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
28582
28600
  }),
28583
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", className: "flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: [
28601
+ itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", className: "justify-end flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: [
28584
28602
  (maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions).map((action, i) => /* @__PURE__ */ jsxRuntime.jsxs(
28585
28603
  exports.Button,
28586
28604
  {
@@ -8627,7 +8627,7 @@ var init_MapView = __esm({
8627
8627
  shadowSize: [41, 41]
8628
8628
  });
8629
8629
  L.Marker.prototype.options.icon = defaultIcon;
8630
- const { useEffect: useEffect72, useRef: useRef66, useCallback: useCallback128, useState: useState110 } = React80__default;
8630
+ const { useEffect: useEffect72, useRef: useRef66, useCallback: useCallback128, useState: useState111 } = React80__default;
8631
8631
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
8632
8632
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
8633
8633
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -8672,7 +8672,7 @@ var init_MapView = __esm({
8672
8672
  showAttribution = true
8673
8673
  }) {
8674
8674
  const eventBus = useEventBus2();
8675
- const [clickedPosition, setClickedPosition] = useState110(null);
8675
+ const [clickedPosition, setClickedPosition] = useState111(null);
8676
8676
  const handleMapClick = useCallback128((lat, lng) => {
8677
8677
  if (showClickedPin) {
8678
8678
  setClickedPosition({ lat, lng });
@@ -25777,8 +25777,16 @@ function GameCanvas2D({
25777
25777
  drawEventRef.current = drawEvent;
25778
25778
  const emitRef = React80.useRef(emit);
25779
25779
  emitRef.current = emit;
25780
+ const assetBaseUrlRef = React80.useRef(assetBaseUrl);
25781
+ assetBaseUrlRef.current = assetBaseUrl;
25782
+ const backgroundImageRef = React80.useRef(backgroundImage);
25783
+ backgroundImageRef.current = backgroundImage;
25784
+ const widthRef = React80.useRef(width);
25785
+ widthRef.current = width;
25786
+ const heightRef = React80.useRef(height);
25787
+ heightRef.current = height;
25780
25788
  const loadImage = React80.useCallback((url) => {
25781
- const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
25789
+ const fullUrl = url.startsWith("http") ? url : `${assetBaseUrlRef.current}${url}`;
25782
25790
  const cached = imageCache.current.get(fullUrl);
25783
25791
  if (cached?.complete && cached.naturalWidth > 0) return cached;
25784
25792
  if (!cached) {
@@ -25788,7 +25796,7 @@ function GameCanvas2D({
25788
25796
  imageCache.current.set(fullUrl, img);
25789
25797
  }
25790
25798
  return null;
25791
- }, [assetBaseUrl]);
25799
+ }, []);
25792
25800
  React80.useEffect(() => {
25793
25801
  const canvas = canvasRef.current;
25794
25802
  if (!canvas) return;
@@ -25810,10 +25818,10 @@ function GameCanvas2D({
25810
25818
  if (tickEventRef.current) {
25811
25819
  emitRef.current(tickEventRef.current, { dt, frame });
25812
25820
  }
25813
- if (backgroundImage) {
25814
- const bgImg = loadImage(backgroundImage);
25821
+ if (backgroundImageRef.current) {
25822
+ const bgImg = loadImage(backgroundImageRef.current);
25815
25823
  if (bgImg) {
25816
- ctx.drawImage(bgImg, 0, 0, width, height);
25824
+ ctx.drawImage(bgImg, 0, 0, widthRef.current, heightRef.current);
25817
25825
  }
25818
25826
  }
25819
25827
  onDrawRef.current?.(ctx, frame);
@@ -25829,7 +25837,7 @@ function GameCanvas2D({
25829
25837
  running = false;
25830
25838
  cancelAnimationFrame(rafRef.current);
25831
25839
  };
25832
- }, [fps]);
25840
+ }, [fps, loadImage]);
25833
25841
  return /* @__PURE__ */ jsx(Box, { className: cn("inline-block", className), children: /* @__PURE__ */ jsx(
25834
25842
  "canvas",
25835
25843
  {
@@ -27023,15 +27031,22 @@ function PlatformerCanvas({
27023
27031
  const eventBus = useEventBus();
27024
27032
  const keysRef = useRef(/* @__PURE__ */ new Set());
27025
27033
  const imageCache = useRef(/* @__PURE__ */ new Map());
27034
+ const [loadedImages, setLoadedImages] = useState(/* @__PURE__ */ new Set());
27026
27035
  const loadImage = useCallback((url) => {
27027
27036
  const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
27028
27037
  const cached = imageCache.current.get(fullUrl);
27029
- if (cached?.complete && cached.naturalWidth > 0) return cached;
27038
+ if (cached?.complete && cached.naturalWidth > 0) {
27039
+ if (!loadedImages.has(fullUrl)) {
27040
+ setLoadedImages((prev) => new Set(prev).add(fullUrl));
27041
+ }
27042
+ return cached;
27043
+ }
27030
27044
  if (!cached) {
27031
27045
  const img = new Image();
27032
27046
  img.crossOrigin = "anonymous";
27033
27047
  img.src = fullUrl;
27034
27048
  img.onload = () => {
27049
+ setLoadedImages((prev) => new Set(prev).add(fullUrl));
27035
27050
  updateAssetStatus(fullUrl, "loaded");
27036
27051
  };
27037
27052
  img.onerror = () => {
@@ -27041,7 +27056,7 @@ function PlatformerCanvas({
27041
27056
  updateAssetStatus(fullUrl, "pending");
27042
27057
  }
27043
27058
  return null;
27044
- }, [assetBaseUrl]);
27059
+ }, [assetBaseUrl, loadedImages]);
27045
27060
  useEffect(() => {
27046
27061
  if (typeof window === "undefined") return;
27047
27062
  const canvas = canvasRef.current;
@@ -27223,7 +27238,7 @@ function PlatformerCanvas({
27223
27238
  ctx.arc(ppx + eyeOffsetX + 7, eyeY, eyeSize, 0, Math.PI * 2);
27224
27239
  ctx.fill();
27225
27240
  }
27226
- });
27241
+ }, [player, platforms, worldWidth, worldHeight, canvasWidth, canvasHeight, followCamera, bgColor, playerSprite, tileSprites, backgroundImage, assetBaseUrl, loadedImages]);
27227
27242
  return /* @__PURE__ */ jsx(
27228
27243
  "canvas",
27229
27244
  {
@@ -28441,10 +28456,13 @@ function TableView({
28441
28456
  }
28442
28457
  const lk = LOOKS[look];
28443
28458
  const hasActions = Boolean(itemActions && itemActions.length > 0);
28459
+ const inlineActionCount = hasActions ? maxInlineActions != null ? Math.min(itemActions.length, maxInlineActions) : itemActions.length : 0;
28460
+ const hasOverflowActions = hasActions && maxInlineActions != null && itemActions.length > maxInlineActions;
28461
+ const actionsTrack = hasActions ? `${inlineActionCount * 6 + (hasOverflowActions ? 3 : 0)}rem` : null;
28444
28462
  const gridTemplateColumns = [
28445
28463
  selectable ? "auto" : null,
28446
28464
  ...colDefs.map((c) => c.width ?? "minmax(0, 1fr)"),
28447
- hasActions ? "auto" : null
28465
+ actionsTrack
28448
28466
  ].filter(Boolean).join(" ");
28449
28467
  const header = /* @__PURE__ */ jsxs(
28450
28468
  Box,
@@ -28531,7 +28549,7 @@ function TableView({
28531
28549
  }
28532
28550
  return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
28533
28551
  }),
28534
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: [
28552
+ itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "justify-end flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: [
28535
28553
  (maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions).map((action, i) => /* @__PURE__ */ jsxs(
28536
28554
  Button,
28537
28555
  {
@@ -10244,7 +10244,7 @@ var init_MapView = __esm({
10244
10244
  shadowSize: [41, 41]
10245
10245
  });
10246
10246
  L.Marker.prototype.options.icon = defaultIcon;
10247
- const { useEffect: useEffect69, useRef: useRef65, useCallback: useCallback114, useState: useState99 } = React86__namespace.default;
10247
+ const { useEffect: useEffect69, useRef: useRef65, useCallback: useCallback114, useState: useState100 } = React86__namespace.default;
10248
10248
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
10249
10249
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
10250
10250
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -10289,7 +10289,7 @@ var init_MapView = __esm({
10289
10289
  showAttribution = true
10290
10290
  }) {
10291
10291
  const eventBus = useEventBus2();
10292
- const [clickedPosition, setClickedPosition] = useState99(null);
10292
+ const [clickedPosition, setClickedPosition] = useState100(null);
10293
10293
  const handleMapClick = useCallback114((lat, lng) => {
10294
10294
  if (showClickedPin) {
10295
10295
  setClickedPosition({ lat, lng });
@@ -26853,8 +26853,16 @@ function GameCanvas2D({
26853
26853
  drawEventRef.current = drawEvent;
26854
26854
  const emitRef = React86__namespace.useRef(emit);
26855
26855
  emitRef.current = emit;
26856
+ const assetBaseUrlRef = React86__namespace.useRef(assetBaseUrl);
26857
+ assetBaseUrlRef.current = assetBaseUrl;
26858
+ const backgroundImageRef = React86__namespace.useRef(backgroundImage);
26859
+ backgroundImageRef.current = backgroundImage;
26860
+ const widthRef = React86__namespace.useRef(width);
26861
+ widthRef.current = width;
26862
+ const heightRef = React86__namespace.useRef(height);
26863
+ heightRef.current = height;
26856
26864
  const loadImage = React86__namespace.useCallback((url) => {
26857
- const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
26865
+ const fullUrl = url.startsWith("http") ? url : `${assetBaseUrlRef.current}${url}`;
26858
26866
  const cached = imageCache.current.get(fullUrl);
26859
26867
  if (cached?.complete && cached.naturalWidth > 0) return cached;
26860
26868
  if (!cached) {
@@ -26864,7 +26872,7 @@ function GameCanvas2D({
26864
26872
  imageCache.current.set(fullUrl, img);
26865
26873
  }
26866
26874
  return null;
26867
- }, [assetBaseUrl]);
26875
+ }, []);
26868
26876
  React86__namespace.useEffect(() => {
26869
26877
  const canvas = canvasRef.current;
26870
26878
  if (!canvas) return;
@@ -26886,10 +26894,10 @@ function GameCanvas2D({
26886
26894
  if (tickEventRef.current) {
26887
26895
  emitRef.current(tickEventRef.current, { dt, frame });
26888
26896
  }
26889
- if (backgroundImage) {
26890
- const bgImg = loadImage(backgroundImage);
26897
+ if (backgroundImageRef.current) {
26898
+ const bgImg = loadImage(backgroundImageRef.current);
26891
26899
  if (bgImg) {
26892
- ctx.drawImage(bgImg, 0, 0, width, height);
26900
+ ctx.drawImage(bgImg, 0, 0, widthRef.current, heightRef.current);
26893
26901
  }
26894
26902
  }
26895
26903
  onDrawRef.current?.(ctx, frame);
@@ -26905,7 +26913,7 @@ function GameCanvas2D({
26905
26913
  running = false;
26906
26914
  cancelAnimationFrame(rafRef.current);
26907
26915
  };
26908
- }, [fps]);
26916
+ }, [fps, loadImage]);
26909
26917
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: cn("inline-block", className), children: /* @__PURE__ */ jsxRuntime.jsx(
26910
26918
  "canvas",
26911
26919
  {
@@ -28047,15 +28055,22 @@ function PlatformerCanvas({
28047
28055
  const eventBus = useEventBus();
28048
28056
  const keysRef = React86.useRef(/* @__PURE__ */ new Set());
28049
28057
  const imageCache = React86.useRef(/* @__PURE__ */ new Map());
28058
+ const [loadedImages, setLoadedImages] = React86.useState(/* @__PURE__ */ new Set());
28050
28059
  const loadImage = React86.useCallback((url) => {
28051
28060
  const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
28052
28061
  const cached = imageCache.current.get(fullUrl);
28053
- if (cached?.complete && cached.naturalWidth > 0) return cached;
28062
+ if (cached?.complete && cached.naturalWidth > 0) {
28063
+ if (!loadedImages.has(fullUrl)) {
28064
+ setLoadedImages((prev) => new Set(prev).add(fullUrl));
28065
+ }
28066
+ return cached;
28067
+ }
28054
28068
  if (!cached) {
28055
28069
  const img = new Image();
28056
28070
  img.crossOrigin = "anonymous";
28057
28071
  img.src = fullUrl;
28058
28072
  img.onload = () => {
28073
+ setLoadedImages((prev) => new Set(prev).add(fullUrl));
28059
28074
  updateAssetStatus(fullUrl, "loaded");
28060
28075
  };
28061
28076
  img.onerror = () => {
@@ -28065,7 +28080,7 @@ function PlatformerCanvas({
28065
28080
  updateAssetStatus(fullUrl, "pending");
28066
28081
  }
28067
28082
  return null;
28068
- }, [assetBaseUrl]);
28083
+ }, [assetBaseUrl, loadedImages]);
28069
28084
  React86.useEffect(() => {
28070
28085
  if (typeof window === "undefined") return;
28071
28086
  const canvas = canvasRef.current;
@@ -28247,7 +28262,7 @@ function PlatformerCanvas({
28247
28262
  ctx.arc(ppx + eyeOffsetX + 7, eyeY, eyeSize, 0, Math.PI * 2);
28248
28263
  ctx.fill();
28249
28264
  }
28250
- });
28265
+ }, [player, platforms, worldWidth, worldHeight, canvasWidth, canvasHeight, followCamera, bgColor, playerSprite, tileSprites, backgroundImage, assetBaseUrl, loadedImages]);
28251
28266
  return /* @__PURE__ */ jsxRuntime.jsx(
28252
28267
  "canvas",
28253
28268
  {
@@ -29443,10 +29458,13 @@ function TableView({
29443
29458
  }
29444
29459
  const lk = LOOKS[look];
29445
29460
  const hasActions = Boolean(itemActions && itemActions.length > 0);
29461
+ const inlineActionCount = hasActions ? maxInlineActions != null ? Math.min(itemActions.length, maxInlineActions) : itemActions.length : 0;
29462
+ const hasOverflowActions = hasActions && maxInlineActions != null && itemActions.length > maxInlineActions;
29463
+ const actionsTrack = hasActions ? `${inlineActionCount * 6 + (hasOverflowActions ? 3 : 0)}rem` : null;
29446
29464
  const gridTemplateColumns = [
29447
29465
  selectable ? "auto" : null,
29448
29466
  ...colDefs.map((c) => c.width ?? "minmax(0, 1fr)"),
29449
- hasActions ? "auto" : null
29467
+ actionsTrack
29450
29468
  ].filter(Boolean).join(" ");
29451
29469
  const header = /* @__PURE__ */ jsxRuntime.jsxs(
29452
29470
  Box,
@@ -29533,7 +29551,7 @@ function TableView({
29533
29551
  }
29534
29552
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
29535
29553
  }),
29536
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: [
29554
+ itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "justify-end flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: [
29537
29555
  (maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions).map((action, i) => /* @__PURE__ */ jsxRuntime.jsxs(
29538
29556
  Button,
29539
29557
  {
@@ -10195,7 +10195,7 @@ var init_MapView = __esm({
10195
10195
  shadowSize: [41, 41]
10196
10196
  });
10197
10197
  L.Marker.prototype.options.icon = defaultIcon;
10198
- const { useEffect: useEffect69, useRef: useRef65, useCallback: useCallback114, useState: useState99 } = React86__default;
10198
+ const { useEffect: useEffect69, useRef: useRef65, useCallback: useCallback114, useState: useState100 } = React86__default;
10199
10199
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
10200
10200
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
10201
10201
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -10240,7 +10240,7 @@ var init_MapView = __esm({
10240
10240
  showAttribution = true
10241
10241
  }) {
10242
10242
  const eventBus = useEventBus2();
10243
- const [clickedPosition, setClickedPosition] = useState99(null);
10243
+ const [clickedPosition, setClickedPosition] = useState100(null);
10244
10244
  const handleMapClick = useCallback114((lat, lng) => {
10245
10245
  if (showClickedPin) {
10246
10246
  setClickedPosition({ lat, lng });
@@ -26804,8 +26804,16 @@ function GameCanvas2D({
26804
26804
  drawEventRef.current = drawEvent;
26805
26805
  const emitRef = React86.useRef(emit);
26806
26806
  emitRef.current = emit;
26807
+ const assetBaseUrlRef = React86.useRef(assetBaseUrl);
26808
+ assetBaseUrlRef.current = assetBaseUrl;
26809
+ const backgroundImageRef = React86.useRef(backgroundImage);
26810
+ backgroundImageRef.current = backgroundImage;
26811
+ const widthRef = React86.useRef(width);
26812
+ widthRef.current = width;
26813
+ const heightRef = React86.useRef(height);
26814
+ heightRef.current = height;
26807
26815
  const loadImage = React86.useCallback((url) => {
26808
- const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
26816
+ const fullUrl = url.startsWith("http") ? url : `${assetBaseUrlRef.current}${url}`;
26809
26817
  const cached = imageCache.current.get(fullUrl);
26810
26818
  if (cached?.complete && cached.naturalWidth > 0) return cached;
26811
26819
  if (!cached) {
@@ -26815,7 +26823,7 @@ function GameCanvas2D({
26815
26823
  imageCache.current.set(fullUrl, img);
26816
26824
  }
26817
26825
  return null;
26818
- }, [assetBaseUrl]);
26826
+ }, []);
26819
26827
  React86.useEffect(() => {
26820
26828
  const canvas = canvasRef.current;
26821
26829
  if (!canvas) return;
@@ -26837,10 +26845,10 @@ function GameCanvas2D({
26837
26845
  if (tickEventRef.current) {
26838
26846
  emitRef.current(tickEventRef.current, { dt, frame });
26839
26847
  }
26840
- if (backgroundImage) {
26841
- const bgImg = loadImage(backgroundImage);
26848
+ if (backgroundImageRef.current) {
26849
+ const bgImg = loadImage(backgroundImageRef.current);
26842
26850
  if (bgImg) {
26843
- ctx.drawImage(bgImg, 0, 0, width, height);
26851
+ ctx.drawImage(bgImg, 0, 0, widthRef.current, heightRef.current);
26844
26852
  }
26845
26853
  }
26846
26854
  onDrawRef.current?.(ctx, frame);
@@ -26856,7 +26864,7 @@ function GameCanvas2D({
26856
26864
  running = false;
26857
26865
  cancelAnimationFrame(rafRef.current);
26858
26866
  };
26859
- }, [fps]);
26867
+ }, [fps, loadImage]);
26860
26868
  return /* @__PURE__ */ jsx(Box, { className: cn("inline-block", className), children: /* @__PURE__ */ jsx(
26861
26869
  "canvas",
26862
26870
  {
@@ -27998,15 +28006,22 @@ function PlatformerCanvas({
27998
28006
  const eventBus = useEventBus();
27999
28007
  const keysRef = useRef(/* @__PURE__ */ new Set());
28000
28008
  const imageCache = useRef(/* @__PURE__ */ new Map());
28009
+ const [loadedImages, setLoadedImages] = useState(/* @__PURE__ */ new Set());
28001
28010
  const loadImage = useCallback((url) => {
28002
28011
  const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
28003
28012
  const cached = imageCache.current.get(fullUrl);
28004
- if (cached?.complete && cached.naturalWidth > 0) return cached;
28013
+ if (cached?.complete && cached.naturalWidth > 0) {
28014
+ if (!loadedImages.has(fullUrl)) {
28015
+ setLoadedImages((prev) => new Set(prev).add(fullUrl));
28016
+ }
28017
+ return cached;
28018
+ }
28005
28019
  if (!cached) {
28006
28020
  const img = new Image();
28007
28021
  img.crossOrigin = "anonymous";
28008
28022
  img.src = fullUrl;
28009
28023
  img.onload = () => {
28024
+ setLoadedImages((prev) => new Set(prev).add(fullUrl));
28010
28025
  updateAssetStatus(fullUrl, "loaded");
28011
28026
  };
28012
28027
  img.onerror = () => {
@@ -28016,7 +28031,7 @@ function PlatformerCanvas({
28016
28031
  updateAssetStatus(fullUrl, "pending");
28017
28032
  }
28018
28033
  return null;
28019
- }, [assetBaseUrl]);
28034
+ }, [assetBaseUrl, loadedImages]);
28020
28035
  useEffect(() => {
28021
28036
  if (typeof window === "undefined") return;
28022
28037
  const canvas = canvasRef.current;
@@ -28198,7 +28213,7 @@ function PlatformerCanvas({
28198
28213
  ctx.arc(ppx + eyeOffsetX + 7, eyeY, eyeSize, 0, Math.PI * 2);
28199
28214
  ctx.fill();
28200
28215
  }
28201
- });
28216
+ }, [player, platforms, worldWidth, worldHeight, canvasWidth, canvasHeight, followCamera, bgColor, playerSprite, tileSprites, backgroundImage, assetBaseUrl, loadedImages]);
28202
28217
  return /* @__PURE__ */ jsx(
28203
28218
  "canvas",
28204
28219
  {
@@ -29394,10 +29409,13 @@ function TableView({
29394
29409
  }
29395
29410
  const lk = LOOKS[look];
29396
29411
  const hasActions = Boolean(itemActions && itemActions.length > 0);
29412
+ const inlineActionCount = hasActions ? maxInlineActions != null ? Math.min(itemActions.length, maxInlineActions) : itemActions.length : 0;
29413
+ const hasOverflowActions = hasActions && maxInlineActions != null && itemActions.length > maxInlineActions;
29414
+ const actionsTrack = hasActions ? `${inlineActionCount * 6 + (hasOverflowActions ? 3 : 0)}rem` : null;
29397
29415
  const gridTemplateColumns = [
29398
29416
  selectable ? "auto" : null,
29399
29417
  ...colDefs.map((c) => c.width ?? "minmax(0, 1fr)"),
29400
- hasActions ? "auto" : null
29418
+ actionsTrack
29401
29419
  ].filter(Boolean).join(" ");
29402
29420
  const header = /* @__PURE__ */ jsxs(
29403
29421
  Box,
@@ -29484,7 +29502,7 @@ function TableView({
29484
29502
  }
29485
29503
  return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
29486
29504
  }),
29487
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: [
29505
+ itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "justify-end flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: [
29488
29506
  (maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions).map((action, i) => /* @__PURE__ */ jsxs(
29489
29507
  Button,
29490
29508
  {
@@ -10132,7 +10132,7 @@ var init_MapView = __esm({
10132
10132
  shadowSize: [41, 41]
10133
10133
  });
10134
10134
  L.Marker.prototype.options.icon = defaultIcon;
10135
- const { useEffect: useEffect70, useRef: useRef65, useCallback: useCallback114, useState: useState102 } = React85__namespace.default;
10135
+ const { useEffect: useEffect70, useRef: useRef65, useCallback: useCallback114, useState: useState103 } = React85__namespace.default;
10136
10136
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
10137
10137
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
10138
10138
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -10177,7 +10177,7 @@ var init_MapView = __esm({
10177
10177
  showAttribution = true
10178
10178
  }) {
10179
10179
  const eventBus = useEventBus2();
10180
- const [clickedPosition, setClickedPosition] = useState102(null);
10180
+ const [clickedPosition, setClickedPosition] = useState103(null);
10181
10181
  const handleMapClick = useCallback114((lat, lng) => {
10182
10182
  if (showClickedPin) {
10183
10183
  setClickedPosition({ lat, lng });
@@ -26558,8 +26558,16 @@ function GameCanvas2D({
26558
26558
  drawEventRef.current = drawEvent;
26559
26559
  const emitRef = React85__namespace.useRef(emit);
26560
26560
  emitRef.current = emit;
26561
+ const assetBaseUrlRef = React85__namespace.useRef(assetBaseUrl);
26562
+ assetBaseUrlRef.current = assetBaseUrl;
26563
+ const backgroundImageRef = React85__namespace.useRef(backgroundImage);
26564
+ backgroundImageRef.current = backgroundImage;
26565
+ const widthRef = React85__namespace.useRef(width);
26566
+ widthRef.current = width;
26567
+ const heightRef = React85__namespace.useRef(height);
26568
+ heightRef.current = height;
26561
26569
  const loadImage = React85__namespace.useCallback((url) => {
26562
- const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
26570
+ const fullUrl = url.startsWith("http") ? url : `${assetBaseUrlRef.current}${url}`;
26563
26571
  const cached = imageCache.current.get(fullUrl);
26564
26572
  if (cached?.complete && cached.naturalWidth > 0) return cached;
26565
26573
  if (!cached) {
@@ -26569,7 +26577,7 @@ function GameCanvas2D({
26569
26577
  imageCache.current.set(fullUrl, img);
26570
26578
  }
26571
26579
  return null;
26572
- }, [assetBaseUrl]);
26580
+ }, []);
26573
26581
  React85__namespace.useEffect(() => {
26574
26582
  const canvas = canvasRef.current;
26575
26583
  if (!canvas) return;
@@ -26591,10 +26599,10 @@ function GameCanvas2D({
26591
26599
  if (tickEventRef.current) {
26592
26600
  emitRef.current(tickEventRef.current, { dt, frame });
26593
26601
  }
26594
- if (backgroundImage) {
26595
- const bgImg = loadImage(backgroundImage);
26602
+ if (backgroundImageRef.current) {
26603
+ const bgImg = loadImage(backgroundImageRef.current);
26596
26604
  if (bgImg) {
26597
- ctx.drawImage(bgImg, 0, 0, width, height);
26605
+ ctx.drawImage(bgImg, 0, 0, widthRef.current, heightRef.current);
26598
26606
  }
26599
26607
  }
26600
26608
  onDrawRef.current?.(ctx, frame);
@@ -26610,7 +26618,7 @@ function GameCanvas2D({
26610
26618
  running = false;
26611
26619
  cancelAnimationFrame(rafRef.current);
26612
26620
  };
26613
- }, [fps]);
26621
+ }, [fps, loadImage]);
26614
26622
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: cn("inline-block", className), children: /* @__PURE__ */ jsxRuntime.jsx(
26615
26623
  "canvas",
26616
26624
  {
@@ -27752,15 +27760,22 @@ function PlatformerCanvas({
27752
27760
  const eventBus = useEventBus();
27753
27761
  const keysRef = React85.useRef(/* @__PURE__ */ new Set());
27754
27762
  const imageCache = React85.useRef(/* @__PURE__ */ new Map());
27763
+ const [loadedImages, setLoadedImages] = React85.useState(/* @__PURE__ */ new Set());
27755
27764
  const loadImage = React85.useCallback((url) => {
27756
27765
  const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
27757
27766
  const cached = imageCache.current.get(fullUrl);
27758
- if (cached?.complete && cached.naturalWidth > 0) return cached;
27767
+ if (cached?.complete && cached.naturalWidth > 0) {
27768
+ if (!loadedImages.has(fullUrl)) {
27769
+ setLoadedImages((prev) => new Set(prev).add(fullUrl));
27770
+ }
27771
+ return cached;
27772
+ }
27759
27773
  if (!cached) {
27760
27774
  const img = new Image();
27761
27775
  img.crossOrigin = "anonymous";
27762
27776
  img.src = fullUrl;
27763
27777
  img.onload = () => {
27778
+ setLoadedImages((prev) => new Set(prev).add(fullUrl));
27764
27779
  updateAssetStatus(fullUrl, "loaded");
27765
27780
  };
27766
27781
  img.onerror = () => {
@@ -27770,7 +27785,7 @@ function PlatformerCanvas({
27770
27785
  updateAssetStatus(fullUrl, "pending");
27771
27786
  }
27772
27787
  return null;
27773
- }, [assetBaseUrl]);
27788
+ }, [assetBaseUrl, loadedImages]);
27774
27789
  React85.useEffect(() => {
27775
27790
  if (typeof window === "undefined") return;
27776
27791
  const canvas = canvasRef.current;
@@ -27952,7 +27967,7 @@ function PlatformerCanvas({
27952
27967
  ctx.arc(ppx + eyeOffsetX + 7, eyeY, eyeSize, 0, Math.PI * 2);
27953
27968
  ctx.fill();
27954
27969
  }
27955
- });
27970
+ }, [player, platforms, worldWidth, worldHeight, canvasWidth, canvasHeight, followCamera, bgColor, playerSprite, tileSprites, backgroundImage, assetBaseUrl, loadedImages]);
27956
27971
  return /* @__PURE__ */ jsxRuntime.jsx(
27957
27972
  "canvas",
27958
27973
  {
@@ -29148,10 +29163,13 @@ function TableView({
29148
29163
  }
29149
29164
  const lk = LOOKS[look];
29150
29165
  const hasActions = Boolean(itemActions && itemActions.length > 0);
29166
+ const inlineActionCount = hasActions ? maxInlineActions != null ? Math.min(itemActions.length, maxInlineActions) : itemActions.length : 0;
29167
+ const hasOverflowActions = hasActions && maxInlineActions != null && itemActions.length > maxInlineActions;
29168
+ const actionsTrack = hasActions ? `${inlineActionCount * 6 + (hasOverflowActions ? 3 : 0)}rem` : null;
29151
29169
  const gridTemplateColumns = [
29152
29170
  selectable ? "auto" : null,
29153
29171
  ...colDefs.map((c) => c.width ?? "minmax(0, 1fr)"),
29154
- hasActions ? "auto" : null
29172
+ actionsTrack
29155
29173
  ].filter(Boolean).join(" ");
29156
29174
  const header = /* @__PURE__ */ jsxRuntime.jsxs(
29157
29175
  Box,
@@ -29238,7 +29256,7 @@ function TableView({
29238
29256
  }
29239
29257
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
29240
29258
  }),
29241
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: [
29259
+ itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "justify-end flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: [
29242
29260
  (maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions).map((action, i) => /* @__PURE__ */ jsxRuntime.jsxs(
29243
29261
  Button,
29244
29262
  {
@@ -10083,7 +10083,7 @@ var init_MapView = __esm({
10083
10083
  shadowSize: [41, 41]
10084
10084
  });
10085
10085
  L.Marker.prototype.options.icon = defaultIcon;
10086
- const { useEffect: useEffect70, useRef: useRef65, useCallback: useCallback114, useState: useState102 } = React85__default;
10086
+ const { useEffect: useEffect70, useRef: useRef65, useCallback: useCallback114, useState: useState103 } = React85__default;
10087
10087
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
10088
10088
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
10089
10089
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -10128,7 +10128,7 @@ var init_MapView = __esm({
10128
10128
  showAttribution = true
10129
10129
  }) {
10130
10130
  const eventBus = useEventBus2();
10131
- const [clickedPosition, setClickedPosition] = useState102(null);
10131
+ const [clickedPosition, setClickedPosition] = useState103(null);
10132
10132
  const handleMapClick = useCallback114((lat, lng) => {
10133
10133
  if (showClickedPin) {
10134
10134
  setClickedPosition({ lat, lng });
@@ -26509,8 +26509,16 @@ function GameCanvas2D({
26509
26509
  drawEventRef.current = drawEvent;
26510
26510
  const emitRef = React85.useRef(emit);
26511
26511
  emitRef.current = emit;
26512
+ const assetBaseUrlRef = React85.useRef(assetBaseUrl);
26513
+ assetBaseUrlRef.current = assetBaseUrl;
26514
+ const backgroundImageRef = React85.useRef(backgroundImage);
26515
+ backgroundImageRef.current = backgroundImage;
26516
+ const widthRef = React85.useRef(width);
26517
+ widthRef.current = width;
26518
+ const heightRef = React85.useRef(height);
26519
+ heightRef.current = height;
26512
26520
  const loadImage = React85.useCallback((url) => {
26513
- const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
26521
+ const fullUrl = url.startsWith("http") ? url : `${assetBaseUrlRef.current}${url}`;
26514
26522
  const cached = imageCache.current.get(fullUrl);
26515
26523
  if (cached?.complete && cached.naturalWidth > 0) return cached;
26516
26524
  if (!cached) {
@@ -26520,7 +26528,7 @@ function GameCanvas2D({
26520
26528
  imageCache.current.set(fullUrl, img);
26521
26529
  }
26522
26530
  return null;
26523
- }, [assetBaseUrl]);
26531
+ }, []);
26524
26532
  React85.useEffect(() => {
26525
26533
  const canvas = canvasRef.current;
26526
26534
  if (!canvas) return;
@@ -26542,10 +26550,10 @@ function GameCanvas2D({
26542
26550
  if (tickEventRef.current) {
26543
26551
  emitRef.current(tickEventRef.current, { dt, frame });
26544
26552
  }
26545
- if (backgroundImage) {
26546
- const bgImg = loadImage(backgroundImage);
26553
+ if (backgroundImageRef.current) {
26554
+ const bgImg = loadImage(backgroundImageRef.current);
26547
26555
  if (bgImg) {
26548
- ctx.drawImage(bgImg, 0, 0, width, height);
26556
+ ctx.drawImage(bgImg, 0, 0, widthRef.current, heightRef.current);
26549
26557
  }
26550
26558
  }
26551
26559
  onDrawRef.current?.(ctx, frame);
@@ -26561,7 +26569,7 @@ function GameCanvas2D({
26561
26569
  running = false;
26562
26570
  cancelAnimationFrame(rafRef.current);
26563
26571
  };
26564
- }, [fps]);
26572
+ }, [fps, loadImage]);
26565
26573
  return /* @__PURE__ */ jsx(Box, { className: cn("inline-block", className), children: /* @__PURE__ */ jsx(
26566
26574
  "canvas",
26567
26575
  {
@@ -27703,15 +27711,22 @@ function PlatformerCanvas({
27703
27711
  const eventBus = useEventBus();
27704
27712
  const keysRef = useRef(/* @__PURE__ */ new Set());
27705
27713
  const imageCache = useRef(/* @__PURE__ */ new Map());
27714
+ const [loadedImages, setLoadedImages] = useState(/* @__PURE__ */ new Set());
27706
27715
  const loadImage = useCallback((url) => {
27707
27716
  const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
27708
27717
  const cached = imageCache.current.get(fullUrl);
27709
- if (cached?.complete && cached.naturalWidth > 0) return cached;
27718
+ if (cached?.complete && cached.naturalWidth > 0) {
27719
+ if (!loadedImages.has(fullUrl)) {
27720
+ setLoadedImages((prev) => new Set(prev).add(fullUrl));
27721
+ }
27722
+ return cached;
27723
+ }
27710
27724
  if (!cached) {
27711
27725
  const img = new Image();
27712
27726
  img.crossOrigin = "anonymous";
27713
27727
  img.src = fullUrl;
27714
27728
  img.onload = () => {
27729
+ setLoadedImages((prev) => new Set(prev).add(fullUrl));
27715
27730
  updateAssetStatus(fullUrl, "loaded");
27716
27731
  };
27717
27732
  img.onerror = () => {
@@ -27721,7 +27736,7 @@ function PlatformerCanvas({
27721
27736
  updateAssetStatus(fullUrl, "pending");
27722
27737
  }
27723
27738
  return null;
27724
- }, [assetBaseUrl]);
27739
+ }, [assetBaseUrl, loadedImages]);
27725
27740
  useEffect(() => {
27726
27741
  if (typeof window === "undefined") return;
27727
27742
  const canvas = canvasRef.current;
@@ -27903,7 +27918,7 @@ function PlatformerCanvas({
27903
27918
  ctx.arc(ppx + eyeOffsetX + 7, eyeY, eyeSize, 0, Math.PI * 2);
27904
27919
  ctx.fill();
27905
27920
  }
27906
- });
27921
+ }, [player, platforms, worldWidth, worldHeight, canvasWidth, canvasHeight, followCamera, bgColor, playerSprite, tileSprites, backgroundImage, assetBaseUrl, loadedImages]);
27907
27922
  return /* @__PURE__ */ jsx(
27908
27923
  "canvas",
27909
27924
  {
@@ -29099,10 +29114,13 @@ function TableView({
29099
29114
  }
29100
29115
  const lk = LOOKS[look];
29101
29116
  const hasActions = Boolean(itemActions && itemActions.length > 0);
29117
+ const inlineActionCount = hasActions ? maxInlineActions != null ? Math.min(itemActions.length, maxInlineActions) : itemActions.length : 0;
29118
+ const hasOverflowActions = hasActions && maxInlineActions != null && itemActions.length > maxInlineActions;
29119
+ const actionsTrack = hasActions ? `${inlineActionCount * 6 + (hasOverflowActions ? 3 : 0)}rem` : null;
29102
29120
  const gridTemplateColumns = [
29103
29121
  selectable ? "auto" : null,
29104
29122
  ...colDefs.map((c) => c.width ?? "minmax(0, 1fr)"),
29105
- hasActions ? "auto" : null
29123
+ actionsTrack
29106
29124
  ].filter(Boolean).join(" ");
29107
29125
  const header = /* @__PURE__ */ jsxs(
29108
29126
  Box,
@@ -29189,7 +29207,7 @@ function TableView({
29189
29207
  }
29190
29208
  return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
29191
29209
  }),
29192
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: [
29210
+ itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "justify-end flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: [
29193
29211
  (maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions).map((action, i) => /* @__PURE__ */ jsxs(
29194
29212
  Button,
29195
29213
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "5.11.0",
3
+ "version": "5.12.1",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "sideEffects": [