Feat/thaw utils (#145)

* feat: extract utils as the library

* refactor: thaw_utils directory

* style: fmt
This commit is contained in:
luoxiaozero 2024-03-19 22:02:43 +08:00 committed by GitHub
parent a0654a789d
commit 9bf0f7da1a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
89 changed files with 324 additions and 398 deletions

View file

@ -1,4 +1,8 @@
[workspace]
resolver = "2"
members = ["thaw", "demo", "demo_markdown"]
members = ["thaw", "thaw_utils", "demo", "demo_markdown"]
exclude = ["examples"]
[workspace.dependencies]
thaw = { version = "0.2.3", path = "./thaw" }
thaw_utils = { version = "0.0.1", path = "./thaw_utils" }

View file

@ -14,7 +14,7 @@ license = "MIT"
[dependencies]
leptos = { version = "0.6.9" }
leptos_meta = { version = "0.6.9", optional = true }
thaw_utils = { workspace = true }
web-sys = { version = "0.3.69", features = [
"DomRect",
"File",
@ -30,6 +30,6 @@ chrono = "0.4.35"
palette = "0.7.5"
[features]
csr = ["leptos/csr"]
ssr = ["leptos/ssr", "leptos_meta/ssr"]
hydrate = ["leptos/hydrate"]
csr = ["leptos/csr", "thaw_utils/csr"]
ssr = ["leptos/ssr", "thaw_utils/ssr"]
hydrate = ["leptos/hydrate", "thaw_utils/hydrate"]

View file

@ -1,14 +1,11 @@
mod theme;
use crate::{
components::OptionComp,
theme::use_theme,
utils::{class_list::class_list, mount_style, OptionalProp},
Icon, Theme,
};
use leptos::*;
pub use theme::AlertTheme;
use crate::{components::OptionComp, theme::use_theme, Icon, Theme};
use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalProp};
#[derive(Clone)]
pub enum AlertVariant {
Success,

View file

@ -1,13 +1,13 @@
mod theme;
pub use theme::AutoCompleteTheme;
use crate::{
components::{Binder, CSSTransition, Follower, FollowerPlacement, FollowerWidth},
use_theme,
utils::{class_list::class_list, mount_style, Model, OptionalProp, StoredMaybeSignal},
ComponentRef, Input, InputPrefix, InputRef, InputSuffix, Theme,
use_theme, ComponentRef, Input, InputPrefix, InputRef, InputSuffix, Theme,
};
use leptos::*;
pub use theme::AutoCompleteTheme;
use thaw_utils::{class_list, mount_style, Model, OptionalProp, StoredMaybeSignal};
#[derive(Clone, PartialEq)]
pub struct AutoCompleteOption {
@ -211,7 +211,13 @@ pub fn AutoComplete(
>
<div
class="thaw-auto-complete__menu"
style=move || display.get().map(|d| d.to_string()).unwrap_or_else(|| menu_css_vars.get())
style=move || {
display
.get()
.map(|d| d.to_string())
.unwrap_or_else(|| menu_css_vars.get())
}
ref=menu_ref
>

View file

@ -1,14 +1,11 @@
mod theme;
use crate::{
components::OptionComp,
use_theme,
utils::{class_list::class_list, mount_style, OptionalProp},
Theme,
};
use leptos::*;
pub use theme::AvatarTheme;
use crate::{components::OptionComp, use_theme, Theme};
use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalProp};
#[component]
pub fn Avatar(
#[prop(optional, into)] src: Option<MaybeSignal<String>>,

View file

@ -1,9 +1,6 @@
use crate::{
theme::use_theme,
utils::{class_list::class_list, mount_style, OptionalProp},
Theme,
};
use crate::{theme::use_theme, Theme};
use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalProp};
#[derive(Default, Clone)]
pub enum BadgeVariant {

View file

@ -1,6 +1,6 @@
use super::use_breadcrumb_separator;
use crate::utils::{class_list::class_list, OptionalProp};
use leptos::*;
use thaw_utils::{class_list, OptionalProp};
#[component]
pub fn BreadcrumbItem(

View file

@ -1,14 +1,12 @@
mod breadcrumb_item;
mod theme;
use crate::{
use_theme,
utils::{class_list::class_list, mount_style, OptionalProp},
Theme,
};
pub use theme::BreadcrumbTheme;
use crate::{use_theme, Theme};
pub use breadcrumb_item::BreadcrumbItem;
use leptos::*;
pub use theme::BreadcrumbTheme;
use thaw_utils::{class_list, mount_style, OptionalProp};
#[component]
pub fn Breadcrumb(

View file

@ -1,5 +1,5 @@
use crate::utils::{class_list::class_list, mount_style, OptionalProp};
use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalProp};
#[component]
pub fn ButtonGroup(
@ -9,7 +9,10 @@ pub fn ButtonGroup(
) -> impl IntoView {
mount_style("button-group", include_str!("./button-group.css"));
view! {
<div class=class_list!["thaw-button-group", class.map(| c | move || c.get())] class=("thaw-button-group--vertical", vertical)>
<div
class=class_list!["thaw-button-group", class.map(| c | move || c.get())]
class=("thaw-button-group--vertical", vertical)
>
{children()}
</div>
}

View file

@ -1,15 +1,16 @@
mod button_group;
mod theme;
pub use button_group::ButtonGroup;
pub use theme::ButtonTheme;
use crate::{
components::{OptionComp, Wave, WaveRef},
icon::Icon,
theme::*,
utils::{class_list::class_list, mount_style, ComponentRef, OptionalMaybeSignal, OptionalProp},
};
pub use button_group::ButtonGroup;
use leptos::*;
pub use theme::ButtonTheme;
use thaw_utils::{class_list, mount_style, ComponentRef, OptionalMaybeSignal, OptionalProp};
#[derive(Default, PartialEq, Clone, Copy)]
pub enum ButtonVariant {
@ -229,7 +230,8 @@ pub fn Button(
ButtonVariant::Text), ("thaw-button--link", move || variant.get() ==
ButtonVariant::Link), ("thaw-button--round", move || round.get()),
("thaw-button--circle", move || circle.get()), ("thaw-button--disabled", move ||
disabled.get()), ("thaw-button--block", move || block.get()), class.map(| c | move || c.get())
disabled.get()), ("thaw-button--block", move || block.get()), class.map(| c | move
|| c.get())
]
style=move || {
@ -249,8 +251,8 @@ pub fn Button(
"animation: thawLoadingCircle 1s infinite linear;{icon_style}",
)
/>
}.into_view()
}
.into_view()
} else {
(move || {
let icon = icon.get();
@ -259,7 +261,8 @@ pub fn Button(
<Icon icon=icon style=icon_style/>
</OptionComp>
}
}).into_view()
})
.into_view()
}
}}

View file

@ -2,15 +2,11 @@ mod theme;
pub use theme::CalendarTheme;
use crate::{
use_theme,
utils::{class_list::class_list, mount_style, Model, OptionalProp},
Button, ButtonGroup, ButtonVariant, Theme,
};
use chrono::{Datelike, Days, Local, NaiveDate};
use chrono::{Month, Months};
use crate::{use_theme, Button, ButtonGroup, ButtonVariant, Theme};
use chrono::{Datelike, Days, Local, Month, Months, NaiveDate};
use leptos::*;
use std::ops::Deref;
use thaw_utils::{class_list, mount_style, Model, OptionalProp};
#[component]
pub fn Calendar(

View file

@ -1,10 +1,6 @@
use crate::{
components::*,
use_theme,
utils::{class_list::class_list, mount_style, OptionalProp},
Theme,
};
use crate::{components::*, use_theme, Theme};
use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalProp};
#[slot]
pub struct CardHeader {

View file

@ -1,6 +1,6 @@
use crate::utils::Model;
use leptos::*;
use std::collections::HashSet;
use thaw_utils::Model;
#[component]
pub fn CheckboxGroup(

View file

@ -1,9 +1,9 @@
use crate::{
checkbox::{checkbox_group::use_checkbox_group, Checkbox},
utils::OptionalProp,
SignalWatch,
};
use leptos::*;
use thaw_utils::OptionalProp;
#[component]
pub fn CheckboxItem(

View file

@ -1,16 +1,12 @@
mod checkbox_group;
mod checkbox_item;
use crate::{
components::*,
icon::*,
theme::use_theme,
utils::{class_list::class_list, mount_style, Model, OptionalProp},
Theme,
};
pub use checkbox_group::CheckboxGroup;
pub use checkbox_item::CheckboxItem;
use crate::{components::*, icon::*, theme::use_theme, Theme};
use leptos::*;
use thaw_utils::{class_list, mount_style, Model, OptionalProp};
#[component]
pub fn Checkbox(

View file

@ -1,5 +1,5 @@
use crate::utils::{class_list::class_list, mount_style, OptionalProp};
use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalProp};
#[component]
pub fn Code(

View file

@ -1,10 +1,7 @@
use super::use_collapse;
use crate::{
components::CSSTransition,
utils::{class_list::class_list, OptionalProp, StoredMaybeSignal},
Icon,
};
use crate::{components::CSSTransition, Icon};
use leptos::*;
use thaw_utils::{class_list, OptionalProp, StoredMaybeSignal};
#[component]
pub fn CollapseItem(

View file

@ -4,13 +4,10 @@ mod theme;
pub use collapse_item::CollapseItem;
pub use theme::CollapseTheme;
use crate::{
use_theme,
utils::{class_list::class_list, mount_style, Model, OptionalProp},
Theme,
};
use crate::{use_theme, Theme};
use leptos::*;
use std::collections::HashSet;
use thaw_utils::{class_list, mount_style, Model, OptionalProp};
#[component]
pub fn Collapse(

View file

@ -6,13 +6,12 @@ pub use theme::ColorPickerTheme;
use crate::{
components::{Binder, CSSTransition, Follower, FollowerPlacement},
use_theme,
utils::{class_list::class_list, mount_style, Model, OptionalProp},
Theme,
use_theme, Theme,
};
use leptos::leptos_dom::helpers::WindowListenerHandle;
use leptos::*;
use palette::{Hsv, IntoColor, Srgb};
use thaw_utils::{class_list, mount_style, Model, OptionalProp};
#[component]
pub fn ColorPicker(
@ -153,14 +152,20 @@ pub fn ColorPicker(
</div>
<Follower slot show=is_show_popover placement=FollowerPlacement::BottomStart>
<CSSTransition
node_ref=popover_ref name="fade-in-scale-up-transition"
node_ref=popover_ref
name="fade-in-scale-up-transition"
show=is_show_popover
let:display
>
<div
class="thaw-color-picker-popover"
ref=popover_ref
style=move || display.get().map(|d| d.to_string()).unwrap_or_else(|| popover_css_vars.get())
style=move || {
display
.get()
.map(|d| d.to_string())
.unwrap_or_else(|| popover_css_vars.get())
}
>
<ColorPanel hue=hue.read_only() sv/>

View file

@ -1,17 +1,15 @@
mod get_placement_style;
use crate::{
components::Teleport,
utils::{add_event_listener, EventListenerHandle},
utils::{mount_style, with_hydration_off},
};
pub use get_placement_style::FollowerPlacement;
use crate::components::Teleport;
use get_placement_style::{get_follower_placement_offset, FollowerPlacementOffset};
use leptos::{
html::{AnyElement, ElementDescriptor, ToHtmlElement},
leptos_dom::helpers::WindowListenerHandle,
*,
};
use thaw_utils::{add_event_listener, mount_style, with_hydration_off, EventListenerHandle};
#[slot]
pub struct Follower {

View file

@ -1,6 +1,6 @@
use crate::utils::{add_event_listener, EventListenerHandle};
use leptos::{html::ElementDescriptor, *};
use std::{ops::Deref, time::Duration};
use thaw_utils::{add_event_listener, EventListenerHandle};
/// # CSS Transition
///

View file

@ -11,7 +11,7 @@ pub fn Teleport(
cfg_if! { if #[cfg(all(target_arch = "wasm32", any(feature = "csr", feature = "hydrate")))] {
use leptos::wasm_bindgen::JsCast;
use leptos::leptos_dom::Mountable;
use crate::utils::with_hydration_off;
use thaw_utils::with_hydration_off;
let mount = mount.unwrap_or_else(|| {
document()

View file

@ -1,6 +1,6 @@
use crate::utils::{mount_style, ComponentRef};
use leptos::{leptos_dom::helpers::TimeoutHandle, *};
use std::time::Duration;
use thaw_utils::{mount_style, ComponentRef};
#[derive(Clone)]
pub struct WaveRef {

View file

@ -5,12 +5,12 @@ pub use theme::DatePickerTheme;
use crate::{
components::{Binder, Follower, FollowerPlacement},
utils::{mount_style, now_date, ComponentRef, Model, OptionalProp},
Icon, Input, InputSuffix, SignalWatch,
};
use chrono::NaiveDate;
use leptos::*;
use panel::{Panel, PanelRef};
use thaw_utils::{mount_style, now_date, ComponentRef, Model, OptionalProp};
#[component]
pub fn DatePicker(

View file

@ -1,8 +1,9 @@
use super::PanelVariant;
use crate::{utils::now_date, Button, ButtonSize, ButtonVariant, CalendarItemDate};
use crate::{Button, ButtonSize, ButtonVariant, CalendarItemDate};
use chrono::{Datelike, Days, Month, Months, NaiveDate};
use leptos::*;
use std::ops::Deref;
use thaw_utils::now_date;
#[component]
pub fn DatePanel(

View file

@ -2,16 +2,12 @@ mod date_panel;
mod month_panel;
mod year_panel;
use crate::{
components::CSSTransition,
use_theme,
utils::{now_date, ComponentRef},
Theme,
};
use crate::{components::CSSTransition, use_theme, Theme};
use chrono::NaiveDate;
use date_panel::DatePanel;
use leptos::*;
use month_panel::MonthPanel;
use thaw_utils::{now_date, ComponentRef};
use year_panel::YearPanel;
#[component]

View file

@ -1,5 +1,5 @@
use crate::utils::{class_list::class_list, mount_style, OptionalProp};
use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalProp};
#[component]
pub fn Divider(#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>) -> impl IntoView {

View file

@ -1,9 +1,9 @@
use crate::{
components::{CSSTransition, Teleport},
utils::{class_list::class_list, mount_style, use_lock_html_scroll, Model, OptionalProp},
Card,
};
use leptos::*;
use thaw_utils::{class_list, mount_style, use_lock_html_scroll, Model, OptionalProp};
#[component]
pub fn Drawer(

View file

@ -1,6 +1,6 @@
use super::use_grid;
use crate::utils::{class_list::class_list, OptionalProp};
use leptos::*;
use thaw_utils::{class_list, OptionalProp};
#[component]
pub fn GridItem(

View file

@ -1,8 +1,8 @@
mod grid_item;
use crate::utils::{class_list::class_list, OptionalProp};
pub use grid_item::*;
use leptos::*;
use thaw_utils::{class_list, OptionalProp};
#[component]
pub fn Grid(

View file

@ -1,5 +1,5 @@
use crate::utils::OptionalProp;
use leptos::*;
use thaw_utils::OptionalProp;
#[component]
pub fn Image(

View file

@ -4,11 +4,9 @@ mod theme;
pub use text_area::{TextArea, TextAreaRef};
pub use theme::InputTheme;
use crate::{
theme::{use_theme, Theme},
utils::{class_list::class_list, mount_style, ComponentRef, Model, OptionalProp},
};
use crate::theme::{use_theme, Theme};
use leptos::*;
use thaw_utils::{class_list, mount_style, ComponentRef, Model, OptionalProp};
#[derive(Default, Clone)]
pub enum InputVariant {

View file

@ -1,8 +1,6 @@
use crate::{
theme::{use_theme, Theme},
utils::{class_list::class_list, mount_style, ComponentRef, Model, OptionalProp},
};
use crate::theme::{use_theme, Theme};
use leptos::*;
use thaw_utils::{class_list, mount_style, ComponentRef, Model, OptionalProp};
#[component]
pub fn TextArea(

View file

@ -1,8 +1,8 @@
use crate::utils::{Model, OptionalProp, StoredMaybeSignal};
use crate::{Button, ButtonVariant, ComponentRef, Icon, Input, InputRef, InputSuffix};
use leptos::*;
use std::ops::{Add, Sub};
use std::str::FromStr;
use thaw_utils::{Model, OptionalProp, StoredMaybeSignal};
#[component]
pub fn InputNumber<T>(

View file

@ -1,5 +1,5 @@
use crate::utils::{class_list::class_list, OptionalProp};
use leptos::*;
use thaw_utils::{class_list, OptionalProp};
#[component]
pub fn LayoutHeader(

View file

@ -1,5 +1,5 @@
use crate::utils::{class_list::class_list, mount_style, OptionalProp};
use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalProp};
#[component]
pub fn LayoutSider(

View file

@ -1,10 +1,11 @@
mod layout_header;
mod layout_sider;
use crate::utils::{class_list::class_list, mount_style, OptionalProp};
pub use layout_header::*;
pub use layout_sider::*;
use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalProp};
#[derive(Default, PartialEq)]
pub enum LayoutPosition {

View file

@ -42,7 +42,6 @@ mod theme;
mod time_picker;
mod typography;
mod upload;
mod utils;
pub use alert::*;
pub use auto_complete::*;
@ -82,8 +81,8 @@ pub use switch::*;
pub use table::*;
pub use tabs::*;
pub use tag::*;
pub use thaw_utils::{create_component_ref, ComponentRef, SignalWatch};
pub use theme::*;
pub use time_picker::*;
pub use typography::*;
pub use upload::*;
pub use utils::{create_component_ref, ComponentRef, SignalWatch};

View file

@ -1,6 +1,7 @@
use super::{LoadingBar, LoadingBarRef};
use crate::{components::Teleport, utils::ComponentRef};
use crate::components::Teleport;
use leptos::*;
use thaw_utils::ComponentRef;
#[component]
pub fn LoadingBarProvider(children: Children) -> impl IntoView {

View file

@ -1,9 +1,11 @@
mod loading_bar_provider;
use crate::{use_theme, utils::mount_style, utils::ComponentRef, Theme};
use leptos::*;
pub use loading_bar_provider::{use_loading_bar, LoadingBarProvider};
use crate::{use_theme, Theme};
use leptos::*;
use thaw_utils::{mount_style, ComponentRef};
#[derive(Clone)]
pub(crate) struct LoadingBarRef {
start: Callback<()>,

View file

@ -1,9 +1,6 @@
use crate::{
theme::use_theme,
utils::{class_list::class_list, mount_style, OptionalProp},
Theme,
};
use crate::{theme::use_theme, Theme};
use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalProp};
#[component]
pub fn MenuGroup(

View file

@ -1,10 +1,7 @@
use super::use_menu;
use crate::{
theme::use_theme,
utils::{class_list::class_list, mount_style, OptionalProp},
Theme,
};
use crate::{theme::use_theme, Theme};
use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalProp};
#[component]
pub fn MenuItem(

View file

@ -2,12 +2,13 @@ mod menu_group;
mod menu_item;
mod theme;
use crate::utils::{class_list::class_list, Model, OptionalProp};
use leptos::*;
pub use menu_group::MenuGroup;
pub use menu_item::*;
pub use theme::MenuTheme;
use leptos::*;
use thaw_utils::{class_list, Model, OptionalProp};
#[component]
pub fn Menu(
#[prop(optional, into)] value: Model<String>,

View file

@ -1,10 +1,8 @@
use super::{message_environment::MessageEnvironment, MessageVariant};
use crate::{
components::Teleport,
utils::{class_list::class_list, mount_style},
};
use crate::components::Teleport;
use leptos::*;
use std::time::Duration;
use thaw_utils::{class_list, mount_style};
use uuid::Uuid;
#[derive(Default, Clone)]

View file

@ -2,14 +2,15 @@ mod message_environment;
mod message_provider;
mod theme;
pub use message_provider::*;
pub use theme::MessageTheme;
use crate::{
components::{If, Then},
theme::use_theme,
Icon, Theme,
};
use leptos::*;
pub use message_provider::*;
pub use theme::MessageTheme;
use uuid::Uuid;
#[derive(Default, Clone)]

View file

@ -1,15 +1,11 @@
mod theme;
use crate::{
components::*,
icon::*,
use_theme,
utils::{class_list::class_list, mount_style, OptionalProp},
Theme,
};
use leptos::*;
pub use theme::NavBarTheme;
use crate::{components::*, icon::*, use_theme, Theme};
use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalProp};
#[slot]
pub struct NavBarLeft {
#[prop(optional, into)]

View file

@ -1,15 +1,13 @@
mod tabbar_item;
mod theme;
use crate::{
use_theme,
utils::{mount_style, Model},
Theme,
};
use leptos::*;
pub use tabbar_item::*;
pub use theme::TabbarTheme;
use crate::{use_theme, Theme};
use leptos::*;
use thaw_utils::{mount_style, Model};
#[component]
pub fn Tabbar(#[prop(optional, into)] value: Model<String>, children: Children) -> impl IntoView {
mount_style("tabbar", include_str!("./tabbar.css"));

View file

@ -1,8 +1,8 @@
use super::use_tabbar;
use crate::components::*;
use crate::utils::StoredMaybeSignal;
use crate::{icon::Icon, theme::use_theme, utils::mount_style, Theme};
use crate::{icon::Icon, theme::use_theme, Theme};
use leptos::*;
use thaw_utils::{mount_style, StoredMaybeSignal};
#[component]
pub fn TabbarItem(

View file

@ -1,6 +1,6 @@
use crate::utils::mount_style;
use cfg_if::cfg_if;
use std::time::Duration;
use thaw_utils::mount_style;
pub struct ToastOptions {
pub message: String,

View file

@ -1,9 +1,9 @@
use crate::{
components::{CSSTransition, OptionComp, Teleport},
utils::{mount_style, use_click_position, Model},
Card, CardFooter, CardHeader, CardHeaderExtra, Icon,
};
use leptos::*;
use thaw_utils::{mount_style, use_click_position, Model};
#[slot]
pub struct ModalFooter {
@ -82,7 +82,11 @@ pub fn Modal(
ref=mask_ref
></div>
</CSSTransition>
<div class="thaw-modal-scroll" style=move || (!displayed.get()).then_some("display: none") ref=scroll_ref>
<div
class="thaw-modal-scroll"
style=move || (!displayed.get()).then_some("display: none")
ref=scroll_ref
>
<CSSTransition
node_ref=modal_ref
show=show.signal()
@ -91,7 +95,13 @@ pub fn Modal(
on_after_leave=move |_| displayed.set(false)
let:display
>
<div class="thaw-modal-body" ref=modal_ref role="dialog" aria-modal="true" style=move || display.get()>
<div
class="thaw-modal-body"
ref=modal_ref
role="dialog"
aria-modal="true"
style=move || display.get()
>
<Card>
<CardHeader slot>
<span class="thaw-model-title">{move || title.get()}</span>

View file

@ -4,12 +4,11 @@ pub use theme::PopoverTheme;
use crate::{
components::{Binder, CSSTransition, Follower, FollowerPlacement},
use_theme,
utils::{add_event_listener, class_list::class_list, mount_style, OptionalProp},
Theme,
use_theme, Theme,
};
use leptos::{leptos_dom::helpers::TimeoutHandle, *};
use std::time::Duration;
use thaw_utils::{add_event_listener, class_list, mount_style, OptionalProp};
#[slot]
pub struct PopoverTrigger {
@ -126,7 +125,8 @@ pub fn Popover(
</div>
<Follower slot show=follower_enabled placement>
<CSSTransition
node_ref=popover_ref name="popover-transition"
node_ref=popover_ref
name="popover-transition"
show=is_show_popover
on_enter=move |_| follower_enabled.set(true)
on_after_leave=move |_| follower_enabled.set(false)
@ -134,7 +134,10 @@ pub fn Popover(
>
<div
class="thaw-popover"
style=move || display.get().map(|d| d.to_string()).unwrap_or_else(|| css_vars.get())
style=move || {
display.get().map(|d| d.to_string()).unwrap_or_else(|| css_vars.get())
}
ref=popover_ref
on:mouseenter=on_mouse_enter
on:mouseleave=on_mouse_leave

View file

@ -4,8 +4,9 @@ mod theme;
pub use progress_circle::ProgressCircle;
pub use theme::ProgressTheme;
use crate::{use_theme, utils::mount_style, Theme};
use crate::{use_theme, Theme};
use leptos::*;
use thaw_utils::mount_style;
#[derive(Default, Clone, PartialEq)]
pub enum ProgressIndicatorPlacement {

View file

@ -1,10 +1,7 @@
use super::ProgressColor;
use crate::{
use_theme,
utils::{class_list::class_list, mount_style, OptionalProp},
Theme,
};
use crate::{use_theme, Theme};
use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalProp};
#[component]
pub fn ProgressCircle(
@ -61,8 +58,8 @@ pub fn ProgressCircle(
aria-valuenow=move || percentage.get()
style=("--thaw-fill-color", move || fill_stroke_color.get())
style=("--thaw-size", move || size.get())
>
<svg viewBox="0 0 107 107">
<g>
<path
@ -87,21 +84,17 @@ pub fn ProgressCircle(
></path>
</g>
</svg>
{
if let Some(children) = children {
view! {
<div class="thaw-progress-circle__content">
{children()}
</div>
}
{if let Some(children) = children {
view! { <div class="thaw-progress-circle__content">{children()}</div> }
} else {
view! {
<div class="thaw-progress-circle__content thaw-progress-circle__content--text">
{move || percentage.get()} "%"
</div>
}
}
}
}}
</div>
}
}

View file

@ -4,12 +4,9 @@ mod radio_item;
pub use radio_group::RadioGroup;
pub use radio_item::RadioItem;
use crate::{
theme::use_theme,
utils::{class_list::class_list, mount_style, Model, OptionalProp},
Theme,
};
use crate::{theme::use_theme, Theme};
use leptos::*;
use thaw_utils::{class_list, mount_style, Model, OptionalProp};
#[component]
pub fn Radio(

View file

@ -1,5 +1,5 @@
use crate::utils::Model;
use leptos::*;
use thaw_utils::Model;
#[component]
pub fn RadioGroup(

View file

@ -1,8 +1,6 @@
use crate::{
radio::{radio_group::use_radio_group, Radio},
utils::OptionalProp,
};
use crate::radio::{radio_group::use_radio_group, Radio};
use leptos::*;
use thaw_utils::OptionalProp;
#[component]
pub fn RadioItem(

View file

@ -1,14 +1,15 @@
mod theme;
pub use theme::SelectTheme;
use crate::{
components::{Binder, CSSTransition, Follower, FollowerPlacement, FollowerWidth},
theme::use_theme,
utils::{class_list::class_list, mount_style, Model, OptionalProp},
Theme,
};
use leptos::*;
use std::hash::Hash;
pub use theme::SelectTheme;
use thaw_utils::{class_list, mount_style, Model, OptionalProp};
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct SelectOption<T> {
@ -134,7 +135,13 @@ where
>
<div
class="thaw-select-menu"
style=move || display.get().map(|d| d.to_string()).unwrap_or_else(|| menu_css_vars.get())
style=move || {
display
.get()
.map(|d| d.to_string())
.unwrap_or_else(|| menu_css_vars.get())
}
ref=menu_ref
>
<For
@ -143,7 +150,8 @@ where
children=move |item| {
let item = store_value(item);
let onclick = move |_| {
let SelectOption { value: item_value, label: _ } = item.get_value();
let SelectOption { value: item_value, label: _ } = item
.get_value();
value.set(Some(item_value));
is_show_menu.set(false);
};

View file

@ -1,9 +1,11 @@
mod theme;
use crate::{theme::use_theme, utils::mount_style, Theme};
use leptos::*;
pub use theme::SkeletionTheme;
use crate::{theme::use_theme, Theme};
use leptos::*;
use thaw_utils::mount_style;
#[component]
pub fn Skeleton(
#[prop(default = MaybeSignal::Static(1), into)] repeat: MaybeSignal<u32>,

View file

@ -1,18 +1,14 @@
mod slider_label;
mod theme;
use crate::{
components::OptionComp,
theme::use_theme,
utils::{class_list::class_list, mount_style, Model, OptionalProp},
Theme,
};
use leptos::*;
use web_sys::DomRect;
pub use slider_label::SliderLabel;
pub use theme::SliderTheme;
use crate::{components::OptionComp, theme::use_theme, Theme};
use leptos::*;
use thaw_utils::{class_list, mount_style, Model, OptionalProp};
use web_sys::DomRect;
#[component]
pub fn Slider(
#[prop(optional, into)] value: Model<f64>,

View file

@ -1,5 +1,5 @@
use crate::utils::mount_style;
use leptos::*;
use thaw_utils::mount_style;
#[component]
pub fn SliderLabel(#[prop(into)] value: MaybeSignal<f64>, children: Children) -> impl IntoView {

View file

@ -1,5 +1,5 @@
use crate::utils::{class_list::class_list, mount_style, OptionalMaybeSignal, OptionalProp};
use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalMaybeSignal, OptionalProp};
#[derive(Default)]
pub enum SpaceGap {

View file

@ -1,13 +1,11 @@
mod theme;
use crate::{
theme::use_theme,
utils::{class_list::class_list, mount_style, OptionalProp},
Theme,
};
use leptos::*;
pub use theme::SpinnerTheme;
use crate::{theme::use_theme, Theme};
use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalProp};
#[derive(Default, Clone)]
pub enum SpinnerSize {
Tiny,

View file

@ -1,13 +1,11 @@
mod theme;
use crate::{
theme::use_theme,
utils::{class_list::class_list, mount_style, Model, OptionalProp},
Theme,
};
use leptos::*;
pub use theme::SwitchTheme;
use crate::{theme::use_theme, Theme};
use leptos::*;
use thaw_utils::{class_list, mount_style, Model, OptionalProp};
#[component]
pub fn Switch(
#[prop(optional, into)] value: Model<bool>,

View file

@ -1,13 +1,11 @@
mod theme;
use crate::{
theme::use_theme,
utils::{class_list::class_list, mount_style, OptionalProp},
Theme,
};
use leptos::*;
pub use theme::TableTheme;
use crate::{theme::use_theme, Theme};
use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalProp};
#[component]
pub fn Table(
#[prop(optional, into)] style: MaybeSignal<String>,

View file

@ -1,14 +1,11 @@
mod tab;
use crate::{
theme::use_theme,
utils::{class_list::class_list, mount_style, Model, OptionalProp},
Theme,
};
use leptos::*;
pub use tab::*;
use crate::{theme::use_theme, Theme};
use leptos::*;
use thaw_utils::{class_list, mount_style, Model, OptionalProp};
#[component]
pub fn Tabs(
#[prop(optional, into)] value: Model<String>,

View file

@ -1,6 +1,6 @@
use super::use_tabs;
use crate::utils::{class_list::class_list, mount_style, OptionalProp};
use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalProp};
#[derive(Clone)]
pub(crate) struct TabOption {

View file

@ -2,12 +2,9 @@ mod theme;
pub use theme::TagTheme;
use crate::{
theme::use_theme,
utils::{class_list::class_list, mount_style, OptionalProp},
Icon, Theme,
};
use crate::{theme::use_theme, Icon, Theme};
use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalProp};
#[derive(Clone, Default)]
pub enum TagVariant {
@ -88,19 +85,20 @@ pub fn Tag(
style=move || css_vars.get()
>
<span class="thaw-tag__content">{children()}</span>
{
move || {
{move || {
if closable.get() {
view! {
<button class="thaw-tag__close" on:click=on_close>
<Icon icon=icondata_ai::AiCloseOutlined style="font-size: 14px"/>
</button>
}.into()
}
.into()
} else {
None
}
}
}
}}
</div>
}
}

View file

@ -4,12 +4,11 @@ pub use theme::TimePickerTheme;
use crate::{
components::{Binder, CSSTransition, Follower, FollowerPlacement},
use_theme,
utils::{mount_style, ComponentRef, Model, OptionalProp},
Button, ButtonSize, ButtonVariant, Icon, Input, InputSuffix, SignalWatch, Theme,
use_theme, Button, ButtonSize, ButtonVariant, Icon, Input, InputSuffix, SignalWatch, Theme,
};
use chrono::{Local, NaiveTime, Timelike};
use leptos::*;
use thaw_utils::{mount_style, ComponentRef, Model, OptionalProp};
#[component]
pub fn TimePicker(
@ -207,7 +206,12 @@ fn Panel(
selected_time.get().map_or(false, |v| v.hour() == hour)
});
view! {
<PanelTimeItem value=hour on:click=on_click is_selected comp_ref/>
<PanelTimeItem
value=hour
on:click=on_click
is_selected
comp_ref
/>
}
})
.collect_view()}
@ -233,7 +237,12 @@ fn Panel(
selected_time.get().map_or(false, |v| v.minute() == minute)
});
view! {
<PanelTimeItem value=minute on:click=on_click is_selected comp_ref/>
<PanelTimeItem
value=minute
on:click=on_click
is_selected
comp_ref
/>
}
})
.collect_view()}
@ -259,7 +268,12 @@ fn Panel(
selected_time.get().map_or(false, |v| v.second() == second)
});
view! {
<PanelTimeItem value=second on:click=on_click is_selected comp_ref/>
<PanelTimeItem
value=second
on:click=on_click
is_selected
comp_ref
/>
}
})
.collect_view()}

View file

@ -1,9 +1,6 @@
use crate::{
use_theme,
utils::{class_list::class_list, mount_style, OptionalProp},
Theme,
};
use crate::{use_theme, Theme};
use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalProp};
#[component]
pub fn Text(

View file

@ -1,12 +1,13 @@
mod theme;
mod upload_dragger;
use crate::{utils::add_event_listener, utils::mount_style};
use leptos::*;
pub use theme::UploadTheme;
pub use upload_dragger::UploadDragger;
pub use web_sys::FileList;
use leptos::*;
use thaw_utils::{add_event_listener, mount_style};
#[component]
pub fn Upload(
#[prop(optional, into)] accept: MaybeSignal<String>,

View file

@ -1,5 +1,6 @@
use crate::{use_theme, utils::mount_style, Theme};
use crate::{use_theme, Theme};
use leptos::*;
use thaw_utils::mount_style;
#[component]
pub fn UploadDragger(children: Children) -> impl IntoView {

View file

@ -1,89 +0,0 @@
// use leptos::StoredValue;
// use std::{fmt, future::Future, pin::Pin, rc::Rc};
// pub struct AsyncCallback<In: 'static, Out: 'static = ()>(
// #[allow(clippy::complexity)] StoredValue<Rc<dyn Fn(In) -> Pin<Box<dyn Future<Output = Out>>>>>,
// );
// impl<In> fmt::Debug for AsyncCallback<In> {
// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
// fmt.write_str("AsyncCallback")
// }
// }
// impl<In, Out> Clone for AsyncCallback<In, Out> {
// fn clone(&self) -> Self {
// *self
// }
// }
// impl<In, Out> Copy for AsyncCallback<In, Out> {}
// impl<In, Out> AsyncCallback<In, Out> {
// pub fn new<F, Fu>(f: F) -> Self
// where
// F: Fn(In) -> Fu + 'static,
// Fu: Future<Output = Out> + 'static,
// {
// let f = Rc::new(move |input: In| {
// let fut = f(input);
// Box::pin(fut) as Pin<Box<dyn Future<Output = Out>>>
// });
// Self(StoredValue::new(f))
// }
// pub async fn call(&self, input: In) -> Out {
// let f = self.0.get_value();
// f(input).await
// }
// }
// impl<F, In, Fu, Out> From<F> for AsyncCallback<In, Out>
// where
// F: Fn(In) -> Fu + 'static,
// Fu: Future<Output = Out> + 'static,
// {
// fn from(f: F) -> AsyncCallback<In, Out> {
// AsyncCallback::new(f)
// }
// }
// #[cfg(test)]
// mod tests {
// use crate::utils::AsyncCallback;
// use leptos::create_runtime;
// struct NoClone {}
// #[test]
// fn clone_async_callback() {
// let rt = create_runtime();
// let callback = AsyncCallback::new(move |_no_clone: NoClone| async { NoClone {} });
// let _cloned = callback.clone();
// rt.dispose();
// }
// #[test]
// fn async_callback_from() {
// let rt = create_runtime();
// let _callback: AsyncCallback<(), String> = (|()| async { "test".to_string() }).into();
// rt.dispose();
// }
// #[test]
// fn async_callback_from_html() {
// let rt = create_runtime();
// use leptos::{
// html::{HtmlElement, H1},
// *,
// };
// let _callback: AsyncCallback<String, HtmlElement<H1>> = (|x: String| async move {
// view! {
// <h1>{x}</h1>
// }
// })
// .into();
// rt.dispose();
// }
// }

View file

@ -1,38 +0,0 @@
// mod callback;
pub(crate) mod class_list;
mod component_ref;
mod event_listener;
mod model;
mod mount_style;
mod optional_maybe_signal;
mod optional_prop;
mod signal;
mod stored_maybe_signal;
mod time;
mod use_click_position;
mod use_lock_html_scroll;
// pub use callback::AsyncCallback;
pub use component_ref::{create_component_ref, ComponentRef};
pub(crate) use event_listener::*;
pub(crate) use model::Model;
pub(crate) use mount_style::mount_style;
pub(crate) use optional_maybe_signal::OptionalMaybeSignal;
pub(crate) use optional_prop::OptionalProp;
pub use signal::SignalWatch;
pub(crate) use stored_maybe_signal::*;
pub(crate) use time::*;
pub(crate) use use_click_position::*;
pub(crate) use use_lock_html_scroll::*;
pub(crate) fn with_hydration_off<T>(f: impl FnOnce() -> T) -> T {
#[cfg(feature = "hydrate")]
{
use leptos::leptos_dom::HydrationCtx;
HydrationCtx::with_hydration_off(f)
}
#[cfg(not(feature = "hydrate"))]
{
f()
}
}

25
thaw_utils/Cargo.toml Normal file
View file

@ -0,0 +1,25 @@
[package]
name = "thaw_utils"
version = "0.0.1"
edition = "2021"
keywords = ["leptos", "thaw", "utils"]
readme = "../README.md"
authors = ["luoxiaozero"]
description = "Shared Thaw utility functions"
repository = "https://github.com/thaw-ui/thaw"
license = "MIT"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
leptos = { version = "0.6.9" }
leptos_meta = { version = "0.6.9", optional = true }
web-sys = "0.3.69"
wasm-bindgen = "0.2.92"
cfg-if = "1.0.0"
chrono = "0.4.35"
[features]
csr = ["leptos/csr"]
ssr = ["leptos/ssr", "leptos_meta/ssr"]
hydrate = ["leptos/hydrate"]

View file

@ -172,15 +172,15 @@ where
}
}
#[macro_export]
macro_rules! class_list {
($($name:expr),+) => {
{
use crate::utils::class_list::ClassList;
use $crate::class_list::ClassList;
ClassList::new()$(.add($name))+
}
};
}
pub(crate) use class_list;
#[cfg(test)]
mod tests {

View file

@ -0,0 +1,5 @@
mod use_click_position;
mod use_lock_html_scroll;
pub use use_click_position::use_click_position;
pub use use_lock_html_scroll::use_lock_html_scroll;

28
thaw_utils/src/lib.rs Normal file
View file

@ -0,0 +1,28 @@
pub mod class_list;
mod event_listener;
mod hooks;
mod mount_style;
mod optional_prop;
mod signals;
mod time;
pub use event_listener::*;
pub use hooks::{use_click_position, use_lock_html_scroll};
pub use mount_style::mount_style;
pub use optional_prop::OptionalProp;
pub use signals::{
create_component_ref, ComponentRef, Model, OptionalMaybeSignal, SignalWatch, StoredMaybeSignal,
};
pub use time::*;
pub fn with_hydration_off<T>(f: impl FnOnce() -> T) -> T {
#[cfg(feature = "hydrate")]
{
use leptos::leptos_dom::HydrationCtx;
HydrationCtx::with_hydration_off(f)
}
#[cfg(not(feature = "hydrate"))]
{
f()
}
}

View file

@ -0,0 +1,11 @@
mod component_ref;
mod model;
mod optional_maybe_signal;
mod signal_watch;
mod stored_maybe_signal;
pub use component_ref::{create_component_ref, ComponentRef};
pub use model::Model;
pub use optional_maybe_signal::OptionalMaybeSignal;
pub use signal_watch::SignalWatch;
pub use stored_maybe_signal::StoredMaybeSignal;