taffy-js 0.2.5 → 0.2.6

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