taffy-js 0.2.5 → 0.2.7

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
@@ -44,18 +44,13 @@ async function main() {
44
44
  containerStyle.display = Display.Flex;
45
45
  containerStyle.flexDirection = FlexDirection.Column;
46
46
  containerStyle.alignItems = AlignItems.Center;
47
- containerStyle.size = { width: { Length: 300 }, height: { Length: 200 } };
48
- containerStyle.padding = {
49
- left: { Length: 10 },
50
- right: { Length: 10 },
51
- top: { Length: 10 },
52
- bottom: { Length: 10 },
53
- };
47
+ containerStyle.size = { width: 300, height: 200 };
48
+ containerStyle.padding = { left: 10, right: 10, top: 10, bottom: 10 };
54
49
 
55
50
  // Create child styles
56
51
  const childStyle = new Style();
57
52
  childStyle.flexGrow = 1;
58
- childStyle.size = { width: { Percent: 100 }, height: "Auto" };
53
+ childStyle.size = { width: "100%", height: "auto" };
59
54
 
60
55
  // Create nodes
61
56
  const child1 = tree.newLeaf(childStyle);
@@ -66,10 +61,7 @@ async function main() {
66
61
  );
67
62
 
68
63
  // Compute layout
69
- tree.computeLayout(container, {
70
- width: { Definite: 300 },
71
- height: { Definite: 200 },
72
- });
64
+ tree.computeLayout(container, { width: 300, height: 200 });
73
65
 
74
66
  // Read computed layouts
75
67
  const containerLayout = tree.getLayout(container);
@@ -311,10 +303,10 @@ enum BoxSizing {
311
303
  ### Types
312
304
 
313
305
  ```typescript
314
- // Dimension values
315
- type Dimension = { Length: number } | { Percent: number } | "Auto";
316
- type LengthPercentage = { Length: number } | { Percent: number };
317
- type LengthPercentageAuto = { Length: number } | { Percent: number } | "Auto";
306
+ // Dimension values (CSS-like syntax)
307
+ type Dimension = number | `${number}%` | "auto"; // e.g., 100, "50%", "auto"
308
+ type LengthPercentage = number | `${number}%`; // e.g., 10, "25%"
309
+ type LengthPercentageAuto = number | `${number}%` | "auto";
318
310
 
319
311
  // Geometry
320
312
  interface Size<T> {
@@ -333,7 +325,7 @@ interface Point<T> {
333
325
  }
334
326
 
335
327
  // Available space for layout computation
336
- type AvailableSpace = { Definite: number } | "MinContent" | "MaxContent";
328
+ type AvailableSpace = number | "MinContent" | "MaxContent";
337
329
 
338
330
  // Measure function for custom content measurement
339
331
  type MeasureFunction = (
@@ -354,7 +346,7 @@ const textNode = tree.newLeafWithContext(textStyle, { text: "Hello, World!" });
354
346
 
355
347
  tree.computeLayoutWithMeasure(
356
348
  rootNode,
357
- { width: { Definite: 800 }, height: "MaxContent" },
349
+ { width: 800, height: "MaxContent" },
358
350
  (known, available, node, context, style) => {
359
351
  if (context?.text) {
360
352
  // Your text measurement logic here
@@ -399,7 +391,7 @@ const rowStyle = new Style();
399
391
  rowStyle.display = Display.Flex;
400
392
  rowStyle.flexDirection = FlexDirection.Row;
401
393
  rowStyle.justifyContent = JustifyContent.SpaceBetween;
402
- rowStyle.gap = { width: { Length: 10 }, height: { Length: 0 } };
394
+ rowStyle.gap = { width: 10, height: 0 };
403
395
  ```
404
396
 
405
397
  ### Absolute Positioning
@@ -407,13 +399,8 @@ rowStyle.gap = { width: { Length: 10 }, height: { Length: 0 } };
407
399
  ```javascript
408
400
  const absoluteStyle = new Style();
409
401
  absoluteStyle.position = Position.Absolute;
410
- absoluteStyle.inset = {
411
- left: { Length: 10 },
412
- top: { Length: 10 },
413
- right: "Auto",
414
- bottom: "Auto",
415
- };
416
- absoluteStyle.size = { width: { Length: 100 }, height: { Length: 50 } };
402
+ absoluteStyle.inset = { left: 10, top: 10, right: "auto", bottom: "auto" };
403
+ absoluteStyle.size = { width: 100, height: 50 };
417
404
  ```
418
405
 
419
406
  ### Percentage Sizing
@@ -421,8 +408,8 @@ absoluteStyle.size = { width: { Length: 100 }, height: { Length: 50 } };
421
408
  ```javascript
422
409
  const percentStyle = new Style();
423
410
  percentStyle.size = {
424
- width: { Percent: 50 }, // 50% of parent
425
- height: { Percent: 100 }, // 100% of parent
411
+ width: "50%", // 50% of parent
412
+ height: "100%", // 100% of parent
426
413
  };
427
414
  ```
428
415
 
@@ -430,7 +417,7 @@ percentStyle.size = {
430
417
 
431
418
  ```bash
432
419
  # Clone the repository
433
- git clone https://github.com/user/taffy-js.git
420
+ git clone https://github.com/ByteLandTechnology/taffy-js.git
434
421
  cd taffy-js
435
422
 
436
423
  # Install dependencies
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taffy-js",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "WebAssembly bindings for Taffy layout library",
5
5
  "keywords": [
6
6
  "layout",
@@ -40,7 +40,7 @@
40
40
  ],
41
41
  "scripts": {
42
42
  "build": "npm run build:wasm && npm run build:ts && npm run docs",
43
- "build:wasm": "wasm-pack build --release --target web && npm run patch-dts",
43
+ "build:wasm": "wasm-pack build --release --target web && rm -f pkg/.gitignore && npm run patch-dts",
44
44
  "build:ts": "tsc",
45
45
  "build:dev": "wasm-pack build --dev --target web && npm run patch-dts && npm run build:ts",
46
46
  "docs": "typedoc && prettier --write docs",
@@ -76,4 +76,4 @@
76
76
  "*.{js,ts,jsx,tsx,json,md,yaml,yml}": "prettier --write",
77
77
  "*.rs": "cargo fmt --"
78
78
  }
79
- }
79
+ }
package/pkg/README.md ADDED
@@ -0,0 +1,440 @@
1
+ # Taffy-JS
2
+
3
+ [![npm version](https://badge.fury.io/js/taffy-js.svg)](https://www.npmjs.com/package/taffy-js)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ High-performance WebAssembly bindings for the [Taffy](https://github.com/DioxusLabs/taffy) layout engine, bringing CSS Flexbox and Grid layout algorithms to JavaScript with near-native performance.
7
+
8
+ ## ✨ Features
9
+
10
+ - **🚀 High Performance**: WebAssembly-powered layout calculations
11
+ - **📦 Complete CSS Support**: Full Flexbox and CSS Grid implementation
12
+ - **🔧 Custom Measurement**: Support for custom text/content measurement callbacks
13
+ - **📝 TypeScript Ready**: Complete type definitions included
14
+ - **🌳 Tree-Based API**: Efficient tree structure for complex layouts
15
+ - **💡 Familiar API**: CSS-like property names and values
16
+
17
+ ## 📦 Installation
18
+
19
+ ```bash
20
+ npm install taffy-js
21
+ ```
22
+
23
+ ## 🚀 Quick Start
24
+
25
+ ```javascript
26
+ import {
27
+ loadTaffy,
28
+ TaffyTree,
29
+ Style,
30
+ Display,
31
+ FlexDirection,
32
+ AlignItems,
33
+ } from "taffy-js";
34
+
35
+ async function main() {
36
+ // Initialize WebAssembly module
37
+ await loadTaffy();
38
+
39
+ // Create a layout tree
40
+ const tree = new TaffyTree();
41
+
42
+ // Create container style
43
+ const containerStyle = new Style();
44
+ containerStyle.display = Display.Flex;
45
+ containerStyle.flexDirection = FlexDirection.Column;
46
+ containerStyle.alignItems = AlignItems.Center;
47
+ containerStyle.size = { width: 300, height: 200 };
48
+ containerStyle.padding = { left: 10, right: 10, top: 10, bottom: 10 };
49
+
50
+ // Create child styles
51
+ const childStyle = new Style();
52
+ childStyle.flexGrow = 1;
53
+ childStyle.size = { width: "100%", height: "auto" };
54
+
55
+ // Create nodes
56
+ const child1 = tree.newLeaf(childStyle);
57
+ const child2 = tree.newLeaf(childStyle);
58
+ const container = tree.newWithChildren(
59
+ containerStyle,
60
+ BigUint64Array.from([child1, child2]),
61
+ );
62
+
63
+ // Compute layout
64
+ tree.computeLayout(container, { width: 300, height: 200 });
65
+
66
+ // Read computed layouts
67
+ const containerLayout = tree.getLayout(container);
68
+ const child1Layout = tree.getLayout(child1);
69
+ const child2Layout = tree.getLayout(child2);
70
+
71
+ console.log(`Container: ${containerLayout.width}x${containerLayout.height}`);
72
+ console.log(
73
+ `Child 1: ${child1Layout.width}x${child1Layout.height} at (${child1Layout.x}, ${child1Layout.y})`,
74
+ );
75
+ console.log(
76
+ `Child 2: ${child2Layout.width}x${child2Layout.height} at (${child2Layout.x}, ${child2Layout.y})`,
77
+ );
78
+ }
79
+
80
+ main();
81
+ ```
82
+
83
+ ## 📖 API Reference
84
+
85
+ ### TaffyTree
86
+
87
+ The main class for managing layout trees.
88
+
89
+ ```typescript
90
+ class TaffyTree {
91
+ // Construction
92
+ constructor();
93
+ static withCapacity(capacity: number): TaffyTree;
94
+
95
+ // Node Creation (throws TaffyError on failure)
96
+ newLeaf(style: Style): bigint;
97
+ newLeafWithContext(style: Style, context: any): bigint;
98
+ newWithChildren(style: Style, children: BigUint64Array): bigint;
99
+
100
+ // Tree Operations
101
+ clear(): void;
102
+ remove(node: bigint): bigint; // throws TaffyError
103
+ totalNodeCount(): number;
104
+
105
+ // Child Management (throws TaffyError on failure)
106
+ addChild(parent: bigint, child: bigint): void;
107
+ removeChild(parent: bigint, child: bigint): bigint;
108
+ setChildren(parent: bigint, children: BigUint64Array): void;
109
+ children(parent: bigint): BigUint64Array;
110
+ childCount(parent: bigint): number;
111
+ parent(child: bigint): bigint | undefined;
112
+
113
+ // Style Management (throws TaffyError on failure)
114
+ setStyle(node: bigint, style: Style): void;
115
+ getStyle(node: bigint): Style;
116
+
117
+ // Layout Computation (throws TaffyError on failure)
118
+ computeLayout(node: bigint, availableSpace: Size<AvailableSpace>): void;
119
+ computeLayoutWithMeasure(
120
+ node: bigint,
121
+ availableSpace: Size<AvailableSpace>,
122
+ measureFunc: MeasureFunction,
123
+ ): void;
124
+
125
+ // Layout Results (throws TaffyError on failure)
126
+ getLayout(node: bigint): Layout;
127
+ unroundedLayout(node: bigint): Layout;
128
+
129
+ // Dirty Tracking (throws TaffyError on failure)
130
+ markDirty(node: bigint): void;
131
+ dirty(node: bigint): boolean;
132
+
133
+ // Configuration
134
+ enableRounding(): void;
135
+ disableRounding(): void;
136
+ }
137
+ ```
138
+
139
+ ### Style
140
+
141
+ Configuration object for node layout properties.
142
+
143
+ ```typescript
144
+ class Style {
145
+ constructor();
146
+
147
+ // Layout Mode
148
+ display: Display; // Block, Flex, Grid, None
149
+ position: Position; // Relative, Absolute
150
+
151
+ // Flexbox
152
+ flexDirection: FlexDirection; // Row, Column, RowReverse, ColumnReverse
153
+ flexWrap: FlexWrap; // NoWrap, Wrap, WrapReverse
154
+ flexGrow: number; // Growth factor (default: 0)
155
+ flexShrink: number; // Shrink factor (default: 1)
156
+ flexBasis: Dimension; // Initial size
157
+
158
+ // Alignment
159
+ alignItems: AlignItems | undefined;
160
+ alignSelf: AlignSelf | undefined;
161
+ alignContent: AlignContent | undefined;
162
+ justifyContent: JustifyContent | undefined;
163
+
164
+ // Sizing
165
+ size: Size<Dimension>; // Width and height
166
+ minSize: Size<Dimension>; // Minimum constraints
167
+ maxSize: Size<Dimension>; // Maximum constraints
168
+ aspectRatio: number | undefined; // Width/height ratio
169
+ boxSizing: BoxSizing; // BorderBox, ContentBox
170
+
171
+ // Spacing
172
+ margin: Rect<LengthPercentageAuto>;
173
+ padding: Rect<LengthPercentage>;
174
+ border: Rect<LengthPercentage>;
175
+ gap: Size<LengthPercentage>; // Row and column gap
176
+ inset: Rect<LengthPercentageAuto>; // For absolute positioning
177
+
178
+ // Overflow
179
+ overflow: Point<Overflow>;
180
+ }
181
+ ```
182
+
183
+ ### Layout
184
+
185
+ Read-only computed layout result.
186
+
187
+ ```typescript
188
+ class Layout {
189
+ // Position (relative to parent)
190
+ readonly x: number;
191
+ readonly y: number;
192
+
193
+ // Size
194
+ readonly width: number;
195
+ readonly height: number;
196
+
197
+ // Content size (for scrollable content)
198
+ readonly contentWidth: number;
199
+ readonly contentHeight: number;
200
+
201
+ // Spacing
202
+ readonly paddingTop: number;
203
+ readonly paddingRight: number;
204
+ readonly paddingBottom: number;
205
+ readonly paddingLeft: number;
206
+
207
+ readonly borderTop: number;
208
+ readonly borderRight: number;
209
+ readonly borderBottom: number;
210
+ readonly borderLeft: number;
211
+
212
+ readonly marginTop: number;
213
+ readonly marginRight: number;
214
+ readonly marginBottom: number;
215
+ readonly marginLeft: number;
216
+
217
+ // Scrollbars
218
+ readonly scrollbarWidth: number;
219
+ readonly scrollbarHeight: number;
220
+
221
+ // Rendering order
222
+ readonly order: number;
223
+ }
224
+ ```
225
+
226
+ ### Enums
227
+
228
+ ```typescript
229
+ enum Display {
230
+ Block,
231
+ Flex,
232
+ Grid,
233
+ None,
234
+ }
235
+ enum Position {
236
+ Relative,
237
+ Absolute,
238
+ }
239
+ enum FlexDirection {
240
+ Row,
241
+ Column,
242
+ RowReverse,
243
+ ColumnReverse,
244
+ }
245
+ enum FlexWrap {
246
+ NoWrap,
247
+ Wrap,
248
+ WrapReverse,
249
+ }
250
+ enum AlignItems {
251
+ Start,
252
+ End,
253
+ FlexStart,
254
+ FlexEnd,
255
+ Center,
256
+ Baseline,
257
+ Stretch,
258
+ }
259
+ enum AlignSelf {
260
+ Auto,
261
+ Start,
262
+ End,
263
+ FlexStart,
264
+ FlexEnd,
265
+ Center,
266
+ Baseline,
267
+ Stretch,
268
+ }
269
+ enum AlignContent {
270
+ Start,
271
+ End,
272
+ FlexStart,
273
+ FlexEnd,
274
+ Center,
275
+ Stretch,
276
+ SpaceBetween,
277
+ SpaceAround,
278
+ SpaceEvenly,
279
+ }
280
+ enum JustifyContent {
281
+ Start,
282
+ End,
283
+ FlexStart,
284
+ FlexEnd,
285
+ Center,
286
+ Stretch,
287
+ SpaceBetween,
288
+ SpaceAround,
289
+ SpaceEvenly,
290
+ }
291
+ enum Overflow {
292
+ Visible,
293
+ Hidden,
294
+ Scroll,
295
+ Auto,
296
+ }
297
+ enum BoxSizing {
298
+ BorderBox,
299
+ ContentBox,
300
+ }
301
+ ```
302
+
303
+ ### Types
304
+
305
+ ```typescript
306
+ // Dimension values (CSS-like syntax)
307
+ type Dimension = number | `${number}%` | "auto"; // e.g., 100, "50%", "auto"
308
+ type LengthPercentage = number | `${number}%`; // e.g., 10, "25%"
309
+ type LengthPercentageAuto = number | `${number}%` | "auto";
310
+
311
+ // Geometry
312
+ interface Size<T> {
313
+ width: T;
314
+ height: T;
315
+ }
316
+ interface Rect<T> {
317
+ left: T;
318
+ right: T;
319
+ top: T;
320
+ bottom: T;
321
+ }
322
+ interface Point<T> {
323
+ x: T;
324
+ y: T;
325
+ }
326
+
327
+ // Available space for layout computation
328
+ type AvailableSpace = number | "MinContent" | "MaxContent";
329
+
330
+ // Measure function for custom content measurement
331
+ type MeasureFunction = (
332
+ knownDimensions: Size<number | null>,
333
+ availableSpace: Size<AvailableSpace>,
334
+ node: bigint,
335
+ context: any,
336
+ style: Style,
337
+ ) => Size<number>;
338
+ ```
339
+
340
+ ## 📐 Custom Text Measurement
341
+
342
+ For text nodes or other content that needs dynamic measurement:
343
+
344
+ ```javascript
345
+ const textNode = tree.newLeafWithContext(textStyle, { text: "Hello, World!" });
346
+
347
+ tree.computeLayoutWithMeasure(
348
+ rootNode,
349
+ { width: 800, height: "MaxContent" },
350
+ (known, available, node, context, style) => {
351
+ if (context?.text) {
352
+ // Your text measurement logic here
353
+ const width = measureTextWidth(context.text);
354
+ const height = measureTextHeight(context.text, available.width);
355
+ return { width, height };
356
+ }
357
+ return { width: 0, height: 0 };
358
+ },
359
+ );
360
+ ```
361
+
362
+ ## 🔧 Error Handling
363
+
364
+ Methods that can fail throw a `TaffyError` as a JavaScript exception. Use try-catch to handle errors:
365
+
366
+ ```javascript
367
+ try {
368
+ const nodeId = tree.newLeaf(style);
369
+ console.log("Created node:", nodeId);
370
+ } catch (error) {
371
+ // error is a TaffyError instance
372
+ console.error("Error:", error.message);
373
+ }
374
+ ```
375
+
376
+ ## 🌐 Browser Support
377
+
378
+ Taffy-JS works in all modern browsers that support WebAssembly:
379
+
380
+ - Chrome 57+
381
+ - Firefox 52+
382
+ - Safari 11+
383
+ - Edge 16+
384
+
385
+ ## 📚 Examples
386
+
387
+ ### Flexbox Row Layout
388
+
389
+ ```javascript
390
+ const rowStyle = new Style();
391
+ rowStyle.display = Display.Flex;
392
+ rowStyle.flexDirection = FlexDirection.Row;
393
+ rowStyle.justifyContent = JustifyContent.SpaceBetween;
394
+ rowStyle.gap = { width: 10, height: 0 };
395
+ ```
396
+
397
+ ### Absolute Positioning
398
+
399
+ ```javascript
400
+ const absoluteStyle = new Style();
401
+ absoluteStyle.position = Position.Absolute;
402
+ absoluteStyle.inset = { left: 10, top: 10, right: "auto", bottom: "auto" };
403
+ absoluteStyle.size = { width: 100, height: 50 };
404
+ ```
405
+
406
+ ### Percentage Sizing
407
+
408
+ ```javascript
409
+ const percentStyle = new Style();
410
+ percentStyle.size = {
411
+ width: "50%", // 50% of parent
412
+ height: "100%", // 100% of parent
413
+ };
414
+ ```
415
+
416
+ ## 🏗️ Building from Source
417
+
418
+ ```bash
419
+ # Clone the repository
420
+ git clone https://github.com/ByteLandTechnology/taffy-js.git
421
+ cd taffy-js
422
+
423
+ # Install dependencies
424
+ npm install
425
+
426
+ # Build the WebAssembly module
427
+ npm run build
428
+
429
+ # Run tests
430
+ npm test
431
+ ```
432
+
433
+ ## 📄 License
434
+
435
+ MIT License - see [LICENSE](LICENSE) for details.
436
+
437
+ ## 🙏 Acknowledgments
438
+
439
+ - [Taffy](https://github.com/DioxusLabs/taffy) - The Rust layout engine this project wraps
440
+ - [wasm-bindgen](https://github.com/rustwasm/wasm-bindgen) - Rust/WebAssembly interoperability
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "taffy-wasm",
3
+ "type": "module",
4
+ "collaborators": [
5
+ "ByteLandTechnology <github@byteland.app>"
6
+ ],
7
+ "description": "WebAssembly bindings for Taffy layout library",
8
+ "version": "0.9.5",
9
+ "license": "MIT",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/ByteLandTechnology/taffy-js"
13
+ },
14
+ "files": [
15
+ "taffy_wasm_bg.wasm",
16
+ "taffy_wasm.js",
17
+ "taffy_wasm.d.ts"
18
+ ],
19
+ "main": "taffy_wasm.js",
20
+ "types": "taffy_wasm.d.ts",
21
+ "sideEffects": [
22
+ "./snippets/*"
23
+ ]
24
+ }