Moving flexbox behind a feature flag (#414)
* Moving flexbox behind a feature flag
* More stuff behind feature flag
* Enabling flexbox by default
* Fixing double definition of default
* Update workflow
* Adding default const to Display when no features are enabled
* Comment out more stuff from the prelude
* Ensure only one default
* Putting stuff behind feature flags
* formatting
* adding std to feature testing
* Uncomment temp commented code
* Fix missing comma
* Update Ci job keys
* Cleanup and documentatnion
* Gating alignement properties behind flexbox or grid
* Rename job key back to original value
* Gate justify_items and justify_self behind the grid feature
* Reinstate alloc job name
* Fix github actions job name
---------
Co-authored-by: Nico Burns <nico@nicoburns.com>
0bccf6cb6a3fc322e8e4fcc10ae38f8c42b26cf1 · por Andreas Weibye · 2023-04-10T11:44:40Z (hace 3 años) · padre 83b9ac1f4 · ver el árbol en este commit
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ebca2eebf..aa8e1c130 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -9,6 +9,7 @@ on:
name: Continuous integration
jobs:
+ # None
test-features-none:
name: "Test Suite [Features: None]"
runs-on: ubuntu-latest
@@ -19,6 +20,7 @@ jobs:
- run: cargo build --no-default-features
- run: cargo test --no-default-features
+ # Default
test-features-default:
name: "Test Suite [Features: Default]"
runs-on: ubuntu-latest
@@ -37,8 +39,37 @@ jobs:
- run: cargo build --features serde
- run: cargo test --features serde
- test-features-alloc:
- name: "Test Suite [Features: alloc]"
+ test-features-no-grid-nor-flexbox:
+ name: "Test Suite [Features: std (no grid or flexbox)]"
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: dtolnay/rust-toolchain@stable
+ - run: cargo build --no-default-features --features std
+ - run: cargo test --no-default-features --features std
+
+ # Flexbox
+ test-features-flexbox:
+ name: "Test Suite [Features: flexbox + std]"
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: dtolnay/rust-toolchain@stable
+ - run: cargo build --no-default-features --features flexbox,std
+ - run: cargo test --no-default-features --features flexbox,std
+
+ # Grid
+ test-features-grid:
+ name: "Test Suite [Features: grid + std]"
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: dtolnay/rust-toolchain@stable
+ - run: cargo build --no-default-features --features grid,std
+ - run: cargo test --no-default-features --features grid,std
+
+ test-features-grid-with-alloc:
+ name: "Test Suite [Features: grid + alloc]"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
@@ -46,8 +77,8 @@ jobs:
- run: cargo build --no-default-features --features alloc,grid
- run: cargo test --no-default-features --features alloc,grid
- test-features-alloc-no-grid:
- name: "Test Suite [Features: alloc (no grid)]"
+ test-features-alloc:
+ name: "Test Suite [Features: alloc]"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
diff --git a/Cargo.toml b/Cargo.toml
index fc415b670..855eef245 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -22,7 +22,8 @@ slotmap = "1.0.6"
grid = { version = "0.9.0", optional = true }
[features]
-default = ["std", "grid"]
+default = ["std", "flexbox", "grid" ]
+flexbox = []
grid = ["alloc", "dep:grid"]
alloc = []
std = ["num-traits/std"]
diff --git a/RELEASES.md b/RELEASES.md
index 47ba3a2f3..97a7ab4c4 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,5 +1,12 @@
# Release Notes
+## Unreleased
+
+### Changes
+
+- The Flexbox algorithm has now been moved behind the `flexbox` feature. The `flexbox` feature is enabled by default.
+- The `justify_self` property has been moved behind the `grid` feature.
+
## 0.3.11
### Fixes
diff --git a/src/compute/mod.rs b/src/compute/mod.rs
index 35fc1b9b0..0fa23fae8 100644
--- a/src/compute/mod.rs
+++ b/src/compute/mod.rs
@@ -1,9 +1,11 @@
//! The layout algorithms themselves
pub(crate) mod common;
-pub(crate) mod flexbox;
pub(crate) mod leaf;
+#[cfg(feature = "flexbox")]
+pub(crate) mod flexbox;
+
#[cfg(feature = "grid")]
pub(crate) mod grid;
@@ -16,7 +18,9 @@ use crate::style::{AvailableSpace, Display};
use crate::sys::round;
use crate::tree::LayoutTree;
+#[cfg(feature = "flexbox")]
use self::flexbox::FlexboxAlgorithm;
+
#[cfg(feature = "grid")]
use self::grid::CssGridAlgorithm;
use self::leaf::LeafAlgorithm;
@@ -189,6 +193,7 @@ fn compute_node_layout(
run_mode,
sizing_mode,
),
+ #[cfg(feature = "flexbox")]
(Display::Flex, true) => perform_computations::<FlexboxAlgorithm>(
tree,
node,
diff --git a/src/debug.rs b/src/debug.rs
index 991cbc4a2..b95fa4703 100644
--- a/src/debug.rs
+++ b/src/debug.rs
@@ -21,6 +21,7 @@ fn print_node(tree: &impl LayoutTree, node: Node, has_sibling: bool, lines_strin
let display = match (num_children, style.display) {
(_, style::Display::None) => "NONE",
(0, _) => "LEAF",
+ #[cfg(feature = "flexbox")]
(_, style::Display::Flex) => "FLEX",
#[cfg(feature = "grid")]
(_, style::Display::Grid) => "GRID",
diff --git a/src/geometry.rs b/src/geometry.rs
index 3f96d3d85..65dce8e3e 100644
--- a/src/geometry.rs
+++ b/src/geometry.rs
@@ -1,9 +1,12 @@
//! Geometric primitives useful for layout
-use crate::style::{Dimension, FlexDirection};
+use crate::style::Dimension;
use crate::sys::f32_max;
use core::ops::Add;
+#[cfg(feature = "flexbox")]
+use crate::style::FlexDirection;
+
#[cfg(feature = "grid")]
use crate::axis::AbstractAxis;
@@ -61,6 +64,7 @@ impl<T> Rect<T> {
/// When applied to the left and right sides, the width is used
/// as the second parameter of `f`.
/// When applied to the top or bottom sides, the height is used instead.
+ #[cfg(feature = "flexbox")]
pub(crate) fn zip_size<R, F, U>(self, size: Size<U>, f: F) -> Rect<R>
where
F: Fn(T, U) -> R,
@@ -134,6 +138,7 @@ where
///
/// If the [`FlexDirection`] is [`FlexDirection::Row`] or [`FlexDirection::RowReverse`], this is [`Rect::horizontal`].
/// Otherwise, this is [`Rect::vertical`].
+ #[cfg(feature = "flexbox")]
pub(crate) fn main_axis_sum(&self, direction: FlexDirection) -> U {
if direction.is_row() {
self.horizontal_axis_sum()
@@ -146,6 +151,7 @@ where
///
/// If the [`FlexDirection`] is [`FlexDirection::Row`] or [`FlexDirection::RowReverse`], this is [`Rect::vertical`].
/// Otherwise, this is [`Rect::horizontal`].
+ #[cfg(feature = "flexbox")]
pub(crate) fn cross_axis_sum(&self, direction: FlexDirection) -> U {
if direction.is_row() {
self.vertical_axis_sum()
@@ -160,6 +166,7 @@ where
T: Copy + Clone,
{
/// The `start` or `top` value of the [`Rect`], from the perspective of the main layout axis
+ #[cfg(feature = "flexbox")]
pub(crate) fn main_start(&self, direction: FlexDirection) -> T {
if direction.is_row() {
self.left
@@ -169,6 +176,7 @@ where
}
/// The `end` or `bottom` value of the [`Rect`], from the perspective of the main layout axis
+ #[cfg(feature = "flexbox")]
pub(crate) fn main_end(&self, direction: FlexDirection) -> T {
if direction.is_row() {
self.right
@@ -178,6 +186,7 @@ where
}
/// The `start` or `top` value of the [`Rect`], from the perspective of the cross layout axis
+ #[cfg(feature = "flexbox")]
pub(crate) fn cross_start(&self, direction: FlexDirection) -> T {
if direction.is_row() {
self.top
@@ -187,6 +196,7 @@ where
}
/// The `end` or `bottom` value of the [`Rect`], from the perspective of the main layout axis
+ #[cfg(feature = "flexbox")]
pub(crate) fn cross_end(&self, direction: FlexDirection) -> T {
if direction.is_row() {
self.bottom
@@ -301,6 +311,7 @@ impl<T> Size<T> {
/// Sets the extent of the main layout axis
///
/// Whether this is the width or height depends on the `direction` provided
+ #[cfg(feature = "flexbox")]
pub(crate) fn set_main(&mut self, direction: FlexDirection, value: T) {
if direction.is_row() {
self.width = value
@@ -312,6 +323,7 @@ impl<T> Size<T> {
/// Sets the extent of the cross layout axis
///
/// Whether this is the width or height depends on the `direction` provided
+ #[cfg(feature = "flexbox")]
pub(crate) fn set_cross(&mut self, direction: FlexDirection, value: T) {
if direction.is_row() {
self.height = value
@@ -324,6 +336,7 @@ impl<T> Size<T> {
///
/// Whether this is the width or height depends on the `direction` provided
#[allow(dead_code)]
+ #[cfg(feature = "flexbox")]
pub(crate) fn with_main(self, direction: FlexDirection, value: T) -> Self {
let mut new = self;
if direction.is_row() {
@@ -337,6 +350,7 @@ impl<T> Size<T> {
/// Creates a new value of type Self with the cross axis set to value provided
///
/// Whether this is the width or height depends on the `direction` provided
+ #[cfg(feature = "flexbox")]
pub(crate) fn with_cross(self, direction: FlexDirection, value: T) -> Self {
let mut new = self;
if direction.is_row() {
@@ -350,6 +364,7 @@ impl<T> Size<T> {
/// Gets the extent of the main layout axis
///
/// Whether this is the width or height depends on the `direction` provided
+ #[cfg(feature = "flexbox")]
pub(crate) fn main(self, direction: FlexDirection) -> T {
if direction.is_row() {
self.width
@@ -361,6 +376,7 @@ impl<T> Size<T> {
/// Gets the extent of the cross layout axis
///
/// Whether this is the width or height depends on the `direction` provided
+ #[cfg(feature = "flexbox")]
pub(crate) fn cross(self, direction: FlexDirection) -> T {
if direction.is_row() {
self.height
diff --git a/src/prelude.rs b/src/prelude.rs
index db21a6df2..22a89a119 100644
--- a/src/prelude.rs
+++ b/src/prelude.rs
@@ -1,9 +1,13 @@
//! Commonly used types
-use crate::compute::LayoutAlgorithm;
-use crate::layout::{SizeAndBaselines, SizingMode};
+#[cfg(feature = "flexbox")]
+use crate::{
+ compute::LayoutAlgorithm,
+ layout::{SizeAndBaselines, SizingMode},
+};
/// Apply the flexbox algorithm and recursively layout the specified node
+#[cfg(feature = "flexbox")]
#[inline(always)]
pub fn layout_flexbox(
tree: &mut impl LayoutTree,
@@ -28,8 +32,8 @@ pub use crate::{
layout::Layout,
node::{Node, Taffy},
style::{
- AlignContent, AlignItems, AlignSelf, AvailableSpace, Dimension, Display, FlexDirection, FlexWrap,
- JustifyContent, JustifyItems, JustifySelf, LengthPercentage, LengthPercentageAuto, Position, Style,
+ AlignContent, AlignItems, AlignSelf, AvailableSpace, Dimension, Display, JustifyContent, JustifyItems,
+ JustifySelf, LengthPercentage, LengthPercentageAuto, Position, Style,
},
style_helpers::{
auto, fit_content, max_content, min_content, percent, points, zero, FromFlex, FromPercent, FromPoints,
@@ -38,6 +42,9 @@ pub use crate::{
tree::LayoutTree,
};
+#[cfg(feature = "flexbox")]
+pub use crate::style::{FlexDirection, FlexWrap};
+
#[cfg(feature = "grid")]
pub use crate::style::{
GridAutoFlow, GridPlacement, GridTrackRepetition, MaxTrackSizingFunction, MinTrackSizingFunction,
diff --git a/src/style/mod.rs b/src/style/mod.rs
index ee4fa9d21..a784bd6e8 100644
--- a/src/style/mod.rs
+++ b/src/style/mod.rs
@@ -1,10 +1,14 @@
//! A representation of [CSS layout properties](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) in Rust, used for flexbox layout
mod alignment;
mod dimension;
+
+#[cfg(feature = "flexbox")]
mod flex;
pub use self::alignment::{AlignContent, AlignItems, AlignSelf, JustifyContent, JustifyItems, JustifySelf};
pub use self::dimension::{AvailableSpace, Dimension, LengthPercentage, LengthPercentageAuto};
+
+#[cfg(feature = "flexbox")]
pub use self::flex::{FlexDirection, FlexWrap};
#[cfg(feature = "grid")]
@@ -27,11 +31,12 @@ use crate::sys::GridTrackVec;
/// Sets the layout used for the children of this node
///
-/// [`Display::Flex`] is the default value.
+/// The default values depends on on which feature flags are enabled. The order of precedence is: Flex, Grid, None.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum Display {
/// The children will follow the flexbox layout algorithm
+ #[cfg(feature = "flexbox")]
Flex,
/// The children will follow the CSS Grid layout algorithm
#[cfg(feature = "grid")]
@@ -40,9 +45,23 @@ pub enum Display {
None,
}
+impl Display {
+ /// The default of Display.
+ #[cfg(feature = "flexbox")]
+ pub const DEFAULT: Display = Display::Flex;
+
+ /// The default of Display.
+ #[cfg(all(feature = "grid", not(feature = "flexbox")))]
+ pub const DEFAULT: Display = Display::Grid;
+
+ /// The default of Display.
+ #[cfg(all(not(feature = "flexbox"), not(feature = "grid")))]
+ pub const DEFAULT: Display = Display::None;
+}
+
impl Default for Display {
fn default() -> Self {
- Self::Flex
+ Self::DEFAULT
}
}
@@ -131,38 +150,49 @@ pub struct Style {
// Alignment properties
/// How this node's children aligned in the cross/block axis?
+ #[cfg(any(feature = "flexbox", feature = "grid"))]
pub align_items: Option<AlignItems>,
/// How this node should be aligned in the cross/block axis
/// Falls back to the parents [`AlignItems`] if not set
+ #[cfg(any(feature = "flexbox", feature = "grid"))]
pub align_self: Option<AlignSelf>,
/// How this node's children should be aligned in the inline axis
#[cfg(feature = "grid")]
pub justify_items: Option<AlignItems>,
/// How this node should be aligned in the inline axis
/// Falls back to the parents [`JustifyItems`] if not set
+ #[cfg(feature = "grid")]
pub justify_self: Option<AlignSelf>,
/// How should content contained within this item be aligned in the cross/block axis
+ #[cfg(any(feature = "flexbox", feature = "grid"))]
pub align_content: Option<AlignContent>,
/// How should contained within this item be aligned in the main/inline axis
+ #[cfg(any(feature = "flexbox", feature = "grid"))]
pub justify_content: Option<JustifyContent>,
/// How large should the gaps between items in a grid or flex container be?
+ #[cfg(any(feature = "flexbox", feature = "grid"))]
#[cfg_attr(feature = "serde", serde(default = "style_helpers::zero"))]
pub gap: Size<LengthPercentage>,
// Flexbox properies
/// Which direction does the main axis flow in?
+ #[cfg(feature = "flexbox")]
pub flex_direction: FlexDirection,
/// Should elements wrap, or stay in a single line?
+ #[cfg(feature = "flexbox")]
pub flex_wrap: FlexWrap,
/// Sets the initial main axis size of the item
+ #[cfg(feature = "flexbox")]
pub flex_basis: Dimension,
/// The relative rate at which this item grows when it is expanding to fill space
///
/// 0.0 is the default value, and this value must be positive.
+ #[cfg(feature = "flexbox")]
pub flex_grow: f32,
/// The relative rate at which this item shrinks when it is contracting to fit into space
///
/// 1.0 is the default value, and this value must be positive.
+ #[cfg(feature = "flexbox")]
pub flex_shrink: f32,
// Grid container properies
@@ -194,29 +224,43 @@ pub struct Style {
impl Style {
/// The [`Default`] layout, in a form that can be used in const functions
pub const DEFAULT: Style = Style {
- display: Display::Flex,
+ display: Display::DEFAULT,
position: Position::Relative,
- flex_direction: FlexDirection::Row,
- flex_wrap: FlexWrap::NoWrap,
+ inset: Rect::auto(),
+ margin: Rect::zero(),
+ padding: Rect::zero(),
+ border: Rect::zero(),
+ size: Size::auto(),
+ min_size: Size::auto(),
+ max_size: Size::auto(),
+ aspect_ratio: None,
+ #[cfg(any(feature = "flexbox", feature = "grid"))]
+ gap: Size::zero(),
+ // Aligment
+ #[cfg(any(feature = "flexbox", feature = "grid"))]
align_items: None,
+ #[cfg(any(feature = "flexbox", feature = "grid"))]
align_self: None,
#[cfg(feature = "grid")]
justify_items: None,
+ #[cfg(feature = "grid")]
justify_self: None,
+ #[cfg(any(feature = "flexbox", feature = "grid"))]
align_content: None,
+ #[cfg(any(feature = "flexbox", feature = "grid"))]
justify_content: None,
- inset: Rect::auto(),
- margin: Rect::zero(),
- padding: Rect::zero(),
- border: Rect::zero(),
- gap: Size::zero(),
+ // Flexbox
+ #[cfg(feature = "flexbox")]
+ flex_direction: FlexDirection::Row,
+ #[cfg(feature = "flexbox")]
+ flex_wrap: FlexWrap::NoWrap,
+ #[cfg(feature = "flexbox")]
flex_grow: 0.0,
+ #[cfg(feature = "flexbox")]
flex_shrink: 1.0,
+ #[cfg(feature = "flexbox")]
flex_basis: Dimension::Auto,
- size: Size::auto(),
- min_size: Size::auto(),
- max_size: Size::auto(),
- aspect_ratio: None,
+ // Grid
#[cfg(feature = "grid")]
grid_template_rows: GridTrackVec::new(),
#[cfg(feature = "grid")]
@@ -253,22 +297,32 @@ mod tests {
let old_defaults = Style {
display: Default::default(),
position: Default::default(),
+ #[cfg(feature = "flexbox")]
flex_direction: Default::default(),
+ #[cfg(feature = "flexbox")]
flex_wrap: Default::default(),
+ #[cfg(any(feature = "flexbox", feature = "grid"))]
align_items: Default::default(),
+ #[cfg(any(feature = "flexbox", feature = "grid"))]
align_self: Default::default(),
#[cfg(feature = "grid")]
justify_items: Default::default(),
+ #[cfg(feature = "grid")]
justify_self: Default::default(),
+ #[cfg(any(feature = "flexbox", feature = "grid"))]
align_content: Default::default(),
+ #[cfg(any(feature = "flexbox", feature = "grid"))]
justify_content: Default::default(),
inset: Rect::auto(),
margin: Rect::zero(),
padding: Rect::zero(),
border: Rect::zero(),
gap: Size::zero(),
+ #[cfg(feature = "flexbox")]
flex_grow: 0.0,
+ #[cfg(feature = "flexbox")]
flex_shrink: 1.0,
+ #[cfg(feature = "flexbox")]
flex_basis: super::Dimension::Auto,
size: Size::auto(),
min_size: Size::auto(),