taffy-js 0.1.2 → 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.
- package/README.md +422 -114
- package/package.json +50 -16
- package/taffy_js.d.ts +0 -1142
- package/taffy_js.js +0 -2413
- package/taffy_js_bg.wasm +0 -0
package/README.md
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
# Taffy WebAssembly Bindings
|
|
1
|
+
# Taffy-JS: WebAssembly Bindings for Taffy Layout Engine
|
|
2
2
|
|
|
3
3
|
> **High-performance Flexbox and CSS Grid layout for JavaScript/TypeScript, powered by Rust and WebAssembly.**
|
|
4
4
|
|
|
5
5
|
  
|
|
6
6
|
|
|
7
|
-
**Taffy** is a
|
|
7
|
+
**Taffy** is a high-performance UI layout library written in Rust. This package (`taffy-js`) provides WebAssembly bindings, enabling JavaScript/TypeScript applications to use standards-compliant Flexbox, CSS Grid, and Block layout algorithms with near-native performance.
|
|
8
8
|
|
|
9
9
|
## ✨ Features
|
|
10
10
|
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
11
|
+
- 🚀 **High Performance** – Rust + WebAssembly for complex layout computations
|
|
12
|
+
- 📦 **Tiny Footprint** – Optimized WASM binary size
|
|
13
|
+
- 🎨 **Modern Layouts** – Full Flexbox, CSS Grid, and Block layout support
|
|
14
|
+
- 🛠 **Framework Agnostic** – Works with React, Vue, Svelte, vanilla JS, Node.js
|
|
15
|
+
- 🔒 **Type-Safe** – Full TypeScript definitions included
|
|
16
|
+
- 📐 **Custom Measurement** – Support for text measurement via callback functions
|
|
16
17
|
|
|
17
18
|
## 📦 Installation
|
|
18
19
|
|
|
@@ -20,156 +21,463 @@
|
|
|
20
21
|
npm install taffy-js
|
|
21
22
|
```
|
|
22
23
|
|
|
23
|
-
> **Note**:
|
|
24
|
+
> **Note**: Requires a runtime that supports WebAssembly (all modern browsers and Node.js 12+).
|
|
24
25
|
|
|
25
|
-
## 🚀
|
|
26
|
-
|
|
27
|
-
Here is a complete example showing how to create a layout tree, style nodes, and compute results.
|
|
26
|
+
## 🚀 Quick Start
|
|
28
27
|
|
|
29
28
|
```typescript
|
|
30
29
|
import init, {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
compute_layout,
|
|
34
|
-
get_layout,
|
|
30
|
+
TaffyTree,
|
|
31
|
+
Style,
|
|
35
32
|
Display,
|
|
36
33
|
FlexDirection,
|
|
37
34
|
AlignItems,
|
|
38
35
|
JustifyContent,
|
|
39
|
-
Style,
|
|
40
36
|
} from "taffy-js";
|
|
41
37
|
|
|
42
|
-
async function
|
|
43
|
-
// 1. Initialize
|
|
38
|
+
async function main() {
|
|
39
|
+
// 1. Initialize WASM module
|
|
44
40
|
await init();
|
|
45
41
|
|
|
46
|
-
// 2.
|
|
47
|
-
|
|
48
|
-
const boxStyle: Style = {
|
|
49
|
-
display: Display.Flex,
|
|
50
|
-
width: { value: 100, unit: "Pixels" },
|
|
51
|
-
height: { value: 100, unit: "Pixels" },
|
|
52
|
-
justify_content: JustifyContent.Center,
|
|
53
|
-
align_items: AlignItems.Center,
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
const rootStyle: Style = {
|
|
57
|
-
display: Display.Flex,
|
|
58
|
-
// layout 500x500 container
|
|
59
|
-
width: { value: 500, unit: "Pixels" },
|
|
60
|
-
height: { value: 500, unit: "Pixels" },
|
|
61
|
-
flex_direction: FlexDirection.Row,
|
|
62
|
-
justify_content: JustifyContent.SpaceAround,
|
|
63
|
-
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
|
-
};
|
|
69
|
-
|
|
70
|
-
// 3. Create Tree Nodes
|
|
71
|
-
// Leaf nodes
|
|
72
|
-
const child1 = new_leaf(boxStyle);
|
|
73
|
-
const child2 = new_leaf(boxStyle);
|
|
74
|
-
|
|
75
|
-
// Root node with children
|
|
76
|
-
const root = new_with_children(rootStyle, [child1, child2]);
|
|
77
|
-
|
|
78
|
-
// 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
|
-
});
|
|
42
|
+
// 2. Create tree and styles
|
|
43
|
+
const tree = new TaffyTree();
|
|
85
44
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
45
|
+
const rootStyle = new Style();
|
|
46
|
+
rootStyle.display = Display.Flex;
|
|
47
|
+
rootStyle.flex_direction = FlexDirection.Row;
|
|
48
|
+
rootStyle.justify_content = JustifyContent.SpaceAround;
|
|
49
|
+
rootStyle.align_items = AlignItems.Center;
|
|
50
|
+
rootStyle.size = { width: { Length: 500 }, height: { Length: 400 } };
|
|
51
|
+
|
|
52
|
+
const childStyle = new Style();
|
|
53
|
+
childStyle.size = { width: { Length: 100 }, height: { Length: 100 } };
|
|
54
|
+
|
|
55
|
+
// 3. Build the tree
|
|
56
|
+
const child1 = tree.newLeaf(childStyle);
|
|
57
|
+
const child2 = tree.newLeaf(childStyle);
|
|
58
|
+
const root = tree.newWithChildren(rootStyle, [child1, child2]);
|
|
59
|
+
|
|
60
|
+
// 4. Compute layout
|
|
61
|
+
tree.computeLayout(root, {
|
|
62
|
+
width: { Definite: 500 },
|
|
63
|
+
height: { Definite: 400 },
|
|
64
|
+
});
|
|
90
65
|
|
|
91
|
-
|
|
92
|
-
console.log("
|
|
93
|
-
console.log("Child
|
|
66
|
+
// 5. Read results
|
|
67
|
+
console.log("Root:", tree.getLayout(root));
|
|
68
|
+
console.log("Child 1:", tree.getLayout(child1));
|
|
69
|
+
console.log("Child 2:", tree.getLayout(child2));
|
|
94
70
|
}
|
|
95
71
|
|
|
96
|
-
|
|
72
|
+
main();
|
|
97
73
|
```
|
|
98
74
|
|
|
99
75
|
## 📐 Architecture
|
|
100
76
|
|
|
101
|
-
|
|
77
|
+
The library is organized into four main components:
|
|
102
78
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
79
|
+
| Component | Description |
|
|
80
|
+
| :------------ | :------------------------------------------------------------------------------------ |
|
|
81
|
+
| **Enums** | CSS layout enum types (Display, Position, FlexDirection, FlexWrap, AlignItems, etc.) |
|
|
82
|
+
| **DTOs** | Data Transfer Objects for JS ↔ Rust serialization (JsDimension, JsSize, JsRect, etc.) |
|
|
83
|
+
| **Style** | Node style configuration with getter/setter methods for all CSS layout properties |
|
|
84
|
+
| **TaffyTree** | Layout tree manager for node creation, tree manipulation, and layout computation |
|
|
85
|
+
|
|
86
|
+
### How It Works
|
|
87
|
+
|
|
88
|
+
1. **Create Tree** – Instantiate a `TaffyTree` to manage layout nodes
|
|
89
|
+
2. **Define Styles** – Create `Style` objects and set CSS layout properties
|
|
90
|
+
3. **Build Nodes** – Use `newLeaf()` or `newWithChildren()` to create nodes
|
|
91
|
+
4. **Compute Layout** – Call `computeLayout()` on the root node
|
|
92
|
+
5. **Read Results** – Use `getLayout()` to retrieve computed positions and sizes
|
|
93
|
+
|
|
94
|
+
---
|
|
107
95
|
|
|
108
96
|
## 📚 API Reference
|
|
109
97
|
|
|
110
|
-
###
|
|
98
|
+
### TaffyTree Class
|
|
99
|
+
|
|
100
|
+
The main entry point for layout computation.
|
|
101
|
+
|
|
102
|
+
#### Constructors
|
|
103
|
+
|
|
104
|
+
| Method | Description |
|
|
105
|
+
| :-------------------------- | :------------------------------------------------------- |
|
|
106
|
+
| `new TaffyTree()` | Creates a new empty layout tree |
|
|
107
|
+
| `TaffyTree.withCapacity(n)` | Creates a tree with pre-allocated capacity for `n` nodes |
|
|
108
|
+
|
|
109
|
+
#### Configuration
|
|
110
|
+
|
|
111
|
+
| Method | Description |
|
|
112
|
+
| :------------------ | :------------------------------------------------------- |
|
|
113
|
+
| `enableRounding()` | Enables rounding layout values to whole pixels (default) |
|
|
114
|
+
| `disableRounding()` | Disables rounding for sub-pixel precision |
|
|
115
|
+
|
|
116
|
+
#### Node Creation
|
|
117
|
+
|
|
118
|
+
| Method | Signature | Description |
|
|
119
|
+
| :------------------- | :-------------------------------------------- | :---------------------------------------- |
|
|
120
|
+
| `newLeaf` | `(style: Style) → number` | Creates a leaf node (no children) |
|
|
121
|
+
| `newLeafWithContext` | `(style: Style, context: any) → number` | Creates a leaf with attached context data |
|
|
122
|
+
| `newWithChildren` | `(style: Style, children: number[]) → number` | Creates a container node with children |
|
|
123
|
+
|
|
124
|
+
#### Style Management
|
|
125
|
+
|
|
126
|
+
| Method | Signature | Description |
|
|
127
|
+
| :--------- | :------------------------------------ | :----------------------------------- |
|
|
128
|
+
| `setStyle` | `(node: number, style: Style) → void` | Updates a node's style (marks dirty) |
|
|
129
|
+
| `getStyle` | `(node: number) → Style` | Returns a copy of the node's style |
|
|
130
|
+
|
|
131
|
+
#### Tree Operations
|
|
132
|
+
|
|
133
|
+
| Method | Signature | Description |
|
|
134
|
+
| :-------------------- | :-------------------------------- | :----------------------------- |
|
|
135
|
+
| `addChild` | `(parent, child) → void` | Appends a child to a parent |
|
|
136
|
+
| `removeChild` | `(parent, child) → number` | Removes and returns the child |
|
|
137
|
+
| `removeChildAtIndex` | `(parent, index) → number` | Removes child at index |
|
|
138
|
+
| `insertChildAtIndex` | `(parent, index, child) → void` | Inserts child at index |
|
|
139
|
+
| `replaceChildAtIndex` | `(parent, index, child) → number` | Replaces and returns old child |
|
|
140
|
+
| `setChildren` | `(parent, children[]) → void` | Replaces all children |
|
|
141
|
+
| `remove` | `(node) → number` | Removes node from tree |
|
|
142
|
+
| `clear` | `() → void` | Removes all nodes |
|
|
143
|
+
|
|
144
|
+
#### Tree Queries
|
|
145
|
+
|
|
146
|
+
| Method | Signature | Description |
|
|
147
|
+
| :---------------- | :------------------------- | :-------------------------- |
|
|
148
|
+
| `parent` | `(child) → number \| null` | Returns parent node ID |
|
|
149
|
+
| `children` | `(parent) → number[]` | Returns array of child IDs |
|
|
150
|
+
| `childCount` | `(parent) → number` | Returns number of children |
|
|
151
|
+
| `getChildAtIndex` | `(parent, index) → number` | Returns child at index |
|
|
152
|
+
| `totalNodeCount` | `() → number` | Returns total nodes in tree |
|
|
153
|
+
|
|
154
|
+
#### Dirty Tracking
|
|
155
|
+
|
|
156
|
+
| Method | Signature | Description |
|
|
157
|
+
| :---------- | :----------------- | :----------------------------- |
|
|
158
|
+
| `markDirty` | `(node) → void` | Marks node for re-layout |
|
|
159
|
+
| `dirty` | `(node) → boolean` | Checks if node needs re-layout |
|
|
160
|
+
|
|
161
|
+
#### Layout Computation
|
|
162
|
+
|
|
163
|
+
| Method | Signature | Description |
|
|
164
|
+
| :------------------------- | :----------------------------------------- | :------------------------------------ |
|
|
165
|
+
| `computeLayout` | `(node, availableSpace) → void` | Computes layout for subtree |
|
|
166
|
+
| `computeLayoutWithMeasure` | `(node, availableSpace, measureFn) → void` | Computes with custom measure function |
|
|
167
|
+
|
|
168
|
+
#### Layout Results
|
|
169
|
+
|
|
170
|
+
| Method | Signature | Description |
|
|
171
|
+
| :---------------- | :---------------- | :------------------------------------ |
|
|
172
|
+
| `getLayout` | `(node) → Layout` | Returns computed layout (rounded) |
|
|
173
|
+
| `unroundedLayout` | `(node) → Layout` | Returns layout with fractional values |
|
|
174
|
+
|
|
175
|
+
#### Node Context
|
|
176
|
+
|
|
177
|
+
| Method | Signature | Description |
|
|
178
|
+
| :--------------- | :----------------------- | :---------------------- |
|
|
179
|
+
| `setNodeContext` | `(node, context) → void` | Attaches data to node |
|
|
180
|
+
| `getNodeContext` | `(node) → any` | Retrieves attached data |
|
|
111
181
|
|
|
112
|
-
|
|
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. |
|
|
182
|
+
#### Debug
|
|
116
183
|
|
|
117
|
-
|
|
184
|
+
| Method | Description |
|
|
185
|
+
| :---------------- | :------------------------------- |
|
|
186
|
+
| `printTree(node)` | Prints tree structure to console |
|
|
118
187
|
|
|
119
|
-
|
|
120
|
-
| :------------------ | :--------------------------------------------- | :-------------------------------------- |
|
|
121
|
-
| `new_leaf` | `(style: Style) -> number` | Creates a leaf node (no children). |
|
|
122
|
-
| `new_with_children` | `(style: Style, children: number[]) -> number` | Creates a node containing child nodes. |
|
|
123
|
-
| `add_child` | `(parent: number, child: number) -> void` | Appends a child to a parent. |
|
|
124
|
-
| `remove_child` | `(parent: number, child: number) -> void` | Removes a specific child from a parent. |
|
|
125
|
-
| `set_children` | `(parent: number, children: number[]) -> void` | Replaces all children of a node. |
|
|
126
|
-
| `remove_node` | `(node: number) -> void` | Deletes a node and frees its memory. |
|
|
188
|
+
---
|
|
127
189
|
|
|
128
|
-
###
|
|
190
|
+
### Style Class
|
|
129
191
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
192
|
+
Configuration object for CSS layout properties.
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
const style = new Style();
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
#### Layout Mode
|
|
199
|
+
|
|
200
|
+
| Property | Type | Description |
|
|
201
|
+
| :--------- | :--------- | :---------------------------------------- |
|
|
202
|
+
| `display` | `Display` | Layout algorithm: Block, Flex, Grid, None |
|
|
203
|
+
| `position` | `Position` | Positioning: Relative, Absolute |
|
|
204
|
+
|
|
205
|
+
#### Flexbox Properties
|
|
206
|
+
|
|
207
|
+
| Property | Type | Description |
|
|
208
|
+
| :--------------- | :-------------- | :------------------------------------------------ |
|
|
209
|
+
| `flex_direction` | `FlexDirection` | Main axis: Row, Column, RowReverse, ColumnReverse |
|
|
210
|
+
| `flex_wrap` | `FlexWrap` | Wrap behavior: NoWrap, Wrap, WrapReverse |
|
|
211
|
+
| `flex_grow` | `number` | Grow factor (default: 0) |
|
|
212
|
+
| `flex_shrink` | `number` | Shrink factor (default: 1) |
|
|
213
|
+
| `flex_basis` | `Dimension` | Initial size before grow/shrink |
|
|
214
|
+
|
|
215
|
+
#### Alignment
|
|
216
|
+
|
|
217
|
+
| Property | Type | Description |
|
|
218
|
+
| :---------------- | :---------------- | :--------------------------------- |
|
|
219
|
+
| `align_items` | `AlignItems?` | Cross-axis alignment for children |
|
|
220
|
+
| `align_self` | `AlignSelf?` | Cross-axis alignment for this item |
|
|
221
|
+
| `align_content` | `AlignContent?` | Multi-line cross-axis alignment |
|
|
222
|
+
| `justify_content` | `JustifyContent?` | Main-axis alignment |
|
|
223
|
+
|
|
224
|
+
#### Sizing
|
|
225
|
+
|
|
226
|
+
| Property | Type | Description |
|
|
227
|
+
| :------------- | :------------------ | :----------------------- |
|
|
228
|
+
| `size` | `{ width, height }` | Element dimensions |
|
|
229
|
+
| `min_size` | `{ width, height }` | Minimum size constraints |
|
|
230
|
+
| `max_size` | `{ width, height }` | Maximum size constraints |
|
|
231
|
+
| `aspect_ratio` | `number?` | Width-to-height ratio |
|
|
232
|
+
|
|
233
|
+
#### Spacing
|
|
234
|
+
|
|
235
|
+
| Property | Type | Description |
|
|
236
|
+
| :-------- | :----------------------------- | :------------------------------------ |
|
|
237
|
+
| `margin` | `{ left, right, top, bottom }` | Outer spacing (supports Auto) |
|
|
238
|
+
| `padding` | `{ left, right, top, bottom }` | Inner spacing |
|
|
239
|
+
| `border` | `{ left, right, top, bottom }` | Border width |
|
|
240
|
+
| `gap` | `{ width, height }` | Gap between children (column/row gap) |
|
|
241
|
+
| `inset` | `{ left, right, top, bottom }` | Absolute positioning offsets |
|
|
242
|
+
|
|
243
|
+
#### Overflow
|
|
244
|
+
|
|
245
|
+
| Property | Type | Description |
|
|
246
|
+
| :--------- | :--------- | :------------------------- |
|
|
247
|
+
| `overflow` | `{ x, y }` | Overflow behavior per axis |
|
|
248
|
+
|
|
249
|
+
---
|
|
136
250
|
|
|
137
251
|
### Type Definitions
|
|
138
252
|
|
|
139
|
-
####
|
|
253
|
+
#### Dimension (JsDimension)
|
|
254
|
+
|
|
255
|
+
Values for size properties:
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
// Fixed pixel value
|
|
259
|
+
{
|
|
260
|
+
Length: 100;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Percentage of parent
|
|
264
|
+
{
|
|
265
|
+
Percent: 0.5;
|
|
266
|
+
} // 50%
|
|
267
|
+
|
|
268
|
+
// Automatic sizing
|
|
269
|
+
("Auto");
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
#### LengthPercentage (JsLengthPercentage)
|
|
273
|
+
|
|
274
|
+
For properties that don't support Auto (padding, border):
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
{
|
|
278
|
+
Length: 10;
|
|
279
|
+
}
|
|
280
|
+
{
|
|
281
|
+
Percent: 0.1;
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
#### LengthPercentageAuto (JsLengthPercentageAuto)
|
|
140
286
|
|
|
141
|
-
|
|
287
|
+
For properties that support Auto (margin, inset):
|
|
142
288
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
289
|
+
```typescript
|
|
290
|
+
{
|
|
291
|
+
Length: 10;
|
|
292
|
+
}
|
|
293
|
+
{
|
|
294
|
+
Percent: 0.1;
|
|
295
|
+
}
|
|
296
|
+
("Auto");
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
#### AvailableSpace (JsAvailableSize)
|
|
300
|
+
|
|
301
|
+
Constraints for layout computation:
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
{
|
|
305
|
+
width: { Definite: 800 }, // Fixed width
|
|
306
|
+
height: { Definite: 600 } // Fixed height
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
{
|
|
310
|
+
width: "MaxContent", // Intrinsic max width
|
|
311
|
+
height: "MinContent" // Intrinsic min height
|
|
312
|
+
}
|
|
313
|
+
```
|
|
147
314
|
|
|
148
|
-
####
|
|
315
|
+
#### Layout Result
|
|
149
316
|
|
|
150
|
-
|
|
317
|
+
Returned by `getLayout()`:
|
|
151
318
|
|
|
152
319
|
```typescript
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
320
|
+
{
|
|
321
|
+
order: number,
|
|
322
|
+
size: { width: number, height: number },
|
|
323
|
+
location: { x: number, y: number },
|
|
324
|
+
padding: { left, right, top, bottom },
|
|
325
|
+
border: { left, right, top, bottom },
|
|
326
|
+
scrollbar_size: { width, height },
|
|
327
|
+
content_size: { width, height }
|
|
156
328
|
}
|
|
157
329
|
```
|
|
158
330
|
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
### Enums
|
|
334
|
+
|
|
335
|
+
#### Display
|
|
336
|
+
|
|
337
|
+
```typescript
|
|
338
|
+
Display.Block; // Block layout (default)
|
|
339
|
+
Display.Flex; // Flexbox container
|
|
340
|
+
Display.Grid; // CSS Grid container
|
|
341
|
+
Display.None; // Hidden, takes no space
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
#### Position
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
Position.Relative; // Normal document flow (default)
|
|
348
|
+
Position.Absolute; // Removed from flow, positioned via inset
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
#### FlexDirection
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
FlexDirection.Row; // Horizontal, left to right
|
|
355
|
+
FlexDirection.Column; // Vertical, top to bottom
|
|
356
|
+
FlexDirection.RowReverse; // Horizontal, right to left
|
|
357
|
+
FlexDirection.ColumnReverse; // Vertical, bottom to top
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
#### FlexWrap
|
|
361
|
+
|
|
362
|
+
```typescript
|
|
363
|
+
FlexWrap.NoWrap; // Single line (default)
|
|
364
|
+
FlexWrap.Wrap; // Wrap to multiple lines
|
|
365
|
+
FlexWrap.WrapReverse; // Wrap in reverse order
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
#### AlignItems / AlignSelf
|
|
369
|
+
|
|
370
|
+
```typescript
|
|
371
|
+
AlignItems.Start; // Align to start
|
|
372
|
+
AlignItems.End; // Align to end
|
|
373
|
+
AlignItems.FlexStart; // Align to flex start
|
|
374
|
+
AlignItems.FlexEnd; // Align to flex end
|
|
375
|
+
AlignItems.Center; // Center alignment
|
|
376
|
+
AlignItems.Baseline; // Baseline alignment
|
|
377
|
+
AlignItems.Stretch; // Stretch to fill
|
|
378
|
+
|
|
379
|
+
AlignSelf.Auto; // Inherit from parent (AlignSelf only)
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
#### AlignContent
|
|
383
|
+
|
|
384
|
+
```typescript
|
|
385
|
+
AlignContent.Start;
|
|
386
|
+
AlignContent.End;
|
|
387
|
+
AlignContent.FlexStart;
|
|
388
|
+
AlignContent.FlexEnd;
|
|
389
|
+
AlignContent.Center;
|
|
390
|
+
AlignContent.Stretch;
|
|
391
|
+
AlignContent.SpaceBetween;
|
|
392
|
+
AlignContent.SpaceAround;
|
|
393
|
+
AlignContent.SpaceEvenly;
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
#### JustifyContent
|
|
397
|
+
|
|
398
|
+
```typescript
|
|
399
|
+
JustifyContent.Start;
|
|
400
|
+
JustifyContent.End;
|
|
401
|
+
JustifyContent.FlexStart;
|
|
402
|
+
JustifyContent.FlexEnd;
|
|
403
|
+
JustifyContent.Center;
|
|
404
|
+
JustifyContent.Stretch;
|
|
405
|
+
JustifyContent.SpaceBetween;
|
|
406
|
+
JustifyContent.SpaceAround;
|
|
407
|
+
JustifyContent.SpaceEvenly;
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
#### Overflow
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
Overflow.Visible; // Content not clipped
|
|
414
|
+
Overflow.Hidden; // Content clipped
|
|
415
|
+
Overflow.Scroll; // Always show scrollbars
|
|
416
|
+
Overflow.Auto; // Show scrollbars when needed
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## 📏 Custom Measurement
|
|
422
|
+
|
|
423
|
+
For nodes with intrinsic sizes (like text), use `computeLayoutWithMeasure`:
|
|
424
|
+
|
|
425
|
+
```typescript
|
|
426
|
+
tree.computeLayoutWithMeasure(
|
|
427
|
+
root,
|
|
428
|
+
{ width: { Definite: 800 }, height: { Definite: 600 } },
|
|
429
|
+
(knownDimensions, availableSpace, context) => {
|
|
430
|
+
// knownDimensions: { width: number | null, height: number | null }
|
|
431
|
+
// availableSpace: { width: AvailableSpace, height: AvailableSpace }
|
|
432
|
+
// context: The value attached via setNodeContext/newLeafWithContext
|
|
433
|
+
|
|
434
|
+
// Return the measured size
|
|
435
|
+
return { width: 100, height: 20 };
|
|
436
|
+
},
|
|
437
|
+
);
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
**Example with text measurement:**
|
|
441
|
+
|
|
442
|
+
```typescript
|
|
443
|
+
// Create a text node with context
|
|
444
|
+
const textNode = tree.newLeafWithContext(style, { text: "Hello World" });
|
|
445
|
+
|
|
446
|
+
// Measure function
|
|
447
|
+
tree.computeLayoutWithMeasure(root, availableSpace, (known, available, ctx) => {
|
|
448
|
+
if (ctx?.text) {
|
|
449
|
+
// Use your text measurement library here
|
|
450
|
+
const measured = measureText(ctx.text, available.width);
|
|
451
|
+
return { width: measured.width, height: measured.height };
|
|
452
|
+
}
|
|
453
|
+
return { width: 0, height: 0 };
|
|
454
|
+
});
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
---
|
|
458
|
+
|
|
159
459
|
## 🛠 Building from Source
|
|
160
460
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
2.
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
461
|
+
1. **Prerequisites**: Install Rust and `wasm-pack`
|
|
462
|
+
|
|
463
|
+
```bash
|
|
464
|
+
curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
2. **Build**
|
|
468
|
+
|
|
469
|
+
```bash
|
|
470
|
+
npm install
|
|
471
|
+
npm run build
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
3. **Build with debug features**
|
|
475
|
+
|
|
476
|
+
```bash
|
|
477
|
+
wasm-pack build --features console_error_panic_hook
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
---
|
|
173
481
|
|
|
174
482
|
## 📄 License
|
|
175
483
|
|
package/package.json
CHANGED
|
@@ -1,24 +1,58 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "taffy-js",
|
|
3
|
-
"
|
|
4
|
-
"collaborators": [
|
|
5
|
-
"ByteLandTechnology <github@byteland.app>"
|
|
6
|
-
],
|
|
3
|
+
"version": "0.2.0",
|
|
7
4
|
"description": "WebAssembly bindings for Taffy layout library",
|
|
8
|
-
"
|
|
9
|
-
|
|
5
|
+
"keywords": [
|
|
6
|
+
"layout",
|
|
7
|
+
"flexbox",
|
|
8
|
+
"css-grid",
|
|
9
|
+
"grid",
|
|
10
|
+
"ui",
|
|
11
|
+
"wasm",
|
|
12
|
+
"webassembly"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://github.com/ByteLandTechnology/taffy-js#readme",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/ByteLandTechnology/taffy-js/issues"
|
|
17
|
+
},
|
|
10
18
|
"repository": {
|
|
11
19
|
"type": "git",
|
|
12
|
-
"url": "https://github.com/ByteLandTechnology/taffy-js"
|
|
20
|
+
"url": "git+https://github.com/ByteLandTechnology/taffy-js.git"
|
|
13
21
|
},
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"author": "ByteLandTechnology <github@byteland.app>",
|
|
24
|
+
"type": "module",
|
|
25
|
+
"main": "pkg/taffy_js.js",
|
|
26
|
+
"types": "pkg/taffy_js.d.ts",
|
|
14
27
|
"files": [
|
|
15
|
-
"
|
|
16
|
-
"taffy_js.js",
|
|
17
|
-
"taffy_js.d.ts"
|
|
28
|
+
"pkg"
|
|
18
29
|
],
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
}
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "wasm-pack build --release --target web",
|
|
32
|
+
"build:dev": "wasm-pack build --dev --target web",
|
|
33
|
+
"test": "wasm-pack test --node",
|
|
34
|
+
"prepare": "husky"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@commitlint/cli": "^20.3.0",
|
|
38
|
+
"@commitlint/config-conventional": "^20.3.0",
|
|
39
|
+
"husky": "^9.1.7",
|
|
40
|
+
"lint-staged": "^16.2.7",
|
|
41
|
+
"prettier": "^3.7.4",
|
|
42
|
+
"wasm-pack": "^0.13.1"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=12"
|
|
46
|
+
},
|
|
47
|
+
"overrides": {
|
|
48
|
+
"axios": "^1.7.9"
|
|
49
|
+
},
|
|
50
|
+
"commitlint": {
|
|
51
|
+
"extends": [
|
|
52
|
+
"@commitlint/config-conventional"
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
"lint-staged": {
|
|
56
|
+
"*.{js,ts,jsx,tsx,json,md,yaml,yml}": "prettier --write"
|
|
57
|
+
}
|
|
58
|
+
}
|