Añade componentes para enlaces

This commit is contained in:
Manuel Cillero 2022-05-13 16:25:11 +02:00
parent dda666e889
commit 075c546fd5
7 changed files with 338 additions and 81 deletions

View file

@ -0,0 +1,227 @@
use crate::prelude::*;
pub const ANCHOR_COMPONENT: &str = "pagetop::component::anchor";
pub enum AnchorType {
Button,
Link,
Location,
}
pub enum AnchorTarget {
Blank,
Context(String),
Default,
Parent,
Top,
}
pub struct Anchor {
renderable : fn() -> bool,
weight : isize,
anchor_type: AnchorType,
href : OptAttr,
html : Markup,
target : AnchorTarget,
id : OptIden,
classes : Classes,
template : String,
}
impl ComponentTrait for Anchor {
fn new() -> Self {
Anchor {
renderable : render_always,
weight : 0,
anchor_type: AnchorType::Link,
href : OptAttr::new(),
html : html! {},
target : AnchorTarget::Default,
id : OptIden::new(),
classes : Classes::new(),
template : "default".to_owned(),
}
}
fn handler(&self) -> &'static str {
ANCHOR_COMPONENT
}
fn is_renderable(&self) -> bool {
(self.renderable)()
}
fn weight(&self) -> isize {
self.weight
}
fn default_render(&self, _: &mut Assets) -> Markup {
let target = match &self.target() {
AnchorTarget::Blank => Some("_blank"),
AnchorTarget::Context(name) => Some(name.as_str()),
AnchorTarget::Parent => Some("_parent"),
AnchorTarget::Top => Some("_top"),
_ => None,
};
html! {
a
id=[self.id()]
class=[self.classes()]
href=[self.href()]
target=[target]
{
(*self.html())
}
}
}
fn as_ref_any(&self) -> &dyn AnyComponent {
self
}
fn as_mut_any(&mut self) -> &mut dyn AnyComponent {
self
}
}
impl Anchor {
pub fn link(href: &str, html: Markup) -> Self {
Anchor::new().with_href(href).with_html(html)
}
pub fn button(href: &str, html: Markup) -> Self {
Anchor::new().with_type(AnchorType::Button).with_href(href).with_html(html)
}
pub fn location(id: &str) -> Self {
Anchor::new().with_type(AnchorType::Location).with_id(id)
}
// Anchor BUILDER.
pub fn with_renderable(mut self, renderable: fn() -> bool) -> Self {
self.alter_renderable(renderable);
self
}
pub fn with_weight(mut self, weight: isize) -> Self {
self.alter_weight(weight);
self
}
pub fn with_type(mut self, anchor_type: AnchorType) -> Self {
self.alter_type(anchor_type);
self
}
pub fn with_href(mut self, href: &str) -> Self {
self.alter_href(href);
self
}
pub fn with_html(mut self, html: Markup) -> Self {
self.alter_html(html);
self
}
pub fn with_target(mut self, target: AnchorTarget) -> Self {
self.alter_target(target);
self
}
pub fn with_id(mut self, id: &str) -> Self {
self.alter_id(id);
self
}
pub fn with_classes(mut self, classes: &str, op: ClassesOp) -> Self {
self.alter_classes(classes, op);
self
}
pub fn using_template(mut self, template: &str) -> Self {
self.alter_template(template);
self
}
// Anchor ALTER.
pub fn alter_renderable(&mut self, renderable: fn() -> bool) -> &mut Self {
self.renderable = renderable;
self
}
pub fn alter_weight(&mut self, weight: isize) -> &mut Self {
self.weight = weight;
self
}
pub fn alter_type(&mut self, anchor_type: AnchorType) -> &mut Self {
self.anchor_type = anchor_type;
self.classes.alter(match self.anchor_type {
AnchorType::Button => "btn btn-primary",
_ => "",
}, ClassesOp::SetDefault);
self
}
pub fn alter_href(&mut self, href: &str) -> &mut Self {
self.href.with_value(href);
self
}
pub fn alter_html(&mut self, html: Markup) -> &mut Self {
self.html = html;
self
}
pub fn alter_target(&mut self, target: AnchorTarget) -> &mut Self {
self.target = target;
self
}
pub fn alter_id(&mut self, id: &str) -> &mut Self {
self.id.with_value(id);
self
}
pub fn alter_classes(&mut self, classes: &str, op: ClassesOp) -> &mut Self {
self.classes.alter(classes, op);
self
}
pub fn alter_template(&mut self, template: &str) -> &mut Self {
self.template = template.to_owned();
self
}
// Anchor GETTERS.
pub fn anchor_type(&self) -> &AnchorType {
&self.anchor_type
}
pub fn href(&self) -> &Option<String> {
self.href.option()
}
pub fn html(&self) -> &Markup {
&self.html
}
pub fn target(&self) -> &AnchorTarget {
&self.target
}
pub fn id(&self) -> &Option<String> {
self.id.option()
}
pub fn classes(&self) -> &Option<String> {
self.classes.option()
}
pub fn template(&self) -> &str {
self.template.as_str()
}
}

View file

@ -2,28 +2,22 @@ use crate::prelude::*;
pub const HEADING_COMPONENT: &str = "pagetop::component::heading";
pub enum HeadingType {
H1(String),
H2(String),
H3(String),
H4(String),
H5(String),
H6(String),
}
pub enum HeadingType { H1, H2, H3, H4, H5, H6 }
pub enum HeadingDisplay {
XxLarge,
Large,
Normal,
Medium,
Small,
XxSmall,
Normal,
}
pub struct Heading {
renderable: fn() -> bool,
weight : isize,
heading : HeadingType,
html : Markup,
display : HeadingDisplay,
id : OptIden,
classes : Classes,
@ -35,7 +29,8 @@ impl ComponentTrait for Heading {
Heading {
renderable: render_always,
weight : 0,
heading : HeadingType::H1("".to_owned()),
heading : HeadingType::H1,
html : html! {},
display : HeadingDisplay::Normal,
id : OptIden::new(),
classes : Classes::new(),
@ -57,12 +52,12 @@ impl ComponentTrait for Heading {
fn default_render(&self, _: &mut Assets) -> Markup {
html! { @match &self.heading() {
HeadingType::H1(text) => h1 id=[self.id()] class=[self.classes()] { (text) },
HeadingType::H2(text) => h2 id=[self.id()] class=[self.classes()] { (text) },
HeadingType::H3(text) => h3 id=[self.id()] class=[self.classes()] { (text) },
HeadingType::H4(text) => h4 id=[self.id()] class=[self.classes()] { (text) },
HeadingType::H5(text) => h5 id=[self.id()] class=[self.classes()] { (text) },
HeadingType::H6(text) => h6 id=[self.id()] class=[self.classes()] { (text) },
HeadingType::H1 => h1 id=[self.id()] class=[self.classes()] { (*self.html()) },
HeadingType::H2 => h2 id=[self.id()] class=[self.classes()] { (*self.html()) },
HeadingType::H3 => h3 id=[self.id()] class=[self.classes()] { (*self.html()) },
HeadingType::H4 => h4 id=[self.id()] class=[self.classes()] { (*self.html()) },
HeadingType::H5 => h5 id=[self.id()] class=[self.classes()] { (*self.html()) },
HeadingType::H6 => h6 id=[self.id()] class=[self.classes()] { (*self.html()) },
}}
}
@ -76,8 +71,28 @@ impl ComponentTrait for Heading {
}
impl Heading {
pub fn with(heading: HeadingType) -> Self {
Heading::new().with_heading(heading)
pub fn h1(html: Markup) -> Self {
Heading::new().with_heading(HeadingType::H1).with_html(html)
}
pub fn h2(html: Markup) -> Self {
Heading::new().with_heading(HeadingType::H2).with_html(html)
}
pub fn h3(html: Markup) -> Self {
Heading::new().with_heading(HeadingType::H3).with_html(html)
}
pub fn h4(html: Markup) -> Self {
Heading::new().with_heading(HeadingType::H4).with_html(html)
}
pub fn h5(html: Markup) -> Self {
Heading::new().with_heading(HeadingType::H5).with_html(html)
}
pub fn h6(html: Markup) -> Self {
Heading::new().with_heading(HeadingType::H6).with_html(html)
}
// Heading BUILDER.
@ -97,6 +112,11 @@ impl Heading {
self
}
pub fn with_html(mut self, html: Markup) -> Self {
self.alter_html(html);
self
}
pub fn with_display(mut self, display: HeadingDisplay) -> Self {
self.alter_display(display);
self
@ -134,15 +154,20 @@ impl Heading {
self
}
pub fn alter_html(&mut self, html: Markup) -> &mut Self {
self.html = html;
self
}
pub fn alter_display(&mut self, display: HeadingDisplay) -> &mut Self {
self.display = display;
self.classes.alter(match &self.display() {
HeadingDisplay::XxLarge => "display-2",
HeadingDisplay::Large => "display-3",
HeadingDisplay::Normal => "",
HeadingDisplay::Medium => "display-4",
HeadingDisplay::Small => "display-5",
HeadingDisplay::XxSmall => "display-6",
HeadingDisplay::XxLarge => "display-2",
HeadingDisplay::Large => "display-3",
HeadingDisplay::Medium => "display-4",
HeadingDisplay::Small => "display-5",
HeadingDisplay::XxSmall => "display-6",
HeadingDisplay::Normal => "",
}, ClassesOp::SetDefault);
self
}
@ -168,6 +193,10 @@ impl Heading {
&self.heading
}
pub fn html(&self) -> &Markup {
&self.html
}
pub fn display(&self) -> &HeadingDisplay {
&self.display
}

View file

@ -17,6 +17,10 @@ mod paragraph;
pub use paragraph::{
PARAGRAPH_COMPONENT, Paragraph, ParagraphDisplay
};
mod anchor;
pub use anchor::{
ANCHOR_COMPONENT, Anchor, AnchorTarget, AnchorType
};
mod block;
pub use block::{
BLOCK_COMPONENT, Block

View file

@ -5,11 +5,10 @@ pub const PARAGRAPH_COMPONENT: &str = "pagetop::component::paragraph";
pub enum ParagraphDisplay {
XxLarge,
Large,
MediumPlus,
Normal,
Medium,
Small,
XxSmall,
Normal,
}
pub struct Paragraph {
@ -123,18 +122,14 @@ impl Paragraph {
pub fn alter_display(&mut self, display: ParagraphDisplay) -> &mut Self {
self.display = display;
self.classes.alter(
match &self.display() {
ParagraphDisplay::XxLarge => "fs-1",
ParagraphDisplay::Large => "fs-2",
ParagraphDisplay::MediumPlus => "fs-3",
ParagraphDisplay::Normal => "",
ParagraphDisplay::Medium => "fs-4",
ParagraphDisplay::Small => "fs-5",
ParagraphDisplay::XxSmall => "fs-6",
},
ClassesOp::SetDefault
);
self.classes.alter(match &self.display() {
ParagraphDisplay::XxLarge => "fs-2",
ParagraphDisplay::Large => "fs-3",
ParagraphDisplay::Medium => "fs-4",
ParagraphDisplay::Small => "fs-5",
ParagraphDisplay::XxSmall => "fs-6",
ParagraphDisplay::Normal => "",
}, ClassesOp::SetDefault);
self
}

View file

@ -40,30 +40,27 @@ fn hello_world() -> Container {
Container::header()
.add(grid::Row::new()
.add_column(grid::Column::new()
.add(Chunck::with(html! {
div class="area-title" {
(t("welcome_to", &args![
"app" => SETTINGS.app.name.as_str()
]))
}
.add(Heading::h1(html! {
(l("page_title"))
}).with_display(HeadingDisplay::Large))
.add(Paragraph::with(html! {
(t("welcome_to", &args![
"app" => SETTINGS.app.name.as_str()
]))
}))
.add(Heading::with(HeadingType::H1(
l("page_title"))
).with_display(HeadingDisplay::Large))
.add(Paragraph::with(html! {
(e("welcome_intro", &args![
"app" => format!(
"<strong>{}</strong>",
&SETTINGS.app.name
)
"app" => format!("<strong>{}</strong>", &SETTINGS.app.name)
]))
}).with_display(ParagraphDisplay::Large))
}).with_display(ParagraphDisplay::Small))
.add(Paragraph::with(html! {
(e("welcome_pagetop", &args![
"pagetop" => "<a href=\"https://pagetop-rs\">PageTop</a>"
]))
}))
.add(Anchor::button("#", html! { ("Offered services") }))
.add(Anchor::button("#", html! { ("Get quote") }))
.add(Chunck::with(html! {
p {
(e("welcome_pagetop", &args![
"pagetop" => "<a href=\"https://pagetop-rs\">PageTop</a>"
]))
}
a class="btn-solid-lg" href="#services" {
"Offered services"
}

View file

@ -38,32 +38,32 @@ impl ThemeTrait for Bulmix {
match component.handler() {
HEADING_COMPONENT => {
let h = component_mut::<Heading>(component);
h.alter_classes(
concat_string!("title ", match h.display() {
HeadingDisplay::XxLarge => "is-1",
HeadingDisplay::Large => "is-2",
HeadingDisplay::Normal => "",
HeadingDisplay::Medium => "is-3",
HeadingDisplay::Small => "is-4",
HeadingDisplay::XxSmall => "is-5",
}).as_str(),
ClassesOp::SetDefault
);
h.alter_classes(concat_string!("title ", match h.display() {
HeadingDisplay::XxLarge => "is-1",
HeadingDisplay::Large => "is-2",
HeadingDisplay::Medium => "is-3",
HeadingDisplay::Small => "is-4",
HeadingDisplay::XxSmall => "is-5",
HeadingDisplay::Normal => "",
}).as_str(), ClassesOp::SetDefault);
},
PARAGRAPH_COMPONENT => {
let p = component_mut::<Paragraph>(component);
p.alter_classes(
match p.display() {
ParagraphDisplay::XxLarge => "is-size-2",
ParagraphDisplay::Large => "is-size-3",
ParagraphDisplay::MediumPlus => "is-size-4",
ParagraphDisplay::Normal => "",
ParagraphDisplay::Medium => "is-size-5",
ParagraphDisplay::Small => "is-size-6",
ParagraphDisplay::XxSmall => "is-size-7",
},
ClassesOp::SetDefault
);
p.alter_classes(match p.display() {
ParagraphDisplay::XxLarge => "is-size-2",
ParagraphDisplay::Large => "is-size-3",
ParagraphDisplay::Medium => "is-size-4",
ParagraphDisplay::Small => "is-size-5",
ParagraphDisplay::XxSmall => "is-size-6",
ParagraphDisplay::Normal => "",
}, ClassesOp::SetDefault);
},
ANCHOR_COMPONENT => {
let a = component_mut::<Anchor>(component);
a.alter_classes(match a.anchor_type() {
AnchorType::Button => "button is-primary",
_ => "",
}, ClassesOp::SetDefault);
},
grid::ROW_COMPONENT => {
let row = component_mut::<grid::Row>(component);
@ -71,7 +71,7 @@ impl ThemeTrait for Bulmix {
},
grid::COLUMN_COMPONENT => {
let col = component_mut::<grid::Column>(component);
col.alter_classes("column", ClassesOp::SetDefault);
col.alter_classes("column content", ClassesOp::SetDefault);
},
_ => {},
}

View file

@ -8,6 +8,7 @@ pub enum ClassesOp {
Replace(&'static str),
Reset,
SetDefault,
SetDefaultIfEmpty,
}
pub struct Classes {
@ -75,6 +76,10 @@ impl Classes {
ClassesOp::Reset => self.added = classes.to_owned(),
ClassesOp::SetDefault => self.default = classes.to_owned(),
ClassesOp::SetDefaultIfEmpty => if self.default.is_empty() {
self.default = classes.to_owned()
},
}
self.option = Some(concat_string!(self.default, " ", self.added).trim().to_owned());
self