use gpui::{Div, FontWeight, InteractiveElement, ParentElement, SharedString, Styled, div, px};
use gpui_kit_theme::{Elevation, Radius, Space, Surface, TextTone, Theme, TypeScale};
pub fn text(theme: &Theme, scale: TypeScale, content: impl Into<SharedString>) -> Div {
div()
.type_scale(theme, scale)
.text_tone(theme, TextTone::Primary)
.child(content.into())
}
pub trait StyledExt: Styled + Sized {
fn surface(self, theme: &Theme, surface: Surface) -> Self {
self.bg(theme.surface(surface))
}
fn text_tone(self, theme: &Theme, tone: TextTone) -> Self {
self.text_color(theme.text_color(tone))
}
fn type_scale(self, theme: &Theme, scale: TypeScale) -> Self {
let style = theme.type_style(scale);
self.text_size(px(style.size))
.line_height(px(style.line_height))
.font_weight(FontWeight(style.weight))
}
fn radius(self, theme: &Theme, radius: Radius) -> Self {
self.rounded(px(theme.radius(radius)))
}
fn gap_token(self, theme: &Theme, space: Space) -> Self {
self.gap(px(theme.space(space)))
}
fn p_token(self, theme: &Theme, space: Space) -> Self {
self.p(px(theme.space(space)))
}
fn px_token(self, theme: &Theme, space: Space) -> Self {
self.px(px(theme.space(space)))
}
fn py_token(self, theme: &Theme, space: Space) -> Self {
self.py(px(theme.space(space)))
}
fn mt_token(self, theme: &Theme, space: Space) -> Self {
self.mt(px(theme.space(space)))
}
fn elevation(self, theme: &Theme, level: Elevation) -> Self {
let shadow = theme.shadow(level);
if shadow.is_empty() {
self
} else {
self.shadow(shadow.to_vec())
}
}
fn hairline(self, theme: &Theme) -> Self {
self.border(px(theme.borders.hairline))
.border_color(theme.colors.hairline)
}
fn hairline_strong(self, theme: &Theme) -> Self {
self.border(px(theme.borders.hairline))
.border_color(theme.colors.hairline_strong)
}
fn frame(self, theme: &Theme, surface: Surface, level: Elevation) -> Self {
self.surface(theme, surface).elevation(theme, level)
}
fn well(self, theme: &Theme) -> Self {
self.surface(theme, Surface::Sunken)
.border(px(theme.borders.hairline))
.border_color(gpui::transparent_black())
}
fn glow(self, theme: &Theme, color: gpui::Hsla) -> Self {
self.shadow(theme.glow(color))
}
fn row(self) -> Self {
self.flex().flex_row().items_center()
}
fn column(self) -> Self {
self.flex().flex_col()
}
}
impl<T: Styled + Sized> StyledExt for T {}
pub trait FocusRing: InteractiveElement + Sized {
fn focus_ring(self, theme: &Theme) -> Self {
self.focus(|style| {
style
.border_color(theme.colors.focus)
.shadow(theme.focus_ring())
})
}
}
impl<T: InteractiveElement + Sized> FocusRing for T {}