taffy-js 0.1.1 → 0.1.3

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/README.md CHANGED
@@ -13,6 +13,7 @@
13
13
  - **🎨 Modern Layouts**: Full support for **Flexbox** and **CSS Grid** specifications.
14
14
  - **🛠 Framework Agnostic**: Use it with React, Vue, Svelte, vanilla JS, or even in Node.js for server-side layout calculation.
15
15
  - **🔒 Type-Safe**: Fully typed API with TypeScript definitions included.
16
+ - **🐛 Debug Mode**: Optional verbose logging for debugging layout issues.
16
17
 
17
18
  ## 📦 Installation
18
19
 
@@ -22,9 +23,9 @@ npm install taffy-js
22
23
 
23
24
  > **Note**: This package relies on WebAssembly. Ensure your runtime (modern browser or Node.js) supports WASM.
24
25
 
25
- ## 🚀 Usage
26
+ ## 🚀 Quick Start
26
27
 
27
- Here is a complete example showing how to create a layout tree, style nodes, and compute results.
28
+ ### Functional API
28
29
 
29
30
  ```typescript
30
31
  import init, {
@@ -36,7 +37,6 @@ import init, {
36
37
  FlexDirection,
37
38
  AlignItems,
38
39
  JustifyContent,
39
- Style,
40
40
  } from "taffy-js";
41
41
 
42
42
  async function run() {
@@ -44,8 +44,7 @@ async function run() {
44
44
  await init();
45
45
 
46
46
  // 2. Define Styles
47
- // Styles match CSS properties. You can mix specific units like Pixels, Percent, or Auto.
48
- const boxStyle: Style = {
47
+ const boxStyle = {
49
48
  display: Display.Flex,
50
49
  width: { value: 100, unit: "Pixels" },
51
50
  height: { value: 100, unit: "Pixels" },
@@ -53,35 +52,22 @@ async function run() {
53
52
  align_items: AlignItems.Center,
54
53
  };
55
54
 
56
- const rootStyle: Style = {
55
+ const rootStyle = {
57
56
  display: Display.Flex,
58
- // layout 500x500 container
59
57
  width: { value: 500, unit: "Pixels" },
60
58
  height: { value: 500, unit: "Pixels" },
61
59
  flex_direction: FlexDirection.Row,
62
60
  justify_content: JustifyContent.SpaceAround,
63
61
  align_items: AlignItems.Center,
64
- gap: {
65
- width: { value: 20, unit: "Pixels" },
66
- height: { value: 0, unit: "Pixels" },
67
- }, // Example of potential gap usage if supported
68
62
  };
69
63
 
70
64
  // 3. Create Tree Nodes
71
- // Leaf nodes
72
65
  const child1 = new_leaf(boxStyle);
73
66
  const child2 = new_leaf(boxStyle);
74
-
75
- // Root node with children
76
67
  const root = new_with_children(rootStyle, [child1, child2]);
77
68
 
78
69
  // 4. Compute Layout
79
- // You can pass available space constraints (width/height).
80
- // Passing values corresponds to "Definite" size, null corresponds to "MaxContent/Available".
81
- compute_layout(root, {
82
- width: 500,
83
- height: 500,
84
- });
70
+ compute_layout(root, { width: 500, height: 500 });
85
71
 
86
72
  // 5. Retrieve Results
87
73
  const rootLayout = get_layout(root);
@@ -96,25 +82,77 @@ async function run() {
96
82
  run();
97
83
  ```
98
84
 
85
+ ### Object-Oriented API (Yoga-like)
86
+
87
+ The library also provides an OO wrapper for a more intuitive, Yoga-style experience:
88
+
89
+ ```typescript
90
+ import init, {
91
+ TaffyNode,
92
+ Display,
93
+ FlexDirection,
94
+ Edge,
95
+ Gutter,
96
+ } from "taffy-js";
97
+
98
+ async function run() {
99
+ await init();
100
+
101
+ // Create nodes using the OO API
102
+ const root = new TaffyNode({});
103
+ root.setDisplay(Display.Flex);
104
+ root.setFlexDirection(FlexDirection.Column);
105
+ root.setWidth(400);
106
+ root.setHeight(400);
107
+ root.setPadding(Edge.All, 10);
108
+ root.setGap(Gutter.Row, 8);
109
+
110
+ const child1 = new TaffyNode({});
111
+ child1.setHeight(100);
112
+ child1.setFlexGrow(1);
113
+
114
+ const child2 = new TaffyNode({});
115
+ child2.setHeight(50);
116
+
117
+ // Build the tree
118
+ root.addChild(child1);
119
+ root.addChild(child2);
120
+
121
+ // Compute layout
122
+ root.computeLayout({ width: 400, height: 400 });
123
+
124
+ // Get results
125
+ const layout = root.getLayout();
126
+ console.log("Root layout:", layout);
127
+ console.log("Child1 layout:", child1.getLayout());
128
+ console.log("Child2 layout:", child2.getLayout());
129
+
130
+ // Cleanup (optional - nodes are automatically freed when dropped)
131
+ root.free();
132
+ }
133
+
134
+ run();
135
+ ```
136
+
99
137
  ## 📐 Architecture
100
138
 
101
139
  `taffy-js` acts as a thin wrapper around the [Taffy](https://github.com/DioxusLabs/taffy) Rust crate.
102
140
 
103
- 1. **Node Tree**: You build a flat tree of nodes in the WASM memory space using integer IDs (`u32`).
141
+ 1. **Node Tree**: You build a flat tree of nodes in the WASM memory space using integer IDs (`u64`).
104
142
  2. **Style Transfer**: Styles are serialized from JS objects to Rust structs via `serde-wasm-bindgen`.
105
- 3. **Computation**: Rust runs the layout algorithms (Flexbox/Grid).
143
+ 3. **Computation**: Rust runs the layout algorithms (Flexbox/Grid/Block).
106
144
  4. **Readout**: You query the final computed geometry (x, y, width, height) back to JS.
107
145
 
108
146
  ## 📚 API Reference
109
147
 
110
148
  ### Lifecycle
111
149
 
112
- | Function | Description |
113
- | :------- | :------------------------------------------------------------------------------ |
114
- | `init()` | Initializes the WASM module. Must be awaited before calling any other function. |
115
- | `free()` | (Optional) Manually free memory if required by your specific WASM loader setup. |
150
+ | Function | Description |
151
+ | :-------- | :------------------------------------------------------------------------------ |
152
+ | `init()` | Initializes the WASM module. Must be awaited before calling any other function. |
153
+ | `clear()` | Clears all nodes from the layout tree, resetting to empty state. |
116
154
 
117
- ### Node Management
155
+ ### Node Management (Functional API)
118
156
 
119
157
  | Function | Signature | Description |
120
158
  | :------------------ | :--------------------------------------------- | :-------------------------------------- |
@@ -124,52 +162,274 @@ run();
124
162
  | `remove_child` | `(parent: number, child: number) -> void` | Removes a specific child from a parent. |
125
163
  | `set_children` | `(parent: number, children: number[]) -> void` | Replaces all children of a node. |
126
164
  | `remove_node` | `(node: number) -> void` | Deletes a node and frees its memory. |
127
-
128
- ### Layout & Style
129
-
130
- | Function | Signature | Description |
131
- | :--------------- | :---------------------------------------------- | :-------------------------------------------------------------------------- |
132
- | `set_style` | `(node: number, style: Style) -> void` | Updates the style properties of a node. |
133
- | `compute_layout` | `(root: number, space: AvailableSpace) -> void` | Triggers the layout calculation algorithm. |
134
- | `get_layout` | `(node: number) -> Layout` | Returns `{x, y, width, height}` for a node. |
135
- | `mark_dirty` | `(node: number) -> void` | Manually validates a node (usually handled automatically by style setters). |
165
+ | `get_children` | `(parent: number) -> number[]` | Returns an array of child node IDs. |
166
+ | `get_parent` | `(node: number) -> number \| null` | Returns the parent node ID, or null. |
167
+
168
+ ### Layout & Style (Functional API)
169
+
170
+ | Function | Signature | Description |
171
+ | :--------------- | :---------------------------------------------- | :--------------------------------------------------- |
172
+ | `set_style` | `(node: number, style: Style) -> void` | Updates the style properties of a node. |
173
+ | `compute_layout` | `(root: number, space: AvailableSpace) -> void` | Triggers the layout calculation algorithm. |
174
+ | `get_layout` | `(node: number) -> Layout` | Returns `{x, y, width, height}` for a node. |
175
+ | `mark_dirty` | `(node: number) -> void` | Manually marks a node as dirty, requiring re-layout. |
176
+ | `node_count` | `() -> number` | Returns the total number of nodes in the tree. |
177
+
178
+ ### Dimension Helpers
179
+
180
+ | Function | Signature | Description |
181
+ | :---------- | :-------------------------------------------------- | :-------------------------------------- |
182
+ | `px` | `(value: number) -> Dimension` | Creates a pixel dimension. |
183
+ | `percent` | `(value: number) -> Dimension` | Creates a percentage dimension. |
184
+ | `auto` | `() -> Dimension` | Creates an auto dimension. |
185
+ | `dimension` | `(value: number, unit: DimensionUnit) -> Dimension` | Creates a dimension with explicit unit. |
186
+
187
+ ### TaffyNode Class (OO API)
188
+
189
+ The `TaffyNode` class provides a Yoga-like object-oriented interface:
190
+
191
+ #### Constructor & Lifecycle
192
+
193
+ | Method | Description |
194
+ | :--------------------- | :------------------------------------------------------------ |
195
+ | `new TaffyNode(style)` | Creates a new node with the given style. |
196
+ | `free()` | Explicitly frees the node. Nodes are also auto-freed on drop. |
197
+
198
+ #### Style Methods
199
+
200
+ | Method | Description |
201
+ | :---------------------------- | :--------------------------------------------- |
202
+ | `setStyle(style)` | Updates the full style object. |
203
+ | `setDisplay(display)` | Sets display mode (Flex, Grid, Block, None). |
204
+ | `setPositionType(position)` | Sets positioning (Relative, Absolute). |
205
+ | `setFlexDirection(direction)` | Sets flex direction (Row, Column, etc.). |
206
+ | `setFlexWrap(wrap)` | Sets flex wrap behavior. |
207
+ | `setAlignItems(align)` | Sets cross-axis alignment for children. |
208
+ | `setAlignSelf(align)` | Sets cross-axis alignment for this item. |
209
+ | `setJustifyContent(justify)` | Sets main-axis alignment. |
210
+ | `setFlexGrow(value)` | Sets the flex grow factor. |
211
+ | `setFlexShrink(value)` | Sets the flex shrink factor. |
212
+ | `setFlexBasis(value)` | Sets flex basis in pixels. |
213
+ | `setFlexBasisPercent(value)` | Sets flex basis as percentage. |
214
+ | `setFlexBasisAuto()` | Sets flex basis to auto. |
215
+ | `setWidth(value)` | Sets width in pixels. |
216
+ | `setWidthPercent(value)` | Sets width as percentage. |
217
+ | `setWidthAuto()` | Sets width to auto. |
218
+ | `setHeight(value)` | Sets height in pixels. |
219
+ | `setHeightPercent(value)` | Sets height as percentage. |
220
+ | `setHeightAuto()` | Sets height to auto. |
221
+ | `setMinWidth(value)` | Sets minimum width in pixels. |
222
+ | `setMinWidthPercent(value)` | Sets minimum width as percentage. |
223
+ | `setMinHeight(value)` | Sets minimum height in pixels. |
224
+ | `setMinHeightPercent(value)` | Sets minimum height as percentage. |
225
+ | `setMargin(edge, value)` | Sets margin for specified edge(s). |
226
+ | `setMarginAuto(edge)` | Sets margin to auto for specified edge(s). |
227
+ | `setPadding(edge, value)` | Sets padding for specified edge(s). |
228
+ | `setBorder(edge, value)` | Sets border for specified edge(s). |
229
+ | `setGap(gutter, value)` | Sets gap between children. |
230
+ | `setMeasureFunc(fn)` | Sets a custom measure function for leaf nodes. |
231
+
232
+ #### Tree Methods
233
+
234
+ | Method | Description |
235
+ | :-------------------------- | :---------------------------------------- |
236
+ | `addChild(child)` | Appends a child node. |
237
+ | `insertChild(child, index)` | Inserts a child at the specified index. |
238
+ | `removeChild(child)` | Removes a child node. |
239
+ | `setChildren(childIds)` | Replaces all children with the given IDs. |
240
+
241
+ #### Layout Methods
242
+
243
+ | Method | Description |
244
+ | :------------------------------ | :------------------------------------ |
245
+ | `computeLayout(availableSpace)` | Computes layout for this subtree. |
246
+ | `getLayout()` | Returns the computed layout. |
247
+ | `markDirty()` | Marks this node as needing re-layout. |
136
248
 
137
249
  ### Type Definitions
138
250
 
139
251
  #### `Style`
140
252
 
141
- A comprehensive object mirroring CSS properties.
253
+ A comprehensive object mirroring CSS properties:
254
+
255
+ ```typescript
256
+ interface Style {
257
+ // Display & Position
258
+ display?: Display; // Flex, Grid, Block, None
259
+ position?: Position; // Relative, Absolute
260
+
261
+ // Dimensions
262
+ width?: Dimension;
263
+ height?: Dimension;
264
+ min_width?: Dimension;
265
+ min_height?: Dimension;
266
+ max_width?: Dimension;
267
+ max_height?: Dimension;
268
+
269
+ // Position offsets (for absolute positioning)
270
+ left?: Dimension;
271
+ right?: Dimension;
272
+ top?: Dimension;
273
+ bottom?: Dimension;
274
+
275
+ // Flexbox
276
+ flex_direction?: FlexDirection;
277
+ flex_wrap?: FlexWrap;
278
+ flex_grow?: number;
279
+ flex_shrink?: number;
280
+ flex_basis?: Dimension;
281
+ justify_content?: JustifyContent;
282
+ align_items?: AlignItems;
283
+ align_self?: AlignSelf;
284
+ align_content?: AlignContent;
285
+
286
+ // Spacing
287
+ margin_left?: Dimension;
288
+ margin_right?: Dimension;
289
+ margin_top?: Dimension;
290
+ margin_bottom?: Dimension;
291
+ padding_left?: Dimension;
292
+ padding_right?: Dimension;
293
+ padding_top?: Dimension;
294
+ padding_bottom?: Dimension;
295
+ row_gap?: Dimension;
296
+ column_gap?: Dimension;
297
+
298
+ // Grid
299
+ grid_template_rows?: TrackDefinition[];
300
+ grid_template_columns?: TrackDefinition[];
301
+ grid_auto_rows?: TrackDefinition[];
302
+ grid_auto_columns?: TrackDefinition[];
303
+ grid_auto_flow?: GridAutoFlow;
304
+ grid_row?: Line;
305
+ grid_column?: Line;
306
+ }
307
+ ```
308
+
309
+ #### `Dimension`
142
310
 
143
- - **Display**: `Display.Flex`, `Display.Grid`, `Display.None`
144
- - **Dimensions**: `{ value: number, unit: "Pixels" | "Percent" | "Auto" }`
145
- - **Flexbox**: `flex_direction`, `justify_content`, `align_items`, `flex_wrap`, etc.
146
- - **Grid**: `grid_template_rows`, `grid_template_columns`, etc.
311
+ ```typescript
312
+ interface Dimension {
313
+ value: number;
314
+ unit: "Pixels" | "Percent" | "Auto";
315
+ }
316
+ ```
147
317
 
148
318
  #### `AvailableSpace`
149
319
 
150
- Used when triggering computation.
320
+ Used when triggering layout computation:
151
321
 
152
322
  ```typescript
153
323
  interface AvailableSpace {
154
- width: number | null; // null = unlimited/content-based
155
- height: number | null; // null = unlimited/content-based
324
+ width?: number; // undefined = unlimited/content-based
325
+ height?: number; // undefined = unlimited/content-based
156
326
  }
157
327
  ```
158
328
 
329
+ #### `Layout`
330
+
331
+ The computed layout result:
332
+
333
+ ```typescript
334
+ interface Layout {
335
+ x: number; // X position relative to parent
336
+ y: number; // Y position relative to parent
337
+ width: number; // Computed width
338
+ height: number; // Computed height
339
+ }
340
+ ```
341
+
342
+ ### Enums
343
+
344
+ #### Display
345
+
346
+ - `Display.None` - Hidden, takes no space
347
+ - `Display.Flex` - Flexbox container
348
+ - `Display.Grid` - Grid container
349
+ - `Display.Block` - Block layout
350
+
351
+ #### Position
352
+
353
+ - `Position.Static` - Normal flow (treated as Relative)
354
+ - `Position.Relative` - Normal flow
355
+ - `Position.Absolute` - Removed from flow, positioned relative to containing block
356
+
357
+ #### FlexDirection
358
+
359
+ - `FlexDirection.Row` - Horizontal, left to right
360
+ - `FlexDirection.Column` - Vertical, top to bottom
361
+ - `FlexDirection.RowReverse` - Horizontal, right to left
362
+ - `FlexDirection.ColumnReverse` - Vertical, bottom to top
363
+
364
+ #### JustifyContent
365
+
366
+ - `JustifyContent.Start`, `FlexStart`
367
+ - `JustifyContent.End`, `FlexEnd`
368
+ - `JustifyContent.Center`
369
+ - `JustifyContent.SpaceBetween`
370
+ - `JustifyContent.SpaceAround`
371
+ - `JustifyContent.SpaceEvenly`
372
+
373
+ #### AlignItems / AlignSelf
374
+
375
+ - `Start`, `End`, `FlexStart`, `FlexEnd`
376
+ - `Center`, `Baseline`, `Stretch`
377
+ - `AlignSelf.Auto` (inherit from parent)
378
+
379
+ #### Edge
380
+
381
+ - `Edge.Left`, `Edge.Right`, `Edge.Top`, `Edge.Bottom`
382
+ - `Edge.Start`, `Edge.End` (logical)
383
+ - `Edge.Horizontal`, `Edge.Vertical`
384
+ - `Edge.All`
385
+
386
+ #### Gutter
387
+
388
+ - `Gutter.Column` - Gap between columns
389
+ - `Gutter.Row` - Gap between rows
390
+ - `Gutter.All` - Both directions
391
+
392
+ ## 🐛 Debug Logging
393
+
394
+ For development, you can enable verbose console logging by building with the `debug` feature:
395
+
396
+ ```bash
397
+ # When building from source
398
+ wasm-pack build --features debug
399
+ ```
400
+
401
+ When enabled, the library outputs detailed logs to the browser console including:
402
+
403
+ - Node creation and removal
404
+ - Style updates
405
+ - Layout computation details
406
+ - Error diagnostics
407
+
408
+ **Note**: Debug logging is disabled by default for optimal performance in production.
409
+
159
410
  ## 🛠 Building from Source
160
411
 
161
412
  If you want to contribute or build the WASM binary yourself:
162
413
 
163
414
  1. **Prerequisites**: Install Rust and `wasm-pack`.
415
+
164
416
  ```bash
165
417
  curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
166
418
  ```
167
- 2. **Build**:
419
+
420
+ 2. **Build** (production):
421
+
168
422
  ```bash
169
423
  npm install
170
424
  npm run build
171
425
  ```
172
- The artifacts will be generated in the `pkg/` directory.
426
+
427
+ 3. **Build** (with debug logging):
428
+ ```bash
429
+ wasm-pack build --features debug
430
+ ```
431
+
432
+ The artifacts will be generated in the `pkg/` directory.
173
433
 
174
434
  ## 📄 License
175
435
 
package/package.json CHANGED
@@ -1,38 +1,24 @@
1
1
  {
2
2
  "name": "taffy-js",
3
- "version": "0.1.1",
4
- "description": "WebAssembly bindings for Taffy layout library",
5
- "keywords": [
6
- "layout",
7
- "flexbox",
8
- "css-grid",
9
- "grid",
10
- "ui",
11
- "wasm",
12
- "webassembly"
3
+ "type": "module",
4
+ "collaborators": [
5
+ "ByteLandTechnology <github@byteland.app>"
13
6
  ],
7
+ "description": "WebAssembly bindings for Taffy layout library",
8
+ "version": "0.1.3",
14
9
  "license": "MIT",
15
10
  "repository": {
16
11
  "type": "git",
17
12
  "url": "https://github.com/ByteLandTechnology/taffy-js"
18
13
  },
19
- "main": "pkg/taffy_wasm.js",
20
- "types": "pkg/taffy_wasm.d.ts",
21
14
  "files": [
22
- "pkg"
15
+ "taffy_js_bg.wasm",
16
+ "taffy_js.js",
17
+ "taffy_js.d.ts"
23
18
  ],
24
- "scripts": {
25
- "build": "wasm-pack build --release --target web && rm pkg/.gitignore",
26
- "build:dev": "wasm-pack build --dev --target web",
27
- "test": "wasm-pack test --node"
28
- },
29
- "devDependencies": {
30
- "wasm-pack": "^0.13.1"
31
- },
32
- "engines": {
33
- "node": ">=12"
34
- },
35
- "overrides": {
36
- "axios": "^1.7.9"
37
- }
19
+ "main": "taffy_js.js",
20
+ "types": "taffy_js.d.ts",
21
+ "sideEffects": [
22
+ "./snippets/*"
23
+ ]
38
24
  }