machinalayout 0.1.0 → 0.2.0

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.
Files changed (45) hide show
  1. package/README.md +280 -49
  2. package/dist/chunk-BJOQRPPX.js +382 -0
  3. package/dist/chunk-HU6XYOH7.js +133 -0
  4. package/dist/chunk-KYWOCAHK.js +205 -0
  5. package/dist/chunk-RJYRJ3LD.js +0 -0
  6. package/dist/chunk-TR24ERZT.js +66 -0
  7. package/dist/dispatch/index.d.ts +49 -0
  8. package/dist/dispatch/index.js +217 -0
  9. package/dist/index.d.ts +15 -238
  10. package/dist/index.js +596 -591
  11. package/dist/react/index.d.ts +33 -0
  12. package/dist/react/index.js +7 -0
  13. package/dist/react-native/index.d.ts +30 -0
  14. package/dist/react-native/index.js +83 -0
  15. package/dist/text/index.d.ts +10 -0
  16. package/dist/text/index.js +9 -0
  17. package/dist/text/react/index.d.ts +14 -0
  18. package/dist/text/react/index.js +7 -0
  19. package/dist/text/react-native/index.d.ts +16 -0
  20. package/dist/text/react-native/index.js +155 -0
  21. package/dist/text/vue/index.d.ts +113 -0
  22. package/dist/text/vue/index.js +202 -0
  23. package/dist/types-BudfpzZX.d.ts +184 -0
  24. package/dist/types-C4poVJpR.d.ts +74 -0
  25. package/dist/vue/index.d.ts +173 -0
  26. package/dist/vue/index.js +111 -0
  27. package/docs/adapter-packaging-a0-plan.md +352 -0
  28. package/docs/adapters.md +19 -0
  29. package/docs/api-coherence-m8-audit.md +397 -0
  30. package/docs/error-codes.md +84 -0
  31. package/docs/grid-arrange-m5a-contract.md +480 -0
  32. package/docs/grid-arrange.md +51 -0
  33. package/docs/layout-interpolation.md +52 -0
  34. package/docs/machina-dispatch-d0-contract.md +496 -0
  35. package/docs/machina-dispatch.md +143 -0
  36. package/docs/named-layers.md +40 -0
  37. package/docs/react-adapter.md +51 -69
  38. package/docs/react-native-adapter.md +56 -0
  39. package/docs/react-native-text-renderer.md +50 -0
  40. package/docs/reference-alignment-m7a-contract.md +384 -0
  41. package/docs/reference-alignment.md +44 -0
  42. package/docs/responsive-variants.md +54 -0
  43. package/docs/vue-adapter.md +55 -0
  44. package/docs/vue-text-renderer.md +55 -0
  45. package/package.json +60 -5
package/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # MachinaLayout
2
2
 
3
- MachinaLayout is a framework-independent, machine-native layout system that resolves flat typed layout records into deterministic rectangles.
3
+ MachinaLayout is a machine-native UI layout substrate: flat records in, deterministic rectangles out.
4
+
5
+ **CSS paints; Machina places.**
4
6
 
5
7
  ## Install
6
8
 
@@ -8,20 +10,111 @@ MachinaLayout is a framework-independent, machine-native layout system that reso
8
10
  npm install machinalayout
9
11
  ```
10
12
 
11
- ## Core principles
13
+ ## One-page mental model
14
+
15
+ 1. Author layout as flat `LayoutRow[]` records.
16
+ 2. Parent means coordinate ownership.
17
+ 3. `frame` decides a node rectangle.
18
+ 4. `arrange` decides direct child placement.
19
+ 5. Metadata (like `view`, `slot`, `z`, layers, data) shapes rendering behavior, not geometry solving.
20
+ 6. Variants are authoring-time row selection.
21
+ 7. The resolver outputs deterministic rectangles.
22
+ 8. Adapters render those rectangles.
23
+ 9. Text renders inside owned rectangles.
24
+ 10. CSS paints; Machina places.
25
+
26
+ ## Adapter philosophy
27
+
28
+ Machina adapters ask you to learn one layout model: Machina records. The framework adapter only asks for components in that framework.
29
+
30
+ - Machina adapters do not introduce a new layout model per framework.
31
+ - Layout stays framework-independent: author rows, resolve rectangles, render through adapters.
32
+ - Frameworks supply components; Machina supplies geometry.
33
+ - Users should not need framework-specific layout ceremony to place boxes.
34
+ - If you know TypeScript and what a component looks like in your renderer, that is enough.
35
+ - Adapter-specific details stay inside adapter internals.
36
+
37
+ **CSS paints; Machina places; adapters translate.**
38
+
39
+
40
+ ## Adapter/text subpath matrix
41
+
42
+ ### Layout adapters
43
+
44
+ - React DOM: `machinalayout/react`
45
+ - React Native: `machinalayout/react-native`
46
+ - Vue DOM: `machinalayout/vue`
47
+
48
+ ### Text
49
+
50
+ - Parser/core text: `machinalayout/text`
51
+
52
+ ### Text renderers
53
+
54
+ - React DOM: `machinalayout/text/react`
55
+ - React Native: `machinalayout/text/react-native`
56
+ - Vue DOM: `machinalayout/text/vue`
57
+
58
+ Subpath imports are preferred for adapters/renderers. Root imports remain valid during `0.x` compatibility windows.
59
+
60
+ Framework peers are adapter-specific (`react`/`react-dom`, `react-native`, `vue`) based on the subpaths you use.
61
+
62
+ Normal users should not need to learn each framework's layout/template box-drawing system: layout is Machina records, framework components are payloads rendered inside resolved rectangles.
63
+
64
+ ## Current capability summary
65
+
66
+ ### Core
67
+
68
+ - `RootFrame`
69
+ - `AbsoluteFrame`
70
+ - `AnchorFrame` with `UiLength`
71
+ - `GuideFrame`
72
+ - `FixedFrame`
73
+ - `FillFrame`
74
+ - `CellFrame`
75
+ - `StackArrange`
76
+ - `GridArrange`
77
+ - `OffsetSpec`
78
+ - responsive variants
79
+ - bounded `z`
80
+ - named layers
81
+ - layout interpolation helpers
82
+
83
+ ### React
84
+
85
+ - `MachinaReactView`
86
+ - effective render key: `view ?? slot`
87
+ - `viewData` / `nodeData`
88
+ - named layer paint ordering
89
+ - containment/content-visibility options
12
90
 
13
- - **Layout is data.**
14
- - **Rendering is an adapter.**
15
- - **Nesting is an output shape, not an authoring strategy.**
16
- - **MachinaLayout controls outer rectangles; host frameworks control view internals (using `view ?? slot`).**
91
+ ### Vue
17
92
 
18
- ## What problem it solves
93
+ - `MachinaVueView`
94
+ - same resolved-layout rectangle rendering model as React DOM
95
+ - effective render key: `view ?? slot`
96
+ - `viewData` / `nodeData`
97
+ - named layer paint ordering
98
+ - containment/content-visibility options
19
99
 
20
- MachinaLayout keeps geometry explicit and local:
100
+ ### Text
21
101
 
22
- - avoids vague CSS negotiation,
23
- - makes numeric layout edits predictable,
24
- - gives humans and LLMs a table/record-shaped layout format.
102
+ - MachinaText parser
103
+ - diagnostics
104
+ - `MachinaTextView`
105
+ - vertical rhythm policy
106
+
107
+ ### Sharp boundaries
108
+
109
+ - No portals/reparenting.
110
+ - No intrinsic text sizing driving outer layout.
111
+ - No general constraint solver.
112
+ - No CSS Grid clone.
113
+ - No auto-placement.
114
+
115
+ `GuideFrame` reads other nodes’ resolved geometry as a read-only alignment input. It preserves the one-parent model: parent remains the coordinate owner. `GuideFrame` does not portal, reparent DOM nodes, or escape clipping.
116
+
117
+ Named layers organize paint order over the existing bounded `z` system. Layers are not portals.
25
118
 
26
119
  ## Tiny `LayoutRow[]` example
27
120
 
@@ -42,14 +135,14 @@ const rows: LayoutRow[] = [
42
135
  parent: "root",
43
136
  order: 0,
44
137
  frame: { kind: "anchor", left: 0, right: 0, top: 0, height: 64 },
45
- slot: "header",
138
+ view: "header",
46
139
  },
47
140
  {
48
141
  id: "sidebar",
49
142
  parent: "root",
50
143
  order: 1,
51
144
  frame: { kind: "anchor", left: 0, top: 64, bottom: 0, width: 240 },
52
- slot: "sidebar",
145
+ view: "sidebar",
53
146
  },
54
147
  {
55
148
  id: "toolbar",
@@ -70,7 +163,7 @@ const rows: LayoutRow[] = [
70
163
  parent: "toolbar",
71
164
  order: 0,
72
165
  frame: { kind: "fixed", width: 120, height: 40 },
73
- slot: "toolbarButton",
166
+ view: "toolbarButton",
74
167
  },
75
168
  ];
76
169
 
@@ -78,12 +171,18 @@ const rootRect: Rect = { x: 0, y: 0, width: 1024, height: 640 };
78
171
  const resolved = resolveLayoutRows(rows, rootRect);
79
172
  ```
80
173
 
174
+ `view` is the preferred author-facing render key. `slot` remains valid as the adapter-facing technical key. The effective render key is `view ?? slot`.
175
+
81
176
  ## React adapter quick example
82
177
 
83
178
  ```tsx
84
- import { MachinaReactView, resolveLayoutRows } from "machinalayout";
179
+ import { resolveLayoutRows } from "machinalayout";
180
+ import { MachinaReactView } from "machinalayout/react";
181
+ import { parseMachinaText } from "machinalayout/text";
182
+ import { MachinaTextView } from "machinalayout/text/react";
85
183
 
86
184
  const resolved = resolveLayoutRows(rows, rootRect);
185
+ const textAst = parseMachinaText("Hello");
87
186
 
88
187
  const views = {
89
188
  header: HeaderView,
@@ -96,60 +195,192 @@ export function App() {
96
195
  }
97
196
  ```
98
197
 
99
- ## Sample demo
100
198
 
101
- See [`samples/control-room`](samples/control-room/README.md).
199
+ Subpath imports are the preferred path for adapters (`machinalayout/react`, `machinalayout/react-native`, `machinalayout/vue`, `machinalayout/text`, `machinalayout/text/react`, `machinalayout/text/react-native`, `machinalayout/text/vue`).
102
200
 
103
- Run it locally:
201
+ `machinalayout/react-native` and `machinalayout/text/react-native` require the `react-native` peer dependency in your app, and `machinalayout/vue` / `machinalayout/text/vue` require the `vue` peer dependency in your app. Root imports remain valid for compatibility during `0.x`.
104
202
 
105
- ```bash
106
- cd samples/control-room
107
- npm install
108
- npm run dev
203
+ ## Unified adapter usage pattern
204
+
205
+ ```ts
206
+ import { resolveLayoutRows, type LayoutRow } from "machinalayout";
207
+
208
+ const rows: LayoutRow[] = [
209
+ { id: "root", frame: { kind: "root" } },
210
+ {
211
+ id: "sidebar",
212
+ parent: "root",
213
+ frame: { kind: "anchor", left: 0, top: 0, bottom: 0, width: 240 },
214
+ view: "Sidebar",
215
+ },
216
+ ];
217
+
218
+ const layout = resolveLayoutRows(rows, { x: 0, y: 0, width: 1200, height: 800 });
219
+ ```
220
+
221
+ ```tsx
222
+ import { MachinaReactView } from "machinalayout/react";
223
+ const views = { Sidebar };
224
+ <MachinaReactView layout={layout} views={views} />;
225
+ ```
226
+
227
+ ```tsx
228
+ import { MachinaReactNativeView } from "machinalayout/react-native";
229
+ const views = { Sidebar };
230
+ <MachinaReactNativeView layout={layout} views={views} />;
231
+ ```
232
+
233
+ ```vue
234
+ <script setup lang="ts">
235
+ import { MachinaVueView } from "machinalayout/vue";
236
+ const views = { Sidebar };
237
+ </script>
238
+
239
+ <template>
240
+ <MachinaVueView :layout="layout" :views="views" />
241
+ </template>
109
242
  ```
110
243
 
111
- ## M0 scope (current)
244
+ Keep `views` stable (component references), and send changing data through `viewData` / `nodeData`:
245
+
246
+ ```tsx
247
+ const views = { Inspector };
248
+
249
+ <MachinaReactView
250
+ layout={layout}
251
+ views={views}
252
+ viewData={{ Inspector: inspectorData }}
253
+ />;
254
+ ```
255
+
256
+ ```tsx
257
+ const views = {
258
+ Inspector: () => <Inspector value={value} />,
259
+ };
260
+ ```
112
261
 
113
- M0 supports:
262
+ ## Public API index
114
263
 
115
- - `RootFrame` (M1a)
264
+ ### Core authoring/types
265
+
266
+ - `LayoutRow`
267
+ - `FrameSpec`
268
+ - `ArrangeSpec`
269
+ - `UiLength`
270
+ - `OffsetSpec`
271
+
272
+ ### Frames
273
+
274
+ - `RootFrame`
116
275
  - `AbsoluteFrame`
117
276
  - `AnchorFrame`
277
+ - `GuideFrame`
118
278
  - `FixedFrame`
119
- - `FillFrame` (M1b, stack-child weighted fill)
279
+ - `FillFrame`
280
+ - `CellFrame`
281
+
282
+ ### Arrangers
283
+
120
284
  - `StackArrange`
121
- - bounded sibling-local z metadata
122
- - React adapter
285
+ - `GridArrange`
286
+
287
+ ### Core functions
288
+
289
+ - `compileLayoutRows`
290
+ - `selectLayoutRowsForRoot`
291
+ - `resolveLayoutRows`
292
+ - `resolveLayoutDocument`
293
+ - `resolveFrame`
294
+ - `lerpResolvedLayouts`
295
+
296
+ ### Resolved helpers
297
+
298
+ - `toResolvedTree`
299
+ - `flattenResolvedTree`
300
+ - `formatRect`
301
+
302
+ ### React
303
+
304
+ - `MachinaReactView`
305
+ - `MachinaReactViewProps`
306
+ - `MachinaSlotProps`
307
+ - `MachinaRenderLayer`
308
+
309
+ ### Text
123
310
 
124
- M0 does **not** support:
311
+ - `parseMachinaText`
312
+ - `MachinaTextView`
313
+ - `MachinaTextSpec`
314
+ - `MachinaTextDocument`
125
315
 
126
- - FlowBox
127
- - wrapping
128
- - flexbox-style shrink/basis/min/max negotiation
129
- - intrinsic sizing
130
- - text measurement
131
- - routing
132
- - state management
133
- - CSS layout authority for Machina rectangles
316
+ ### Error
317
+
318
+ - `MachinaLayoutError`
319
+ - `MachinaLayoutErrorCode`
320
+
321
+ ## Sample demos
322
+
323
+ - [`samples/control-room`](samples/control-room/README.md)
324
+ - [`samples/music-player`](samples/music-player/README.md)
325
+ - [`samples/dispatch-counter`](samples/dispatch-counter/README.md)
326
+
327
+ Run it locally:
328
+
329
+ ```bash
330
+ cd samples/control-room
331
+ npm install
332
+ npm run dev
333
+ ```
334
+
335
+ ## Formatting
336
+
337
+ This repo uses Biome.
338
+
339
+ - `npm run format` rewrites files.
340
+ - `npm run format:check` checks formatting.
341
+ - `npm run lint` runs Biome lint rules.
342
+ - Generated `dist/` is ignored by Biome.
134
343
 
135
344
  ## Documentation
136
345
 
346
+ ### Milestones and audits
347
+
137
348
  - [M0 contract](docs/m0-contract.md)
138
- - [Row model](docs/row-model.md)
139
- - [Frames and stack](docs/frames-and-stack.md)
140
- - [React adapter boundary](docs/react-adapter.md)
141
- - [Z-order and containment](docs/z-order-and-containment.md)
142
- - [Forbidden concepts](docs/forbidden-concepts.md)
349
+ - [M1/M2 MachinaText plan notes](docs/machina-text-m2a-plan.md)
350
+ - [M2z npm prepublish audit](docs/npm-prepublish-m2z-audit.md)
351
+ - [M3c npm cleanup audit](docs/npm-prepublish-m3c-cleanup.md)
352
+ - [M4 interpolation guide](docs/layout-interpolation.md)
353
+ - [M5a GridArrange design contract](docs/grid-arrange-m5a-contract.md)
354
+ - [M7a reference alignment design contract](docs/reference-alignment-m7a-contract.md)
355
+ - [M8 API coherence audit](docs/api-coherence-m8-audit.md)
356
+ - [A0 adapter packaging plan](docs/adapter-packaging-a0-plan.md)
143
357
 
358
+ ### Core layout model
144
359
 
145
- ## M1c typed UI lengths
360
+ - [Row model](docs/row-model.md)
361
+ - [Frames and stack](docs/frames-and-stack.md)
362
+ - [Grid arrange runtime guide](docs/grid-arrange.md)
363
+ - [Reference alignment runtime guide](docs/reference-alignment.md)
364
+ - [Responsive variants](docs/responsive-variants.md)
365
+ - [Named layers](docs/named-layers.md)
366
+ - [Layout interpolation](docs/layout-interpolation.md)
146
367
 
147
- Anchor fields now accept typed `UiLength` values in addition to numeric pixels:
368
+ ### Adapters and text
148
369
 
149
- - `number` (implicit px)
150
- - `{ unit: "px", value: number }`
151
- - `{ unit: "ui", value: number }` (normalized against parent axis)
370
+ - [Adapter overview](docs/adapters.md)
371
+ - [React adapter boundary](docs/react-adapter.md)
372
+ - [React Native adapter](docs/react-native-adapter.md)
373
+ - [Vue adapter](docs/vue-adapter.md)
374
+ - [A0 adapter packaging plan](docs/adapter-packaging-a0-plan.md)
375
+ - [MachinaText parser](docs/machina-text-parser.md)
376
+ - [MachinaText React renderer](docs/machina-text-react.md)
377
+ - [MachinaText React Native renderer](docs/react-native-text-renderer.md)
378
+ - [MachinaText Vue renderer](docs/vue-text-renderer.md)
152
379
 
153
- Example: `left: { unit: "ui", value: 0.25 }`.
380
+ ### Boundaries and diagnostics
154
381
 
155
- - node-level `OffsetSpec` post-placement nudges (M1d, not margins)
382
+ - [Forbidden concepts](docs/forbidden-concepts.md)
383
+ - [Z-order and containment](docs/z-order-and-containment.md)
384
+ - [Error code reference](docs/error-codes.md)
385
+ - [MachinaDispatch runtime guide](docs/machina-dispatch.md)
386
+ - Dispatch sample: [`samples/dispatch-counter`](samples/dispatch-counter/README.md) (uses `machinalayout/dispatch`)