tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

HTML 206Rust 8TOML 2CSS 1310 Definitions

⎇ 1f12fb8db0d02f29a3c6cdc00610938f02ae05e1 README.md Markdown · 210 lines · 7.6 KB History raw

wip: bump cargo and readme 1f12fb8db · Jonathan Kelley ·

1# Stretch2
2[![CircleCI](https://circleci.com/gh/vislyhq/stretch.svg?style=svg)](https://circleci.com/gh/vislyhq/stretch)
3[![Cargo](https://img.shields.io/crates/v/stretch.svg)](https://crates.io/crates/stretch)
4[![npm](https://img.shields.io/npm/v/stretch-layout.svg)](https://www.npmjs.com/package/stretch-layout)
5[![cocoapods](https://img.shields.io/cocoapods/v/StretchKit.svg)](https://cocoapods.org/pods/StretchKit)
6[![bintray](https://api.bintray.com/packages/visly/maven/stretch-kotlin-bindings/images/download.svg)](https://bintray.com/visly/maven/stretch-kotlin-bindings)
7
8> THIS IS A FORK OF THE ORIGINAL STRETCH. CURRENTLY MAINTAINED BY DIOXUS.
9
10Stretch2 is an implementation of Flexbox written in [Rust](https://www.rust-lang.org). The goal of stretch2 is to provide a solid foundation for layout across all platforms with a specific focus on mobile. Long term we want stretch2 to not only support flexbox but also many other layout algorithms such as grid layout. Stretch was made for and powers https://visly.app.
11
12## Goals
13Before using or contributing to stretch2 it is good to be aware of the core goals of the project. These are goals we are working towards, not necessarily features we currently support.
14
15- High performance
16- Cross platform
17- Small binary size
18- Support multiple layout systems
19- Multi-threaded layout
20- Language bindings for most common languages
21
22## Supported Platforms
23
24- Rust
25- Android
26- iOS
27- JavaScript / TypeScript
28
29## Usage
30Stretch2 is built in Rust but comes with bindings to multiple languages and platforms so you can use it in a way that feels natural to your project.
31
32### Rust
33```toml
34# Cargo.toml
35
36[dependencies]
37stretch2 = "0.3.2"
38```
39
40```rust
41// main.rs
42
43use stretch2::geometry::Size;
44use stretch2::style::*;
45
46fn main() -> Result<(), stretch2::Error> {
47    let mut stretch2 = stretch2::node::Stretch::new();
48
49    let child = stretch.new_node(
50        Style { size: Size { width: Dimension::Percent(0.5), height: Dimension::Auto }, ..Default::default() },
51        vec![],
52    )?;
53
54    let node = stretch.new_node(
55        Style {
56            size: Size { width: Dimension::Points(100.0), height: Dimension::Points(100.0) },
57            justify_content: JustifyContent::Center,
58            ..Default::default()
59        },
60        vec![child],
61    )?;
62
63    stretch.compute_layout(node, Size::undefined())?;
64    dbg!(stretch.layout(node)?);
65}
66
67```
68
69### Android
70```groovy
71// Build.gradle
72
73android {
74    splits {
75        abi {
76            enable true
77        }
78    }
79}
80
81dependencies {
82    implementation 'app.visly.stretch:stretch:0.3.2'
83}
84```
85
86```kotlin
87// MainActivity.kt
88
89val node = Node(
90  Style(size = Size(Dimension.Points(100f), Dimension.Points(100f)), justifyContent = JustifyContent.Center),
91  listOf(
92    Node(Style(size = Size(Dimension.Percent(0.5f), Dimension.Percent(0.5f))), listOf())
93  ))
94
95val layout = node.computeLayout(Size(null, null))
96Log.d(TAG, "width: ${layout.width}, height: ${layout.height}")
97```
98
99### iOS
100```ruby
101# Podfile
102
103pod 'StretchKit', '~> 0.3.2'
104```
105
106```swift
107// ViewController.swift
108
109let node = Node(
110  style: Style(size: Size(width: .points(100.0), height: .points(100.0)), justifyContent: .center),
111  children: [
112    Node(style: Style(size: Size(width: .percent(0.5), height: .percent(0.5))), children: [])
113  ])
114
115let layout = node.computeLayout(thatFits: Size(width: nil, height: nil))
116print("width: \(layout.width), height: \(layout.height)")
117```
118
119### JavaScript
120```bash
121> npm install --save stretch-layout
122```
123
124```javascript
125// index.js
126
127import { Allocator, Node, JustifyContent } from 'stretch-layout';
128
129const allocator = new Allocator();
130const node = new Node(allocator, {width: 100, height: 100, justifyContent: JustifyContent.Center});
131node.addChild(new Node(allocator, {width: '50%', height: '50%'}));
132const layout = node.computeLayout();
133
134console.log(layout.width, layout.height);
135```
136
137## Contributing
138Contributions are very welcome. Though we ask that you open an issue or pull request early in the process (before writing code) so we can discuss solutions and additions before you start spending time on implementing them. There are some specific areas where we would be extra happy to receive contributions in.
139
140- Binary size reduction
141- Runtime performance
142- Ensure build / test environment works well on non macOS platforms
143- Alternate layout systems (grid layout perhaps?)
144- Web compatibility tests
145- RTL support
146- Platform bindings
147- API improvements
148- Documentation & Examples
149
150### Installation
151If you don't have Rust installed you have to do that first as well as install some components that we make use of to format and lint the codebase. For more on Rust see their [website](https://www.rust-lang.org).
152
153```bash
154curl https://sh.rustup.rs -sSf | sh
155rustup component add rustfmt
156rustup component add clippy
157```
158
159Once that is done you can clone the repo and do some sanity checks to make sure everything is working correctly.
160
161```bash
162git clone https://github.com/vislyhq/stretch.git
163cd stretch
164cargo test
165```
166
167If you have made any changes to the API you should also update and run tests for all the platform bindings located in `/bindings/*`.
168
169### Testing
170Stretch2 is tested by validating that layouts written in stretch2 perform the same as in Chrome. This is done by rendering an equivalent layout in HTML and then generating a Rust test case which asserts that the resulting layout is the same when run through stretch.
171
172You can run these tests without setting up a webdriver environment but if you are looking to add any test case you will need to install [chromedriver](http://chromedriver.chromium.org). If you are developing on macOS this is easy to do through brew.
173
174```bash
175brew tap homebrew/cask
176brew cask install chromedriver
177```
178
179Once you have chromedriver installed and available in `PATH` you can re-generate all tests by running `cargo run --package gentest`.
180
181To add a new test case add another HTML file to `/test_fixtures` following the current tests as a template for new tests.
182
183### Benchmarking
184Benchmarks build on the same infrastructure as testing, and actually benchmarks are automatically generated from test fixtures just like tests. Run `cargo bench` to run benchmarks locally.
185
186## Relationship to Yoga
187[Yoga](https://www.yogalayout.com) is a cross-platform implementation of Flexbox written in C. Yoga is a fantastic project but has some fundamental issues which we hope to resolve. Compared to Yoga we aim to have a stronger adherence to web standards, a flexible architecture eventually supporting multiple layout algorithms, and future performance improvements including multi-threaded layout. In addition to this we aim to use a safer language with a more modern codebase.
188
189# LICENCE
190```
191Copyright (c) 2018 Visly Inc.
192
193Permission is hereby granted, free of charge, to any person obtaining a copy
194of this software and associated documentation files (the "Software"), to deal
195in the Software without restriction, including without limitation the rights
196to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
197copies of the Software, and to permit persons to whom the Software is
198furnished to do so, subject to the following conditions:
199
200The above copyright notice and this permission notice shall be included in all
201copies or substantial portions of the Software.
202
203THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
204IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
205FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
206AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
207LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
208OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
209SOFTWARE.
210```

README.md

Stretch2

CircleCI Cargo npm cocoapods bintray

THIS IS A FORK OF THE ORIGINAL STRETCH. CURRENTLY MAINTAINED BY DIOXUS.

Stretch2 is an implementation of Flexbox written in Rust. The goal of stretch2 is to provide a solid foundation for layout across all platforms with a specific focus on mobile. Long term we want stretch2 to not only support flexbox but also many other layout algorithms such as grid layout. Stretch was made for and powers https://visly.app.

Goals

Before using or contributing to stretch2 it is good to be aware of the core goals of the project. These are goals we are working towards, not necessarily features we currently support.

Supported Platforms

Usage

Stretch2 is built in Rust but comes with bindings to multiple languages and platforms so you can use it in a way that feels natural to your project.

Rust

# Cargo.toml

[dependencies]
stretch2 = "0.3.2"
// main.rs

use stretch2::geometry::Size;
use stretch2::style::*;

fn main() -> Result<(), stretch2::Error> {
    let mut stretch2 = stretch2::node::Stretch::new();

    let child = stretch.new_node(
        Style { size: Size { width: Dimension::Percent(0.5), height: Dimension::Auto }, ..Default::default() },
        vec![],
    )?;

    let node = stretch.new_node(
        Style {
            size: Size { width: Dimension::Points(100.0), height: Dimension::Points(100.0) },
            justify_content: JustifyContent::Center,
            ..Default::default()
        },
        vec![child],
    )?;

    stretch.compute_layout(node, Size::undefined())?;
    dbg!(stretch.layout(node)?);
}

Android

// Build.gradle

android {
    splits {
        abi {
            enable true
        }
    }
}

dependencies {
    implementation 'app.visly.stretch:stretch:0.3.2'
}
// MainActivity.kt

val node = Node(
  Style(size = Size(Dimension.Points(100f), Dimension.Points(100f)), justifyContent = JustifyContent.Center),
  listOf(
    Node(Style(size = Size(Dimension.Percent(0.5f), Dimension.Percent(0.5f))), listOf())
  ))

val layout = node.computeLayout(Size(null, null))
Log.d(TAG, "width: ${layout.width}, height: ${layout.height}")

iOS

# Podfile

pod 'StretchKit', '~> 0.3.2'
// ViewController.swift

let node = Node(
  style: Style(size: Size(width: .points(100.0), height: .points(100.0)), justifyContent: .center),
  children: [
    Node(style: Style(size: Size(width: .percent(0.5), height: .percent(0.5))), children: [])
  ])

let layout = node.computeLayout(thatFits: Size(width: nil, height: nil))
print("width: \(layout.width), height: \(layout.height)")

JavaScript

> npm install --save stretch-layout
// index.js

import { Allocator, Node, JustifyContent } from 'stretch-layout';

const allocator = new Allocator();
const node = new Node(allocator, {width: 100, height: 100, justifyContent: JustifyContent.Center});
node.addChild(new Node(allocator, {width: '50%', height: '50%'}));
const layout = node.computeLayout();

console.log(layout.width, layout.height);

Contributing

Contributions are very welcome. Though we ask that you open an issue or pull request early in the process (before writing code) so we can discuss solutions and additions before you start spending time on implementing them. There are some specific areas where we would be extra happy to receive contributions in.

Installation

If you don't have Rust installed you have to do that first as well as install some components that we make use of to format and lint the codebase. For more on Rust see their website.

curl https://sh.rustup.rs -sSf | sh
rustup component add rustfmt
rustup component add clippy

Once that is done you can clone the repo and do some sanity checks to make sure everything is working correctly.

git clone https://github.com/vislyhq/stretch.git
cd stretch
cargo test

If you have made any changes to the API you should also update and run tests for all the platform bindings located in /bindings/*.

Testing

Stretch2 is tested by validating that layouts written in stretch2 perform the same as in Chrome. This is done by rendering an equivalent layout in HTML and then generating a Rust test case which asserts that the resulting layout is the same when run through stretch.

You can run these tests without setting up a webdriver environment but if you are looking to add any test case you will need to install chromedriver. If you are developing on macOS this is easy to do through brew.

brew tap homebrew/cask
brew cask install chromedriver

Once you have chromedriver installed and available in PATH you can re-generate all tests by running cargo run --package gentest.

To add a new test case add another HTML file to /test_fixtures following the current tests as a template for new tests.

Benchmarking

Benchmarks build on the same infrastructure as testing, and actually benchmarks are automatically generated from test fixtures just like tests. Run cargo bench to run benchmarks locally.

Relationship to Yoga

Yoga is a cross-platform implementation of Flexbox written in C. Yoga is a fantastic project but has some fundamental issues which we hope to resolve. Compared to Yoga we aim to have a stronger adherence to web standards, a flexible architecture eventually supporting multiple layout algorithms, and future performance improvements including multi-threaded layout. In addition to this we aim to use a safer language with a more modern codebase.

LICENCE

Copyright (c) 2018 Visly Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.