///|
/// CSS display property
pub(all) enum Display {
Block
Inline
InlineBlock
Flex
InlineFlex
Grid
InlineGrid
// Table display types
Table
InlineTable
TableRow
TableCell
TableCaption
TableRowGroup // tbody
TableHeaderGroup // thead
TableFooterGroup // tfoot
TableColumn // col (not rendered)
TableColumnGroup // colgroup (not rendered)
None
// Special display type - element doesn't generate a box
// but its children are treated as if they were children of the parent
Contents
// Flow-root creates a new block formatting context
// Similar to Block but establishes BFC (contains floats, prevents margin collapse)
FlowRoot
} derive(Show, Eq)
///|
/// CSS position property
pub(all) enum Position {
Static // Default - no offset applied
Relative
Absolute
Fixed
} derive(Show, Eq)
///|
/// Flex direction
pub(all) enum FlexDirection {
Row
RowReverse
Column
ColumnReverse
} derive(Show, Eq)
///|
/// Alignment for justify-content, align-items, etc.
/// Note: Start/End are physical/logical directions (not affected by flex-wrap direction)
/// FlexStart/FlexEnd are flex-relative (affected by wrap-reverse)
pub(all) enum Alignment {
Start
End
FlexStart
FlexEnd
Center
SpaceBetween
SpaceAround
SpaceEvenly
Stretch
Baseline // Align items by their baselines (bottom of box for simple elements)
} derive(Show, Eq)
///|
/// Flex wrap mode
pub(all) enum FlexWrap {
NoWrap
Wrap
WrapReverse
} derive(Show, Eq)
///|
/// Align-self value (can override align-items for individual items)
pub(all) enum AlignSelf {
Auto // Inherit from parent's align-items
Start
End
Center
Stretch
Baseline // Align item by its baseline
} derive(Show, Eq)
///|
/// CSS float property
pub(all) enum Float {
None
Left
Right
} derive(Show, Eq)
///|
/// CSS clear property
pub(all) enum Clear {
None
Left
Right
Both
} derive(Show, Eq)
///|
/// CSS border-collapse property (for tables)
pub(all) enum BorderCollapse {
Separate // Default - borders have spacing
Collapse // Adjacent borders merge
} derive(Show, Eq)
///|
/// Table layout algorithm
pub(all) enum TableLayout {
Auto // Default - column widths based on content
Fixed // Column widths based on first row only
} derive(Show, Eq)
///|
/// CSS caption-side property (for table captions)
pub(all) enum CaptionSide {
Top // Caption above the table (default)
Bottom // Caption below the table
} derive(Show, Eq)
///|
/// CSS overflow property
pub(all) enum Overflow {
Visible // Content is not clipped (default)
Hidden // Content is clipped, no scrollbars
Scroll // Content is clipped with scrollbars
Auto // Scrollbars if needed
} derive(Show, Eq)
///|
/// CSS box-sizing property
pub(all) enum BoxSizing {
ContentBox // width/height = content only (default)
BorderBox // width/height = content + padding + border
} derive(Show, Eq)
///|
/// CSS visibility property
pub(all) enum Visibility {
Visible // Element is visible (default)
Hidden // Element is invisible but takes up space
Collapse // Same as hidden for most elements
} derive(Show, Eq)
///|
/// CSS z-index property
pub(all) enum ZIndex {
Auto // Stacking order determined by DOM order
Value(Int) // Explicit stacking level
} derive(Show, Eq)
///|
/// CSS transform translate value (can be length or percent)
pub(all) enum TranslateValue {
Length(Double) // Fixed length in pixels
Percent(Double) // Percentage of element's own dimension (0.0 - 1.0)
} derive(Show, Eq)
///|
/// CSS transform property - list of transform functions
/// Currently supports translate only for layout purposes
pub(all) struct Transform {
translate_x : TranslateValue // translateX or first arg of translate()
translate_y : TranslateValue // translateY or second arg of translate()
} derive(Show, Eq)
///|
/// Create a none/identity transform
pub fn Transform::none() -> Transform {
{
translate_x: TranslateValue::Length(0.0),
translate_y: TranslateValue::Length(0.0),
}
}
///|
/// Check if transform is identity (no visual change)
pub fn Transform::is_none(self : Transform) -> Bool {
match (self.translate_x, self.translate_y) {
(TranslateValue::Length(0.0), TranslateValue::Length(0.0)) => true
(TranslateValue::Percent(0.0), TranslateValue::Percent(0.0)) => true
_ => false
}
}
///|
/// Compute translate X offset given element width
pub fn Transform::compute_translate_x(
self : Transform,
element_width : Double,
) -> Double {
match self.translate_x {
TranslateValue::Length(v) => v
TranslateValue::Percent(p) => element_width * p
}
}
///|
/// Compute translate Y offset given element height
pub fn Transform::compute_translate_y(
self : Transform,
element_height : Double,
) -> Double {
match self.translate_y {
TranslateValue::Length(v) => v
TranslateValue::Percent(p) => element_height * p
}
}
///|
/// CSS contain property - uses flags since multiple values can be combined
/// e.g., "contain: layout paint" or "contain: strict"
pub(all) struct Contain {
size : Bool // Size containment - element size computed independently
inline_size : Bool // Inline-size containment only (mutually exclusive with size)
layout : Bool // Layout containment - isolates internal layout
paint : Bool // Paint containment - clips overflow, creates stacking context
style : Bool // Style containment - scopes counters/quotes
} derive(Show, Eq)
///|
pub fn Contain::none() -> Contain {
{ size: false, inline_size: false, layout: false, paint: false, style: false }
}
///|
/// strict = size + layout + paint + style
pub fn Contain::strict() -> Contain {
{ size: true, inline_size: false, layout: true, paint: true, style: true }
}
///|
/// content = layout + paint + style (no size)
pub fn Contain::content() -> Contain {
{ size: false, inline_size: false, layout: true, paint: true, style: true }
}
///|
pub fn Contain::has_containment(self : Contain) -> Bool {
self.size || self.inline_size || self.layout || self.paint || self.style
}
///|
/// Grid auto-flow direction
pub(all) enum GridAutoFlow {
Row // Fill rows first (default)
Column // Fill columns first
RowDense // Fill rows first with dense packing
ColumnDense // Fill columns first with dense packing
} derive(Show, Eq)
///|
/// Grid line placement for grid items
pub(all) enum GridPlacement {
Auto // Auto placement
Line(Int) // Place at specific line (1-indexed, negative counts from end)
Span(Int) // Span specified number of tracks
} derive(Show, Eq)
///|
/// Single track sizing function (non-repeating)
pub(all) enum SingleTrackSizing {
Length(Double) // Fixed length (px)
Percent(Double) // Percentage (0.0 - 1.0)
Fr(Double) // Flexible fraction (fr unit)
Auto // Auto sizing
MinContent // Min-content sizing
MaxContent // Max-content sizing
MinMax(MinTrackSizing, MaxTrackSizing) // minmax(min, max)
FitContentLength(Double) // fit-content(length)
FitContentPercent(Double) // fit-content(percent)
} derive(Show, Eq)
///|
/// Repeat count for repeat() function
pub(all) enum RepeatCount {
Count(Int) // Fixed number of repetitions
AutoFill // Fill with as many tracks as fit
AutoFit // Like AutoFill but collapse empty tracks
} derive(Show, Eq)
///|
/// Track sizing function for grid-template-rows/columns
pub(all) enum TrackSizingFunction {
Length(Double) // Fixed length (px)
Percent(Double) // Percentage (0.0 - 1.0)
Fr(Double) // Flexible fraction (fr unit)
Auto // Auto sizing
MinContent // Min-content sizing
MaxContent // Max-content sizing
MinMax(MinTrackSizing, MaxTrackSizing) // minmax(min, max)
Repeat(RepeatCount, Array[SingleTrackSizing]) // repeat(count, tracks)
FitContentLength(Double) // fit-content(length)
FitContentPercent(Double) // fit-content(percent)
} derive(Show, Eq)
///|
/// Minimum track sizing function for minmax()
pub(all) enum MinTrackSizing {
Length(Double)
Percent(Double)
Auto
MinContent
MaxContent
} derive(Show, Eq)
///|
/// Maximum track sizing function for minmax()
pub(all) enum MaxTrackSizing {
Length(Double)
Percent(Double)
Fr(Double)
Auto
MinContent
MaxContent
} derive(Show, Eq)
///|
/// Grid line range (start and end)
pub(all) struct GridLine {
start : GridPlacement
end : GridPlacement
} derive(Show, Eq)
///|
pub fn GridLine::auto() -> GridLine {
{ start: Auto, end: Auto }
}
///|
/// Vertical alignment for inline elements
pub(all) enum VerticalAlign {
Baseline // Align baseline (default, simplified to bottom for now)
Top // Align to top of line box
Middle // Align middle
Bottom // Align to bottom of line box
TextTop // Align to top of parent's font (simplified to Top)
TextBottom // Align to bottom of parent's font (simplified to Bottom)
Sub // Subscript position
Super // Superscript position
} derive(Show, Eq)
///|
/// CSS Style definition for layout computation
/// All fields are mutable to support Yoga-like setter API
pub(all) struct Style {
mut display : Display
mut position : Position
mut float : Float
mut clear : Clear
// Box sizing
mut box_sizing : BoxSizing
// Overflow
mut overflow_x : Overflow
mut overflow_y : Overflow
// Sizing
mut width : @types.Dimension
mut height : @types.Dimension
mut min_width : @types.Dimension
mut min_height : @types.Dimension
mut max_width : @types.Dimension
mut max_height : @types.Dimension
// Box model
mut margin : @types.Rect[@types.Dimension]
mut padding : @types.Rect[@types.Dimension]
mut border : @types.Rect[@types.Dimension]
// Flexbox
mut flex_direction : FlexDirection
mut flex_wrap : FlexWrap
mut justify_content : Alignment
mut align_items : Alignment
mut align_content : Alignment
mut align_self : AlignSelf
mut flex_grow : Double
mut flex_shrink : Double
mut flex_basis : @types.Dimension
mut order : Int // Flex item order (default 0)
// Gap
mut row_gap : @types.Dimension
mut column_gap : @types.Dimension
// Aspect ratio (width / height)
mut aspect_ratio : Double?
// Inset for position: absolute (left, right, top, bottom)
mut inset : @types.Rect[@types.Dimension]
// Grid container properties
mut grid_template_rows : Array[TrackSizingFunction]
mut grid_template_columns : Array[TrackSizingFunction]
mut grid_auto_rows : Array[TrackSizingFunction]
mut grid_auto_columns : Array[TrackSizingFunction]
mut grid_auto_flow : GridAutoFlow
// Grid template areas (each string is a row, e.g. ["header header", "sidebar main"])
mut grid_template_areas : Array[String]
// Grid item properties
mut grid_row : GridLine
mut grid_column : GridLine
mut grid_area : String? // Named area for item placement
// justify-items for grid (different from justify-content)
mut justify_items : Alignment
// justify-self for grid items (horizontal self-alignment)
mut justify_self : AlignSelf
// Font properties (for baseline calculation)
mut font_size : Double // Computed font size in pixels (default 16.0)
mut line_height : Double // Computed line height in pixels (default = font_size)
// Vertical alignment for inline elements
mut vertical_align : VerticalAlign
// Clip (legacy, deprecated but widely used for a11y)
mut clip : @types.ClipRect
// Paint properties (visual, not layout)
mut visibility : Visibility
mut z_index : ZIndex
mut opacity : Double // 0.0 = transparent, 1.0 = opaque
// Color properties (resolved RGBA values)
mut color : @types.Color // Text color (inherited)
mut background_color : @types.Color // Background color (not inherited)
// Containment (for layout optimization)
mut contain : Contain
// CSS transform (visual offset, applied in paint phase)
mut transform : Transform
// Table properties
mut border_spacing : Double // border-spacing in pixels (horizontal and vertical, simplified)
mut border_collapse : BorderCollapse // border-collapse: separate | collapse
mut table_layout : TableLayout // table-layout: auto | fixed
mut caption_side : CaptionSide // caption-side: top | bottom
// Table cell properties (from HTML attributes)
mut rowspan : Int // rowspan attribute (default 1)
mut colspan : Int // colspan attribute (default 1)
}
///|
pub fn Style::default() -> Style {
{
display: Block,
position: Static,
float: None,
clear: None,
box_sizing: ContentBox,
overflow_x: Visible,
overflow_y: Visible,
width: @types.Auto,
height: @types.Auto,
min_width: @types.Auto,
min_height: @types.Auto,
max_width: @types.Auto,
max_height: @types.Auto,
margin: {
left: @types.Length(0.0),
right: @types.Length(0.0),
top: @types.Length(0.0),
bottom: @types.Length(0.0),
},
padding: {
left: @types.Length(0.0),
right: @types.Length(0.0),
top: @types.Length(0.0),
bottom: @types.Length(0.0),
},
border: {
left: @types.Length(0.0),
right: @types.Length(0.0),
top: @types.Length(0.0),
bottom: @types.Length(0.0),
},
flex_direction: Row,
flex_wrap: NoWrap,
justify_content: Start,
align_items: Stretch,
align_content: Stretch,
align_self: Auto,
flex_grow: 0.0,
flex_shrink: 1.0,
flex_basis: @types.Auto,
order: 0,
row_gap: @types.Length(0.0),
column_gap: @types.Length(0.0),
aspect_ratio: None,
inset: {
left: @types.Auto,
right: @types.Auto,
top: @types.Auto,
bottom: @types.Auto,
},
grid_template_rows: [],
grid_template_columns: [],
grid_auto_rows: [],
grid_auto_columns: [],
grid_auto_flow: Row,
grid_template_areas: [],
grid_row: GridLine::auto(),
grid_column: GridLine::auto(),
grid_area: None,
justify_items: Stretch,
justify_self: Auto,
font_size: 16.0,
line_height: 16.0,
vertical_align: Baseline,
clip: @types.ClipRect::Auto,
visibility: Visible,
z_index: Auto,
opacity: 1.0,
color: @types.Color::black(),
background_color: @types.Color::transparent(),
contain: Contain::none(),
transform: Transform::none(),
border_spacing: 0.0,
border_collapse: Separate,
table_layout: Auto,
caption_side: Top,
rowspan: 1,
colspan: 1,
}
}