taffy/lib.rs
1//! # Taffy
2//!
3//! Taffy is a flexible, high-performance library for **UI layout**.
4//! It currently implements the Flexbox, Grid and Block layout algorithms from the CSS specification. Support for other paradigms is planned.
5//! For more information on this and other future development plans see the [roadmap issue](https://github.com/DioxusLabs/taffy/issues/345).
6//!
7//! ## Architecture
8//!
9//! 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:
10//! - A [`Style`] struct which holds a set of CSS styles which function as the primary input to the layout computations.
11//! - A [`Layout`] struct containing a position (x/y) and a size (width/height) which function as the output of the layout computations.
12//! - Optionally:
13//! - A `Vec` set of child nodes
14//! - "Context": arbitrary user-defined data (which you can access when using a "measure function" to integrate Taffy with other kinds of layout such as text layout)
15//!
16//! Usage of Taffy consists of constructing a tree of UI nodes (with associated styles, children and context), then calling function(s)
17//! from Taffy to translate those styles, parent-child relationships and measure functions into a size and position in 2d space for each node
18//! in the tree.
19//!
20//! ## High-level API vs. Low-level API
21//!
22//! 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.
23//! 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
24//! a wider layout system or as part of a UI framework that already has it's own node/widget tree representation.
25//!
26//! ### High-level API
27//!
28//! The high-level API consists of the [`TaffyTree`] struct which contains a tree implementation and provides methods that allow you to construct
29//! 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
30//! the layout of each node using the [`layout`](crate::TaffyTree::layout) method.
31//!
32//! 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.
33//! See the [`TaffyTree`] struct for more details on this API.
34//!
35//! Examples which show usage of the high-level API include:
36//!
37//! - [basic](https://github.com/DioxusLabs/taffy/blob/main/examples/basic.rs)
38//! - [flexbox_gap](https://github.com/DioxusLabs/taffy/blob/main/examples/flexbox_gap.rs)
39//! - [grid_holy_grail](https://github.com/DioxusLabs/taffy/blob/main/examples/grid_holy_grail.rs)
40//! - [measure](https://github.com/DioxusLabs/taffy/blob/main/examples/measure.rs)
41//! - [cosmic_text](https://github.com/DioxusLabs/taffy/blob/main/examples/cosmic_text.rs)
42//!
43//! 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.
44//!
45//! ### Low-level API
46//!
47//! The low-level API consists of a [set of traits](crate::tree::traits) (notably the [`LayoutPartialTree`] trait) which define an interface behind which you must implement your own
48//! tree implementation, and a [set of functions](crate::compute) 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
49//! and easy to integrate into a wider layout or UI system.
50//!
51//! When using this API, you must handle node storage, caching, and dispatching to the correct layout algorithm for a given node yourself.
52//! See the [`crate::tree::traits`] module for more details on this API.
53//!
54//! Examples which show usage of the low-level API are:
55//!
56//! - [custom_tree_vec](https://github.com/DioxusLabs/taffy/blob/main/examples/custom_tree_vec.rs) which implements a custom Taffy tree using a `Vec` as an arena with NodeId's being index's into the Vec.
57//! - [custom_tree_owned_partial](https://github.com/DioxusLabs/taffy/blob/main/examples/custom_tree_owned_partial.rs) which implements a custom Taffy tree using directly owned children with NodeId's being index's into vec on parent node.
58//! - [custom_tree_owned_unsafe](https://github.com/DioxusLabs/taffy/blob/main/examples/custom_tree_owned_unsafe.rs) which implements a custom Taffy tree using directly owned children with NodeId's being pointers.
59
60// document the feature flags for the crate by extracting the comments from Cargo.toml
61#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
62// annotate items with their required features (gated by docsrs flag as this requires the nightly toolchain)
63#![cfg_attr(docsrs, feature(doc_auto_cfg))]
64#![cfg_attr(not(feature = "std"), no_std)]
65#![deny(unsafe_code)]
66#![warn(missing_docs)]
67#![warn(clippy::missing_docs_in_private_items)]
68// Disable "unused_x" warnings when default features aren't enabled.
69#![cfg_attr(not(feature = "default"), allow(dead_code))]
70#![cfg_attr(not(feature = "default"), allow(unused_imports))]
71#![cfg_attr(not(feature = "default"), allow(unused_variables))]
72#![cfg_attr(not(feature = "default"), allow(unused_mut))]
73
74// We always need std for the tests
75// See <https://github.com/la10736/rstest/issues/149#issuecomment-1156402989>
76#[cfg(all(test, not(feature = "std")))]
77#[macro_use]
78extern crate std;
79
80#[cfg(all(not(feature = "std"), feature = "alloc"))]
81extern crate alloc;
82
83#[cfg_attr(feature = "serde", macro_use)]
84#[cfg(feature = "serde")]
85extern crate serde;
86
87pub mod compute;
88pub mod geometry;
89pub mod prelude;
90pub mod style;
91pub mod style_helpers;
92pub mod tree;
93#[macro_use]
94pub mod util;
95
96mod readme_doctest {
97 #![doc = include_str!("../README.md")]
98}
99
100#[cfg(feature = "block_layout")]
101#[doc(inline)]
102pub use crate::compute::compute_block_layout;
103#[cfg(feature = "flexbox")]
104#[doc(inline)]
105pub use crate::compute::compute_flexbox_layout;
106#[cfg(feature = "grid")]
107#[doc(inline)]
108pub use crate::compute::compute_grid_layout;
109#[cfg(feature = "detailed_layout_info")]
110pub use crate::compute::detailed_info::*;
111#[doc(inline)]
112pub use crate::compute::{
113 compute_cached_layout, compute_hidden_layout, compute_leaf_layout, compute_root_layout, round_layout,
114};
115#[doc(inline)]
116pub use crate::style::Style;
117#[doc(inline)]
118pub use crate::tree::traits::*;
119#[cfg(feature = "taffy_tree")]
120#[doc(inline)]
121pub use crate::tree::TaffyTree;
122#[cfg(feature = "std")]
123#[doc(inline)]
124pub use crate::util::print_tree;
125
126pub use crate::geometry::*;
127pub use crate::style::*;
128pub use crate::tree::*;
129pub use crate::util::*;