use crate::{prelude::*, *};
use std::sync::Arc;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum TitleLevel {
H1,
#[default]
H2,
H3,
H4,
H5,
}
impl TitleLevel {
fn size(&self) -> Pixels {
match self {
TitleLevel::H1 => px(24.0),
TitleLevel::H2 => px(20.0),
TitleLevel::H3 => px(16.0),
TitleLevel::H4 => px(14.0),
TitleLevel::H5 => px(12.0),
}
}
}
#[derive(IntoElement)]
pub struct Title {
level: TitleLevel,
text: SharedString,
}
impl Title {
pub fn new(text: impl Into<SharedString>) -> Self {
Self {
level: TitleLevel::H2,
text: text.into(),
}
}
pub fn level(mut self, level: TitleLevel) -> Self {
self.level = level;
self
}
}
impl RenderOnce for Title {
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
div()
.text_size(self.level.size())
.text_color(cx.theme().tokens.foreground.color)
.child(self.text)
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum TextVariant {
#[default]
Body,
Secondary,
Danger,
Warning,
}
#[derive(IntoElement)]
pub struct Paragraph {
variant: TextVariant,
text: SharedString,
}
impl Paragraph {
pub fn new(text: impl Into<SharedString>) -> Self {
Self {
variant: TextVariant::Body,
text: text.into(),
}
}
pub fn variant(mut self, variant: TextVariant) -> Self {
self.variant = variant;
self
}
}
impl RenderOnce for Paragraph {
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
let tokens = &cx.theme().tokens;
let color = match self.variant {
TextVariant::Body => tokens.foreground.color,
TextVariant::Secondary => tokens.muted_foreground.color,
TextVariant::Danger => red(),
TextVariant::Warning => yellow(),
};
div().text_sm().text_color(color).child(self.text)
}
}
#[derive(IntoElement)]
pub struct Link {
id: SharedString,
text: SharedString,
on_click: Option<Arc<dyn Fn(&ClickEvent, &mut Window, &mut App) + Send + Sync + 'static>>,
}
impl Link {
#[track_caller]
pub fn new(text: impl Into<SharedString>) -> Self {
Self {
id: crate::caller_element_id("link"),
text: text.into(),
on_click: None,
}
}
pub fn id(mut self, id: impl Into<SharedString>) -> Self {
self.id = id.into();
self
}
pub fn on_click<F>(mut self, f: F) -> Self
where
F: Fn(&ClickEvent, &mut Window, &mut App) + Send + Sync + 'static,
{
self.on_click = Some(Arc::new(f));
self
}
}
impl RenderOnce for Link {
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
let accent = cx.theme().tokens.accent.color;
div()
.id(self.id.clone())
.text_sm()
.text_color(accent)
.text_decoration_1()
.cursor_pointer()
.child(self.text)
.when_some(self.on_click, |this, cb| {
this.on_click(move |event, window, cx| cb(event, window, cx))
})
}
}