feat: adds class prop

This commit is contained in:
luoxiao 2024-07-26 00:16:19 +08:00
parent f11efb4ef8
commit 1a001d5834
70 changed files with 307 additions and 210 deletions

View file

@ -1,10 +1,11 @@
use crate::AccordionInjection; use crate::AccordionInjection;
use leptos::{html, prelude::*}; use leptos::{html, prelude::*};
use thaw_components::CSSTransition; use thaw_components::CSSTransition;
use thaw_utils::{mount_style, update, with, StoredMaybeSignal}; use thaw_utils::{class_list, mount_style, update, with, StoredMaybeSignal};
#[component] #[component]
pub fn AccordionItem( pub fn AccordionItem(
#[prop(optional, into)] class: MaybeProp<String>,
/// Required value that identifies this item inside an Accordion component. /// Required value that identifies this item inside an Accordion component.
#[prop(into)] #[prop(into)]
value: MaybeSignal<String>, value: MaybeSignal<String>,
@ -41,7 +42,7 @@ pub fn AccordionItem(
}; };
view! { view! {
<div class="thaw-accordion-item"> <div class=class_list!["thaw-accordion-item", class]>
<div class="thaw-accordion-header"> <div class="thaw-accordion-header">
<button <button
class="thaw-accordion-header__button" class="thaw-accordion-header__button"

View file

@ -4,10 +4,11 @@ pub use accordion_item::*;
use leptos::{context::Provider, prelude::*}; use leptos::{context::Provider, prelude::*};
use std::collections::HashSet; use std::collections::HashSet;
use thaw_utils::Model; use thaw_utils::{class_list, Model};
#[component] #[component]
pub fn Accordion( pub fn Accordion(
#[prop(optional, into)] class: MaybeProp<String>,
/// Controls the state of the panel. /// Controls the state of the panel.
#[prop(optional, into)] #[prop(optional, into)]
open_items: Model<HashSet<String>>, open_items: Model<HashSet<String>>,
@ -25,7 +26,7 @@ pub fn Accordion(
collapsible, collapsible,
multiple multiple
}> }>
<div class="thaw-accordion"> <div class=class_list!["thaw-accordion", class]>
{children()} {children()}
</div> </div>
</Provider> </Provider>

View file

@ -1,16 +1,16 @@
use super::AnchorInjection; use super::AnchorInjection;
use leptos::{html, prelude::*}; use leptos::{html, prelude::*};
use thaw_components::OptionComp; use thaw_components::OptionComp;
use thaw_utils::{class_list, OptionalProp, StoredMaybeSignal}; use thaw_utils::{class_list, StoredMaybeSignal};
#[component] #[component]
pub fn AnchorLink( pub fn AnchorLink(
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
#[prop(into)] title: MaybeSignal<String>, #[prop(into)] title: MaybeSignal<String>,
#[prop(into)] href: String, #[prop(into)] href: String,
#[prop(optional)] children: Option<Children>, #[prop(optional)] children: Option<Children>,
) -> impl IntoView { ) -> impl IntoView {
let anchor = AnchorInjection::use_(); let anchor = AnchorInjection::expect_context();
let title: StoredMaybeSignal<_> = title.into(); let title: StoredMaybeSignal<_> = title.into();
let title_ref = NodeRef::<html::A>::new(); let title_ref = NodeRef::<html::A>::new();
@ -61,9 +61,7 @@ pub fn AnchorLink(
view! { view! {
<div class=class_list![ <div class=class_list![
"thaw-anchor-link", ("thaw-anchor-link--active", move || is_active.get()), class.map(| c "thaw-anchor-link", ("thaw-anchor-link--active", move || is_active.get()), class]>
| move || c.get())
]>
<a <a
href=href href=href
class="thaw-anchor-link__title" class="thaw-anchor-link__title"

View file

@ -4,12 +4,12 @@ pub use anchor_link::AnchorLink;
use leptos::{context::Provider, ev, html, prelude::*}; use leptos::{context::Provider, ev, html, prelude::*};
use std::cmp::Ordering; use std::cmp::Ordering;
use thaw_utils::{add_event_listener_with_bool, class_list, mount_style, throttle, OptionalProp}; use thaw_utils::{add_event_listener_with_bool, class_list, mount_style, throttle};
use web_sys::{DomRect, Element}; use web_sys::{DomRect, Element};
#[component] #[component]
pub fn Anchor( pub fn Anchor(
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
#[prop(into, optional)] offset_target: Option<OffsetTarget>, #[prop(into, optional)] offset_target: Option<OffsetTarget>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
@ -87,7 +87,7 @@ pub fn Anchor(
}); });
view! { view! {
<div <div
class=class_list!["thaw-anchor", class.map(| c | move || c.get())] class=class_list!["thaw-anchor", class]
node_ref=anchor_ref node_ref=anchor_ref
> >
<div class="thaw-anchor-rail"> <div class="thaw-anchor-rail">
@ -122,7 +122,7 @@ pub(crate) struct AnchorInjection {
impl Copy for AnchorInjection {} impl Copy for AnchorInjection {}
impl AnchorInjection { impl AnchorInjection {
pub fn use_() -> Self { pub fn expect_context() -> Self {
expect_context() expect_context()
} }

View file

@ -1,9 +1,14 @@
use super::AutoCompleteInjection; use super::AutoCompleteInjection;
use crate::combobox::listbox::ListboxInjection; use crate::combobox::listbox::ListboxInjection;
use leptos::prelude::*; use leptos::prelude::*;
use thaw_utils::class_list;
#[component] #[component]
pub fn AutoCompleteOption(value: String, children: Children) -> impl IntoView { pub fn AutoCompleteOption(
#[prop(optional, into)] class: MaybeProp<String>,
value: String,
children: Children,
) -> impl IntoView {
let auto_complete = AutoCompleteInjection::expect_context(); let auto_complete = AutoCompleteInjection::expect_context();
let listbox = ListboxInjection::expect_context(); let listbox = ListboxInjection::expect_context();
let is_selected = Memo::new({ let is_selected = Memo::new({
@ -23,7 +28,7 @@ pub fn AutoCompleteOption(value: String, children: Children) -> impl IntoView {
view! { view! {
<div <div
class="thaw-auto-complete-option" class=class_list!["thaw-auto-complete-option", class]
role="option" role="option"
id=id id=id
aria-selected=move || if is_selected.get() { "true" } else { "false" } aria-selected=move || if is_selected.get() { "true" } else { "false" }

View file

@ -30,7 +30,7 @@ pub fn AutoComplete(
#[prop(optional, into)] blur_after_select: MaybeSignal<bool>, #[prop(optional, into)] blur_after_select: MaybeSignal<bool>,
#[prop(optional, into)] on_select: Option<BoxOneCallback<String>>, #[prop(optional, into)] on_select: Option<BoxOneCallback<String>>,
#[prop(optional, into)] disabled: MaybeSignal<bool>, #[prop(optional, into)] disabled: MaybeSignal<bool>,
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional)] auto_complete_prefix: Option<AutoCompletePrefix>, #[prop(optional)] auto_complete_prefix: Option<AutoCompletePrefix>,
#[prop(optional)] auto_complete_suffix: Option<AutoCompleteSuffix>, #[prop(optional)] auto_complete_suffix: Option<AutoCompleteSuffix>,
#[prop(optional)] comp_ref: ComponentRef<AutoCompleteRef>, #[prop(optional)] comp_ref: ComponentRef<AutoCompleteRef>,
@ -98,7 +98,7 @@ pub fn AutoComplete(
view! { view! {
<Binder target_ref=auto_complete_ref> <Binder target_ref=auto_complete_ref>
<div <div
class=class_list!["thaw-auto-complete", class.map(| c | move || c.get())] class=class_list!["thaw-auto-complete", class]
node_ref=auto_complete_ref node_ref=auto_complete_ref
on:keydown=on_keydown on:keydown=on_keydown
> >

View file

@ -1,6 +1,6 @@
use leptos::prelude::*; use leptos::prelude::*;
use thaw_components::OptionComp; use thaw_components::OptionComp;
use thaw_utils::{class_list, mount_style, OptionalProp, StoredMaybeSignal}; use thaw_utils::{class_list, mount_style, StoredMaybeSignal};
#[component] #[component]
pub fn Avatar( pub fn Avatar(
@ -19,7 +19,7 @@ pub fn Avatar(
/// Size of the avatar in pixels. /// Size of the avatar in pixels.
#[prop(optional, into)] #[prop(optional, into)]
size: Option<MaybeSignal<u8>>, size: Option<MaybeSignal<u8>>,
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
) -> impl IntoView { ) -> impl IntoView {
mount_style("avatar", include_str!("./avatar.css")); mount_style("avatar", include_str!("./avatar.css"));
@ -48,7 +48,7 @@ pub fn Avatar(
view! { view! {
<span <span
class=class_list!["thaw-avatar", move || format!("thaw-avatar--{}", shape.get().as_str()), class.map(| c | move || c.get())] class=class_list!["thaw-avatar", move || format!("thaw-avatar--{}", shape.get().as_str()), class]
style=move || style().unwrap_or_default() style=move || style().unwrap_or_default()
role="img" role="img"
aria-label=move || name.as_ref().map(|n| n.get()) aria-label=move || name.as_ref().map(|n| n.get())

View file

@ -3,19 +3,19 @@ use leptos::{either::Either, ev, html, prelude::*};
use thaw_components::{CSSTransition, Teleport}; use thaw_components::{CSSTransition, Teleport};
use thaw_utils::{ use thaw_utils::{
add_event_listener, class_list, get_scroll_parent, mount_style, BoxCallback, add_event_listener, class_list, get_scroll_parent, mount_style, BoxCallback,
EventListenerHandle, OptionalProp, EventListenerHandle,
}; };
#[component] #[component]
pub fn BackTop( pub fn BackTop(
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
#[prop(default=40.into(), into)] right: MaybeSignal<i32>, #[prop(default=40.into(), into)] right: MaybeSignal<i32>,
#[prop(default=40.into(), into)] bottom: MaybeSignal<i32>, #[prop(default=40.into(), into)] bottom: MaybeSignal<i32>,
#[prop(default=180.into(), into)] visibility_height: MaybeSignal<i32>, #[prop(default=180.into(), into)] visibility_height: MaybeSignal<i32>,
#[prop(optional)] children: Option<Children>, #[prop(optional)] children: Option<Children>,
) -> impl IntoView { ) -> impl IntoView {
mount_style("back-top", include_str!("./back-top.css")); mount_style("back-top", include_str!("./back-top.css"));
let config_provider = ConfigInjection::use_(); let config_provider = ConfigInjection::expect_context();
let placeholder_ref = NodeRef::<html::Div>::new(); let placeholder_ref = NodeRef::<html::Div>::new();
let back_top_ref = NodeRef::<html::Div>::new(); let back_top_ref = NodeRef::<html::Div>::new();
let is_show_back_top = RwSignal::new(false); let is_show_back_top = RwSignal::new(false);
@ -85,7 +85,7 @@ pub fn BackTop(
let:display let:display
> >
<div <div
class=class_list!["thaw-config-provider thaw-back-top", class.map(| c | move || c.get())] class=class_list!["thaw-config-provider thaw-back-top", class]
data-thaw-id=config_provider.id().clone() data-thaw-id=config_provider.id().clone()
node_ref=back_top_ref node_ref=back_top_ref
style=move || { style=move || {

View file

@ -1,16 +1,16 @@
use leptos::prelude::*; use leptos::prelude::*;
use thaw_utils::{class_list, mount_style, OptionalProp}; use thaw_utils::{class_list, mount_style};
#[component] #[component]
pub fn ButtonGroup( pub fn ButtonGroup(
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional)] vertical: bool, #[prop(optional)] vertical: bool,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
mount_style("button-group", include_str!("./button-group.css")); mount_style("button-group", include_str!("./button-group.css"));
view! { view! {
<div <div
class=class_list!["thaw-button-group", class.map(| c | move || c.get())] class=class_list!["thaw-button-group", class]
class=("thaw-button-group--vertical", vertical) class=("thaw-button-group--vertical", vertical)
> >
{children()} {children()}

View file

@ -4,7 +4,7 @@ pub use button_group::ButtonGroup;
use crate::icon::Icon; use crate::icon::Icon;
use leptos::{either::Either, ev, prelude::*}; use leptos::{either::Either, ev, prelude::*};
use thaw_utils::{class_list, mount_style, BoxOneCallback, OptionalMaybeSignal, OptionalProp}; use thaw_utils::{class_list, mount_style, BoxOneCallback, OptionalMaybeSignal};
#[derive(Default, PartialEq, Clone, Copy)] #[derive(Default, PartialEq, Clone, Copy)]
pub enum ButtonAppearance { pub enum ButtonAppearance {
@ -64,7 +64,7 @@ impl ButtonSize {
#[component] #[component]
pub fn Button( pub fn Button(
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional, into)] appearance: MaybeSignal<ButtonAppearance>, #[prop(optional, into)] appearance: MaybeSignal<ButtonAppearance>,
#[prop(optional, into)] shape: MaybeSignal<ButtonShape>, #[prop(optional, into)] shape: MaybeSignal<ButtonShape>,
#[prop(optional, into)] size: MaybeSignal<ButtonSize>, #[prop(optional, into)] size: MaybeSignal<ButtonSize>,
@ -102,7 +102,7 @@ pub fn Button(
move || format!("thaw-button--{}", size.get().as_str()), move || format!("thaw-button--{}", size.get().as_str()),
move || format!("thaw-button--{}", appearance.get().as_str()), move || format!("thaw-button--{}", appearance.get().as_str()),
move || format!("thaw-button--{}", shape.get().as_str()), move || format!("thaw-button--{}", shape.get().as_str()),
class.map(| c | move || c.get()) class
] ]
disabled=move || disabled.get().then_some("") disabled=move || disabled.get().then_some("")

View file

@ -2,11 +2,11 @@ use crate::{Button, ButtonGroup};
use chrono::{Datelike, Days, Local, Month, Months, NaiveDate}; use chrono::{Datelike, Days, Local, Month, Months, NaiveDate};
use leptos::prelude::*; use leptos::prelude::*;
use std::ops::Deref; use std::ops::Deref;
use thaw_utils::{class_list, mount_style, OptionModel, OptionalProp}; use thaw_utils::{class_list, mount_style, OptionModel};
#[component] #[component]
pub fn Calendar( pub fn Calendar(
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional, into)] value: OptionModel<NaiveDate>, #[prop(optional, into)] value: OptionModel<NaiveDate>,
) -> impl IntoView { ) -> impl IntoView {
mount_style("calendar", include_str!("./calendar.css")); mount_style("calendar", include_str!("./calendar.css"));
@ -87,7 +87,7 @@ pub fn Calendar(
view! { view! {
<div <div
class=class_list!["thaw-calendar", class.map(| c | move || c.get())] class=class_list!["thaw-calendar", class]
> >
<div class="thaw-calendar__header"> <div class="thaw-calendar__header">
<span class="thaw-calendar__header-title"> <span class="thaw-calendar__header-title">

View file

@ -1,11 +1,14 @@
use leptos::prelude::*; use leptos::prelude::*;
use thaw_utils::mount_style; use thaw_utils::{class_list, mount_style};
#[component] #[component]
pub fn CardFooter(children: Children) -> impl IntoView { pub fn CardFooter(
#[prop(optional, into)] class: MaybeProp<String>,
children: Children,
) -> impl IntoView {
mount_style("card-footer", include_str!("./card-footer.css")); mount_style("card-footer", include_str!("./card-footer.css"));
view! { view! {
<div class="thaw-card-footer"> <div class=class_list!["thaw-card-footer", class]>
{children()} {children()}
</div> </div>
} }

View file

@ -1,16 +1,17 @@
use leptos::prelude::*; use leptos::prelude::*;
use thaw_components::OptionComp; use thaw_components::OptionComp;
use thaw_utils::mount_style; use thaw_utils::{class_list, mount_style};
#[component] #[component]
pub fn CardHeader( pub fn CardHeader(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional)] card_header_description: Option<CardHeaderDescription>, #[prop(optional)] card_header_description: Option<CardHeaderDescription>,
#[prop(optional)] card_header_action: Option<CardHeaderAction>, #[prop(optional)] card_header_action: Option<CardHeaderAction>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
mount_style("card-header", include_str!("./card-header.css")); mount_style("card-header", include_str!("./card-header.css"));
view! { view! {
<div class="thaw-card-header"> <div class=class_list!["thaw-card-header", class]>
<div class="thaw-card-header__header"> <div class="thaw-card-header__header">
{children()} {children()}
</div> </div>

View file

@ -1,9 +1,13 @@
use leptos::prelude::*; use leptos::prelude::*;
use thaw_utils::class_list;
#[component] #[component]
pub fn CardPreview(children: Children) -> impl IntoView { pub fn CardPreview(
#[prop(optional, into)] class: MaybeProp<String>,
children: Children,
) -> impl IntoView {
view! { view! {
<div class="thaw-card-preview" style="position: relative"> <div class=class_list!["thaw-card-preview", class] style="position: relative">
{children()} {children()}
</div> </div>
} }

View file

@ -7,18 +7,15 @@ pub use card_header::*;
pub use card_preview::*; pub use card_preview::*;
use leptos::prelude::*; use leptos::prelude::*;
use thaw_utils::{class_list, mount_style, OptionalProp}; use thaw_utils::{class_list, mount_style};
#[component] #[component]
pub fn Card( pub fn Card(#[prop(optional, into)] class: MaybeProp<String>, children: Children) -> impl IntoView {
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>,
children: Children,
) -> impl IntoView {
mount_style("card", include_str!("./card.css")); mount_style("card", include_str!("./card.css"));
view! { view! {
<div <div
class=class_list!["thaw-card", class.map(| c | move || c.get())] class=class_list!["thaw-card", class]
role="group" role="group"
> >
{children()} {children()}

View file

@ -1,15 +1,16 @@
use leptos::{context::Provider, prelude::*}; use leptos::{context::Provider, prelude::*};
use std::collections::HashSet; use std::collections::HashSet;
use thaw_utils::Model; use thaw_utils::{class_list, Model};
#[component] #[component]
pub fn CheckboxGroup( pub fn CheckboxGroup(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional, into)] value: Model<HashSet<String>>, #[prop(optional, into)] value: Model<HashSet<String>>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
view! { view! {
<Provider value=CheckboxGroupInjection(value)> <Provider value=CheckboxGroupInjection(value)>
<div class="thaw-checkbox-group" role="group"> <div class=class_list!["thaw-checkbox-group", class] role="group">
{children()} {children()}
</div> </div>
</Provider> </Provider>
@ -22,7 +23,7 @@ pub(crate) struct CheckboxGroupInjection(pub Model<HashSet<String>>);
impl Copy for CheckboxGroupInjection {} impl Copy for CheckboxGroupInjection {}
impl CheckboxGroupInjection { impl CheckboxGroupInjection {
pub fn use_() -> Option<Self> { pub fn use_context() -> Option<Self> {
use_context() use_context()
} }
} }

View file

@ -4,12 +4,12 @@ pub use checkbox_group::CheckboxGroup;
use checkbox_group::CheckboxGroupInjection; use checkbox_group::CheckboxGroupInjection;
use leptos::{html, prelude::*}; use leptos::{html, prelude::*};
use thaw_utils::{class_list, mount_style, Model, OptionalProp}; use thaw_utils::{class_list, mount_style, Model};
#[component] #[component]
pub fn Checkbox( pub fn Checkbox(
#[prop(optional, into)] checked: Model<bool>, #[prop(optional, into)] checked: Model<bool>,
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional, into)] value: Option<String>, #[prop(optional, into)] value: Option<String>,
#[prop(optional, into)] label: MaybeProp<String>, #[prop(optional, into)] label: MaybeProp<String>,
) -> impl IntoView { ) -> impl IntoView {
@ -17,7 +17,7 @@ pub fn Checkbox(
let id = uuid::Uuid::new_v4().to_string(); let id = uuid::Uuid::new_v4().to_string();
let input_ref = NodeRef::<html::Input>::new(); let input_ref = NodeRef::<html::Input>::new();
let group = CheckboxGroupInjection::use_(); let group = CheckboxGroupInjection::use_context();
let item_value = StoredValue::new(value); let item_value = StoredValue::new(value);
let group_checked = Memo::new(move |_| { let group_checked = Memo::new(move |_| {
@ -58,8 +58,8 @@ pub fn Checkbox(
view! { view! {
<span <span
class=class_list![ class=class_list![
"thaw-checkbox", ("thaw-checkbox--checked", checked), class.map(| c | "thaw-checkbox", ("thaw-checkbox--checked", checked),
move || c.get()) class
] ]
> >
<input <input

View file

@ -1,17 +1,15 @@
use leptos::prelude::*; use leptos::prelude::*;
use thaw_utils::{class_list, mount_style, OptionalProp}; use thaw_utils::{class_list, mount_style};
#[component] #[component]
pub fn Code( pub fn Code(
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional, into)] text: Option<String>, #[prop(optional, into)] text: Option<String>,
#[prop(optional, into)] inner_html: Option<String>, #[prop(optional, into)] inner_html: Option<String>,
) -> impl IntoView { ) -> impl IntoView {
mount_style("code", include_str!("./code.css")); mount_style("code", include_str!("./code.css"));
view! { view! {
<code class=class_list![ <code class=class_list!["thaw-code", class]>
"thaw-code", class.map(| c | move || c.get())
]>
{if let Some(inner_html) = inner_html { {if let Some(inner_html) = inner_html {
view! { <pre inner_html=inner_html></pre> }.into_any().into() view! { <pre inner_html=inner_html></pre> }.into_any().into()

View file

@ -15,7 +15,7 @@ pub fn ColorPicker(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
) -> impl IntoView { ) -> impl IntoView {
mount_style("color-picker", include_str!("./color-picker.css")); mount_style("color-picker", include_str!("./color-picker.css"));
let config_provider = ConfigInjection::use_(); let config_provider = ConfigInjection::expect_context();
let hue = RwSignal::new(0f32); let hue = RwSignal::new(0f32);
let sv = RwSignal::new((0f32, 0f32)); let sv = RwSignal::new((0f32, 0f32));
let label = RwSignal::new(String::new()); let label = RwSignal::new(String::new());

View file

@ -3,10 +3,11 @@ use crate::_aria::use_active_descendant;
use leptos::{context::Provider, ev, html, prelude::*}; use leptos::{context::Provider, ev, html, prelude::*};
use std::collections::HashMap; use std::collections::HashMap;
use thaw_components::{Binder, Follower, FollowerPlacement, FollowerWidth}; use thaw_components::{Binder, Follower, FollowerPlacement, FollowerWidth};
use thaw_utils::{add_event_listener, mount_style, Model, VecModel}; use thaw_utils::{add_event_listener, class_list, mount_style, Model, VecModel};
#[component] #[component]
pub fn Combobox( pub fn Combobox(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional, into)] value: Model<String>, #[prop(optional, into)] value: Model<String>,
#[prop(optional, into)] selected_options: VecModel<String>, #[prop(optional, into)] selected_options: VecModel<String>,
#[prop(optional)] clearable: bool, #[prop(optional)] clearable: bool,
@ -147,7 +148,7 @@ pub fn Combobox(
view! { view! {
<Binder target_ref=trigger_ref> <Binder target_ref=trigger_ref>
<div <div
class="thaw-combobox" class=class_list!["thaw-combobox", class]
node_ref=trigger_ref node_ref=trigger_ref
> >
<input <input

View file

@ -6,6 +6,7 @@ use thaw_utils::class_list;
#[component] #[component]
pub fn ComboboxOption( pub fn ComboboxOption(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional, into)] value: Option<String>, #[prop(optional, into)] value: Option<String>,
#[prop(into)] text: String, #[prop(into)] text: String,
#[prop(optional)] children: Option<Children>, #[prop(optional)] children: Option<Children>,
@ -42,7 +43,8 @@ pub fn ComboboxOption(
id=id id=id
class=class_list![ class=class_list![
"thaw-combobox-option", "thaw-combobox-option",
("thaw-combobox-option--selected", move || is_selected.get()) ("thaw-combobox-option--selected", move || is_selected.get()),
class
] ]
on:click=on_click on:click=on_click
> >

View file

@ -1,9 +1,10 @@
use crate::Theme; use crate::Theme;
use leptos::{context::Provider, prelude::*}; use leptos::{context::Provider, prelude::*};
use thaw_utils::{mount_dynamic_style, mount_style}; use thaw_utils::{class_list, mount_dynamic_style, mount_style};
#[component] #[component]
pub fn ConfigProvider( pub fn ConfigProvider(
#[prop(optional, into)] class: MaybeProp<String>,
/// Sets the theme used in a scope. /// Sets the theme used in a scope.
#[prop(optional, into)] #[prop(optional, into)]
theme: Option<RwSignal<Theme>>, theme: Option<RwSignal<Theme>>,
@ -46,7 +47,7 @@ pub fn ConfigProvider(
view! { view! {
<Provider value=config_injection> <Provider value=config_injection>
<div <div
class="thaw-config-provider" class=class_list!["thaw-config-provider", class]
data-thaw-id=id.get_value() data-thaw-id=id.get_value()
dir=move || dir.get().map(move |dir| dir.as_str()) dir=move || dir.get().map(move |dir| dir.as_str())
> >
@ -68,10 +69,6 @@ impl ConfigInjection {
&self.id &self.id
} }
pub fn use_() -> ConfigInjection {
expect_context()
}
pub fn expect_context() -> Self { pub fn expect_context() -> Self {
expect_context() expect_context()
} }

View file

@ -4,12 +4,12 @@ use chrono::NaiveDate;
use leptos::{html, prelude::*}; use leptos::{html, prelude::*};
use panel::{Panel, PanelRef}; use panel::{Panel, PanelRef};
use thaw_components::{Binder, Follower, FollowerPlacement}; use thaw_components::{Binder, Follower, FollowerPlacement};
use thaw_utils::{mount_style, now_date, ComponentRef, OptionModel, OptionalProp}; use thaw_utils::{class_list, mount_style, now_date, ComponentRef, OptionModel};
#[component] #[component]
pub fn DatePicker( pub fn DatePicker(
#[prop(optional, into)] value: OptionModel<NaiveDate>, #[prop(optional, into)] value: OptionModel<NaiveDate>,
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
) -> impl IntoView { ) -> impl IntoView {
mount_style("date-picker", include_str!("./date-picker.css")); mount_style("date-picker", include_str!("./date-picker.css"));
let date_picker_ref = NodeRef::<html::Div>::new(); let date_picker_ref = NodeRef::<html::Div>::new();
@ -67,8 +67,8 @@ pub fn DatePicker(
view! { view! {
<Binder target_ref=date_picker_ref> <Binder target_ref=date_picker_ref>
<div node_ref=date_picker_ref> <div node_ref=date_picker_ref class=class_list!["thaw-date-picker", class]>
<Input class value=show_date_text on_focus=open_panel on_blur=on_input_blur> <Input value=show_date_text on_focus=open_panel on_blur=on_input_blur>
<InputSuffix slot> <InputSuffix slot>
<Icon icon=icondata_ai::AiCalendarOutlined style="font-size: 18px"/> <Icon icon=icondata_ai::AiCalendarOutlined style="font-size: 18px"/>
</InputSuffix> </InputSuffix>

View file

@ -19,7 +19,7 @@ pub fn Panel(
#[prop(into)] is_show_panel: MaybeSignal<bool>, #[prop(into)] is_show_panel: MaybeSignal<bool>,
#[prop(optional)] comp_ref: ComponentRef<PanelRef>, #[prop(optional)] comp_ref: ComponentRef<PanelRef>,
) -> impl IntoView { ) -> impl IntoView {
let config_provider = ConfigInjection::use_(); let config_provider = ConfigInjection::expect_context();
let panel_ref = NodeRef::<html::Div>::new(); let panel_ref = NodeRef::<html::Div>::new();
#[cfg(any(feature = "csr", feature = "hydrate"))] #[cfg(any(feature = "csr", feature = "hydrate"))]
{ {

View file

@ -1,17 +1,18 @@
use crate::ConfigInjection; use crate::ConfigInjection;
use leptos::{context::Provider, ev, html, prelude::*}; use leptos::{context::Provider, ev, html, prelude::*};
use thaw_components::{CSSTransition, FocusTrap, Teleport}; use thaw_components::{CSSTransition, FocusTrap, Teleport};
use thaw_utils::{mount_style, Model}; use thaw_utils::{class_list, mount_style, Model};
#[component] #[component]
pub fn Dialog( pub fn Dialog(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(into)] open: Model<bool>, #[prop(into)] open: Model<bool>,
#[prop(default = true.into(), into)] mask_closeable: MaybeSignal<bool>, #[prop(default = true.into(), into)] mask_closeable: MaybeSignal<bool>,
#[prop(default = true, into)] close_on_esc: bool, #[prop(default = true, into)] close_on_esc: bool,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
mount_style("dialog", include_str!("./dialog.css")); mount_style("dialog", include_str!("./dialog.css"));
let config_provider = ConfigInjection::use_(); let config_provider = ConfigInjection::expect_context();
let mask_ref = NodeRef::<html::Div>::new(); let mask_ref = NodeRef::<html::Div>::new();
let on_mask_click = move |_| { let on_mask_click = move |_| {
@ -27,7 +28,7 @@ pub fn Dialog(
<Teleport immediate=open.signal()> <Teleport immediate=open.signal()>
<FocusTrap disabled=!close_on_esc active=open.signal() on_esc> <FocusTrap disabled=!close_on_esc active=open.signal() on_esc>
<div <div
class="thaw-config-provider thaw-dialog" class=class_list!["thaw-config-provider thaw-dialog", class]
data-thaw-id=config_provider.id().clone() data-thaw-id=config_provider.id().clone()
> >
<CSSTransition <CSSTransition

View file

@ -1,9 +1,13 @@
use leptos::prelude::*; use leptos::prelude::*;
use thaw_utils::class_list;
#[component] #[component]
pub fn DialogActions(children: Children) -> impl IntoView { pub fn DialogActions(
#[prop(optional, into)] class: MaybeProp<String>,
children: Children,
) -> impl IntoView {
view! { view! {
<div class="thaw-dialog-actions"> <div class=class_list!["thaw-dialog-actions", class]>
{children()} {children()}
</div> </div>
} }

View file

@ -1,9 +1,13 @@
use leptos::prelude::*; use leptos::prelude::*;
use thaw_utils::class_list;
#[component] #[component]
pub fn DialogBody(children: Children) -> impl IntoView { pub fn DialogBody(
#[prop(optional, into)] class: MaybeProp<String>,
children: Children,
) -> impl IntoView {
view! { view! {
<div class="thaw-dialog-body"> <div class=class_list!["thaw-dialog-body", class]>
{children()} {children()}
</div> </div>
} }

View file

@ -1,9 +1,13 @@
use leptos::prelude::*; use leptos::prelude::*;
use thaw_utils::class_list;
#[component] #[component]
pub fn DialogContent(children: Children) -> impl IntoView { pub fn DialogContent(
#[prop(optional, into)] class: MaybeProp<String>,
children: Children,
) -> impl IntoView {
view! { view! {
<h2 class="thaw-dialog-content"> <h2 class=class_list!["thaw-dialog-content", class]>
{children()} {children()}
</h2> </h2>
} }

View file

@ -1,9 +1,13 @@
use super::dialog::DialogInjection; use super::dialog::DialogInjection;
use leptos::{html, prelude::*}; use leptos::{html, prelude::*};
use thaw_components::CSSTransition; use thaw_components::CSSTransition;
use thaw_utils::class_list;
#[component] #[component]
pub fn DialogSurface(children: Children) -> impl IntoView { pub fn DialogSurface(
#[prop(optional, into)] class: MaybeProp<String>,
children: Children,
) -> impl IntoView {
let dialog = DialogInjection::expect_use(); let dialog = DialogInjection::expect_use();
let surface_ref = NodeRef::<html::Div>::new(); let surface_ref = NodeRef::<html::Div>::new();
@ -16,7 +20,7 @@ pub fn DialogSurface(children: Children) -> impl IntoView {
let:display let:display
> >
<div <div
class="thaw-dialog-surface" class=class_list!["thaw-dialog-surface", class]
node_ref=surface_ref node_ref=surface_ref
role="dialog" role="dialog"
aria-modal="true" aria-modal="true"

View file

@ -1,9 +1,13 @@
use leptos::prelude::*; use leptos::prelude::*;
use thaw_utils::class_list;
#[component] #[component]
pub fn DialogTitle(children: Children) -> impl IntoView { pub fn DialogTitle(
#[prop(optional, into)] class: MaybeProp<String>,
children: Children,
) -> impl IntoView {
view! { view! {
<h2 class="thaw-dialog-title"> <h2 class=class_list!["thaw-dialog-title", class]>
{children()} {children()}
</h2> </h2>
} }

View file

@ -1,10 +1,10 @@
use leptos::prelude::*; use leptos::prelude::*;
use thaw_components::OptionComp; use thaw_components::OptionComp;
use thaw_utils::{class_list, mount_style, OptionalProp}; use thaw_utils::{class_list, mount_style};
#[component] #[component]
pub fn Divider( pub fn Divider(
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional, into)] vertical: MaybeSignal<bool>, #[prop(optional, into)] vertical: MaybeSignal<bool>,
#[prop(optional)] children: Option<Children>, #[prop(optional)] children: Option<Children>,
) -> impl IntoView { ) -> impl IntoView {
@ -12,7 +12,7 @@ pub fn Divider(
view! { view! {
<div <div
class=class_list!["thaw-divider", ("thaw-divider--vertical", move || vertical.get()), class.map(| c | move || c.get())] class=class_list!["thaw-divider", ("thaw-divider--vertical", move || vertical.get()), class]
aria-orientation=move || if vertical.get() { "vertical" } else { "horizontal" } aria-orientation=move || if vertical.get() { "vertical" } else { "horizontal" }
role="separator" role="separator"
> >

View file

@ -1,11 +1,15 @@
use crate::Scrollbar; use crate::Scrollbar;
use leptos::prelude::*; use leptos::prelude::*;
use thaw_utils::class_list;
#[component] #[component]
pub fn DrawerBody(children: Children) -> impl IntoView { pub fn DrawerBody(
#[prop(optional, into)] class: MaybeProp<String>,
children: Children,
) -> impl IntoView {
view! { view! {
<Scrollbar> <Scrollbar>
<div class="thaw-drawer-body"> <div class=class_list!["thaw-drawer-body", class]>
{children()} {children()}
</div> </div>
</Scrollbar> </Scrollbar>

View file

@ -1,9 +1,13 @@
use leptos::prelude::*; use leptos::prelude::*;
use thaw_utils::class_list;
#[component] #[component]
pub fn DrawerHeader(children: Children) -> impl IntoView { pub fn DrawerHeader(
#[prop(optional, into)] class: MaybeProp<String>,
children: Children,
) -> impl IntoView {
view! { view! {
<header class="thaw-drawer-header"> <header class=class_list!["thaw-drawer-header", class]>
{children()} {children()}
</header> </header>
} }

View file

@ -1,13 +1,15 @@
use leptos::prelude::*; use leptos::prelude::*;
use thaw_components::OptionComp; use thaw_components::OptionComp;
use thaw_utils::class_list;
#[component] #[component]
pub fn DrawerHeaderTitle( pub fn DrawerHeaderTitle(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional)] drawer_header_title_action: Option<DrawerHeaderTitleAction>, #[prop(optional)] drawer_header_title_action: Option<DrawerHeaderTitleAction>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
view! { view! {
<div class="thaw-drawer-header-title"> <div class=class_list!["thaw-drawer-header-title", class]>
<h2 class="thaw-drawer-header-title__heading"> <h2 class="thaw-drawer-header-title__heading">
{children()} {children()}
</h2> </h2>

View file

@ -5,6 +5,7 @@ use thaw_utils::{class_list, mount_style, Model};
#[component] #[component]
pub fn InlineDrawer( pub fn InlineDrawer(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(into)] open: Model<bool>, #[prop(into)] open: Model<bool>,
#[prop(optional, into)] position: MaybeSignal<DrawerPosition>, #[prop(optional, into)] position: MaybeSignal<DrawerPosition>,
#[prop(optional, into)] size: MaybeSignal<DrawerSize>, #[prop(optional, into)] size: MaybeSignal<DrawerSize>,
@ -33,7 +34,8 @@ pub fn InlineDrawer(
<div <div
class=class_list![ class=class_list![
"thaw-inline-drawer", "thaw-inline-drawer",
move || format!("thaw-inline-drawer--position-{}", position.get().as_str()) move || format!("thaw-inline-drawer--position-{}", position.get().as_str()),
class
] ]
style=move || { style=move || {
let size = move || {format!("--thaw-drawer--size: {}", size.get().as_size_str(position))}; let size = move || {format!("--thaw-drawer--size: {}", size.get().as_size_str(position))};

View file

@ -6,6 +6,7 @@ use thaw_utils::{class_list, mount_style, use_lock_html_scroll, Model};
#[component] #[component]
pub fn OverlayDrawer( pub fn OverlayDrawer(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(into)] open: Model<bool>, #[prop(into)] open: Model<bool>,
#[prop(default = true.into(), into)] mask_closeable: MaybeSignal<bool>, #[prop(default = true.into(), into)] mask_closeable: MaybeSignal<bool>,
#[prop(optional, into)] close_on_esc: bool, #[prop(optional, into)] close_on_esc: bool,
@ -16,7 +17,7 @@ pub fn OverlayDrawer(
mount_style("drawer", include_str!("./drawer.css")); mount_style("drawer", include_str!("./drawer.css"));
mount_style("overlay-drawer", include_str!("./overlay-drawer.css")); mount_style("overlay-drawer", include_str!("./overlay-drawer.css"));
let config_provider = ConfigInjection::use_(); let config_provider = ConfigInjection::expect_context();
let drawer_ref = NodeRef::<html::Div>::new(); let drawer_ref = NodeRef::<html::Div>::new();
let open_drawer: RwSignal<bool> = RwSignal::new(open.get_untracked()); let open_drawer: RwSignal<bool> = RwSignal::new(open.get_untracked());
let is_lock = RwSignal::new(open.get_untracked()); let is_lock = RwSignal::new(open.get_untracked());
@ -45,7 +46,7 @@ pub fn OverlayDrawer(
view! { view! {
<Teleport immediate=open.signal()> <Teleport immediate=open.signal()>
<FocusTrap disabled=!close_on_esc active=open.signal() on_esc> <FocusTrap disabled=!close_on_esc active=open.signal() on_esc>
<div class="thaw-config-provider thaw-overlay-drawer-container" data-thaw-id=config_provider.id().clone()> <div class=class_list!["thaw-config-provider thaw-overlay-drawer-container", class] data-thaw-id=config_provider.id().clone()>
<CSSTransition <CSSTransition
node_ref=mask_ref node_ref=mask_ref
appear=open.get_untracked() appear=open.get_untracked()

View file

@ -1,12 +1,12 @@
use super::use_grid; use super::use_grid;
use leptos::prelude::*; use leptos::prelude::*;
use thaw_utils::{class_list, OptionalProp}; use thaw_utils::class_list;
#[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: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
let grid = use_grid(); let grid = use_grid();
@ -37,7 +37,7 @@ pub fn GridItem(
view! { view! {
<div <div
class=class_list!["thaw-grid-item", class.map(| c | move || c.get())] class=class_list!["thaw-grid-item", class]
style=move || style.get() style=move || style.get()
> >
{children()} {children()}

View file

@ -2,14 +2,14 @@ mod grid_item;
pub use grid_item::*; pub use grid_item::*;
use leptos::{context::Provider, prelude::*}; use leptos::{context::Provider, prelude::*};
use thaw_utils::{class_list, OptionalProp}; use thaw_utils::class_list;
#[component] #[component]
pub fn Grid( 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: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
let style = Memo::new(move |_| { let style = Memo::new(move |_| {
@ -25,7 +25,7 @@ pub fn Grid(
view! { view! {
<Provider value=GridInjection::new(x_gap)> <Provider value=GridInjection::new(x_gap)>
<div <div
class=class_list!["thaw-grid", class.map(| c | move || c.get())] class=class_list!["thaw-grid", class]
style=move || style.get() style=move || style.get()
> >
{children()} {children()}

View file

@ -43,7 +43,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: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
// #[prop(attrs)] attrs: Vec<(&'static str, Attribute)>, // #[prop(attrs)] attrs: Vec<(&'static str, Attribute)>,
) -> impl IntoView { ) -> impl IntoView {
mount_style("input", include_str!("./input.css")); mount_style("input", include_str!("./input.css"));
@ -125,7 +125,7 @@ pub fn Input(
("thaw-input--prefix", prefix_if_), ("thaw-input--prefix", prefix_if_),
("thaw-input--suffix", suffix_if_), ("thaw-input--suffix", suffix_if_),
("thaw-input--disabled", move || disabled.get()), ("thaw-input--disabled", move || disabled.get()),
class.map(| c | move || c.get()) class
] ]
on:mousedown=on_mousedown on:mousedown=on_mousedown

View file

@ -1,9 +1,13 @@
use leptos::prelude::*; use leptos::prelude::*;
use thaw_utils::class_list;
#[component] #[component]
pub fn LayoutHeader(children: Children) -> impl IntoView { pub fn LayoutHeader(
#[prop(optional, into)] class: MaybeProp<String>,
children: Children,
) -> impl IntoView {
view! { view! {
<div class="thaw-layout-header"> <div class=class_list!["thaw-layout-header", class]>
{children()} {children()}
</div> </div>
} }

View file

@ -1,16 +1,17 @@
use crate::Scrollbar; use crate::Scrollbar;
use leptos::prelude::*; use leptos::prelude::*;
use thaw_utils::{mount_style, OptionalProp}; use thaw_utils::{class_list, mount_style};
#[component] #[component]
pub fn LayoutSider( pub fn LayoutSider(
#[prop(optional, into)] content_class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional, into)] content_style: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] content_class: MaybeProp<String>,
#[prop(optional, into)] content_style: MaybeProp<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
mount_style("layout-sider", include_str!("./layout-sider.css")); mount_style("layout-sider", include_str!("./layout-sider.css"));
view! { view! {
<div class="thaw-layout-sider"> <div class=class_list!["thaw-layout-sider", class]>
<Scrollbar content_class content_style> <Scrollbar content_class content_style>
{children()} {children()}
</Scrollbar> </Scrollbar>

View file

@ -6,7 +6,7 @@ pub use layout_sider::*;
use crate::Scrollbar; use crate::Scrollbar;
use leptos::prelude::*; use leptos::prelude::*;
use thaw_utils::{mount_style, OptionalProp}; use thaw_utils::{class_list, mount_style};
#[derive(Default, PartialEq)] #[derive(Default, PartialEq)]
pub enum LayoutPosition { pub enum LayoutPosition {
@ -26,8 +26,9 @@ impl LayoutPosition {
#[component] #[component]
pub fn Layout( pub fn Layout(
#[prop(optional, into)] content_class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional, into)] content_style: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] content_class: MaybeProp<String>,
#[prop(optional, into)] content_style: MaybeProp<String>,
#[prop(optional)] position: LayoutPosition, #[prop(optional)] position: LayoutPosition,
#[prop(optional, into)] has_sider: MaybeSignal<bool>, #[prop(optional, into)] has_sider: MaybeSignal<bool>,
children: Children, children: Children,
@ -42,14 +43,14 @@ pub fn Layout(
} }
}); });
view! { view! {
<div class=gen_class(position)> <div class=class_list![gen_class(position), class]>
<Scrollbar <Scrollbar
content_class content_class
content_style=Signal::derive(move || { content_style=Signal::derive(move || {
format!( format!(
"{} {}", "{} {}",
sider_style.get().unwrap_or_default(), sider_style.get().unwrap_or_default(),
content_style.as_ref().map_or(String::new(), |s| s.get()), content_style.get().unwrap_or_default(),
) )
}) })
> >

View file

@ -4,7 +4,7 @@ use crate::{
}; };
use leptos::prelude::*; use leptos::prelude::*;
use thaw_components::{Fallback, If, OptionComp, Then}; use thaw_components::{Fallback, If, OptionComp, Then};
use thaw_utils::{class_list, mount_style, OptionalMaybeSignal, OptionalProp}; use thaw_utils::{class_list, mount_style, OptionalMaybeSignal};
#[component] #[component]
pub fn MenuItem( pub fn MenuItem(
@ -12,7 +12,7 @@ pub fn MenuItem(
#[prop(into)] label: MaybeSignal<String>, #[prop(into)] label: MaybeSignal<String>,
#[prop(into)] key: MaybeSignal<String>, #[prop(into)] key: MaybeSignal<String>,
#[prop(optional, into)] disabled: MaybeSignal<bool>, #[prop(optional, into)] disabled: MaybeSignal<bool>,
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
) -> impl IntoView { ) -> impl IntoView {
mount_style("menu-item", include_str!("./menu-item.css")); mount_style("menu-item", include_str!("./menu-item.css"));
@ -35,7 +35,7 @@ pub fn MenuItem(
<div <div
class=class_list![ class=class_list![
"thaw-menu-item", ("thaw-menu-item--disabled", move || disabled.get()), "thaw-menu-item", ("thaw-menu-item--disabled", move || disabled.get()),
class.map(| c | move || c.get()) class
] ]
on:click=on_click on:click=on_click
> >

View file

@ -35,7 +35,7 @@ pub fn Menu(
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
mount_style("menu", include_str!("./menu.css")); mount_style("menu", include_str!("./menu.css"));
let config_provider = ConfigInjection::use_(); let config_provider = ConfigInjection::expect_context();
let menu_ref = NodeRef::<Div>::new(); let menu_ref = NodeRef::<Div>::new();
let target_ref = NodeRef::<Div>::new(); let target_ref = NodeRef::<Div>::new();

View file

@ -3,6 +3,7 @@ use thaw_utils::{class_list, mount_style, StoredMaybeSignal};
#[component] #[component]
pub fn MessageBar( pub fn MessageBar(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional, into)] layout: MaybeSignal<MessageBarLayout>, #[prop(optional, into)] layout: MaybeSignal<MessageBarLayout>,
#[prop(optional, into)] intent: MaybeSignal<MessageBarIntent>, #[prop(optional, into)] intent: MaybeSignal<MessageBarIntent>,
children: Children, children: Children,
@ -15,7 +16,8 @@ pub fn MessageBar(
class=class_list![ class=class_list![
"thaw-message-bar", "thaw-message-bar",
move || format!("thaw-message-bar--{}", intent.get().as_str()), move || format!("thaw-message-bar--{}", intent.get().as_str()),
move || format!("thaw-message-bar--{}", layout.get().as_str()) move || format!("thaw-message-bar--{}", layout.get().as_str()),
class
] ]
role="group" role="group"
> >

View file

@ -1,9 +1,13 @@
use leptos::prelude::*; use leptos::prelude::*;
use thaw_utils::class_list;
#[component] #[component]
pub fn MessageBarBody(children: Children) -> impl IntoView { pub fn MessageBarBody(
#[prop(optional, into)] class: MaybeProp<String>,
children: Children,
) -> impl IntoView {
view! { view! {
<div class="thaw-message-bar-body"> <div class=class_list!["thaw-message-bar-body", class]>
{children()} {children()}
</div> </div>
} }

View file

@ -1,9 +1,13 @@
use leptos::prelude::*; use leptos::prelude::*;
use thaw_utils::class_list;
#[component] #[component]
pub fn MessageBarTitle(children: Children) -> impl IntoView { pub fn MessageBarTitle(
#[prop(optional, into)] class: MaybeProp<String>,
children: Children,
) -> impl IntoView {
view! { view! {
<span class="thaw-message-bar-title"> <span class=class_list!["thaw-message-bar-title", class]>
{children()} {children()}
</span> </span>
} }

View file

@ -1,10 +1,11 @@
use crate::Scrollbar; use crate::Scrollbar;
use leptos::{context::Provider, prelude::*}; use leptos::{context::Provider, prelude::*};
use thaw_components::OptionComp; use thaw_components::OptionComp;
use thaw_utils::{mount_style, Model}; use thaw_utils::{class_list, mount_style, Model};
#[component] #[component]
pub fn NavDrawer( pub fn NavDrawer(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional, into)] selected_value: Model<String>, #[prop(optional, into)] selected_value: Model<String>,
children: Children, children: Children,
#[prop(optional)] nav_drawer_header: Option<NavDrawerHeader>, #[prop(optional)] nav_drawer_header: Option<NavDrawerHeader>,
@ -14,7 +15,7 @@ pub fn NavDrawer(
view! { view! {
<Provider value=NavDrawerInjection(selected_value)> <Provider value=NavDrawerInjection(selected_value)>
<div class="thaw-nav-drawer"> <div class=class_list!["thaw-nav-drawer", class]>
<OptionComp value=nav_drawer_header let:header> <OptionComp value=nav_drawer_header let:header>
<header class="thaw-nav-drawer__header">{(header.children)()}</header> <header class="thaw-nav-drawer__header">{(header.children)()}</header>
</OptionComp> </OptionComp>

View file

@ -3,7 +3,11 @@ use leptos::prelude::*;
use thaw_utils::{class_list, StoredMaybeSignal}; use thaw_utils::{class_list, StoredMaybeSignal};
#[component] #[component]
pub fn NavItem(#[prop(into)] value: MaybeSignal<String>, children: Children) -> impl IntoView { pub fn NavItem(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(into)] value: MaybeSignal<String>,
children: Children,
) -> impl IntoView {
let nav_drawer = use_nav_drawer(); let nav_drawer = use_nav_drawer();
let value: StoredMaybeSignal<_> = value.into(); let value: StoredMaybeSignal<_> = value.into();
let on_click = move |_| { let on_click = move |_| {
@ -13,7 +17,7 @@ pub fn NavItem(#[prop(into)] value: MaybeSignal<String>, children: Children) ->
} }
}; };
view! { view! {
<a class=class_list!["thaw-nav-item", ("thaw-nav-item--selected", move || nav_drawer.0.get() == value.get())] <a class=class_list!["thaw-nav-item", ("thaw-nav-item--selected", move || nav_drawer.0.get() == value.get()), class]
role="nav" role="nav"
type="navigation" type="navigation"
on:click=on_click on:click=on_click

View file

@ -21,7 +21,7 @@ pub fn Popover(
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
mount_style("popover", include_str!("./popover.css")); mount_style("popover", include_str!("./popover.css"));
let config_provider = ConfigInjection::use_(); let config_provider = ConfigInjection::expect_context();
let popover_ref = NodeRef::<html::Div>::new(); let popover_ref = NodeRef::<html::Div>::new();
let target_ref = NodeRef::<html::Div>::new(); let target_ref = NodeRef::<html::Div>::new();

View file

@ -3,6 +3,7 @@ use thaw_utils::{class_list, mount_style};
#[component] #[component]
pub fn ProgressBar( pub fn ProgressBar(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(into, optional)] value: MaybeSignal<f64>, #[prop(into, optional)] value: MaybeSignal<f64>,
#[prop(default = 1.0.into(), optional)] max: MaybeSignal<f64>, #[prop(default = 1.0.into(), optional)] max: MaybeSignal<f64>,
#[prop(into, optional)] color: MaybeSignal<ProgressBarColor>, #[prop(into, optional)] color: MaybeSignal<ProgressBarColor>,
@ -19,7 +20,8 @@ pub fn ProgressBar(
<div <div
class=class_list![ class=class_list![
"thaw-progress-bar", "thaw-progress-bar",
move || format!("thaw-progress-bar--{}", color.get().as_str()) move || format!("thaw-progress-bar--{}", color.get().as_str()),
class
] ]
role="progressbar" role="progressbar"
aria_valuemax=move || max.get() aria_valuemax=move || max.get()

View file

@ -1,9 +1,9 @@
use leptos::prelude::*; use leptos::prelude::*;
use thaw_utils::{class_list, mount_style, OptionalProp}; use thaw_utils::{class_list, mount_style};
#[component] #[component]
pub fn ProgressCircle( pub fn ProgressCircle(
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
#[prop(into, optional)] value: MaybeSignal<f64>, #[prop(into, optional)] value: MaybeSignal<f64>,
#[prop(into, optional)] color: MaybeSignal<ProgressCircleColor>, #[prop(into, optional)] color: MaybeSignal<ProgressCircleColor>,
#[prop(into, default = "120px".into())] size: MaybeSignal<String>, #[prop(into, default = "120px".into())] size: MaybeSignal<String>,
@ -40,7 +40,7 @@ pub fn ProgressCircle(
view! { view! {
<div <div
class=class_list!["thaw-progress-circle", class.map(| c | move || c.get())] class=class_list!["thaw-progress-circle", class]
role="progressbar" role="progressbar"
aria-valuemax="100" aria-valuemax="100"
aria-valuemin="0" aria-valuemin="0"

View file

@ -4,11 +4,11 @@ pub use radio_group::RadioGroup;
use leptos::prelude::*; use leptos::prelude::*;
use radio_group::RadioGroupInjection; use radio_group::RadioGroupInjection;
use thaw_utils::{class_list, mount_style, OptionalProp}; use thaw_utils::{class_list, mount_style};
#[component] #[component]
pub fn Radio( pub fn Radio(
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional, into)] value: String, #[prop(optional, into)] value: String,
#[prop(optional, into)] label: MaybeProp<String>, #[prop(optional, into)] label: MaybeProp<String>,
) -> impl IntoView { ) -> impl IntoView {
@ -31,11 +31,7 @@ pub fn Radio(
}; };
view! { view! {
<span <span class=class_list!["thaw-radio", class]>
class=class_list![
"thaw-radio", class.map(| c | move || c.get())
]
>
<input <input
class="thaw-radio__input" class="thaw-radio__input"
type="radio" type="radio"

View file

@ -1,8 +1,9 @@
use leptos::{context::Provider, prelude::*}; use leptos::{context::Provider, prelude::*};
use thaw_utils::OptionModel; use thaw_utils::{class_list, OptionModel};
#[component] #[component]
pub fn RadioGroup( pub fn RadioGroup(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional, into)] value: OptionModel<String>, #[prop(optional, into)] value: OptionModel<String>,
/// The name of this radio group. /// The name of this radio group.
#[prop(optional, into)] #[prop(optional, into)]
@ -13,7 +14,7 @@ pub fn RadioGroup(
view! { view! {
<Provider value=RadioGroupInjection{ value, name }> <Provider value=RadioGroupInjection{ value, name }>
<div class="thaw-radio-group" role="radiogroup" style="display: flex;align-items: flex-start"> <div class=class_list!["thaw-radio-group", class] role="radiogroup" style="display: flex;align-items: flex-start">
{children()} {children()}
</div> </div>
</Provider> </Provider>

View file

@ -1,12 +1,12 @@
use leptos::{ev, html, leptos_dom::helpers::WindowListenerHandle, prelude::*}; use leptos::{ev, html, leptos_dom::helpers::WindowListenerHandle, prelude::*};
use thaw_utils::{class_list, mount_style, ComponentRef, OptionalProp}; use thaw_utils::{class_list, mount_style, ComponentRef};
#[component] #[component]
pub fn Scrollbar( pub fn Scrollbar(
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional, into)] style: Option<MaybeSignal<String>>, #[prop(optional, into)] style: Option<MaybeSignal<String>>,
#[prop(optional, into)] content_class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] content_class: MaybeProp<String>,
#[prop(optional, into)] content_style: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] content_style: MaybeProp<String>,
#[prop(default = 8)] size: u8, #[prop(default = 8)] size: u8,
#[prop(optional)] comp_ref: Option<ComponentRef<ScrollbarRef>>, #[prop(optional)] comp_ref: Option<ComponentRef<ScrollbarRef>>,
children: Children, children: Children,
@ -285,7 +285,7 @@ pub fn Scrollbar(
view! { view! {
<div <div
class=class_list!["thaw-scrollbar", class.map(| c | move || c.get())] class=class_list!["thaw-scrollbar", class]
style=move || { style=move || {
format!("--thaw-scrollbar-size: {}px;{}", size, style.as_ref().map(|s| s.get()).unwrap_or_default()) format!("--thaw-scrollbar-size: {}px;{}", size, style.as_ref().map(|s| s.get()).unwrap_or_default())
} }
@ -297,13 +297,13 @@ pub fn Scrollbar(
<div class="thaw-scrollbar__container" node_ref=container_ref on:scroll=on_scroll> <div class="thaw-scrollbar__container" node_ref=container_ref on:scroll=on_scroll>
<div <div
class=class_list![ class=class_list![
"thaw-scrollbar__content", content_class.map(| c | move || c.get()) "thaw-scrollbar__content", content_class
] ]
style=move || { style=move || {
format!( format!(
"width: fit-content; {}", "width: fit-content; {}",
content_style.as_ref().map_or(String::new(), |s| s.get()), content_style.get().unwrap_or_default(),
) )
} }

View file

@ -1,12 +1,16 @@
use leptos::prelude::*; use leptos::prelude::*;
use thaw_utils::class_list;
#[component] #[component]
pub fn Skeleton(children: Children) -> impl IntoView { pub fn Skeleton(
#[prop(optional, into)] class: MaybeProp<String>,
children: Children,
) -> impl IntoView {
view! { view! {
<div <div
role="progressbar" role="progressbar"
aria-busy="true" aria-busy="true"
class="thaw-skeleton" class=class_list!["thaw-skeleton", class]
> >
{children()} {children()}
</div> </div>

View file

@ -1,12 +1,12 @@
use leptos::prelude::*; use leptos::prelude::*;
use thaw_utils::mount_style; use thaw_utils::{class_list, mount_style};
#[component] #[component]
pub fn SkeletonItem() -> impl IntoView { pub fn SkeletonItem(#[prop(optional, into)] class: MaybeProp<String>) -> impl IntoView {
mount_style("skeleton-item", include_str!("./skeleton-item.css")); mount_style("skeleton-item", include_str!("./skeleton-item.css"));
view! { view! {
<div class="thaw-skeleton-item"> <div class=class_list!["thaw-skeleton-item", class]>
</div> </div>
} }
} }

View file

@ -4,7 +4,7 @@ pub use slider_label::SliderLabel;
use leptos::{context::Provider, ev, prelude::*}; use leptos::{context::Provider, ev, prelude::*};
use thaw_components::OptionComp; use thaw_components::OptionComp;
use thaw_utils::{class_list, mount_style, Model, OptionalProp}; use thaw_utils::{class_list, mount_style, Model};
#[component] #[component]
pub fn Slider( pub fn Slider(
@ -12,7 +12,7 @@ pub fn Slider(
#[prop(default = 0f64.into(), into)] min: MaybeSignal<f64>, #[prop(default = 0f64.into(), into)] min: MaybeSignal<f64>,
#[prop(default = 100f64.into(), into)] max: MaybeSignal<f64>, #[prop(default = 100f64.into(), into)] max: MaybeSignal<f64>,
#[prop(optional, into)] step: MaybeProp<f64>, #[prop(optional, into)] step: MaybeProp<f64>,
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<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"));
@ -69,7 +69,7 @@ pub fn Slider(
view! { view! {
<Provider value=SliderInjection { max, min }> <Provider value=SliderInjection { max, min }>
<div <div
class=class_list!["thaw-slider", class.map(| c | move || c.get())] class=class_list!["thaw-slider", class]
style=css_vars style=css_vars
> >
<input <input
@ -104,7 +104,7 @@ pub(crate) struct SliderInjection {
} }
impl SliderInjection { impl SliderInjection {
pub fn use_() -> Self { pub fn expect_context() -> Self {
expect_context() expect_context()
} }
} }

View file

@ -1,13 +1,16 @@
use leptos::prelude::*;
use thaw_utils::mount_style;
use crate::SliderInjection; use crate::SliderInjection;
use leptos::prelude::*;
use thaw_utils::{class_list, mount_style};
#[component] #[component]
pub fn SliderLabel(#[prop(into)] value: MaybeSignal<f64>, children: Children) -> impl IntoView { pub fn SliderLabel(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(into)] value: MaybeSignal<f64>,
children: Children,
) -> impl IntoView {
mount_style("slider-label", include_str!("./slider_label.css")); mount_style("slider-label", include_str!("./slider_label.css"));
let slider = SliderInjection::use_(); let slider = SliderInjection::expect_context();
let style = move || { let style = move || {
let value = (value.get() - slider.min.get()) / (slider.max.get() - slider.min.get()); let value = (value.get() - slider.min.get()) / (slider.max.get() - slider.min.get());
@ -16,7 +19,7 @@ pub fn SliderLabel(#[prop(into)] value: MaybeSignal<f64>, children: Children) ->
view! { view! {
<option <option
class:thaw-slider-label=true class=class_list!["thaw-slider-label", class]
style=style style=style
value=move || value.get() value=move || value.get()
> >

View file

@ -2,10 +2,11 @@ use leptos::prelude::*;
use num_traits::Bounded; use num_traits::Bounded;
use std::ops::{Add, Sub}; use std::ops::{Add, Sub};
use std::str::FromStr; use std::str::FromStr;
use thaw_utils::{mount_style, with, Model, StoredMaybeSignal}; use thaw_utils::{class_list, mount_style, with, Model, StoredMaybeSignal};
#[component] #[component]
pub fn SpinButton<T>( pub fn SpinButton<T>(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional, into)] value: Model<T>, #[prop(optional, into)] value: Model<T>,
#[prop(into)] step_page: MaybeSignal<T>, #[prop(into)] step_page: MaybeSignal<T>,
#[prop(default = T::min_value().into(), into)] min: MaybeSignal<T>, #[prop(default = T::min_value().into(), into)] min: MaybeSignal<T>,
@ -54,8 +55,7 @@ where
view! { view! {
<span <span
class="thaw-spin-button" class=class_list!["thaw-spin-button", ("thaw-spin-button--disabled", move || disabled.get()), class]
class=("thaw-spin-button--disabled", move || disabled.get())
> >
<input <input
autocomplete="off" autocomplete="off"

View file

@ -1,10 +1,10 @@
use leptos::{html, prelude::*}; use leptos::{html, prelude::*};
use thaw_utils::{class_list, mount_style, Model, OptionalProp}; use thaw_utils::{class_list, mount_style, Model};
#[component] #[component]
pub fn Switch( pub fn Switch(
#[prop(optional, into)] checked: Model<bool>, #[prop(optional, into)] checked: Model<bool>,
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional, into)] label: MaybeProp<String>, #[prop(optional, into)] label: MaybeProp<String>,
) -> impl IntoView { ) -> impl IntoView {
mount_style("switch", include_str!("./switch.css")); mount_style("switch", include_str!("./switch.css"));
@ -17,12 +17,7 @@ pub fn Switch(
}; };
view! { view! {
<div <div class=class_list!["thaw-switch", class]>
class=class_list![
"thaw-switch", class.map(| c | move ||
c.get())
]
>
<input <input
class="thaw-switch__input" class="thaw-switch__input"
role="switch" role="switch"

View file

@ -44,7 +44,7 @@ pub(crate) struct TabListInjection {
impl Copy for TabListInjection {} impl Copy for TabListInjection {}
impl TabListInjection { impl TabListInjection {
pub fn use_() -> Self { pub fn expect_context() -> Self {
expect_context() expect_context()
} }

View file

@ -12,7 +12,7 @@ pub fn Tab(
mount_style("tab", include_str!("./tab.css")); mount_style("tab", include_str!("./tab.css"));
let tab_ref = NodeRef::<html::Button>::new(); let tab_ref = NodeRef::<html::Button>::new();
let tab_list = TabListInjection::use_(); let tab_list = TabListInjection::expect_context();
let value = StoredValue::new(value); let value = StoredValue::new(value);
tab_list.register(TabRegisterData { tab_list.register(TabRegisterData {
value: value.get_value(), value: value.get_value(),

View file

@ -16,18 +16,24 @@ pub fn Table(
} }
#[component] #[component]
pub fn TableHeader(children: Children) -> impl IntoView { pub fn TableHeader(
#[prop(optional, into)] class: MaybeProp<String>,
children: Children,
) -> impl IntoView {
view! { view! {
<thead class="thaw-table-header"> <thead class=class_list!["thaw-table-header", class]>
{children()} {children()}
</thead> </thead>
} }
} }
#[component] #[component]
pub fn TableHeaderCell(#[prop(optional)] children: Option<Children>) -> impl IntoView { pub fn TableHeaderCell(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional)] children: Option<Children>,
) -> impl IntoView {
view! { view! {
<th class="thaw-table-header-cell"> <th class=class_list!["thaw-table-header-cell", class]>
<button class="thaw-table-header-cell__button" role="presentation"> <button class="thaw-table-header-cell__button" role="presentation">
{ {
if let Some(children) = children { if let Some(children) = children {
@ -42,27 +48,36 @@ pub fn TableHeaderCell(#[prop(optional)] children: Option<Children>) -> impl Int
} }
#[component] #[component]
pub fn TableBody(children: Children) -> impl IntoView { pub fn TableBody(
#[prop(optional, into)] class: MaybeProp<String>,
children: Children,
) -> impl IntoView {
view! { view! {
<tbody class="thaw-table-body"> <tbody class=class_list!["thaw-table-body", class]>
{children()} {children()}
</tbody> </tbody>
} }
} }
#[component] #[component]
pub fn TableRow(children: Children) -> impl IntoView { pub fn TableRow(
#[prop(optional, into)] class: MaybeProp<String>,
children: Children,
) -> impl IntoView {
view! { view! {
<tr class="thaw-table-row"> <tr class=class_list!["thaw-table-row", class]>
{children()} {children()}
</tr> </tr>
} }
} }
#[component] #[component]
pub fn TableCell(#[prop(optional)] children: Option<Children>) -> impl IntoView { pub fn TableCell(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional)] children: Option<Children>,
) -> impl IntoView {
view! { view! {
<td class="thaw-table-cell"> <td class=class_list!["thaw-table-cell", class]>
{ {
if let Some(children) = children { if let Some(children) = children {
Either::Left(children()) Either::Left(children())
@ -75,9 +90,12 @@ pub fn TableCell(#[prop(optional)] children: Option<Children>) -> impl IntoView
} }
#[component] #[component]
pub fn TableCellLayout(children: Children) -> impl IntoView { pub fn TableCellLayout(
#[prop(optional, into)] class: MaybeProp<String>,
children: Children,
) -> impl IntoView {
view! { view! {
<div class="thaw-table-cell-layout"> <div class=class_list!["thaw-table-cell-layout", class]>
{children()} {children()}
</div> </div>
} }

View file

@ -1,9 +1,9 @@
use leptos::{either::Either, ev, prelude::*}; use leptos::{either::Either, ev, prelude::*};
use thaw_utils::{class_list, mount_style, ArcOneCallback, OptionalProp}; use thaw_utils::{class_list, mount_style, ArcOneCallback};
#[component] #[component]
pub fn Tag( pub fn Tag(
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional, into)] closable: MaybeSignal<bool>, #[prop(optional, into)] closable: MaybeSignal<bool>,
#[prop(optional, into)] on_close: Option<ArcOneCallback<ev::MouseEvent>>, #[prop(optional, into)] on_close: Option<ArcOneCallback<ev::MouseEvent>>,
children: Children, children: Children,
@ -12,7 +12,7 @@ pub fn Tag(
view! { view! {
<span <span
class=class_list!["thaw-tag", ("thaw-tag--closable", move || closable.get()), class.map(| c | move || c.get())] class=class_list!["thaw-tag", ("thaw-tag--closable", move || closable.get()), class]
> >
<span class="thaw-tag__primary-text">{children()}</span> <span class="thaw-tag__primary-text">{children()}</span>

View file

@ -5,12 +5,12 @@ use crate::{
use chrono::{Local, NaiveTime, Timelike}; use chrono::{Local, NaiveTime, Timelike};
use leptos::{html, prelude::*}; use leptos::{html, prelude::*};
use thaw_components::{Binder, CSSTransition, Follower, FollowerPlacement}; use thaw_components::{Binder, CSSTransition, Follower, FollowerPlacement};
use thaw_utils::{mount_style, ComponentRef, OptionModel, OptionalProp}; use thaw_utils::{class_list, mount_style, ComponentRef, OptionModel};
#[component] #[component]
pub fn TimePicker( pub fn TimePicker(
#[prop(optional, into)] value: OptionModel<NaiveTime>, #[prop(optional, into)] value: OptionModel<NaiveTime>,
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>, #[prop(optional, into)] class: MaybeProp<String>,
// #[prop(attrs)] attrs: Vec<(&'static str, Attribute)>, // #[prop(attrs)] attrs: Vec<(&'static str, Attribute)>,
) -> impl IntoView { ) -> impl IntoView {
mount_style("time-picker", include_str!("./time-picker.css")); mount_style("time-picker", include_str!("./time-picker.css"));
@ -70,8 +70,8 @@ pub fn TimePicker(
view! { view! {
<Binder target_ref=time_picker_ref> <Binder target_ref=time_picker_ref>
<div node_ref=time_picker_ref> <div node_ref=time_picker_ref class=class_list!["thaw-time-picker", class]>
<Input class value=show_time_text on_focus=open_panel on_blur=on_input_blur> <Input value=show_time_text on_focus=open_panel on_blur=on_input_blur>
<InputSuffix slot> <InputSuffix slot>
<Icon icon=icondata_ai::AiClockCircleOutlined style="font-size: 18px"/> <Icon icon=icondata_ai::AiClockCircleOutlined style="font-size: 18px"/>
</InputSuffix> </InputSuffix>
@ -98,7 +98,7 @@ fn Panel(
#[prop(into)] is_show_panel: MaybeSignal<bool>, #[prop(into)] is_show_panel: MaybeSignal<bool>,
comp_ref: ComponentRef<PanelRef>, comp_ref: ComponentRef<PanelRef>,
) -> impl IntoView { ) -> impl IntoView {
let config_provider = ConfigInjection::use_(); let config_provider = ConfigInjection::expect_context();
let now = move |_| { let now = move |_| {
close_panel.call(Some(now_time())); close_panel.call(Some(now_time()));
}; };

View file

@ -1,10 +1,14 @@
use leptos::prelude::*; use leptos::prelude::*;
use std::time::Duration; use std::time::Duration;
use thaw_utils::class_list;
#[component] #[component]
pub fn Toast(children: Children) -> impl IntoView { pub fn Toast(
#[prop(optional, into)] class: MaybeProp<String>,
children: Children,
) -> impl IntoView {
view! { view! {
<div class="thaw-toast"> <div class=class_list!["thaw-toast", class]>
{children()} {children()}
</div> </div>
} }

View file

@ -1,9 +1,13 @@
use leptos::prelude::*; use leptos::prelude::*;
use thaw_utils::class_list;
#[component] #[component]
pub fn ToastFooter(children: Children) -> impl IntoView { pub fn ToastFooter(
#[prop(optional, into)] class: MaybeProp<String>,
children: Children,
) -> impl IntoView {
view! { view! {
<div class="thaw-toast-footer"> <div class=class_list!["thaw-toast-footer", class]>
{children()} {children()}
</div> </div>
} }

View file

@ -4,10 +4,11 @@ pub use upload_dragger::UploadDragger;
pub use web_sys::FileList; pub use web_sys::FileList;
use leptos::{ev, html, prelude::*}; use leptos::{ev, html, prelude::*};
use thaw_utils::{add_event_listener, mount_style, ArcOneCallback}; use thaw_utils::{add_event_listener, class_list, mount_style, ArcOneCallback};
#[component] #[component]
pub fn Upload( pub fn Upload(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional, into)] accept: MaybeSignal<String>, #[prop(optional, into)] accept: MaybeSignal<String>,
#[prop(optional, into)] multiple: MaybeSignal<bool>, #[prop(optional, into)] multiple: MaybeSignal<bool>,
#[prop(optional, into)] custom_request: Option<ArcOneCallback<FileList>>, #[prop(optional, into)] custom_request: Option<ArcOneCallback<FileList>>,
@ -74,8 +75,10 @@ pub fn Upload(
view! { view! {
<div <div
class="thaw-upload" class=class_list!["thaw-upload",
class=("thaw-upload--drag-over", move || is_trigger_dragover.get()) ("thaw-upload--drag-over", move || is_trigger_dragover.get()),
class
]
> >
<input <input
class="thaw-upload__input" class="thaw-upload__input"

View file

@ -1,12 +1,15 @@
use leptos::prelude::*; use leptos::prelude::*;
use thaw_utils::mount_style; use thaw_utils::{class_list, mount_style};
#[component] #[component]
pub fn UploadDragger(children: Children) -> impl IntoView { pub fn UploadDragger(
#[prop(optional, into)] class: MaybeProp<String>,
children: Children,
) -> impl IntoView {
mount_style("upload-dragger", include_str!("./upload-dragger.css")); mount_style("upload-dragger", include_str!("./upload-dragger.css"));
view! { view! {
<div class="thaw-upload-dragger"> <div class=class_list!["thaw-upload-dragger", class]>
{children()} {children()}
</div> </div>
} }