htmx_components/server/
button.rs1use 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}