mirror of
https://github.com/adoyle0/thaw.git
synced 2025-01-22 22:09:22 -05:00
feat: text
This commit is contained in:
parent
372941b01d
commit
eeff259208
10 changed files with 171 additions and 88 deletions
|
@ -4,9 +4,9 @@
|
|||
view! {
|
||||
<Card>
|
||||
<CardHeader>
|
||||
"Header"
|
||||
<Body1>"Header"</Body1>
|
||||
<CardHeaderDescription slot>
|
||||
"Description"
|
||||
<Caption1>"Description"</Caption1>
|
||||
</CardHeaderDescription>
|
||||
<CardHeaderAction slot>
|
||||
<Button appearance=ButtonAppearance::Transparent>
|
||||
|
|
|
@ -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::*;
|
||||
|
|
|
@ -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
30
thaw/src/text/text.css
Normal 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);
|
||||
}
|
|
@ -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(),
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
mod text;
|
||||
mod theme;
|
||||
|
||||
pub use text::*;
|
||||
pub use theme::TypographyTheme;
|
|
@ -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;
|
||||
}
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue