Skip to content

Repository files navigation

Taffy Layout Logo Taffy Layout

English | 简体中文 | 日本語

npm versionLicense: MIT

High-performance WebAssembly bindings for the Taffy layout engine, bringing CSS Flexbox and Grid layout algorithms to JavaScript with near-native performance.

✨ Features

  • 🚀 High Performance: WebAssembly-powered layout calculations
  • 📦 Complete CSS Support: Full Flexbox and CSS Grid implementation
  • 🔧 Custom Measurement: Support for custom text/content measurement callbacks
  • 📝 TypeScript Ready: Complete type definitions included
  • 🌳 Tree-Based API: Efficient tree structure for complex layouts
  • 💡 Familiar API: CSS-like property names and values

📦 Installation

npm install taffy-layout

🚀 Quick Start

import{loadTaffy,TaffyTree,Style,Display,FlexDirection,AlignItems,}from"taffy-layout";// Initialize WebAssembly moduleawaitloadTaffy();// Create a layout treeconsttree=newTaffyTree();// Create container styleconstcontainerStyle=newStyle();containerStyle.display=Display.Flex;containerStyle.flexDirection=FlexDirection.Column;containerStyle.alignItems=AlignItems.Center;// You can set size as an objectcontainerStyle.size={width: 300,height: 200};// Or use individual width/height propertiescontainerStyle.width=300;containerStyle.height=200;// Set padding as an objectcontainerStyle.padding={left: 10,right: 10,top: 10,bottom: 10};// Or use individual padding propertiescontainerStyle.paddingLeft=10;containerStyle.paddingRight=10;containerStyle.paddingTop=10;containerStyle.paddingBottom=10;// Create child stylesconstchildStyle=newStyle();childStyle.flexGrow=1;childStyle.width="100%";childStyle.height="auto";// Create nodesconstchild1=tree.newLeaf(childStyle);constchild2=tree.newLeaf(childStyle);constcontainer=tree.newWithChildren(containerStyle,[child1,child2]);// Compute layouttree.computeLayout(container,{width: 300,height: 200});// Read computed layoutsconstcontainerLayout=tree.getLayout(container);constchild1Layout=tree.getLayout(child1);constchild2Layout=tree.getLayout(child2);console.log(`Container: ${containerLayout.width}x${containerLayout.height}`);console.log(`Child 1: ${child1Layout.width}x${child1Layout.height} at (${child1Layout.x}, ${child1Layout.y})`,);console.log(`Child 2: ${child2Layout.width}x${child2Layout.height} at (${child2Layout.x}, ${child2Layout.y})`,);

📚 Documentation

📖 API Reference

TaffyTree

The main class for managing layout trees.

View Documentation

Style

Configuration object for node layout properties.

View Documentation

Layout

Read-only computed layout result.

View Documentation

Enums

View Documentation

Types

View Documentation

📐 Custom Text Measurement

For text nodes or other content that needs dynamic measurement:

consttree=newTaffyTree();consttextStyle=newStyle();constrootNode=tree.newLeaf(newStyle());constmeasureTextWidth=(text: string)=>text.length*8;constmeasureTextHeight=(text: string,width: number)=>20;consttextNode=tree.newLeafWithContext(textStyle,{text: "Hello, World!"});tree.computeLayoutWithMeasure(rootNode,{width: 800,height: "max-content"},(known,available,node,context,style)=>{if(context?.text){// Your text measurement logic hereconstwidth=measureTextWidth(context.text);constheight=measureTextHeight(context.text,available.widthasnumber);return{ width, height };}return{width: 0,height: 0};},);

🔧 Error Handling

Methods that can fail throw a TaffyError as a JavaScript exception. Use try-catch to handle errors:

try{consttree=newTaffyTree();conststyle=newStyle();constnodeId=tree.newLeaf(style);console.log("Created node:",nodeId);}catch(e){if(einstanceofTaffyError){console.error("Error:",e.message);}}

🌐 Browser Support

Taffy Layout works in all modern browsers that support WebAssembly:

  • Chrome 57+
  • Firefox 52+
  • Safari 11+
  • Edge 16+

📚 Examples

Flexbox Row Layout

constrowStyle=newStyle();rowStyle.display=Display.Flex;rowStyle.flexDirection=FlexDirection.Row;rowStyle.justifyContent=JustifyContent.SpaceBetween;rowStyle.gap={width: 10,height: 0};

CSS Grid Layout

import{Style,Display,GridAutoFlow}from"taffy-layout";constgridStyle=newStyle();gridStyle.display=Display.Grid;gridStyle.gridAutoFlow=GridAutoFlow.Row;gridStyle.gap={width: 10,height: 10};// Grid item placementconstitemStyle=newStyle();itemStyle.gridRow={start: 1,end: 3};// Spans 2 rowsitemStyle.gridColumn={start: 1,end: {span: 2}};// Spans 2 columns

Grid Template Areas

constgridStyle=newStyle();gridStyle.display=Display.Grid;gridStyle.gridTemplateAreas=[{name: "header",rowStart: 1,rowEnd: 2,columnStart: 1,columnEnd: 4},{name: "sidebar",rowStart: 2,rowEnd: 4,columnStart: 1,columnEnd: 2},{name: "main",rowStart: 2,rowEnd: 4,columnStart: 2,columnEnd: 4},{name: "footer",rowStart: 4,rowEnd: 5,columnStart: 1,columnEnd: 4},];// Named grid linesgridStyle.gridTemplateRowNames=[["header-start"],["header-end","content-start"],["content-end","footer-start"],["footer-end"],];

Absolute Positioning

constabsoluteStyle=newStyle();absoluteStyle.position=Position.Absolute;absoluteStyle.inset={left: 10,top: 10,right: "auto",bottom: "auto"};absoluteStyle.size={width: 100,height: 50};

Percentage Sizing

constpercentStyle=newStyle();percentStyle.size={width: "50%",// 50% of parentheight: "100%",// 100% of parent};

Block Layout with Replaced Elements

constimgStyle=newStyle();imgStyle.itemIsReplaced=true;imgStyle.aspectRatio=16/9;// 16:9 aspect ratioimgStyle.size={width: "100%",height: "auto"};

🏗️ Building from Source

# Clone the repository
git clone https://github.com/ByteLandTechnology/taffy-layout.git
cd taffy-layout
# Install dependencies
npm install
# Build the WebAssembly module
npm run build
# Run tests
npm test

📄 License

MIT License - see LICENSE for details.

🙏 Acknowledgments

  • Taffy - The Rust layout engine this project wraps
  • wasm-bindgen - Rust/WebAssembly interoperability

About

WebAssembly bindings for the Taffy layout engine

Topics

Resources

Stars

17 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages