Skip to main content

dioxus_bootstrap_css/
types.rs

1use std::fmt;
2
3/// Bootstrap contextual color variants.
4///
5/// Maps to Bootstrap's color classes: `primary`, `secondary`, `success`,
6/// `danger`, `warning`, `info`, `light`, `dark`.
7///
8/// # Bootstrap HTML → Dioxus
9///
10/// | HTML class | Dioxus |
11/// |---|---|
12/// | `btn-primary` | `Button { color: Color::Primary }` |
13/// | `alert-danger` | `Alert { color: Color::Danger }` |
14/// | `text-bg-success` | `Badge { color: Color::Success }` |
15/// | `bg-warning` | `Toast { color: Color::Warning }` |
16#[derive(Clone, Copy, Debug, Default, PartialEq)]
17pub enum Color {
18    #[default]
19    Primary,
20    Secondary,
21    Success,
22    Danger,
23    Warning,
24    Info,
25    Light,
26    Dark,
27}
28
29impl fmt::Display for Color {
30    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31        match self {
32            Color::Primary => write!(f, "primary"),
33            Color::Secondary => write!(f, "secondary"),
34            Color::Success => write!(f, "success"),
35            Color::Danger => write!(f, "danger"),
36            Color::Warning => write!(f, "warning"),
37            Color::Info => write!(f, "info"),
38            Color::Light => write!(f, "light"),
39            Color::Dark => write!(f, "dark"),
40        }
41    }
42}
43
44/// How a badge takes its colour.
45///
46/// Bootstrap 5.3 offers three distinct colour idioms for a badge, and they are
47/// not interchangeable. `text-bg-*` sets a background **and** a contrasting
48/// foreground; `bg-*` sets only the background and lets the text colour be
49/// inherited; the subtle pair is a background and text colour that are designed
50/// together. Without this choice a caller can only get the first, and reaching
51/// for the others means hand-writing the classes the component exists to type.
52///
53/// # Bootstrap HTML → Dioxus
54///
55/// | HTML class | Dioxus |
56/// |---|---|
57/// | `badge text-bg-primary` | `Badge { color: Color::Primary }` |
58/// | `badge bg-secondary` | `Badge { color: Color::Secondary, fill: BadgeFill::Bg }` |
59/// | `badge bg-info-subtle text-info-emphasis` | `Badge { color: Color::Info, fill: BadgeFill::Subtle }` |
60/// | `badge` | `Badge { fill: BadgeFill::None }` |
61#[derive(Clone, Copy, Debug, Default, PartialEq)]
62pub enum BadgeFill {
63    /// `text-bg-<color>` — background plus contrasting text. Bootstrap's badge
64    /// helper, and the default, so omitting the prop changes nothing.
65    #[default]
66    TextBg,
67    /// `bg-<color>` — the background utility alone, text colour inherited.
68    Bg,
69    /// `bg-<color>-subtle text-<color>-emphasis` — Bootstrap's low-contrast
70    /// pair. Both classes together: the subtle background is near-invisible
71    /// without its matching emphasis foreground, so this is one idiom rather
72    /// than two utilities a caller should have to remember to combine.
73    Subtle,
74    /// No colour idiom — a bare `badge`, the chip geometry only. Use this when
75    /// painting the background yourself: `text-bg-*` also sets a foreground, so
76    /// an inline background override would otherwise inherit a text colour it
77    /// never asked for.
78    None,
79}
80
81/// The container a navbar wraps its contents in.
82///
83/// Bootstrap's navbar examples put the brand and links inside a `.container` or
84/// `.container-fluid`; the gutter belongs to that container, not to `<nav>`.
85/// A navbar that supplies its own padding needs to be able to omit it.
86///
87/// # Bootstrap HTML → Dioxus
88///
89/// | HTML | Dioxus |
90/// |---|---|
91/// | `<div class="container-fluid">` | `Navbar { container: NavbarContainer::Fluid }` |
92/// | `<div class="container">` | `Navbar { container: NavbarContainer::Fixed }` |
93/// | (no wrapper) | `Navbar { container: NavbarContainer::None }` |
94#[derive(Clone, Copy, Debug, Default, PartialEq)]
95pub enum NavbarContainer {
96    /// `container-fluid` — full width with gutters. Bootstrap's own default and
97    /// this component's, so omitting the prop is unchanged behaviour.
98    #[default]
99    Fluid,
100    /// `container` — the responsive fixed-width container.
101    Fixed,
102    /// No container element at all: brand and children are direct children of
103    /// `<nav>`.
104    None,
105}
106
107impl NavbarContainer {
108    /// The container class, or `None` when no wrapper element should be
109    /// emitted. Returning an `Option` rather than an empty string keeps
110    /// "no class" and "no element" from being the same answer — an empty
111    /// `<div class="">` is still a box in the layout.
112    pub fn class(&self) -> Option<&'static str> {
113        match self {
114            NavbarContainer::Fluid => Some("container-fluid"),
115            NavbarContainer::Fixed => Some("container"),
116            NavbarContainer::None => None,
117        }
118    }
119}
120
121/// Bootstrap component size variants.
122///
123/// # Bootstrap HTML → Dioxus
124///
125/// | HTML class | Dioxus |
126/// |---|---|
127/// | `btn-sm` | `Button { size: Size::Sm }` |
128/// | `btn-lg` | `Button { size: Size::Lg }` |
129/// | `form-control-sm` | `Input { size: Size::Sm }` |
130/// | `pagination-lg` | `Pagination { size: Size::Lg }` |
131#[derive(Clone, Copy, Debug, Default, PartialEq)]
132pub enum Size {
133    Sm,
134    #[default]
135    Md,
136    Lg,
137}
138
139impl fmt::Display for Size {
140    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141        match self {
142            Size::Sm => write!(f, "sm"),
143            Size::Md => write!(f, "md"),
144            Size::Lg => write!(f, "lg"),
145        }
146    }
147}
148
149/// Bootstrap column span (1–12 or auto).
150///
151/// # Bootstrap HTML → Dioxus
152///
153/// | HTML class | Dioxus |
154/// |---|---|
155/// | `col-6` | `Col { xs: ColumnSize::Span(6) }` |
156/// | `col-md-4` | `Col { md: ColumnSize::Span(4) }` |
157/// | `col-auto` | `Col { xs: ColumnSize::Auto }` |
158/// | `col-lg-auto` | `Col { lg: ColumnSize::Auto }` |
159#[derive(Clone, Copy, Debug, PartialEq)]
160pub enum ColumnSize {
161    Auto,
162    Span(u8),
163}
164
165impl fmt::Display for ColumnSize {
166    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
167        match self {
168            ColumnSize::Auto => write!(f, "auto"),
169            ColumnSize::Span(n) => write!(f, "{n}"),
170        }
171    }
172}
173
174/// Bootstrap navbar responsive expand breakpoints.
175///
176/// Controls when the navbar switches from collapsed (hamburger) to expanded (horizontal).
177///
178/// # Bootstrap HTML → Dioxus
179///
180/// | HTML class | Dioxus |
181/// |---|---|
182/// | `navbar-expand-lg` | `Navbar { expand: NavbarExpand::Lg }` |
183/// | `navbar-expand` | `Navbar { expand: NavbarExpand::Always }` |
184#[derive(Clone, Copy, Debug, Default, PartialEq)]
185pub enum NavbarExpand {
186    Sm,
187    #[default]
188    Md,
189    Lg,
190    Xl,
191    Xxl,
192    Always,
193}
194
195impl fmt::Display for NavbarExpand {
196    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
197        match self {
198            NavbarExpand::Sm => write!(f, "navbar-expand-sm"),
199            NavbarExpand::Md => write!(f, "navbar-expand-md"),
200            NavbarExpand::Lg => write!(f, "navbar-expand-lg"),
201            NavbarExpand::Xl => write!(f, "navbar-expand-xl"),
202            NavbarExpand::Xxl => write!(f, "navbar-expand-xxl"),
203            NavbarExpand::Always => write!(f, "navbar-expand"),
204        }
205    }
206}
207
208/// Bootstrap modal size.
209///
210/// # Bootstrap HTML → Dioxus
211///
212/// | HTML class | Dioxus |
213/// |---|---|
214/// | `modal-sm` | `Modal { size: ModalSize::Sm }` |
215/// | (default) | `Modal { size: ModalSize::Default }` |
216/// | `modal-lg` | `Modal { size: ModalSize::Lg }` |
217/// | `modal-xl` | `Modal { size: ModalSize::Xl }` |
218#[derive(Clone, Copy, Debug, Default, PartialEq)]
219pub enum ModalSize {
220    Sm,
221    #[default]
222    Default,
223    Lg,
224    Xl,
225}
226
227/// Spinner animation style.
228///
229/// # Bootstrap HTML → Dioxus
230///
231/// | HTML class | Dioxus |
232/// |---|---|
233/// | `spinner-border` | `Spinner { style: SpinnerStyle::Border }` |
234/// | `spinner-grow` | `Spinner { style: SpinnerStyle::Grow }` |
235#[derive(Clone, Copy, Debug, Default, PartialEq)]
236pub enum SpinnerStyle {
237    #[default]
238    Border,
239    Grow,
240}