htmx_components/server/
button.rs

1use super::html_element::HtmlElement;
2use rscx::{component, html, props};
3use rscx_web_macros::*;
4
5#[derive(Clone)]
6pub enum ButtonSize {
7    Xs,
8    Sm,
9    Md,
10    Lg,
11    Xl,
12}
13
14#[html_element]
15pub struct PrimaryButtonProps {
16    children: String,
17
18    #[builder(default = ButtonSize::Md)]
19    size: ButtonSize,
20
21    #[builder(setter(into), default=String::from("button"))]
22    tag: String,
23
24    #[builder(setter(into), default)]
25    href: String,
26}
27
28#[component]
29pub fn PrimaryButton(props: PrimaryButtonProps) -> String {
30    let tag = props.tag.clone();
31    let href = props.href.clone();
32
33    html! {
34        <HtmlElement
35            tag=props.tag
36            class={
37                let class = match props.size {
38                    ButtonSize::Xs => "rounded bg-indigo-600 px-2 py-1 text-xs font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600",
39                    ButtonSize::Sm => "rounded bg-indigo-600 px-2 py-1 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600",
40                    ButtonSize::Md => "rounded-md bg-indigo-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600",
41                    ButtonSize::Lg => "rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600",
42                    ButtonSize::Xl => "rounded-md bg-indigo-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600",
43                };
44                format!("{} {}", class, props.class).trim()
45            }
46            attrs=spread_attrs!(props | omit(class))
47                .set("type", "button".into())
48                .set_if("href", props.href, !href.is_empty() && tag == "a")
49        >
50            {props.children}
51        </HtmlElement>
52    }
53}
54
55#[html_element]
56pub struct SecondaryButtonProps {
57    children: String,
58
59    #[builder(default = ButtonSize::Md)]
60    size: ButtonSize,
61
62    #[builder(setter(into), default=String::from("button"))]
63    tag: String,
64
65    #[builder(setter(into), default)]
66    href: String,
67}
68
69#[component]
70pub fn SecondaryButton(props: SecondaryButtonProps) -> String {
71    let tag = props.tag.clone();
72    let href = props.href.clone();
73
74    html! {
75        <HtmlElement
76            tag=props.tag
77            class={
78                let class = match props.size {
79                    ButtonSize::Xs => "rounded bg-white px-2 py-1 text-xs font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50",
80                    ButtonSize::Sm => "rounded bg-white px-2 py-1 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50",
81                    ButtonSize::Md => "rounded-md bg-white px-2.5 py-1.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50",
82                    ButtonSize::Lg => "rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50",
83                    ButtonSize::Xl => "rounded-md bg-white px-3.5 py-2.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50",
84                };
85                format!("{} {}", class, props.class).trim()
86            }
87            attrs=spread_attrs!(props | omit(class))
88                .set("type", "button".into())
89                .set_if("href", props.href, !href.is_empty() && tag == "a")
90        >
91            {props.children}
92        </HtmlElement>
93    }
94}