Feat/class param continued (#55)

* Add class param to components

* Add class param to all components

* Add class param to all components

* fix: Failed to run the SSR mode

* style: cargo fmt and leptosfmt

---------

Co-authored-by: Cristobal Andrada <kandrelczyk@gmail.com>
Co-authored-by: luoxiao <luoxiaozero@163.com>
This commit is contained in:
kandrelczyk 2023-12-20 06:44:30 +01:00 committed by GitHub
parent 1f074d4222
commit 46af07746c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
54 changed files with 539 additions and 57 deletions

View file

@ -107,6 +107,12 @@ pub fn BadgePage() -> impl IntoView {
<td></td> <td></td>
<td>"Badge's content."</td> <td>"Badge's content."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the badge element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
</div> </div>

View file

@ -86,6 +86,12 @@ pub fn BreadcrumbPage() -> impl IntoView {
<td></td> <td></td>
<td>"Breadcrumb's content."</td> <td>"Breadcrumb's content."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the breadcrumb element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
<h3>"BreadcrumbItem Props"</h3> <h3>"BreadcrumbItem Props"</h3>
@ -105,6 +111,12 @@ pub fn BreadcrumbPage() -> impl IntoView {
<td></td> <td></td>
<td>"BreadcrumbItem's content."</td> <td>"BreadcrumbItem's content."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the breadcrumb link element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
</div> </div>

View file

@ -50,6 +50,12 @@ pub fn CalendarPage() -> impl IntoView {
</td> </td>
<td></td> <td></td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the calendar element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
</div> </div>

View file

@ -84,6 +84,12 @@ pub fn CardPage() -> impl IntoView {
<td></td> <td></td>
<td>"Card's content."</td> <td>"Card's content."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the card element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
<h3>"Card Slots"</h3> <h3>"Card Slots"</h3>

View file

@ -106,6 +106,12 @@ pub fn CheckboxPage() -> impl IntoView {
<td></td> <td></td>
<td>"CheckboxGroup's content."</td> <td>"CheckboxGroup's content."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the checkbox element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
<h3>"CheckboxItem Props"</h3> <h3>"CheckboxItem Props"</h3>

View file

@ -44,6 +44,12 @@ pub fn ColorPickerPage() -> impl IntoView {
<td>"RwSignal<RGBA>"</td> <td>"RwSignal<RGBA>"</td>
<td>"Value of the picker."</td> <td>"Value of the picker."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the color picker element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
</div> </div>

View file

@ -23,6 +23,25 @@ pub fn DividerPage() -> impl IntoView {
</DemoCode> </DemoCode>
</Demo> </Demo>
<h3>"Divider Props"</h3>
<Table single_column=true>
<thead>
<tr>
<th>"Name"</th>
<th>"Type"</th>
<th>"Default"</th>
<th>"Description"</th>
</tr>
</thead>
<tbody>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the divider element."</td>
</tr>
</tbody>
</Table>
</div> </div>
} }
} }

View file

@ -142,6 +142,43 @@ pub fn GridPage() -> impl IntoView {
<td>"0"</td> <td>"0"</td>
<td>"Vertical gap."</td> <td>"Vertical gap."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the grid element."</td>
</tr>
</tbody>
</Table>
<h3>"GridItem Props"</h3>
<Table single_column=true>
<thead>
<tr>
<th>"Name"</th>
<th>"Type"</th>
<th>"Default"</th>
<th>"Description"</th>
</tr>
</thead>
<tbody>
<tr>
<td>"column"</td>
<td>"MaybeSignal<u16>"</td>
<td>"1"</td>
<td>"Number of columns this grid item will occupy."</td>
</tr>
<tr>
<td>"offset"</td>
<td>"MaybeSignal<u16>"</td>
<td>"0"</td>
<td>"Horizontal offset."</td>
</tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the grid item element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
</div> </div>

View file

@ -70,6 +70,12 @@ pub fn ImagePage() -> impl IntoView {
<td>"Default::default()"</td> <td>"Default::default()"</td>
<td>"Object-fit type of the image in the container."</td> <td>"Object-fit type of the image in the container."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the image element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
</div> </div>

View file

@ -213,6 +213,12 @@ pub fn InputPage() -> impl IntoView {
<td>"None"</td> <td>"None"</td>
<td>"Callback triggered when the input is blurred."</td> <td>"Callback triggered when the input is blurred."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the input element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
<h3>"Input Slots"</h3> <h3>"Input Slots"</h3>

View file

@ -108,6 +108,12 @@ pub fn InputNumberPage() -> impl IntoView {
<td>"false"</td> <td>"false"</td>
<td>"Whether the input is invalid."</td> <td>"Whether the input is invalid."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the input element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
<h3>"T impl"</h3> <h3>"T impl"</h3>

View file

@ -15,9 +15,7 @@ pub fn MenuPage() -> impl IntoView {
<MenuItem key="o" label="or"/> <MenuItem key="o" label="or"/>
</Menu> </Menu>
<DemoCode slot> <DemoCode slot>
{highlight_str!( r#"
{highlight_str!(
r#"
let value = create_rw_signal(String::from("o")); let value = create_rw_signal(String::from("o"));
<Menu value> <Menu value>
@ -53,6 +51,12 @@ pub fn MenuPage() -> impl IntoView {
<td></td> <td></td>
<td>"Menu's content."</td> <td>"Menu's content."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the menu element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
<h3>"MenuGroup Props"</h3> <h3>"MenuGroup Props"</h3>
@ -78,6 +82,12 @@ pub fn MenuPage() -> impl IntoView {
<td></td> <td></td>
<td>"MenuGroup's content."</td> <td>"MenuGroup's content."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the menu group element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
<h3>"MenuItem Props"</h3> <h3>"MenuItem Props"</h3>
@ -103,6 +113,12 @@ pub fn MenuPage() -> impl IntoView {
<td>"Default::default()"</td> <td>"Default::default()"</td>
<td>"The indentifier of the menu item."</td> <td>"The indentifier of the menu item."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the menu item element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
</div> </div>

View file

@ -89,6 +89,12 @@ pub fn NavBarPage() -> impl IntoView {
<td>"Default::default()"</td> <td>"Default::default()"</td>
<td>"NavBar right click."</td> <td>"NavBar right click."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the NavBar element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
</div> </div>

View file

@ -51,6 +51,12 @@ pub fn RadioPage() -> impl IntoView {
<td></td> <td></td>
<td>"Radio's content."</td> <td>"Radio's content."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the radio element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
</div> </div>

View file

@ -56,6 +56,12 @@ pub fn SelectPage() -> impl IntoView {
<td>"vec![]"</td> <td>"vec![]"</td>
<td>"Options that can be selected."</td> <td>"Options that can be selected."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the select element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
</div> </div>

View file

@ -114,6 +114,12 @@ pub fn SliderPage() -> impl IntoView {
<td></td> <td></td>
<td>"Slider labels."</td> <td>"Slider labels."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the slider element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
<h3>"SliderLabel Props"</h3> <h3>"SliderLabel Props"</h3>

View file

@ -112,6 +112,12 @@ pub fn SpacePage() -> impl IntoView {
<td></td> <td></td>
<td>"Space's content."</td> <td>"Space's content."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the space element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
</div> </div>

View file

@ -42,6 +42,12 @@ pub fn SwitchPage() -> impl IntoView {
<td>"false"</td> <td>"false"</td>
<td>"Swith's value."</td> <td>"Swith's value."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the switch element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
</div> </div>

View file

@ -96,6 +96,12 @@ pub fn TablePage() -> impl IntoView {
<td></td> <td></td>
<td>"Table's content."</td> <td>"Table's content."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the table element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
</div> </div>

View file

@ -69,6 +69,12 @@ pub fn TabsPage() -> impl IntoView {
<td></td> <td></td>
<td>"Tabs content."</td> <td>"Tabs content."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the tabs element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
<h3>"Tab Props"</h3> <h3>"Tab Props"</h3>
@ -106,6 +112,12 @@ pub fn TabsPage() -> impl IntoView {
<td></td> <td></td>
<td>"Tab's content."</td> <td>"Tab's content."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the tab element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
</div> </div>

View file

@ -62,6 +62,12 @@ pub fn TagPage() -> impl IntoView {
<td></td> <td></td>
<td>"Tag's content."</td> <td>"Tag's content."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the tag element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
</div> </div>

View file

@ -47,6 +47,12 @@ pub fn TimePickerPage() -> impl IntoView {
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the time picker element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
</div> </div>

View file

@ -60,6 +60,12 @@ pub fn TypographyPage() -> impl IntoView {
<td></td> <td></td>
<td>"Text's content."</td> <td>"Text's content."</td>
</tr> </tr>
<tr>
<td>"class"</td>
<td>"MaybeSignal<String>"</td>
<td>"Default::default()"</td>
<td>"Addtional classes for the text element."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
</div> </div>

View file

@ -6,6 +6,7 @@
position: absolute; position: absolute;
color: var(--thaw-font-color); color: var(--thaw-font-color);
background-color: var(--thaw-background-color); background-color: var(--thaw-background-color);
z-index: 10;
} }
.thaw-badge__sup--value { .thaw-badge__sup--value {
top: -9px; top: -9px;

View file

@ -1,4 +1,11 @@
use crate::{theme::use_theme, utils::mount_style, Theme}; #[cfg(not(feature = "ssr"))]
use crate::utils::dyn_classes;
use crate::{
theme::use_theme,
utils::{mount_style, ssr_class},
Theme,
};
use leptos::*; use leptos::*;
#[derive(Default, Clone)] #[derive(Default, Clone)]
@ -25,6 +32,7 @@ pub fn Badge(
#[prop(default = MaybeSignal::Static(u32::MAX), into)] max: MaybeSignal<u32>, #[prop(default = MaybeSignal::Static(u32::MAX), into)] max: MaybeSignal<u32>,
#[prop(optional, into)] variant: MaybeSignal<BadgeVariant>, #[prop(optional, into)] variant: MaybeSignal<BadgeVariant>,
#[prop(optional, into)] dot: MaybeSignal<bool>, #[prop(optional, into)] dot: MaybeSignal<bool>,
#[prop(optional, into)] class: MaybeSignal<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
let theme = use_theme(Theme::light); let theme = use_theme(Theme::light);
@ -51,9 +59,12 @@ pub fn Badge(
value.to_string() value.to_string()
} }
}); });
let ssr_class = ssr_class(&class);
view! { view! {
<div class="thaw-badge" style=move || css_vars.get()> <div class="thaw-badge" style=move || css_vars.get()>
<div <div
class=ssr_class
use:dyn_classes=class
class="thaw-badge__sup" class="thaw-badge__sup"
class=("thaw-badge__sup--value", move || !dot.get() && !value.get().is_empty()) class=("thaw-badge__sup--value", move || !dot.get() && !value.get().is_empty())
class=("thaw-badge__sup--dot", move || dot.get()) class=("thaw-badge__sup--dot", move || dot.get())

View file

@ -1,12 +1,22 @@
use super::use_breadcrumb_separator; use super::use_breadcrumb_separator;
use leptos::*; use leptos::*;
#[cfg(not(feature = "ssr"))]
use crate::utils::dyn_classes;
use crate::utils::ssr_class;
#[component] #[component]
pub fn BreadcrumbItem(children: Children) -> impl IntoView { pub fn BreadcrumbItem(
#[prop(optional, into)] class: MaybeSignal<String>,
children: Children,
) -> impl IntoView {
let breadcrumb_separator = use_breadcrumb_separator(); let breadcrumb_separator = use_breadcrumb_separator();
let ssr_class = ssr_class(&class);
view! { view! {
<li class="thaw-breadcrumb-item"> <li class="thaw-breadcrumb-item">
<span class="thaw-breadcrumb-item__link">{children()}</span> <span class=ssr_class use:dyn_classes=class class="thaw-breadcrumb-item__link">
{children()}
</span>
<span class="thaw-breadcrumb-item__separator"> <span class="thaw-breadcrumb-item__separator">
{move || breadcrumb_separator.0.get()} {move || breadcrumb_separator.0.get()}
</span> </span>

View file

@ -1,7 +1,12 @@
mod breadcrumb_item; mod breadcrumb_item;
mod theme; mod theme;
use crate::{use_theme, utils::mount_style, Theme}; use crate::utils::dyn_classes;
use crate::{
use_theme,
utils::{mount_style, ssr_class},
Theme,
};
pub use breadcrumb_item::BreadcrumbItem; pub use breadcrumb_item::BreadcrumbItem;
use leptos::*; use leptos::*;
pub use theme::BreadcrumbTheme; pub use theme::BreadcrumbTheme;
@ -9,6 +14,7 @@ pub use theme::BreadcrumbTheme;
#[component] #[component]
pub fn Breadcrumb( pub fn Breadcrumb(
#[prop(default = MaybeSignal::Static("/".to_string()),into)] separator: MaybeSignal<String>, #[prop(default = MaybeSignal::Static("/".to_string()),into)] separator: MaybeSignal<String>,
#[prop(optional, into)] class: MaybeSignal<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
mount_style("breadcrumb", include_str!("./breadcrumb.css")); mount_style("breadcrumb", include_str!("./breadcrumb.css"));
@ -31,9 +37,15 @@ pub fn Breadcrumb(
}); });
css_vars css_vars
}); });
let ssr_class = ssr_class(&class);
view! { view! {
<Provider value=BreadcrumbSeparatorInjection(separator)> <Provider value=BreadcrumbSeparatorInjection(separator)>
<nav class="thaw-breadcrumb" style=move || css_vars.get()> <nav
class=ssr_class
use:dyn_classes=class
class="thaw-breadcrumb"
style=move || css_vars.get()
>
<ul>{children()}</ul> <ul>{children()}</ul>
</nav> </nav>
</Provider> </Provider>

View file

@ -1,9 +1,11 @@
mod theme; mod theme;
#[cfg(not(feature = "ssr"))]
use crate::utils::dyn_classes;
use crate::{ use crate::{
chrono::{Datelike, Days, Local, NaiveDate}, chrono::{Datelike, Days, Local, NaiveDate},
use_theme, use_theme,
utils::mount_style, utils::{mount_style, ssr_class},
Button, ButtonGroup, ButtonVariant, Theme, Button, ButtonGroup, ButtonVariant, Theme,
}; };
use chrono::{Month, Months}; use chrono::{Month, Months};
@ -13,7 +15,10 @@ use std::ops::Deref;
pub use theme::CalendarTheme; pub use theme::CalendarTheme;
#[component] #[component]
pub fn Calendar(#[prop(optional, into)] value: RwSignal<Option<NaiveDate>>) -> impl IntoView { pub fn Calendar(
#[prop(optional, into)] class: MaybeSignal<String>,
#[prop(optional, into)] value: RwSignal<Option<NaiveDate>>,
) -> impl IntoView {
mount_style("calendar", include_str!("./calendar.css")); mount_style("calendar", include_str!("./calendar.css"));
let theme = use_theme(Theme::light); let theme = use_theme(Theme::light);
let css_vars = create_memo(move |_| { let css_vars = create_memo(move |_| {
@ -112,8 +117,14 @@ pub fn Calendar(#[prop(optional, into)] value: RwSignal<Option<NaiveDate>>) -> i
*date = *date + Months::new(1); *date = *date + Months::new(1);
}); });
}; };
let ssr_class = ssr_class(&class);
view! { view! {
<div class="thaw-calendar" style=move || css_vars.get()> <div
class=ssr_class
use:dyn_classes=class
class="thaw-calendar"
style=move || css_vars.get()
>
<div class="thaw-calendar__header"> <div class="thaw-calendar__header">
<span class="thaw-calendar__header-title"> <span class="thaw-calendar__header-title">

View file

@ -4,6 +4,7 @@
border: 1px solid var(--thaw-border-color); border: 1px solid var(--thaw-border-color);
border-radius: 3px; border-radius: 3px;
overflow: hidden; overflow: hidden;
background-color: var(--thaw-background-color); /* moving here so that applying padding to card element works correctly */
} }
.thaw-card__header { .thaw-card__header {
font-weight: 600; font-weight: 600;
@ -21,7 +22,6 @@
.thaw-card__content, .thaw-card__content,
.thaw-card__footer { .thaw-card__footer {
padding: 12px 28px; padding: 12px 28px;
background-color: var(--thaw-background-color);
} }
.thaw-card__header { .thaw-card__header {
padding: 20px 28px; padding: 20px 28px;

View file

@ -1,4 +1,11 @@
use crate::{components::*, use_theme, utils::mount_style, Theme}; #[cfg(not(feature = "ssr"))]
use crate::utils::dyn_classes;
use crate::{
components::*,
use_theme,
utils::{mount_style, ssr_class},
Theme,
};
use leptos::*; use leptos::*;
#[derive(Clone)] #[derive(Clone)]
@ -25,6 +32,7 @@ pub fn Card(
#[prop(optional, into)] title: MaybeSignal<String>, #[prop(optional, into)] title: MaybeSignal<String>,
#[prop(optional)] card_header: Option<CardHeader>, #[prop(optional)] card_header: Option<CardHeader>,
#[prop(optional)] card_header_extra: Option<CardHeaderExtra>, #[prop(optional)] card_header_extra: Option<CardHeaderExtra>,
#[prop(optional, into)] class: MaybeSignal<String>,
children: Children, children: Children,
#[prop(optional)] card_footer: Option<CardFooter>, #[prop(optional)] card_footer: Option<CardFooter>,
) -> impl IntoView { ) -> impl IntoView {
@ -51,8 +59,9 @@ pub fn Card(
let header = store_value(card_header); let header = store_value(card_header);
let header_extra = store_value(card_header_extra); let header_extra = store_value(card_header_extra);
let ssr_class = ssr_class(&class);
view! { view! {
<div class="thaw-card" style=move || css_vars.get()> <div class=ssr_class use:dyn_classes=class class="thaw-card" style=move || css_vars.get()>
<If cond=is_header> <If cond=is_header>
<Then slot> <Then slot>
<div class="thaw-card__header"> <div class="thaw-card__header">

View file

@ -7,6 +7,7 @@ use leptos::*;
#[component] #[component]
pub fn CheckboxItem( pub fn CheckboxItem(
#[prop(optional, into)] label: Option<String>, #[prop(optional, into)] label: Option<String>,
#[prop(optional, into)] class: MaybeSignal<String>,
#[prop(into)] key: String, #[prop(into)] key: String,
) -> impl IntoView { ) -> impl IntoView {
let checkbox_group = use_checkbox_group(); let checkbox_group = use_checkbox_group();
@ -32,5 +33,9 @@ pub fn CheckboxItem(
item_key.get_value() item_key.get_value()
}; };
view! { <Checkbox value=checked>{label}</Checkbox> } view! {
<Checkbox class value=checked>
{label}
</Checkbox>
}
} }

View file

@ -1,7 +1,15 @@
mod checkbox_group; mod checkbox_group;
mod checkbox_item; mod checkbox_item;
use crate::{components::*, icon::*, theme::use_theme, utils::mount_style, Theme}; #[cfg(not(feature = "ssr"))]
use crate::utils::dyn_classes;
use crate::{
components::*,
icon::*,
theme::use_theme,
utils::{mount_style, ssr_class},
Theme,
};
pub use checkbox_group::CheckboxGroup; pub use checkbox_group::CheckboxGroup;
pub use checkbox_item::CheckboxItem; pub use checkbox_item::CheckboxItem;
use icondata::AiIcon; use icondata::AiIcon;
@ -10,6 +18,7 @@ use leptos::*;
#[component] #[component]
pub fn Checkbox( pub fn Checkbox(
#[prop(optional, into)] value: RwSignal<bool>, #[prop(optional, into)] value: RwSignal<bool>,
#[prop(optional, into)] class: MaybeSignal<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
let theme = use_theme(Theme::light); let theme = use_theme(Theme::light);
@ -26,8 +35,11 @@ pub fn Checkbox(
css_vars css_vars
}); });
let ssr_class = ssr_class(&class);
view! { view! {
<div <div
class=ssr_class
use:dyn_classes=class
class:thaw-checkbox=true class:thaw-checkbox=true
class=("thaw-checkbox--checked", move || value.get()) class=("thaw-checkbox--checked", move || value.get())
style=move || css_vars.get() style=move || css_vars.get()

View file

@ -2,14 +2,22 @@ mod color;
mod theme; mod theme;
use crate::components::{Binder, Follower, FollowerPlacement}; use crate::components::{Binder, Follower, FollowerPlacement};
use crate::{use_theme, utils::mount_style, Theme}; use crate::utils::dyn_classes;
use crate::{
use_theme,
utils::{mount_style, ssr_class},
Theme,
};
pub use color::*; pub use color::*;
use leptos::leptos_dom::helpers::WindowListenerHandle; use leptos::leptos_dom::helpers::WindowListenerHandle;
use leptos::*; use leptos::*;
pub use theme::ColorPickerTheme; pub use theme::ColorPickerTheme;
#[component] #[component]
pub fn ColorPicker(#[prop(optional, into)] value: RwSignal<RGBA>) -> impl IntoView { pub fn ColorPicker(
#[prop(optional, into)] value: RwSignal<RGBA>,
#[prop(optional, into)] class: MaybeSignal<String>,
) -> impl IntoView {
mount_style("color-picker", include_str!("./color-picker.css")); mount_style("color-picker", include_str!("./color-picker.css"));
let theme = use_theme(Theme::light); let theme = use_theme(Theme::light);
let popover_css_vars = create_memo(move |_| { let popover_css_vars = create_memo(move |_| {
@ -90,9 +98,16 @@ pub fn ColorPicker(#[prop(optional, into)] value: RwSignal<RGBA>) -> impl IntoVi
on_cleanup(move || timer.remove()); on_cleanup(move || timer.remove());
} }
let ssr_class = ssr_class(&class);
view! { view! {
<Binder target_ref=trigger_ref> <Binder target_ref=trigger_ref>
<div class="thaw-color-picker-trigger" on:click=show_popover ref=trigger_ref> <div
class=ssr_class
use:dyn_classes=class
class="thaw-color-picker-trigger"
on:click=show_popover
ref=trigger_ref
>
<div class="thaw-color-picker-trigger__content" style=move || style.get()> <div class="thaw-color-picker-trigger__content" style=move || style.get()>
{move || label.get()} {move || label.get()}
</div> </div>

View file

@ -1,12 +1,15 @@
use leptos::*; use leptos::*;
use crate::utils::mount_style; #[cfg(not(feature = "ssr"))]
use crate::utils::dyn_classes;
use crate::utils::{mount_style, ssr_class};
#[component] #[component]
pub fn Divider() -> impl IntoView { pub fn Divider(#[prop(optional, into)] class: MaybeSignal<String>) -> impl IntoView {
mount_style("divider", include_str!("./divider.css")); mount_style("divider", include_str!("./divider.css"));
let ssr_class = ssr_class(&class);
view! { view! {
<div class="thaw-divider"> <div class=ssr_class use:dyn_classes=class class="thaw-divider">
<div class="thaw-divider__line"></div> <div class="thaw-divider__line"></div>
</div> </div>
} }

View file

@ -1,10 +1,15 @@
use super::use_grid; use super::use_grid;
use leptos::*; use leptos::*;
#[cfg(not(feature = "ssr"))]
use crate::utils::dyn_classes;
use crate::utils::ssr_class;
#[component] #[component]
pub fn GridItem( pub fn GridItem(
#[prop(default = MaybeSignal::Static(1u16), into)] column: MaybeSignal<u16>, #[prop(default = MaybeSignal::Static(1u16), into)] column: MaybeSignal<u16>,
#[prop(optional, into)] offset: MaybeSignal<u16>, #[prop(optional, into)] offset: MaybeSignal<u16>,
#[prop(optional, into)] class: MaybeSignal<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
let grid = use_grid(); let grid = use_grid();
@ -32,8 +37,9 @@ pub fn GridItem(
style style
}); });
let ssr_class = ssr_class(&class);
view! { view! {
<div class="thaw-grid-item" style=move || style.get()> <div class=ssr_class use:dyn_classes=class class="thaw-grid-item" style=move || style.get()>
{children()} {children()}
</div> </div>
} }

View file

@ -1,5 +1,8 @@
mod grid_item; mod grid_item;
use crate::utils::dyn_classes;
use crate::utils::ssr_class;
pub use grid_item::*; pub use grid_item::*;
use leptos::*; use leptos::*;
@ -8,6 +11,7 @@ pub fn Grid(
#[prop(default = MaybeSignal::Static(1u16), into)] cols: MaybeSignal<u16>, #[prop(default = MaybeSignal::Static(1u16), into)] cols: MaybeSignal<u16>,
#[prop(optional, into)] x_gap: MaybeSignal<u16>, #[prop(optional, into)] x_gap: MaybeSignal<u16>,
#[prop(optional, into)] y_gap: MaybeSignal<u16>, #[prop(optional, into)] y_gap: MaybeSignal<u16>,
#[prop(optional, into)] class: MaybeSignal<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
let style = create_memo(move |_| { let style = create_memo(move |_| {
@ -20,9 +24,10 @@ pub fn Grid(
style style
}); });
let ssr_class = ssr_class(&class);
view! { view! {
<Provider value=GridInjection::new(x_gap)> <Provider value=GridInjection::new(x_gap)>
<div class="thaw-grid" style=move || style.get()> <div class=ssr_class use:dyn_classes=class class="thaw-grid" style=move || style.get()>
{children()} {children()}
</div> </div>
</Provider> </Provider>

View file

@ -1,5 +1,9 @@
use leptos::*; use leptos::*;
#[cfg(not(feature = "ssr"))]
use crate::utils::dyn_classes;
use crate::utils::ssr_class;
#[component] #[component]
pub fn Image( pub fn Image(
#[prop(optional, into)] src: MaybeSignal<String>, #[prop(optional, into)] src: MaybeSignal<String>,
@ -8,6 +12,7 @@ pub fn Image(
#[prop(optional, into)] height: MaybeSignal<String>, #[prop(optional, into)] height: MaybeSignal<String>,
#[prop(optional, into)] border_radius: MaybeSignal<String>, #[prop(optional, into)] border_radius: MaybeSignal<String>,
#[prop(optional, into)] object_fit: MaybeSignal<String>, #[prop(optional, into)] object_fit: MaybeSignal<String>,
#[prop(optional, into)] class: MaybeSignal<String>,
) -> impl IntoView { ) -> impl IntoView {
let style = move || { let style = move || {
let mut style = String::new(); let mut style = String::new();
@ -29,8 +34,12 @@ pub fn Image(
style style
}; };
let ssr_class = ssr_class(&class);
view! { view! {
<img <img
class=ssr_class
use:dyn_classes=class
src=move || src.get() src=move || src.get()
alt=move || alt.get() alt=move || alt.get()
style=style style=style

View file

@ -1,8 +1,10 @@
mod theme; mod theme;
#[cfg(not(feature = "ssr"))]
use crate::utils::dyn_classes;
use crate::{ use crate::{
theme::{use_theme, Theme}, theme::{use_theme, Theme},
utils::{mount_style, ComponentRef}, utils::{mount_style, ssr_class, ComponentRef},
}; };
use leptos::*; use leptos::*;
pub use theme::InputTheme; pub use theme::InputTheme;
@ -50,6 +52,7 @@ pub fn Input(
#[prop(optional)] input_prefix: Option<InputPrefix>, #[prop(optional)] input_prefix: Option<InputPrefix>,
#[prop(optional)] input_suffix: Option<InputSuffix>, #[prop(optional)] input_suffix: Option<InputSuffix>,
#[prop(optional)] comp_ref: ComponentRef<InputRef>, #[prop(optional)] comp_ref: ComponentRef<InputRef>,
#[prop(optional, into)] class: MaybeSignal<String>,
) -> impl IntoView { ) -> impl IntoView {
let theme = use_theme(Theme::light); let theme = use_theme(Theme::light);
mount_style("input", include_str!("./input.css")); mount_style("input", include_str!("./input.css"));
@ -123,8 +126,12 @@ pub fn Input(
input_ref.on_load(move |_| { input_ref.on_load(move |_| {
comp_ref.load(InputRef { input_ref }); comp_ref.load(InputRef { input_ref });
}); });
let ssr_class = ssr_class(&class);
view! { view! {
<div <div
class=ssr_class
use:dyn_classes=class
class="thaw-input" class="thaw-input"
class=("thaw-input--focus", move || is_focus.get()) class=("thaw-input--focus", move || is_focus.get())
class=("thaw-input--disabled", move || disabled.get()) class=("thaw-input--disabled", move || disabled.get())

View file

@ -11,6 +11,7 @@ pub fn InputNumber<T>(
#[prop(into)] step: MaybeSignal<T>, #[prop(into)] step: MaybeSignal<T>,
#[prop(optional, into)] disabled: MaybeSignal<bool>, #[prop(optional, into)] disabled: MaybeSignal<bool>,
#[prop(optional, into)] invalid: MaybeSignal<bool>, #[prop(optional, into)] invalid: MaybeSignal<bool>,
#[prop(optional, into)] class: MaybeSignal<String>,
) -> impl IntoView ) -> impl IntoView
where where
T: Add<Output = T> + Sub<Output = T>, T: Add<Output = T> + Sub<Output = T>,
@ -46,7 +47,7 @@ where
value.set(value.get_untracked() - step.get_untracked()); value.set(value.get_untracked() - step.get_untracked());
}); });
view! { view! {
<Input value=input_value allow_value placeholder disabled invalid> <Input class value=input_value allow_value placeholder disabled invalid>
<InputSuffix slot> <InputSuffix slot>
<Button disabled variant=ButtonVariant::Link on_click=sub> <Button disabled variant=ButtonVariant::Link on_click=sub>
<Icon icon=Icon::from(AiIcon::AiMinusOutlined) style="font-size: 18px"/> <Icon icon=Icon::from(AiIcon::AiMinusOutlined) style="font-size: 18px"/>

View file

@ -1,8 +1,18 @@
use crate::{theme::use_theme, utils::mount_style, Theme}; #[cfg(not(feature = "ssr"))]
use crate::utils::dyn_classes;
use crate::{
theme::use_theme,
utils::{mount_style, ssr_class},
Theme,
};
use leptos::*; use leptos::*;
#[component] #[component]
pub fn MenuGroup(#[prop(into)] label: String, children: Children) -> impl IntoView { pub fn MenuGroup(
#[prop(into)] label: String,
#[prop(optional, into)] class: MaybeSignal<String>,
children: Children,
) -> impl IntoView {
mount_style("menu-group", include_str!("./menu-group.css")); mount_style("menu-group", include_str!("./menu-group.css"));
let theme = use_theme(Theme::light); let theme = use_theme(Theme::light);
let css_vars = create_memo(move |_| { let css_vars = create_memo(move |_| {
@ -12,8 +22,14 @@ pub fn MenuGroup(#[prop(into)] label: String, children: Children) -> impl IntoVi
}); });
css_vars css_vars
}); });
let ssr_class = ssr_class(&class);
view! { view! {
<div class="thaw-menu-group" style=move || css_vars.get()> <div
class=ssr_class
use:dyn_classes=class
class="thaw-menu-group"
style=move || css_vars.get()
>
{label} {label}
</div> </div>
{children()} {children()}

View file

@ -1,11 +1,19 @@
use super::use_menu; use super::use_menu;
use crate::{theme::use_theme, utils::mount_style, Theme};
#[cfg(not(feature = "ssr"))]
use crate::utils::dyn_classes;
use crate::{
theme::use_theme,
utils::{mount_style, ssr_class},
Theme,
};
use leptos::*; use leptos::*;
#[component] #[component]
pub fn MenuItem( pub fn MenuItem(
#[prop(into)] key: MaybeSignal<String>, #[prop(into)] key: MaybeSignal<String>,
#[prop(into)] label: MaybeSignal<String>, #[prop(into)] label: MaybeSignal<String>,
#[prop(optional, into)] class: MaybeSignal<String>,
) -> impl IntoView { ) -> impl IntoView {
mount_style("menu-item", include_str!("./menu-item.css")); mount_style("menu-item", include_str!("./menu-item.css"));
let theme = use_theme(Theme::light); let theme = use_theme(Theme::light);
@ -32,9 +40,12 @@ pub fn MenuItem(
}); });
css_vars css_vars
}); });
let ssr_class = ssr_class(&class);
view! { view! {
<div class="thaw-menu-item"> <div class="thaw-menu-item">
<div <div
class=ssr_class
use:dyn_classes=class
class="thaw-menu-item__content" class="thaw-menu-item__content"
class=("thaw-menu-item__content--selected", move || menu.0.get() == key.get()) class=("thaw-menu-item__content--selected", move || menu.0.get() == key.get())
on:click=on_click on:click=on_click

View file

@ -2,16 +2,26 @@ mod menu_group;
mod menu_item; mod menu_item;
mod theme; mod theme;
use crate::utils::dyn_classes;
use crate::utils::ssr_class;
use leptos::*; use leptos::*;
pub use menu_group::MenuGroup; pub use menu_group::MenuGroup;
pub use menu_item::*; pub use menu_item::*;
pub use theme::MenuTheme; pub use theme::MenuTheme;
#[component] #[component]
pub fn Menu(#[prop(optional, into)] value: RwSignal<String>, children: Children) -> impl IntoView { pub fn Menu(
#[prop(optional, into)] value: RwSignal<String>,
#[prop(optional, into)] class: MaybeSignal<String>,
children: Children,
) -> impl IntoView {
let ssr_class = ssr_class(&class);
view! { view! {
<Provider value=MenuInjection(value)> <Provider value=MenuInjection(value)>
<div class="thaw-menu">{children()}</div> <div class=ssr_class use:dyn_classes=class class="thaw-menu">
{children()}
</div>
</Provider> </Provider>
} }
} }

View file

@ -1,10 +1,12 @@
mod theme; mod theme;
#[cfg(not(feature = "ssr"))]
use crate::utils::dyn_classes;
use crate::{ use crate::{
components::*, components::*,
icon::*, icon::*,
use_theme, use_theme,
utils::{mount_style, StoredMaybeSignal}, utils::{mount_style, ssr_class, StoredMaybeSignal},
Theme, Theme,
}; };
use leptos::*; use leptos::*;
@ -18,6 +20,7 @@ pub fn NavBar(
#[prop(optional, into)] on_click_left: Option<Callback<ev::MouseEvent>>, #[prop(optional, into)] on_click_left: Option<Callback<ev::MouseEvent>>,
#[prop(optional, into)] right_text: MaybeSignal<String>, #[prop(optional, into)] right_text: MaybeSignal<String>,
#[prop(optional, into)] on_click_right: Option<Callback<ev::MouseEvent>>, #[prop(optional, into)] on_click_right: Option<Callback<ev::MouseEvent>>,
#[prop(optional, into)] class: MaybeSignal<String>,
) -> impl IntoView { ) -> impl IntoView {
mount_style("nav-bar", include_str!("./nav-bar.css")); mount_style("nav-bar", include_str!("./nav-bar.css"));
let theme = use_theme(Theme::light); let theme = use_theme(Theme::light);
@ -45,8 +48,14 @@ pub fn NavBar(
} }
}; };
let ssr_class = ssr_class(&class);
view! { view! {
<div class="thaw-nav-bar" style=move || css_vars.get()> <div
class=ssr_class
use:dyn_classes=class
class="thaw-nav-bar"
style=move || css_vars.get()
>
<If cond=MaybeSignal::derive(move || left_arrow.get() || !left_text.get().is_empty())> <If cond=MaybeSignal::derive(move || left_arrow.get() || !left_text.get().is_empty())>
<Then slot> <Then slot>
<div class="thaw-nav-bar__left" on:click=on_click_left> <div class="thaw-nav-bar__left" on:click=on_click_left>

View file

@ -1,8 +1,18 @@
use crate::{theme::use_theme, utils::mount_style, Theme}; #[cfg(not(feature = "ssr"))]
use crate::utils::dyn_classes;
use crate::{
theme::use_theme,
utils::{mount_style, ssr_class},
Theme,
};
use leptos::*; use leptos::*;
#[component] #[component]
pub fn Radio(#[prop(optional, into)] value: RwSignal<bool>, children: Children) -> impl IntoView { pub fn Radio(
#[prop(optional, into)] value: RwSignal<bool>,
#[prop(optional, into)] class: MaybeSignal<String>,
children: Children,
) -> impl IntoView {
let theme = use_theme(Theme::light); let theme = use_theme(Theme::light);
mount_style("radio", include_str!("./radio.css")); mount_style("radio", include_str!("./radio.css"));
@ -16,8 +26,11 @@ pub fn Radio(#[prop(optional, into)] value: RwSignal<bool>, children: Children)
css_vars css_vars
}); });
let ssr_class = ssr_class(&class);
view! { view! {
<div <div
class=ssr_class
use:dyn_classes=class
class="thaw-radio" class="thaw-radio"
class=("thaw-radio--checked", move || value.get()) class=("thaw-radio--checked", move || value.get())
style=move || css_vars.get() style=move || css_vars.get()

View file

@ -1,9 +1,10 @@
mod theme; mod theme;
use crate::utils::dyn_classes;
use crate::{ use crate::{
components::{Binder, Follower, FollowerPlacement, FollowerWidth}, components::{Binder, Follower, FollowerPlacement, FollowerWidth},
theme::use_theme, theme::use_theme,
utils::mount_style, utils::{mount_style, ssr_class},
Theme, Theme,
}; };
use leptos::*; use leptos::*;
@ -20,6 +21,7 @@ pub struct SelectOption<T> {
pub fn Select<T>( pub fn Select<T>(
#[prop(optional, into)] value: RwSignal<Option<T>>, #[prop(optional, into)] value: RwSignal<Option<T>>,
#[prop(optional, into)] options: MaybeSignal<Vec<SelectOption<T>>>, #[prop(optional, into)] options: MaybeSignal<Vec<SelectOption<T>>>,
#[prop(optional, into)] class: MaybeSignal<String>,
) -> impl IntoView ) -> impl IntoView
where where
T: Eq + Hash + Clone + 'static, T: Eq + Hash + Clone + 'static,
@ -106,9 +108,12 @@ where
.map_or(String::new(), |v| v.label.clone()), .map_or(String::new(), |v| v.label.clone()),
None => String::new(), None => String::new(),
}); });
let ssr_class = ssr_class(&class);
view! { view! {
<Binder target_ref=trigger_ref> <Binder target_ref=trigger_ref>
<div <div
class=ssr_class
use:dyn_classes=class
class="thaw-select" class="thaw-select"
ref=trigger_ref ref=trigger_ref
on:click=show_menu on:click=show_menu

View file

@ -1,7 +1,14 @@
mod slider_label; mod slider_label;
mod theme; mod theme;
use crate::{components::OptionComp, theme::use_theme, utils::mount_style, Theme}; #[cfg(not(feature = "ssr"))]
use crate::utils::dyn_classes;
use crate::{
components::OptionComp,
theme::use_theme,
utils::{mount_style, ssr_class},
Theme,
};
use leptos::*; use leptos::*;
use web_sys::DomRect; use web_sys::DomRect;
@ -13,6 +20,7 @@ pub fn Slider(
#[prop(optional, into)] value: RwSignal<f64>, #[prop(optional, into)] value: RwSignal<f64>,
#[prop(default = MaybeSignal::Static(100f64), into)] max: MaybeSignal<f64>, #[prop(default = MaybeSignal::Static(100f64), into)] max: MaybeSignal<f64>,
#[prop(optional, into)] step: MaybeSignal<f64>, #[prop(optional, into)] step: MaybeSignal<f64>,
#[prop(optional, into)] class: MaybeSignal<String>,
#[prop(optional)] children: Option<Children>, #[prop(optional)] children: Option<Children>,
) -> impl IntoView { ) -> impl IntoView {
mount_style("slider", include_str!("./slider.css")); mount_style("slider", include_str!("./slider.css"));
@ -110,8 +118,15 @@ pub fn Slider(
}); });
on_cleanup(move || on_mouse_move.remove()); on_cleanup(move || on_mouse_move.remove());
let ssr_class = ssr_class(&class);
view! { view! {
<div class="thaw-slider" style=move || css_vars.get() on:click=on_mouse_click> <div
class=ssr_class
use:dyn_classes=class
class="thaw-slider"
style=move || css_vars.get()
on:click=on_mouse_click
>
<div class="thaw-slider-rail" ref=rail_ref> <div class="thaw-slider-rail" ref=rail_ref>
<div <div
class="thaw-slider-rail__fill" class="thaw-slider-rail__fill"
@ -126,6 +141,7 @@ pub fn Slider(
class="thaw-slider-handle" class="thaw-slider-handle"
style=move || { format!("left: {}%", percentage.get()) } style=move || { format!("left: {}%", percentage.get()) }
></div> ></div>
</div> </div>
} }
} }

View file

@ -1,4 +1,6 @@
use crate::utils::mount_style; #[cfg(not(feature = "ssr"))]
use crate::utils::dyn_classes;
use crate::utils::{mount_style, ssr_class};
use leptos::*; use leptos::*;
#[derive(Default)] #[derive(Default)]
@ -16,6 +18,7 @@ pub enum SpaceGap {
pub fn Space( pub fn Space(
#[prop(optional)] gap: SpaceGap, #[prop(optional)] gap: SpaceGap,
#[prop(optional)] vertical: bool, #[prop(optional)] vertical: bool,
#[prop(optional, into)] class: MaybeSignal<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
mount_style("space", include_str!("./space.css")); mount_style("space", include_str!("./space.css"));
@ -27,8 +30,11 @@ pub fn Space(
SpaceGap::WH(width, height) => format!("{width}px {height}px"), SpaceGap::WH(width, height) => format!("{width}px {height}px"),
}; };
let ssr_class = ssr_class(&class);
view! { view! {
<div <div
class=ssr_class
use:dyn_classes=class
class="thaw-space" class="thaw-space"
style:gap=gap style:gap=gap
style:flex-direction=if vertical { "column" } else { "row" } style:flex-direction=if vertical { "column" } else { "row" }

View file

@ -1,11 +1,20 @@
mod theme; mod theme;
use crate::{theme::use_theme, utils::mount_style, Theme}; #[cfg(not(feature = "ssr"))]
use crate::utils::dyn_classes;
use crate::{
theme::use_theme,
utils::{mount_style, ssr_class},
Theme,
};
use leptos::*; use leptos::*;
pub use theme::SwitchTheme; pub use theme::SwitchTheme;
#[component] #[component]
pub fn Switch(#[prop(optional, into)] value: RwSignal<bool>) -> impl IntoView { pub fn Switch(
#[prop(optional, into)] value: RwSignal<bool>,
#[prop(optional, into)] class: MaybeSignal<String>,
) -> impl IntoView {
mount_style("switch", include_str!("./switch.css")); mount_style("switch", include_str!("./switch.css"));
let theme = use_theme(Theme::light); let theme = use_theme(Theme::light);
let css_vars = create_memo(move |_| { let css_vars = create_memo(move |_| {
@ -22,8 +31,11 @@ pub fn Switch(#[prop(optional, into)] value: RwSignal<bool>) -> impl IntoView {
}); });
css_vars css_vars
}); });
let ssr_class = ssr_class(&class);
view! { view! {
<div <div
class=ssr_class
use:dyn_classes=class
class="thaw-switch" class="thaw-switch"
class=("thaw-switch--active", move || value.get()) class=("thaw-switch--active", move || value.get())
style=move || css_vars.get() style=move || css_vars.get()

View file

@ -1,6 +1,12 @@
mod theme; mod theme;
use crate::{theme::use_theme, utils::mount_style, Theme}; #[cfg(not(feature = "ssr"))]
use crate::utils::dyn_classes;
use crate::{
theme::use_theme,
utils::{mount_style, ssr_class},
Theme,
};
use leptos::*; use leptos::*;
pub use theme::TableTheme; pub use theme::TableTheme;
@ -8,6 +14,7 @@ pub use theme::TableTheme;
pub fn Table( pub fn Table(
#[prop(optional, into)] style: MaybeSignal<String>, #[prop(optional, into)] style: MaybeSignal<String>,
#[prop(default=true.into(), into)] single_row: MaybeSignal<bool>, #[prop(default=true.into(), into)] single_row: MaybeSignal<bool>,
#[prop(optional, into)] class: MaybeSignal<String>,
#[prop(optional, into)] single_column: MaybeSignal<bool>, #[prop(optional, into)] single_column: MaybeSignal<bool>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
@ -36,8 +43,11 @@ pub fn Table(
css_vars css_vars
}); });
let ssr_class = ssr_class(&class);
view! { view! {
<table <table
class=ssr_class
use:dyn_classes=class
class="thaw-table" class="thaw-table"
class=("thaw-table--single-row", move || single_row.get()) class=("thaw-table--single-row", move || single_row.get())
class=("thaw-table--single-column", move || single_column.get()) class=("thaw-table--single-column", move || single_column.get())

View file

@ -1,12 +1,22 @@
mod tab; mod tab;
use crate::{theme::use_theme, utils::mount_style, Theme}; #[cfg(not(feature = "ssr"))]
use crate::utils::dyn_classes;
use crate::{
theme::use_theme,
utils::{mount_style, ssr_class},
Theme,
};
use leptos::*; use leptos::*;
pub use tab::*; pub use tab::*;
#[component] #[component]
pub fn Tabs(#[prop(optional, into)] value: RwSignal<String>, children: Children) -> impl IntoView { pub fn Tabs(
#[prop(optional, into)] value: RwSignal<String>,
#[prop(optional, into)] class: MaybeSignal<String>,
children: Children,
) -> impl IntoView {
mount_style("tabs", include_str!("./tabs.css")); mount_style("tabs", include_str!("./tabs.css"));
let tab_options_vec = create_rw_signal(vec![]); let tab_options_vec = create_rw_signal(vec![]);
@ -15,7 +25,7 @@ pub fn Tabs(#[prop(optional, into)] value: RwSignal<String>, children: Children)
active_key: value, active_key: value,
tab_options_vec, tab_options_vec,
}> }>
<TabsInner value tab_options_vec children/> <TabsInner class value tab_options_vec children/>
</Provider> </Provider>
} }
} }
@ -24,6 +34,7 @@ pub fn Tabs(#[prop(optional, into)] value: RwSignal<String>, children: Children)
fn TabsInner( fn TabsInner(
value: RwSignal<String>, value: RwSignal<String>,
tab_options_vec: RwSignal<Vec<TabOption>>, tab_options_vec: RwSignal<Vec<TabOption>>,
#[prop(optional, into)] class: MaybeSignal<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
mount_style("tabs", include_str!("./tabs.css")); mount_style("tabs", include_str!("./tabs.css"));
@ -50,8 +61,9 @@ fn TabsInner(
let label_list_ref = create_node_ref::<html::Div>(); let label_list_ref = create_node_ref::<html::Div>();
let children = children(); let children = children();
let ssr_class = ssr_class(&class);
view! { view! {
<div class="thaw-tabs" style=move || css_vars.get()> <div class=ssr_class use:dyn_classes=class class="thaw-tabs" style=move || css_vars.get()>
<div class="thaw-tabs__label-list" ref=label_list_ref> <div class="thaw-tabs__label-list" ref=label_list_ref>
<For <For
each=move || tab_options_vec.get() each=move || tab_options_vec.get()

View file

@ -1,5 +1,7 @@
use super::use_tabs; use super::use_tabs;
use crate::utils::mount_style; #[cfg(not(feature = "ssr"))]
use crate::utils::dyn_classes;
use crate::utils::{mount_style, ssr_class};
use leptos::*; use leptos::*;
#[derive(Clone)] #[derive(Clone)]
@ -12,6 +14,7 @@ pub(crate) struct TabOption {
pub fn Tab( pub fn Tab(
#[prop(into)] key: String, #[prop(into)] key: String,
#[prop(into)] label: String, #[prop(into)] label: String,
#[prop(optional, into)] class: MaybeSignal<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
mount_style("tab", include_str!("./tab.css")); mount_style("tab", include_str!("./tab.css"));
@ -20,8 +23,14 @@ pub fn Tab(
key: key.clone(), key: key.clone(),
label, label,
}); });
let ssr_class = ssr_class(&class);
view! { view! {
<div class="thaw-tab" class=("thaw-tab--hidden", move || key != tabs.get_key())> <div
class=ssr_class
use:dyn_classes=class
class="thaw-tab"
class=("thaw-tab--hidden", move || key != tabs.get_key())
>
{children()} {children()}
</div> </div>
} }

View file

@ -1,6 +1,12 @@
mod theme; mod theme;
use crate::{theme::use_theme, utils::mount_style, Theme}; #[cfg(not(feature = "ssr"))]
use crate::utils::dyn_classes;
use crate::{
theme::use_theme,
utils::{mount_style, ssr_class},
Theme,
};
use leptos::*; use leptos::*;
pub use theme::TagTheme; pub use theme::TagTheme;
@ -43,6 +49,7 @@ impl TagVariant {
#[component] #[component]
pub fn Tag( pub fn Tag(
#[prop(optional, into)] variant: MaybeSignal<TagVariant>, #[prop(optional, into)] variant: MaybeSignal<TagVariant>,
#[prop(optional, into)] class: MaybeSignal<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
mount_style("tag", include_str!("./tag.css")); mount_style("tag", include_str!("./tag.css"));
@ -66,8 +73,9 @@ pub fn Tag(
}); });
css_vars css_vars
}); });
let ssr_class = ssr_class(&class);
view! { view! {
<div class="thaw-tag" style=move || css_vars.get()> <div class=ssr_class use:dyn_classes=class class="thaw-tag" style=move || css_vars.get()>
<span class="thaw-tag__content">{children()}</span> <span class="thaw-tag__content">{children()}</span>
</div> </div>
} }

View file

@ -11,7 +11,10 @@ use leptos::*;
pub use theme::TimePickerTheme; pub use theme::TimePickerTheme;
#[component] #[component]
pub fn TimePicker(#[prop(optional, into)] value: RwSignal<Option<NaiveTime>>) -> impl IntoView { pub fn TimePicker(
#[prop(optional, into)] value: RwSignal<Option<NaiveTime>>,
#[prop(optional, into)] class: MaybeSignal<String>,
) -> impl IntoView {
mount_style("time-picker", include_str!("./time-picker.css")); mount_style("time-picker", include_str!("./time-picker.css"));
let time_picker_ref = create_node_ref::<html::Div>(); let time_picker_ref = create_node_ref::<html::Div>();
let panel_ref = ComponentRef::<PanelRef>::default(); let panel_ref = ComponentRef::<PanelRef>::default();
@ -70,7 +73,7 @@ pub fn TimePicker(#[prop(optional, into)] value: RwSignal<Option<NaiveTime>>) ->
view! { view! {
<Binder target_ref=time_picker_ref> <Binder target_ref=time_picker_ref>
<div ref=time_picker_ref> <div ref=time_picker_ref>
<Input value=show_time_text on_focus=open_panel on_blur=on_input_blur> <Input class value=show_time_text on_focus=open_panel on_blur=on_input_blur>
<InputSuffix slot> <InputSuffix slot>
<Icon <Icon
icon=Icon::from(AiIcon::AiClockCircleOutlined) icon=Icon::from(AiIcon::AiClockCircleOutlined)

View file

@ -1,8 +1,18 @@
use crate::{use_theme, utils::mount_style, Theme}; #[cfg(not(feature = "ssr"))]
use crate::utils::dyn_classes;
use crate::{
use_theme,
utils::{mount_style, ssr_class},
Theme,
};
use leptos::*; use leptos::*;
#[component] #[component]
pub fn Text(#[prop(optional)] code: bool, children: Children) -> impl IntoView { pub fn Text(
#[prop(optional)] code: bool,
#[prop(optional, into)] class: MaybeSignal<String>,
children: Children,
) -> impl IntoView {
mount_style("text", include_str!("./text.css")); mount_style("text", include_str!("./text.css"));
let theme = use_theme(Theme::light); let theme = use_theme(Theme::light);
let css_vars = create_memo(move |_| { let css_vars = create_memo(move |_| {
@ -16,14 +26,25 @@ pub fn Text(#[prop(optional)] code: bool, children: Children) -> impl IntoView {
css_vars css_vars
}); });
let ssr_class = ssr_class(&class);
if code { if code {
view! { view! {
<code class="thaw-text thaw-text--code" style=move || css_vars.get()> <code
class=ssr_class
use:dyn_classes=class
class="thaw-text thaw-text--code"
style=move || css_vars.get()
>
{children()} {children()}
</code> </code>
} }
.into_any() .into_any()
} else { } else {
view! { <span class="thaw-text">{children()}</span> }.into_any() view! {
<span class=ssr_class use:dyn_classes=class class="thaw-text">
{children()}
</span>
}
.into_any()
} }
} }