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