#![allow(clippy::pedantic, clippy::restriction)]
use crate::{
app::theme::Theme,
components::{label_style, section_title},
};
use michiu_ui::prelude::*;
use std::time::Duration;
pub fn container() -> Element {
v_flex(ts().gap(28.0).p(16.0)).children([
section_normal(),
section_pseudo(),
section_transition(),
])
}
fn section_style() -> ThisStyle {
ts().grow().gap(16.0)
}
fn wrapper_style() -> ThisStyle {
ts().w_full().gap(16.0)
}
fn item_style() -> ThisStyle {
ts().p(12.0)
.r(4.0)
.size((120.0, 70.0))
.justify_center()
.items_center()
}
fn section_normal() -> Element {
let wrapper =
h_flex(wrapper_style()).children([signal_btn(), direct_btn(), event_btn(), tag_btn()]);
v_flex(section_style()).children([section_title("Button"), wrapper])
}
fn signal_btn() -> Element {
let (count, set_count) = create_signal(0u32);
h_flex(
item_style()
.border_solid(2.0)
.border_color(dynamic(|t: &Theme| t.primary)),
)
.on_click(move || set_count.set(count.get() + 1))
.label(move || format!("Signal: {}", count.get()), label_style())
}
fn direct_btn() -> Element {
let el = h_flex(
item_style()
.border_solid(2.0)
.border_color(dynamic(|t: &Theme| t.border)),
);
let style = ts()
.text_color(dynamic(|t: &Theme| t.primary))
.font_size(16.0)
.font_weight(400);
let mut count = 0u32;
el.label(
move || format!("Direct: {}.{}", count / 10, count % 10),
&style,
)
.on_click(move || {
count += 1;
el.set_contents(div_n().label(
move || format!("Direct: {}.{}", count / 10, count % 10),
&style,
));
})
}
fn event_btn() -> Element {
let style = ts()
.text_color(dynamic(|t: &Theme| t.surface))
.font_size(16.0)
.font_weight(400);
let mut count = 0u32;
h_flex(item_style().bg_color(dynamic(|t: &Theme| t.primary)))
.label(move || format!("Event: {count}"), &style)
.on_click_with(move |cx| {
count += 1;
cx.current()
.set_contents(div_n().label(move || format!("Event: {count}"), &style));
})
}
fn tag_btn() -> Element {
struct MichiuTag;
let style = ts()
.text_color(dynamic(|t: &Theme| t.primary))
.font_size(16.0)
.font_weight(400);
let mut count = 0u32;
let left = h_flex(ts())
.label(move || format!("Tag: {count}"), &style)
.tag::<MichiuTag>();
let right = h_flex(ts())
.label(
move || "Click",
style.clone().pressed_parent(ts().text_color(Color::WHITE)),
)
.on_click_with(move |cx| {
if let Some(el) = cx.try_query_first::<MichiuTag>() {
count += 1;
el.set_contents(div_n().label(move || format!("Tag: {count}"), &style));
}
});
h_flex(
item_style()
.gap(8.0)
.border_solid(1.0)
.border_color(dynamic(|t: &Theme| t.primary)),
)
.children([left, right])
}
fn section_pseudo() -> Element {
let wrapper = h_flex(wrapper_style()).children([
hovered_btn(),
pressed_btn(),
dragged_btn(),
actived_btn(),
selected_btn(),
]);
v_flex(section_style()).children([section_title("Button Pseudo Class"), wrapper])
}
fn hovered_btn() -> Element {
h_flex(
item_style()
.shadow_color(Color::BLACK)
.shadow_blur(4.0)
.shadow_offset(0.0)
.shadow_spread(1.0)
.hovered(ts().shadow_blur(8.0)),
)
.label("Hovered", label_style())
}
fn pressed_btn() -> Element {
h_flex(
ts().p(12.0)
.r(4.0)
.size((120.0, 70.0))
.justify_center()
.items_center()
.border_dashed(2.0)
.border_color(dynamic(|t: &Theme| t.primary))
.pressed(ts().transform_scale(0.96, 0.96)),
)
.label(
"Pressed",
ts().text_color(dynamic(|t: &Theme| t.text_muted))
.font_size(16.0)
.font_weight(400)
.transform_inherit(true),
)
}
fn dragged_btn() -> Element {
h_flex(item_style())
.style_d(|t: &Theme| {
ts().bg_color(t.background_hover).dragged(
ts().bg_color(t.background)
.border_dashed(2.0)
.border_color(t.background_hover),
)
})
.label("Dragged", label_style())
}
fn actived_btn() -> Element {
let (is_active, set_is_active) = create_signal(false);
h_flex(item_style())
.style_d(|t: &Theme| {
ts().border_color(t.border)
.border_solid(2.0)
.bg_color(t.surface)
.actived(ts().bg_color(t.primary))
})
.label("Actived", label_style())
.active(is_active)
.on_click(move || {
set_is_active.set(!is_active.get());
})
.on_active(|| {
println!("Actived");
})
}
pub fn selected_btn() -> Element {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Option {
A,
B,
C,
}
let (selected, set_selected) = create_signal(Option::A);
let item = move |opt: Option, label_text: &'static str| {
h_flex(item_style().border_dashed(2.0).w_full().justify_center())
.style_d(|t: &Theme| {
ts().border_color(t.border_hover)
.selected(ts().border_color(t.primary).border_solid(2.0))
})
.label(label_text, label_style())
.select(move || selected.get() == opt)
.on_click(move || {
set_selected.set(opt);
})
.on_select(move || {
println!("{opt:?} is now selected!");
})
};
h_flex(ts().gap(2.0)).children([
item(Option::A, "Sel"),
item(Option::B, "ec"),
item(Option::C, "ted"),
])
}
fn transition_btn(ms: u64, label_text: &'static str) -> Element {
h_flex(item_style().box_shadow(shadow().blur(4.0).color(Color::BLACK).spread(1.0))).child(
h_flex(
ts().w_full()
.p_y(4.0)
.items_center()
.justify_center()
.border_bottom(BorderStyle::Solid, 2.0)
.border_align(BorderAlignment::Center)
.border_bottom_length(0.6)
.border_color(dynamic(|t: &Theme| t.border))
.pressed(ts().border_color(dynamic(|t: &Theme| t.primary)))
.trans_border_color(Duration::from_millis(ms), AnimationCurve::EaseInOutQuad),
)
.label(label_text, label_style()),
)
}
fn section_transition() -> Element {
let wrapper = h_flex(wrapper_style()).children([
transition_btn(150, "150 ms"),
transition_btn(300, "300 ms"),
transition_btn(450, "450 ms"),
transition_btn(600, "600 ms"),
]);
v_flex(section_style()).children([section_title("Button Transition"), wrapper])
}