diff --git a/demo/src/pages/badge/mod.rs b/demo/src/pages/badge/mod.rs index 60b5924..a45d93b 100644 --- a/demo/src/pages/badge/mod.rs +++ b/demo/src/pages/badge/mod.rs @@ -107,6 +107,12 @@ pub fn BadgePage() -> impl IntoView { <td></td> <td>"Badge's content."</td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the badge element."</td> + </tr> </tbody> </Table> </div> diff --git a/demo/src/pages/breadcrumb/mod.rs b/demo/src/pages/breadcrumb/mod.rs index e347d8c..98870e6 100644 --- a/demo/src/pages/breadcrumb/mod.rs +++ b/demo/src/pages/breadcrumb/mod.rs @@ -86,6 +86,12 @@ pub fn BreadcrumbPage() -> impl IntoView { <td></td> <td>"Breadcrumb's content."</td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the breadcrumb element."</td> + </tr> </tbody> </Table> <h3>"BreadcrumbItem Props"</h3> @@ -105,6 +111,12 @@ pub fn BreadcrumbPage() -> impl IntoView { <td></td> <td>"BreadcrumbItem's content."</td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the breadcrumb link element."</td> + </tr> </tbody> </Table> </div> diff --git a/demo/src/pages/calendar/mod.rs b/demo/src/pages/calendar/mod.rs index 595a9c2..a256d34 100644 --- a/demo/src/pages/calendar/mod.rs +++ b/demo/src/pages/calendar/mod.rs @@ -50,6 +50,12 @@ pub fn CalendarPage() -> impl IntoView { </td> <td></td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the calendar element."</td> + </tr> </tbody> </Table> </div> diff --git a/demo/src/pages/card/mod.rs b/demo/src/pages/card/mod.rs index 276fb3e..98a6b7c 100644 --- a/demo/src/pages/card/mod.rs +++ b/demo/src/pages/card/mod.rs @@ -84,6 +84,12 @@ pub fn CardPage() -> impl IntoView { <td></td> <td>"Card's content."</td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the card element."</td> + </tr> </tbody> </Table> <h3>"Card Slots"</h3> diff --git a/demo/src/pages/checkbox/mod.rs b/demo/src/pages/checkbox/mod.rs index 1fb699c..957d91a 100644 --- a/demo/src/pages/checkbox/mod.rs +++ b/demo/src/pages/checkbox/mod.rs @@ -106,6 +106,12 @@ pub fn CheckboxPage() -> impl IntoView { <td></td> <td>"CheckboxGroup's content."</td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the checkbox element."</td> + </tr> </tbody> </Table> <h3>"CheckboxItem Props"</h3> diff --git a/demo/src/pages/color_picker/mod.rs b/demo/src/pages/color_picker/mod.rs index 257bcd3..ff9ec57 100644 --- a/demo/src/pages/color_picker/mod.rs +++ b/demo/src/pages/color_picker/mod.rs @@ -44,6 +44,12 @@ pub fn ColorPickerPage() -> impl IntoView { <td>"RwSignal<RGBA>"</td> <td>"Value of the picker."</td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the color picker element."</td> + </tr> </tbody> </Table> </div> diff --git a/demo/src/pages/divider/mod.rs b/demo/src/pages/divider/mod.rs index f588e51..e0eb907 100644 --- a/demo/src/pages/divider/mod.rs +++ b/demo/src/pages/divider/mod.rs @@ -23,6 +23,25 @@ pub fn DividerPage() -> impl IntoView { </DemoCode> </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> } } diff --git a/demo/src/pages/grid/mod.rs b/demo/src/pages/grid/mod.rs index da508f2..1d809a1 100644 --- a/demo/src/pages/grid/mod.rs +++ b/demo/src/pages/grid/mod.rs @@ -142,6 +142,43 @@ pub fn GridPage() -> impl IntoView { <td>"0"</td> <td>"Vertical gap."</td> </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> </Table> </div> diff --git a/demo/src/pages/image/mod.rs b/demo/src/pages/image/mod.rs index 1b6e5a9..75c18ea 100644 --- a/demo/src/pages/image/mod.rs +++ b/demo/src/pages/image/mod.rs @@ -70,6 +70,12 @@ pub fn ImagePage() -> impl IntoView { <td>"Default::default()"</td> <td>"Object-fit type of the image in the container."</td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the image element."</td> + </tr> </tbody> </Table> </div> diff --git a/demo/src/pages/input/mod.rs b/demo/src/pages/input/mod.rs index 8641034..e3805f6 100644 --- a/demo/src/pages/input/mod.rs +++ b/demo/src/pages/input/mod.rs @@ -213,6 +213,12 @@ pub fn InputPage() -> impl IntoView { <td>"None"</td> <td>"Callback triggered when the input is blurred."</td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the input element."</td> + </tr> </tbody> </Table> <h3>"Input Slots"</h3> diff --git a/demo/src/pages/input_number/mod.rs b/demo/src/pages/input_number/mod.rs index a882411..db15093 100644 --- a/demo/src/pages/input_number/mod.rs +++ b/demo/src/pages/input_number/mod.rs @@ -108,6 +108,12 @@ pub fn InputNumberPage() -> impl IntoView { <td>"false"</td> <td>"Whether the input is invalid."</td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the input element."</td> + </tr> </tbody> </Table> <h3>"T impl"</h3> diff --git a/demo/src/pages/menu/mod.rs b/demo/src/pages/menu/mod.rs index f05c041..30f2387 100644 --- a/demo/src/pages/menu/mod.rs +++ b/demo/src/pages/menu/mod.rs @@ -15,9 +15,7 @@ pub fn MenuPage() -> impl IntoView { <MenuItem key="o" label="or"/> </Menu> <DemoCode slot> - - {highlight_str!( - r#" +{highlight_str!( r#" let value = create_rw_signal(String::from("o")); <Menu value> @@ -53,6 +51,12 @@ pub fn MenuPage() -> impl IntoView { <td></td> <td>"Menu's content."</td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the menu element."</td> + </tr> </tbody> </Table> <h3>"MenuGroup Props"</h3> @@ -78,6 +82,12 @@ pub fn MenuPage() -> impl IntoView { <td></td> <td>"MenuGroup's content."</td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the menu group element."</td> + </tr> </tbody> </Table> <h3>"MenuItem Props"</h3> @@ -103,6 +113,12 @@ pub fn MenuPage() -> impl IntoView { <td>"Default::default()"</td> <td>"The indentifier of the menu item."</td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the menu item element."</td> + </tr> </tbody> </Table> </div> diff --git a/demo/src/pages/nav_bar/mod.rs b/demo/src/pages/nav_bar/mod.rs index cf1652f..70e7735 100644 --- a/demo/src/pages/nav_bar/mod.rs +++ b/demo/src/pages/nav_bar/mod.rs @@ -89,6 +89,12 @@ pub fn NavBarPage() -> impl IntoView { <td>"Default::default()"</td> <td>"NavBar right click."</td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the NavBar element."</td> + </tr> </tbody> </Table> </div> diff --git a/demo/src/pages/radio/mod.rs b/demo/src/pages/radio/mod.rs index bd031ae..e8711ff 100644 --- a/demo/src/pages/radio/mod.rs +++ b/demo/src/pages/radio/mod.rs @@ -51,6 +51,12 @@ pub fn RadioPage() -> impl IntoView { <td></td> <td>"Radio's content."</td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the radio element."</td> + </tr> </tbody> </Table> </div> diff --git a/demo/src/pages/select/mod.rs b/demo/src/pages/select/mod.rs index 61b9845..cfce1bf 100644 --- a/demo/src/pages/select/mod.rs +++ b/demo/src/pages/select/mod.rs @@ -56,6 +56,12 @@ pub fn SelectPage() -> impl IntoView { <td>"vec![]"</td> <td>"Options that can be selected."</td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the select element."</td> + </tr> </tbody> </Table> </div> diff --git a/demo/src/pages/slider/mod.rs b/demo/src/pages/slider/mod.rs index 493beb6..91835f9 100644 --- a/demo/src/pages/slider/mod.rs +++ b/demo/src/pages/slider/mod.rs @@ -114,6 +114,12 @@ pub fn SliderPage() -> impl IntoView { <td></td> <td>"Slider labels."</td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the slider element."</td> + </tr> </tbody> </Table> <h3>"SliderLabel Props"</h3> diff --git a/demo/src/pages/space/mod.rs b/demo/src/pages/space/mod.rs index 2db6653..da07c37 100644 --- a/demo/src/pages/space/mod.rs +++ b/demo/src/pages/space/mod.rs @@ -112,6 +112,12 @@ pub fn SpacePage() -> impl IntoView { <td></td> <td>"Space's content."</td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the space element."</td> + </tr> </tbody> </Table> </div> diff --git a/demo/src/pages/switch/mod.rs b/demo/src/pages/switch/mod.rs index 2f5d4c6..6829192 100644 --- a/demo/src/pages/switch/mod.rs +++ b/demo/src/pages/switch/mod.rs @@ -42,6 +42,12 @@ pub fn SwitchPage() -> impl IntoView { <td>"false"</td> <td>"Swith's value."</td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the switch element."</td> + </tr> </tbody> </Table> </div> diff --git a/demo/src/pages/table/mod.rs b/demo/src/pages/table/mod.rs index 79c6e2c..d335184 100644 --- a/demo/src/pages/table/mod.rs +++ b/demo/src/pages/table/mod.rs @@ -96,6 +96,12 @@ pub fn TablePage() -> impl IntoView { <td></td> <td>"Table's content."</td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the table element."</td> + </tr> </tbody> </Table> </div> diff --git a/demo/src/pages/tabs/mod.rs b/demo/src/pages/tabs/mod.rs index 30e33cc..d6a36e5 100644 --- a/demo/src/pages/tabs/mod.rs +++ b/demo/src/pages/tabs/mod.rs @@ -69,6 +69,12 @@ pub fn TabsPage() -> impl IntoView { <td></td> <td>"Tabs content."</td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the tabs element."</td> + </tr> </tbody> </Table> <h3>"Tab Props"</h3> @@ -106,6 +112,12 @@ pub fn TabsPage() -> impl IntoView { <td></td> <td>"Tab's content."</td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the tab element."</td> + </tr> </tbody> </Table> </div> diff --git a/demo/src/pages/tag/mod.rs b/demo/src/pages/tag/mod.rs index 8164ef8..f3b7fb2 100644 --- a/demo/src/pages/tag/mod.rs +++ b/demo/src/pages/tag/mod.rs @@ -62,6 +62,12 @@ pub fn TagPage() -> impl IntoView { <td></td> <td>"Tag's content."</td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the tag element."</td> + </tr> </tbody> </Table> </div> diff --git a/demo/src/pages/time_picker/mod.rs b/demo/src/pages/time_picker/mod.rs index dee2dfa..96a7866 100644 --- a/demo/src/pages/time_picker/mod.rs +++ b/demo/src/pages/time_picker/mod.rs @@ -47,6 +47,12 @@ pub fn TimePickerPage() -> impl IntoView { <td></td> <td></td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the time picker element."</td> + </tr> </tbody> </Table> </div> diff --git a/demo/src/pages/typography/mod.rs b/demo/src/pages/typography/mod.rs index 5b6762b..01f2816 100644 --- a/demo/src/pages/typography/mod.rs +++ b/demo/src/pages/typography/mod.rs @@ -60,6 +60,12 @@ pub fn TypographyPage() -> impl IntoView { <td></td> <td>"Text's content."</td> </tr> + <tr> + <td>"class"</td> + <td>"MaybeSignal<String>"</td> + <td>"Default::default()"</td> + <td>"Addtional classes for the text element."</td> + </tr> </tbody> </Table> </div> diff --git a/src/badge/badge.css b/src/badge/badge.css index ba241da..e245bbc 100644 --- a/src/badge/badge.css +++ b/src/badge/badge.css @@ -6,6 +6,7 @@ position: absolute; color: var(--thaw-font-color); background-color: var(--thaw-background-color); + z-index: 10; } .thaw-badge__sup--value { top: -9px; diff --git a/src/badge/mod.rs b/src/badge/mod.rs index 3c100cf..1874956 100644 --- a/src/badge/mod.rs +++ b/src/badge/mod.rs @@ -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::*; #[derive(Default, Clone)] @@ -25,6 +32,7 @@ pub fn Badge( #[prop(default = MaybeSignal::Static(u32::MAX), into)] max: MaybeSignal<u32>, #[prop(optional, into)] variant: MaybeSignal<BadgeVariant>, #[prop(optional, into)] dot: MaybeSignal<bool>, + #[prop(optional, into)] class: MaybeSignal<String>, children: Children, ) -> impl IntoView { let theme = use_theme(Theme::light); @@ -51,9 +59,12 @@ pub fn Badge( value.to_string() } }); + let ssr_class = ssr_class(&class); view! { <div class="thaw-badge" style=move || css_vars.get()> <div + class=ssr_class + use:dyn_classes=class class="thaw-badge__sup" class=("thaw-badge__sup--value", move || !dot.get() && !value.get().is_empty()) class=("thaw-badge__sup--dot", move || dot.get()) diff --git a/src/breadcrumb/breadcrumb_item.rs b/src/breadcrumb/breadcrumb_item.rs index 9926710..d71c1f5 100644 --- a/src/breadcrumb/breadcrumb_item.rs +++ b/src/breadcrumb/breadcrumb_item.rs @@ -1,12 +1,22 @@ use super::use_breadcrumb_separator; use leptos::*; +#[cfg(not(feature = "ssr"))] +use crate::utils::dyn_classes; +use crate::utils::ssr_class; + #[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 ssr_class = ssr_class(&class); view! { <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"> {move || breadcrumb_separator.0.get()} </span> diff --git a/src/breadcrumb/mod.rs b/src/breadcrumb/mod.rs index b311bee..ef7e5ee 100644 --- a/src/breadcrumb/mod.rs +++ b/src/breadcrumb/mod.rs @@ -1,7 +1,12 @@ mod breadcrumb_item; 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; use leptos::*; pub use theme::BreadcrumbTheme; @@ -9,6 +14,7 @@ pub use theme::BreadcrumbTheme; #[component] pub fn Breadcrumb( #[prop(default = MaybeSignal::Static("/".to_string()),into)] separator: MaybeSignal<String>, + #[prop(optional, into)] class: MaybeSignal<String>, children: Children, ) -> impl IntoView { mount_style("breadcrumb", include_str!("./breadcrumb.css")); @@ -31,9 +37,15 @@ pub fn Breadcrumb( }); css_vars }); + let ssr_class = ssr_class(&class); view! { <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> </nav> </Provider> diff --git a/src/calendar/mod.rs b/src/calendar/mod.rs index 7b2f8b0..578ef37 100644 --- a/src/calendar/mod.rs +++ b/src/calendar/mod.rs @@ -1,9 +1,11 @@ mod theme; +#[cfg(not(feature = "ssr"))] +use crate::utils::dyn_classes; use crate::{ chrono::{Datelike, Days, Local, NaiveDate}, use_theme, - utils::mount_style, + utils::{mount_style, ssr_class}, Button, ButtonGroup, ButtonVariant, Theme, }; use chrono::{Month, Months}; @@ -13,7 +15,10 @@ use std::ops::Deref; pub use theme::CalendarTheme; #[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")); let theme = use_theme(Theme::light); 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); }); }; + let ssr_class = ssr_class(&class); 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"> <span class="thaw-calendar__header-title"> diff --git a/src/card/card.css b/src/card/card.css index cd29be7..c461ef2 100644 --- a/src/card/card.css +++ b/src/card/card.css @@ -4,6 +4,7 @@ border: 1px solid var(--thaw-border-color); border-radius: 3px; overflow: hidden; + background-color: var(--thaw-background-color); /* moving here so that applying padding to card element works correctly */ } .thaw-card__header { font-weight: 600; @@ -21,7 +22,6 @@ .thaw-card__content, .thaw-card__footer { padding: 12px 28px; - background-color: var(--thaw-background-color); } .thaw-card__header { padding: 20px 28px; diff --git a/src/card/mod.rs b/src/card/mod.rs index 8ce1955..c3d2e79 100644 --- a/src/card/mod.rs +++ b/src/card/mod.rs @@ -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::*; #[derive(Clone)] @@ -25,6 +32,7 @@ pub fn Card( #[prop(optional, into)] title: MaybeSignal<String>, #[prop(optional)] card_header: Option<CardHeader>, #[prop(optional)] card_header_extra: Option<CardHeaderExtra>, + #[prop(optional, into)] class: MaybeSignal<String>, children: Children, #[prop(optional)] card_footer: Option<CardFooter>, ) -> impl IntoView { @@ -51,8 +59,9 @@ pub fn Card( let header = store_value(card_header); let header_extra = store_value(card_header_extra); + let ssr_class = ssr_class(&class); 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> <Then slot> <div class="thaw-card__header"> diff --git a/src/checkbox/checkbox_item.rs b/src/checkbox/checkbox_item.rs index a31e178..cd49a2c 100644 --- a/src/checkbox/checkbox_item.rs +++ b/src/checkbox/checkbox_item.rs @@ -7,6 +7,7 @@ use leptos::*; #[component] pub fn CheckboxItem( #[prop(optional, into)] label: Option<String>, + #[prop(optional, into)] class: MaybeSignal<String>, #[prop(into)] key: String, ) -> impl IntoView { let checkbox_group = use_checkbox_group(); @@ -32,5 +33,9 @@ pub fn CheckboxItem( item_key.get_value() }; - view! { <Checkbox value=checked>{label}</Checkbox> } + view! { + <Checkbox class value=checked> + {label} + </Checkbox> + } } diff --git a/src/checkbox/mod.rs b/src/checkbox/mod.rs index 17248a8..c27a5ea 100644 --- a/src/checkbox/mod.rs +++ b/src/checkbox/mod.rs @@ -1,7 +1,15 @@ mod checkbox_group; 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_item::CheckboxItem; use icondata::AiIcon; @@ -10,6 +18,7 @@ use leptos::*; #[component] pub fn Checkbox( #[prop(optional, into)] value: RwSignal<bool>, + #[prop(optional, into)] class: MaybeSignal<String>, children: Children, ) -> impl IntoView { let theme = use_theme(Theme::light); @@ -26,8 +35,11 @@ pub fn Checkbox( css_vars }); + let ssr_class = ssr_class(&class); view! { <div + class=ssr_class + use:dyn_classes=class class:thaw-checkbox=true class=("thaw-checkbox--checked", move || value.get()) style=move || css_vars.get() diff --git a/src/color_picker/mod.rs b/src/color_picker/mod.rs index 4c99756..18d1c7b 100644 --- a/src/color_picker/mod.rs +++ b/src/color_picker/mod.rs @@ -2,14 +2,22 @@ mod color; mod theme; 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::*; use leptos::leptos_dom::helpers::WindowListenerHandle; use leptos::*; pub use theme::ColorPickerTheme; #[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")); let theme = use_theme(Theme::light); 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()); } + let ssr_class = ssr_class(&class); view! { <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()> {move || label.get()} </div> diff --git a/src/divider/mod.rs b/src/divider/mod.rs index b021766..a66ba6c 100644 --- a/src/divider/mod.rs +++ b/src/divider/mod.rs @@ -1,12 +1,15 @@ use leptos::*; -use crate::utils::mount_style; +#[cfg(not(feature = "ssr"))] +use crate::utils::dyn_classes; +use crate::utils::{mount_style, ssr_class}; #[component] -pub fn Divider() -> impl IntoView { +pub fn Divider(#[prop(optional, into)] class: MaybeSignal<String>) -> impl IntoView { mount_style("divider", include_str!("./divider.css")); + let ssr_class = ssr_class(&class); view! { - <div class="thaw-divider"> + <div class=ssr_class use:dyn_classes=class class="thaw-divider"> <div class="thaw-divider__line"></div> </div> } diff --git a/src/grid/grid_item.rs b/src/grid/grid_item.rs index 232a923..70d7737 100644 --- a/src/grid/grid_item.rs +++ b/src/grid/grid_item.rs @@ -1,10 +1,15 @@ use super::use_grid; use leptos::*; +#[cfg(not(feature = "ssr"))] +use crate::utils::dyn_classes; +use crate::utils::ssr_class; + #[component] pub fn GridItem( #[prop(default = MaybeSignal::Static(1u16), into)] column: MaybeSignal<u16>, #[prop(optional, into)] offset: MaybeSignal<u16>, + #[prop(optional, into)] class: MaybeSignal<String>, children: Children, ) -> impl IntoView { let grid = use_grid(); @@ -32,8 +37,9 @@ pub fn GridItem( style }); + let ssr_class = ssr_class(&class); 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()} </div> } diff --git a/src/grid/mod.rs b/src/grid/mod.rs index f1278f3..19a1231 100644 --- a/src/grid/mod.rs +++ b/src/grid/mod.rs @@ -1,5 +1,8 @@ mod grid_item; +use crate::utils::dyn_classes; +use crate::utils::ssr_class; + pub use grid_item::*; use leptos::*; @@ -8,6 +11,7 @@ pub fn Grid( #[prop(default = MaybeSignal::Static(1u16), into)] cols: MaybeSignal<u16>, #[prop(optional, into)] x_gap: MaybeSignal<u16>, #[prop(optional, into)] y_gap: MaybeSignal<u16>, + #[prop(optional, into)] class: MaybeSignal<String>, children: Children, ) -> impl IntoView { let style = create_memo(move |_| { @@ -20,9 +24,10 @@ pub fn Grid( style }); + let ssr_class = ssr_class(&class); view! { <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()} </div> </Provider> diff --git a/src/image/mod.rs b/src/image/mod.rs index 9b362be..3d9aa4f 100644 --- a/src/image/mod.rs +++ b/src/image/mod.rs @@ -1,5 +1,9 @@ use leptos::*; +#[cfg(not(feature = "ssr"))] +use crate::utils::dyn_classes; +use crate::utils::ssr_class; + #[component] pub fn Image( #[prop(optional, into)] src: MaybeSignal<String>, @@ -8,6 +12,7 @@ pub fn Image( #[prop(optional, into)] height: MaybeSignal<String>, #[prop(optional, into)] border_radius: MaybeSignal<String>, #[prop(optional, into)] object_fit: MaybeSignal<String>, + #[prop(optional, into)] class: MaybeSignal<String>, ) -> impl IntoView { let style = move || { let mut style = String::new(); @@ -29,8 +34,12 @@ pub fn Image( style }; + + let ssr_class = ssr_class(&class); view! { <img + class=ssr_class + use:dyn_classes=class src=move || src.get() alt=move || alt.get() style=style diff --git a/src/input/mod.rs b/src/input/mod.rs index 2d37cdf..6feabbc 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -1,8 +1,10 @@ mod theme; +#[cfg(not(feature = "ssr"))] +use crate::utils::dyn_classes; use crate::{ theme::{use_theme, Theme}, - utils::{mount_style, ComponentRef}, + utils::{mount_style, ssr_class, ComponentRef}, }; use leptos::*; pub use theme::InputTheme; @@ -50,6 +52,7 @@ pub fn Input( #[prop(optional)] input_prefix: Option<InputPrefix>, #[prop(optional)] input_suffix: Option<InputSuffix>, #[prop(optional)] comp_ref: ComponentRef<InputRef>, + #[prop(optional, into)] class: MaybeSignal<String>, ) -> impl IntoView { let theme = use_theme(Theme::light); mount_style("input", include_str!("./input.css")); @@ -123,8 +126,12 @@ pub fn Input( input_ref.on_load(move |_| { comp_ref.load(InputRef { input_ref }); }); + + let ssr_class = ssr_class(&class); view! { <div + class=ssr_class + use:dyn_classes=class class="thaw-input" class=("thaw-input--focus", move || is_focus.get()) class=("thaw-input--disabled", move || disabled.get()) diff --git a/src/input_number/mod.rs b/src/input_number/mod.rs index 0c32d61..b7c0920 100644 --- a/src/input_number/mod.rs +++ b/src/input_number/mod.rs @@ -11,6 +11,7 @@ pub fn InputNumber<T>( #[prop(into)] step: MaybeSignal<T>, #[prop(optional, into)] disabled: MaybeSignal<bool>, #[prop(optional, into)] invalid: MaybeSignal<bool>, + #[prop(optional, into)] class: MaybeSignal<String>, ) -> impl IntoView where T: Add<Output = T> + Sub<Output = T>, @@ -46,7 +47,7 @@ where value.set(value.get_untracked() - step.get_untracked()); }); view! { - <Input value=input_value allow_value placeholder disabled invalid> + <Input class value=input_value allow_value placeholder disabled invalid> <InputSuffix slot> <Button disabled variant=ButtonVariant::Link on_click=sub> <Icon icon=Icon::from(AiIcon::AiMinusOutlined) style="font-size: 18px"/> diff --git a/src/menu/menu_group.rs b/src/menu/menu_group.rs index d4a5260..017e182 100644 --- a/src/menu/menu_group.rs +++ b/src/menu/menu_group.rs @@ -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::*; #[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")); let theme = use_theme(Theme::light); let css_vars = create_memo(move |_| { @@ -12,8 +22,14 @@ pub fn MenuGroup(#[prop(into)] label: String, children: Children) -> impl IntoVi }); css_vars }); + let ssr_class = ssr_class(&class); 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} </div> {children()} diff --git a/src/menu/menu_item.rs b/src/menu/menu_item.rs index e4fce27..9774963 100644 --- a/src/menu/menu_item.rs +++ b/src/menu/menu_item.rs @@ -1,11 +1,19 @@ 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::*; #[component] pub fn MenuItem( #[prop(into)] key: MaybeSignal<String>, #[prop(into)] label: MaybeSignal<String>, + #[prop(optional, into)] class: MaybeSignal<String>, ) -> impl IntoView { mount_style("menu-item", include_str!("./menu-item.css")); let theme = use_theme(Theme::light); @@ -32,9 +40,12 @@ pub fn MenuItem( }); css_vars }); + let ssr_class = ssr_class(&class); view! { <div class="thaw-menu-item"> <div + class=ssr_class + use:dyn_classes=class class="thaw-menu-item__content" class=("thaw-menu-item__content--selected", move || menu.0.get() == key.get()) on:click=on_click diff --git a/src/menu/mod.rs b/src/menu/mod.rs index 3e291d2..d8b09cf 100644 --- a/src/menu/mod.rs +++ b/src/menu/mod.rs @@ -2,16 +2,26 @@ mod menu_group; mod menu_item; mod theme; +use crate::utils::dyn_classes; +use crate::utils::ssr_class; + use leptos::*; pub use menu_group::MenuGroup; pub use menu_item::*; pub use theme::MenuTheme; #[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! { <Provider value=MenuInjection(value)> - <div class="thaw-menu">{children()}</div> + <div class=ssr_class use:dyn_classes=class class="thaw-menu"> + {children()} + </div> </Provider> } } diff --git a/src/mobile/nav_bar/mod.rs b/src/mobile/nav_bar/mod.rs index 3975587..ba589ee 100644 --- a/src/mobile/nav_bar/mod.rs +++ b/src/mobile/nav_bar/mod.rs @@ -1,10 +1,12 @@ mod theme; +#[cfg(not(feature = "ssr"))] +use crate::utils::dyn_classes; use crate::{ components::*, icon::*, use_theme, - utils::{mount_style, StoredMaybeSignal}, + utils::{mount_style, ssr_class, StoredMaybeSignal}, Theme, }; use leptos::*; @@ -18,6 +20,7 @@ pub fn NavBar( #[prop(optional, into)] on_click_left: Option<Callback<ev::MouseEvent>>, #[prop(optional, into)] right_text: MaybeSignal<String>, #[prop(optional, into)] on_click_right: Option<Callback<ev::MouseEvent>>, + #[prop(optional, into)] class: MaybeSignal<String>, ) -> impl IntoView { mount_style("nav-bar", include_str!("./nav-bar.css")); let theme = use_theme(Theme::light); @@ -45,8 +48,14 @@ pub fn NavBar( } }; + let ssr_class = ssr_class(&class); 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())> <Then slot> <div class="thaw-nav-bar__left" on:click=on_click_left> diff --git a/src/radio/mod.rs b/src/radio/mod.rs index 99fd1cf..c7fc6ce 100644 --- a/src/radio/mod.rs +++ b/src/radio/mod.rs @@ -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::*; #[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); mount_style("radio", include_str!("./radio.css")); @@ -16,8 +26,11 @@ pub fn Radio(#[prop(optional, into)] value: RwSignal<bool>, children: Children) css_vars }); + let ssr_class = ssr_class(&class); view! { <div + class=ssr_class + use:dyn_classes=class class="thaw-radio" class=("thaw-radio--checked", move || value.get()) style=move || css_vars.get() diff --git a/src/select/mod.rs b/src/select/mod.rs index 011fe62..7416693 100644 --- a/src/select/mod.rs +++ b/src/select/mod.rs @@ -1,9 +1,10 @@ mod theme; +use crate::utils::dyn_classes; use crate::{ components::{Binder, Follower, FollowerPlacement, FollowerWidth}, theme::use_theme, - utils::mount_style, + utils::{mount_style, ssr_class}, Theme, }; use leptos::*; @@ -20,6 +21,7 @@ pub struct SelectOption<T> { pub fn Select<T>( #[prop(optional, into)] value: RwSignal<Option<T>>, #[prop(optional, into)] options: MaybeSignal<Vec<SelectOption<T>>>, + #[prop(optional, into)] class: MaybeSignal<String>, ) -> impl IntoView where T: Eq + Hash + Clone + 'static, @@ -106,9 +108,12 @@ where .map_or(String::new(), |v| v.label.clone()), None => String::new(), }); + let ssr_class = ssr_class(&class); view! { <Binder target_ref=trigger_ref> <div + class=ssr_class + use:dyn_classes=class class="thaw-select" ref=trigger_ref on:click=show_menu diff --git a/src/slider/mod.rs b/src/slider/mod.rs index 17f8ba3..6ad6c73 100644 --- a/src/slider/mod.rs +++ b/src/slider/mod.rs @@ -1,7 +1,14 @@ mod slider_label; 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 web_sys::DomRect; @@ -13,6 +20,7 @@ pub fn Slider( #[prop(optional, into)] value: RwSignal<f64>, #[prop(default = MaybeSignal::Static(100f64), into)] max: MaybeSignal<f64>, #[prop(optional, into)] step: MaybeSignal<f64>, + #[prop(optional, into)] class: MaybeSignal<String>, #[prop(optional)] children: Option<Children>, ) -> impl IntoView { mount_style("slider", include_str!("./slider.css")); @@ -110,8 +118,15 @@ pub fn Slider( }); on_cleanup(move || on_mouse_move.remove()); + let ssr_class = ssr_class(&class); 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__fill" @@ -126,6 +141,7 @@ pub fn Slider( class="thaw-slider-handle" style=move || { format!("left: {}%", percentage.get()) } ></div> + </div> } } diff --git a/src/space/mod.rs b/src/space/mod.rs index 33857e9..1c3a2d5 100644 --- a/src/space/mod.rs +++ b/src/space/mod.rs @@ -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::*; #[derive(Default)] @@ -16,6 +18,7 @@ pub enum SpaceGap { pub fn Space( #[prop(optional)] gap: SpaceGap, #[prop(optional)] vertical: bool, + #[prop(optional, into)] class: MaybeSignal<String>, children: Children, ) -> impl IntoView { mount_style("space", include_str!("./space.css")); @@ -27,8 +30,11 @@ pub fn Space( SpaceGap::WH(width, height) => format!("{width}px {height}px"), }; + let ssr_class = ssr_class(&class); view! { <div + class=ssr_class + use:dyn_classes=class class="thaw-space" style:gap=gap style:flex-direction=if vertical { "column" } else { "row" } diff --git a/src/switch/mod.rs b/src/switch/mod.rs index 1f6aaac..52e26f8 100644 --- a/src/switch/mod.rs +++ b/src/switch/mod.rs @@ -1,11 +1,20 @@ 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::*; pub use theme::SwitchTheme; #[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")); let theme = use_theme(Theme::light); let css_vars = create_memo(move |_| { @@ -22,8 +31,11 @@ pub fn Switch(#[prop(optional, into)] value: RwSignal<bool>) -> impl IntoView { }); css_vars }); + let ssr_class = ssr_class(&class); view! { <div + class=ssr_class + use:dyn_classes=class class="thaw-switch" class=("thaw-switch--active", move || value.get()) style=move || css_vars.get() diff --git a/src/table/mod.rs b/src/table/mod.rs index f18bd43..07367ce 100644 --- a/src/table/mod.rs +++ b/src/table/mod.rs @@ -1,6 +1,12 @@ 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::*; pub use theme::TableTheme; @@ -8,6 +14,7 @@ pub use theme::TableTheme; pub fn Table( #[prop(optional, into)] style: MaybeSignal<String>, #[prop(default=true.into(), into)] single_row: MaybeSignal<bool>, + #[prop(optional, into)] class: MaybeSignal<String>, #[prop(optional, into)] single_column: MaybeSignal<bool>, children: Children, ) -> impl IntoView { @@ -36,8 +43,11 @@ pub fn Table( css_vars }); + let ssr_class = ssr_class(&class); view! { <table + class=ssr_class + use:dyn_classes=class class="thaw-table" class=("thaw-table--single-row", move || single_row.get()) class=("thaw-table--single-column", move || single_column.get()) diff --git a/src/tabs/mod.rs b/src/tabs/mod.rs index 71ba144..f9fbd81 100644 --- a/src/tabs/mod.rs +++ b/src/tabs/mod.rs @@ -1,12 +1,22 @@ 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::*; pub use tab::*; #[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")); 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, tab_options_vec, }> - <TabsInner value tab_options_vec children/> + <TabsInner class value tab_options_vec children/> </Provider> } } @@ -24,6 +34,7 @@ pub fn Tabs(#[prop(optional, into)] value: RwSignal<String>, children: Children) fn TabsInner( value: RwSignal<String>, tab_options_vec: RwSignal<Vec<TabOption>>, + #[prop(optional, into)] class: MaybeSignal<String>, children: Children, ) -> impl IntoView { mount_style("tabs", include_str!("./tabs.css")); @@ -50,8 +61,9 @@ fn TabsInner( let label_list_ref = create_node_ref::<html::Div>(); let children = children(); + let ssr_class = ssr_class(&class); 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> <For each=move || tab_options_vec.get() diff --git a/src/tabs/tab.rs b/src/tabs/tab.rs index d2fbe27..760ee5f 100644 --- a/src/tabs/tab.rs +++ b/src/tabs/tab.rs @@ -1,5 +1,7 @@ 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::*; #[derive(Clone)] @@ -12,6 +14,7 @@ pub(crate) struct TabOption { pub fn Tab( #[prop(into)] key: String, #[prop(into)] label: String, + #[prop(optional, into)] class: MaybeSignal<String>, children: Children, ) -> impl IntoView { mount_style("tab", include_str!("./tab.css")); @@ -20,8 +23,14 @@ pub fn Tab( key: key.clone(), label, }); + let ssr_class = ssr_class(&class); 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()} </div> } diff --git a/src/tag/mod.rs b/src/tag/mod.rs index 38a3ce5..5e3c448 100644 --- a/src/tag/mod.rs +++ b/src/tag/mod.rs @@ -1,6 +1,12 @@ 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::*; pub use theme::TagTheme; @@ -43,6 +49,7 @@ impl TagVariant { #[component] pub fn Tag( #[prop(optional, into)] variant: MaybeSignal<TagVariant>, + #[prop(optional, into)] class: MaybeSignal<String>, children: Children, ) -> impl IntoView { mount_style("tag", include_str!("./tag.css")); @@ -66,8 +73,9 @@ pub fn Tag( }); css_vars }); + let ssr_class = ssr_class(&class); 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> </div> } diff --git a/src/time_picker/mod.rs b/src/time_picker/mod.rs index 5468560..1dcc6d1 100644 --- a/src/time_picker/mod.rs +++ b/src/time_picker/mod.rs @@ -11,7 +11,10 @@ use leptos::*; pub use theme::TimePickerTheme; #[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")); let time_picker_ref = create_node_ref::<html::Div>(); let panel_ref = ComponentRef::<PanelRef>::default(); @@ -70,7 +73,7 @@ pub fn TimePicker(#[prop(optional, into)] value: RwSignal<Option<NaiveTime>>) -> view! { <Binder target_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> <Icon icon=Icon::from(AiIcon::AiClockCircleOutlined) diff --git a/src/typography/text.rs b/src/typography/text.rs index bc49d0e..160caa6 100644 --- a/src/typography/text.rs +++ b/src/typography/text.rs @@ -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::*; #[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")); let theme = use_theme(Theme::light); let css_vars = create_memo(move |_| { @@ -16,14 +26,25 @@ pub fn Text(#[prop(optional)] code: bool, children: Children) -> impl IntoView { css_vars }); + let ssr_class = ssr_class(&class); if code { 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()} </code> } .into_any() } 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() } }