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 #![forbid(unsafe_code)] 67 #![warn(missing_docs)] 68 #![warn(clippy::missing_docs_in_private_items)] 69 70 // We always need std for the tests 71 // See <https://github.com/la10736/rstest/issues/149#issuecomment-1156402989> 72 #[cfg(all(test, not(feature = "std")))] 73 #[macro_use] 74 extern crate std; 75 76 #[cfg(all(not(feature = "std"), feature = "alloc"))] 77 extern crate alloc; 78 79 #[cfg_attr(feature = "serde", macro_use)] 80 #[cfg(feature = "serde")] 81 extern crate serde; 82 83 pub mod compute; 84 pub mod geometry; 85 pub mod prelude; 86 pub mod style; 87 pub mod style_helpers; 88 pub mod tree; 89 #[macro_use] 90 pub mod util; 91 92 mod readme_doctest { 93 #![doc = include_str!("../README.md")] 94 } 95 96 #[cfg(feature = "block_layout")] 97 #[doc(inline)] 98 pub use crate::compute::compute_block_layout; 99 #[cfg(feature = "flexbox")] 100 #[doc(inline)] 101 pub use crate::compute::compute_flexbox_layout; 102 #[cfg(feature = "grid")] 103 #[doc(inline)] 104 pub use crate::compute::compute_grid_layout; 105 #[cfg(feature = "detailed_layout_info")] 106 pub use crate::compute::detailed_info::*; 107 #[doc(inline)] 108 pub use crate::compute::{ 109 compute_cached_layout, compute_hidden_layout, compute_leaf_layout, compute_root_layout, round_layout, 110 }; 111 #[doc(inline)] 112 pub use crate::style::Style; 113 #[doc(inline)] 114 pub use crate::tree::traits::*; 115 #[cfg(feature = "taffy_tree")] 116 #[doc(inline)] 117 pub use crate::tree::TaffyTree; 118 #[cfg(feature = "std")] 119 #[doc(inline)] 120 pub use crate::util::print_tree; 121 122 pub use crate::geometry::*; 123 pub use crate::style::*; 124 pub use crate::tree::*; 125 pub use crate::util::*; 126