From 468b9449b26329b15dd7833ae5f7d59a16ab96f3 Mon Sep 17 00:00:00 2001 From: Myrddin Dundragon Date: Sun, 28 Sep 2025 15:12:03 -0400 Subject: [PATCH] Client side settings can now be specified. Here we use a context provider on the app itself to handle passing the settings to our library. This way even the layout can use them. --- bard/Cargo.toml | 2 +- bard/assets/css/blog.css | 108 +++++++++++++++++++++++++----------- bard/src/components/post.rs | 7 ++- bard/src/lib.rs | 2 + bard/src/page.rs | 32 ++++++++++- bard/src/settings.rs | 33 +++++++++++ 6 files changed, 150 insertions(+), 34 deletions(-) create mode 100644 bard/src/settings.rs diff --git a/bard/Cargo.toml b/bard/Cargo.toml index 0ce13aa..8e9291f 100644 --- a/bard/Cargo.toml +++ b/bard/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bard" -version = "0.3.2" +version = "0.3.3" edition = "2024" description = "Dioxus components that will display a Tavern blogging system Blog." repository = "/CyberMages/tavern" diff --git a/bard/assets/css/blog.css b/bard/assets/css/blog.css index a01c3a3..77fc082 100644 --- a/bard/assets/css/blog.css +++ b/bard/assets/css/blog.css @@ -40,6 +40,7 @@ .blog_title { margin-top: 0px; + color: var(--accent-color); } .blog_item @@ -89,16 +90,26 @@ margin-bottom: 20px; } - .embeded_video + .blog_post_tale { - margin-top: 50px; - display: flex; - align-content: center; - justify-content: center; + all: initial; - iframe + pre { - box-shadow: 0 0 80px var(--accent-color); + padding-left: 20px; + } + + .embeded_video + { + margin-top: 50px; + display: flex; + align-content: center; + justify-content: center; + + iframe + { + box-shadow: 0 0 80px var(--accent-color); + } } } } @@ -144,9 +155,10 @@ legend { - min-width: 120px; + min-width: 130px; padding: 0; margin: 0; + font-weight: bold; } .tag_list @@ -155,40 +167,74 @@ flex-direction: column; } +.toggle_button { + display: inline-block; + margin-top: 5px; + margin-right: 5px; + padding: 0px 6px; + border: 2px solid var(--text-color); + border-radius: 5px; + color: var(--text-color); + cursor: pointer; + user-select: none; + transition: 0.1s ease-in; +} + +.toggle_button:hover { + color: var(--accent-color); + border-color: var(--accent-color); + transform: translateY(-2px); +} + +.toggle_button input[type="checkbox"] { + position: absolute; + opacity: 0; + width: 0; + height: 0; + pointer-events: none; +} + +/* Checked state using :has() — modern browsers only */ +.toggle_button:has(input:checked) { + color: var(--accent-color); + border-color: var(--accent-color); +} + + @container site (max-width: 1230px) { display: none; } } - .tag_list +.tag_list +{ + list-style: none; + padding: 0px; + margin: 0px; + + .tag_item { - list-style: none; - padding: 0px; - margin: 0px; + margin-top: 5px; + margin-right: 5px; - .tag_item + a { - margin-top: 5px; - margin-right: 5px; + display: inline-block; + padding: 0px 4px; + text-decoration: none; + border: 2px solid var(--text-color); + border-radius: 5px; - a + color: var(--text-color); + transition: 0.1s ease-in; + + &:hover { - display: block; - padding: 0px 4px; - text-decoration: none; - border: 2px solid var(--text-color); - border-radius: 5px; - - color: var(--text-color); - transition: 0.1s ease-in; - - &:hover - { - color: var(--accent-color); - border: 2px solid var(--accent-color); - transform: translateY(-2px); - } + color: var(--accent-color); + border: 2px solid var(--accent-color); + transform: translateY(-2px); } } } +} diff --git a/bard/src/components/post.rs b/bard/src/components/post.rs index 7848629..b2461e0 100644 --- a/bard/src/components/post.rs +++ b/bard/src/components/post.rs @@ -82,7 +82,12 @@ pub fn Story(text: String) -> Element { rsx! { - div { dangerous_inner_html: "{text}" } + div + { + class: "blog_post_tale", + + dangerous_inner_html: "{text}" + } } } diff --git a/bard/src/lib.rs b/bard/src/lib.rs index 6edbc26..837c3d9 100644 --- a/bard/src/lib.rs +++ b/bard/src/lib.rs @@ -6,6 +6,7 @@ mod components; mod page; mod pages; mod server; +mod settings; mod togglable; @@ -14,5 +15,6 @@ pub use crate::components::*; pub use crate::info::{get_name, get_version}; pub use crate::page::Page; pub use crate::pages::*; +pub use crate::settings::*; #[cfg(feature = "server")] pub use crate::server::*; diff --git a/bard/src/page.rs b/bard/src/page.rs index 7fa0471..e25fc78 100644 --- a/bard/src/page.rs +++ b/bard/src/page.rs @@ -1,6 +1,7 @@ use dioxus::prelude::*; use crate::pages::{Blog, Post, Root}; +use crate::settings::{BardSettings, StylesheetBehavior}; @@ -11,9 +12,38 @@ const BLOG_CSS: Asset = asset!("/assets/css/blog.css"); #[component] fn BlogLayout() -> Element { + // Retrieve the provided settings from context. + let settings = use_context::(); + rsx! { - document::Stylesheet { href: BLOG_CSS } + match settings.stylesheet + { + StylesheetBehavior::Override(asset) => + { + rsx! + { + document::Stylesheet { href: asset } + } + } + + StylesheetBehavior::Extend(asset) => + { + rsx! + { + document::Stylesheet { href: BLOG_CSS } + document::Stylesheet { href: asset } + } + } + + StylesheetBehavior::None => + { + rsx! + { + document::Stylesheet { href: BLOG_CSS } + } + } + } Outlet:: {} } diff --git a/bard/src/settings.rs b/bard/src/settings.rs new file mode 100644 index 0000000..074836b --- /dev/null +++ b/bard/src/settings.rs @@ -0,0 +1,33 @@ +use dioxus::prelude::*; + + +#[derive(Copy, Clone)] +pub enum StylesheetBehavior +{ + /// Overrides the default stylesheet. + Override(Asset), + + /// Extends the default stylesheet. The library will load both. + Extend(Asset), + + /// Uses the library's default stylesheet. + None +} + + +#[derive(Copy, Clone, Default)] +pub struct BardSettings +{ + /// A user defined stylesheet and how the library should include it. + pub stylesheet: StylesheetBehavior +} + + + +impl Default for StylesheetBehavior +{ + fn default() -> Self + { + StylesheetBehavior::None + } +}