gioser

tawasuyu/taffy

A high performance rust-powered UI layout library

HTML 5544Rust 88Markdown 11TOML 91926 Definitions

⎇ 70341c9f697b610470b0806a53266aa75343563b src/style/mod.rs Rust · 1294 lines · 44.1 KB History Who touched what raw

Add support for parsing Taffy style types from string (#929) 70341c9f6 · Nico Burns ·

1//! A typed representation of [CSS style properties](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) in Rust. Used as input to layout computation.
2mod alignment;
3mod available_space;
4mod compact_length;
5mod dimension;
6
7#[cfg(feature = "block_layout")]
8mod block;
9#[cfg(feature = "flexbox")]
10mod flex;
11#[cfg(feature = "float_layout")]
12mod float;
13#[cfg(feature = "grid")]
14mod grid;
15
16pub use self::alignment::{AlignContent, AlignItems, AlignSelf, JustifyContent, JustifyItems, JustifySelf};
17pub use self::available_space::AvailableSpace;
18pub use self::compact_length::CompactLength;
19pub use self::dimension::{Dimension, LengthPercentage, LengthPercentageAuto};
20use crate::sys::DefaultCheapStr;
21
22#[cfg(feature = "block_layout")]
23pub use self::block::{BlockContainerStyle, BlockItemStyle, TextAlign};
24#[cfg(feature = "flexbox")]
25pub use self::flex::{FlexDirection, FlexWrap, FlexboxContainerStyle, FlexboxItemStyle};
26#[cfg(feature = "float_layout")]
27pub use self::float::{Clear, Float, FloatDirection};
28#[cfg(feature = "grid")]
29pub use self::grid::{
30    GenericGridPlacement, GenericGridTemplateComponent, GenericRepetition, GridAutoFlow, GridAutoTracks,
31    GridContainerStyle, GridItemStyle, GridPlacement, GridTemplateComponent, GridTemplateRepetition,
32    GridTemplateTracks, MaxTrackSizingFunction, MinTrackSizingFunction, RepetitionCount, TrackSizingFunction,
33};
34#[cfg(feature = "grid")]
35pub(crate) use self::grid::{GridAreaAxis, GridAreaEnd};
36#[cfg(feature = "grid")]
37pub use self::grid::{GridTemplateArea, NamedGridLine, TemplateLineNames};
38#[cfg(feature = "grid")]
39pub(crate) use self::grid::{NonNamedGridPlacement, OriginZeroGridPlacement};
40
41use crate::geometry::{Point, Rect, Size};
42use crate::style_helpers::TaffyAuto as _;
43use core::fmt::Debug;
44
45#[cfg(feature = "grid")]
46use crate::geometry::Line;
47#[cfg(feature = "serde")]
48use crate::style_helpers;
49#[cfg(feature = "grid")]
50use crate::util::sys::GridTrackVec;
51
52use crate::sys::String;
53
54/// Trait that represents a cheaply clonable string. If you're unsure what to use here
55/// consider `Arc<str>` or `string_cache::Atom`.
56#[cfg(any(feature = "alloc", feature = "std"))]
57pub trait CheapCloneStr:
58    AsRef<str> + for<'a> From<&'a str> + From<String> + PartialEq + Eq + Clone + Default + Debug + 'static
59{
60}
61#[cfg(any(feature = "alloc", feature = "std"))]
62impl<T> CheapCloneStr for T where
63    T: AsRef<str> + for<'a> From<&'a str> + From<String> + PartialEq + Eq + Clone + Default + Debug + 'static
64{
65}
66
67/// Trait that represents a cheaply clonable string. If you're unsure what to use here
68/// consider `Arc<str>` or `string_cache::Atom`.
69#[cfg(not(any(feature = "alloc", feature = "std")))]
70pub trait CheapCloneStr {}
71#[cfg(not(any(feature = "alloc", feature = "std")))]
72impl<T> CheapCloneStr for T {}
73
74/// The core set of styles that are shared between all CSS layout nodes
75///
76/// Note that all methods come with a default implementation which simply returns the default value for that style property
77/// but this is a just a convenience to save on boilerplate for styles that your implementation doesn't support. You will need
78/// to override the default implementation for each style property that your style type actually supports.
79pub trait CoreStyle {
80    /// The type of custom identifiers used to identify named grid lines and areas
81    type CustomIdent: CheapCloneStr;
82
83    /// Which box generation mode should be used
84    #[inline(always)]
85    fn box_generation_mode(&self) -> BoxGenerationMode {
86        BoxGenerationMode::DEFAULT
87    }
88    /// Is block layout?
89    #[inline(always)]
90    fn is_block(&self) -> bool {
91        false
92    }
93    /// Is it a compressible replaced element?
94    /// <https://drafts.csswg.org/css-sizing-3/#min-content-zero>
95    #[inline(always)]
96    fn is_compressible_replaced(&self) -> bool {
97        false
98    }
99    /// Which box do size styles apply to
100    #[inline(always)]
101    fn box_sizing(&self) -> BoxSizing {
102        BoxSizing::BorderBox
103    }
104
105    // Overflow properties
106    /// How children overflowing their container should affect layout
107    #[inline(always)]
108    fn overflow(&self) -> Point<Overflow> {
109        Style::<Self::CustomIdent>::DEFAULT.overflow
110    }
111    /// How much space (in points) should be reserved for the scrollbars of `Overflow::Scroll` and `Overflow::Auto` nodes.
112    #[inline(always)]
113    fn scrollbar_width(&self) -> f32 {
114        0.0
115    }
116
117    // Position properties
118    /// What should the `position` value of this struct use as a base offset?
119    #[inline(always)]
120    fn position(&self) -> Position {
121        Style::<Self::CustomIdent>::DEFAULT.position
122    }
123    /// How should the position of this element be tweaked relative to the layout defined?
124    #[inline(always)]
125    fn inset(&self) -> Rect<LengthPercentageAuto> {
126        Style::<Self::CustomIdent>::DEFAULT.inset
127    }
128
129    // Size properies
130    /// Sets the initial size of the item
131    #[inline(always)]
132    fn size(&self) -> Size<Dimension> {
133        Style::<Self::CustomIdent>::DEFAULT.size
134    }
135    /// Controls the minimum size of the item
136    #[inline(always)]
137    fn min_size(&self) -> Size<Dimension> {
138        Style::<Self::CustomIdent>::DEFAULT.min_size
139    }
140    /// Controls the maximum size of the item
141    #[inline(always)]
142    fn max_size(&self) -> Size<Dimension> {
143        Style::<Self::CustomIdent>::DEFAULT.max_size
144    }
145    /// Sets the preferred aspect ratio for the item
146    /// The ratio is calculated as width divided by height.
147    #[inline(always)]
148    fn aspect_ratio(&self) -> Option<f32> {
149        Style::<Self::CustomIdent>::DEFAULT.aspect_ratio
150    }
151
152    // Spacing Properties
153    /// How large should the margin be on each side?
154    #[inline(always)]
155    fn margin(&self) -> Rect<LengthPercentageAuto> {
156        Style::<Self::CustomIdent>::DEFAULT.margin
157    }
158    /// How large should the padding be on each side?
159    #[inline(always)]
160    fn padding(&self) -> Rect<LengthPercentage> {
161        Style::<Self::CustomIdent>::DEFAULT.padding
162    }
163    /// How large should the border be on each side?
164    #[inline(always)]
165    fn border(&self) -> Rect<LengthPercentage> {
166        Style::<Self::CustomIdent>::DEFAULT.border
167    }
168}
169
170/// Sets the layout used for the children of this node
171///
172/// The default values depends on on which feature flags are enabled. The order of precedence is: Flex, Grid, Block, None.
173#[derive(Copy, Clone, PartialEq, Eq, Debug)]
174#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
175pub enum Display {
176    /// The children will follow the block layout algorithm
177    #[cfg(feature = "block_layout")]
178    Block,
179    /// The children will follow the flexbox layout algorithm
180    #[cfg(feature = "flexbox")]
181    Flex,
182    /// The children will follow the CSS Grid layout algorithm
183    #[cfg(feature = "grid")]
184    Grid,
185    /// The node is hidden, and it's children will also be hidden
186    None,
187}
188
189impl Display {
190    /// The default Display mode
191    #[cfg(feature = "flexbox")]
192    pub const DEFAULT: Display = Display::Flex;
193
194    /// The default Display mode
195    #[cfg(all(feature = "grid", not(feature = "flexbox")))]
196    pub const DEFAULT: Display = Display::Grid;
197
198    /// The default Display mode
199    #[cfg(all(feature = "block_layout", not(feature = "flexbox"), not(feature = "grid")))]
200    pub const DEFAULT: Display = Display::Block;
201
202    /// The default Display mode
203    #[cfg(all(not(feature = "flexbox"), not(feature = "grid"), not(feature = "block_layout")))]
204    pub const DEFAULT: Display = Display::None;
205}
206
207impl Default for Display {
208    fn default() -> Self {
209        Self::DEFAULT
210    }
211}
212
213#[cfg(feature = "parse")]
214crate::util::parse::impl_parse_for_keyword_enum!(Display,
215    "none" => None,
216    #[cfg(feature = "flexbox")]
217    "flex" => Flex,
218    #[cfg(feature = "grid")]
219    "grid" => Grid,
220    #[cfg(feature = "block_layout")]
221    "block" => Block,
222);
223
224impl core::fmt::Display for Display {
225    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
226        match self {
227            Display::None => write!(f, "NONE"),
228            #[cfg(feature = "block_layout")]
229            Display::Block => write!(f, "BLOCK"),
230            #[cfg(feature = "flexbox")]
231            Display::Flex => write!(f, "FLEX"),
232            #[cfg(feature = "grid")]
233            Display::Grid => write!(f, "GRID"),
234        }
235    }
236}
237
238/// An abstracted version of the CSS `display` property where any value other than "none" is represented by "normal"
239/// See: <https://www.w3.org/TR/css-display-3/#box-generation>
240#[derive(Copy, Clone, PartialEq, Eq, Debug)]
241#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
242pub enum BoxGenerationMode {
243    /// The node generates a box in the regular way
244    Normal,
245    /// The node and it's descendants generate no boxes (they are hidden)
246    None,
247}
248
249impl BoxGenerationMode {
250    /// The default of BoxGenerationMode
251    pub const DEFAULT: BoxGenerationMode = BoxGenerationMode::Normal;
252}
253
254impl Default for BoxGenerationMode {
255    fn default() -> Self {
256        Self::DEFAULT
257    }
258}
259
260/// The positioning strategy for this item.
261///
262/// This controls both how the origin is determined for the [`Style::position`] field,
263/// and whether or not the item will be controlled by flexbox's layout algorithm.
264///
265/// WARNING: this enum follows the behavior of [CSS's `position` property](https://developer.mozilla.org/en-US/docs/Web/CSS/position),
266/// which can be unintuitive.
267///
268/// [`Position::Relative`] is the default value, in contrast to the default behavior in CSS.
269#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
270#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
271pub enum Position {
272    /// The offset is computed relative to the final position given by the layout algorithm.
273    /// Offsets do not affect the position of any other items; they are effectively a correction factor applied at the end.
274    #[default]
275    Relative,
276    /// The offset is computed relative to this item's closest positioned ancestor, if any.
277    /// Otherwise, it is placed relative to the origin.
278    /// No space is created for the item in the page layout, and its size will not be altered.
279    ///
280    /// WARNING: to opt-out of layouting entirely, you must use [`Display::None`] instead on your [`Style`] object.
281    Absolute,
282}
283
284#[cfg(feature = "parse")]
285crate::util::parse::impl_parse_for_keyword_enum!(Position,
286    "relative" => Relative,
287    "absolute" => Absolute,
288);
289
290/// Specifies whether size styles for this node are assigned to the node's "content box" or "border box"
291///
292/// - The "content box" is the node's inner size excluding padding, border and margin
293/// - The "border box" is the node's outer size including padding and border (but still excluding margin)
294///
295/// This property modifies the application of the following styles:
296///
297///   - `size`
298///   - `min_size`
299///   - `max_size`
300///   - `flex_basis`
301///
302/// See <https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing>
303#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
304#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
305pub enum BoxSizing {
306    /// Size styles such size, min_size, max_size specify the box's "border box" (the size excluding margin but including padding/border)
307    #[default]
308    BorderBox,
309    /// Size styles such size, min_size, max_size specify the box's "content box" (the size excluding padding/border/margin)
310    ContentBox,
311}
312
313#[cfg(feature = "parse")]
314crate::util::parse::impl_parse_for_keyword_enum!(BoxSizing,
315    "border-box" => BorderBox,
316    "content-box" => ContentBox,
317);
318
319/// How children overflowing their container should affect layout
320///
321/// In CSS the primary effect of this property is to control whether contents of a parent container that overflow that container should
322/// be displayed anyway, be clipped, or trigger the container to become a scroll container. However it also has secondary effects on layout,
323/// the main ones being:
324///
325///   - The automatic minimum size Flexbox/CSS Grid items with non-`Visible` overflow is `0` rather than being content based
326///   - `Overflow::Scroll` nodes have space in the layout reserved for a scrollbar (width controlled by the `scrollbar_width` property)
327///
328/// In Taffy, we only implement the layout related secondary effects as we are not concerned with drawing/painting. The amount of space reserved for
329/// a scrollbar is controlled by the `scrollbar_width` property. If this is `0` then `Scroll` behaves identically to `Hidden`.
330///
331/// <https://developer.mozilla.org/en-US/docs/Web/CSS/overflow>
332#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
333#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
334pub enum Overflow {
335    /// The automatic minimum size of this node as a flexbox/grid item should be based on the size of its content.
336    /// Content that overflows this node *should* contribute to the scroll region of its parent.
337    #[default]
338    Visible,
339    /// The automatic minimum size of this node as a flexbox/grid item should be based on the size of its content.
340    /// Content that overflows this node should *not* contribute to the scroll region of its parent.
341    Clip,
342    /// The automatic minimum size of this node as a flexbox/grid item should be `0`.
343    /// Content that overflows this node should *not* contribute to the scroll region of its parent.
344    Hidden,
345    /// The automatic minimum size of this node as a flexbox/grid item should be `0`. Additionally, space should be reserved
346    /// for a scrollbar. The amount of space reserved is controlled by the `scrollbar_width` property.
347    /// Content that overflows this node should *not* contribute to the scroll region of its parent.
348    Scroll,
349}
350
351impl Overflow {
352    /// Returns true for overflow modes that contain their contents (`Overflow::Hidden`, `Overflow::Scroll`, `Overflow::Auto`)
353    /// or else false for overflow modes that allow their contains to spill (`Overflow::Visible`).
354    #[inline(always)]
355    pub fn is_scroll_container(self) -> bool {
356        match self {
357            Self::Visible | Self::Clip => false,
358            Self::Hidden | Self::Scroll => true,
359        }
360    }
361
362    /// Returns `Some(0.0)` if the overflow mode would cause the automatic minimum size of a Flexbox or CSS Grid item
363    /// to be `0`. Else returns None.
364    #[inline(always)]
365    pub(crate) fn maybe_into_automatic_min_size(self) -> Option<f32> {
366        match self.is_scroll_container() {
367            true => Some(0.0),
368            false => None,
369        }
370    }
371}
372
373#[cfg(feature = "parse")]
374crate::util::parse::impl_parse_for_keyword_enum!(Overflow,
375    "visible" => Visible,
376    "hidden" => Hidden,
377    "clip" => Clip,
378    "scroll" => Scroll,
379);
380
381/// A typed representation of the CSS style information for a single node.
382///
383/// The most important idea in flexbox is the notion of a "main" and "cross" axis, which are always perpendicular to each other.
384/// The orientation of these axes are controlled via the [`FlexDirection`] field of this struct.
385///
386/// This struct follows the [CSS equivalent](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox) directly;
387/// information about the behavior on the web should transfer directly.
388///
389/// Detailed information about the exact behavior of each of these fields
390/// can be found on [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS) by searching for the field name.
391/// The distinction between margin, padding and border is explained well in
392/// this [introduction to the box model](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model).
393///
394/// If the behavior does not match the flexbox layout algorithm on the web, please file a bug!
395#[derive(Clone, PartialEq, Debug)]
396#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
397#[cfg_attr(feature = "serde", serde(default))]
398pub struct Style<S: CheapCloneStr = DefaultCheapStr> {
399    /// This is a dummy field which is necessary to make Taffy compile with the `grid` feature disabled
400    /// It should always be set to `core::marker::PhantomData`.
401    pub dummy: core::marker::PhantomData<S>,
402    /// What layout strategy should be used?
403    pub display: Display,
404    /// Whether a child is display:table or not. This affects children of block layouts.
405    /// This should really be part of `Display`, but it is currently seperate because table layout isn't implemented
406    pub item_is_table: bool,
407    /// Is it a replaced element like an image or form field?
408    /// <https://drafts.csswg.org/css-sizing-3/#min-content-zero>
409    pub item_is_replaced: bool,
410    /// Should size styles apply to the content box or the border box of the node
411    pub box_sizing: BoxSizing,
412
413    // Overflow properties
414    /// How children overflowing their container should affect layout
415    pub overflow: Point<Overflow>,
416    /// How much space (in points) should be reserved for the scrollbars of `Overflow::Scroll` and `Overflow::Auto` nodes.
417    pub scrollbar_width: f32,
418
419    #[cfg(feature = "float_layout")]
420    /// Should the box be floated
421    pub float: Float,
422    #[cfg(feature = "float_layout")]
423    /// Should the box clear floats
424    pub clear: Clear,
425
426    // Position properties
427    /// What should the `position` value of this struct use as a base offset?
428    pub position: Position,
429    /// How should the position of this element be tweaked relative to the layout defined?
430    #[cfg_attr(feature = "serde", serde(default = "style_helpers::auto"))]
431    pub inset: Rect<LengthPercentageAuto>,
432
433    // Size properties
434    /// Sets the initial size of the item
435    #[cfg_attr(feature = "serde", serde(default = "style_helpers::auto"))]
436    pub size: Size<Dimension>,
437    /// Controls the minimum size of the item
438    #[cfg_attr(feature = "serde", serde(default = "style_helpers::auto"))]
439    pub min_size: Size<Dimension>,
440    /// Controls the maximum size of the item
441    #[cfg_attr(feature = "serde", serde(default = "style_helpers::auto"))]
442    pub max_size: Size<Dimension>,
443    /// Sets the preferred aspect ratio for the item
444    ///
445    /// The ratio is calculated as width divided by height.
446    pub aspect_ratio: Option<f32>,
447
448    // Spacing Properties
449    /// How large should the margin be on each side?
450    #[cfg_attr(feature = "serde", serde(default = "style_helpers::zero"))]
451    pub margin: Rect<LengthPercentageAuto>,
452    /// How large should the padding be on each side?
453    #[cfg_attr(feature = "serde", serde(default = "style_helpers::zero"))]
454    pub padding: Rect<LengthPercentage>,
455    /// How large should the border be on each side?
456    #[cfg_attr(feature = "serde", serde(default = "style_helpers::zero"))]
457    pub border: Rect<LengthPercentage>,
458
459    // Alignment properties
460    /// How this node's children aligned in the cross/block axis?
461    #[cfg(any(feature = "flexbox", feature = "grid"))]
462    pub align_items: Option<AlignItems>,
463    /// How this node should be aligned in the cross/block axis
464    /// Falls back to the parents [`AlignItems`] if not set
465    #[cfg(any(feature = "flexbox", feature = "grid"))]
466    pub align_self: Option<AlignSelf>,
467    /// How this node's children should be aligned in the inline axis
468    #[cfg(feature = "grid")]
469    pub justify_items: Option<AlignItems>,
470    /// How this node should be aligned in the inline axis
471    /// Falls back to the parents [`JustifyItems`] if not set
472    #[cfg(feature = "grid")]
473    pub justify_self: Option<AlignSelf>,
474    /// How should content contained within this item be aligned in the cross/block axis
475    #[cfg(any(feature = "flexbox", feature = "grid"))]
476    pub align_content: Option<AlignContent>,
477    /// How should content contained within this item be aligned in the main/inline axis
478    #[cfg(any(feature = "flexbox", feature = "grid"))]
479    pub justify_content: Option<JustifyContent>,
480    /// How large should the gaps between items in a grid or flex container be?
481    #[cfg(any(feature = "flexbox", feature = "grid"))]
482    #[cfg_attr(feature = "serde", serde(default = "style_helpers::zero"))]
483    pub gap: Size<LengthPercentage>,
484
485    // Block container properties
486    /// How items elements should aligned in the inline axis
487    #[cfg(feature = "block_layout")]
488    pub text_align: TextAlign,
489
490    // Flexbox container properties
491    /// Which direction does the main axis flow in?
492    #[cfg(feature = "flexbox")]
493    pub flex_direction: FlexDirection,
494    /// Should elements wrap, or stay in a single line?
495    #[cfg(feature = "flexbox")]
496    pub flex_wrap: FlexWrap,
497
498    // Flexbox item properties
499    /// Sets the initial main axis size of the item
500    #[cfg(feature = "flexbox")]
501    pub flex_basis: Dimension,
502    /// The relative rate at which this item grows when it is expanding to fill space
503    ///
504    /// 0.0 is the default value, and this value must be positive.
505    #[cfg(feature = "flexbox")]
506    pub flex_grow: f32,
507    /// The relative rate at which this item shrinks when it is contracting to fit into space
508    ///
509    /// 1.0 is the default value, and this value must be positive.
510    #[cfg(feature = "flexbox")]
511    pub flex_shrink: f32,
512
513    // Grid container properies
514    /// Defines the track sizing functions (heights) of the grid rows
515    #[cfg(feature = "grid")]
516    pub grid_template_rows: GridTrackVec<GridTemplateComponent<S>>,
517    /// Defines the track sizing functions (widths) of the grid columns
518    #[cfg(feature = "grid")]
519    pub grid_template_columns: GridTrackVec<GridTemplateComponent<S>>,
520    /// Defines the size of implicitly created rows
521    #[cfg(feature = "grid")]
522    pub grid_auto_rows: GridTrackVec<TrackSizingFunction>,
523    /// Defined the size of implicitly created columns
524    #[cfg(feature = "grid")]
525    pub grid_auto_columns: GridTrackVec<TrackSizingFunction>,
526    /// Controls how items get placed into the grid for auto-placed items
527    #[cfg(feature = "grid")]
528    pub grid_auto_flow: GridAutoFlow,
529
530    // Grid container named properties
531    /// Defines the rectangular grid areas
532    #[cfg(feature = "grid")]
533    pub grid_template_areas: GridTrackVec<GridTemplateArea<S>>,
534    /// The named lines between the columns
535    #[cfg(feature = "grid")]
536    pub grid_template_column_names: GridTrackVec<GridTrackVec<S>>,
537    /// The named lines between the rows
538    #[cfg(feature = "grid")]
539    pub grid_template_row_names: GridTrackVec<GridTrackVec<S>>,
540
541    // Grid child properties
542    /// Defines which row in the grid the item should start and end at
543    #[cfg(feature = "grid")]
544    pub grid_row: Line<GridPlacement<S>>,
545    /// Defines which column in the grid the item should start and end at
546    #[cfg(feature = "grid")]
547    pub grid_column: Line<GridPlacement<S>>,
548}
549
550impl<S: CheapCloneStr> Style<S> {
551    /// The [`Default`] layout, in a form that can be used in const functions
552    pub const DEFAULT: Style<S> = Style {
553        dummy: core::marker::PhantomData,
554        display: Display::DEFAULT,
555        item_is_table: false,
556        item_is_replaced: false,
557        box_sizing: BoxSizing::BorderBox,
558        overflow: Point { x: Overflow::Visible, y: Overflow::Visible },
559        scrollbar_width: 0.0,
560        #[cfg(feature = "float_layout")]
561        float: Float::None,
562        #[cfg(feature = "float_layout")]
563        clear: Clear::None,
564        position: Position::Relative,
565        inset: Rect::auto(),
566        margin: Rect::zero(),
567        padding: Rect::zero(),
568        border: Rect::zero(),
569        size: Size::auto(),
570        min_size: Size::auto(),
571        max_size: Size::auto(),
572        aspect_ratio: None,
573        #[cfg(any(feature = "flexbox", feature = "grid"))]
574        gap: Size::zero(),
575        // Alignment
576        #[cfg(any(feature = "flexbox", feature = "grid"))]
577        align_items: None,
578        #[cfg(any(feature = "flexbox", feature = "grid"))]
579        align_self: None,
580        #[cfg(feature = "grid")]
581        justify_items: None,
582        #[cfg(feature = "grid")]
583        justify_self: None,
584        #[cfg(any(feature = "flexbox", feature = "grid"))]
585        align_content: None,
586        #[cfg(any(feature = "flexbox", feature = "grid"))]
587        justify_content: None,
588        // Block
589        #[cfg(feature = "block_layout")]
590        text_align: TextAlign::Auto,
591        // Flexbox
592        #[cfg(feature = "flexbox")]
593        flex_direction: FlexDirection::Row,
594        #[cfg(feature = "flexbox")]
595        flex_wrap: FlexWrap::NoWrap,
596        #[cfg(feature = "flexbox")]
597        flex_grow: 0.0,
598        #[cfg(feature = "flexbox")]
599        flex_shrink: 1.0,
600        #[cfg(feature = "flexbox")]
601        flex_basis: Dimension::AUTO,
602        // Grid
603        #[cfg(feature = "grid")]
604        grid_template_rows: GridTrackVec::new(),
605        #[cfg(feature = "grid")]
606        grid_template_columns: GridTrackVec::new(),
607        #[cfg(feature = "grid")]
608        grid_template_areas: GridTrackVec::new(),
609        #[cfg(feature = "grid")]
610        grid_template_column_names: GridTrackVec::new(),
611        #[cfg(feature = "grid")]
612        grid_template_row_names: GridTrackVec::new(),
613        #[cfg(feature = "grid")]
614        grid_auto_rows: GridTrackVec::new(),
615        #[cfg(feature = "grid")]
616        grid_auto_columns: GridTrackVec::new(),
617        #[cfg(feature = "grid")]
618        grid_auto_flow: GridAutoFlow::Row,
619        #[cfg(feature = "grid")]
620        grid_row: Line { start: GridPlacement::<S>::Auto, end: GridPlacement::<S>::Auto },
621        #[cfg(feature = "grid")]
622        grid_column: Line { start: GridPlacement::<S>::Auto, end: GridPlacement::<S>::Auto },
623    };
624}
625
626impl<S: CheapCloneStr> Default for Style<S> {
627    fn default() -> Self {
628        Style::DEFAULT
629    }
630}
631
632impl<S: CheapCloneStr> CoreStyle for Style<S> {
633    type CustomIdent = S;
634
635    #[inline(always)]
636    fn box_generation_mode(&self) -> BoxGenerationMode {
637        match self.display {
638            Display::None => BoxGenerationMode::None,
639            _ => BoxGenerationMode::Normal,
640        }
641    }
642    #[inline(always)]
643    #[cfg(feature = "block_layout")]
644    fn is_block(&self) -> bool {
645        matches!(self.display, Display::Block)
646    }
647    #[inline(always)]
648    fn is_compressible_replaced(&self) -> bool {
649        self.item_is_replaced
650    }
651    #[inline(always)]
652    fn box_sizing(&self) -> BoxSizing {
653        self.box_sizing
654    }
655    #[inline(always)]
656    fn overflow(&self) -> Point<Overflow> {
657        self.overflow
658    }
659    #[inline(always)]
660    fn scrollbar_width(&self) -> f32 {
661        self.scrollbar_width
662    }
663    #[inline(always)]
664    fn position(&self) -> Position {
665        self.position
666    }
667    #[inline(always)]
668    fn inset(&self) -> Rect<LengthPercentageAuto> {
669        self.inset
670    }
671    #[inline(always)]
672    fn size(&self) -> Size<Dimension> {
673        self.size
674    }
675    #[inline(always)]
676    fn min_size(&self) -> Size<Dimension> {
677        self.min_size
678    }
679    #[inline(always)]
680    fn max_size(&self) -> Size<Dimension> {
681        self.max_size
682    }
683    #[inline(always)]
684    fn aspect_ratio(&self) -> Option<f32> {
685        self.aspect_ratio
686    }
687    #[inline(always)]
688    fn margin(&self) -> Rect<LengthPercentageAuto> {
689        self.margin
690    }
691    #[inline(always)]
692    fn padding(&self) -> Rect<LengthPercentage> {
693        self.padding
694    }
695    #[inline(always)]
696    fn border(&self) -> Rect<LengthPercentage> {
697        self.border
698    }
699}
700
701impl<T: CoreStyle> CoreStyle for &'_ T {
702    type CustomIdent = T::CustomIdent;
703
704    #[inline(always)]
705    fn box_generation_mode(&self) -> BoxGenerationMode {
706        (*self).box_generation_mode()
707    }
708    #[inline(always)]
709    fn is_block(&self) -> bool {
710        (*self).is_block()
711    }
712    #[inline(always)]
713    fn is_compressible_replaced(&self) -> bool {
714        (*self).is_compressible_replaced()
715    }
716    #[inline(always)]
717    fn box_sizing(&self) -> BoxSizing {
718        (*self).box_sizing()
719    }
720    #[inline(always)]
721    fn overflow(&self) -> Point<Overflow> {
722        (*self).overflow()
723    }
724    #[inline(always)]
725    fn scrollbar_width(&self) -> f32 {
726        (*self).scrollbar_width()
727    }
728    #[inline(always)]
729    fn position(&self) -> Position {
730        (*self).position()
731    }
732    #[inline(always)]
733    fn inset(&self) -> Rect<LengthPercentageAuto> {
734        (*self).inset()
735    }
736    #[inline(always)]
737    fn size(&self) -> Size<Dimension> {
738        (*self).size()
739    }
740    #[inline(always)]
741    fn min_size(&self) -> Size<Dimension> {
742        (*self).min_size()
743    }
744    #[inline(always)]
745    fn max_size(&self) -> Size<Dimension> {
746        (*self).max_size()
747    }
748    #[inline(always)]
749    fn aspect_ratio(&self) -> Option<f32> {
750        (*self).aspect_ratio()
751    }
752    #[inline(always)]
753    fn margin(&self) -> Rect<LengthPercentageAuto> {
754        (*self).margin()
755    }
756    #[inline(always)]
757    fn padding(&self) -> Rect<LengthPercentage> {
758        (*self).padding()
759    }
760    #[inline(always)]
761    fn border(&self) -> Rect<LengthPercentage> {
762        (*self).border()
763    }
764}
765
766#[cfg(feature = "block_layout")]
767impl<S: CheapCloneStr> BlockContainerStyle for Style<S> {
768    #[inline(always)]
769    fn text_align(&self) -> TextAlign {
770        self.text_align
771    }
772}
773
774#[cfg(feature = "block_layout")]
775impl<T: BlockContainerStyle> BlockContainerStyle for &'_ T {
776    #[inline(always)]
777    fn text_align(&self) -> TextAlign {
778        (*self).text_align()
779    }
780}
781
782#[cfg(feature = "block_layout")]
783impl<S: CheapCloneStr> BlockItemStyle for Style<S> {
784    #[inline(always)]
785    fn is_table(&self) -> bool {
786        self.item_is_table
787    }
788
789    #[cfg(feature = "float_layout")]
790    #[inline(always)]
791    fn float(&self) -> Float {
792        self.float
793    }
794
795    #[cfg(feature = "float_layout")]
796    #[inline(always)]
797    fn clear(&self) -> Clear {
798        self.clear
799    }
800}
801
802#[cfg(feature = "block_layout")]
803impl<T: BlockItemStyle> BlockItemStyle for &'_ T {
804    #[inline(always)]
805    fn is_table(&self) -> bool {
806        (*self).is_table()
807    }
808
809    #[cfg(feature = "float_layout")]
810    #[inline(always)]
811    fn float(&self) -> Float {
812        (*self).float()
813    }
814
815    #[cfg(feature = "float_layout")]
816    #[inline(always)]
817    fn clear(&self) -> Clear {
818        (*self).clear()
819    }
820}
821
822#[cfg(feature = "flexbox")]
823impl<S: CheapCloneStr> FlexboxContainerStyle for Style<S> {
824    #[inline(always)]
825    fn flex_direction(&self) -> FlexDirection {
826        self.flex_direction
827    }
828    #[inline(always)]
829    fn flex_wrap(&self) -> FlexWrap {
830        self.flex_wrap
831    }
832    #[inline(always)]
833    fn gap(&self) -> Size<LengthPercentage> {
834        self.gap
835    }
836    #[inline(always)]
837    fn align_content(&self) -> Option<AlignContent> {
838        self.align_content
839    }
840    #[inline(always)]
841    fn align_items(&self) -> Option<AlignItems> {
842        self.align_items
843    }
844    #[inline(always)]
845    fn justify_content(&self) -> Option<JustifyContent> {
846        self.justify_content
847    }
848}
849
850#[cfg(feature = "flexbox")]
851impl<T: FlexboxContainerStyle> FlexboxContainerStyle for &'_ T {
852    #[inline(always)]
853    fn flex_direction(&self) -> FlexDirection {
854        (*self).flex_direction()
855    }
856    #[inline(always)]
857    fn flex_wrap(&self) -> FlexWrap {
858        (*self).flex_wrap()
859    }
860    #[inline(always)]
861    fn gap(&self) -> Size<LengthPercentage> {
862        (*self).gap()
863    }
864    #[inline(always)]
865    fn align_content(&self) -> Option<AlignContent> {
866        (*self).align_content()
867    }
868    #[inline(always)]
869    fn align_items(&self) -> Option<AlignItems> {
870        (*self).align_items()
871    }
872    #[inline(always)]
873    fn justify_content(&self) -> Option<JustifyContent> {
874        (*self).justify_content()
875    }
876}
877
878#[cfg(feature = "flexbox")]
879impl<S: CheapCloneStr> FlexboxItemStyle for Style<S> {
880    #[inline(always)]
881    fn flex_basis(&self) -> Dimension {
882        self.flex_basis
883    }
884    #[inline(always)]
885    fn flex_grow(&self) -> f32 {
886        self.flex_grow
887    }
888    #[inline(always)]
889    fn flex_shrink(&self) -> f32 {
890        self.flex_shrink
891    }
892    #[inline(always)]
893    fn align_self(&self) -> Option<AlignSelf> {
894        self.align_self
895    }
896}
897
898#[cfg(feature = "flexbox")]
899impl<T: FlexboxItemStyle> FlexboxItemStyle for &'_ T {
900    #[inline(always)]
901    fn flex_basis(&self) -> Dimension {
902        (*self).flex_basis()
903    }
904    #[inline(always)]
905    fn flex_grow(&self) -> f32 {
906        (*self).flex_grow()
907    }
908    #[inline(always)]
909    fn flex_shrink(&self) -> f32 {
910        (*self).flex_shrink()
911    }
912    #[inline(always)]
913    fn align_self(&self) -> Option<AlignSelf> {
914        (*self).align_self()
915    }
916}
917
918#[cfg(feature = "grid")]
919impl<S: CheapCloneStr> GridContainerStyle for Style<S> {
920    type Repetition<'a>
921        = &'a GridTemplateRepetition<S>
922    where
923        Self: 'a;
924
925    type TemplateTrackList<'a>
926        = core::iter::Map<
927        core::slice::Iter<'a, GridTemplateComponent<S>>,
928        fn(&'a GridTemplateComponent<S>) -> GenericGridTemplateComponent<S, &'a GridTemplateRepetition<S>>,
929    >
930    where
931        Self: 'a;
932
933    type AutoTrackList<'a>
934        = core::iter::Copied<core::slice::Iter<'a, TrackSizingFunction>>
935    where
936        Self: 'a;
937
938    #[cfg(feature = "grid")]
939    type TemplateLineNames<'a>
940        = core::iter::Map<core::slice::Iter<'a, GridTrackVec<S>>, fn(&GridTrackVec<S>) -> core::slice::Iter<'_, S>>
941    where
942        Self: 'a;
943    #[cfg(feature = "grid")]
944    type GridTemplateAreas<'a>
945        = core::iter::Cloned<core::slice::Iter<'a, GridTemplateArea<S>>>
946    where
947        Self: 'a;
948
949    #[inline(always)]
950    fn grid_template_rows(&self) -> Option<Self::TemplateTrackList<'_>> {
951        Some(self.grid_template_rows.iter().map(|c| c.as_component_ref()))
952    }
953    #[inline(always)]
954    fn grid_template_columns(&self) -> Option<Self::TemplateTrackList<'_>> {
955        Some(self.grid_template_columns.iter().map(|c| c.as_component_ref()))
956    }
957    #[inline(always)]
958    fn grid_auto_rows(&self) -> Self::AutoTrackList<'_> {
959        self.grid_auto_rows.iter().copied()
960    }
961    #[inline(always)]
962    fn grid_auto_columns(&self) -> Self::AutoTrackList<'_> {
963        self.grid_auto_columns.iter().copied()
964    }
965    #[inline(always)]
966    fn grid_auto_flow(&self) -> GridAutoFlow {
967        self.grid_auto_flow
968    }
969    #[inline(always)]
970    fn gap(&self) -> Size<LengthPercentage> {
971        self.gap
972    }
973    #[inline(always)]
974    fn align_content(&self) -> Option<AlignContent> {
975        self.align_content
976    }
977    #[inline(always)]
978    fn justify_content(&self) -> Option<JustifyContent> {
979        self.justify_content
980    }
981    #[inline(always)]
982    fn align_items(&self) -> Option<AlignItems> {
983        self.align_items
984    }
985    #[inline(always)]
986    fn justify_items(&self) -> Option<AlignItems> {
987        self.justify_items
988    }
989
990    #[inline(always)]
991    #[cfg(feature = "grid")]
992    fn grid_template_areas(&self) -> Option<Self::GridTemplateAreas<'_>> {
993        Some(self.grid_template_areas.iter().cloned())
994    }
995
996    #[inline(always)]
997    #[cfg(feature = "grid")]
998    fn grid_template_column_names(&self) -> Option<Self::TemplateLineNames<'_>> {
999        Some(self.grid_template_column_names.iter().map(|names| names.iter()))
1000    }
1001
1002    #[inline(always)]
1003    #[cfg(feature = "grid")]
1004    fn grid_template_row_names(&self) -> Option<Self::TemplateLineNames<'_>> {
1005        Some(self.grid_template_row_names.iter().map(|names| names.iter()))
1006    }
1007}
1008
1009#[cfg(feature = "grid")]
1010impl<T: GridContainerStyle> GridContainerStyle for &'_ T {
1011    type Repetition<'a>
1012        = T::Repetition<'a>
1013    where
1014        Self: 'a;
1015
1016    type TemplateTrackList<'a>
1017        = T::TemplateTrackList<'a>
1018    where
1019        Self: 'a;
1020
1021    type AutoTrackList<'a>
1022        = T::AutoTrackList<'a>
1023    where
1024        Self: 'a;
1025
1026    /// The type returned by grid_template_row_names and grid_template_column_names
1027    #[cfg(feature = "grid")]
1028    type TemplateLineNames<'a>
1029        = T::TemplateLineNames<'a>
1030    where
1031        Self: 'a;
1032    #[cfg(feature = "grid")]
1033    type GridTemplateAreas<'a>
1034        = T::GridTemplateAreas<'a>
1035    where
1036        Self: 'a;
1037
1038    #[inline(always)]
1039    fn grid_template_rows(&self) -> Option<Self::TemplateTrackList<'_>> {
1040        (*self).grid_template_rows()
1041    }
1042    #[inline(always)]
1043    fn grid_template_columns(&self) -> Option<Self::TemplateTrackList<'_>> {
1044        (*self).grid_template_columns()
1045    }
1046    #[inline(always)]
1047    fn grid_auto_rows(&self) -> Self::AutoTrackList<'_> {
1048        (*self).grid_auto_rows()
1049    }
1050    #[inline(always)]
1051    fn grid_auto_columns(&self) -> Self::AutoTrackList<'_> {
1052        (*self).grid_auto_columns()
1053    }
1054    #[cfg(feature = "grid")]
1055    #[inline(always)]
1056    fn grid_template_areas(&self) -> Option<Self::GridTemplateAreas<'_>> {
1057        (*self).grid_template_areas()
1058    }
1059    #[cfg(feature = "grid")]
1060    #[inline(always)]
1061    fn grid_template_column_names(&self) -> Option<Self::TemplateLineNames<'_>> {
1062        (*self).grid_template_column_names()
1063    }
1064    #[cfg(feature = "grid")]
1065    #[inline(always)]
1066    fn grid_template_row_names(&self) -> Option<Self::TemplateLineNames<'_>> {
1067        (*self).grid_template_row_names()
1068    }
1069    #[inline(always)]
1070    fn grid_auto_flow(&self) -> GridAutoFlow {
1071        (*self).grid_auto_flow()
1072    }
1073    #[inline(always)]
1074    fn gap(&self) -> Size<LengthPercentage> {
1075        (*self).gap()
1076    }
1077    #[inline(always)]
1078    fn align_content(&self) -> Option<AlignContent> {
1079        (*self).align_content()
1080    }
1081    #[inline(always)]
1082    fn justify_content(&self) -> Option<JustifyContent> {
1083        (*self).justify_content()
1084    }
1085    #[inline(always)]
1086    fn align_items(&self) -> Option<AlignItems> {
1087        (*self).align_items()
1088    }
1089    #[inline(always)]
1090    fn justify_items(&self) -> Option<AlignItems> {
1091        (*self).justify_items()
1092    }
1093}
1094
1095#[cfg(feature = "grid")]
1096impl<S: CheapCloneStr> GridItemStyle for Style<S> {
1097    #[inline(always)]
1098    fn grid_row(&self) -> Line<GridPlacement<S>> {
1099        // TODO: Investigate eliminating clone
1100        self.grid_row.clone()
1101    }
1102    #[inline(always)]
1103    fn grid_column(&self) -> Line<GridPlacement<S>> {
1104        // TODO: Investigate eliminating clone
1105        self.grid_column.clone()
1106    }
1107    #[inline(always)]
1108    fn align_self(&self) -> Option<AlignSelf> {
1109        self.align_self
1110    }
1111    #[inline(always)]
1112    fn justify_self(&self) -> Option<AlignSelf> {
1113        self.justify_self
1114    }
1115}
1116
1117#[cfg(feature = "grid")]
1118impl<T: GridItemStyle> GridItemStyle for &'_ T {
1119    #[inline(always)]
1120    fn grid_row(&self) -> Line<GridPlacement<Self::CustomIdent>> {
1121        (*self).grid_row()
1122    }
1123    #[inline(always)]
1124    fn grid_column(&self) -> Line<GridPlacement<Self::CustomIdent>> {
1125        (*self).grid_column()
1126    }
1127    #[inline(always)]
1128    fn align_self(&self) -> Option<AlignSelf> {
1129        (*self).align_self()
1130    }
1131    #[inline(always)]
1132    fn justify_self(&self) -> Option<AlignSelf> {
1133        (*self).justify_self()
1134    }
1135}
1136
1137#[cfg(test)]
1138mod tests {
1139    use std::sync::Arc;
1140
1141    use super::Style;
1142    use crate::sys::DefaultCheapStr;
1143    use crate::{geometry::*, style_helpers::TaffyAuto as _};
1144
1145    #[test]
1146    fn defaults_match() {
1147        #[cfg(feature = "grid")]
1148        use super::GridPlacement;
1149
1150        let old_defaults: Style<DefaultCheapStr> = Style {
1151            dummy: core::marker::PhantomData,
1152            display: Default::default(),
1153            item_is_table: false,
1154            item_is_replaced: false,
1155            box_sizing: Default::default(),
1156            #[cfg(feature = "float_layout")]
1157            float: Default::default(),
1158            #[cfg(feature = "float_layout")]
1159            clear: Default::default(),
1160            overflow: Default::default(),
1161            scrollbar_width: 0.0,
1162            position: Default::default(),
1163            #[cfg(feature = "flexbox")]
1164            flex_direction: Default::default(),
1165            #[cfg(feature = "flexbox")]
1166            flex_wrap: Default::default(),
1167            #[cfg(any(feature = "flexbox", feature = "grid"))]
1168            align_items: Default::default(),
1169            #[cfg(any(feature = "flexbox", feature = "grid"))]
1170            align_self: Default::default(),
1171            #[cfg(feature = "grid")]
1172            justify_items: Default::default(),
1173            #[cfg(feature = "grid")]
1174            justify_self: Default::default(),
1175            #[cfg(any(feature = "flexbox", feature = "grid"))]
1176            align_content: Default::default(),
1177            #[cfg(any(feature = "flexbox", feature = "grid"))]
1178            justify_content: Default::default(),
1179            inset: Rect::auto(),
1180            margin: Rect::zero(),
1181            padding: Rect::zero(),
1182            border: Rect::zero(),
1183            gap: Size::zero(),
1184            #[cfg(feature = "block_layout")]
1185            text_align: Default::default(),
1186            #[cfg(feature = "flexbox")]
1187            flex_grow: 0.0,
1188            #[cfg(feature = "flexbox")]
1189            flex_shrink: 1.0,
1190            #[cfg(feature = "flexbox")]
1191            flex_basis: super::Dimension::AUTO,
1192            size: Size::auto(),
1193            min_size: Size::auto(),
1194            max_size: Size::auto(),
1195            aspect_ratio: Default::default(),
1196            #[cfg(feature = "grid")]
1197            grid_template_rows: Default::default(),
1198            #[cfg(feature = "grid")]
1199            grid_template_columns: Default::default(),
1200            #[cfg(feature = "grid")]
1201            grid_template_row_names: Default::default(),
1202            #[cfg(feature = "grid")]
1203            grid_template_column_names: Default::default(),
1204            #[cfg(feature = "grid")]
1205            grid_template_areas: Default::default(),
1206            #[cfg(feature = "grid")]
1207            grid_auto_rows: Default::default(),
1208            #[cfg(feature = "grid")]
1209            grid_auto_columns: Default::default(),
1210            #[cfg(feature = "grid")]
1211            grid_auto_flow: Default::default(),
1212            #[cfg(feature = "grid")]
1213            grid_row: Line { start: GridPlacement::Auto, end: GridPlacement::Auto },
1214            #[cfg(feature = "grid")]
1215            grid_column: Line { start: GridPlacement::Auto, end: GridPlacement::Auto },
1216        };
1217
1218        assert_eq!(Style::DEFAULT, Style::<DefaultCheapStr>::default());
1219        assert_eq!(Style::DEFAULT, old_defaults);
1220    }
1221
1222    // NOTE: Please feel free the update the sizes in this test as required. This test is here to prevent unintentional size changes
1223    // and to serve as accurate up-to-date documentation on the sizes.
1224    #[test]
1225    fn style_sizes() {
1226        use super::*;
1227        type S = crate::sys::DefaultCheapStr;
1228
1229        fn assert_type_size<T>(expected_size: usize) {
1230            let name = ::core::any::type_name::<T>();
1231            let name = name.replace("taffy::geometry::", "");
1232            let name = name.replace("taffy::style::dimension::", "");
1233            let name = name.replace("taffy::style::alignment::", "");
1234            let name = name.replace("taffy::style::flex::", "");
1235            let name = name.replace("taffy::style::grid::", "");
1236
1237            assert_eq!(
1238                ::core::mem::size_of::<T>(),
1239                expected_size,
1240                "Expected {} for be {} byte(s) but it was {} byte(s)",
1241                name,
1242                expected_size,
1243                ::core::mem::size_of::<T>(),
1244            );
1245        }
1246
1247        // Display and Position
1248        assert_type_size::<Display>(1);
1249        assert_type_size::<BoxSizing>(1);
1250        assert_type_size::<Position>(1);
1251        assert_type_size::<Overflow>(1);
1252
1253        // Dimensions and aggregations of Dimensions
1254        assert_type_size::<f32>(4);
1255        assert_type_size::<LengthPercentage>(8);
1256        assert_type_size::<LengthPercentageAuto>(8);
1257        assert_type_size::<Dimension>(8);
1258        assert_type_size::<Size<LengthPercentage>>(16);
1259        assert_type_size::<Size<LengthPercentageAuto>>(16);
1260        assert_type_size::<Size<Dimension>>(16);
1261        assert_type_size::<Rect<LengthPercentage>>(32);
1262        assert_type_size::<Rect<LengthPercentageAuto>>(32);
1263        assert_type_size::<Rect<Dimension>>(32);
1264
1265        // Alignment
1266        assert_type_size::<AlignContent>(1);
1267        assert_type_size::<AlignItems>(1);
1268        assert_type_size::<Option<AlignItems>>(1);
1269
1270        // Flexbox Container
1271        assert_type_size::<FlexDirection>(1);
1272        assert_type_size::<FlexWrap>(1);
1273
1274        // CSS Grid Container
1275        assert_type_size::<GridAutoFlow>(1);
1276        assert_type_size::<MinTrackSizingFunction>(8);
1277        assert_type_size::<MaxTrackSizingFunction>(8);
1278        assert_type_size::<TrackSizingFunction>(16);
1279        assert_type_size::<Vec<TrackSizingFunction>>(24);
1280        assert_type_size::<Vec<GridTemplateComponent<S>>>(24);
1281
1282        // String-type dependent (String)
1283        assert_type_size::<GridTemplateComponent<String>>(56);
1284        assert_type_size::<GridPlacement<String>>(32);
1285        assert_type_size::<Line<GridPlacement<String>>>(64);
1286        assert_type_size::<Style<String>>(536);
1287
1288        // String-type dependent (Arc<str>)
1289        assert_type_size::<GridTemplateComponent<Arc<str>>>(56);
1290        assert_type_size::<GridPlacement<Arc<str>>>(24);
1291        assert_type_size::<Line<GridPlacement<Arc<str>>>>(48);
1292        assert_type_size::<Style<Arc<str>>>(504);
1293    }
1294}