based/src/ui/mod.rs
2025-01-20 23:09:36 +01:00

192 lines
5.6 KiB
Rust

use components::Shell;
use maud::{Markup, PreEscaped, Render};
use prelude::Text;
// 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::Context;
pub use super::primitives::Nothing;
pub use super::primitives::Side;
pub use super::primitives::Size;
pub use super::primitives::animation::{Animated, Animation, Delay, Duration, Scope, Timing};
pub use super::primitives::aspect::Aspect;
pub use super::primitives::background::Background;
pub use super::primitives::border::{
Border, BorderSide, BorderSize, BorderStyle, Outline, OutlineStyle, Ring,
};
pub use super::primitives::container::Container;
pub use super::primitives::cursor::Cursor;
pub use super::primitives::div::Div;
pub use super::primitives::filter::{
Blur, Brightness, Contrast, Grayscale, HueRotate, Invert, Saturate, Sepia,
};
pub use super::primitives::flex::{
Direction, Flex, FlexBasis, FlexGrow, Justify, Order, Strategy, Wrap,
};
pub use super::primitives::header::Header;
pub use super::primitives::height::{Height, MaxHeight, MinHeight};
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::position::{Position, PositionKind};
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::svg::SVG;
pub use super::primitives::text::{
Code, DecorationKind, DecorationStyle, DecorationThickness, LetterSpacing, LineClamp,
LineHeight, ListStyle, NumberStyle, Paragraph, Span, Text, TextAlignment, TextContent,
TextDecoration, TextHyphens, TextOverflow, TextTransform, TextWhitespace, TextWordBreak,
TextWrap, UnderlineOffset, VerticalTextAlignment,
};
pub use super::primitives::transform::{
RenderTransformCPU, RenderTransformGPU, Rotate, Scale, Skew, Transform, TransformOrigin,
};
pub use super::primitives::visibility::Visibility;
pub use super::primitives::width::{MaxWidth, MinWidth, Width};
pub use super::primitives::zindex::ZIndex;
pub use super::wrapper::{
_2XLScreen, Hover, LargeScreen, MediumScreen, Screen, SmallScreen, XLScreen,
};
}
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
///
/// Base here means all classes defining the current widget
fn base_class(&self) -> Vec<String>;
/// Return own base classes and all classes below the tree
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()
}
}
impl UIWidget for String {
fn can_inherit(&self) -> bool {
Text(&self).can_inherit()
}
fn base_class(&self) -> Vec<String> {
Text(&self).base_class()
}
fn extended_class(&self) -> Vec<String> {
Text(&self).extended_class()
}
fn render_with_class(&self, class: &str) -> Markup {
Text(&self).render_with_class(class)
}
}
impl UIWidget for &str {
fn can_inherit(&self) -> bool {
Text(&self).can_inherit()
}
fn base_class(&self) -> Vec<String> {
Text(&self).base_class()
}
fn extended_class(&self) -> Vec<String> {
Text(&self).extended_class()
}
fn render_with_class(&self, class: &str) -> Markup {
Text(&self).render_with_class(class)
}
}
/// 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;
}