Implement the Pico CSS theme editor.

This commit is contained in:
2026-07-20 14:28:47 +02:00
parent 1d190d33c5
commit fe7dd82f33
20 changed files with 1033 additions and 161 deletions

View File

@@ -1,5 +1,21 @@
use serde::{Deserialize, Serialize};
pub const SUPPORTED_PICO_THEMES: [&str; 20] = [
"default", "amber", "blue", "cyan", "fuchsia", "green", "grey", "indigo", "jade", "lime",
"orange", "pink", "pumpkin", "purple", "red", "sand", "slate", "violet", "yellow", "zinc",
];
pub fn is_supported_pico_theme(theme: &str) -> bool {
SUPPORTED_PICO_THEMES.contains(&theme)
}
pub fn pico_stylesheet_href(theme: Option<&str>) -> String {
match theme.filter(|theme| is_supported_pico_theme(theme)) {
Some("default") | None => "/assets/pico.min.css".to_string(),
Some(theme) => format!("/assets/pico.{theme}.min.css"),
}
}
fn default_max_posts() -> i32 {
50
}
@@ -69,6 +85,11 @@ impl ProjectMetadata {
self.image_import_concurrency
));
}
if let Some(theme) = self.pico_theme.as_deref()
&& !is_supported_pico_theme(theme)
{
return Err(format!("unsupported picoTheme: {theme}"));
}
Ok(())
}
}
@@ -209,4 +230,14 @@ mod tests {
meta.max_posts_per_page = 500;
assert!(meta.validate().is_ok());
}
#[test]
fn pico_theme_validation_accepts_only_bundled_themes() {
let mut meta: ProjectMetadata = serde_json::from_str(r#"{"name":"Test"}"#).unwrap();
meta.pico_theme = Some("amber".into());
assert!(meta.validate().is_ok());
meta.pico_theme = Some("nightfall".into());
assert!(meta.validate().is_err());
}
}

View File

@@ -26,7 +26,10 @@ pub use import::{
};
pub use mcp::{McpProposal, ProposalKind, ProposalStatus};
pub use media::{Media, MediaTranslation};
pub use metadata::{CategorySettings, ProjectMetadata, TagEntry};
pub use metadata::{
CategorySettings, ProjectMetadata, SUPPORTED_PICO_THEMES, TagEntry, is_supported_pico_theme,
pico_stylesheet_href,
};
pub use post::{Post, PostLink, PostMedia, PostStatus, PostTranslation};
pub use project::{Project, Setting};
pub use script::{Script, ScriptKind, ScriptStatus};