dioxus_bootstrap_css/head.rs
1use dioxus::prelude::*;
2
3const BOOTSTRAP_CSS: Asset = asset!("/assets/bootstrap.min.css");
4const BOOTSTRAP_ICONS_CSS: Asset = asset!("/assets/bootstrap-icons.min.css");
5
6/// How to load Bootstrap CSS.
7///
8/// Default: `Bundled` — uses the crate's embedded Bootstrap 5.3.3.
9#[derive(Clone, PartialEq, Default)]
10pub enum BootstrapCss {
11 /// Use the crate's bundled Bootstrap 5.3.3 CSS (default, zero config).
12 #[default]
13 Bundled,
14 /// Load from a custom URL (self-hosted, proxy to SSR backend, etc.).
15 ///
16 /// ```rust,ignore
17 /// BootstrapHead { css: BootstrapCss::Url("/static/vendor/bootstrap.min.css".into()) }
18 /// ```
19 Url(String),
20 /// Load from jsDelivr CDN with a specific version.
21 ///
22 /// ```rust,ignore
23 /// BootstrapHead { css: BootstrapCss::Cdn("5.3.3".into()) }
24 /// ```
25 Cdn(String),
26 /// Don't load any CSS — user handles it themselves.
27 None,
28}
29
30/// How to load Bootstrap Icons CSS.
31///
32/// Default: `Bundled` — uses the crate's embedded Bootstrap Icons.
33#[derive(Clone, PartialEq, Default)]
34pub enum BootstrapIcons {
35 /// Use the crate's bundled Bootstrap Icons CSS (default).
36 #[default]
37 Bundled,
38 /// Load from a custom URL.
39 Url(String),
40 /// Don't load icons CSS — user handles it.
41 None,
42}
43
44/// Loads Bootstrap CSS and Bootstrap Icons for your Dioxus app.
45///
46/// Place this at the top of your app, before any Bootstrap components.
47///
48/// # Zero config (default — bundled Bootstrap 5.3.3)
49/// ```rust,ignore
50/// rsx! { BootstrapHead {} }
51/// ```
52///
53/// # Custom CSS URL (migrating from SSR with its own Bootstrap)
54/// ```rust,ignore
55/// rsx! {
56/// BootstrapHead {
57/// css: BootstrapCss::Url("/static/vendor/bootstrap.min.css".into()),
58/// icons: BootstrapIcons::Url("/static/vendor/bootstrap-icons/font/bootstrap-icons.css".into()),
59/// }
60/// }
61/// ```
62///
63/// # CDN with specific version
64/// ```rust,ignore
65/// rsx! { BootstrapHead { css: BootstrapCss::Cdn("5.3.3".into()) } }
66/// ```
67///
68/// # Full control (load CSS yourself)
69/// ```rust,ignore
70/// rsx! {
71/// BootstrapHead { css: BootstrapCss::None, icons: BootstrapIcons::None }
72/// link { rel: "stylesheet", href: "my-custom-bootstrap.css" }
73/// }
74/// ```
75#[derive(Clone, PartialEq, Props)]
76pub struct BootstrapHeadProps {
77 /// How to load Bootstrap CSS. Default: bundled v5.3.3.
78 #[props(default)]
79 pub css: BootstrapCss,
80 /// How to load Bootstrap Icons CSS. Default: bundled.
81 #[props(default)]
82 pub icons: BootstrapIcons,
83}
84
85#[component]
86pub fn BootstrapHead(props: BootstrapHeadProps) -> Element {
87 let css_element = match &props.css {
88 BootstrapCss::Bundled => rsx! {
89 document::Link { rel: "stylesheet", href: BOOTSTRAP_CSS }
90 },
91 BootstrapCss::Url(url) => {
92 let url = url.clone();
93 rsx! { link { rel: "stylesheet", href: "{url}" } }
94 }
95 BootstrapCss::Cdn(version) => {
96 let href = format!(
97 "https://cdn.jsdelivr.net/npm/bootstrap@{version}/dist/css/bootstrap.min.css"
98 );
99 rsx! { link { rel: "stylesheet", href: "{href}" } }
100 }
101 BootstrapCss::None => rsx! {},
102 };
103
104 let icons_element = match &props.icons {
105 BootstrapIcons::Bundled => rsx! {
106 document::Link { rel: "stylesheet", href: BOOTSTRAP_ICONS_CSS }
107 },
108 BootstrapIcons::Url(url) => {
109 let url = url.clone();
110 rsx! { link { rel: "stylesheet", href: "{url}" } }
111 }
112 BootstrapIcons::None => rsx! {},
113 };
114
115 rsx! {
116 {css_element}
117 {icons_element}
118 }
119}