@solidrt/3d 0.0.69 → 0.0.70

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/AGENTS.md CHANGED
@@ -629,6 +629,16 @@ or fixed is decided at mount; `output` requires explicit sizes (the
629
629
  target cannot follow a leaf it does not own), and giving exactly one of
630
630
  width/height throws.
631
631
 
632
+ The fill leaf is size-contained (`contain="size"`, the CSS layout prop
633
+ every element takes): it adds nothing to its ancestors' sizes, exactly as
634
+ an empty `<view>` at 100% would. So a column of header, `<Scene>` pane
635
+ (`flexGrow: 1`) and footer lays out at the window's height with no
636
+ `minHeight={0}` anywhere, and a pane with no definite height does not
637
+ come out square. The price is that the leaf has no size of its own at
638
+ all: a parent with no size leaves it empty, the scene is invisible, and
639
+ the component warns once with the stack of the component that built it,
640
+ naming the fix (a size, or flexGrow in a sized column).
641
+
632
642
  Fixed sizes still matter where the target is a measured quantity: probes
633
643
  and checks that snapshot exact pixels, supersampling via `output`, or a
634
644
  scene composited at a size unrelated to its layout. `width`/`height` are
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidrt/3d",
3
- "version": "0.0.69",
3
+ "version": "0.0.70",
4
4
  "license": "MIT",
5
5
  "funding": "https://github.com/sponsors/wellawaretech",
6
6
  "author": "Antoine van Wel",
@@ -20,10 +20,10 @@
20
20
  "AGENTS.md"
21
21
  ],
22
22
  "devDependencies": {
23
- "@solidrt/test": "0.0.69"
23
+ "@solidrt/test": "0.0.70"
24
24
  },
25
25
  "peerDependencies": {
26
26
  "@solidjs/signals": "2.0.0-rc.13",
27
- "@solidrt/core": "0.0.69"
27
+ "@solidrt/core": "0.0.70"
28
28
  }
29
29
  }
@@ -1,4 +1,4 @@
1
- import { createEffect, createRenderEffect, createSignal, displayScale, getBoundingBoxViewport, getLayoutBox, onCleanup, onLayout, untrack } from "@solidrt/core"
1
+ import { createEffect, createRenderEffect, createSignal, displayScale, getBoundingBoxViewport, getLayoutBox, onCleanup, onLayout, untrack, warnOnce } from "@solidrt/core"
2
2
  import type { Element, ParentComponent, PointerFeed, TextureId } from "@solidrt/core"
3
3
  import { SceneContext } from "./context.tsx"
4
4
  import { createScene } from "../scene.ts"
@@ -311,11 +311,22 @@ export let Scene: ParentComponent<SceneProps> = props => {
311
311
  // onLayout handler and as an effect apply, both untracked scopes, so
312
312
  // its scale read is wrapped in an explicit untrack (the effect's
313
313
  // compute is what tracks it).
314
+ let warnEmpty = warnOnce()
314
315
  let apply = () =>
315
316
  untrack(() => {
316
317
  if (!leafNode) return
317
318
  let box = getBoundingBoxViewport(leafNode)
318
319
  if (!box) return
320
+ // The leaf adds no size of its own (contain="size" below), so a
321
+ // parent with no size leaves it empty: nothing renders, and nothing
322
+ // on screen says why.
323
+ if (box.width === 0 || box.height === 0) {
324
+ warnEmpty(
325
+ `Scene: the fill leaf laid out ${box.width} x ${box.height}, so the scene is invisible. ` +
326
+ `It adds no size of its own: give its parent a size (width/height, or flexGrow in a sized column), as on the web.`,
327
+ )
328
+ return
329
+ }
319
330
  let scale = displayScale()
320
331
  scene.setSize(Math.max(1, Math.round(box.width * scale)), Math.max(1, Math.round(box.height * scale)))
321
332
  })
@@ -325,6 +336,11 @@ export let Scene: ParentComponent<SceneProps> = props => {
325
336
  // Pointer events on the built-in leaf: at target size the plain
326
337
  // handlers, in fill mode scaled from the laid-out box.
327
338
  let sceneHandlers = fill ? scene.handlersFor(builtinLayout) : scene.handlers
339
+ // The fill leaf is size-contained: the target follows the leaf's box, so
340
+ // the target's pixels must never come back as the leaf's intrinsic size
341
+ // (the flex automatic minimum would pin every ancestor to the target, and
342
+ // an indefinite height would come out square). The leaf adds nothing to
343
+ // its ancestors, exactly as an empty view at 100% would.
328
344
  return (
329
345
  <SceneContext value={{ scene, parent: scene.root, viewport: scene, pointer }}>
330
346
  {output ? (
@@ -335,6 +351,7 @@ export let Scene: ParentComponent<SceneProps> = props => {
335
351
  src={scene.texture}
336
352
  width={fill ? "100%" : props.width}
337
353
  height={fill ? "100%" : props.height}
354
+ contain={fill ? "size" : undefined}
338
355
  onPointerDown={events ? sceneHandlers.onPointerDown : undefined}
339
356
  onPointerMove={events ? sceneHandlers.onPointerMove : undefined}
340
357
  onPointerUp={events ? sceneHandlers.onPointerUp : undefined}