Skip to main content

basecoat_core/props/
button.rs

1use crate::{AttrMap, BasecoatProps, Children};
2use std::borrow::Cow;
3
4/// Button visual variant — maps to upstream CSS class prefix.
5///
6/// The upstream class pattern is `btn-{size}-{variant}` (compound).
7/// Default size + Default variant → `btn-primary`.
8#[derive(Clone, Debug, PartialEq, Eq, Default)]
9pub enum ButtonVariant {
10    /// `btn-primary` (default)
11    #[default]
12    Primary,
13    Secondary,
14    Outline,
15    Ghost,
16    Link,
17    Destructive,
18}
19
20impl std::fmt::Display for ButtonVariant {
21    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22        let s = match self {
23            ButtonVariant::Primary => "primary",
24            ButtonVariant::Secondary => "secondary",
25            ButtonVariant::Outline => "outline",
26            ButtonVariant::Ghost => "ghost",
27            ButtonVariant::Link => "link",
28            ButtonVariant::Destructive => "destructive",
29        };
30        f.write_str(s)
31    }
32}
33
34/// Button size variant.
35#[derive(Clone, Debug, PartialEq, Eq, Default)]
36pub enum ButtonSize {
37    /// Default size — no size prefix in CSS class.
38    #[default]
39    Default,
40    Sm,
41    Lg,
42    Icon,
43}
44
45impl std::fmt::Display for ButtonSize {
46    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47        let s = match self {
48            ButtonSize::Default => "",
49            ButtonSize::Sm => "sm",
50            ButtonSize::Lg => "lg",
51            ButtonSize::Icon => "icon",
52        };
53        f.write_str(s)
54    }
55}
56
57#[derive(BasecoatProps, Default, Clone, Debug)]
58pub struct ButtonProps {
59    #[prop(default)]
60    pub variant: ButtonVariant,
61    #[prop(default)]
62    pub size: ButtonSize,
63    #[prop(optional, into)]
64    pub class: Option<Cow<'static, str>>,
65    #[prop(extend)]
66    pub attrs: AttrMap,
67    pub children: Children,
68}