based/src/ui/mod.rs
2025-01-15 19:20:46 +01:00

123 lines
3.3 KiB
Rust

use components::Shell;
use maud::{Markup, PreEscaped, Render};
// UI
// Basic Primitives
pub mod color;
pub mod htmx;
pub mod primitives;
pub mod wrapper;
// Stacked Components
pub mod components;
// Preludes
pub mod prelude {
pub use super::color::*;
pub use super::primitives::Nothing;
pub use super::primitives::Side;
pub use super::primitives::Size;
pub use super::primitives::aspect::Aspect;
pub use super::primitives::background::Background;
pub use super::primitives::container::Container;
pub use super::primitives::div::Div;
pub use super::primitives::flex::{Flex, Justify};
pub use super::primitives::header::Header;
pub use super::primitives::image::Image;
pub use super::primitives::link::Link;
pub use super::primitives::margin::Margin;
pub use super::primitives::padding::Padding;
pub use super::primitives::rounded::Rounded;
pub use super::primitives::script;
pub use super::primitives::shadow::Shadow;
pub use super::primitives::sized::Sized;
pub use super::primitives::space::{ScreenValue, SpaceBetween};
pub use super::primitives::text::{Paragraph, Span, Text};
pub use super::primitives::width::FitWidth;
pub use super::wrapper::Hover;
}
use crate::request::{RequestContext, StringResponse};
use rocket::http::{ContentType, Status};
/// Renders a full page or an HTMX-compatible fragment based on the request context.
///
/// If the request is not an HTMX request, this function uses the provided shell to generate
/// a full HTML page. If it is an HTMX request, only the provided content is rendered.
///
/// # Arguments
/// * `content` - The HTML content to render.
/// * `title` - The title of the page for full-page rendering.
/// * `ctx` - The `RequestContext` containing request metadata.
/// * `shell` - The `Shell` instance used for full-page rendering.
///
/// # Returns
/// A `StringResponse`
pub async fn render_page(
content: PreEscaped<String>,
title: &str,
ctx: RequestContext,
shell: &Shell,
) -> StringResponse {
if ctx.is_htmx {
(Status::Ok, (ContentType::HTML, content.into_string()))
} else {
(
Status::Ok,
(
ContentType::HTML,
shell.render(content, title).into_string(),
),
)
}
}
// Grids
// ListViews
// ListTiles
// Cards
/// Generic UI Widget
pub trait UIWidget: Render {
/// Indicating if the widget supports inheriting classes
fn can_inherit(&self) -> bool;
/// Returning the base classes for this widget
fn base_class(&self) -> Vec<String>;
fn extended_class(&self) -> Vec<String>;
/// Render the widget with additional classes
fn render_with_class(&self, class: &str) -> Markup;
}
/// Implementation for raw HTML with html! macro
impl UIWidget for PreEscaped<String> {
fn can_inherit(&self) -> bool {
false
}
fn base_class(&self) -> Vec<String> {
vec![]
}
fn extended_class(&self) -> Vec<String> {
vec![]
}
fn render_with_class(&self, _: &str) -> Markup {
self.render()
}
}
/// Trait for an element which can add new `attrs`
pub trait AttrExtendable {
#[must_use]
fn add_attr(self, key: &str, val: &str) -> Self;
/// Set the `id` attribute of an element.
#[must_use]
fn id(self, id: &str) -> Self;
}