update
This commit is contained in:
parent
8208fa8899
commit
ed739d792f
35 changed files with 1675 additions and 447 deletions
232
src/ui/mod.rs
232
src/ui/mod.rs
|
@ -1,134 +1,46 @@
|
|||
use maud::{Markup, PreEscaped, Render, html};
|
||||
|
||||
pub mod appbar;
|
||||
pub mod aspect;
|
||||
pub mod background;
|
||||
pub mod container;
|
||||
pub mod div;
|
||||
pub mod flex;
|
||||
pub mod header;
|
||||
pub mod image;
|
||||
pub mod link;
|
||||
pub mod padding;
|
||||
pub mod rounded;
|
||||
pub mod search;
|
||||
pub mod shadow;
|
||||
pub mod sized;
|
||||
pub mod text;
|
||||
pub mod width;
|
||||
use components::Shell;
|
||||
use maud::{Markup, PreEscaped, Render};
|
||||
|
||||
// UI
|
||||
|
||||
// Preludes
|
||||
|
||||
// Basic Primitives
|
||||
pub mod basic {
|
||||
pub use super::aspect::Aspect;
|
||||
pub use super::background::Background;
|
||||
pub use super::background::{Blue, Gray};
|
||||
pub use super::container::Container;
|
||||
pub use super::div::Div;
|
||||
pub use super::flex::Flex;
|
||||
pub use super::flex::Justify;
|
||||
pub use super::header::Header;
|
||||
pub use super::image::Image;
|
||||
pub use super::link::Link;
|
||||
pub use super::padding::Padding;
|
||||
pub use super::rounded::Rounded;
|
||||
pub use super::rounded::RoundedMedium;
|
||||
pub use super::shadow::Shadow;
|
||||
pub use super::sized::Sized;
|
||||
pub use super::text::{Paragraph, Span, Text};
|
||||
pub use super::width::FitWidth;
|
||||
}
|
||||
pub mod color;
|
||||
pub mod htmx;
|
||||
pub mod primitives;
|
||||
pub mod wrapper;
|
||||
|
||||
// Stacked Components
|
||||
pub mod extended {
|
||||
pub use super::appbar::AppBar;
|
||||
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::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};
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn Nothing() -> PreEscaped<String> {
|
||||
html! {}
|
||||
}
|
||||
|
||||
/// Represents the HTML structure of a page shell, including the head, body class, and body content.
|
||||
///
|
||||
/// This structure is used to construct the overall HTML structure of a page, making it easier to generate consistent HTML pages dynamically.
|
||||
pub struct Shell {
|
||||
/// The HTML content for the `<head>` section of the page.
|
||||
head: PreEscaped<String>,
|
||||
/// An optional class attribute for the `<body>` element.
|
||||
body_class: Option<String>,
|
||||
/// The HTML content for the static body portion.
|
||||
body_content: PreEscaped<String>,
|
||||
}
|
||||
|
||||
impl Shell {
|
||||
/// Constructs a new `Shell` instance with the given head content, body content, and body class.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `head` - The HTML content for the page's head.
|
||||
/// * `body_content` - The HTML content for the body of the page.
|
||||
/// * `body_class` - An optional class to apply to the `<body>` element.
|
||||
///
|
||||
/// # Returns
|
||||
/// A `Shell` instance encapsulating the provided HTML content and attributes.
|
||||
#[must_use]
|
||||
pub const fn new(
|
||||
head: PreEscaped<String>,
|
||||
body_content: PreEscaped<String>,
|
||||
body_class: Option<String>,
|
||||
) -> Self {
|
||||
Self {
|
||||
head,
|
||||
body_class,
|
||||
body_content,
|
||||
}
|
||||
}
|
||||
|
||||
/// Renders the full HTML page using the shell structure, with additional content and a title.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `content` - The additional HTML content to render inside the main content div.
|
||||
/// * `title` - The title of the page, rendered inside the `<title>` element.
|
||||
///
|
||||
/// # Returns
|
||||
/// A `PreEscaped<String>` containing the full HTML page content.
|
||||
#[must_use]
|
||||
pub fn render(&self, content: PreEscaped<String>, title: &str) -> PreEscaped<String> {
|
||||
html! {
|
||||
html {
|
||||
head {
|
||||
title { (title) };
|
||||
(self.head)
|
||||
};
|
||||
@if self.body_class.is_some() {
|
||||
body class=(self.body_class.as_ref().unwrap()) {
|
||||
(self.body_content);
|
||||
|
||||
div id="main_content" {
|
||||
(content)
|
||||
};
|
||||
};
|
||||
} @else {
|
||||
body {
|
||||
(self.body_content);
|
||||
|
||||
div id="main_content" {
|
||||
(content)
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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
|
||||
|
@ -161,61 +73,6 @@ pub async fn render_page(
|
|||
}
|
||||
}
|
||||
|
||||
/// Generates an HTML link with HTMX attributes for dynamic behavior.
|
||||
///
|
||||
/// This function creates an `<a>` element with attributes that enable HTMX behavior for navigation without reload.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `url` - The URL to link to.
|
||||
/// * `class` - The CSS class for styling the link.
|
||||
/// * `onclick` - The JavaScript `onclick` handler for the link.
|
||||
/// * `content` - The content inside the link element.
|
||||
///
|
||||
/// # Returns
|
||||
/// A `PreEscaped<String>` containing the rendered HTML link element.
|
||||
#[must_use]
|
||||
pub fn htmx_link(
|
||||
url: &str,
|
||||
class: &str,
|
||||
onclick: &str,
|
||||
content: PreEscaped<String>,
|
||||
) -> PreEscaped<String> {
|
||||
html!(
|
||||
a class=(class) onclick=(onclick) href=(url) hx-get=(url) hx-target="#main_content" hx-push-url="true" hx-swap="innerHTML" {
|
||||
(content);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
/// Generates a `<script>` element containing the provided JavaScript code.
|
||||
///
|
||||
/// This function wraps the provided JavaScript code in a `<script>` tag,
|
||||
/// allowing for easy inclusion of custom scripts in the rendered HTML.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `script` - The JavaScript code to include.
|
||||
///
|
||||
/// # Returns
|
||||
/// A `PreEscaped<String>` containing the rendered `<script>` element.
|
||||
#[must_use]
|
||||
pub fn script(script: &str) -> PreEscaped<String> {
|
||||
html!(
|
||||
script {
|
||||
(PreEscaped(script))
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
pub struct Row(PreEscaped<String>);
|
||||
|
||||
impl Render for Row {
|
||||
fn render(&self) -> maud::Markup {
|
||||
html! {
|
||||
div class="flex" { (self.0) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Grids
|
||||
|
||||
// ListViews
|
||||
|
@ -224,23 +81,40 @@ impl Render for Row {
|
|||
|
||||
// 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()
|
||||
}
|
||||
}
|
||||
|
||||
// TODO :
|
||||
// hover focus
|
||||
// responsive media
|
||||
// more elements
|
||||
// htmx builder trait?
|
||||
/// Trait for an element which can add new `attrs`
|
||||
pub trait AttrExtendable {
|
||||
fn add_attr(self, key: &str, val: &str) -> Self;
|
||||
|
||||
/// Set the `id` attribute of an element.
|
||||
fn id(self, id: &str) -> Self;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue