サンプル
yoga-layout 3.2.1: Yoga 3 re-indexes PositionType (making 0 Static which silently drops insets), defaults to Errata.None where unpositioned absolute nodes include padding and percentages resolve against padding-box, isolates per-node scale factors, and maps column flex spacing to Gutter.Row
検証済みサンプル — npm yoga-layout 3.2.1: Yoga 3 re-indexes PositionType (making 0 Static which silently drops insets), defaults to Errata.None where unpositioned…
sha256:03f15f0805842659a9e2ee054e4b3bb4e0576a1f4686887fb2146938c59e962d
このネットワークが提供するのは一つだけです。ビルドされるサンプル。サンドボックスで実行し、署名済みの受領証を保管します。等級はつけず、何も保証しません — 同じコードがあなたの環境でビルドされるかは測定していません。
合格した契約受領証を提出した異なる署名鍵の数です。1 なら作者だけ、2 以上なら他の誰かもビルドしています。鍵は自己生成で背後に登録された身元がないため、数えているのは人ではなく鍵です。
MIT-0
実行証拠
宣言された環境と署名済みの実行を分けてあります。このサンプルが何をどこで実行したかをそのまま確認できます。
- 証拠の基準
- 署名済みコントラクト合格
- 検証レシート
- 3
- ビルドした署名鍵
- 3
宣言された環境
node linux x64 node node npm
検証実行環境
| 環境 | コントラクト | ステージ | 実行日 |
|---|---|---|---|
| node 22 · linux alpine/x64 · docker ed25519:d91480838ac982c9 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1 |
2026-08-16 |
| node 22 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1 |
2026-08-18 |
| node 22 · linux alpine/x64 · docker ed25519:c1973797be207ac4 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1node:22-alpine@sha256:c610fcdfb1d5… |
2026-09-07 |
ケース
HOW- ゴール
- Yoga 3 re-indexes PositionType (making 0 Static which silently drops insets), defaults to Errata.None where unpositioned absolute nodes include padding and percentages resolve against padding-box, isolates per-node scale factors, and maps column flex spacing to Gutter.Row
- パッケージ
- シンボル
-
- Yoga.Node
- Yoga.Config
- PositionType
- Errata
- Gutter
- loadYoga
- 環境
- node
- 作成日
- 2026-08-16T07:08:33Z
コントラクト
- assert PositionType enum shifted (Static=0, Relative=1, Absolute=2) and new nodes default to Relative
- assert PositionType.Static silently ignores top and left position insets without throwing while Relative offsets the node
- assert default Errata.None places auto-positioned absolute children at parent padding offsets rather than origin 0
- assert default Errata.None resolves percentage dimensions on absolute children against parent padding box rather than inner content box
- assert child nodes respect their own Config pointScaleFactor rather than inheriting root scale factor
- assert vertical spacing in FlexDirection.Column is controlled by Gutter.Row while Gutter.Column has no effect on child spacing
- assert yoga-layout/load exports async loadYoga loader and root ESM export provides ready pre-wrapped Yoga instance
ファイル
- NOTES.md
- csx.json
- package-lock.json
- package.json
- test/contract.mjs
ソース
# Notes
## Prior Search
`search_known_solution` returned no previous entries for `yoga-layout` (falling back to unrelated matches for `dotenv` and `detect-libc`).
## What a Model Writes Instead
A model imports `loadYoga` directly from `'yoga-layout'`, sets `node.setPositionType(0)` expecting `PositionType.Relative` offset behavior with `setPosition(Edge.Top, val)`, configures `setGap(Gutter.Column, val)` on a `FlexDirection.Column` layout to space child elements vertically, and assumes absolute children and percentage measurements exclude parent padding without configuring `Errata.Classic`.
## How the Wrong Version Fails
Fails silently with unexpected layout geometry: `PositionType.Static` (0 in v3) silently drops all `top`/`left` insets leaving calculated offsets at `0`, `Gutter.Column` has zero effect on `FlexDirection.Column` child spacing (leaving elements flush at `0px` gap instead of spaced), default `Errata.None` shifts absolute nodes by the parent's padding and expands percentage sizes against the full padding box rather than inner content box, and importing `{ loadYoga }` from `'yoga-layout'` crashes with `SyntaxError: The requested module 'yoga-layout' does not provide an export named 'loadYoga'`.
{"case":{"caseId":"case:sha256:908d7e426eea84efbd3e2d780d39cc163155eaae846581917e64108eaccba16e","contract":["assert PositionType enum shifted (Static=0, Relative=1, Absolute=2) and new nodes default to Relative","assert PositionType.Static silently ignores top and left position insets without throwing while Relative offsets the node","assert default Errata.None places auto-positioned absolute children at parent padding offsets rather than origin 0","assert default Errata.None resolves percentage dimensions on absolute children against parent padding box rather than inner content box","assert child nodes respect their own Config pointScaleFactor rather than inheriting root scale factor","assert vertical spacing in FlexDirection.Column is controlled by Gutter.Row while Gutter.Column has no effect on child spacing","assert yoga-layout/load exports async loadYoga loader and root ESM export provides ready pre-wrapped Yoga instance"],"goal":"Yoga 3 re-indexes PositionType (making 0 Static which silently drops insets), defaults to Errata.None where unpositioned absolute nodes include padding and percentages resolve against padding-box, isolates per-node scale factors, and maps column flex spacing to Gutter.Row","kind":"HOW","packages":["pkg:npm/yoga-layout@3.2.1"],"schemaVersion":1,"symbols":["Yoga.Node","Yoga.Config","PositionType","Errata","Gutter","loadYoga"]},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","ecosystem":"npm","executionContext":"node","language":"node","os":"linux","packageManager":"npm","runtime":"node","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/yoga-layout@3.2.1"],"schemaVersion":1,"symbols":["Yoga.Node","Yoga.Config","PositionType","Errata","Gutter","loadYoga"],"verifierAdapter":"node-typescript@1"}
{
"name": "csx-sample-npm-yoga-layout-version",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "csx-sample-npm-yoga-layout-version",
"version": "1.0.0",
"license": "MIT-0",
"dependencies": {
"yoga-layout": "3.2.1"
}
},
"node_modules/yoga-layout": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/yoga-layout/-/yoga-layout-3.2.1.tgz",
"integrity": "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==",
"license": "MIT"
}
}
}
{
"name": "csx-sample-npm-yoga-layout-version",
"version": "1.0.0",
"private": true,
"type": "module",
"license": "MIT-0",
"dependencies": {
"yoga-layout": "3.2.1"
}
}
import { strict as assert } from 'node:assert';
import Yoga, {
Align,
BoxSizing,
Direction,
Edge,
Errata,
FlexDirection,
Gutter,
Justify,
PositionType,
Unit
} from 'yoga-layout';
import { loadYoga } from 'yoga-layout/load';
// 1. POSITION TYPE ENUM SHIFT & STATIC INSET SILENT IGNORANCE
// In Yoga 1.x/2.x: Relative was 0, Absolute was 1.
// In Yoga 3.x: Static is 0, Relative is 1, Absolute is 2.
assert.equal(PositionType.Static, 0, 'PositionType.Static is enum index 0 in Yoga 3');
assert.equal(PositionType.Relative, 1, 'PositionType.Relative shifted to enum index 1 in Yoga 3');
assert.equal(PositionType.Absolute, 2, 'PositionType.Absolute shifted to enum index 2 in Yoga 3');
// Newly instantiated nodes default to Relative (1) for backward compatibility
const freshNode = Yoga.Node.create();
assert.equal(freshNode.getPositionType(), PositionType.Relative, 'New nodes default to PositionType.Relative (1)');
freshNode.free();
const parentContainer = Yoga.Node.create();
parentContainer.setWidth(200);
parentContainer.setHeight(200);
const staticChild = Yoga.Node.create();
staticChild.setPositionType(PositionType.Static);
staticChild.setWidth(50);
staticChild.setHeight(50);
staticChild.setPosition(Edge.Top, 30);
staticChild.setPosition(Edge.Left, 30);
parentContainer.insertChild(staticChild, 0);
parentContainer.calculateLayout(200, 200, Direction.LTR);
// Naive expectation: setting top/left insets on a static node moves it (top=30, left=30).
// Reality: Yoga 3 adheres to CSS spec and silently ignores insets on static nodes without throwing.
assert.equal(staticChild.getComputedTop(), 0, 'PositionType.Static silently ignores top insets');
assert.equal(staticChild.getComputedLeft(), 0, 'PositionType.Static silently ignores left insets');
// In contrast, Relative nodes apply insets as offsets
const relativeChild = Yoga.Node.create();
relativeChild.setPositionType(PositionType.Relative);
relativeChild.setWidth(50);
relativeChild.setHeight(50);
relativeChild.setPosition(Edge.Top, 30);
relativeChild.setPosition(Edge.Left, 30);
parentContainer.removeChild(staticChild);
parentContainer.insertChild(relativeChild, 0);
parentContainer.calculateLayout(200, 200, Direction.LTR);
assert.equal(relativeChild.getComputedTop(), 30, 'PositionType.Relative applies top insets');
assert.equal(relativeChild.getComputedLeft(), 30, 'PositionType.Relative applies left insets');
parentContainer.removeChild(relativeChild);
staticChild.free();
relativeChild.free();
// 2. ERRATA.NONE (DEFAULT) VS ERRATA.CLASSIC: ABSOLUTE POSITIONING WITH PADDING
// In Yoga 3 default (Errata.None), absolute children without insets start at padding offset.
// In Yoga 2.x / Errata.Classic, absolute children without insets ignored padding and started at (0, 0).
const paddedParent = Yoga.Node.create();
paddedParent.setWidth(200);
paddedParent.setHeight(200);
paddedParent.setPadding(Edge.Top, 20);
paddedParent.setPadding(Edge.Left, 20);
const defaultAbsChild = Yoga.Node.create();
defaultAbsChild.setPositionType(PositionType.Absolute);
defaultAbsChild.setWidth(60);
defaultAbsChild.setHeight(60);
paddedParent.insertChild(defaultAbsChild, 0);
paddedParent.calculateLayout(200, 200, Direction.LTR);
// Yoga 3 default respects padding for auto-positioned absolute children
assert.equal(defaultAbsChild.getComputedTop(), 20, 'Yoga 3 default places auto absolute child at padding top');
assert.equal(defaultAbsChild.getComputedLeft(), 20, 'Yoga 3 default places auto absolute child at padding left');
// With Errata.Classic (reproducing Yoga 2.x behavior)
const classicConfig = Yoga.Config.create();
classicConfig.setErrata(Errata.Classic);
const classicParent = Yoga.Node.create(classicConfig);
classicParent.setWidth(200);
classicParent.setHeight(200);
classicParent.setPadding(Edge.Top, 20);
classicParent.setPadding(Edge.Left, 20);
const classicAbsChild = Yoga.Node.create(classicConfig);
classicAbsChild.setPositionType(PositionType.Absolute);
classicAbsChild.setWidth(60);
classicAbsChild.setHeight(60);
classicParent.insertChild(classicAbsChild, 0);
classicParent.calculateLayout(200, 200, Direction.LTR);
// Classic behavior ignored padding
assert.equal(classicAbsChild.getComputedTop(), 0, 'Errata.Classic places auto absolute child at origin 0 ignoring padding');
assert.equal(classicAbsChild.getComputedLeft(), 0, 'Errata.Classic places auto absolute child at origin 0 ignoring padding');
// 3. ERRATA PERCENTAGE CALCULATION: PADDING BOX VS CONTENT BOX
// Yoga 3 default resolves percentages against full padding box (200 * 50% = 100).
// Errata.Classic resolves percentages against inner content box ((200 - 20) * 50% = 90).
const defaultPercentChild = Yoga.Node.create();
defaultPercentChild.setPositionType(PositionType.Absolute);
defaultPercentChild.setWidthPercent(50);
defaultPercentChild.setHeightPercent(50);
paddedParent.removeChild(defaultAbsChild);
paddedParent.insertChild(defaultPercentChild, 0);
paddedParent.calculateLayout(200, 200, Direction.LTR);
assert.equal(defaultPercentChild.getComputedWidth(), 100, 'Yoga 3 default resolves width percent against padding box');
const classicPercentChild = Yoga.Node.create(classicConfig);
classicPercentChild.setPositionType(PositionType.Absolute);
classicPercentChild.setWidthPercent(50);
classicPercentChild.setHeightPercent(50);
classicParent.removeChild(classicAbsChild);
classicParent.insertChild(classicPercentChild, 0);
classicParent.calculateLayout(200, 200, Direction.LTR);
assert.equal(classicPercentChild.getComputedWidth(), 90, 'Errata.Classic resolves width percent against inner content box');
paddedParent.freeRecursive();
classicParent.freeRecursive();
classicConfig.free();
// 4. PER-NODE POINT SCALE FACTOR INDEPENDENCE
// In Yoga 3, child nodes respect their own Config scale factor rather than root override
const rootScaleConfig = Yoga.Config.create();
rootScaleConfig.setPointScaleFactor(2.0); // 2x scale: rounds to 0.5px steps
const childScaleConfig = Yoga.Config.create();
childScaleConfig.setPointScaleFactor(1.0); // 1x scale: rounds to 1.0px steps
const scaleRoot = Yoga.Node.create(rootScaleConfig);
scaleRoot.setWidth(100.3);
scaleRoot.setHeight(100.3);
const scaleChild = Yoga.Node.create(childScaleConfig);
scaleChild.setWidth(50.3);
scaleChild.setHeight(50.3);
scaleRoot.insertChild(scaleChild, 0);
scaleRoot.calculateLayout(100.3, 100.3, Direction.LTR);
assert.equal(scaleRoot.getComputedWidth(), 100.5, 'Root node respects its 2.0 scale factor rounding (100.3 -> 100.5)');
assert.equal(scaleChild.getComputedWidth(), 50, 'Child node respects its own 1.0 scale factor rounding (50.3 -> 50)');
scaleRoot.freeRecursive();
rootScaleConfig.free();
childScaleConfig.free();
// 5. GUTTER ROW VS COLUMN AXIS MAPPING
// In FlexDirection.Column, vertical spacing between consecutive children is Gutter.Row, NOT Gutter.Column.
const colFlexNode = Yoga.Node.create();
colFlexNode.setFlexDirection(FlexDirection.Column);
colFlexNode.setWidth(100);
colFlexNode.setHeight(200);
// Setting Gutter.Column on Column flex layout has NO effect on vertical spacing
colFlexNode.setGap(Gutter.Column, 20);
const itemA = Yoga.Node.create(); itemA.setWidth(40); itemA.setHeight(30);
const itemB = Yoga.Node.create(); itemB.setWidth(40); itemB.setHeight(30);
colFlexNode.insertChild(itemA, 0);
colFlexNode.insertChild(itemB, 1);
colFlexNode.calculateLayout(100, 200, Direction.LTR);
assert.equal(itemA.getComputedTop(), 0);
assert.equal(itemB.getComputedTop(), 30, 'Gutter.Column in Column layout leaves item spacing at 0');
// Setting Gutter.Row applies vertical spacing between column items
colFlexNode.setGap(Gutter.Row, 20);
colFlexNode.calculateLayout(100, 200, Direction.LTR);
assert.equal(itemB.getComputedTop(), 50, 'Gutter.Row in Column layout applies 20px gap (30 + 20 = 50)');
colFlexNode.freeRecursive();
parentContainer.free();
// 6. ASYNC LOADING VIA LOAD ENTRYPOINT VS ESM DEFAULT EXPORT
assert.equal(typeof Yoga.Node.create, 'function', 'Default ESM import provides pre-initialized Yoga instance');
assert.equal(typeof loadYoga, 'function', 'loadYoga async loader is exported for explicit lifecycle handling');
const asyncYoga = await loadYoga();
assert.equal(typeof asyncYoga.Node.create, 'function', 'loadYoga() resolves to functional Yoga layout engine');
console.log('CONTRACT PASS: yoga-layout 3.x PositionType enum shifting, static inset dropping, Errata.Classic delta, scale factor isolation, and Gutter axis mapping verified');