🎨 Review layout composition with Flex components

This commit is contained in:
Manuel Cillero 2024-03-18 00:00:50 +01:00
parent dfbe807a61
commit 4c026e696b
19 changed files with 658 additions and 674 deletions

View file

@ -154,10 +154,10 @@ pub async fn summary(request: HttpRequest) -> ResultPage<Markup, ErrorPage> {
.with_title(L10n::n("Admin"))
.with_component_in("top-menu", side_menu)
.with_component(
flex::Container::new()
.add_item(flex::Item::with(Html::with(html! { p { "Columna 1"} })))
.add_item(flex::Item::with(top_menu))
.add_item(flex::Item::with(Html::with(html! { p { "Columna 3"} }))),
Container::new()
.add_item(Flex::with(Html::with(html! { p { "Columna 1"} })))
.add_item(Flex::with(top_menu))
.add_item(Flex::with(Html::with(html! { p { "Columna 3"} }))),
)
.render()
}

View file

@ -32,42 +32,6 @@ impl ThemeTrait for Bootsier {
]
}
fn builtin_classes(&self, builtin: ThemeBuiltInClasses) -> Option<String> {
match builtin {
ThemeBuiltInClasses::RegionContainer => Some(String::from("container")),
_ => Some(builtin.to_string()),
}
}
fn prepare_body(&self, page: &mut Page) -> Markup {
match page.template() {
"admin" => html! {
body id=[page.body_id().get()] class=[page.body_classes().get()] {
@for region in &[
"top-menu",
"side-menu",
"content"
] {
(self.prepare_region(page, region))
}
}
},
_ => html! {
body id=[page.body_id().get()] class=[page.body_classes().get()] {
(self.prepare_region(page, "header"))
(self.prepare_region(page, "nav_branding"))
(self.prepare_region(page, "nav_main"))
(self.prepare_region(page, "nav_additional"))
(self.prepare_region(page, "breadcrumb"))
(self.prepare_region(page, "content"))
(self.prepare_region(page, "sidebar_first"))
(self.prepare_region(page, "sidebar_second"))
(self.prepare_region(page, "footer"))
}
},
}
}
fn after_prepare_body(&self, page: &mut Page) {
page.alter_favicon(Some(Favicon::new().with_icon("/base/favicon.ico")))
.alter_assets(AssetsOp::AddStyleSheet(
@ -148,6 +112,29 @@ impl ThemeTrait for Bootsier {
fn render_component(&self, component: &dyn ComponentTrait, cx: &mut Context) -> Option<Markup> {
match component.type_id() {
t if t == TypeId::of::<Layout>() => 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),
),
t if t == TypeId::of::<Error404>() => Some(html! {
div class="jumbotron" {
div class="media" {

View file

@ -15,16 +15,17 @@ impl PackageTrait for Bulmix {
}
impl ThemeTrait for Bulmix {
#[rustfmt::skip]
fn builtin_classes(&self, builtin: ThemeBuiltInClasses) -> Option<String> {
match builtin {
ThemeBuiltInClasses::BodyWrapper => Some(String::from("container")),
ThemeBuiltInClasses::ContentWrapper => Some(String::from("container")),
ThemeBuiltInClasses::RegionContainer => Some(String::from("container")),
_ => Some(builtin.to_string()),
/*
#[rustfmt::skip]
fn builtin_classes(&self, builtin: ThemeBuiltInClasses) -> Option<String> {
match builtin {
ThemeBuiltInClasses::BodyWrapper => Some(String::from("container")),
ThemeBuiltInClasses::FlexWrapper => Some(String::from("container")),
ThemeBuiltInClasses::RegionContainer => Some(String::from("container")),
_ => Some(builtin.to_string()),
}
}
}
*/
fn after_prepare_body(&self, page: &mut Page) {
page.alter_favicon(Some(Favicon::new().with_icon("/base/favicon.ico")))
.alter_assets(AssetsOp::AddStyleSheet(

View file

@ -33,9 +33,9 @@ async fn login(request: HttpRequest) -> ResultPage<Markup, ErrorPage> {
Page::new(request)
.with_title(L10n::n("Identificación del usuario"))
.with_component(
flex::Container::new()
Container::new()
.with_id("welcome")
.add_item(flex::Item::with(form_login())),
.add_item(Flex::with(form_login())),
)
.render()
}

View file

@ -157,28 +157,14 @@ impl ToString for FontSize {
// *************************************************************************************************
mod layout;
pub use layout::Layout;
mod basic;
pub use basic::*;
mod region;
pub use region::Region;
mod composition;
pub use composition::*;
mod html;
pub use html::Html;
mod fluent;
pub use fluent::Fluent;
mod error403;
pub use error403::Error403;
mod error404;
pub use error404::Error404;
pub mod flex;
mod icon;
pub use icon::Icon;
mod error;
pub use error::*;
mod heading;
pub use heading::{Heading, HeadingSize, HeadingType};
@ -186,6 +172,9 @@ pub use heading::{Heading, HeadingSize, HeadingType};
mod paragraph;
pub use paragraph::Paragraph;
mod icon;
pub use icon::Icon;
mod button;
pub use button::{Button, ButtonTarget};

View file

@ -0,0 +1,5 @@
mod html;
pub use html::Html;
mod fluent;
pub use fluent::Fluent;

View file

@ -0,0 +1,325 @@
mod container;
pub use container::Container;
mod flex;
pub use flex::Flex;
mod layout;
pub use layout::Layout;
mod region;
pub use region::Region;
use crate::prelude::*;
// *************************************************************************************************
#[derive(AutoDefault)]
pub enum FlexDirection {
#[default]
Default,
Row(BreakPoint),
RowReverse(BreakPoint),
Column(BreakPoint),
ColumnReverse(BreakPoint),
}
#[rustfmt::skip]
impl ToString for FlexDirection {
fn to_string(&self) -> String {
match self {
FlexDirection::Default => concat_string!(
"flex__row ", BreakPoint::default().to_string()
),
FlexDirection::Row(breakpoint) => concat_string!(
"flex__row ", breakpoint.to_string()
),
FlexDirection::RowReverse(breakpoint) => concat_string!(
"flex__row flex__reverse ", breakpoint.to_string()
),
FlexDirection::Column(breakpoint) => concat_string!(
"flex__col ", breakpoint.to_string()
),
FlexDirection::ColumnReverse(breakpoint) => concat_string!(
"flex__col flex__reverse ", breakpoint.to_string()
),
}
}
}
// *************************************************************************************************
#[derive(AutoDefault)]
pub enum FlexWrap {
#[default]
Default,
NoWrap,
Wrap(ContentAlign),
WrapReverse(ContentAlign),
}
#[rustfmt::skip]
impl ToString for FlexWrap {
fn to_string(&self) -> String {
match self {
FlexWrap::Default => "".to_owned(),
FlexWrap::NoWrap => "flex__nowrap".to_owned(),
FlexWrap::Wrap(a) => concat_string!("flex__wrap ", a.to_string()),
FlexWrap::WrapReverse(a) => concat_string!("flex__wrap-reverse ", a.to_string()),
}
}
}
// *************************************************************************************************
#[derive(AutoDefault)]
pub enum ContentAlign {
#[default]
Default,
Start,
End,
Center,
Stretch,
SpaceBetween,
SpaceAround,
}
#[rustfmt::skip]
impl ToString for ContentAlign {
fn to_string(&self) -> String {
String::from(match self {
ContentAlign::Default => "",
ContentAlign::Start => "flex__align-start",
ContentAlign::End => "flex__align-end",
ContentAlign::Center => "flex__align-center",
ContentAlign::Stretch => "flex__align-stretch",
ContentAlign::SpaceBetween => "flex__align-space-between",
ContentAlign::SpaceAround => "flex__align-space-around",
})
}
}
// *************************************************************************************************
#[derive(AutoDefault)]
pub enum FlexJustify {
#[default]
Default,
Start,
End,
Center,
SpaceBetween,
SpaceAround,
SpaceEvenly,
}
#[rustfmt::skip]
impl ToString for FlexJustify {
fn to_string(&self) -> String {
String::from(match self {
FlexJustify::Default => "",
FlexJustify::Start => "flex__justify-start",
FlexJustify::End => "flex__justify-end",
FlexJustify::Center => "flex__justify-center",
FlexJustify::SpaceBetween => "flex__justify-space-between",
FlexJustify::SpaceAround => "flex__justify-space-around",
FlexJustify::SpaceEvenly => "flex__justify-space-evenly",
})
}
}
// *************************************************************************************************
#[derive(AutoDefault)]
pub enum FlexAlign {
#[default]
Default,
Start,
End,
Center,
Stretch,
Baseline,
}
#[rustfmt::skip]
impl ToString for FlexAlign {
fn to_string(&self) -> String {
String::from(match self {
FlexAlign::Default => "",
FlexAlign::Start => "flex__start",
FlexAlign::End => "flex__end",
FlexAlign::Center => "flex__center",
FlexAlign::Stretch => "flex__stretch",
FlexAlign::Baseline => "flex__baseline",
})
}
}
// *************************************************************************************************
#[derive(AutoDefault)]
pub enum FlexGap {
#[default]
Default,
Row(unit::Value),
Column(unit::Value),
Distinct(unit::Value, unit::Value),
Both(unit::Value),
}
#[rustfmt::skip]
impl ToString for FlexGap {
fn to_string(&self) -> String {
match self {
FlexGap::Default => "".to_owned(),
FlexGap::Row(r) => concat_string!("row-gap: ", r.to_string(), ";"),
FlexGap::Column(c) => concat_string!("column-gap: ", c.to_string(), ";"),
FlexGap::Distinct(r, c) => concat_string!("gap: ", r.to_string(), " ", c.to_string(), ";"),
FlexGap::Both(v) => concat_string!("gap: ", v.to_string(), ";"),
}
}
}
// *************************************************************************************************
#[derive(AutoDefault)]
pub enum FlexGrow {
#[default]
Default,
Is1,
Is2,
Is3,
Is4,
Is5,
Is6,
Is7,
Is8,
Is9,
}
impl ToString for FlexGrow {
fn to_string(&self) -> String {
String::from(match self {
FlexGrow::Default => "",
FlexGrow::Is1 => "flex__grow-1",
FlexGrow::Is2 => "flex__grow-2",
FlexGrow::Is3 => "flex__grow-3",
FlexGrow::Is4 => "flex__grow-4",
FlexGrow::Is5 => "flex__grow-5",
FlexGrow::Is6 => "flex__grow-6",
FlexGrow::Is7 => "flex__grow-7",
FlexGrow::Is8 => "flex__grow-8",
FlexGrow::Is9 => "flex__grow-9",
})
}
}
// *************************************************************************************************
#[derive(AutoDefault)]
pub enum FlexShrink {
#[default]
Default,
Is1,
Is2,
Is3,
Is4,
Is5,
Is6,
Is7,
Is8,
Is9,
}
impl ToString for FlexShrink {
fn to_string(&self) -> String {
String::from(match self {
FlexShrink::Default => "",
FlexShrink::Is1 => "flex__shrink-1",
FlexShrink::Is2 => "flex__shrink-2",
FlexShrink::Is3 => "flex__shrink-3",
FlexShrink::Is4 => "flex__shrink-4",
FlexShrink::Is5 => "flex__shrink-5",
FlexShrink::Is6 => "flex__shrink-6",
FlexShrink::Is7 => "flex__shrink-7",
FlexShrink::Is8 => "flex__shrink-8",
FlexShrink::Is9 => "flex__shrink-9",
})
}
}
// *************************************************************************************************
#[derive(AutoDefault)]
pub enum FlexSize {
#[default]
Default,
Percent10,
Percent20,
Percent25,
Percent33,
Percent40,
Percent50,
Percent60,
Percent66,
Percent75,
Percent80,
Percent90,
}
impl ToString for FlexSize {
fn to_string(&self) -> String {
String::from(match self {
FlexSize::Default => "",
FlexSize::Percent10 => "flex__size-10",
FlexSize::Percent20 => "flex__size-20",
FlexSize::Percent25 => "flex__size-25",
FlexSize::Percent33 => "flex__size-33",
FlexSize::Percent40 => "flex__size-40",
FlexSize::Percent50 => "flex__size-50",
FlexSize::Percent60 => "flex__size-60",
FlexSize::Percent66 => "flex__size-66",
FlexSize::Percent75 => "flex__size-75",
FlexSize::Percent80 => "flex__size-80",
FlexSize::Percent90 => "flex__size-90",
})
}
}
// *************************************************************************************************
#[derive(AutoDefault)]
pub enum FlexOffset {
#[default]
Default,
Offset10,
Offset20,
Offset25,
Offset33,
Offset40,
Offset50,
Offset60,
Offset66,
Offset75,
Offset80,
Offset90,
}
impl ToString for FlexOffset {
fn to_string(&self) -> String {
String::from(match self {
FlexOffset::Default => "",
FlexOffset::Offset10 => "flex__offset-10",
FlexOffset::Offset20 => "flex__offset-20",
FlexOffset::Offset25 => "flex__offset-25",
FlexOffset::Offset33 => "flex__offset-33",
FlexOffset::Offset40 => "flex__offset-40",
FlexOffset::Offset50 => "flex__offset-50",
FlexOffset::Offset60 => "flex__offset-60",
FlexOffset::Offset66 => "flex__offset-66",
FlexOffset::Offset75 => "flex__offset-75",
FlexOffset::Offset80 => "flex__offset-80",
FlexOffset::Offset90 => "flex__offset-90",
})
}
}

View file

@ -14,17 +14,17 @@ pub enum ContainerType {
#[rustfmt::skip]
#[derive(AutoDefault, ComponentClasses)]
pub struct Container {
id : OptionId,
weight : Weight,
renderable : Renderable,
classes : OptionClasses,
container_type : ContainerType,
direction : flex::Direction,
wrap_align : flex::WrapAlign,
content_justify: flex::ContentJustify,
items_align : flex::ItemAlign,
gap : flex::Gap,
items : MixedComponents,
id : OptionId,
weight : Weight,
renderable : Renderable,
classes : OptionClasses,
container_type: ContainerType,
direction : FlexDirection,
flex_wrap : FlexWrap,
flex_justify : FlexJustify,
flex_align : FlexAlign,
flex_gap : FlexGap,
items : MixedComponents,
}
impl ComponentTrait for Container {
@ -50,9 +50,9 @@ impl ComponentTrait for Container {
[
String::from("flex__container"),
self.direction().to_string(),
self.wrap_align().to_string(),
self.content_justify().to_string(),
self.items_align().to_string(),
self.wrap().to_string(),
self.justify().to_string(),
self.align().to_string(),
]
.join(" "),
);
@ -67,7 +67,7 @@ impl ComponentTrait for Container {
}
let gap = match self.gap() {
flex::Gap::Default => None,
FlexGap::Default => None,
_ => Some(self.gap().to_string()),
};
match self.container_type() {
@ -162,43 +162,43 @@ impl Container {
}
#[fn_builder]
pub fn alter_direction(&mut self, direction: flex::Direction) -> &mut Self {
pub fn alter_direction(&mut self, direction: FlexDirection) -> &mut Self {
self.direction = direction;
self
}
#[fn_builder]
pub fn alter_wrap_align(&mut self, wrap: flex::WrapAlign) -> &mut Self {
self.wrap_align = wrap;
pub fn alter_wrap(&mut self, wrap: FlexWrap) -> &mut Self {
self.flex_wrap = wrap;
self
}
#[fn_builder]
pub fn alter_content_justify(&mut self, justify: flex::ContentJustify) -> &mut Self {
self.content_justify = justify;
pub fn alter_justify(&mut self, justify: FlexJustify) -> &mut Self {
self.flex_justify = justify;
self
}
#[fn_builder]
pub fn alter_items_align(&mut self, align: flex::ItemAlign) -> &mut Self {
self.items_align = align;
pub fn alter_align(&mut self, align: FlexAlign) -> &mut Self {
self.flex_align = align;
self
}
#[fn_builder]
pub fn alter_gap(&mut self, gap: flex::Gap) -> &mut Self {
self.gap = gap;
pub fn alter_gap(&mut self, gap: FlexGap) -> &mut Self {
self.flex_gap = gap;
self
}
#[fn_builder]
pub fn alter_items(&mut self, op: TypedOp<flex::Item>) -> &mut Self {
pub fn alter_items(&mut self, op: TypedOp<Flex>) -> &mut Self {
self.items.alter_typed(op);
self
}
#[rustfmt::skip]
pub fn add_item(mut self, item: flex::Item) -> Self {
pub fn add_item(mut self, item: Flex) -> Self {
self.items.alter_value(AnyOp::Add(AnyComponent::with(item)));
self
}
@ -209,24 +209,24 @@ impl Container {
&self.container_type
}
pub fn direction(&self) -> &flex::Direction {
pub fn direction(&self) -> &FlexDirection {
&self.direction
}
pub fn wrap_align(&self) -> &flex::WrapAlign {
&self.wrap_align
pub fn wrap(&self) -> &FlexWrap {
&self.flex_wrap
}
pub fn content_justify(&self) -> &flex::ContentJustify {
&self.content_justify
pub fn justify(&self) -> &FlexJustify {
&self.flex_justify
}
pub fn items_align(&self) -> &flex::ItemAlign {
&self.items_align
pub fn align(&self) -> &FlexAlign {
&self.flex_align
}
pub fn gap(&self) -> &flex::Gap {
&self.gap
pub fn gap(&self) -> &FlexGap {
&self.flex_gap
}
pub fn items(&self) -> &MixedComponents {

View file

@ -2,22 +2,22 @@ use crate::prelude::*;
#[rustfmt::skip]
#[derive(AutoDefault, ComponentClasses)]
pub struct Item {
pub struct Flex {
id : OptionId,
weight : Weight,
renderable : Renderable,
classes : OptionClasses,
item_grow : flex::ItemGrow,
item_shrink : flex::ItemShrink,
item_size : flex::ItemSize,
item_offset : flex::ItemOffset,
item_align : flex::ItemAlign,
flex_grow : FlexGrow,
flex_shrink : FlexShrink,
flex_size : FlexSize,
flex_offset : FlexOffset,
flex_align : FlexAlign,
mixed : MixedComponents,
}
impl ComponentTrait for Item {
impl ComponentTrait for Flex {
fn new() -> Self {
Item::default()
Flex::default()
}
fn id(&self) -> Option<String> {
@ -67,9 +67,9 @@ impl ComponentTrait for Item {
}
}
impl Item {
impl Flex {
pub fn with(component: impl ComponentTrait) -> Self {
Item::default().add_component(component)
Flex::default().add_component(component)
}
// Item BUILDER.
@ -93,34 +93,34 @@ impl Item {
}
#[fn_builder]
pub fn alter_grow(&mut self, grow: flex::ItemGrow) -> &mut Self {
self.item_grow = grow;
pub fn alter_grow(&mut self, grow: FlexGrow) -> &mut Self {
self.flex_grow = grow;
self
}
#[fn_builder]
pub fn alter_shrink(&mut self, shrink: flex::ItemShrink) -> &mut Self {
self.item_shrink = shrink;
pub fn alter_shrink(&mut self, shrink: FlexShrink) -> &mut Self {
self.flex_shrink = shrink;
self
}
#[fn_builder]
// Ensures the item occupies the exact specified width, neither growing nor shrinking,
// regardless of the available space in the container or the size of other items.
pub fn alter_size(&mut self, size: flex::ItemSize) -> &mut Self {
self.item_size = size;
pub fn alter_size(&mut self, size: FlexSize) -> &mut Self {
self.flex_size = size;
self
}
#[fn_builder]
pub fn alter_offset(&mut self, offset: flex::ItemOffset) -> &mut Self {
self.item_offset = offset;
pub fn alter_offset(&mut self, offset: FlexOffset) -> &mut Self {
self.flex_offset = offset;
self
}
#[fn_builder]
pub fn alter_align(&mut self, align: flex::ItemAlign) -> &mut Self {
self.item_align = align;
pub fn alter_align(&mut self, align: FlexAlign) -> &mut Self {
self.flex_align = align;
self
}
@ -138,24 +138,24 @@ impl Item {
// Item GETTERS.
pub fn grow(&self) -> &flex::ItemGrow {
&self.item_grow
pub fn grow(&self) -> &FlexGrow {
&self.flex_grow
}
pub fn shrink(&self) -> &flex::ItemShrink {
&self.item_shrink
pub fn shrink(&self) -> &FlexShrink {
&self.flex_shrink
}
pub fn size(&self) -> &flex::ItemSize {
&self.item_size
pub fn size(&self) -> &FlexSize {
&self.flex_size
}
pub fn offset(&self) -> &flex::ItemOffset {
&self.item_offset
pub fn offset(&self) -> &FlexOffset {
&self.flex_offset
}
pub fn align(&self) -> &flex::ItemAlign {
&self.item_align
pub fn align(&self) -> &FlexAlign {
&self.flex_align
}
pub fn components(&self) -> &MixedComponents {

View file

@ -19,35 +19,35 @@ impl ComponentTrait for Layout {
impl Layout {
fn default_layout(cx: &mut Context) -> Markup {
flex::Container::new()
Container::new()
.with_id("body__wrapper")
.with_direction(flex::Direction::Column(BreakPoint::None))
.with_items_align(flex::ItemAlign::Center)
.add_item(flex::Item::with(Region::named("header")).with_id("header"))
.add_item(flex::Item::with(Region::named("pagetop")).with_id("pagetop"))
.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::Item::with(
flex::Container::new()
.with_direction(flex::Direction::Row(BreakPoint::None))
Flex::with(
Container::new()
.with_direction(FlexDirection::Row(BreakPoint::None))
.add_item(
flex::Item::with(Region::named("sidebar_left"))
Flex::with(Region::named("sidebar_left"))
.with_id("sidebar_left")
.with_grow(flex::ItemGrow::Is1),
.with_grow(FlexGrow::Is1),
)
.add_item(
flex::Item::with(Region::named("content"))
Flex::with(Region::named("content"))
.with_id("content")
.with_grow(flex::ItemGrow::Is3),
.with_grow(FlexGrow::Is3),
)
.add_item(
flex::Item::with(Region::named("sidebar_right"))
Flex::with(Region::named("sidebar_right"))
.with_id("sidebar_right")
.with_grow(flex::ItemGrow::Is1),
.with_grow(FlexGrow::Is1),
),
)
.with_id("content__wrapper"),
.with_id("flex__wrapper"),
)
.add_item(flex::Item::with(Region::named("footer")).with_id("footer"))
.add_item(Flex::with(Region::named("footer")).with_id("footer"))
.render(cx)
}

View file

@ -0,0 +1,5 @@
mod error403;
pub use error403::Error403;
mod error404;
pub use error404::Error404;

View file

@ -1,318 +0,0 @@
mod container;
pub use container::Container;
mod item;
pub use item::Item;
use crate::prelude::*;
// *************************************************************************************************
#[derive(AutoDefault)]
pub enum Direction {
#[default]
Default,
Row(BreakPoint),
RowReverse(BreakPoint),
Column(BreakPoint),
ColumnReverse(BreakPoint),
}
#[rustfmt::skip]
impl ToString for Direction {
fn to_string(&self) -> String {
match self {
Direction::Default => concat_string!(
"flex__row ", BreakPoint::default().to_string()
),
Direction::Row(breakpoint) => concat_string!(
"flex__row ", breakpoint.to_string()
),
Direction::RowReverse(breakpoint) => concat_string!(
"flex__row flex__reverse ", breakpoint.to_string()
),
Direction::Column(breakpoint) => concat_string!(
"flex__col ", breakpoint.to_string()
),
Direction::ColumnReverse(breakpoint) => concat_string!(
"flex__col flex__reverse ", breakpoint.to_string()
),
}
}
}
// *************************************************************************************************
#[derive(AutoDefault)]
pub enum WrapAlign {
#[default]
Default,
NoWrap,
Wrap(ContentAlign),
WrapReverse(ContentAlign),
}
#[rustfmt::skip]
impl ToString for WrapAlign {
fn to_string(&self) -> String {
match self {
WrapAlign::Default => "".to_owned(),
WrapAlign::NoWrap => "flex-nowrap".to_owned(),
WrapAlign::Wrap(a) => concat_string!("flex__wrap ", a.to_string()),
WrapAlign::WrapReverse(a) => concat_string!("flex__wrap-reverse ", a.to_string()),
}
}
}
// *************************************************************************************************
#[derive(AutoDefault)]
pub enum ContentAlign {
#[default]
Default,
Start,
End,
Center,
Stretch,
SpaceBetween,
SpaceAround,
}
#[rustfmt::skip]
impl ToString for ContentAlign {
fn to_string(&self) -> String {
String::from(match self {
ContentAlign::Default => "",
ContentAlign::Start => "flex__align-start",
ContentAlign::End => "flex__align-end",
ContentAlign::Center => "flex__align-center",
ContentAlign::Stretch => "flex__align-stretch",
ContentAlign::SpaceBetween => "flex__align-space-between",
ContentAlign::SpaceAround => "flex__align-space-around",
})
}
}
// *************************************************************************************************
#[derive(AutoDefault)]
pub enum ContentJustify {
#[default]
Default,
Start,
End,
Center,
SpaceBetween,
SpaceAround,
SpaceEvenly,
}
#[rustfmt::skip]
impl ToString for ContentJustify {
fn to_string(&self) -> String {
String::from(match self {
ContentJustify::Default => "",
ContentJustify::Start => "flex__justify-start",
ContentJustify::End => "flex__justify-end",
ContentJustify::Center => "flex__justify-center",
ContentJustify::SpaceBetween => "flex__justify-space-between",
ContentJustify::SpaceAround => "flex__justify-space-around",
ContentJustify::SpaceEvenly => "flex__justify-space-evenly",
})
}
}
// *************************************************************************************************
#[derive(AutoDefault)]
pub enum ItemAlign {
#[default]
Default,
Start,
End,
Center,
Stretch,
Baseline,
}
#[rustfmt::skip]
impl ToString for ItemAlign {
fn to_string(&self) -> String {
String::from(match self {
ItemAlign::Default => "",
ItemAlign::Start => "flex__item-start",
ItemAlign::End => "flex__item-end",
ItemAlign::Center => "flex__item-center",
ItemAlign::Stretch => "flex__item-stretch",
ItemAlign::Baseline => "flex__item-baseline",
})
}
}
// *************************************************************************************************
#[derive(AutoDefault)]
pub enum Gap {
#[default]
Default,
Row(unit::Value),
Column(unit::Value),
Distinct(unit::Value, unit::Value),
Both(unit::Value),
}
#[rustfmt::skip]
impl ToString for Gap {
fn to_string(&self) -> String {
match self {
Gap::Default => "".to_owned(),
Gap::Row(r) => concat_string!("row-gap: ", r.to_string(), ";"),
Gap::Column(c) => concat_string!("column-gap: ", c.to_string(), ";"),
Gap::Distinct(r, c) => concat_string!("gap: ", r.to_string(), " ", c.to_string(), ";"),
Gap::Both(v) => concat_string!("gap: ", v.to_string(), ";"),
}
}
}
// *************************************************************************************************
#[derive(AutoDefault)]
pub enum ItemGrow {
#[default]
Default,
Is1,
Is2,
Is3,
Is4,
Is5,
Is6,
Is7,
Is8,
Is9,
}
impl ToString for ItemGrow {
fn to_string(&self) -> String {
String::from(match self {
ItemGrow::Default => "",
ItemGrow::Is1 => "flex__item-grow-1",
ItemGrow::Is2 => "flex__item-grow-2",
ItemGrow::Is3 => "flex__item-grow-3",
ItemGrow::Is4 => "flex__item-grow-4",
ItemGrow::Is5 => "flex__item-grow-5",
ItemGrow::Is6 => "flex__item-grow-6",
ItemGrow::Is7 => "flex__item-grow-7",
ItemGrow::Is8 => "flex__item-grow-8",
ItemGrow::Is9 => "flex__item-grow-9",
})
}
}
// *************************************************************************************************
#[derive(AutoDefault)]
pub enum ItemShrink {
#[default]
Default,
Is1,
Is2,
Is3,
Is4,
Is5,
Is6,
Is7,
Is8,
Is9,
}
impl ToString for ItemShrink {
fn to_string(&self) -> String {
String::from(match self {
ItemShrink::Default => "",
ItemShrink::Is1 => "flex__item-shrink-1",
ItemShrink::Is2 => "flex__item-shrink-2",
ItemShrink::Is3 => "flex__item-shrink-3",
ItemShrink::Is4 => "flex__item-shrink-4",
ItemShrink::Is5 => "flex__item-shrink-5",
ItemShrink::Is6 => "flex__item-shrink-6",
ItemShrink::Is7 => "flex__item-shrink-7",
ItemShrink::Is8 => "flex__item-shrink-8",
ItemShrink::Is9 => "flex__item-shrink-9",
})
}
}
// *************************************************************************************************
#[derive(AutoDefault)]
pub enum ItemSize {
#[default]
Default,
Percent10,
Percent20,
Percent25,
Percent33,
Percent40,
Percent50,
Percent60,
Percent66,
Percent75,
Percent80,
Percent90,
}
impl ToString for ItemSize {
fn to_string(&self) -> String {
String::from(match self {
ItemSize::Default => "",
ItemSize::Percent10 => "flex__item-size-10",
ItemSize::Percent20 => "flex__item-size-20",
ItemSize::Percent25 => "flex__item-size-25",
ItemSize::Percent33 => "flex__item-size-33",
ItemSize::Percent40 => "flex__item-size-40",
ItemSize::Percent50 => "flex__item-size-50",
ItemSize::Percent60 => "flex__item-size-60",
ItemSize::Percent66 => "flex__item-size-66",
ItemSize::Percent75 => "flex__item-size-75",
ItemSize::Percent80 => "flex__item-size-80",
ItemSize::Percent90 => "flex__item-size-90",
})
}
}
// *************************************************************************************************
#[derive(AutoDefault)]
pub enum ItemOffset {
#[default]
Default,
Offset10,
Offset20,
Offset25,
Offset33,
Offset40,
Offset50,
Offset60,
Offset66,
Offset75,
Offset80,
Offset90,
}
impl ToString for ItemOffset {
fn to_string(&self) -> String {
String::from(match self {
ItemOffset::Default => "",
ItemOffset::Offset10 => "flex__item-offset-10",
ItemOffset::Offset20 => "flex__item-offset-20",
ItemOffset::Offset25 => "flex__item-offset-25",
ItemOffset::Offset33 => "flex__item-offset-33",
ItemOffset::Offset40 => "flex__item-offset-40",
ItemOffset::Offset50 => "flex__item-offset-50",
ItemOffset::Offset60 => "flex__item-offset-60",
ItemOffset::Offset66 => "flex__item-offset-66",
ItemOffset::Offset75 => "flex__item-offset-75",
ItemOffset::Offset80 => "flex__item-offset-80",
ItemOffset::Offset90 => "flex__item-offset-90",
})
}
}

View file

@ -47,78 +47,74 @@ fn home(request: HttpRequest, lang: &'static LanguageIdentifier) -> ResultPage<M
.render()
}
fn hello_world() -> flex::Container {
flex::Container::header()
fn hello_world() -> Container {
Container::header()
.with_classes(ClassesOp::Add, "hello-world")
.with_content_justify(flex::ContentJustify::Center)
.with_justify(FlexJustify::Center)
.add_item(
flex::Item::new()
.with_size(flex::ItemSize::Percent90)
.add_component(
flex::Container::new()
.with_direction(flex::Direction::Column(BreakPoint::MD))
.add_item(
flex::Item::new()
.with_classes(ClassesOp::Add, "hello-col-text")
.with_size(flex::ItemSize::Percent40)
.add_component(
Heading::h1(L10n::l("welcome_title"))
.with_size(HeadingSize::Medium),
)
.add_component(
Paragraph::fluent(L10n::l("welcome_intro").with_arg(
"app",
format!(
"<span class=\"app-name\">{}</span>",
&config::SETTINGS.app.name,
),
))
.with_font_size(FontSize::Medium),
)
.add_component(Paragraph::fluent(
L10n::l("welcome_powered").with_arg(
"pagetop",
format!(
"<a href=\"{}\" target=\"_blank\">{}</a>",
"https://pagetop.cillero.es", "PageTop",
),
Flex::new().with_size(FlexSize::Percent90).add_component(
Container::new()
.with_direction(FlexDirection::Column(BreakPoint::MD))
.add_item(
Flex::new()
.with_classes(ClassesOp::Add, "hello-col-text")
.with_size(FlexSize::Percent40)
.add_component(
Heading::h1(L10n::l("welcome_title"))
.with_size(HeadingSize::Medium),
)
.add_component(
Paragraph::fluent(L10n::l("welcome_intro").with_arg(
"app",
format!(
"<span class=\"app-name\">{}</span>",
&config::SETTINGS.app.name,
),
))
.add_component(
Button::anchor(
"https://github.com/manuelcillero/pagetop",
L10n::l("welcome_code"),
)
.with_target(ButtonTarget::Blank)
.with_left_icon(Some(Icon::with("git")))
.with_classes(ClassesOp::Add, "code-link")
.with_font_size(FontSize::Medium),
)
.add_component(
Button::anchor("#welcome-page", L10n::l("welcome"))
.with_style(StyleBase::Link)
.with_left_icon(Some(Icon::with("arrow-down-circle-fill")))
.with_classes(ClassesOp::Add, "welcome-link")
.with_font_size(FontSize::Medium),
.with_font_size(FontSize::Medium),
)
.add_component(Paragraph::fluent(L10n::l("welcome_powered").with_arg(
"pagetop",
format!(
"<a href=\"{}\" target=\"_blank\">{}</a>",
"https://pagetop.cillero.es", "PageTop",
),
)
.add_item(
flex::Item::with(Image::with("/base/images/header.svg"))
.with_classes(ClassesOp::Add, "hello-col-image")
.with_size(flex::ItemSize::Percent60),
),
),
)))
.add_component(
Button::anchor(
"https://github.com/manuelcillero/pagetop",
L10n::l("welcome_code"),
)
.with_target(ButtonTarget::Blank)
.with_left_icon(Some(Icon::with("git")))
.with_classes(ClassesOp::Add, "code-link")
.with_font_size(FontSize::Medium),
)
.add_component(
Button::anchor("#welcome-page", L10n::l("welcome"))
.with_style(StyleBase::Link)
.with_left_icon(Some(Icon::with("arrow-down-circle-fill")))
.with_classes(ClassesOp::Add, "welcome-link")
.with_font_size(FontSize::Medium),
),
)
.add_item(
Flex::with(Image::with("/base/images/header.svg"))
.with_classes(ClassesOp::Add, "hello-col-image")
.with_size(FlexSize::Percent60),
),
),
)
}
fn welcome() -> flex::Container {
flex::Container::section()
fn welcome() -> Container {
Container::section()
.with_id("welcome-page")
.with_classes(ClassesOp::Add, "welcome")
.with_content_justify(flex::ContentJustify::Center)
.with_justify(FlexJustify::Center)
.add_item(
flex::Item::new()
.with_size(flex::ItemSize::Percent80)
Flex::new()
.with_size(FlexSize::Percent80)
.add_component(Heading::h2(L10n::l("welcome_page")))
.add_component(
Heading::h3(L10n::l("welcome_subtitle").with_arg(
@ -137,104 +133,98 @@ fn welcome() -> flex::Container {
)
}
fn about_pagetop() -> flex::Container {
flex::Container::new()
fn about_pagetop() -> Container {
Container::new()
.with_classes(ClassesOp::Add, "pagetop")
.with_content_justify(flex::ContentJustify::Center)
.with_justify(FlexJustify::Center)
.add_item(
flex::Item::new()
.with_size(flex::ItemSize::Percent90)
.add_component(
flex::Container::new()
.with_direction(flex::Direction::Column(BreakPoint::SM))
.add_item(
flex::Item::with(Image::with("/base/images/about.svg"))
.with_classes(ClassesOp::Add, "pagetop-col-image")
.with_size(flex::ItemSize::Percent40),
)
.add_item(
flex::Item::new()
.with_classes(ClassesOp::Add, "pagetop-col-text")
.add_component(Heading::h2(L10n::l("welcome_pagetop_title")))
.add_component(
Paragraph::fluent(L10n::l("welcome_pagetop_text1"))
.with_font_size(FontSize::Medium),
)
.add_component(Paragraph::fluent(L10n::l("welcome_pagetop_text2")))
.add_component(Paragraph::fluent(L10n::l("welcome_pagetop_text3"))),
),
),
)
}
fn promo_pagetop() -> flex::Container {
flex::Container::new()
.with_classes(ClassesOp::Add, "promo")
.with_content_justify(flex::ContentJustify::Center)
.add_item(
flex::Item::new()
.with_size(flex::ItemSize::Percent75)
.add_component(
flex::Container::new()
.with_direction(flex::Direction::Column(BreakPoint::MD))
.add_item(
flex::Item::new()
.with_classes(ClassesOp::Add, "promo-col-text")
.with_size(flex::ItemSize::Percent50)
.add_component(Heading::h2(L10n::l("welcome_promo_title")))
.add_component(
Paragraph::fluent(L10n::l("welcome_promo_text1").with_arg(
"pagetop",
format!(
"<a href=\"{}\" target=\"_blank\">{}</a>",
"https://crates.io/crates/pagetop", "PageTop",
),
))
Flex::new().with_size(FlexSize::Percent90).add_component(
Container::new()
.with_direction(FlexDirection::Column(BreakPoint::SM))
.add_item(
Flex::with(Image::with("/base/images/about.svg"))
.with_classes(ClassesOp::Add, "pagetop-col-image")
.with_size(FlexSize::Percent40),
)
.add_item(
Flex::new()
.with_classes(ClassesOp::Add, "pagetop-col-text")
.add_component(Heading::h2(L10n::l("welcome_pagetop_title")))
.add_component(
Paragraph::fluent(L10n::l("welcome_pagetop_text1"))
.with_font_size(FontSize::Medium),
),
)
.add_item(
flex::Item::with(Image::with("/base/images/pagetop.png"))
.with_classes(ClassesOp::Add, "promo-col-image")
.with_size(flex::ItemSize::Percent50),
),
),
)
.add_component(Paragraph::fluent(L10n::l("welcome_pagetop_text2")))
.add_component(Paragraph::fluent(L10n::l("welcome_pagetop_text3"))),
),
),
)
}
fn reporting_issues() -> flex::Container {
flex::Container::new()
.with_classes(ClassesOp::Add, "issues")
.with_content_justify(flex::ContentJustify::Center)
fn promo_pagetop() -> Container {
Container::new()
.with_classes(ClassesOp::Add, "promo")
.with_justify(FlexJustify::Center)
.add_item(
flex::Item::new()
.with_size(flex::ItemSize::Percent90)
.add_component(
flex::Container::new()
.with_direction(flex::Direction::Column(BreakPoint::MD))
.add_item(
flex::Item::with(Image::with("/base/images/issues.jpg"))
.with_classes(ClassesOp::Add, "issues-col-image"),
)
.add_item(
flex::Item::new()
.with_classes(ClassesOp::Add, "issues-col-text")
.with_size(flex::ItemSize::Percent50)
.add_component(Heading::h2(L10n::l("welcome_issues_title")))
.add_component(
Paragraph::fluent(L10n::l("welcome_issues_text1"))
.with_font_size(FontSize::Medium),
)
.add_component(Paragraph::fluent(
L10n::l("welcome_issues_text2").with_arg(
"app",
format!(
"<span class=\"app-name\">{}</span>",
&config::SETTINGS.app.name,
),
Flex::new().with_size(FlexSize::Percent75).add_component(
Container::new()
.with_direction(FlexDirection::Column(BreakPoint::MD))
.add_item(
Flex::new()
.with_classes(ClassesOp::Add, "promo-col-text")
.with_size(FlexSize::Percent50)
.add_component(Heading::h2(L10n::l("welcome_promo_title")))
.add_component(
Paragraph::fluent(L10n::l("welcome_promo_text1").with_arg(
"pagetop",
format!(
"<a href=\"{}\" target=\"_blank\">{}</a>",
"https://crates.io/crates/pagetop", "PageTop",
),
)),
),
),
))
.with_font_size(FontSize::Medium),
),
)
.add_item(
Flex::with(Image::with("/base/images/pagetop.png"))
.with_classes(ClassesOp::Add, "promo-col-image")
.with_size(FlexSize::Percent50),
),
),
)
}
fn reporting_issues() -> Container {
Container::new()
.with_classes(ClassesOp::Add, "issues")
.with_justify(FlexJustify::Center)
.add_item(
Flex::new().with_size(FlexSize::Percent90).add_component(
Container::new()
.with_direction(FlexDirection::Column(BreakPoint::MD))
.add_item(
Flex::with(Image::with("/base/images/issues.jpg"))
.with_classes(ClassesOp::Add, "issues-col-image"),
)
.add_item(
Flex::new()
.with_classes(ClassesOp::Add, "issues-col-text")
.with_size(FlexSize::Percent50)
.add_component(Heading::h2(L10n::l("welcome_issues_title")))
.add_component(
Paragraph::fluent(L10n::l("welcome_issues_text1"))
.with_font_size(FontSize::Medium),
)
.add_component(Paragraph::fluent(
L10n::l("welcome_issues_text2").with_arg(
"app",
format!(
"<span class=\"app-name\">{}</span>",
&config::SETTINGS.app.name,
),
),
)),
),
),
)
}

View file

@ -67,16 +67,16 @@
justify-content: space-evenly;
}
.flex__container.flex__item-end {
.flex__container.flex__end {
align-items: flex-end;
}
.flex__container.flex__item-center {
.flex__container.flex__center {
align-items: center;
}
.flex__container.flex__item-stretch {
.flex__container.flex__stretch {
align-items: stretch;
}
.flex__container.flex__item-baseline {
.flex__container.flex__baseline {
align-items: baseline;
}
@ -90,163 +90,163 @@
width: auto;
}
.flex__item-grow-1 {
.flex__grow-1 {
flex-grow: 1;
}
.flex__item-grow-2 {
.flex__grow-2 {
flex-grow: 2;
}
.flex__item-grow-3 {
.flex__grow-3 {
flex-grow: 3;
}
.flex__item-grow-4 {
.flex__grow-4 {
flex-grow: 4;
}
.flex__item-grow-5 {
.flex__grow-5 {
flex-grow: 5;
}
.flex__item-grow-6 {
.flex__grow-6 {
flex-grow: 6;
}
.flex__item-grow-7 {
.flex__grow-7 {
flex-grow: 7;
}
.flex__item-grow-8 {
.flex__grow-8 {
flex-grow: 8;
}
.flex__item-grow-9 {
.flex__grow-9 {
flex-grow: 9;
}
[class*="flex__item-grow-"] {
[class*="flex__grow-"] {
width: auto;
}
.flex__item-shrink-1 {
.flex__shrink-1 {
flex-shrink: 1;
}
.flex__item-shrink-2 {
.flex__shrink-2 {
flex-shrink: 2;
}
.flex__item-shrink-3 {
.flex__shrink-3 {
flex-shrink: 3;
}
.flex__item-shrink-4 {
.flex__shrink-4 {
flex-shrink: 4;
}
.flex__item-shrink-5 {
.flex__shrink-5 {
flex-shrink: 5;
}
.flex__item-shrink-6 {
.flex__shrink-6 {
flex-shrink: 6;
}
.flex__item-shrink-7 {
.flex__shrink-7 {
flex-shrink: 7;
}
.flex__item-shrink-8 {
.flex__shrink-8 {
flex-shrink: 8;
}
.flex__item-shrink-9 {
.flex__shrink-9 {
flex-shrink: 9;
}
[class*="flex__item-shrink-"] {
[class*="flex__shrink-"] {
width: auto;
}
.flex__item-size-10 {
.flex__size-10 {
flex: 0 0 10%;
max-width: 10%;
}
.flex__item-size-20 {
.flex__size-20 {
flex: 0 0 20%;
max-width: 20%;
}
.flex__item-size-25 {
.flex__size-25 {
flex: 0 0 25%;
max-width: 25%;
}
.flex__item-size-33 {
.flex__size-33 {
flex: 0 0 33.3333%;
max-width: 33.3333%;
}
.flex__item-size-40 {
.flex__size-40 {
flex: 0 0 40%;
max-width: 40%;
}
.flex__item-size-50 {
.flex__size-50 {
flex: 0 0 60%;
max-width: 50%;
}
.flex__item-size-60 {
.flex__size-60 {
flex: 0 0 60%;
max-width: 60%;
}
.flex__item-size-66 {
.flex__size-66 {
flex: 0 0 66.6666%;
max-width: 66.6666%;
}
.flex__item-size-75 {
.flex__size-75 {
flex: 0 0 75%;
max-width: 75%;
}
.flex__item-size-80 {
.flex__size-80 {
flex: 0 0 80%;
max-width: 80%;
}
.flex__item-size-90 {
.flex__size-90 {
flex: 0 0 90%;
max-width: 90%;
}
[class*="flex__item-size-"] {
[class*="flex__size-"] {
width: auto;
}
.flex__item-offset-10 {
.flex__offset-10 {
margin-left: 10%;
}
.flex__item-offset-20 {
.flex__offset-20 {
margin-left: 20%;
}
.flex__item-offset-25 {
.flex__offset-25 {
margin-left: 25%;
}
.flex__item-offset-33 {
.flex__offset-33 {
margin-left: 33.3333%;
}
.flex__item-offset-40 {
.flex__offset-40 {
margin-left: 40%;
}
.flex__item-offset-50 {
.flex__offset-50 {
margin-left: 50%;
}
.flex__item-offset-60 {
.flex__offset-60 {
margin-left: 60%;
}
.flex__item-offset-66 {
.flex__offset-66 {
margin-left: 66.6666%;
}
.flex__item-offset-75 {
.flex__offset-75 {
margin-left: 75%;
}
.flex__item-offset-80 {
.flex__offset-80 {
margin-left: 80%;
}
.flex__item-offset-90 {
.flex__offset-90 {
margin-left: 90%;
}
.flex__item.flex__item-start {
.flex__item.flex__start {
align-self: flex-start;
}
.flex__item.flex__item-end {
.flex__item.flex__end {
align-self: flex-end;
}
.flex__item.flex__item-center {
.flex__item.flex__center {
align-self: center;
}
.flex__item.flex__item-stretch {
.flex__item.flex__stretch {
align-self: stretch;
}
.flex__item.flex__item-baseline {
.flex__item.flex__baseline {
align-self: baseline;
}