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