cargo fmt & leptosfmt

This commit is contained in:
luoxiao 2024-08-13 14:47:13 +08:00 committed by luoxiaozero
parent f01b900252
commit 61284d57fc
82 changed files with 790 additions and 685 deletions

View file

@ -50,23 +50,25 @@ pub fn AccordionItem(
type="button" type="button"
on:click=on_click on:click=on_click
> >
<span <span class="thaw-accordion-header__expand-icon" aria-hidden="true">
class="thaw-accordion-header__expand-icon"
aria-hidden="true"
>
<svg <svg
fill="currentColor" fill="currentColor"
aria-hidden="true" aria-hidden="true"
width="1em" width="1em"
height="1em" height="1em"
viewBox="0 0 20 20" viewBox="0 0 20 20"
style=move || if is_show_panel.get() { style=move || {
"transform: rotate(90deg)" if is_show_panel.get() {
} else { "transform: rotate(90deg)"
"transform: rotate(0deg)" } else {
"transform: rotate(0deg)"
}
} }
> >
<path d="M7.65 4.15c.2-.2.5-.2.7 0l5.49 5.46c.21.22.21.57 0 .78l-5.49 5.46a.5.5 0 0 1-.7-.7L12.8 10 7.65 4.85a.5.5 0 0 1 0-.7Z" fill="currentColor"></path> <path
d="M7.65 4.15c.2-.2.5-.2.7 0l5.49 5.46c.21.22.21.57 0 .78l-5.49 5.46a.5.5 0 0 1-.7-.7L12.8 10 7.65 4.85a.5.5 0 0 1 0-.7Z"
fill="currentColor"
></path>
</svg> </svg>
</span> </span>
{(accordion_header.children)()} {(accordion_header.children)()}

View file

@ -24,11 +24,9 @@ pub fn Accordion(
<Provider value=AccordionInjection { <Provider value=AccordionInjection {
open_items, open_items,
collapsible, collapsible,
multiple multiple,
}> }>
<div class=class_list!["thaw-accordion", class]> <div class=class_list!["thaw-accordion", class]>{children()}</div>
{children()}
</div>
</Provider> </Provider>
} }
} }

View file

@ -7,9 +7,11 @@ use thaw_utils::{class_list, StoredMaybeSignal};
pub fn AnchorLink( pub fn AnchorLink(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
/// The content of link. /// The content of link.
#[prop(into)] title: MaybeSignal<String>, #[prop(into)]
title: MaybeSignal<String>,
/// The target of link. /// The target of link.
#[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::expect_context(); let anchor = AnchorInjection::expect_context();
@ -63,7 +65,10 @@ 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]> "thaw-anchor-link",
("thaw-anchor-link--active", move || is_active.get()),
class
]>
<a <a
href=href href=href
class="thaw-anchor-link__title" class="thaw-anchor-link__title"

View file

@ -107,10 +107,7 @@ pub fn Anchor(
} }
view! { view! {
<div <div class=class_list!["thaw-anchor", class] node_ref=anchor_ref>
class=class_list!["thaw-anchor", class]
node_ref=anchor_ref
>
<div class="thaw-anchor-rail"> <div class="thaw-anchor-rail">
<div <div
class="thaw-anchor-rail__bar" class="thaw-anchor-rail__bar"

View file

@ -26,17 +26,21 @@ pub struct AutoCompleteSuffix {
pub fn AutoComplete( pub fn AutoComplete(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
/// Input of autocomplete. /// Input of autocomplete.
#[prop(optional, into)] value: Model<String>, #[prop(optional, into)]
value: Model<String>,
/// Autocomplete's placeholder. /// Autocomplete's placeholder.
#[prop(optional, into)] placeholder: MaybeProp<String>, #[prop(optional, into)]
placeholder: MaybeProp<String>,
// Whether to clear after selection. // Whether to clear after selection.
#[prop(optional, into)] clear_after_select: MaybeSignal<bool>, #[prop(optional, into)] clear_after_select: MaybeSignal<bool>,
/// Whether to blur after selection. /// Whether to blur after selection.
#[prop(optional, into)] blur_after_select: MaybeSignal<bool>, #[prop(optional, into)]
blur_after_select: MaybeSignal<bool>,
// On select callback function. // On select callback function.
#[prop(optional, into)] on_select: Option<BoxOneCallback<String>>, #[prop(optional, into)] on_select: Option<BoxOneCallback<String>>,
/// Whether the input is disabled. /// Whether the input is disabled.
#[prop(optional, into)] disabled: MaybeSignal<bool>, #[prop(optional, into)]
disabled: MaybeSignal<bool>,
#[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>,
@ -147,15 +151,22 @@ pub fn AutoComplete(
placement=FollowerPlacement::BottomStart placement=FollowerPlacement::BottomStart
width=FollowerWidth::Target width=FollowerWidth::Target
> >
<Provider value=AutoCompleteInjection{value, select_option, options}> <Provider value=AutoCompleteInjection {
<Listbox open=open_listbox.read_only() set_listbox listbox_ref class="thaw-auto-complete__listbox"> value,
{ select_option,
if let Some(children) = children { options,
Either::Left(children()) }>
} else { <Listbox
Either::Right(()) open=open_listbox.read_only()
} set_listbox
} listbox_ref
class="thaw-auto-complete__listbox"
>
{if let Some(children) = children {
Either::Left(children())
} else {
Either::Right(())
}}
</Listbox> </Listbox>
</Provider> </Provider>
</Follower> </Follower>

View file

@ -60,55 +60,62 @@ pub fn Avatar(
view! { view! {
<span <span
class=class_list!["thaw-avatar", move || format!("thaw-avatar--{}", shape.get().as_str()), class] 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.with_value(|n| n.get()) aria-label=move || name.with_value(|n| n.get())
> >
{ {move || {
move || { let mut initials = initials.with_value(|i| i.get());
let mut initials = initials.with_value(|i| i.get()); if initials.is_none() {
if initials.is_none() { name.with_value(|name| {
name.with_value(|name| { if let Some(name) = name.get() {
if let Some(name) = name.get() { initials = Some(initials_name(name));
initials = Some(initials_name(name)); }
} });
});
}
view! {
<OptionComp value=initials let:initials>
<span class="thaw-avatar__initials">
{initials}
</span>
</OptionComp>
}
} }
} view! {
{ <OptionComp value=initials let:initials>
move || { <span class="thaw-avatar__initials">{initials}</span>
let src = src.with_value(|s| s.get()); </OptionComp>
view! {
<OptionComp value=src let:src>
<img src=src class="thaw-avatar__image"/>
</OptionComp>
}
} }
} }}
{ {move || {
move || { let src = src.with_value(|s| s.get());
if is_show_default_icon.get() { view! {
Either::Left(view! { <OptionComp value=src let:src>
<img src=src class="thaw-avatar__image" />
</OptionComp>
}
}}
{move || {
if is_show_default_icon.get() {
Either::Left(
view! {
<span aria-hidden="true" class="thaw-avatar__icon"> <span aria-hidden="true" class="thaw-avatar__icon">
<svg fill="currentColor" aria-hidden="true" width="1em" height="1em" viewBox="0 0 20 20"> <svg
<path d="M10 2a4 4 0 1 0 0 8 4 4 0 0 0 0-8ZM7 6a3 3 0 1 1 6 0 3 3 0 0 1-6 0Zm-2 5a2 2 0 0 0-2 2c0 1.7.83 2.97 2.13 3.8A9.14 9.14 0 0 0 10 18c1.85 0 3.58-.39 4.87-1.2A4.35 4.35 0 0 0 17 13a2 2 0 0 0-2-2H5Zm-1 2a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1c0 1.3-.62 2.28-1.67 2.95A8.16 8.16 0 0 1 10 17a8.16 8.16 0 0 1-4.33-1.05A3.36 3.36 0 0 1 4 13Z" fill="currentColor"></path> fill="currentColor"
aria-hidden="true"
width="1em"
height="1em"
viewBox="0 0 20 20"
>
<path
d="M10 2a4 4 0 1 0 0 8 4 4 0 0 0 0-8ZM7 6a3 3 0 1 1 6 0 3 3 0 0 1-6 0Zm-2 5a2 2 0 0 0-2 2c0 1.7.83 2.97 2.13 3.8A9.14 9.14 0 0 0 10 18c1.85 0 3.58-.39 4.87-1.2A4.35 4.35 0 0 0 17 13a2 2 0 0 0-2-2H5Zm-1 2a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1c0 1.3-.62 2.28-1.67 2.95A8.16 8.16 0 0 1 10 17a8.16 8.16 0 0 1-4.33-1.05A3.36 3.36 0 0 1 4 13Z"
fill="currentColor"
></path>
</svg> </svg>
</span> </span>
}) },
} else { )
Either::Right(()) } else {
} Either::Right(())
} }
} }}
</span> </span>
} }
} }

View file

@ -95,17 +95,28 @@ pub fn BackTop(
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 || {
display.get().map_or_else(|| format!("right: {}px; bottom: {}px", right.get(), bottom.get()), |d| d.to_string()) display
.get()
.map_or_else(
|| {
format!(
"right: {}px; bottom: {}px",
right.get(),
bottom.get(),
)
},
|d| d.to_string(),
)
} }
on:click=on_click on:click=on_click
> >
{ {if let Some(children) = children {
if let Some(children) = children { Either::Left(children())
Either::Left(children()) } else {
} else { Either::Right(
Either::Right(view!{<Icon icon=icondata_ai::AiVerticalAlignTopOutlined/>}) view! { <Icon icon=icondata_ai::AiVerticalAlignTopOutlined /> },
} )
} }}
</div> </div>
</CSSTransition> </CSSTransition>
</Teleport> </Teleport>

View file

@ -25,13 +25,11 @@ pub fn Badge(
move || format!("thaw-badge--{}", color.get().as_str()), move || format!("thaw-badge--{}", color.get().as_str()),
class class
]> ]>
{ {if let Some(children) = children {
if let Some(children) = children { Either::Left(children())
Either::Left(children()) } else {
} else { Either::Right(())
Either::Right(()) }}
}
}
</div> </div>
} }
} }

View file

@ -9,10 +9,10 @@ pub fn Breadcrumb(
mount_style("breadcrumb", include_str!("./breadcrumb.css")); mount_style("breadcrumb", include_str!("./breadcrumb.css"));
view! { view! {
<nav <nav class=class_list!["thaw-breadcrumb", class]>
class=class_list!["thaw-breadcrumb", class] <ol role="list" class="thaw-breadcrumb__list">
> {children()}
<ol role="list" class="thaw-breadcrumb__list">{children()}</ol> </ol>
</nav> </nav>
} }
} }
@ -22,23 +22,24 @@ pub fn BreadcrumbItem(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
view! { view! { <li class=class_list!["thaw-breadcrumb-item", class]>{children()}</li> }
<li class=class_list!["thaw-breadcrumb-item", class]>
{children()}
</li>
}
} }
#[component] #[component]
pub fn BreadcrumbButton( pub fn BreadcrumbButton(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
/// Defines current sate of BreadcrumbButton. /// Defines current sate of BreadcrumbButton.
#[prop(optional, into)] current: MaybeSignal<bool>, #[prop(optional, into)]
current: MaybeSignal<bool>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
view! { view! {
<button <button
class=class_list!["thaw-breadcrumb-button", ("thaw-breadcrumb-button--current", move || current.get()), class] class=class_list![
"thaw-breadcrumb-button",
("thaw-breadcrumb-button--current", move || current.get()),
class
]
aria-disabled=move || current.get().then(|| "true") aria-disabled=move || current.get().then(|| "true")
aria-current=move || current.get().then(|| "page") aria-current=move || current.get().then(|| "page")
> >
@ -51,8 +52,17 @@ pub fn BreadcrumbButton(
pub fn BreadcrumbDivider(#[prop(optional, into)] class: MaybeProp<String>) -> impl IntoView { pub fn BreadcrumbDivider(#[prop(optional, into)] class: MaybeProp<String>) -> impl IntoView {
view! { view! {
<li class=class_list!["thaw-breadcrumb-divider", class] aria-hidden="true"> <li class=class_list!["thaw-breadcrumb-divider", class] aria-hidden="true">
<svg fill="currentColor" aria-hidden="true" width="1em" height="1em" viewBox="0 0 20 20"> <svg
<path d="M7.65 4.15c.2-.2.5-.2.7 0l5.49 5.46c.21.22.21.57 0 .78l-5.49 5.46a.5.5 0 0 1-.7-.7L12.8 10 7.65 4.85a.5.5 0 0 1 0-.7Z" fill="currentColor"></path> fill="currentColor"
aria-hidden="true"
width="1em"
height="1em"
viewBox="0 0 20 20"
>
<path
d="M7.65 4.15c.2-.2.5-.2.7 0l5.49 5.46c.21.22.21.57 0 .78l-5.49 5.46a.5.5 0 0 1-.7-.7L12.8 10 7.65 4.85a.5.5 0 0 1 0-.7Z"
fill="currentColor"
></path>
</svg> </svg>
</li> </li>
} }

View file

@ -5,7 +5,8 @@ use thaw_utils::{class_list, mount_style};
pub fn ButtonGroup( pub fn ButtonGroup(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
/// Directions of buttons in the group. /// Directions of buttons in the group.
#[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 file

@ -125,24 +125,19 @@ pub fn Button(
aria-disabled=move || disabled_focusable.get().then_some("true") aria-disabled=move || disabled_focusable.get().then_some("true")
on:click=on_click on:click=on_click
> >
{ {move || {
let icon = icon.get();
move || { if let Some(icon) = icon {
let icon = icon.get(); Either::Left(view! { <Icon icon=icon class="thaw-button__icon" /> })
if let Some(icon) = icon {
Either::Left(view!{<Icon icon=icon class="thaw-button__icon"/>})
} else {
Either::Right(())
}
}
}
{
if let Some(children) = children {
Either::Left(children())
} else { } else {
Either::Right(()) Either::Right(())
} }
} }}
{if let Some(children) = children {
Either::Left(children())
} else {
Either::Right(())
}}
</button> </button>
} }
} }

View file

@ -8,7 +8,8 @@ use thaw_utils::{class_list, mount_style, OptionModel};
pub fn Calendar( pub fn Calendar(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
/// selected date. /// selected date.
#[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"));
let show_date = RwSignal::new(value.get_untracked().unwrap_or(now_date())); let show_date = RwSignal::new(value.get_untracked().unwrap_or(now_date()));
@ -87,9 +88,7 @@ pub fn Calendar(
}; };
view! { view! {
<div <div class=class_list!["thaw-calendar", class]>
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">
@ -106,17 +105,9 @@ pub fn Calendar(
</span> </span>
<ButtonGroup> <ButtonGroup>
<Button <Button icon=icondata_ai::AiLeftOutlined on_click=previous_month />
icon=icondata_ai::AiLeftOutlined <Button on_click=today>"Today"</Button>
on_click=previous_month <Button icon=icondata_ai::AiRightOutlined on_click=next_month />
/>
<Button on_click=today>
"Today"
</Button>
<Button
icon=icondata_ai::AiRightOutlined
on_click=next_month
/>
</ButtonGroup> </ButtonGroup>
</div> </div>
<div class="thaw-calendar__dates"> <div class="thaw-calendar__dates">
@ -127,7 +118,7 @@ pub fn Calendar(
.into_iter() .into_iter()
.enumerate() .enumerate()
.map(|(index, date)| { .map(|(index, date)| {
view! { <CalendarItem value index=index date=date/> } view! { <CalendarItem value index=index date=date /> }
}) })
.collect_view() .collect_view()
}} }}

View file

@ -7,9 +7,5 @@ pub fn CardFooter(
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
mount_style("card-footer", include_str!("./card-footer.css")); mount_style("card-footer", include_str!("./card-footer.css"));
view! { view! { <div class=class_list!["thaw-card-footer", class]>{children()}</div> }
<div class=class_list!["thaw-card-footer", class]>
{children()}
</div>
}
} }

View file

@ -12,18 +12,12 @@ pub fn CardHeader(
mount_style("card-header", include_str!("./card-header.css")); mount_style("card-header", include_str!("./card-header.css"));
view! { view! {
<div class=class_list!["thaw-card-header", class]> <div class=class_list!["thaw-card-header", class]>
<div class="thaw-card-header__header"> <div class="thaw-card-header__header">{children()}</div>
{children()}
</div>
<OptionComp value=card_header_description let:description> <OptionComp value=card_header_description let:description>
<div class="thaw-card-header__description"> <div class="thaw-card-header__description">{(description.children)()}</div>
{(description.children)()}
</div>
</OptionComp> </OptionComp>
<OptionComp value=card_header_action let:action> <OptionComp value=card_header_action let:action>
<div class="thaw-card-header__action"> <div class="thaw-card-header__action">{(action.children)()}</div>
{(action.children)()}
</div>
</OptionComp> </OptionComp>
</div> </div>
} }

View file

@ -14,10 +14,7 @@ pub fn Card(#[prop(optional, into)] class: MaybeProp<String>, children: Children
mount_style("card", include_str!("./card.css")); mount_style("card", include_str!("./card.css"));
view! { view! {
<div <div class=class_list!["thaw-card", class] role="group">
class=class_list!["thaw-card", class]
role="group"
>
{children()} {children()}
</div> </div>
} }

View file

@ -10,11 +10,14 @@ use thaw_utils::{class_list, mount_style, Model};
pub fn Checkbox( pub fn Checkbox(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
/// The controlled value for the checkbox. /// The controlled value for the checkbox.
#[prop(optional, into)] checked: Model<bool>, #[prop(optional, into)]
checked: Model<bool>,
/// The value of the checkbox to be used in a checkbox group. /// The value of the checkbox to be used in a checkbox group.
#[prop(optional, into)] value: Option<String>, #[prop(optional, into)]
value: Option<String>,
/// The Checkbox's label. /// The Checkbox's label.
#[prop(optional, into)] label: MaybeProp<String>, #[prop(optional, into)]
label: MaybeProp<String>,
) -> impl IntoView { ) -> impl IntoView {
mount_style("checkbox", include_str!("./checkbox.css")); mount_style("checkbox", include_str!("./checkbox.css"));
@ -59,12 +62,11 @@ pub fn Checkbox(
let checked = move || group_checked.get().unwrap_or_else(|| checked.get()); let checked = move || group_checked.get().unwrap_or_else(|| checked.get());
view! { view! {
<span <span class=class_list![
class=class_list![ "thaw-checkbox",
"thaw-checkbox", ("thaw-checkbox--checked", checked), ("thaw-checkbox--checked", checked),
class class
] ]>
>
<input <input
class="thaw-checkbox__input" class="thaw-checkbox__input"
type="checkbox" type="checkbox"
@ -74,27 +76,41 @@ pub fn Checkbox(
on:change=on_change on:change=on_change
/> />
<div aria-hidden="true" class="thaw-checkbox__indicator"> <div aria-hidden="true" class="thaw-checkbox__indicator">
{ {move || {
move || if checked() { if checked() {
view! { view! {
<svg fill="currentColor" aria-hidden="true" width="12" height="12" viewBox="0 0 12 12" style="display: inline;line-height: 0"> <svg
<path d="M9.76 3.2c.3.29.32.76.04 1.06l-4.25 4.5a.75.75 0 0 1-1.08.02L2.22 6.53a.75.75 0 0 1 1.06-1.06l1.7 1.7L8.7 3.24a.75.75 0 0 1 1.06-.04Z" fill="currentColor"></path> fill="currentColor"
aria-hidden="true"
width="12"
height="12"
viewBox="0 0 12 12"
style="display: inline;line-height: 0"
>
<path
d="M9.76 3.2c.3.29.32.76.04 1.06l-4.25 4.5a.75.75 0 0 1-1.08.02L2.22 6.53a.75.75 0 0 1 1.06-1.06l1.7 1.7L8.7 3.24a.75.75 0 0 1 1.06-.04Z"
fill="currentColor"
></path>
</svg> </svg>
}.into() }
.into()
} else { } else {
None None
} }
} }}
</div> </div>
{ {move || {
move || if let Some(label) = label.get() { if let Some(label) = label.get() {
view! { view! {
<label class="thaw-checkbox__label" for=id.clone()>{label}</label> <label class="thaw-checkbox__label" for=id.clone()>
}.into() {label}
</label>
}
.into()
} else { } else {
None None
} }
} }}
</span> </span>
} }
} }

View file

@ -9,7 +9,10 @@ pub fn Code(
) -> impl IntoView { ) -> impl IntoView {
mount_style("code", include_str!("./code.css")); mount_style("code", include_str!("./code.css"));
view! { view! {
<code class=class_list!["thaw-code", class]> <code class=class_list![
"thaw-code",
class
]>
{if let Some(inner_html) = inner_html { {if let Some(inner_html) = inner_html {
EitherOf3::A(view! { <pre inner_html=inner_html></pre> }) EitherOf3::A(view! { <pre inner_html=inner_html></pre> })

View file

@ -158,8 +158,8 @@ pub fn ColorPicker(
data-thaw-id=config_provider.id().clone() data-thaw-id=config_provider.id().clone()
> >
<ColorPanel hue=hue.read_only() sv/> <ColorPanel hue=hue.read_only() sv />
<HueSlider hue/> <HueSlider hue />
</div> </div>
</CSSTransition> </CSSTransition>
</Follower> </Follower>
@ -222,8 +222,7 @@ fn ColorPanel(hue: ReadSignal<f32>, sv: RwSignal<(f32, f32)>) -> impl IntoView {
style:background-image=move || { style:background-image=move || {
format!("linear-gradient(90deg, white, hsl({}, 100%, 50%))", hue.get()) format!("linear-gradient(90deg, white, hsl({}, 100%, 50%))", hue.get())
} }
> ></div>
</div>
<div class="thaw-color-picker-popover__layer--shadowed"></div> <div class="thaw-color-picker-popover__layer--shadowed"></div>
<div <div
class="thaw-color-picker-popover__handle" class="thaw-color-picker-popover__handle"
@ -234,8 +233,7 @@ fn ColorPanel(hue: ReadSignal<f32>, sv: RwSignal<(f32, f32)>) -> impl IntoView {
sv.get().1 * 100.0, sv.get().1 * 100.0,
) )
} }
> ></div>
</div>
</div> </div>
} }
} }

View file

@ -10,7 +10,8 @@ pub fn Combobox(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional, into)] value: Model<String>, #[prop(optional, into)] value: Model<String>,
/// Selected option. /// Selected option.
#[prop(optional, into)] selected_options: VecModel<String>, #[prop(optional, into)]
selected_options: VecModel<String>,
/// Whether the input is disabled. /// Whether the input is disabled.
#[prop(optional, into)] #[prop(optional, into)]
disabled: MaybeSignal<bool>, disabled: MaybeSignal<bool>,
@ -175,9 +176,7 @@ pub fn Combobox(
aria-expanded="true" aria-expanded="true"
role="combobox" role="combobox"
class="thaw-combobox__input" class="thaw-combobox__input"
prop:value=move || { prop:value=move || { value.get() }
value.get()
}
placeholder=move || placeholder.get() placeholder=move || placeholder.get()
disabled=move || disabled.get() disabled=move || disabled.get()
node_ref=input_ref node_ref=input_ref
@ -188,31 +187,45 @@ pub fn Combobox(
is_show_listbox.update(|show| *show = !*show); is_show_listbox.update(|show| *show = !*show);
} }
/> />
{ {if clearable {
if clearable { view! {
view! { <span
<span aria-hidden="true"
class="thaw-combobox__clear-icon"
style=move || {
(!is_show_clear_icon.get())
.then(|| "display: none")
.unwrap_or_default()
}
node_ref=clear_icon_ref
>
<svg
fill="currentColor"
aria-hidden="true" aria-hidden="true"
class="thaw-combobox__clear-icon" width="1em"
style=move || (!is_show_clear_icon.get()).then(|| "display: none").unwrap_or_default() height="1em"
node_ref=clear_icon_ref viewBox="0 0 20 20"
> >
<svg fill="currentColor" aria-hidden="true" width="1em" height="1em" viewBox="0 0 20 20"> <path
<path d="m4.09 4.22.06-.07a.5.5 0 0 1 .63-.06l.07.06L10 9.29l5.15-5.14a.5.5 0 0 1 .63-.06l.07.06c.18.17.2.44.06.63l-.06.07L10.71 10l5.14 5.15c.18.17.2.44.06.63l-.06.07a.5.5 0 0 1-.63.06l-.07-.06L10 10.71l-5.15 5.14a.5.5 0 0 1-.63.06l-.07-.06a.5.5 0 0 1-.06-.63l.06-.07L9.29 10 4.15 4.85a.5.5 0 0 1-.06-.63l.06-.07-.06.07Z" fill="currentColor"></path> d="m4.09 4.22.06-.07a.5.5 0 0 1 .63-.06l.07.06L10 9.29l5.15-5.14a.5.5 0 0 1 .63-.06l.07.06c.18.17.2.44.06.63l-.06.07L10.71 10l5.14 5.15c.18.17.2.44.06.63l-.06.07a.5.5 0 0 1-.63.06l-.07-.06L10 10.71l-5.15 5.14a.5.5 0 0 1-.63.06l-.07-.06a.5.5 0 0 1-.06-.63l.06-.07L9.29 10 4.15 4.85a.5.5 0 0 1-.06-.63l.06-.07-.06.07Z"
</svg> fill="currentColor"
</span> ></path>
}.into() </svg>
} else { </span>
None
} }
} .into()
} else {
None
}}
<span <span
aria-disabled=move || if disabled.get() { "true" } else { "" } aria-disabled=move || if disabled.get() { "true" } else { "" }
aria-expanded=move || is_show_listbox.get().to_string() aria-expanded=move || is_show_listbox.get().to_string()
role="button" role="button"
aria-label="Open" aria-label="Open"
class="thaw-combobox__expand-icon" class="thaw-combobox__expand-icon"
style=move || is_show_clear_icon.get().then(|| "display: none").unwrap_or_default() style=move || {
is_show_clear_icon.get().then(|| "display: none").unwrap_or_default()
}
on:click=move |_| { on:click=move |_| {
if disabled.get_untracked() { if disabled.get_untracked() {
return; return;
@ -223,9 +236,17 @@ pub fn Combobox(
} }
} }
> >
<svg fill="currentColor" aria-hidden="true" width="1em" height="1em" viewBox="0 0 20 20"> <svg
<path d="M15.85 7.65c.2.2.2.5 0 .7l-5.46 5.49a.55.55 0 0 1-.78 0L4.15 8.35a.5.5 0 1 1 .7-.7L10 12.8l5.15-5.16c.2-.2.5-.2.7 0Z" fill="currentColor"> fill="currentColor"
</path> aria-hidden="true"
width="1em"
height="1em"
viewBox="0 0 20 20"
>
<path
d="M15.85 7.65c.2.2.2.5 0 .7l-5.46 5.49a.55.55 0 0 1-.78 0L4.15 8.35a.5.5 0 1 1 .7-.7L10 12.8l5.15-5.16c.2-.2.5-.2.7 0Z"
fill="currentColor"
></path>
</svg> </svg>
</span> </span>
</div> </div>
@ -236,7 +257,12 @@ pub fn Combobox(
width=FollowerWidth::MinTarget width=FollowerWidth::MinTarget
> >
<Provider value=combobox_injection> <Provider value=combobox_injection>
<Listbox open=is_show_listbox.read_only() set_listbox listbox_ref class="thaw-combobox__listbox"> <Listbox
open=is_show_listbox.read_only()
set_listbox
listbox_ref
class="thaw-combobox__listbox"
>
{children()} {children()}
</Listbox> </Listbox>
</Provider> </Provider>

View file

@ -62,33 +62,49 @@ pub fn ComboboxOption(
] ]
on:click=on_click on:click=on_click
> >
{ {if combobox.multiselect {
if combobox.multiselect { view! {
view! { <span aria-hidden="true" class="thaw-combobox-option__check-icon--multiselect">
<span aria-hidden="true" class="thaw-combobox-option__check-icon--multiselect"> <If cond=is_selected>
<If cond=is_selected> <Then slot>
<Then slot> <svg
<svg fill="currentColor" aria-hidden="true" width="12" height="12" viewBox="0 0 12 12"> fill="currentColor"
<path d="M9.76 3.2c.3.29.32.76.04 1.06l-4.25 4.5a.75.75 0 0 1-1.08.02L2.22 6.53a.75.75 0 0 1 1.06-1.06l1.7 1.7L8.7 3.24a.75.75 0 0 1 1.06-.04Z" fill="currentColor"></path> aria-hidden="true"
</svg> width="12"
</Then> height="12"
</If> viewBox="0 0 12 12"
</span> >
}.into_any() <path
} else { d="M9.76 3.2c.3.29.32.76.04 1.06l-4.25 4.5a.75.75 0 0 1-1.08.02L2.22 6.53a.75.75 0 0 1 1.06-1.06l1.7 1.7L8.7 3.24a.75.75 0 0 1 1.06-.04Z"
view! { fill="currentColor"
<span aria-hidden="true" class="thaw-combobox-option__check-icon"> ></path>
<svg fill="currentColor" aria-hidden="true" width="1em" height="1em" viewBox="0 0 20 20"> </svg>
<path d="M7.03 13.9 3.56 10a.75.75 0 0 0-1.12 1l4 4.5c.29.32.79.34 1.09.03l10.5-10.5a.75.75 0 0 0-1.06-1.06l-9.94 9.94Z" fill="currentColor"></path> </Then>
</svg> </If>
</span> </span>
}.into_any()
} }
} .into_any()
} else {
view! {
<span aria-hidden="true" class="thaw-combobox-option__check-icon">
<svg
fill="currentColor"
aria-hidden="true"
width="1em"
height="1em"
viewBox="0 0 20 20"
>
<path
d="M7.03 13.9 3.56 10a.75.75 0 0 0-1.12 1l4 4.5c.29.32.79.34 1.09.03l10.5-10.5a.75.75 0 0 0-1.06-1.06l-9.94 9.94Z"
fill="currentColor"
></path>
</svg>
</span>
}
.into_any()
}}
<OptionComp value=children let:children> <OptionComp value=children let:children>
<Fallback slot> <Fallback slot>{text.get_value()}</Fallback>
{text.get_value()}
</Fallback>
{children()} {children()}
</OptionComp> </OptionComp>
</div> </div>

View file

@ -5,7 +5,8 @@ use thaw_utils::{class_list, mount_style};
pub fn ComboboxOptionGroup( pub fn ComboboxOptionGroup(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
/// Label of the group. /// Label of the group.
#[prop(into)] label: String, #[prop(into)]
label: String,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
mount_style( mount_style(

View file

@ -10,7 +10,8 @@ use thaw_utils::{class_list, mount_style, now_date, ComponentRef, OptionModel};
pub fn DatePicker( pub fn DatePicker(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
/// Set the date picker value. /// Set the date picker value.
#[prop(optional, into)] value: OptionModel<NaiveDate>, #[prop(optional, into)]
value: OptionModel<NaiveDate>,
) -> 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();
@ -71,7 +72,7 @@ pub fn DatePicker(
<div node_ref=date_picker_ref class=class_list!["thaw-date-picker", class]> <div node_ref=date_picker_ref class=class_list!["thaw-date-picker", class]>
<Input 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>
</Input> </Input>
</div> </div>

View file

@ -153,7 +153,7 @@ pub fn DatePanel(
close_panel(Some(*date.deref())); close_panel(Some(*date.deref()));
} }
}; };
view! { <DatePanelItem value date=date on:click=on_click/> } view! { <DatePanelItem value date=date on:click=on_click /> }
}) })
.collect_view() .collect_view()
}} }}

View file

@ -83,14 +83,22 @@ pub fn Panel(
PanelVariant::Date => { PanelVariant::Date => {
let close_panel = close_panel.clone(); let close_panel = close_panel.clone();
view! { view! {
<DatePanel value=selected_date show_date close_panel panel_variant/> <DatePanel
}.into_any() value=selected_date
show_date
close_panel
panel_variant
/>
}
.into_any()
} }
PanelVariant::Month => { PanelVariant::Month => {
view! { <MonthPanel date_panel_show_date=show_date panel_variant/> }.into_any() view! { <MonthPanel date_panel_show_date=show_date panel_variant /> }
.into_any()
} }
PanelVariant::Year => { PanelVariant::Year => {
view! { <YearPanel date_panel_show_date=show_date panel_variant/> }.into_any() view! { <YearPanel date_panel_show_date=show_date panel_variant /> }
.into_any()
} }
} }
}} }}

View file

@ -61,7 +61,7 @@ pub fn MonthPanel(
}); });
panel_variant.set(PanelVariant::Date); panel_variant.set(PanelVariant::Date);
}; };
view! { <MonthPanelItem date_panel_show_date month on:click=on_click/> } view! { <MonthPanelItem date_panel_show_date month on:click=on_click /> }
}) })
.collect_view()} .collect_view()}

View file

@ -62,7 +62,7 @@ pub fn YearPanel(
}); });
panel_variant.set(PanelVariant::Month); panel_variant.set(PanelVariant::Month);
}; };
view! { <YearPanelItem date_panel_show_date year on:click=on_click/> } view! { <YearPanelItem date_panel_show_date year on:click=on_click /> }
}) })
.collect_view() .collect_view()
}} }}

View file

@ -52,9 +52,7 @@ pub fn Dialog(
aria-hidden="true" aria-hidden="true"
></div> ></div>
</CSSTransition> </CSSTransition>
<Provider value=DialogInjection{open}> <Provider value=DialogInjection { open }>{children()}</Provider>
{children()}
</Provider>
</div> </div>
</FocusTrap> </FocusTrap>
</Teleport> </Teleport>

View file

@ -6,9 +6,5 @@ pub fn DialogActions(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
view! { view! { <div class=class_list!["thaw-dialog-actions", class]>{children()}</div> }
<div class=class_list!["thaw-dialog-actions", class]>
{children()}
</div>
}
} }

View file

@ -6,9 +6,5 @@ pub fn DialogBody(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
view! { view! { <div class=class_list!["thaw-dialog-body", class]>{children()}</div> }
<div class=class_list!["thaw-dialog-body", class]>
{children()}
</div>
}
} }

View file

@ -6,9 +6,5 @@ pub fn DialogContent(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
view! { view! { <h2 class=class_list!["thaw-dialog-content", class]>{children()}</h2> }
<h2 class=class_list!["thaw-dialog-content", class]>
{children()}
</h2>
}
} }

View file

@ -6,9 +6,5 @@ pub fn DialogTitle(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
view! { view! { <h2 class=class_list!["thaw-dialog-title", class]>{children()}</h2> }
<h2 class=class_list!["thaw-dialog-title", class]>
{children()}
</h2>
}
} }

View file

@ -6,21 +6,24 @@ use thaw_utils::{class_list, mount_style};
pub fn Divider( pub fn Divider(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
/// A divider can be horizontal (default) or vertical. /// A divider can be horizontal (default) or vertical.
#[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 {
mount_style("divider", include_str!("./divider.css")); mount_style("divider", include_str!("./divider.css"));
view! { view! {
<div <div
class=class_list!["thaw-divider", ("thaw-divider--vertical", move || vertical.get()), class] 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"
> >
<OptionComp value=children let:children> <OptionComp value=children let:children>
<div class="thaw-divider__wrapper"> <div class="thaw-divider__wrapper">{children()}</div>
{children()}
</div>
</OptionComp> </OptionComp>
</div> </div>
} }

View file

@ -9,9 +9,7 @@ pub fn DrawerBody(
) -> impl IntoView { ) -> impl IntoView {
view! { view! {
<Scrollbar> <Scrollbar>
<div class=class_list!["thaw-drawer-body", class]> <div class=class_list!["thaw-drawer-body", class]>{children()}</div>
{children()}
</div>
</Scrollbar> </Scrollbar>
} }
} }

View file

@ -6,9 +6,5 @@ pub fn DrawerHeader(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
view! { view! { <header class=class_list!["thaw-drawer-header", class]>{children()}</header> }
<header class=class_list!["thaw-drawer-header", class]>
{children()}
</header>
}
} }

View file

@ -10,13 +10,9 @@ pub fn DrawerHeaderTitle(
) -> impl IntoView { ) -> impl IntoView {
view! { view! {
<div class=class_list!["thaw-drawer-header-title", class]> <div class=class_list!["thaw-drawer-header-title", class]>
<h2 class="thaw-drawer-header-title__heading"> <h2 class="thaw-drawer-header-title__heading">{children()}</h2>
{children()}
</h2>
<OptionComp value=drawer_header_title_action let:action> <OptionComp value=drawer_header_title_action let:action>
<div class="thaw-drawer-header-title__action"> <div class="thaw-drawer-header-title__action">{(action.children)()}</div>
{(action.children)()}
</div>
</OptionComp> </OptionComp>
</div> </div>
} }

View file

@ -7,11 +7,14 @@ use thaw_utils::{class_list, mount_style, Model};
pub fn InlineDrawer( pub fn InlineDrawer(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
/// Controls the open state of the Drawer. /// Controls the open state of the Drawer.
#[prop(into)] open: Model<bool>, #[prop(into)]
open: Model<bool>,
/// Position of the drawer. /// Position of the drawer.
#[prop(optional, into)] position: MaybeSignal<DrawerPosition>, #[prop(optional, into)]
position: MaybeSignal<DrawerPosition>,
/// Size of the drawer. /// Size of the drawer.
#[prop(optional, into)] size: MaybeSignal<DrawerSize>, #[prop(optional, into)]
size: MaybeSignal<DrawerSize>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
mount_style("drawer", include_str!("./drawer.css")); mount_style("drawer", include_str!("./drawer.css"));
@ -41,10 +44,10 @@ pub fn InlineDrawer(
class class
] ]
style=move || { style=move || {
let size = move || {format!("--thaw-drawer--size: {}", size.get().as_size_str(position))}; let size = move || {
display format!("--thaw-drawer--size: {}", size.get().as_size_str(position))
.get() };
.map_or_else(size, |d| d.to_string()) display.get().map_or_else(size, |d| d.to_string())
} }
node_ref=drawer_ref node_ref=drawer_ref
> >

View file

@ -14,7 +14,8 @@ pub fn OverlayDrawer(
#[prop(default = true.into(), into)] #[prop(default = true.into(), into)]
mask_closeable: MaybeSignal<bool>, mask_closeable: MaybeSignal<bool>,
/// Whether to close drawer on Esc is pressed. /// Whether to close drawer on Esc is pressed.
#[prop(optional, into)] close_on_esc: bool, #[prop(optional, into)]
close_on_esc: bool,
/// Position of the drawer. /// Position of the drawer.
#[prop(optional, into)] #[prop(optional, into)]
position: MaybeSignal<DrawerPosition>, position: MaybeSignal<DrawerPosition>,
@ -55,7 +56,10 @@ 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=class_list!["thaw-config-provider thaw-overlay-drawer-container", class] 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()
@ -88,10 +92,13 @@ pub fn OverlayDrawer(
] ]
style=move || { style=move || {
let size = move || {format!("--thaw-drawer--size: {}", size.get().as_size_str(position))}; let size = move || {
display format!(
.get() "--thaw-drawer--size: {}",
.map_or_else(size, |d| d.to_string()) size.get().as_size_str(position),
)
};
display.get().map_or_else(size, |d| d.to_string())
} }
node_ref=drawer_ref node_ref=drawer_ref
role="dialog" role="dialog"

View file

@ -41,10 +41,7 @@ pub fn GridItem(
}); });
view! { view! {
<div <div class=class_list!["thaw-grid-item", class] style=move || style.get()>
class=class_list!["thaw-grid-item", class]
style=move || style.get()
>
{children()} {children()}
</div> </div>
} }

View file

@ -29,10 +29,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] style=move || style.get()>
class=class_list!["thaw-grid", class]
style=move || style.get()
>
{children()} {children()}
</div> </div>
</Provider> </Provider>

View file

@ -11,9 +11,11 @@ pub fn Image(
#[prop(optional, into)] #[prop(optional, into)]
alt: MaybeProp<String>, alt: MaybeProp<String>,
/// Image width. /// Image width.
#[prop(optional, into)] width: MaybeProp<String>, #[prop(optional, into)]
width: MaybeProp<String>,
/// Image height. /// Image height.
#[prop(optional, into)] height: MaybeProp<String>, #[prop(optional, into)]
height: MaybeProp<String>,
/// An image can appear square, circular, or rounded. /// An image can appear square, circular, or rounded.
#[prop(optional, into)] #[prop(optional, into)]
shape: MaybeSignal<ImageShape>, shape: MaybeSignal<ImageShape>,

View file

@ -6,9 +6,5 @@ pub fn LayoutHeader(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
view! { view! { <div class=class_list!["thaw-layout-header", class]>{children()}</div> }
<div class=class_list!["thaw-layout-header", class]>
{children()}
</div>
}
} }

View file

@ -6,9 +6,11 @@ use thaw_utils::{class_list, mount_style};
pub fn LayoutSider( pub fn LayoutSider(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
/// Addtional classes for the scroll element. /// Addtional classes for the scroll element.
#[prop(optional, into)] content_class: MaybeProp<String>, #[prop(optional, into)]
content_class: MaybeProp<String>,
/// Style of scrollable content node. /// Style of scrollable content node.
#[prop(optional, into)] content_style: 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 file

@ -28,18 +28,22 @@ impl LayoutPosition {
pub fn Layout( pub fn Layout(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
/// Addtional classes for the layout element. /// Addtional classes for the layout element.
#[prop(optional, into)] content_class: MaybeProp<String>, #[prop(optional, into)]
content_class: MaybeProp<String>,
/// Style of scrollable content node. /// Style of scrollable content node.
#[prop(optional, into)] content_style: MaybeProp<String>, #[prop(optional, into)]
content_style: MaybeProp<String>,
/// static position will make it css position set to static. /// static position will make it css position set to static.
/// absolute position will make it css position set to absolute and left, /// absolute position will make it css position set to absolute and left,
/// right, top, bottom to 0. absolute position is very useful /// right, top, bottom to 0. absolute position is very useful
/// when you want to make content scroll in a fixed container or make /// when you want to make content scroll in a fixed container or make
/// the whole page's layout in a fixed position. You may need to change /// the whole page's layout in a fixed position. You may need to change
/// the style of the component to make it display as you expect. /// the style of the component to make it display as you expect.
#[prop(optional)] position: LayoutPosition, #[prop(optional)]
position: LayoutPosition,
/// Whether the component has sider inside. If so it must be true. /// Whether the component has sider inside. If so it must be true.
#[prop(optional, into)] has_sider: MaybeSignal<bool>, #[prop(optional, into)]
has_sider: MaybeSignal<bool>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
mount_style("layout", include_str!("./layout.css")); mount_style("layout", include_str!("./layout.css"));

View file

@ -12,7 +12,7 @@ pub fn LoadingBarProvider(children: Children) -> impl IntoView {
loading_bar_ref, loading_bar_ref,
}> }>
{children()} <Teleport> {children()} <Teleport>
<LoadingBar comp_ref=loading_bar_ref/> <LoadingBar comp_ref=loading_bar_ref />
</Teleport> </Teleport>
</Provider> </Provider>
} }

View file

@ -54,7 +54,7 @@ pub fn MenuItem(
</If> </If>
</Fallback> </Fallback>
<Icon icon=icon style="font-size: 18px; margin-right: 8px"/> <Icon icon=icon style="font-size: 18px; margin-right: 8px" />
</OptionComp> </OptionComp>
<span style="flex-grow: 1">{children()}</span> <span style="flex-grow: 1">{children()}</span>
</div> </div>

View file

@ -24,33 +24,80 @@ pub fn MessageBar(
role="group" role="group"
> >
<div class="thaw-message-bar__icon"> <div class="thaw-message-bar__icon">
{ {move || match intent.get() {
move || match intent.get() { MessageBarIntent::Info => {
MessageBarIntent::Info => EitherOf4::A(view! { EitherOf4::A(
<svg fill="currentColor" aria-hidden="true" width="1em" height="1em" viewBox="0 0 20 20"> view! {
<path d="M18 10a8 8 0 1 0-16 0 8 8 0 0 0 16 0ZM9.5 8.91a.5.5 0 0 1 1 0V13.6a.5.5 0 0 1-1 0V8.9Zm-.25-2.16a.75.75 0 1 1 1.5 0 .75.75 0 0 1-1.5 0Z" fill="currentColor"></path> <svg
</svg> fill="currentColor"
}), aria-hidden="true"
MessageBarIntent::Success => EitherOf4::B(view! { width="1em"
<svg fill="currentColor" aria-hidden="true" width="1em" height="1em" viewBox="0 0 20 20"> height="1em"
<path d="M10 2a8 8 0 1 1 0 16 8 8 0 0 1 0-16Zm3.36 5.65a.5.5 0 0 0-.64-.06l-.07.06L9 11.3 7.35 9.65l-.07-.06a.5.5 0 0 0-.7.7l.07.07 2 2 .07.06c.17.11.4.11.56 0l.07-.06 4-4 .07-.08a.5.5 0 0 0-.06-.63Z" fill="currentColor"> viewBox="0 0 20 20"
</path> >
</svg> <path
}), d="M18 10a8 8 0 1 0-16 0 8 8 0 0 0 16 0ZM9.5 8.91a.5.5 0 0 1 1 0V13.6a.5.5 0 0 1-1 0V8.9Zm-.25-2.16a.75.75 0 1 1 1.5 0 .75.75 0 0 1-1.5 0Z"
MessageBarIntent::Warning => EitherOf4::C(view! { fill="currentColor"
<svg fill="currentColor" aria-hidden="true" width="1em" height="1em" viewBox="0 0 20 20"> ></path>
<path d="M8.68 2.79a1.5 1.5 0 0 1 2.64 0l6.5 12A1.5 1.5 0 0 1 16.5 17h-13a1.5 1.5 0 0 1-1.32-2.21l6.5-12ZM10.5 7.5a.5.5 0 0 0-1 0v4a.5.5 0 0 0 1 0v-4Zm.25 6.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z" fill="currentColor"> </svg>
</path> },
</svg> )
}),
MessageBarIntent::Error => EitherOf4::D(view! {
<svg fill="currentColor" aria-hidden="true" width="1em" height="1em" viewBox="0 0 20 20">
<path d="M10 2a8 8 0 1 1 0 16 8 8 0 0 1 0-16ZM7.8 7.11a.5.5 0 0 0-.63.06l-.06.07a.5.5 0 0 0 .06.64L9.3 10l-2.12 2.12-.06.07a.5.5 0 0 0 .06.64l.07.06c.2.13.47.11.64-.06L10 10.7l2.12 2.12.07.06c.2.13.46.11.64-.06l.06-.07a.5.5 0 0 0-.06-.64L10.7 10l2.12-2.12.06-.07a.5.5 0 0 0-.06-.64l-.07-.06a.5.5 0 0 0-.64.06L10 9.3 7.88 7.17l-.07-.06Z" fill="currentColor">
</path>
</svg>
}),
} }
} MessageBarIntent::Success => {
EitherOf4::B(
view! {
<svg
fill="currentColor"
aria-hidden="true"
width="1em"
height="1em"
viewBox="0 0 20 20"
>
<path
d="M10 2a8 8 0 1 1 0 16 8 8 0 0 1 0-16Zm3.36 5.65a.5.5 0 0 0-.64-.06l-.07.06L9 11.3 7.35 9.65l-.07-.06a.5.5 0 0 0-.7.7l.07.07 2 2 .07.06c.17.11.4.11.56 0l.07-.06 4-4 .07-.08a.5.5 0 0 0-.06-.63Z"
fill="currentColor"
></path>
</svg>
},
)
}
MessageBarIntent::Warning => {
EitherOf4::C(
view! {
<svg
fill="currentColor"
aria-hidden="true"
width="1em"
height="1em"
viewBox="0 0 20 20"
>
<path
d="M8.68 2.79a1.5 1.5 0 0 1 2.64 0l6.5 12A1.5 1.5 0 0 1 16.5 17h-13a1.5 1.5 0 0 1-1.32-2.21l6.5-12ZM10.5 7.5a.5.5 0 0 0-1 0v4a.5.5 0 0 0 1 0v-4Zm.25 6.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z"
fill="currentColor"
></path>
</svg>
},
)
}
MessageBarIntent::Error => {
EitherOf4::D(
view! {
<svg
fill="currentColor"
aria-hidden="true"
width="1em"
height="1em"
viewBox="0 0 20 20"
>
<path
d="M10 2a8 8 0 1 1 0 16 8 8 0 0 1 0-16ZM7.8 7.11a.5.5 0 0 0-.63.06l-.06.07a.5.5 0 0 0 .06.64L9.3 10l-2.12 2.12-.06.07a.5.5 0 0 0 .06.64l.07.06c.2.13.47.11.64-.06L10 10.7l2.12 2.12.07.06c.2.13.46.11.64-.06l.06-.07a.5.5 0 0 0-.06-.64L10.7 10l2.12-2.12.06-.07a.5.5 0 0 0-.06-.64l-.07-.06a.5.5 0 0 0-.64.06L10 9.3 7.88 7.17l-.07-.06Z"
fill="currentColor"
></path>
</svg>
},
)
}
}}
</div> </div>
{children()} {children()}

View file

@ -6,9 +6,7 @@ pub fn MessageBarActions(
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
view! { view! {
<div class="thaw-message-bar-actions"> <div class="thaw-message-bar-actions">{children()}</div>
{children()}
</div>
<div class="tha-message-bar-actions__container-action"> <div class="tha-message-bar-actions__container-action">
{(message_bar_container_action.children)()} {(message_bar_container_action.children)()}
</div> </div>

View file

@ -6,9 +6,5 @@ pub fn MessageBarBody(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
view! { view! { <div class=class_list!["thaw-message-bar-body", class]>{children()}</div> }
<div class=class_list!["thaw-message-bar-body", class]>
{children()}
</div>
}
} }

View file

@ -6,9 +6,5 @@ pub fn MessageBarTitle(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
view! { view! { <span class=class_list!["thaw-message-bar-title", class]>{children()}</span> }
<span class=class_list!["thaw-message-bar-title", class]>
{children()}
</span>
}
} }

View file

@ -77,17 +77,13 @@ pub fn NavCategory(
on:click=on_click on:click=on_click
aria-expanded=move || is_show_group.get() aria-expanded=move || is_show_group.get()
> >
{ {move || {
move || { if let Some(icon) = item_icon.get() {
if let Some(icon) = item_icon.get() { Either::Left(view! { <Icon icon=icon style="font-size: 20px" /> })
Either::Left(view! { } else {
<Icon icon=icon style="font-size: 20px"/> Either::Right(())
})
} else {
Either::Right(())
}
} }
} }}
{item_children()} {item_children()}
<span aria-hidden="true" class="thaw-nav-category-item__expand-icon"> <span aria-hidden="true" class="thaw-nav-category-item__expand-icon">
<svg <svg
@ -96,13 +92,18 @@ pub fn NavCategory(
width="20" width="20"
height="20" height="20"
viewBox="0 0 20 20" viewBox="0 0 20 20"
style=move || if is_show_group.get() { style=move || {
"transform: rotate(90deg)" if is_show_group.get() {
} else { "transform: rotate(90deg)"
"transform: rotate(0deg)" } else {
"transform: rotate(0deg)"
}
} }
> >
<path d="M7.65 4.15c.2-.2.5-.2.7 0l5.49 5.46c.21.22.21.57 0 .78l-5.49 5.46a.5.5 0 0 1-.7-.7L12.8 10 7.65 4.85a.5.5 0 0 1 0-.7Z" fill="currentColor"></path> <path
d="M7.65 4.15c.2-.2.5-.2.7 0l5.49 5.46c.21.22.21.57 0 .78l-5.49 5.46a.5.5 0 0 1-.7-.7L12.8 10 7.65 4.85a.5.5 0 0 1 0-.7Z"
fill="currentColor"
></path>
</svg> </svg>
</span> </span>
</button> </button>

View file

@ -19,15 +19,16 @@ pub fn NavDrawer(
mount_style("nav-drawer", include_str!("./nav-drawer.css")); mount_style("nav-drawer", include_str!("./nav-drawer.css"));
view! { view! {
<Provider value=NavDrawerInjection{ selected_value, selected_category_value }> <Provider value=NavDrawerInjection {
selected_value,
selected_category_value,
}>
<div class=class_list!["thaw-nav-drawer", class]> <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>
<div class="thaw-nav-drawer__body"> <div class="thaw-nav-drawer__body">
<Scrollbar> <Scrollbar>{children()}</Scrollbar>
{children()}
</Scrollbar>
</div> </div>
<OptionComp value=nav_drawer_footer let:footer> <OptionComp value=nav_drawer_footer let:footer>
<footer class="thaw-nav-drawer__footer">{(footer.children)()}</footer> <footer class="thaw-nav-drawer__footer">{(footer.children)()}</footer>

View file

@ -25,17 +25,13 @@ pub fn NavItem(
let children = || { let children = || {
view! { view! {
{ {move || {
move || { if let Some(icon) = icon.get() {
if let Some(icon) = icon.get() { Either::Left(view! { <Icon icon=icon style="font-size: 20px" /> })
Either::Left(view! { } else {
<Icon icon=icon style="font-size: 20px"/> Either::Right(())
})
} else {
Either::Right(())
}
} }
} }}
{children()} {children()}
} }
}; };
@ -49,7 +45,11 @@ pub fn NavItem(
if let Some(href) = href { if let Some(href) = href {
Either::Left(view! { Either::Left(view! {
<a <a
class=class_list!["thaw-nav-item", ("thaw-nav-item--selected", move || selected.get()), class] class=class_list![
"thaw-nav-item",
("thaw-nav-item--selected", move || selected.get()),
class
]
href=move || href.get() href=move || href.get()
on:click=on_click on:click=on_click
> >
@ -59,7 +59,11 @@ pub fn NavItem(
} else { } else {
Either::Right(view! { Either::Right(view! {
<button <button
class=class_list!["thaw-nav-item", ("thaw-nav-item--selected", move || selected.get()), class] class=class_list![
"thaw-nav-item",
("thaw-nav-item--selected", move || selected.get()),
class
]
on:click=on_click on:click=on_click
> >
{children()} {children()}
@ -81,8 +85,8 @@ pub fn NavSubItem(
}); });
if let Some(href) = href { if let Some(href) = href {
Either::Left(view! { <NavItem class href icon value children/> }) Either::Left(view! { <NavItem class href icon value children /> })
} else { } else {
Either::Right(view! { <NavItem class icon value children/> }) Either::Right(view! { <NavItem class icon value children /> })
} }
} }

View file

@ -7,11 +7,14 @@ use thaw_utils::{class_list, mount_style, Model};
pub fn Pagination( pub fn Pagination(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
/// The current page starts from 1. /// The current page starts from 1.
#[prop(default = 1.into(), into)] page: Model<usize>, #[prop(default = 1.into(), into)]
page: Model<usize>,
/// The total numbers of pages. /// The total numbers of pages.
#[prop(into)] page_count: MaybeSignal<usize>, #[prop(into)]
page_count: MaybeSignal<usize>,
/// Number of visible pages after and before the current page. /// Number of visible pages after and before the current page.
#[prop(default = 1.into(), into)] sibling_count: MaybeSignal<usize>, #[prop(default = 1.into(), into)]
sibling_count: MaybeSignal<usize>,
) -> impl IntoView { ) -> impl IntoView {
mount_style("pagination", include_str!("./pagination.css")); mount_style("pagination", include_str!("./pagination.css"));
@ -34,35 +37,38 @@ pub fn Pagination(
icon=icondata_ai::AiLeftOutlined icon=icondata_ai::AiLeftOutlined
disabled=no_previous disabled=no_previous
/> />
{ {move || {
move || { use_pagination(page.get(), page_count.get(), sibling_count.get())
use_pagination(page.get(), page_count.get(), sibling_count.get()).into_iter().map(|item| { .into_iter()
.map(|item| {
if let PaginationItem::Number(nb) = item { if let PaginationItem::Number(nb) = item {
Either::Left(view! { Either::Left(
<Button view! {
class="thaw-pagination-item" <Button
appearance=Memo::new(move |_| if page.get() == nb { class="thaw-pagination-item"
ButtonAppearance::Primary appearance=Memo::new(move |_| {
} else { if page.get() == nb {
ButtonAppearance::Secondary ButtonAppearance::Primary
}) } else {
on_click=move |_| { ButtonAppearance::Secondary
if page.get() != nb { }
page.set(nb) })
on_click=move |_| {
if page.get() != nb {
page.set(nb)
}
} }
} >
> {nb}
{nb} </Button>
</Button> },
}) )
} else { } else {
Either::Right(view! { Either::Right(view! { <div class="thaw-pagination-item">"..."</div> })
<div class="thaw-pagination-item">"..."</div>
})
} }
}).collect_view() })
} .collect_view()
} }}
<Button <Button
class="thaw-pagination-item" class="thaw-pagination-item"
on_click=on_click_next on_click=on_click_next

View file

@ -146,8 +146,7 @@ pub fn Popover(
on:mouseleave=on_mouse_leave on:mouseleave=on_mouse_leave
> >
{children()} {children()}
<div class="thaw-popover-surface__angle"> <div class="thaw-popover-surface__angle"></div>
</div>
</div> </div>
</CSSTransition> </CSSTransition>
</Follower> </Follower>

View file

@ -36,8 +36,7 @@ pub fn ProgressBar(
aria-valuemin="0" aria-valuemin="0"
aria-valuenow=move || value.get() aria-valuenow=move || value.get()
> >
<div class="thaw-progress-bar__bar" style=style> <div class="thaw-progress-bar__bar" style=style></div>
</div>
</div> </div>
} }
} }

View file

@ -86,7 +86,8 @@ pub fn ProgressCircle(
<div class="thaw-progress-circle__content thaw-progress-circle__content--text"> <div class="thaw-progress-circle__content thaw-progress-circle__content--text">
{move || value.get()} "%" {move || value.get()} "%"
</div> </div>
}.into_any() }
.into_any()
}} }}
</div> </div>

View file

@ -46,15 +46,18 @@ pub fn Radio(
on:change=on_change on:change=on_change
/> />
<div aria-hidden="true" class="thaw-radio__indicator"></div> <div aria-hidden="true" class="thaw-radio__indicator"></div>
{ {move || {
move || if let Some(label) = label.get() { if let Some(label) = label.get() {
view! { view! {
<label class="thaw-radio__label" for=id.clone()>{label}</label> <label class="thaw-radio__label" for=id.clone()>
}.into() {label}
</label>
}
.into()
} else { } else {
None None
} }
} }}
</span> </span>
} }
} }

View file

@ -5,7 +5,8 @@ use thaw_utils::{class_list, OptionModel};
pub fn RadioGroup( pub fn RadioGroup(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
/// The selected Radio item in this group. /// The selected Radio item in this group.
#[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)]
name: Option<String>, name: Option<String>,
@ -14,8 +15,12 @@ pub fn RadioGroup(
let name = name.unwrap_or_else(|| uuid::Uuid::new_v4().to_string()); let name = name.unwrap_or_else(|| uuid::Uuid::new_v4().to_string());
view! { view! {
<Provider value=RadioGroupInjection{ value, name }> <Provider value=RadioGroupInjection { value, name }>
<div class=class_list!["thaw-radio-group", class] 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

@ -6,11 +6,14 @@ pub fn Scrollbar(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional, into)] style: MaybeProp<String>, #[prop(optional, into)] style: MaybeProp<String>,
/// Class name of content div. /// Class name of content div.
#[prop(optional, into)] content_class: MaybeProp<String>, #[prop(optional, into)]
content_class: MaybeProp<String>,
/// Style of content div. /// Style of content div.
#[prop(optional, into)] content_style: MaybeProp<String>, #[prop(optional, into)]
content_style: MaybeProp<String>,
/// Size of scrollbar. /// Size of scrollbar.
#[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,
) -> impl IntoView { ) -> impl IntoView {
@ -299,15 +302,10 @@ 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]
"thaw-scrollbar__content", content_class
]
style=move || { style=move || {
format!( format!("width: fit-content; {}", content_style.get().unwrap_or_default())
"width: fit-content; {}",
content_style.get().unwrap_or_default(),
)
} }
node_ref=content_ref node_ref=content_ref
@ -318,7 +316,9 @@ pub fn Scrollbar(
<div class="thaw-scrollbar__track--vertical" node_ref=y_track_ref> <div class="thaw-scrollbar__track--vertical" node_ref=y_track_ref>
<div <div
class="thaw-scrollabr__thumb" class="thaw-scrollabr__thumb"
style:display=move || (!is_show_y_thumb.get()).then_some("none").unwrap_or_default() style:display=move || {
(!is_show_y_thumb.get()).then_some("none").unwrap_or_default()
}
style:height=move || format!("{}px", y_thumb_height.get()) style:height=move || format!("{}px", y_thumb_height.get())
style:top=move || format!("{}px", y_thumb_top.get()) style:top=move || format!("{}px", y_thumb_top.get())
on:mousedown=on_y_thumb_mousedown on:mousedown=on_y_thumb_mousedown
@ -327,7 +327,9 @@ pub fn Scrollbar(
<div class="thaw-scrollbar__track--horizontal" node_ref=x_track_ref> <div class="thaw-scrollbar__track--horizontal" node_ref=x_track_ref>
<div <div
class="thaw-scrollabr__thumb" class="thaw-scrollabr__thumb"
style:display=move || (!is_show_x_thumb.get()).then_some("none").unwrap_or_default() style:display=move || {
(!is_show_x_thumb.get()).then_some("none").unwrap_or_default()
}
style:width=move || format!("{}px", x_thumb_width.get()) style:width=move || format!("{}px", x_thumb_width.get())
style:left=move || format!("{}px", x_thumb_left.get()) style:left=move || format!("{}px", x_thumb_left.get())
on:mousedown=on_x_thumb_mousedown on:mousedown=on_x_thumb_mousedown

View file

@ -7,11 +7,7 @@ pub fn Skeleton(
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
view! { view! {
<div <div role="progressbar" aria-busy="true" class=class_list!["thaw-skeleton", class]>
role="progressbar"
aria-busy="true"
class=class_list!["thaw-skeleton", class]
>
{children()} {children()}
</div> </div>
} }

View file

@ -5,8 +5,5 @@ use thaw_utils::{class_list, mount_style};
pub fn SkeletonItem(#[prop(optional, into)] class: MaybeProp<String>) -> 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=class_list!["thaw-skeleton-item", class]></div> }
<div class=class_list!["thaw-skeleton-item", class]>
</div>
}
} }

View file

@ -76,10 +76,7 @@ pub fn Slider(
view! { view! {
<Provider value=SliderInjection { max, min }> <Provider value=SliderInjection { max, min }>
<div <div class=class_list!["thaw-slider", class] style=css_vars>
class=class_list!["thaw-slider", class]
style=css_vars
>
<input <input
min=move || min.get() min=move || min.get()
max=move || max.get() max=move || max.get()
@ -91,10 +88,8 @@ pub fn Slider(
prop:value=move || current_value.get() prop:value=move || current_value.get()
list=list_id.clone() list=list_id.clone()
/> />
<div class="thaw-slider__rail"> <div class="thaw-slider__rail"></div>
</div> <div class="thaw-slider__thumb"></div>
<div class="thaw-slider__thumb">
</div>
<OptionComp value=children let:children> <OptionComp value=children let:children>
<datalist id=list_id class="thaw-slider__datalist"> <datalist id=list_id class="thaw-slider__datalist">
{children()} {children()}

View file

@ -20,11 +20,7 @@ pub fn SliderLabel(
}; };
view! { view! {
<option <option class=class_list!["thaw-slider-label", class] style=style value=move || value.get()>
class=class_list!["thaw-slider-label", class]
style=style
value=move || value.get()
>
{children()} {children()}
</option> </option>

View file

@ -16,13 +16,17 @@ pub enum SpaceGap {
pub fn Space( pub fn Space(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
/// Space's gap. /// Space's gap.
#[prop(optional)] gap: SpaceGap, #[prop(optional)]
gap: SpaceGap,
/// Whether to lay out vertically. /// Whether to lay out vertically.
#[prop(optional)] vertical: bool, #[prop(optional)]
vertical: bool,
/// Vertical arrangement. /// Vertical arrangement.
#[prop(optional, into)] align: MaybeProp<SpaceAlign>, #[prop(optional, into)]
align: MaybeProp<SpaceAlign>,
/// Horizontal arrangement. /// Horizontal arrangement.
#[prop(optional, into)] justify: MaybeProp<SpaceJustify>, #[prop(optional, into)]
justify: MaybeProp<SpaceJustify>,
children: ChildrenFragment, children: ChildrenFragment,
) -> impl IntoView { ) -> impl IntoView {
mount_style("space", include_str!("./space.css")); mount_style("space", include_str!("./space.css"));

View file

@ -78,9 +78,11 @@ where
}; };
view! { view! {
<span <span class=class_list![
class=class_list!["thaw-spin-button", ("thaw-spin-button--disabled", move || disabled.get()), class] "thaw-spin-button",
> ("thaw-spin-button--disabled", move || disabled.get()),
class
]>
<input <input
autocomplete="off" autocomplete="off"
role="spinbutton" role="spinbutton"
@ -105,7 +107,10 @@ where
aria-label="Increment value" aria-label="Increment value"
type="button" type="button"
class="thaw-spin-button__increment-button" class="thaw-spin-button__increment-button"
class=("thaw-spin-button__increment-button--disabled", move || increment_disabled.get()) class=(
"thaw-spin-button__increment-button--disabled",
move || increment_disabled.get(),
)
disabled=move || disabled.get() disabled=move || disabled.get()
on:click=move |_| { on:click=move |_| {
if !increment_disabled.get_untracked() { if !increment_disabled.get_untracked() {
@ -113,8 +118,17 @@ where
} }
} }
> >
<svg fill="currentColor" aria-hidden="true" width="16" height="16" viewBox="0 0 16 16"> <svg
<path d="M3.15 10.35c.2.2.5.2.7 0L8 6.21l4.15 4.14a.5.5 0 0 0 .7-.7l-4.5-4.5a.5.5 0 0 0-.7 0l-4.5 4.5a.5.5 0 0 0 0 .7Z" fill="currentColor"></path> fill="currentColor"
aria-hidden="true"
width="16"
height="16"
viewBox="0 0 16 16"
>
<path
d="M3.15 10.35c.2.2.5.2.7 0L8 6.21l4.15 4.14a.5.5 0 0 0 .7-.7l-4.5-4.5a.5.5 0 0 0-.7 0l-4.5 4.5a.5.5 0 0 0 0 .7Z"
fill="currentColor"
></path>
</svg> </svg>
</button> </button>
<button <button
@ -123,15 +137,27 @@ where
type="button" type="button"
class="thaw-spin-button__decrement-button" class="thaw-spin-button__decrement-button"
disabled=move || disabled.get() disabled=move || disabled.get()
class=("thaw-spin-button__decrement-button--disabled", move || decrement_disabled.get()) class=(
"thaw-spin-button__decrement-button--disabled",
move || decrement_disabled.get(),
)
on:click=move |_| { on:click=move |_| {
if !decrement_disabled.get_untracked() { if !decrement_disabled.get_untracked() {
update_value(value.get_untracked() - step_page.get_untracked()); update_value(value.get_untracked() - step_page.get_untracked());
} }
} }
> >
<svg fill="currentColor" aria-hidden="true" width="16" height="16" viewBox="0 0 16 16"> <svg
<path d="M3.15 5.65c.2-.2.5-.2.7 0L8 9.79l4.15-4.14a.5.5 0 0 1 .7.7l-4.5 4.5a.5.5 0 0 1-.7 0l-4.5-4.5a.5.5 0 0 1 0-.7Z" fill="currentColor"></path> fill="currentColor"
aria-hidden="true"
width="16"
height="16"
viewBox="0 0 16 16"
>
<path
d="M3.15 5.65c.2-.2.5-.2.7 0L8 9.79l4.15-4.14a.5.5 0 0 1 .7.7l-4.5 4.5a.5.5 0 0 1-.7 0l-4.5-4.5a.5.5 0 0 1 0-.7Z"
fill="currentColor"
></path>
</svg> </svg>
</button> </button>
</span> </span>

View file

@ -55,26 +55,29 @@ pub fn Spinner(
view! { view! {
<div <div
class=class_list!["thaw-spinner", move || format!("thaw-spinner--{}", size.get().as_str()), class] class=class_list![
"thaw-spinner",
move || format!("thaw-spinner--{}", size.get().as_str()),
class
]
role="progressbar" role="progressbar"
aria-labelledby=labelledby aria-labelledby=labelledby
> >
<span class="thaw-spinner__spinner"> <span class="thaw-spinner__spinner">
<span class="thaw-spinner__spinner-tail"></span> <span class="thaw-spinner__spinner-tail"></span>
</span> </span>
{ {move || {
move || { if let Some(label) = label.get() {
if let Some(label) = label.get() { view! {
view! { <label class="thaw-spinner__label" id=id.get_value()>
<label class="thaw-spinner__label" id=id.get_value()> {label}
{label} </label>
</label>
}.into()
} else {
None
} }
.into()
} else {
None
} }
} }}
</div> </div>
} }
} }

View file

@ -5,9 +5,11 @@ use thaw_utils::{class_list, mount_style, Model};
pub fn Switch( pub fn Switch(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
/// Defines the controlled checked state of the Switch. /// Defines the controlled checked state of the Switch.
#[prop(optional, into)] checked: Model<bool>, #[prop(optional, into)]
checked: Model<bool>,
/// The Switch's label. /// The Switch's label.
#[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"));
@ -30,19 +32,28 @@ pub fn Switch(
on:change=on_change on:change=on_change
/> />
<div aria-hidden="true" class="thaw-switch__indicator thaw-switch__button"> <div aria-hidden="true" class="thaw-switch__indicator thaw-switch__button">
<svg fill="currentColor" aria-hidden="true" width="1em" height="1em" viewBox="0 0 20 20"> <svg
fill="currentColor"
aria-hidden="true"
width="1em"
height="1em"
viewBox="0 0 20 20"
>
<path d="M10 2a8 8 0 1 0 0 16 8 8 0 0 0 0-16Z" fill="currentColor"></path> <path d="M10 2a8 8 0 1 0 0 16 8 8 0 0 0 0-16Z" fill="currentColor"></path>
</svg> </svg>
</div> </div>
{ {move || {
move || if let Some(label) = label.get() { if let Some(label) = label.get() {
view! { view! {
<label class="thaw-switch__label" for=id.clone()>{label}</label> <label class="thaw-switch__label" for=id.clone()>
}.into() {label}
</label>
}
.into()
} else { } else {
None None
} }
} }}
</div> </div>
} }
} }

View file

@ -24,10 +24,7 @@ pub fn TabList(
selected_value, selected_value,
registered_tabs, registered_tabs,
}> }>
<div <div class=class_list!["thaw-tab-list", class] role="tablist">
class=class_list!["thaw-tab-list", class]
role="tablist"
>
{children()} {children()}
</div> </div>
</Provider> </Provider>

View file

@ -7,7 +7,8 @@ use thaw_utils::{class_list, mount_style};
pub fn Tab( pub fn Tab(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
/// The indentifier of the tab. /// The indentifier of the tab.
#[prop(into)] value: String, #[prop(into)]
value: String,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
mount_style("tab", include_str!("./tab.css")); mount_style("tab", include_str!("./tab.css"));
@ -62,17 +63,13 @@ pub fn Tab(
view! { view! {
<button <button
class=class_list![ class=class_list!["thaw-tab", ("thaw-tab--selected", move || selected.get()), class]
"thaw-tab", ("thaw-tab--selected", move || selected.get()), class
]
role="tab" role="tab"
aria-selected=move || if selected.get() { "true" } else { "false" } aria-selected=move || if selected.get() { "true" } else { "false" }
node_ref=tab_ref node_ref=tab_ref
on:click=on_select on:click=on_select
> >
<span class="thaw-tab__content"> <span class="thaw-tab__content">{children()}</span>
{children()}
</span>
</button> </button>
} }
} }

View file

@ -8,11 +8,7 @@ pub fn Table(
) -> impl IntoView { ) -> impl IntoView {
mount_style("table", include_str!("./table.css")); mount_style("table", include_str!("./table.css"));
view! { view! { <table class=class_list!["thaw-table", class]>{children()}</table> }
<table class=class_list!["thaw-table", class]>
{children()}
</table>
}
} }
#[component] #[component]
@ -20,11 +16,7 @@ pub fn TableHeader(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
view! { view! { <thead class=class_list!["thaw-table-header", class]>{children()}</thead> }
<thead class=class_list!["thaw-table-header", class]>
{children()}
</thead>
}
} }
#[component] #[component]
@ -35,13 +27,11 @@ pub fn TableHeaderCell(
view! { view! {
<th class=class_list!["thaw-table-header-cell", class]> <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 { Either::Left(children())
Either::Left(children()) } else {
} else { Either::Right(())
Either::Right(()) }}
}
}
</button> </button>
</th> </th>
} }
@ -52,11 +42,7 @@ pub fn TableBody(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
view! { view! { <tbody class=class_list!["thaw-table-body", class]>{children()}</tbody> }
<tbody class=class_list!["thaw-table-body", class]>
{children()}
</tbody>
}
} }
#[component] #[component]
@ -64,11 +50,7 @@ pub fn TableRow(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
view! { view! { <tr class=class_list!["thaw-table-row", class]>{children()}</tr> }
<tr class=class_list!["thaw-table-row", class]>
{children()}
</tr>
}
} }
#[component] #[component]
@ -77,14 +59,14 @@ pub fn TableCell(
#[prop(optional)] children: Option<Children>, #[prop(optional)] children: Option<Children>,
) -> impl IntoView { ) -> impl IntoView {
view! { view! {
<td class=class_list!["thaw-table-cell", class]> <td class=class_list![
{ "thaw-table-cell", class
if let Some(children) = children { ]>
Either::Left(children()) {if let Some(children) = children {
} else { Either::Left(children())
Either::Right(()) } else {
} Either::Right(())
} }}
</td> </td>
} }
} }
@ -94,9 +76,5 @@ pub fn TableCellLayout(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
view! { view! { <div class=class_list!["thaw-table-cell-layout", class]>{children()}</div> }
<div class=class_list!["thaw-table-cell-layout", class]>
{children()}
</div>
}
} }

View file

@ -15,10 +15,8 @@ pub fn Tag(
mount_style("tag", include_str!("./tag.css")); mount_style("tag", include_str!("./tag.css"));
view! { view! {
<span <span class=class_list!["thaw-tag", ("thaw-tag--closable", move || closable.get()), class]>
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>
{move || { {move || {
@ -30,13 +28,24 @@ pub fn Tag(
on_close(event); on_close(event);
}; };
if closable.get() { if closable.get() {
Either::Left(view! { Either::Left(
<button class="thaw-tag__close" on:click=on_close> view! {
<svg fill="currentColor" aria-hidden="true" width="1em" height="1em" viewBox="0 0 20 20"> <button class="thaw-tag__close" on:click=on_close>
<path d="m4.09 4.22.06-.07a.5.5 0 0 1 .63-.06l.07.06L10 9.29l5.15-5.14a.5.5 0 0 1 .63-.06l.07.06c.18.17.2.44.06.63l-.06.07L10.71 10l5.14 5.15c.18.17.2.44.06.63l-.06.07a.5.5 0 0 1-.63.06l-.07-.06L10 10.71l-5.15 5.14a.5.5 0 0 1-.63.06l-.07-.06a.5.5 0 0 1-.06-.63l.06-.07L9.29 10 4.15 4.85a.5.5 0 0 1-.06-.63l.06-.07-.06.07Z" fill="currentColor"></path> <svg
</svg> fill="currentColor"
</button> aria-hidden="true"
}) width="1em"
height="1em"
viewBox="0 0 20 20"
>
<path
d="m4.09 4.22.06-.07a.5.5 0 0 1 .63-.06l.07.06L10 9.29l5.15-5.14a.5.5 0 0 1 .63-.06l.07.06c.18.17.2.44.06.63l-.06.07L10.71 10l5.14 5.15c.18.17.2.44.06.63l-.06.07a.5.5 0 0 1-.63.06l-.07-.06L10 10.71l-5.15 5.14a.5.5 0 0 1-.63.06l-.07-.06a.5.5 0 0 1-.06-.63l.06-.07L9.29 10 4.15 4.85a.5.5 0 0 1-.06-.63l.06-.07-.06.07Z"
fill="currentColor"
></path>
</svg>
</button>
},
)
} else { } else {
Either::Right(()) Either::Right(())
} }

View file

@ -11,9 +11,7 @@ pub fn Caption1(
let class = let class =
Signal::derive(move || format!("thaw-caption-1 {}", class.get().unwrap_or_default())); Signal::derive(move || format!("thaw-caption-1 {}", class.get().unwrap_or_default()));
view! { view! { <Text tag children class style /> }
<Text tag children class style/>
}
} }
#[component] #[component]
@ -27,9 +25,7 @@ pub fn Caption1Strong(
format!("thaw-caption-1-strong {}", class.get().unwrap_or_default()) format!("thaw-caption-1-strong {}", class.get().unwrap_or_default())
}); });
view! { view! { <Text tag children class style /> }
<Text tag children class style/>
}
} }
#[component] #[component]
@ -41,9 +37,7 @@ pub fn Body1(
) -> impl IntoView { ) -> impl IntoView {
let class = Signal::derive(move || format!("thaw-body-1 {}", class.get().unwrap_or_default())); let class = Signal::derive(move || format!("thaw-body-1 {}", class.get().unwrap_or_default()));
view! { view! { <Text tag children class style /> }
<Text tag children class style/>
}
} }
#[component] #[component]

View file

@ -72,14 +72,12 @@ pub fn Textarea(
// } // }
view! { view! {
<span <span class=class_list![
class=class_list![ "thaw-textarea",
"thaw-textarea", ("thaw-textarea--disabled", move || disabled.get()),
("thaw-textarea--disabled", move || disabled.get()), move || format!("thaw-textarea--resize-{}", resize.get().as_str()),
move || format!("thaw-textarea--resize-{}", resize.get().as_str()), class
class ]>
]
>
<textarea <textarea
prop:value=move || { prop:value=move || {
value_trigger.track(); value_trigger.track();

View file

@ -75,7 +75,7 @@ pub fn TimePicker(
<div node_ref=time_picker_ref class=class_list!["thaw-time-picker", class]> <div node_ref=time_picker_ref class=class_list!["thaw-time-picker", class]>
<Input 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>
</Input> </Input>
</div> </div>

View file

@ -7,11 +7,7 @@ pub fn Toast(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
view! { view! { <div class=class_list!["thaw-toast", class]>{children()}</div> }
<div class=class_list!["thaw-toast", class]>
{children()}
</div>
}
} }
#[derive(Default, Clone, Copy)] #[derive(Default, Clone, Copy)]

View file

@ -7,13 +7,9 @@ pub fn ToastBody(
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
view! { view! {
<div class="thaw-toast-body"> <div class="thaw-toast-body">{children()}</div>
{children()}
</div>
<OptionComp value=toast_body_subtitle let:subtitle> <OptionComp value=toast_body_subtitle let:subtitle>
<div class="thaw-toast-body__subtitle"> <div class="thaw-toast-body__subtitle">{(subtitle.children)()}</div>
{(subtitle.children)()}
</div>
</OptionComp> </OptionComp>
} }
} }

View file

@ -6,9 +6,5 @@ pub fn ToastFooter(
#[prop(optional, into)] class: MaybeProp<String>, #[prop(optional, into)] class: MaybeProp<String>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
view! { view! { <div class=class_list!["thaw-toast-footer", class]>{children()}</div> }
<div class=class_list!["thaw-toast-footer", class]>
{children()}
</div>
}
} }

View file

@ -9,25 +9,30 @@ pub fn ToastTitle(
) -> impl IntoView { ) -> impl IntoView {
view! { view! {
<div class="thaw-toast-title__media"> <div class="thaw-toast-title__media">
{ {if let Some(media) = toast_title_media {
if let Some(media) = toast_title_media { Either::Left((media.children)())
Either::Left((media.children)()) } else {
} else { Either::Right(
Either::Right(view! { view! {
<svg fill="currentColor" aria-hidden="true" width="1em" height="1em" viewBox="0 0 20 20"> <svg
<path d="M18 10a8 8 0 1 0-16 0 8 8 0 0 0 16 0ZM9.5 8.91a.5.5 0 0 1 1 0V13.6a.5.5 0 0 1-1 0V8.9Zm-.25-2.16a.75.75 0 1 1 1.5 0 .75.75 0 0 1-1.5 0Z" fill="currentColor"></path> fill="currentColor"
aria-hidden="true"
width="1em"
height="1em"
viewBox="0 0 20 20"
>
<path
d="M18 10a8 8 0 1 0-16 0 8 8 0 0 0 16 0ZM9.5 8.91a.5.5 0 0 1 1 0V13.6a.5.5 0 0 1-1 0V8.9Zm-.25-2.16a.75.75 0 1 1 1.5 0 .75.75 0 0 1-1.5 0Z"
fill="currentColor"
></path>
</svg> </svg>
}) },
} )
} }}
</div>
<div class="thaw-toast-title">
{children()}
</div> </div>
<div class="thaw-toast-title">{children()}</div>
<OptionComp value=toast_title_action let:action> <OptionComp value=toast_title_action let:action>
<div class="thaw-toast-title__action"> <div class="thaw-toast-title__action">{(action.children)()}</div>
{(action.children)()}
</div>
</OptionComp> </OptionComp>
} }
} }

View file

@ -71,93 +71,87 @@ pub fn Toaster(
data-thaw-id=config_provider.id().clone() data-thaw-id=config_provider.id().clone()
> >
<div class="thaw-toaster thaw-toaster--top"> <div class="thaw-toaster thaw-toaster--top">
<For <For each=move || top_id_list.get() key=|id| id.clone() let:id>
each=move || top_id_list.get() {if let Some((view, options)) = toasts
key=|id| id.clone() .try_update_value(|map| { map.remove(&id) })
let:id .flatten()
>
{ {
if let Some((view, options)) = toasts.try_update_value(|map| { map.remove(&id) }).flatten() { Either::Left(
Either::Left(view! { <ToasterContainer on_close view=view.take() options/> }) view! { <ToasterContainer on_close view=view.take() options /> },
} else { )
Either::Right(()) } else {
} Either::Right(())
} }}
</For> </For>
</div> </div>
<div class="thaw-toaster thaw-toaster--top-start"> <div class="thaw-toaster thaw-toaster--top-start">
<For <For each=move || top_start_id_list.get() key=|id| id.clone() let:id>
each=move || top_start_id_list.get() {if let Some((view, options)) = toasts
key=|id| id.clone() .try_update_value(|map| { map.remove(&id) })
let:id .flatten()
>
{ {
if let Some((view, options)) = toasts.try_update_value(|map| { map.remove(&id) }).flatten() { Either::Left(
Either::Left(view! { <ToasterContainer on_close view=view.take() options/> }) view! { <ToasterContainer on_close view=view.take() options /> },
} else { )
Either::Right(()) } else {
} Either::Right(())
} }}
</For> </For>
</div> </div>
<div class="thaw-toaster thaw-toaster--top-end"> <div class="thaw-toaster thaw-toaster--top-end">
<For <For each=move || top_end_id_list.get() key=|id| id.clone() let:id>
each=move || top_end_id_list.get() {if let Some((view, options)) = toasts
key=|id| id.clone() .try_update_value(|map| { map.remove(&id) })
let:id .flatten()
>
{ {
if let Some((view, options)) = toasts.try_update_value(|map| { map.remove(&id) }).flatten() { Either::Left(
Either::Left(view! { <ToasterContainer on_close view=view.take() options/> }) view! { <ToasterContainer on_close view=view.take() options /> },
} else { )
Either::Right(()) } else {
} Either::Right(())
} }}
</For> </For>
</div> </div>
<div class="thaw-toaster thaw-toaster--bottom"> <div class="thaw-toaster thaw-toaster--bottom">
<For <For each=move || bottom_id_list.get() key=|id| id.clone() let:id>
each=move || bottom_id_list.get() {if let Some((view, options)) = toasts
key=|id| id.clone() .try_update_value(|map| { map.remove(&id) })
let:id .flatten()
>
{ {
if let Some((view, options)) = toasts.try_update_value(|map| { map.remove(&id) }).flatten() { Either::Left(
Either::Left(view! { <ToasterContainer on_close view=view.take() options/> }) view! { <ToasterContainer on_close view=view.take() options /> },
} else { )
Either::Right(()) } else {
} Either::Right(())
} }}
</For> </For>
</div> </div>
<div class="thaw-toaster thaw-toaster--bottom-start"> <div class="thaw-toaster thaw-toaster--bottom-start">
<For <For each=move || bottom_start_id_list.get() key=|id| id.clone() let:id>
each=move || bottom_start_id_list.get() {if let Some((view, options)) = toasts
key=|id| id.clone() .try_update_value(|map| { map.remove(&id) })
let:id .flatten()
>
{ {
if let Some((view, options)) = toasts.try_update_value(|map| { map.remove(&id) }).flatten() { Either::Left(
Either::Left(view! { <ToasterContainer on_close view=view.take() options/> }) view! { <ToasterContainer on_close view=view.take() options /> },
} else { )
Either::Right(()) } else {
} Either::Right(())
} }}
</For> </For>
</div> </div>
<div class="thaw-toaster thaw-toaster--bottom-end"> <div class="thaw-toaster thaw-toaster--bottom-end">
<For <For each=move || bottom_end_id_list.get() key=|id| id.clone() let:id>
each=move || bottom_end_id_list.get() {if let Some((view, options)) = toasts
key=|id| id.clone() .try_update_value(|map| { map.remove(&id) })
let:id .flatten()
>
{ {
if let Some((view, options)) = toasts.try_update_value(|map| { map.remove(&id) }).flatten() { Either::Left(
Either::Left(view! { <ToasterContainer on_close view=view.take() options/> }) view! { <ToasterContainer on_close view=view.take() options /> },
} else { )
Either::Right(()) } else {
} Either::Right(())
} }}
</For> </For>
</div> </div>
</div> </div>

View file

@ -4,14 +4,13 @@ use leptos::{context::Provider, prelude::*};
#[component] #[component]
pub fn ToasterProvider( pub fn ToasterProvider(
/// The position the toast should render. /// The position the toast should render.
#[prop(optional)] position: ToastPosition, #[prop(optional)]
position: ToastPosition,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
let (injection, receiver) = ToasterInjection::channel(); let (injection, receiver) = ToasterInjection::channel();
view! { view! {
<Toaster receiver position/> <Toaster receiver position />
<Provider value=injection> <Provider value=injection>{children()}</Provider>
{children()}
</Provider>
} }
} }

View file

@ -80,12 +80,11 @@ pub fn Upload(
}; };
view! { view! {
<div <div class=class_list![
class=class_list!["thaw-upload", "thaw-upload",
("thaw-upload--drag-over", move || is_trigger_dragover.get()), ("thaw-upload--drag-over", move || is_trigger_dragover.get()),
class class
] ]>
>
<input <input
class="thaw-upload__input" class="thaw-upload__input"
node_ref=input_ref node_ref=input_ref

View file

@ -8,9 +8,5 @@ pub fn UploadDragger(
) -> impl IntoView { ) -> impl IntoView {
mount_style("upload-dragger", include_str!("./upload-dragger.css")); mount_style("upload-dragger", include_str!("./upload-dragger.css"));
view! { view! { <div class=class_list!["thaw-upload-dragger", class]>{children()}</div> }
<div class=class_list!["thaw-upload-dragger", class]>
{children()}
</div>
}
} }