use teksilo_core::build_context::BuildContext;
use teksilo_core::color_prop::ColorProp;
use teksilo_core::styles::{BannerStyle, BannerStyleConfig};
use teksilo_core::widget_id::WidgetId;
use teksilo_tokens::{CornerRadius, VAlignment};
use crate::primitives::{Expand, HStack, Padding, RectWidget, ZStack};
pub const BANNER_PADDING_HORIZONTAL: f32 = 12.0;
pub const BANNER_PADDING_VERTICAL: f32 = 10.0;
pub const BANNER_CORNER_RADIUS: f32 = 8.0;
pub const BANNER_GLYPH_SIZE: f32 = 16.0;
pub const BANNER_CONTENT_GAP: f32 = 10.0;
pub const BANNER_TITLE_DESCRIPTION_GAP: f32 = 2.0;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct BannerRecipe {
pub padding_horizontal: f32,
pub padding_vertical: f32,
pub corner_radius: f32,
pub glyph_size: f32,
pub content_gap: f32,
pub title_description_gap: f32,
}
impl Default for BannerRecipe {
fn default() -> Self {
Self {
padding_horizontal: BANNER_PADDING_HORIZONTAL,
padding_vertical: BANNER_PADDING_VERTICAL,
corner_radius: BANNER_CORNER_RADIUS,
glyph_size: BANNER_GLYPH_SIZE,
content_gap: BANNER_CONTENT_GAP,
title_description_gap: BANNER_TITLE_DESCRIPTION_GAP,
}
}
}
#[derive(Debug, Default, Clone, Copy)]
pub struct RecipeBannerStyle {
pub recipe: BannerRecipe,
}
impl RecipeBannerStyle {
pub fn new(recipe: BannerRecipe) -> Self {
Self { recipe }
}
}
impl BannerStyle for RecipeBannerStyle {
fn make_body(&self, cfg: &BannerStyleConfig, ctx: &mut BuildContext) -> WidgetId {
let radius = CornerRadius::uniform(self.recipe.corner_radius);
let bg = ctx.add(
RectWidget::new()
.background(ColorProp::SurfaceRole(cfg.severity.surface()))
.corner_radius(radius),
);
let content = ctx.add(Expand::horizontal().child_id(cfg.content));
let row = ctx.add(
HStack::new()
.spacing(self.recipe.content_gap)
.alignment(VAlignment::Center)
.add_child(cfg.leading_glyph)
.add_child(content),
);
let padded = ctx.add(
Padding::symmetric(self.recipe.padding_vertical, self.recipe.padding_horizontal)
.child_id(row),
);
ctx.add(ZStack::new().add_child(bg).add_child(padded))
}
}