@glissade/scene 0.24.0 → 0.25.0-pre.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/describe.js CHANGED
@@ -22,7 +22,7 @@ import { easings, listValueTypes } from "@glissade/core";
22
22
  * never pulled onto the base embed path — a scene that never calls `describe()`
23
23
  * pays zero bytes for it.
24
24
  */
25
- const RAW_VERSION = "0.24.0";
25
+ const RAW_VERSION = "0.25.0-pre.1";
26
26
  const PACKAGE_VERSION = RAW_VERSION.includes("GLISSADE_".concat("VERSION")) ? "0.0.0-dev" : RAW_VERSION;
27
27
  /** Arity of a value type's numeric repr: vec2/vec2-arc → 2, number → 1; others (color/paint/path/string/boolean) carry no scalar arity. */
28
28
  function arityOf(type) {
@@ -30,9 +30,21 @@ interface ApiExample {
30
30
  run: () => void;
31
31
  }
32
32
  declare const EXAMPLES: readonly ApiExample[];
33
- /** Group the corpus by describe-key → the surfaced code snippets. */
34
- declare function examplesByKey(): {
33
+ /**
34
+ * Rewrite an npm `import`-form snippet to the no-build IIFE form: every export is
35
+ * `window.glissade.<name>`, so `import { Rect, timeline } from '@glissade/scene'`
36
+ * becomes `const { Rect, timeline } = window.glissade`. The body is unchanged, so
37
+ * the snippet runs verbatim in a no-build `<script src>` page (§0.24 follow-up,
38
+ * card 7eC7Pb4wTbHj). Derived from the single npm-form source — no duplicate to
39
+ * maintain.
40
+ */
41
+ declare function toIifeForm(code: string): string;
42
+ /** Group the corpus by describe-key → the surfaced code snippets. `iife: true`
43
+ * rewrites each snippet to the no-build `window.glissade` form. */
44
+ declare function examplesByKey(opts?: {
45
+ iife?: boolean;
46
+ }): {
35
47
  readonly [key: string]: readonly string[];
36
48
  };
37
49
  //#endregion
38
- export { ApiExample, EXAMPLES, examplesByKey };
50
+ export { ApiExample, EXAMPLES, examplesByKey, toIifeForm };
package/dist/examples.js CHANGED
@@ -206,12 +206,24 @@ const EXAMPLES = [
206
206
  run: () => void motionPath(pathFromSvg("M0 0 C50 0 50 100 100 100")).atProgress(.5)
207
207
  }
208
208
  ];
209
- /** Group the corpus by describe-key → the surfaced code snippets. */
210
- function examplesByKey() {
209
+ /**
210
+ * Rewrite an npm `import`-form snippet to the no-build IIFE form: every export is
211
+ * `window.glissade.<name>`, so `import { Rect, timeline } from '@glissade/scene'`
212
+ * becomes `const { Rect, timeline } = window.glissade`. The body is unchanged, so
213
+ * the snippet runs verbatim in a no-build `<script src>` page (§0.24 follow-up,
214
+ * card 7eC7Pb4wTbHj). Derived from the single npm-form source — no duplicate to
215
+ * maintain.
216
+ */
217
+ function toIifeForm(code) {
218
+ return code.replace(/import\s+\{([^}]*)\}\s+from\s+'[^']*';?/g, (_m, names) => `const {${names}} = window.glissade;`);
219
+ }
220
+ /** Group the corpus by describe-key → the surfaced code snippets. `iife: true`
221
+ * rewrites each snippet to the no-build `window.glissade` form. */
222
+ function examplesByKey(opts = {}) {
211
223
  const byKey = {};
212
- for (const ex of EXAMPLES) (byKey[ex.key] ??= []).push(ex.code);
224
+ for (const ex of EXAMPLES) (byKey[ex.key] ??= []).push(opts.iife ? toIifeForm(ex.code) : ex.code);
213
225
  return byKey;
214
226
  }
215
227
  registerExamples(examplesByKey());
216
228
  //#endregion
217
- export { EXAMPLES, examplesByKey };
229
+ export { EXAMPLES, examplesByKey, toIifeForm };
package/dist/grid.d.ts CHANGED
@@ -40,6 +40,15 @@ interface GridProps extends NodeProps {
40
40
  * (v1 is position-only, so the grid does not measure child heights.)
41
41
  */
42
42
  cellHeight?: number;
43
+ /**
44
+ * Stretch each child to fill its cell (0.25): sets the child's `width` to its
45
+ * resolved column-track width and, when `cellHeight` is given, its `height` to
46
+ * `cellHeight` — a plain `signal.set`, so a later explicit bind still wins.
47
+ * Only children that expose a settable `width`/`height` signal (Rect/Image) are
48
+ * sized; others (Circle/Text/Path) keep their own size and are just positioned.
49
+ * Default false (position-only, byte-identical to v1).
50
+ */
51
+ stretch?: boolean;
43
52
  }
44
53
  /**
45
54
  * Lay `children` out into a column grid and return a `Group` holding them, each
package/dist/grid.js CHANGED
@@ -36,7 +36,8 @@ function resolveColumns(spec, columnGap, totalWidth) {
36
36
  }
37
37
  return {
38
38
  centers,
39
- width
39
+ width,
40
+ widths
40
41
  };
41
42
  }
42
43
  /**
@@ -50,11 +51,11 @@ function resolveColumns(spec, columnGap, totalWidth) {
50
51
  * rebinds it). Pass freshly constructed nodes for a clean, deterministic layout.
51
52
  */
52
53
  function Grid(props) {
53
- const { columns, gap = 0, columnGap, rowGap, width, cellHeight } = props;
54
+ const { columns, gap = 0, columnGap, rowGap, width, cellHeight, stretch = false } = props;
54
55
  const children = props.children ?? [];
55
56
  const colGap = columnGap ?? gap;
56
57
  const rowGapPx = rowGap ?? gap;
57
- const { centers, width: gridWidth } = resolveColumns(columns, colGap, width);
58
+ const { centers, width: gridWidth, widths: colWidths } = resolveColumns(columns, colGap, width);
58
59
  const cols = centers.length;
59
60
  const rows = Math.ceil(children.length / cols);
60
61
  if (rows > 1 && cellHeight === void 0) throw new GridError("Grid spanning more than one row needs `cellHeight` (the row pitch) — v1 is position-only and does not measure child heights");
@@ -68,15 +69,25 @@ function Grid(props) {
68
69
  const cx = ox + centers[col];
69
70
  const cy = oy + row * rowPitch + (cellHeight ?? 0) / 2;
70
71
  child.position.set([cx, cy]);
72
+ if (stretch) {
73
+ setDim(child, "width", colWidths[col]);
74
+ if (cellHeight !== void 0) setDim(child, "height", cellHeight);
75
+ }
71
76
  });
72
77
  return new Group({
73
78
  children,
74
79
  ...stripGridOnly(props)
75
80
  });
76
81
  }
82
+ /** Set a child's `width`/`height` signal IF it exposes one (Rect/Image do;
83
+ * Circle/Text/Path don't) — a plain `.set`, so a later explicit bind still wins. */
84
+ function setDim(child, prop, value) {
85
+ const sig = child[prop];
86
+ if (sig != null && typeof sig.set === "function") sig.set(value);
87
+ }
77
88
  /** Strip Grid's own props so the rest (id/position/opacity/…) pass to the Group. */
78
89
  function stripGridOnly(props) {
79
- const { columns, children, gap, columnGap, rowGap, width, cellHeight, ...nodeProps } = props;
90
+ const { columns, children, gap, columnGap, rowGap, width, cellHeight, stretch, ...nodeProps } = props;
80
91
  return nodeProps;
81
92
  }
82
93
  //#endregion
package/dist/scene.js CHANGED
@@ -71,6 +71,7 @@ function constructionPropMessage(nodes, target) {
71
71
  if (!node) continue;
72
72
  const prop = target.slice(slash + 1);
73
73
  if (isConstructionProp(node.describeType, prop)) return `'${target}' is a construction prop (animatable:false) — set it at construction (new ${node.describeType}({ ${prop} })); it is not an animatable target.`;
74
+ if (/^fill\.points\./.test(prop)) return `'${target}' does not resolve — a mesh Paint has no per-point sub-path targets. Animate the WHOLE fill as a paint track: track('${target.slice(0, slash)}/fill', 'paint', [key(0, meshA), key(1, meshB)]) — two same-point-count meshes interpolate their points pairwise (pos + color).`;
74
75
  return;
75
76
  }
76
77
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glissade/scene",
3
- "version": "0.24.0",
3
+ "version": "0.25.0-pre.1",
4
4
  "description": "glissade scene graph: nodes, transforms, DisplayList emission. Renderer-agnostic; zero DOM/Node dependencies.",
5
5
  "license": "Apache-2.0",
6
6
  "engines": {
@@ -65,7 +65,7 @@
65
65
  ],
66
66
  "dependencies": {
67
67
  "yoga-layout": "^3.2.1",
68
- "@glissade/core": "0.24.0"
68
+ "@glissade/core": "0.25.0-pre.1"
69
69
  },
70
70
  "repository": {
71
71
  "type": "git",