Introduce ContextualPath as dynamic path

This commit is contained in:
Manuel Cillero 2023-08-05 10:54:02 +02:00
parent fff8ab19aa
commit 25cb46e712
7 changed files with 74 additions and 19 deletions

View file

@ -7,15 +7,13 @@ new_handle!(COMPONENT_MEGAITEM);
type Label = OneComponent<L10n>; type Label = OneComponent<L10n>;
type Content = OneComponent<Html>; type Content = OneComponent<Html>;
pub type MegaItemPath = fn(cx: &Context) -> &str;
#[derive(Default)] #[derive(Default)]
pub enum MegaItemType { pub enum MegaItemType {
#[default] #[default]
Void, Void,
Label(Label), Label(Label),
Link(Label, MegaItemPath), Link(Label, ContextualPath),
LinkBlank(Label, MegaItemPath), LinkBlank(Label, ContextualPath),
Html(Content), Html(Content),
Submenu(Label, MegaMenu), Submenu(Label, MegaMenu),
Separator, Separator,
@ -86,14 +84,14 @@ impl MegaItem {
} }
} }
pub fn link(label: L10n, path: MegaItemPath) -> Self { pub fn link(label: L10n, path: ContextualPath) -> Self {
MegaItem { MegaItem {
item_type: MegaItemType::Link(Label::with(label), path), item_type: MegaItemType::Link(Label::with(label), path),
..Default::default() ..Default::default()
} }
} }
pub fn link_blank(label: L10n, path: MegaItemPath) -> Self { pub fn link_blank(label: L10n, path: ContextualPath) -> Self {
MegaItem { MegaItem {
item_type: MegaItemType::LinkBlank(Label::with(label), path), item_type: MegaItemType::LinkBlank(Label::with(label), path),
..Default::default() ..Default::default()

View file

@ -2,7 +2,7 @@ use pagetop::prelude::*;
pub mod component { pub mod component {
mod item; mod item;
pub use item::{MegaItem, MegaItemPath, MegaItemType, COMPONENT_MEGAITEM}; pub use item::{MegaItem, MegaItemType, COMPONENT_MEGAITEM};
mod menu; mod menu;
pub use menu::{MegaMenu, COMPONENT_MEGAMENU}; pub use menu::{MegaMenu, COMPONENT_MEGAMENU};
} }

View file

@ -17,8 +17,8 @@ mod block;
pub use block::{Block, COMPONENT_BLOCK}; pub use block::{Block, COMPONENT_BLOCK};
mod site_branding; mod site_branding;
pub use site_branding::{SiteBranding, COMPONENT_BRANDING}; pub use site_branding::{SiteBranding, COMPONENT_BRANDING};
mod poweredby; mod powered_by;
pub use poweredby::{PoweredBy, PoweredByLogo, COMPONENT_POWEREDBY}; pub use powered_by::{PoweredBy, PoweredByLogo, COMPONENT_POWEREDBY};
pub mod form_element; pub mod form_element;
pub use form_element::{Form, FormMethod, COMPONENT_FORM}; pub use form_element::{Form, FormMethod, COMPONENT_FORM};

View file

@ -38,7 +38,7 @@ impl ComponentTrait for PoweredBy {
} }
fn id(&self) -> Option<String> { fn id(&self) -> Option<String> {
Some("poweredby".to_owned()) Some("powered-by".to_owned())
} }
fn weight(&self) -> Weight { fn weight(&self) -> Weight {

View file

@ -10,21 +10,32 @@ type SiteSlogan = OneComponent<L10n>;
type SiteLogo = OneComponent<Image>; type SiteLogo = OneComponent<Image>;
#[rustfmt::skip] #[rustfmt::skip]
#[derive(Default)]
pub struct SiteBranding { pub struct SiteBranding {
weight : Weight, weight : Weight,
renderable: Renderable, renderable: Renderable,
name : String, name : String,
slogan : SiteSlogan, slogan : SiteSlogan,
logo : SiteLogo, logo : SiteLogo,
frontpage : ContextualPath,
}
#[rustfmt::skip]
impl Default for SiteBranding {
fn default() -> Self {
SiteBranding {
weight : Weight::default(),
renderable: Renderable::default(),
name : config::SETTINGS.app.name.to_owned(),
slogan : SiteSlogan::default(),
logo : SiteLogo::default(),
frontpage : |_| "/",
}
}
} }
impl ComponentTrait for SiteBranding { impl ComponentTrait for SiteBranding {
fn new() -> Self { fn new() -> Self {
SiteBranding { SiteBranding::default()
name: config::SETTINGS.app.name.to_owned(),
..Default::default()
}
} }
fn handle(&self) -> Handle { fn handle(&self) -> Handle {
@ -58,7 +69,7 @@ impl ComponentTrait for SiteBranding {
} }
div class="site-branding-text" { div class="site-branding-text" {
div class="site-branding-name" { div class="site-branding-name" {
a href="/" title=(title) rel="home" { (self.name()) } a href=(self.frontpage()(cx)) title=(title) rel="home" { (self.name()) }
} }
@if !slogan.is_empty() { @if !slogan.is_empty() {
div class="site-branding-slogan" { div class="site-branding-slogan" {
@ -105,6 +116,12 @@ impl SiteBranding {
self self
} }
#[fn_builder]
pub fn alter_frontpage(&mut self, frontpage: ContextualPath) -> &mut Self {
self.frontpage = frontpage;
self
}
// SiteBranding GETTERS. // SiteBranding GETTERS.
pub fn name(&self) -> &String { pub fn name(&self) -> &String {
@ -118,4 +135,8 @@ impl SiteBranding {
pub fn logo(&self) -> &SiteLogo { pub fn logo(&self) -> &SiteLogo {
&self.logo &self.logo
} }
pub fn frontpage(&self) -> &ContextualPath {
&self.frontpage
}
} }

View file

@ -1,9 +1,44 @@
/* SiteBranding component */
#site-branding {
float: left;
}
.site-branding-wrapper {
position: relative;
}
.site-branding-logo {
display: none;
}
.site-branding-text {
display: inline-block;
margin: 10px 0 0 10px;
}
.site-branding-slogan {
display: none;
}
@media (min-width: 768px) {
#site-branding {
display: inline-block;
}
.site-branding-logo {
display: inline-block;
margin: 10px 0 0 10px;
}
.site-branding-text {
position: absolute;
width: max-content;
bottom: 0;
}
.site-branding-slogan {
display: block;
}
}
/* PoweredBy component */ /* PoweredBy component */
#poweredby { #powered-by {
text-align: center; text-align: center;
} }
#poweredby .pagetop-logo img, #powered-by .pagetop-logo img,
#poweredby .pagetop-logo svg { #powered-by .pagetop-logo svg {
margin-left: .275em; margin-left: .275em;
height: 1.275em; height: 1.275em;
vertical-align: middle; vertical-align: middle;

View file

@ -1,5 +1,6 @@
mod context; mod context;
pub use context::{Context, ContextOp}; pub use context::{Context, ContextOp};
pub type ContextualPath = fn(cx: &Context) -> &str;
mod definition; mod definition;
pub use definition::{component_mut, component_ref, ComponentBase, ComponentTrait}; pub use definition::{component_mut, component_ref, ComponentBase, ComponentTrait};