feat: text

This commit is contained in:
luoxiao 2024-05-14 17:39:13 +08:00
parent 372941b01d
commit eeff259208
10 changed files with 171 additions and 88 deletions

View file

@ -4,9 +4,9 @@
view! {
<Card>
<CardHeader>
"Header"
<Body1>"Header"</Body1>
<CardHeaderDescription slot>
"Description"
<Caption1>"Description"</Caption1>
</CardHeaderDescription>
<CardHeaderAction slot>
<Button appearance=ButtonAppearance::Transparent>

View file

@ -44,7 +44,6 @@ mod tag;
mod text;
mod theme;
mod time_picker;
mod typography;
mod upload;
pub use alert::*;
@ -89,8 +88,8 @@ pub use switch::*;
pub use table::*;
pub use tabs::*;
pub use tag::*;
pub use text::*;
pub use thaw_utils::{create_component_ref, ComponentRef, SignalWatch};
pub use theme::*;
pub use time_picker::*;
pub use typography::*;
pub use upload::*;

View file

@ -1,6 +1,89 @@
use leptos::*;
use thaw_utils::{class_list, mount_style};
#[component]
pub fn Caption1(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional)] tag: TextTag,
children: Children,
) -> impl IntoView {
let class = Signal::derive(move || format!("thaw-caption-1 {:?}", class.get()));
pub fn Caption1Strong() {
view! {
<Text tag children class/>
}
}
#[component]
pub fn Caption1Strong(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional)] tag: TextTag,
children: Children,
) -> impl IntoView {
let class = Signal::derive(move || format!("thaw-caption-1-strong {:?}", class.get()));
view! {
<Text tag children class/>
}
}
#[component]
pub fn Body1(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional)] tag: TextTag,
children: Children,
) -> impl IntoView {
let class = Signal::derive(move || format!("thaw-body-1 {:?}", class.get()));
view! {
<Text tag children class/>
}
}
#[component]
pub fn Text(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional)] tag: TextTag,
#[prop(optional)] code: bool,
children: Children,
) -> impl IntoView {
mount_style("text", include_str!("./text.css"));
match tag {
TextTag::B => todo!(),
TextTag::Em => todo!(),
TextTag::H1 => todo!(),
TextTag::H2 => todo!(),
TextTag::H3 => todo!(),
TextTag::H4 => todo!(),
TextTag::H5 => todo!(),
TextTag::H6 => todo!(),
TextTag::I => todo!(),
TextTag::P => todo!(),
TextTag::Pre => todo!(),
TextTag::Span => view! {
<span class=class_list!["thaw-text", class]>
{children()}
</span>
},
TextTag::Strong => todo!(),
}
}
#[derive(Default)]
pub enum TextTag {
B,
Em,
H1,
H2,
H3,
H4,
H5,
H6,
I,
P,
Pre,
#[default]
Span,
Strong,
}

30
thaw/src/text/text.css Normal file
View file

@ -0,0 +1,30 @@
.thaw-text {
text-overflow: clip;
overflow-y: visible;
overflow-x: visible;
white-space: normal;
text-align: start;
display: inline;
line-height: var(--lineHeightBase300);
font-weight: var(--fontWeightRegular);
font-size: var(--fontSizeBase300);
font-family: var(--fontFamilyBase);
}
.thaw-caption-1 {
line-height: var(--lineHeightBase200);
font-weight: var(--fontWeightRegular);
font-size: var(--fontSizeBase200);
}
.thaw-caption-1-strong {
line-height: var(--lineHeightBase200);
font-weight: var(--fontWeightSemibold);
font-size: var(--fontSizeBase200);
}
.thaw-body-1 {
line-height: var(--lineHeightBase300);
font-weight: var(--fontWeightRegular);
font-size: var(--fontSizeBase300);
}

View file

@ -4,11 +4,10 @@ mod common;
use self::common::CommonTheme;
use crate::{
mobile::{NavBarTheme, TabbarTheme},
AlertTheme, AnchorTheme, AutoCompleteTheme, BackTopTheme, BreadcrumbTheme,
CalendarTheme, CollapseTheme, ColorPickerTheme, DatePickerTheme, InputTheme, MenuTheme,
MessageTheme, PopoverTheme, ProgressTheme, ScrollbarTheme, SelectTheme, SkeletionTheme,
SliderTheme, SpinnerTheme, SwitchTheme, TableTheme, TagTheme, TimePickerTheme, TypographyTheme,
UploadTheme,
AlertTheme, AnchorTheme, AutoCompleteTheme, BackTopTheme, BreadcrumbTheme, CalendarTheme,
CollapseTheme, ColorPickerTheme, DatePickerTheme, InputTheme, MenuTheme, MessageTheme,
PopoverTheme, ProgressTheme, ScrollbarTheme, SelectTheme, SkeletionTheme, SliderTheme,
SpinnerTheme, SwitchTheme, TableTheme, TagTheme, TimePickerTheme, UploadTheme,
};
pub use color::ColorTheme;
use leptos::*;
@ -41,7 +40,6 @@ pub struct Theme {
pub color_picker: ColorPickerTheme,
pub breadcrumb: BreadcrumbTheme,
pub progress: ProgressTheme,
pub typograph: TypographyTheme,
pub calendar: CalendarTheme,
pub time_picker: TimePickerTheme,
pub date_picker: DatePickerTheme,
@ -76,7 +74,6 @@ impl Theme {
color_picker: ColorPickerTheme::light(),
breadcrumb: BreadcrumbTheme::light(),
progress: ProgressTheme::light(),
typograph: TypographyTheme::light(),
calendar: CalendarTheme::light(),
time_picker: TimePickerTheme::light(),
date_picker: DatePickerTheme::light(),
@ -110,7 +107,6 @@ impl Theme {
color_picker: ColorPickerTheme::dark(),
breadcrumb: BreadcrumbTheme::dark(),
progress: ProgressTheme::dark(),
typograph: TypographyTheme::dark(),
calendar: CalendarTheme::dark(),
time_picker: TimePickerTheme::dark(),
date_picker: DatePickerTheme::dark(),

View file

@ -1,5 +0,0 @@
mod text;
mod theme;
pub use text::*;
pub use theme::TypographyTheme;

View file

@ -1,9 +0,0 @@
.thaw-text--code {
padding: 0.2em 0.35em;
font-size: 0.93em;
line-height: 1.4;
background-color: var(--thaw-background-color);
border: 1px solid #0000;
border-radius: 2px;
box-sizing: border-box;
}

View file

@ -1,38 +0,0 @@
use crate::{use_theme, Theme};
use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalProp};
#[component]
pub fn Text(
#[prop(optional)] code: bool,
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>,
children: Children,
) -> impl IntoView {
mount_style("text", include_str!("./text.css"));
let theme = use_theme(Theme::light);
let css_vars = create_memo(move |_| {
let mut css_vars = String::new();
theme.with(|theme| {
css_vars.push_str(&format!(
"--thaw-background-color: {}",
theme.typograph.code_background_color
));
});
css_vars
});
if code {
view! {
<code
class=class_list!["thaw-text thaw-text--code", class.map(| c | move || c.get())]
style=move || css_vars.get()
>
{children()}
</code>
}
.into_any()
} else {
view! { <span class=class_list!["thaw-text", class.map(| c | move || c.get())]>{children()}</span> }
.into_any()
}
}

View file

@ -1,20 +0,0 @@
use crate::theme::ThemeMethod;
#[derive(Clone)]
pub struct TypographyTheme {
pub code_background_color: String,
}
impl ThemeMethod for TypographyTheme {
fn light() -> Self {
Self {
code_background_color: "#f4f4f8".into(),
}
}
fn dark() -> Self {
Self {
code_background_color: "#ffffff1f".into(),
}
}
}

View file

@ -1,6 +1,8 @@
#[cfg(not(feature = "ssr"))]
use leptos::create_render_effect;
use leptos::{Attribute, IntoAttribute, Memo, Oco, RwSignal, SignalGet, SignalUpdate, SignalWith};
use leptos::{
Attribute, IntoAttribute, MaybeProp, Memo, Oco, RwSignal, SignalGet, SignalUpdate, SignalWith,
};
use std::{collections::HashSet, rc::Rc};
pub struct ClassList(RwSignal<HashSet<Oco<'static, str>>>);
@ -45,6 +47,44 @@ impl ClassList {
name
});
}
Class::FnOptionString(f) => {
#[cfg(feature = "ssr")]
{
if let Some(name) = f() {
self.0.update(|set| {
set.insert(name);
});
}
}
#[cfg(not(feature = "ssr"))]
create_render_effect(move |old_name| {
let name = f();
if let Some(old_name) = old_name {
if old_name != name {
self.0.update(|set| match (old_name, name.clone()) {
(None, Some(name)) => {
set.insert(name);
}
(Some(old_name), None) => {
set.remove(&old_name);
}
(Some(old_name), Some(name)) => {
set.remove(&old_name);
set.insert(name);
}
_ => {}
});
}
} else {
if let Some(name) = name.clone() {
self.0.update(|set| {
set.insert(name.clone());
});
}
}
name
});
}
Class::Fn(name, f) => {
#[cfg(feature = "ssr")]
{
@ -111,6 +151,7 @@ pub enum Class {
None,
String(Oco<'static, str>),
FnString(Box<dyn Fn() -> Oco<'static, str>>),
FnOptionString(Box<dyn Fn() -> Option<Oco<'static, str>>>),
Fn(Oco<'static, str>, Box<dyn Fn() -> bool>),
}
@ -179,6 +220,12 @@ impl IntoClass for (&'static str, Memo<bool>) {
}
}
impl IntoClass for MaybeProp<String> {
fn into_class(self) -> Class {
Class::FnOptionString(Box::new(move || self.get().map(|c| Oco::from(c))))
}
}
impl<T> IntoClass for (String, T)
where
T: Fn() -> bool + 'static,