mirror of
https://github.com/adoyle0/thaw.git
synced 2025-02-02 08:34:15 -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! {
|
view! {
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
"Header"
|
<Body1>"Header"</Body1>
|
||||||
<CardHeaderDescription slot>
|
<CardHeaderDescription slot>
|
||||||
"Description"
|
<Caption1>"Description"</Caption1>
|
||||||
</CardHeaderDescription>
|
</CardHeaderDescription>
|
||||||
<CardHeaderAction slot>
|
<CardHeaderAction slot>
|
||||||
<Button appearance=ButtonAppearance::Transparent>
|
<Button appearance=ButtonAppearance::Transparent>
|
||||||
|
|
|
@ -44,7 +44,6 @@ mod tag;
|
||||||
mod text;
|
mod text;
|
||||||
mod theme;
|
mod theme;
|
||||||
mod time_picker;
|
mod time_picker;
|
||||||
mod typography;
|
|
||||||
mod upload;
|
mod upload;
|
||||||
|
|
||||||
pub use alert::*;
|
pub use alert::*;
|
||||||
|
@ -89,8 +88,8 @@ pub use switch::*;
|
||||||
pub use table::*;
|
pub use table::*;
|
||||||
pub use tabs::*;
|
pub use tabs::*;
|
||||||
pub use tag::*;
|
pub use tag::*;
|
||||||
|
pub use text::*;
|
||||||
pub use thaw_utils::{create_component_ref, ComponentRef, SignalWatch};
|
pub use thaw_utils::{create_component_ref, ComponentRef, SignalWatch};
|
||||||
pub use theme::*;
|
pub use theme::*;
|
||||||
pub use time_picker::*;
|
pub use time_picker::*;
|
||||||
pub use typography::*;
|
|
||||||
pub use upload::*;
|
pub use upload::*;
|
||||||
|
|
|
@ -1,6 +1,89 @@
|
||||||
use leptos::*;
|
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 self::common::CommonTheme;
|
||||||
use crate::{
|
use crate::{
|
||||||
mobile::{NavBarTheme, TabbarTheme},
|
mobile::{NavBarTheme, TabbarTheme},
|
||||||
AlertTheme, AnchorTheme, AutoCompleteTheme, BackTopTheme, BreadcrumbTheme,
|
AlertTheme, AnchorTheme, AutoCompleteTheme, BackTopTheme, BreadcrumbTheme, CalendarTheme,
|
||||||
CalendarTheme, CollapseTheme, ColorPickerTheme, DatePickerTheme, InputTheme, MenuTheme,
|
CollapseTheme, ColorPickerTheme, DatePickerTheme, InputTheme, MenuTheme, MessageTheme,
|
||||||
MessageTheme, PopoverTheme, ProgressTheme, ScrollbarTheme, SelectTheme, SkeletionTheme,
|
PopoverTheme, ProgressTheme, ScrollbarTheme, SelectTheme, SkeletionTheme, SliderTheme,
|
||||||
SliderTheme, SpinnerTheme, SwitchTheme, TableTheme, TagTheme, TimePickerTheme, TypographyTheme,
|
SpinnerTheme, SwitchTheme, TableTheme, TagTheme, TimePickerTheme, UploadTheme,
|
||||||
UploadTheme,
|
|
||||||
};
|
};
|
||||||
pub use color::ColorTheme;
|
pub use color::ColorTheme;
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
|
@ -41,7 +40,6 @@ pub struct Theme {
|
||||||
pub color_picker: ColorPickerTheme,
|
pub color_picker: ColorPickerTheme,
|
||||||
pub breadcrumb: BreadcrumbTheme,
|
pub breadcrumb: BreadcrumbTheme,
|
||||||
pub progress: ProgressTheme,
|
pub progress: ProgressTheme,
|
||||||
pub typograph: TypographyTheme,
|
|
||||||
pub calendar: CalendarTheme,
|
pub calendar: CalendarTheme,
|
||||||
pub time_picker: TimePickerTheme,
|
pub time_picker: TimePickerTheme,
|
||||||
pub date_picker: DatePickerTheme,
|
pub date_picker: DatePickerTheme,
|
||||||
|
@ -76,7 +74,6 @@ impl Theme {
|
||||||
color_picker: ColorPickerTheme::light(),
|
color_picker: ColorPickerTheme::light(),
|
||||||
breadcrumb: BreadcrumbTheme::light(),
|
breadcrumb: BreadcrumbTheme::light(),
|
||||||
progress: ProgressTheme::light(),
|
progress: ProgressTheme::light(),
|
||||||
typograph: TypographyTheme::light(),
|
|
||||||
calendar: CalendarTheme::light(),
|
calendar: CalendarTheme::light(),
|
||||||
time_picker: TimePickerTheme::light(),
|
time_picker: TimePickerTheme::light(),
|
||||||
date_picker: DatePickerTheme::light(),
|
date_picker: DatePickerTheme::light(),
|
||||||
|
@ -110,7 +107,6 @@ impl Theme {
|
||||||
color_picker: ColorPickerTheme::dark(),
|
color_picker: ColorPickerTheme::dark(),
|
||||||
breadcrumb: BreadcrumbTheme::dark(),
|
breadcrumb: BreadcrumbTheme::dark(),
|
||||||
progress: ProgressTheme::dark(),
|
progress: ProgressTheme::dark(),
|
||||||
typograph: TypographyTheme::dark(),
|
|
||||||
calendar: CalendarTheme::dark(),
|
calendar: CalendarTheme::dark(),
|
||||||
time_picker: TimePickerTheme::dark(),
|
time_picker: TimePickerTheme::dark(),
|
||||||
date_picker: DatePickerTheme::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"))]
|
#[cfg(not(feature = "ssr"))]
|
||||||
use leptos::create_render_effect;
|
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};
|
use std::{collections::HashSet, rc::Rc};
|
||||||
|
|
||||||
pub struct ClassList(RwSignal<HashSet<Oco<'static, str>>>);
|
pub struct ClassList(RwSignal<HashSet<Oco<'static, str>>>);
|
||||||
|
@ -45,6 +47,44 @@ impl ClassList {
|
||||||
name
|
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) => {
|
Class::Fn(name, f) => {
|
||||||
#[cfg(feature = "ssr")]
|
#[cfg(feature = "ssr")]
|
||||||
{
|
{
|
||||||
|
@ -111,6 +151,7 @@ pub enum Class {
|
||||||
None,
|
None,
|
||||||
String(Oco<'static, str>),
|
String(Oco<'static, str>),
|
||||||
FnString(Box<dyn Fn() -> 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>),
|
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)
|
impl<T> IntoClass for (String, T)
|
||||||
where
|
where
|
||||||
T: Fn() -> bool + 'static,
|
T: Fn() -> bool + 'static,
|
||||||
|
|
Loading…
Add table
Reference in a new issue