1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//! # Taffy
//!
//! Taffy is a flexible, high-performance library for **UI layout**.
//! It currently implements the Block, Flexbox and Grid layout algorithms from the CSS specification. Support for other paradigms is planned.
//! For more information on this and other future development plans see the [roadmap issue](https://github.com/DioxusLabs/taffy/issues/345).
//!
//! ## Architecture
//!
//! Taffy is based on a tree of "UI nodes" similar to the tree of DOM nodes that one finds in web-based UI. Each node has:
//!   - A [`Style`] struct which holds a set of CSS styles which function as the primary input to the layout computations.
//!   - A [`Layout`] struct containing a position (x/y) and a size (width/height) which function as the output of the layout computations.
//!   - Optionally:
//!       - A `Vec` set of child nodes
//!       - "Context": arbitary user-defined data (which you can access when using a "measure function" to integrate Taffy with other kinds of layout such as text layout)
//!
//! Usage of Taffy consists of constructing a tree of UI nodes (with associated styles, children and context), then calling function(s)
//! from Taffy to translate those styles, parent-child relationships and measure functions into a size and position in 2d space for each node
//! in the tree.
//!
//! ## High-level API vs. Low-level API
//!
//! Taffy has two APIs: a high-level API that is simpler and easier to get started with, and a low-level API that is more flexible gives greater control.
//!
//! We would generally recommend the high-level API for users using Taffy standalone and the low-level API for users wanting to embed Taffy as part of
//! a wider layout system or as part of a UI framework that already has it's own node/widget tree representation.
//!
//! ### High-level API
//!
//! The high-level API** consists of the [`TaffyTree`] struct which contains a tree implementation and provides methods that allow you to construct
//! a tree of UI nodes. Once constructed, you can call the [`compute_layout_with_measure`](crate::TaffyTree::compute_layout_with_measure) method to compute the layout (passing in a "measure function" closure which is used to compute the size of leaf nodes), and then access
//! the layout of each node using the [`layout`](crate::TaffyTree::layout) method.
//!
//! When using the high-level API, Taffy will take care of node storage, caching and dispatching to the correct layout algorithm for a given node for you.
//! See the [`TaffyTree`] struct for more details on this API.
//!
//! Examples which show usage of the high-level API include:
//!
//!   - [basic](https://github.com/DioxusLabs/taffy/blob/main/examples/basic.rs)
//!   - [flexbox_gap](https://github.com/DioxusLabs/taffy/blob/main/examples/flexbox_gap.rs)
//!   - [grid_holy_grail](https://github.com/DioxusLabs/taffy/blob/main/examples/basic.rs)
//!   - [measure](https://github.com/DioxusLabs/taffy/blob/main/examples/measure.rs)
//!
//! In particular, the "measure" example shows how to integrate Taffy layout with other layout modalities such as text or image layout when using the high level API.
//!
//! ### Low-level API
//!
//! The low-level API consists of a set of traits (notably the [`PartialLayoutTree`] trait) which define an interface behind which you must implement your own
//! tree implementation, and a set of functions such as [`compute_flexbox_layout`] and [`compute_grid_layout`] which implement the layout algorithms (for a single node at a time), and are designed to be flexible
//! and easy to integrate into a wider layout or UI system.
//!
//! When using this API, you must handle node storage, caching, and dispatching to the correct layout algorithm for a given node yourself.
//! See the [`PartialLayoutTree`] trait for more details on this API.
//!
//! Examples which show usage of the high-level API are:
//!
//!   - [custom_layout_tree_vec](https://github.com/DioxusLabs/taffy/blob/main/examples/custom_layout_tree_vec.rs) which implements a custom Taffy tree using a `Vec` as an arena with NodeId's being index's into the Vec.
//!   - [custom_layout_tree_owned](https://github.com/DioxusLabs/taffy/blob/main/examples/custom_layout_tree_owned.rs) which implements a custom Taffy tree using directly owned children with NodeId's being pointers.

#![cfg_attr(not(feature = "std"), no_std)]
#![deny(unsafe_code)]
#![forbid(unsafe_code)]
#![warn(missing_docs)]
#![warn(clippy::missing_docs_in_private_items)]

// We always need std for the tests
// See <https://github.com/la10736/rstest/issues/149#issuecomment-1156402989>
#[cfg(all(test, not(feature = "std")))]
#[macro_use]
extern crate std;

#[cfg(all(not(feature = "std"), feature = "alloc"))]
extern crate alloc;

#[cfg_attr(feature = "serde", macro_use)]
#[cfg(feature = "serde")]
extern crate serde;

pub mod compute;
pub mod geometry;
pub mod prelude;
pub mod style;
pub mod style_helpers;
pub mod tree;
#[macro_use]
pub mod util;

mod readme_doctest {
    #![doc = include_str!("../README.md")]
}

#[cfg(feature = "block_layout")]
#[doc(inline)]
pub use crate::compute::compute_block_layout;
#[cfg(feature = "flexbox")]
#[doc(inline)]
pub use crate::compute::compute_flexbox_layout;
#[cfg(feature = "grid")]
#[doc(inline)]
pub use crate::compute::compute_grid_layout;
#[doc(inline)]
pub use crate::compute::{
    compute_cached_layout, compute_hidden_layout, compute_layout, compute_leaf_layout, round_layout,
};
#[doc(inline)]
pub use crate::style::Style;
#[cfg(feature = "taffy_tree")]
#[doc(inline)]
pub use crate::tree::TaffyTree;
#[doc(inline)]
pub use crate::tree::{LayoutTree, PartialLayoutTree};
#[cfg(feature = "std")]
#[doc(inline)]
pub use crate::util::print_tree;

pub use crate::geometry::*;
pub use crate::style::*;
pub use crate::tree::*;
pub use crate::util::*;