🚧 Working on layout

This commit is contained in:
Manuel Cillero 2024-03-28 09:11:14 +01:00
parent d99a5aa586
commit 0f65711d0e
10 changed files with 181 additions and 109 deletions

View file

@ -17,7 +17,6 @@ impl PackageTrait for Bootsier {
action::theme::BeforePrepare::<Button>::new(&Self, before_prepare_button),
action::theme::BeforePrepare::<Heading>::new(&Self, before_prepare_heading),
action::theme::BeforePrepare::<Paragraph>::new(&Self, before_prepare_paragraph),
action::theme::RenderComponent::<Layout>::new(&Self, render_layout),
action::theme::RenderComponent::<Error404>::new(&Self, render_error404),
]
}
@ -43,6 +42,46 @@ impl ThemeTrait for Bootsier {
]
}
fn prepare_body(&self, page: &mut Page) -> Markup {
let skip_to_id = concat_string!("#", page.skip_to().get().unwrap_or("content".to_owned()));
Container::body()
.with_id(page.body_id().get().unwrap_or("".to_string()))
.with_classes(ClassesOp::Add, page.body_classes().get().unwrap_or("".to_string()))
.add_item(Flex::bundle()
.add_component(Html::with(html! {
@if let Some(skip) = L10n::l("skip_to_content").using(page.context().langid()) {
div class="skip__to_content" {
a href=(skip_to_id) { (skip) }
}
}
}))
.add_component(
match page.context().layout() {
"admin" => Container::new().add_item(
Flex::new()
.add_component(Region::named("top-menu"))
.add_component(Region::named("side-menu"))
.add_component(Region::named("content")),
),
_ => Container::new().add_item(
Flex::new()
.add_component(Region::named("header"))
.add_component(Region::named("nav_branding"))
.add_component(Region::named("nav_main"))
.add_component(Region::named("nav_additional"))
.add_component(Region::named("breadcrumb"))
.add_component(Region::named("content"))
.add_component(Region::named("sidebar_first"))
.add_component(Region::named("sidebar_second"))
.add_component(Region::named("footer")),
),
}
)
)
.render(page.context())
}
fn after_prepare_body(&self, page: &mut Page) {
page.alter_favicon(Some(Favicon::new().with_icon("/base/favicon.ico")))
.alter_assets(AssetsOp::AddStyleSheet(
@ -113,32 +152,6 @@ fn before_prepare_paragraph(p: &mut Paragraph, _cx: &mut Context) {
);
}
fn render_layout(_: &Layout, cx: &mut Context) -> Option<Markup> {
Some(
match cx.layout() {
"admin" => Container::new().add_item(
Flex::new()
.add_component(Region::named("top-menu"))
.add_component(Region::named("side-menu"))
.add_component(Region::named("content")),
),
_ => Container::new().add_item(
Flex::new()
.add_component(Region::named("header"))
.add_component(Region::named("nav_branding"))
.add_component(Region::named("nav_main"))
.add_component(Region::named("nav_additional"))
.add_component(Region::named("breadcrumb"))
.add_component(Region::named("content"))
.add_component(Region::named("sidebar_first"))
.add_component(Region::named("sidebar_second"))
.add_component(Region::named("footer")),
),
}
.render(cx),
)
}
fn render_error404(_: &Error404, cx: &mut Context) -> Option<Markup> {
Some(html! {
div class="jumbotron" {

View file

@ -160,8 +160,8 @@ impl ToString for FontSize {
mod basic;
pub use basic::*;
mod composition;
pub use composition::*;
mod layout;
pub use layout::*;
mod error403;
pub use error403::Error403;

View file

@ -3,3 +3,6 @@ pub use html::Html;
mod fluent;
pub use fluent::Fluent;
mod components;
pub use components::Components;

View file

@ -0,0 +1,36 @@
use crate::prelude::*;
#[derive(AutoDefault)]
pub struct Components(MixedComponents);
impl ComponentTrait for Components {
fn new() -> Self {
Components::default()
}
fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
PrepareMarkup::With(self.components().render(cx))
}
}
impl Components {
// Components BUILDER.
#[fn_builder]
pub fn alter_components(&mut self, op: AnyOp) -> &mut Self {
self.0.alter_value(op);
self
}
#[rustfmt::skip]
pub fn add_component(mut self, component: impl ComponentTrait) -> Self {
self.0.alter_value(AnyOp::Add(AnyComponent::with(component)));
self
}
// Components GETTERS.
pub fn components(&self) -> &MixedComponents {
&self.0
}
}

View file

@ -1,60 +0,0 @@
use crate::prelude::*;
#[derive(AutoDefault)]
pub struct Layout;
impl ComponentTrait for Layout {
fn new() -> Self {
Layout
}
fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
PrepareMarkup::With(match cx.layout() {
"default" => Self::default_layout(cx),
"admin" => Self::admin_layout(cx),
_ => Self::default_layout(cx),
})
}
}
impl Layout {
fn default_layout(cx: &mut Context) -> Markup {
Container::new()
.with_id("body__wrapper")
.with_direction(FlexDirection::Column(BreakPoint::None))
.with_align(FlexAlign::Center)
.add_item(Flex::with(Region::named("header")).with_id("header"))
.add_item(Flex::with(Region::named("pagetop")).with_id("pagetop"))
.add_item(
Flex::with(
Container::new()
.with_direction(FlexDirection::Row(BreakPoint::None))
.add_item(
Flex::with(Region::named("sidebar_left"))
.with_id("sidebar_left")
.with_grow(FlexGrow::Is1),
)
.add_item(
Flex::with(Region::named("content"))
.with_id("content")
.with_grow(FlexGrow::Is3),
)
.add_item(
Flex::with(Region::named("sidebar_right"))
.with_id("sidebar_right")
.with_grow(FlexGrow::Is1),
),
)
.with_id("flex__wrapper"),
)
.add_item(Flex::with(Region::named("footer")).with_id("footer"))
.render(cx)
}
fn admin_layout(cx: &mut Context) -> Markup {
Html::with(html! {
("admin")
})
.render(cx)
}
}

View file

@ -4,9 +4,6 @@ pub use container::Container;
mod flex;
pub use flex::Flex;
mod layout;
pub use layout::Layout;
mod region;
pub use region::Region;

View file

@ -4,6 +4,7 @@ use crate::prelude::*;
pub enum ContainerType {
#[default]
Default,
Body,
Header,
Main,
Section,
@ -76,6 +77,11 @@ impl ComponentTrait for Container {
(output)
}
}),
ContainerType::Body => PrepareMarkup::With(html! {
body id=[self.id()] class=[self.classes().get()] style=[gap] {
(output)
}
}),
ContainerType::Header => PrepareMarkup::With(html! {
header id=[self.id()] class=[self.classes().get()] style=[gap] {
(output)
@ -106,6 +112,13 @@ impl ComponentTrait for Container {
}
impl Container {
pub fn body() -> Self {
Container {
container_type: ContainerType::Body,
..Default::default()
}
}
pub fn header() -> Self {
Container {
container_type: ContainerType::Header,

View file

@ -1,5 +1,13 @@
use crate::prelude::*;
#[derive(AutoDefault)]
pub enum ItemType {
#[default]
Default,
Wrapper,
Bundle,
}
#[rustfmt::skip]
#[derive(AutoDefault, ComponentClasses)]
pub struct Flex {
@ -7,6 +15,7 @@ pub struct Flex {
weight : Weight,
renderable : Renderable,
classes : OptionClasses,
item_type : ItemType,
flex_grow : FlexGrow,
flex_shrink : FlexShrink,
flex_size : FlexSize,
@ -54,13 +63,23 @@ impl ComponentTrait for Flex {
0 => None,
_ => Some(concat_string!("order: ", self.weight().to_string(), ";")),
};
PrepareMarkup::With(html! {
div id=[self.id()] class=[self.classes().get()] style=[order] {
div class="flex__content" {
match self.item_type() {
ItemType::Default => PrepareMarkup::With(html! {
div id=[self.id()] class=[self.classes().get()] style=[order] {
div class="flex__content" {
(output)
}
}
}),
ItemType::Wrapper => PrepareMarkup::With(html! {
div id=[self.id()] class=[self.classes().get()] style=[order] {
(output)
}
}
})
}),
ItemType::Bundle => PrepareMarkup::With(html! {
(output)
}),
}
} else {
PrepareMarkup::None
}
@ -68,6 +87,20 @@ impl ComponentTrait for Flex {
}
impl Flex {
pub fn wrapper() -> Self {
Flex {
item_type: ItemType::Wrapper,
..Default::default()
}
}
pub fn bundle() -> Self {
Flex {
item_type: ItemType::Bundle,
..Default::default()
}
}
pub fn with(component: impl ComponentTrait) -> Self {
Flex::default().add_component(component)
}
@ -138,6 +171,10 @@ impl Flex {
// Item GETTERS.
pub fn item_type(&self) -> &ItemType {
&self.item_type
}
pub fn grow(&self) -> &FlexGrow {
&self.flex_grow
}

View file

@ -1,7 +1,7 @@
use crate::base::component::Layout;
use crate::core::component::{ComponentBase, ComponentTrait};
use crate::base::component::*;
use crate::core::component::{ComponentBase, ComponentClassesOp, ComponentTrait};
use crate::core::package::PackageTrait;
use crate::html::{html, Favicon, Markup};
use crate::html::{html, ClassesOp, Favicon, Markup};
use crate::locale::L10n;
use crate::response::page::Page;
use crate::{concat_string, config};
@ -28,16 +28,49 @@ pub trait ThemeTrait: PackageTrait + Send + Sync {
fn prepare_body(&self, page: &mut Page) -> Markup {
let skip_to_id = concat_string!("#", page.skip_to().get().unwrap_or("content".to_owned()));
html! {
body id=[page.body_id().get()] class=[page.body_classes().get()] {
@if let Some(skip) = L10n::l("skip_to_content").using(page.context().langid()) {
div class="skip__to_content" {
a href=(skip_to_id) { (skip) }
Container::body()
.with_id(page.body_id().get().unwrap_or_default())
.with_classes(ClassesOp::Add, page.body_classes().get().unwrap_or_default())
.add_item(Flex::bundle()
.add_component(Html::with(html! {
@if let Some(skip) = L10n::l("skip_to_content").using(page.context().langid()) {
div class="skip__to_content" {
a href=(skip_to_id) { (skip) }
}
}
}
(Layout::new().render(page.context()))
}
}
}))
.add_component(Container::new()
.with_id("body__wrapper")
.with_direction(FlexDirection::Column(BreakPoint::None))
.with_align(FlexAlign::Center)
.add_item(Flex::with(Region::named("header")).with_id("header"))
.add_item(Flex::with(Region::named("pagetop")).with_id("pagetop"))
.add_item(
Flex::with(
Container::new()
.with_direction(FlexDirection::Row(BreakPoint::None))
.add_item(
Flex::with(Region::named("sidebar_left"))
.with_id("sidebar_left")
.with_grow(FlexGrow::Is1),
)
.add_item(
Flex::with(Region::named("content"))
.with_id("content")
.with_grow(FlexGrow::Is3),
)
.add_item(
Flex::with(Region::named("sidebar_right"))
.with_id("sidebar_right")
.with_grow(FlexGrow::Is1),
),
)
.with_id("flex__wrapper"),
)
.add_item(Flex::with(Region::named("footer")).with_id("footer")),
)
)
.render(page.context())
}
fn after_prepare_body(&self, page: &mut Page) {