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}