@vectojs/core 1.28.0 → 1.28.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.
package/dist/index.js CHANGED
@@ -2002,10 +2002,20 @@ var Scene = (_class7 = class _Scene {
2002
2002
  __init82() {this.activeIds = /* @__PURE__ */ new Set()}
2003
2003
  /** Per-parent insertion cursor, reused by `enforceA11yDomOrder`. */
2004
2004
  __init83() {this.a11yOrderCursors = /* @__PURE__ */ new Map()}
2005
- __init84() {this.activePortalsThisFrame = /* @__PURE__ */ new Set()}
2006
- __init85() {this.activePortalsPrevFrame = /* @__PURE__ */ new Set()}
2007
- __init86() {this.portalEntities = /* @__PURE__ */ new Map()}
2008
- __init87() {this.renderOrderCounter = 0}
2005
+ /** Membership set for the elements being ordered, reused per reorder pass. */
2006
+ __init84() {this.a11yOrderMembers = /* @__PURE__ */ new Set()}
2007
+ /**
2008
+ * Elements that are an *ancestor* of another ordered element, reused per pass.
2009
+ *
2010
+ * A composite widget's container (a `grid` around its rows, a `tree` around its
2011
+ * items) spans every descendant row, so it must not extend a visual row band —
2012
+ * see {@link sortNormalElementsVisually}.
2013
+ */
2014
+ __init85() {this.a11yOrderContainers = /* @__PURE__ */ new Set()}
2015
+ __init86() {this.activePortalsThisFrame = /* @__PURE__ */ new Set()}
2016
+ __init87() {this.activePortalsPrevFrame = /* @__PURE__ */ new Set()}
2017
+ __init88() {this.portalEntities = /* @__PURE__ */ new Map()}
2018
+ __init89() {this.renderOrderCounter = 0}
2009
2019
  /**
2010
2020
  * Monotonic render-frame counter, bumped once per authoritative `render()`
2011
2021
  * pass. Entities stamp their per-frame world-matrix cache with this value and
@@ -2014,7 +2024,7 @@ var Scene = (_class7 = class _Scene {
2014
2024
  * back to the ancestor walk. Public for the same reason `Entity._getTrig`/
2015
2025
  * `_setWorldCache` are: it is a cross-class render-internal contract.
2016
2026
  */
2017
- __init88() {this.currentFrame = 0}
2027
+ __init90() {this.currentFrame = 0}
2018
2028
  // ── WASM transform backend (invisible accelerator) ──────────────────────────
2019
2029
  // When `_transformBackend === 'wasm'`, the main render walk sources each
2020
2030
  // entity's world matrix from an SoA store composed by `_wasm` (see
@@ -2022,24 +2032,24 @@ var Scene = (_class7 = class _Scene {
2022
2032
  // fallback and the default: a null backend, a non-main renderer, or any entity
2023
2033
  // absent from the store all fall back to the JS composition, so WASM can only
2024
2034
  // ever change *how fast* a world matrix is produced, never *what* it is.
2025
- __init89() {this._wasm = null}
2026
- __init90() {this._transformBackend = "js"}
2035
+ __init91() {this._wasm = null}
2036
+ __init92() {this._transformBackend = "js"}
2027
2037
  // Resident store state (Stage 3). The store layout — slot assignment + sibling
2028
2038
  // runs — depends only on tree TOPOLOGY, so it is rebuilt only when the
2029
2039
  // structure changes (add/remove/reparent bump `_structureVersion`). Between
2030
2040
  // rebuilds the per-frame cost is: gather each entity's transform into the
2031
2041
  // resident wasm input view + run the kernel — no reallocation, no readback.
2032
- __init91() {this._treeStore = null}
2033
- __init92() {this._slotEntity = []}
2042
+ __init93() {this._treeStore = null}
2043
+ __init94() {this._slotEntity = []}
2034
2044
  // store slot -> entity (also validates slots)
2035
- __init93() {this._wasmInputs = null}
2036
- __init94() {this._wasmWorld = null}
2037
- __init95() {this._structureVersion = 0}
2038
- __init96() {this._storeStructureVersion = -1}
2045
+ __init95() {this._wasmInputs = null}
2046
+ __init96() {this._wasmWorld = null}
2047
+ __init97() {this._structureVersion = 0}
2048
+ __init98() {this._storeStructureVersion = -1}
2039
2049
  // Cached list of ComputeParticleEntity instances in the tree, keyed by the
2040
2050
  // structure version it was gathered at. Rebuilt only on a topology change.
2041
- __init97() {this._computeEntities = []}
2042
- __init98() {this._computeEntitiesVersion = -1}
2051
+ __init99() {this._computeEntities = []}
2052
+ __init100() {this._computeEntitiesVersion = -1}
2043
2053
  /** Invalidate the resident WASM store layout; the next wasm-mode frame rebuilds
2044
2054
  * it. Called by `Entity.add`/`remove` (topology changes only). */
2045
2055
  markStructureChanged() {
@@ -2124,7 +2134,7 @@ var Scene = (_class7 = class _Scene {
2124
2134
  * cached globally; the instance is per-Scene, which is the isolation that
2125
2135
  * actually matters.
2126
2136
  */
2127
- __init99() {this._wasmRuntime = null}
2137
+ __init101() {this._wasmRuntime = null}
2128
2138
  /**
2129
2139
  * Load (or reuse) this Scene's shared WASM runtime.
2130
2140
  *
@@ -2152,30 +2162,30 @@ var Scene = (_class7 = class _Scene {
2152
2162
  get wasmRuntime() {
2153
2163
  return this._wasmRuntime;
2154
2164
  }
2155
- __init100() {this._hitWasm = null}
2165
+ __init102() {this._hitWasm = null}
2156
2166
  // Cache key: which frame + structure version the grid was last (successfully,
2157
2167
  // non-overflowing) built for. findEntityAt is called ad-hoc (pointer
2158
2168
  // hover/click), not every frame, so the grid is refreshed lazily on demand
2159
2169
  // rather than proactively every render() — unlike the transform store, which
2160
2170
  // every frame's draw depends on.
2161
- __init101() {this._hitGridFrame = -1}
2162
- __init102() {this._hitGridOk = false}
2163
- __init103() {this._hitSlotEntity = []}
2164
- __init104() {this._hitBoundless = []}
2171
+ __init103() {this._hitGridFrame = -1}
2172
+ __init104() {this._hitGridOk = false}
2173
+ __init105() {this._hitSlotEntity = []}
2174
+ __init106() {this._hitBoundless = []}
2165
2175
  /** Reused buffer for the fused gather, so a pointer query allocates nothing. */
2166
- __init105() {this._hitGatherBuffer = null}
2176
+ __init107() {this._hitGatherBuffer = null}
2167
2177
  /**
2168
2178
  * Whether the last grid build sourced its AABBs from the WASM transform store
2169
2179
  * rather than recomputing them in JS. Diagnostic only — both paths must
2170
2180
  * produce the same entity for a given point.
2171
2181
  */
2172
- __init106() {this._hitFusedGather = false}
2182
+ __init108() {this._hitFusedGather = false}
2173
2183
  /**
2174
2184
  * Whether `compute_aabbs` has run against the current frame's world matrices.
2175
2185
  * The AABB pass is only meaningful after a `compose_*`, so the fused gather
2176
2186
  * must not read the views before then.
2177
2187
  */
2178
- __init107() {this._wasmAabbsFresh = false}
2188
+ __init109() {this._wasmAabbsFresh = false}
2179
2189
  /** Did the last hit-grid build use the fused (WASM-store) gather? */
2180
2190
  get hitGatherPath() {
2181
2191
  return this._hitFusedGather ? "fused" : "js";
@@ -2184,9 +2194,9 @@ var Scene = (_class7 = class _Scene {
2184
2194
  * Why the transform accelerator did or did not run on the most recent frame.
2185
2195
  * Written by the render walk and `_syncWasmStore`.
2186
2196
  */
2187
- __init108() {this._transformReason = "not-installed"}
2197
+ __init110() {this._transformReason = "not-installed"}
2188
2198
  /** Why the batched-driver accelerator did or did not run. */
2189
- __init109() {this._animReason = "not-installed"}
2199
+ __init111() {this._animReason = "not-installed"}
2190
2200
  /**
2191
2201
  * Why the hit-test accelerator did or did not serve the last pointer query.
2192
2202
  * The grid is built lazily on demand, not every frame, so this describes the
@@ -2194,11 +2204,11 @@ var Scene = (_class7 = class _Scene {
2194
2204
  * before a backend exists; `_ensureHitGrid` moves it to `'not-applicable'`
2195
2205
  * once one is installed but nothing has queried yet.
2196
2206
  */
2197
- __init110() {this._hitReason = "not-installed"}
2207
+ __init112() {this._hitReason = "not-installed"}
2198
2208
  /** Why the particle accelerator did or did not run. */
2199
- __init111() {this._particleReason = "not-applicable"}
2209
+ __init113() {this._particleReason = "not-applicable"}
2200
2210
  /** Which particle implementation actually simulated the most recent frame. */
2201
- __init112() {this._particlePath = "none"}
2211
+ __init114() {this._particlePath = "none"}
2202
2212
  /**
2203
2213
  * Per-frame status of every invisible accelerator: whether each is installed,
2204
2214
  * whether it actually ran on the most recent frame, and why.
@@ -2358,25 +2368,25 @@ var Scene = (_class7 = class _Scene {
2358
2368
  // EasingFn (which cannot cross into WASM) all fall through to it — WASM can
2359
2369
  // only ever change *how* a driver is advanced, never *what* value it lands
2360
2370
  // on.
2361
- __init113() {this._animWasm = null}
2371
+ __init115() {this._animWasm = null}
2362
2372
  // Entities with at least one active driver, added by Entity._spawnDriver.
2363
2373
  // Self-pruning: _tickBatchedDrivers drops an entry the first time it visits
2364
2374
  // an entity whose drivers have since all completed or been removed. This is
2365
2375
  // what lets the batch pass find its candidates in O(active drivers), not
2366
2376
  // O(tree size) — the exact mistake G3's first integrated benchmark made.
2367
- __init114() {this._activeDriverEntities = /* @__PURE__ */ new Set()}
2377
+ __init116() {this._activeDriverEntities = /* @__PURE__ */ new Set()}
2368
2378
  // Reused across frames instead of allocating a fresh array + N {entity,prop,
2369
2379
  // driver} objects every call — the integrated benchmark
2370
2380
  // (benchmarks/anim-wasm-scene) found that allocation churn was the
2371
2381
  // dominant integrated cost, not the wasm kernel itself. Parallel arrays,
2372
2382
  // truncated to the live count after each use so a stale tail slot never
2373
2383
  // pins a no-longer-active entity/driver in memory.
2374
- __init115() {this._springEntities = []}
2375
- __init116() {this._springProps = []}
2376
- __init117() {this._springDrivers = []}
2377
- __init118() {this._tweenEntities = []}
2378
- __init119() {this._tweenProps = []}
2379
- __init120() {this._tweenDrivers = []}
2384
+ __init117() {this._springEntities = []}
2385
+ __init118() {this._springProps = []}
2386
+ __init119() {this._springDrivers = []}
2387
+ __init120() {this._tweenEntities = []}
2388
+ __init121() {this._tweenProps = []}
2389
+ __init122() {this._tweenDrivers = []}
2380
2390
  /**
2381
2391
  * Minimum number of batchable (spring, or named-easing tween) active drivers
2382
2392
  * before a frame engages the WASM batch path at all; below it, every driver
@@ -2448,7 +2458,7 @@ var Scene = (_class7 = class _Scene {
2448
2458
  * Setting {@link animDriverGateCount} overwrites all three, so existing code
2449
2459
  * that tuned the single knob keeps working unchanged.
2450
2460
  */
2451
- __init121() {this._animBatchedLastFrame = false}
2461
+ __init123() {this._animBatchedLastFrame = false}
2452
2462
  /**
2453
2463
  * Whether the WASM batch path actually ran on the most recent frame.
2454
2464
  *
@@ -2460,7 +2470,7 @@ var Scene = (_class7 = class _Scene {
2460
2470
  get animBatchedLastFrame() {
2461
2471
  return this._animBatchedLastFrame;
2462
2472
  }
2463
- __init122() {this.animGate = {
2473
+ __init124() {this.animGate = {
2464
2474
  spring: 128,
2465
2475
  tween: 256,
2466
2476
  mixed: 128
@@ -2498,7 +2508,7 @@ var Scene = (_class7 = class _Scene {
2498
2508
  // (benchmarks/particle-wasm). f32 (matches the WGSL shader), bit-identical to
2499
2509
  // a JS f32 reference oracle; updateCPU (f64) stays the permanent fallback when
2500
2510
  // no backend is installed or a scene runs on WebGPU.
2501
- __init123() {this._particleWasm = null}
2511
+ __init125() {this._particleWasm = null}
2502
2512
  /** Which backend runs the CPU particle simulation. Reflects only whether a
2503
2513
  * backend is installed (the WebGPU compute path, when active, is used first
2504
2514
  * regardless). */
@@ -2775,24 +2785,24 @@ var Scene = (_class7 = class _Scene {
2775
2785
  * sync, so retaining the order prevents a newly opened overlay from spending
2776
2786
  * its first frame below previously projected controls.
2777
2787
  */
2778
- __init124() {this.a11yRenderOrders = /* @__PURE__ */ new Map()}
2788
+ __init126() {this.a11yRenderOrders = /* @__PURE__ */ new Map()}
2779
2789
  // Optional WebGL point-cloud layer (see SceneOptions.pointBackend).
2780
- __init125() {this.pointRenderer = null}
2781
- __init126() {this.glCanvas = null}
2782
- __init127() {this.glContextLostHandler = null}
2783
- __init128() {this.glContextRestoredHandler = null}
2790
+ __init127() {this.pointRenderer = null}
2791
+ __init128() {this.glCanvas = null}
2792
+ __init129() {this.glContextLostHandler = null}
2793
+ __init130() {this.glContextRestoredHandler = null}
2784
2794
 
2785
2795
 
2786
2796
 
2787
- __init129() {this.disableWindowResize = false}
2797
+ __init131() {this.disableWindowResize = false}
2788
2798
  /** See {@link SceneOptions.maxDPR}. `undefined` = uncapped (real DPR). */
2789
2799
 
2790
2800
  // WebGPU properties
2791
- __init130() {this.destroyed = false}
2792
- __init131() {this.device = null}
2793
- __init132() {this.deviceLost = false}
2794
- __init133() {this.particleBackend = "auto"}
2795
- __init134() {this._webgpuDisabled = false}
2801
+ __init132() {this.destroyed = false}
2802
+ __init133() {this.device = null}
2803
+ __init134() {this.deviceLost = false}
2804
+ __init135() {this.particleBackend = "auto"}
2805
+ __init136() {this._webgpuDisabled = false}
2796
2806
  get webgpuDisabled() {
2797
2807
  return this._webgpuDisabled || this.particleBackend === "cpu";
2798
2808
  }
@@ -2820,22 +2830,22 @@ var Scene = (_class7 = class _Scene {
2820
2830
  set webgpuDisabled(value) {
2821
2831
  this._webgpuDisabled = value;
2822
2832
  }
2823
- __init135() {this.recoveryTimerId = null}
2824
- __init136() {this.manager = null}
2825
- __init137() {this.initializingWebGPU = false}
2826
- __init138() {this.gpuCanvas = null}
2827
- __init139() {this.gpuContext = null}
2833
+ __init137() {this.recoveryTimerId = null}
2834
+ __init138() {this.manager = null}
2835
+ __init139() {this.initializingWebGPU = false}
2836
+ __init140() {this.gpuCanvas = null}
2837
+ __init141() {this.gpuContext = null}
2828
2838
  /** True while the GPU canvas holds a presented particle frame (needs clearing when they leave). */
2829
- __init140() {this.gpuHasContent = false}
2830
- __init141() {this.mouseX = -9999}
2831
- __init142() {this.mouseY = -9999}
2832
- __init143() {this.pointerMoveListener = null}
2833
- __init144() {this.pointerLeaveListener = null}
2839
+ __init142() {this.gpuHasContent = false}
2840
+ __init143() {this.mouseX = -9999}
2841
+ __init144() {this.mouseY = -9999}
2842
+ __init145() {this.pointerMoveListener = null}
2843
+ __init146() {this.pointerLeaveListener = null}
2834
2844
  /** Element the pointer listeners are bound to (parent container if present,
2835
2845
  * else the canvas). Stored so `destroy()` detaches from the same element. */
2836
- __init145() {this.pointerEventTarget = null}
2837
- __init146() {this.hasWarnedZeroSize = false}
2838
- __init147() {this.fontLoadHandler = null}
2846
+ __init147() {this.pointerEventTarget = null}
2847
+ __init148() {this.hasWarnedZeroSize = false}
2848
+ __init149() {this.fontLoadHandler = null}
2839
2849
  // ── Dev-mode warning infrastructure ──────────────────────────────
2840
2850
  //
2841
2851
  // Enable with `Scene.devMode = true` or by setting `globalThis.__DEV__`.
@@ -2869,7 +2879,7 @@ var Scene = (_class7 = class _Scene {
2869
2879
  return false;
2870
2880
  }
2871
2881
 
2872
- __init148() {this._devFrameCount = 0}
2882
+ __init150() {this._devFrameCount = 0}
2873
2883
  _devWarn(message) {
2874
2884
  if (!this._devActive) return;
2875
2885
  console.warn(`[vectojs/dev] ${message}`);
@@ -2944,7 +2954,7 @@ var Scene = (_class7 = class _Scene {
2944
2954
  };
2945
2955
  walkProjections(this.root);
2946
2956
  }
2947
- constructor(canvas, options = {}) {;_class7.prototype.__init27.call(this);_class7.prototype.__init28.call(this);_class7.prototype.__init29.call(this);_class7.prototype.__init30.call(this);_class7.prototype.__init31.call(this);_class7.prototype.__init32.call(this);_class7.prototype.__init33.call(this);_class7.prototype.__init34.call(this);_class7.prototype.__init35.call(this);_class7.prototype.__init36.call(this);_class7.prototype.__init37.call(this);_class7.prototype.__init38.call(this);_class7.prototype.__init39.call(this);_class7.prototype.__init40.call(this);_class7.prototype.__init41.call(this);_class7.prototype.__init42.call(this);_class7.prototype.__init43.call(this);_class7.prototype.__init44.call(this);_class7.prototype.__init45.call(this);_class7.prototype.__init46.call(this);_class7.prototype.__init47.call(this);_class7.prototype.__init48.call(this);_class7.prototype.__init49.call(this);_class7.prototype.__init50.call(this);_class7.prototype.__init51.call(this);_class7.prototype.__init52.call(this);_class7.prototype.__init53.call(this);_class7.prototype.__init54.call(this);_class7.prototype.__init55.call(this);_class7.prototype.__init56.call(this);_class7.prototype.__init57.call(this);_class7.prototype.__init58.call(this);_class7.prototype.__init59.call(this);_class7.prototype.__init60.call(this);_class7.prototype.__init61.call(this);_class7.prototype.__init62.call(this);_class7.prototype.__init63.call(this);_class7.prototype.__init64.call(this);_class7.prototype.__init65.call(this);_class7.prototype.__init66.call(this);_class7.prototype.__init67.call(this);_class7.prototype.__init68.call(this);_class7.prototype.__init69.call(this);_class7.prototype.__init70.call(this);_class7.prototype.__init71.call(this);_class7.prototype.__init72.call(this);_class7.prototype.__init73.call(this);_class7.prototype.__init74.call(this);_class7.prototype.__init75.call(this);_class7.prototype.__init76.call(this);_class7.prototype.__init77.call(this);_class7.prototype.__init78.call(this);_class7.prototype.__init79.call(this);_class7.prototype.__init80.call(this);_class7.prototype.__init81.call(this);_class7.prototype.__init82.call(this);_class7.prototype.__init83.call(this);_class7.prototype.__init84.call(this);_class7.prototype.__init85.call(this);_class7.prototype.__init86.call(this);_class7.prototype.__init87.call(this);_class7.prototype.__init88.call(this);_class7.prototype.__init89.call(this);_class7.prototype.__init90.call(this);_class7.prototype.__init91.call(this);_class7.prototype.__init92.call(this);_class7.prototype.__init93.call(this);_class7.prototype.__init94.call(this);_class7.prototype.__init95.call(this);_class7.prototype.__init96.call(this);_class7.prototype.__init97.call(this);_class7.prototype.__init98.call(this);_class7.prototype.__init99.call(this);_class7.prototype.__init100.call(this);_class7.prototype.__init101.call(this);_class7.prototype.__init102.call(this);_class7.prototype.__init103.call(this);_class7.prototype.__init104.call(this);_class7.prototype.__init105.call(this);_class7.prototype.__init106.call(this);_class7.prototype.__init107.call(this);_class7.prototype.__init108.call(this);_class7.prototype.__init109.call(this);_class7.prototype.__init110.call(this);_class7.prototype.__init111.call(this);_class7.prototype.__init112.call(this);_class7.prototype.__init113.call(this);_class7.prototype.__init114.call(this);_class7.prototype.__init115.call(this);_class7.prototype.__init116.call(this);_class7.prototype.__init117.call(this);_class7.prototype.__init118.call(this);_class7.prototype.__init119.call(this);_class7.prototype.__init120.call(this);_class7.prototype.__init121.call(this);_class7.prototype.__init122.call(this);_class7.prototype.__init123.call(this);_class7.prototype.__init124.call(this);_class7.prototype.__init125.call(this);_class7.prototype.__init126.call(this);_class7.prototype.__init127.call(this);_class7.prototype.__init128.call(this);_class7.prototype.__init129.call(this);_class7.prototype.__init130.call(this);_class7.prototype.__init131.call(this);_class7.prototype.__init132.call(this);_class7.prototype.__init133.call(this);_class7.prototype.__init134.call(this);_class7.prototype.__init135.call(this);_class7.prototype.__init136.call(this);_class7.prototype.__init137.call(this);_class7.prototype.__init138.call(this);_class7.prototype.__init139.call(this);_class7.prototype.__init140.call(this);_class7.prototype.__init141.call(this);_class7.prototype.__init142.call(this);_class7.prototype.__init143.call(this);_class7.prototype.__init144.call(this);_class7.prototype.__init145.call(this);_class7.prototype.__init146.call(this);_class7.prototype.__init147.call(this);_class7.prototype.__init148.call(this);
2957
+ constructor(canvas, options = {}) {;_class7.prototype.__init27.call(this);_class7.prototype.__init28.call(this);_class7.prototype.__init29.call(this);_class7.prototype.__init30.call(this);_class7.prototype.__init31.call(this);_class7.prototype.__init32.call(this);_class7.prototype.__init33.call(this);_class7.prototype.__init34.call(this);_class7.prototype.__init35.call(this);_class7.prototype.__init36.call(this);_class7.prototype.__init37.call(this);_class7.prototype.__init38.call(this);_class7.prototype.__init39.call(this);_class7.prototype.__init40.call(this);_class7.prototype.__init41.call(this);_class7.prototype.__init42.call(this);_class7.prototype.__init43.call(this);_class7.prototype.__init44.call(this);_class7.prototype.__init45.call(this);_class7.prototype.__init46.call(this);_class7.prototype.__init47.call(this);_class7.prototype.__init48.call(this);_class7.prototype.__init49.call(this);_class7.prototype.__init50.call(this);_class7.prototype.__init51.call(this);_class7.prototype.__init52.call(this);_class7.prototype.__init53.call(this);_class7.prototype.__init54.call(this);_class7.prototype.__init55.call(this);_class7.prototype.__init56.call(this);_class7.prototype.__init57.call(this);_class7.prototype.__init58.call(this);_class7.prototype.__init59.call(this);_class7.prototype.__init60.call(this);_class7.prototype.__init61.call(this);_class7.prototype.__init62.call(this);_class7.prototype.__init63.call(this);_class7.prototype.__init64.call(this);_class7.prototype.__init65.call(this);_class7.prototype.__init66.call(this);_class7.prototype.__init67.call(this);_class7.prototype.__init68.call(this);_class7.prototype.__init69.call(this);_class7.prototype.__init70.call(this);_class7.prototype.__init71.call(this);_class7.prototype.__init72.call(this);_class7.prototype.__init73.call(this);_class7.prototype.__init74.call(this);_class7.prototype.__init75.call(this);_class7.prototype.__init76.call(this);_class7.prototype.__init77.call(this);_class7.prototype.__init78.call(this);_class7.prototype.__init79.call(this);_class7.prototype.__init80.call(this);_class7.prototype.__init81.call(this);_class7.prototype.__init82.call(this);_class7.prototype.__init83.call(this);_class7.prototype.__init84.call(this);_class7.prototype.__init85.call(this);_class7.prototype.__init86.call(this);_class7.prototype.__init87.call(this);_class7.prototype.__init88.call(this);_class7.prototype.__init89.call(this);_class7.prototype.__init90.call(this);_class7.prototype.__init91.call(this);_class7.prototype.__init92.call(this);_class7.prototype.__init93.call(this);_class7.prototype.__init94.call(this);_class7.prototype.__init95.call(this);_class7.prototype.__init96.call(this);_class7.prototype.__init97.call(this);_class7.prototype.__init98.call(this);_class7.prototype.__init99.call(this);_class7.prototype.__init100.call(this);_class7.prototype.__init101.call(this);_class7.prototype.__init102.call(this);_class7.prototype.__init103.call(this);_class7.prototype.__init104.call(this);_class7.prototype.__init105.call(this);_class7.prototype.__init106.call(this);_class7.prototype.__init107.call(this);_class7.prototype.__init108.call(this);_class7.prototype.__init109.call(this);_class7.prototype.__init110.call(this);_class7.prototype.__init111.call(this);_class7.prototype.__init112.call(this);_class7.prototype.__init113.call(this);_class7.prototype.__init114.call(this);_class7.prototype.__init115.call(this);_class7.prototype.__init116.call(this);_class7.prototype.__init117.call(this);_class7.prototype.__init118.call(this);_class7.prototype.__init119.call(this);_class7.prototype.__init120.call(this);_class7.prototype.__init121.call(this);_class7.prototype.__init122.call(this);_class7.prototype.__init123.call(this);_class7.prototype.__init124.call(this);_class7.prototype.__init125.call(this);_class7.prototype.__init126.call(this);_class7.prototype.__init127.call(this);_class7.prototype.__init128.call(this);_class7.prototype.__init129.call(this);_class7.prototype.__init130.call(this);_class7.prototype.__init131.call(this);_class7.prototype.__init132.call(this);_class7.prototype.__init133.call(this);_class7.prototype.__init134.call(this);_class7.prototype.__init135.call(this);_class7.prototype.__init136.call(this);_class7.prototype.__init137.call(this);_class7.prototype.__init138.call(this);_class7.prototype.__init139.call(this);_class7.prototype.__init140.call(this);_class7.prototype.__init141.call(this);_class7.prototype.__init142.call(this);_class7.prototype.__init143.call(this);_class7.prototype.__init144.call(this);_class7.prototype.__init145.call(this);_class7.prototype.__init146.call(this);_class7.prototype.__init147.call(this);_class7.prototype.__init148.call(this);_class7.prototype.__init149.call(this);_class7.prototype.__init150.call(this);
2948
2958
  this.canvas = canvas;
2949
2959
  this.debugA11y = _nullishCoalesce(options.debugA11y, () => ( false));
2950
2960
  this.disableWindowResize = _nullishCoalesce(options.disableWindowResize, () => ( false));
@@ -4872,7 +4882,9 @@ var Scene = (_class7 = class _Scene {
4872
4882
  this.a11yOrderCursors.set(parent, at + 1);
4873
4883
  const current = parent.childNodes[at];
4874
4884
  if (current !== expected) {
4885
+ const refocus = document.activeElement === expected;
4875
4886
  parent.insertBefore(expected, current || null);
4887
+ if (refocus) expected.focus({ preventScroll: true });
4876
4888
  }
4877
4889
  }
4878
4890
  this.a11yNeedsReorder = false;
@@ -4901,19 +4913,37 @@ var Scene = (_class7 = class _Scene {
4901
4913
  const els = this.normalElements;
4902
4914
  if (els.length < 2) return;
4903
4915
  const rtl = this._readingDirection === "rtl";
4904
- const topOf = (el) => Number.parseFloat(el.style.top) || 0;
4905
- const leftOf = (el) => Number.parseFloat(el.style.left) || 0;
4906
4916
  const heightOf = (el) => Math.max(Number.parseFloat(el.style.height) || 0, 4);
4907
- const order = els.map((el, i) => ({
4908
- el,
4909
- i,
4910
- top: topOf(el),
4911
- left: leftOf(el)
4912
- }));
4917
+ const members = this.a11yOrderMembers;
4918
+ const containers = this.a11yOrderContainers;
4919
+ members.clear();
4920
+ containers.clear();
4921
+ for (const el of els) members.add(el);
4922
+ for (const el of els) {
4923
+ for (let p = el.parentElement; p; p = p.parentElement) {
4924
+ if (members.has(p)) containers.add(p);
4925
+ }
4926
+ }
4927
+ const absolute = (el) => {
4928
+ let top = 0;
4929
+ let left = 0;
4930
+ for (let node = el; node; node = node.parentElement) {
4931
+ top += Number.parseFloat(node.style.top) || 0;
4932
+ left += Number.parseFloat(node.style.left) || 0;
4933
+ const parent = node.parentElement;
4934
+ if (!parent || !members.has(parent)) break;
4935
+ }
4936
+ return { top, left };
4937
+ };
4938
+ const order = els.map((el, i) => {
4939
+ const { top, left } = absolute(el);
4940
+ return { el, i, top, left, container: containers.has(el) };
4941
+ });
4913
4942
  order.sort((p, q) => p.top - q.top || p.i - q.i);
4943
+ const bandBottom = (r) => r.top + (r.container ? 4 : heightOf(r.el));
4914
4944
  const sorted = [];
4915
4945
  let rowStart = 0;
4916
- let rowBottom = order.length ? order[0].top + heightOf(order[0].el) : 0;
4946
+ let rowBottom = order.length ? bandBottom(order[0]) : 0;
4917
4947
  const flushRow = (end) => {
4918
4948
  const row = order.slice(rowStart, end);
4919
4949
  row.sort((p, q) => (rtl ? q.left - p.left : p.left - q.left) || p.i - q.i);
@@ -4921,11 +4951,11 @@ var Scene = (_class7 = class _Scene {
4921
4951
  };
4922
4952
  for (let k = 1; k < order.length; k++) {
4923
4953
  if (order[k].top < rowBottom) {
4924
- rowBottom = Math.max(rowBottom, order[k].top + heightOf(order[k].el));
4954
+ rowBottom = Math.max(rowBottom, bandBottom(order[k]));
4925
4955
  } else {
4926
4956
  flushRow(k);
4927
4957
  rowStart = k;
4928
- rowBottom = order[k].top + heightOf(order[k].el);
4958
+ rowBottom = bandBottom(order[k]);
4929
4959
  }
4930
4960
  }
4931
4961
  flushRow(order.length);
@@ -5863,15 +5893,15 @@ var TextEntity = (_class8 = class extends _chunkZ3HFY75Rjs.Entity {
5863
5893
 
5864
5894
 
5865
5895
 
5866
- __init149() {this.nodes = []}
5896
+ __init151() {this.nodes = []}
5867
5897
 
5868
- __init150() {this.fillStyle = "#94a3b8"}
5869
- __init151() {this.strokeStyle = null}
5870
- __init152() {this.hoveredFillStyle = "#ffffff"}
5871
- __init153() {this.lineWidth = 1}
5872
- __init154() {this.isHovered = false}
5898
+ __init152() {this.fillStyle = "#94a3b8"}
5899
+ __init153() {this.strokeStyle = null}
5900
+ __init154() {this.hoveredFillStyle = "#ffffff"}
5901
+ __init155() {this.lineWidth = 1}
5902
+ __init156() {this.isHovered = false}
5873
5903
  constructor(text, atlas, maxWidth, fontSize = 24) {
5874
- super();_class8.prototype.__init149.call(this);_class8.prototype.__init150.call(this);_class8.prototype.__init151.call(this);_class8.prototype.__init152.call(this);_class8.prototype.__init153.call(this);_class8.prototype.__init154.call(this);;
5904
+ super();_class8.prototype.__init151.call(this);_class8.prototype.__init152.call(this);_class8.prototype.__init153.call(this);_class8.prototype.__init154.call(this);_class8.prototype.__init155.call(this);_class8.prototype.__init156.call(this);;
5875
5905
  this.text = text;
5876
5906
  this.atlas = atlas;
5877
5907
  this.fontSize = fontSize;
@@ -5986,15 +6016,15 @@ var TextEntity = (_class8 = class extends _chunkZ3HFY75Rjs.Entity {
5986
6016
  // src/components/GridTextEntity.ts
5987
6017
  var GridTextEntity = (_class9 = class extends _chunkZ3HFY75Rjs.Entity {
5988
6018
 
5989
- __init155() {this.fillStyle = "#ffffff"}
5990
- __init156() {this.grid = []}
6019
+ __init157() {this.fillStyle = "#ffffff"}
6020
+ __init158() {this.grid = []}
5991
6021
  // Array of rows
5992
- __init157() {this.cols = 0}
5993
- __init158() {this.rows = 0}
6022
+ __init159() {this.cols = 0}
6023
+ __init160() {this.rows = 0}
5994
6024
 
5995
6025
 
5996
6026
  constructor(_atlas, fontSize = 10) {
5997
- super();_class9.prototype.__init155.call(this);_class9.prototype.__init156.call(this);_class9.prototype.__init157.call(this);_class9.prototype.__init158.call(this);;
6027
+ super();_class9.prototype.__init157.call(this);_class9.prototype.__init158.call(this);_class9.prototype.__init159.call(this);_class9.prototype.__init160.call(this);;
5998
6028
  this.fontSize = fontSize;
5999
6029
  this.charWidth = fontSize * 1;
6000
6030
  this.charHeight = fontSize * 1.1;
@@ -6086,23 +6116,23 @@ var SplineEntity = (_class10 = class extends _chunkZ3HFY75Rjs.Entity {
6086
6116
 
6087
6117
 
6088
6118
 
6089
- __init159() {this.offscreen = null}
6090
- __init160() {this.baked = false}
6119
+ __init161() {this.offscreen = null}
6120
+ __init162() {this.baked = false}
6091
6121
  /** Logical (CSS-pixel) size of the baked bitmap — the blit destination size. */
6092
- __init161() {this.bakedWidth = 0}
6093
- __init162() {this.bakedHeight = 0}
6122
+ __init163() {this.bakedWidth = 0}
6123
+ __init164() {this.bakedHeight = 0}
6094
6124
  /** Gradient strokes can't be baked to a solid-color bitmap; they render per-frame. */
6095
6125
 
6096
6126
  /** Lazily-flattened polylines (one Float32Array of [x,y,...] per segment) for hit-testing. */
6097
- __init163() {this.polylines = null}
6127
+ __init165() {this.polylines = null}
6098
6128
  /**
6099
6129
  * When `true`, the renderer draws a rounded-rect outline of the entity's
6100
6130
  * local bounds after painting the curves. Useful for drag feedback and
6101
6131
  * debugging hit areas. Defaults to `false`.
6102
6132
  */
6103
- __init164() {this.showBounds = false}
6133
+ __init166() {this.showBounds = false}
6104
6134
  constructor(doc, opts = {}) {
6105
- super();_class10.prototype.__init159.call(this);_class10.prototype.__init160.call(this);_class10.prototype.__init161.call(this);_class10.prototype.__init162.call(this);_class10.prototype.__init163.call(this);_class10.prototype.__init164.call(this);;
6135
+ super();_class10.prototype.__init161.call(this);_class10.prototype.__init162.call(this);_class10.prototype.__init163.call(this);_class10.prototype.__init164.call(this);_class10.prototype.__init165.call(this);_class10.prototype.__init166.call(this);;
6106
6136
  this.doc = doc;
6107
6137
  this.lineWidth = _nullishCoalesce(opts.lineWidth, () => ( 2));
6108
6138
  this.cache = _nullishCoalesce(opts.cache, () => ( true));
@@ -6483,19 +6513,19 @@ var _math = require('@vectojs/math'); _createStarExport(_math);
6483
6513
  // src/tree/DOMPortalEntity.ts
6484
6514
  var DOMPortalEntity = (_class11 = class extends _chunkZ3HFY75Rjs.Entity {
6485
6515
 
6486
- __init165() {this.isDOMPortal = true}
6487
- __init166() {this.domListeners = []}
6488
- __init167() {this.resizeObserver = null}
6489
- __init168() {this.domBound = false}
6490
- __init169() {this.cachedWidth = 100}
6491
- __init170() {this.cachedHeight = 100}
6492
- __init171() {this.lastWidth = ""}
6493
- __init172() {this.lastHeight = ""}
6494
- __init173() {this.lastTransform = ""}
6495
- __init174() {this.lastZIndex = ""}
6496
- __init175() {this.lastOpacity = ""}
6516
+ __init167() {this.isDOMPortal = true}
6517
+ __init168() {this.domListeners = []}
6518
+ __init169() {this.resizeObserver = null}
6519
+ __init170() {this.domBound = false}
6520
+ __init171() {this.cachedWidth = 100}
6521
+ __init172() {this.cachedHeight = 100}
6522
+ __init173() {this.lastWidth = ""}
6523
+ __init174() {this.lastHeight = ""}
6524
+ __init175() {this.lastTransform = ""}
6525
+ __init176() {this.lastZIndex = ""}
6526
+ __init177() {this.lastOpacity = ""}
6497
6527
  constructor(domElement, width, height, id) {
6498
- super(id);_class11.prototype.__init165.call(this);_class11.prototype.__init166.call(this);_class11.prototype.__init167.call(this);_class11.prototype.__init168.call(this);_class11.prototype.__init169.call(this);_class11.prototype.__init170.call(this);_class11.prototype.__init171.call(this);_class11.prototype.__init172.call(this);_class11.prototype.__init173.call(this);_class11.prototype.__init174.call(this);_class11.prototype.__init175.call(this);;
6528
+ super(id);_class11.prototype.__init167.call(this);_class11.prototype.__init168.call(this);_class11.prototype.__init169.call(this);_class11.prototype.__init170.call(this);_class11.prototype.__init171.call(this);_class11.prototype.__init172.call(this);_class11.prototype.__init173.call(this);_class11.prototype.__init174.call(this);_class11.prototype.__init175.call(this);_class11.prototype.__init176.call(this);_class11.prototype.__init177.call(this);;
6499
6529
  this.domElement = domElement;
6500
6530
  this.width = _nullishCoalesce(width, () => ( 0));
6501
6531
  this.height = _nullishCoalesce(height, () => ( 0));
package/dist/index.mjs CHANGED
@@ -2001,6 +2001,16 @@ var Scene = class _Scene {
2001
2001
  activeIds = /* @__PURE__ */ new Set();
2002
2002
  /** Per-parent insertion cursor, reused by `enforceA11yDomOrder`. */
2003
2003
  a11yOrderCursors = /* @__PURE__ */ new Map();
2004
+ /** Membership set for the elements being ordered, reused per reorder pass. */
2005
+ a11yOrderMembers = /* @__PURE__ */ new Set();
2006
+ /**
2007
+ * Elements that are an *ancestor* of another ordered element, reused per pass.
2008
+ *
2009
+ * A composite widget's container (a `grid` around its rows, a `tree` around its
2010
+ * items) spans every descendant row, so it must not extend a visual row band —
2011
+ * see {@link sortNormalElementsVisually}.
2012
+ */
2013
+ a11yOrderContainers = /* @__PURE__ */ new Set();
2004
2014
  activePortalsThisFrame = /* @__PURE__ */ new Set();
2005
2015
  activePortalsPrevFrame = /* @__PURE__ */ new Set();
2006
2016
  portalEntities = /* @__PURE__ */ new Map();
@@ -4871,7 +4881,9 @@ var Scene = class _Scene {
4871
4881
  this.a11yOrderCursors.set(parent, at + 1);
4872
4882
  const current = parent.childNodes[at];
4873
4883
  if (current !== expected) {
4884
+ const refocus = document.activeElement === expected;
4874
4885
  parent.insertBefore(expected, current || null);
4886
+ if (refocus) expected.focus({ preventScroll: true });
4875
4887
  }
4876
4888
  }
4877
4889
  this.a11yNeedsReorder = false;
@@ -4900,19 +4912,37 @@ var Scene = class _Scene {
4900
4912
  const els = this.normalElements;
4901
4913
  if (els.length < 2) return;
4902
4914
  const rtl = this._readingDirection === "rtl";
4903
- const topOf = (el) => Number.parseFloat(el.style.top) || 0;
4904
- const leftOf = (el) => Number.parseFloat(el.style.left) || 0;
4905
4915
  const heightOf = (el) => Math.max(Number.parseFloat(el.style.height) || 0, 4);
4906
- const order = els.map((el, i) => ({
4907
- el,
4908
- i,
4909
- top: topOf(el),
4910
- left: leftOf(el)
4911
- }));
4916
+ const members = this.a11yOrderMembers;
4917
+ const containers = this.a11yOrderContainers;
4918
+ members.clear();
4919
+ containers.clear();
4920
+ for (const el of els) members.add(el);
4921
+ for (const el of els) {
4922
+ for (let p = el.parentElement; p; p = p.parentElement) {
4923
+ if (members.has(p)) containers.add(p);
4924
+ }
4925
+ }
4926
+ const absolute = (el) => {
4927
+ let top = 0;
4928
+ let left = 0;
4929
+ for (let node = el; node; node = node.parentElement) {
4930
+ top += Number.parseFloat(node.style.top) || 0;
4931
+ left += Number.parseFloat(node.style.left) || 0;
4932
+ const parent = node.parentElement;
4933
+ if (!parent || !members.has(parent)) break;
4934
+ }
4935
+ return { top, left };
4936
+ };
4937
+ const order = els.map((el, i) => {
4938
+ const { top, left } = absolute(el);
4939
+ return { el, i, top, left, container: containers.has(el) };
4940
+ });
4912
4941
  order.sort((p, q) => p.top - q.top || p.i - q.i);
4942
+ const bandBottom = (r) => r.top + (r.container ? 4 : heightOf(r.el));
4913
4943
  const sorted = [];
4914
4944
  let rowStart = 0;
4915
- let rowBottom = order.length ? order[0].top + heightOf(order[0].el) : 0;
4945
+ let rowBottom = order.length ? bandBottom(order[0]) : 0;
4916
4946
  const flushRow = (end) => {
4917
4947
  const row = order.slice(rowStart, end);
4918
4948
  row.sort((p, q) => (rtl ? q.left - p.left : p.left - q.left) || p.i - q.i);
@@ -4920,11 +4950,11 @@ var Scene = class _Scene {
4920
4950
  };
4921
4951
  for (let k = 1; k < order.length; k++) {
4922
4952
  if (order[k].top < rowBottom) {
4923
- rowBottom = Math.max(rowBottom, order[k].top + heightOf(order[k].el));
4953
+ rowBottom = Math.max(rowBottom, bandBottom(order[k]));
4924
4954
  } else {
4925
4955
  flushRow(k);
4926
4956
  rowStart = k;
4927
- rowBottom = order[k].top + heightOf(order[k].el);
4957
+ rowBottom = bandBottom(order[k]);
4928
4958
  }
4929
4959
  }
4930
4960
  flushRow(order.length);
@@ -568,6 +568,16 @@ export declare class Scene {
568
568
  private activeIds;
569
569
  /** Per-parent insertion cursor, reused by `enforceA11yDomOrder`. */
570
570
  private a11yOrderCursors;
571
+ /** Membership set for the elements being ordered, reused per reorder pass. */
572
+ private a11yOrderMembers;
573
+ /**
574
+ * Elements that are an *ancestor* of another ordered element, reused per pass.
575
+ *
576
+ * A composite widget's container (a `grid` around its rows, a `tree` around its
577
+ * items) spans every descendant row, so it must not extend a visual row band —
578
+ * see {@link sortNormalElementsVisually}.
579
+ */
580
+ private a11yOrderContainers;
571
581
  private activePortalsThisFrame;
572
582
  private activePortalsPrevFrame;
573
583
  private portalEntities;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vectojs/core",
3
- "version": "1.28.0",
3
+ "version": "1.28.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },