aura-gui 0.3.5

UI nativa acelerada por GPU para escritorio, Android e iOS, en un solo crate: estilo tipo Tailwind, componentes, sombras, animaciones y agentes de IA. Reposo a cero. Licencia AGPL-3.0 o comercial.
//! Traducción de [`Style`] a estilos de Taffy.

use crate::core::Pixels;
use crate::view::layout_extra;
use crate::view::style::{Align, Direction, Justify, Length, Overflow, Style};
use taffy::prelude::*;

fn dimension(length: Option<Length>) -> Dimension {
    match length {
        Some(Length::Px(value)) => Dimension::length(value.0),
        Some(Length::Percent(fraction)) => Dimension::percent(fraction),
        Some(Length::Auto) | None => Dimension::auto(),
    }
}

fn limit(length: Option<Length>) -> LengthPercentageAuto {
    match length {
        Some(Length::Px(value)) => LengthPercentageAuto::length(value.0),
        Some(Length::Percent(fraction)) => LengthPercentageAuto::percent(fraction),
        Some(Length::Auto) | None => LengthPercentageAuto::auto(),
    }
}

fn padding(value: Option<Pixels>) -> LengthPercentage {
    LengthPercentage::length(value.unwrap_or_default().0)
}

fn margin(value: Option<Pixels>) -> LengthPercentageAuto {
    LengthPercentageAuto::length(value.unwrap_or_default().0)
}

fn inset(value: Option<Pixels>) -> LengthPercentageAuto {
    match value {
        Some(pixels) => LengthPercentageAuto::length(pixels.0),
        None => LengthPercentageAuto::auto(),
    }
}

fn align(value: Align) -> AlignItems {
    match value {
        Align::Baseline => AlignItems::BASELINE,
        Align::Start => AlignItems::FLEX_START,
        Align::Center => AlignItems::CENTER,
        Align::End => AlignItems::FLEX_END,
        Align::Stretch => AlignItems::STRETCH,
    }
}

pub(crate) fn justify(value: Justify) -> JustifyContent {
    match value {
        Justify::Start => JustifyContent::FLEX_START,
        Justify::Center => JustifyContent::CENTER,
        Justify::End => JustifyContent::FLEX_END,
        Justify::SpaceBetween => JustifyContent::SPACE_BETWEEN,
        Justify::SpaceAround => JustifyContent::SPACE_AROUND,
        Justify::SpaceEvenly => JustifyContent::SPACE_EVENLY,
    }
}

fn overflow(value: Option<Overflow>) -> taffy::Overflow {
    match value {
        Some(Overflow::Hidden) => taffy::Overflow::Hidden,
        Some(Overflow::Scroll) => taffy::Overflow::Scroll,
        Some(Overflow::Visible) | None => taffy::Overflow::Visible,
    }
}

pub fn to_taffy(style: &Style) -> taffy::Style {
    let mut out = base(style);
    layout_extra::apply(style, &mut out);
    out
}

fn base(style: &Style) -> taffy::Style {
    taffy::Style {
        display: if style.hidden == Some(true) { Display::None } else { Display::Flex },
        position: if style.absolute == Some(true) { Position::Absolute } else { Position::Relative },
        flex_direction: match style.direction {
            Some(Direction::Column) => FlexDirection::Column,
            _ => FlexDirection::Row,
        },
        flex_wrap: if style.wrap == Some(true) { FlexWrap::Wrap } else { FlexWrap::NoWrap },
        align_items: style.align_items.map(align).unwrap_or_default(),
        align_self: style.align_self.map(align),
        justify_content: style.justify_content.map(justify).unwrap_or_default(),
        flex_grow: style.flex_grow.unwrap_or(0.0),
        flex_shrink: style.flex_shrink.unwrap_or(1.0),
        flex_basis: dimension(style.flex_basis),
        size: taffy::Size { width: dimension(style.width), height: dimension(style.height) },
        min_size: taffy::Size { width: limit(style.min_width), height: limit(style.min_height) },
        max_size: taffy::Size { width: limit(style.max_width), height: limit(style.max_height) },
        aspect_ratio: style.aspect_ratio,
        padding: taffy::Rect {
            left: padding(style.padding.left),
            right: padding(style.padding.right),
            top: padding(style.padding.top),
            bottom: padding(style.padding.bottom),
        },
        margin: taffy::Rect {
            left: margin(style.margin.left),
            right: margin(style.margin.right),
            top: margin(style.margin.top),
            bottom: margin(style.margin.bottom),
        },
        inset: taffy::Rect {
            left: inset(style.inset.left),
            right: inset(style.inset.right),
            top: inset(style.inset.top),
            bottom: inset(style.inset.bottom),
        },
        gap: taffy::Size { width: padding(style.gap_x), height: padding(style.gap_y) },
        overflow: taffy::Point { x: overflow(style.overflow_x), y: overflow(style.overflow_y) },
        scrollbar_width: 0.0,
        ..Default::default()
    }
}