diff --git a/packages/pagetop-user/src/lib.rs b/packages/pagetop-user/src/lib.rs index 7517a20d..8f07ce84 100644 --- a/packages/pagetop-user/src/lib.rs +++ b/packages/pagetop-user/src/lib.rs @@ -33,9 +33,9 @@ async fn login(request: HttpRequest) -> ResultPage { Page::new(request) .with_title(L10n::n("Identificación del usuario")) .with_component( - Wrapper::new() + flex::Container::new() .with_id("welcome") - .add_component(form_login()), + .add_item(flex::Item::with(form_login())), ) .render() } diff --git a/src/base/component.rs b/src/base/component.rs index 973a882c..b972ddae 100644 --- a/src/base/component.rs +++ b/src/base/component.rs @@ -63,14 +63,14 @@ pub(crate) fn add_base_assets(cx: &mut Context) { #[derive(AutoDefault)] pub enum BreakPoint { #[default] - None, /* Does not apply. Rest initially assume 1 pixel = 0.0625rem */ - SM, /* PageTop default applies to <= 568px - @media screen and (max-width: 35.5rem) */ - MD, /* PageTop default applies to <= 768px - @media screen and (max-width: 48rem) */ - LG, /* PageTop default applies to <= 992px - @media screen and (max-width: 62rem) */ - XL, /* PageTop default applies to <= 1280px - @media screen and (max-width: 80rem) */ - X2L, /* PageTop default applies to <= 1440px - @media screen and (max-width: 90rem) */ - X3L, /* PageTop default applies to <= 1920px - @media screen and (max-width: 120rem) */ - X2K, /* PageTop default applies to <= 2560px - @media screen and (max-width: 160rem) */ + None, // Does not apply. Rest initially assume 1 pixel = 0.0625rem + SM, // @media screen and [ (max-width: 35.5rem) <= 568px < (min-width: 35.5625rem) ] + MD, // @media screen and [ (max-width: 48rem) <= 768px < (min-width: 48.0625rem) ] + LG, // @media screen and [ (max-width: 62rem) <= 992px < (min-width: 62.0625rem) ] + XL, // @media screen and [ (max-width: 80rem) <= 1280px < (min-width: 80.0625rem) ] + X2L, // @media screen and [ (max-width: 90rem) <= 1440px < (min-width: 90.0625rem) ] + X3L, // @media screen and [ (max-width: 120rem) <= 1920px < (min-width: 120.0625rem) ] + X2K, // @media screen and [ (max-width: 160rem) <= 2560px < (min-width: 160.0625rem) ] } #[rustfmt::skip] @@ -175,9 +175,6 @@ pub use error403::Error403; mod error404; pub use error404::Error404; -mod wrapper; -pub use wrapper::{Wrapper, WrapperType}; - pub mod flex; mod icon; diff --git a/src/base/component/flex.rs b/src/base/component/flex.rs index 3bbd8149..eef546f7 100644 --- a/src/base/component/flex.rs +++ b/src/base/component/flex.rs @@ -175,24 +175,6 @@ impl ToString for Gap { // ************************************************************************************************* -#[derive(AutoDefault)] -pub enum ItemWide { - #[default] - Auto, - Full, -} - -impl ToString for ItemWide { - fn to_string(&self) -> String { - String::from(match self { - ItemWide::Auto => "", - ItemWide::Full => "flex__full", - }) - } -} - -// ************************************************************************************************* - #[derive(AutoDefault)] pub enum ItemGrow { #[default] @@ -276,25 +258,23 @@ pub enum ItemSize { Percent75, Percent80, Percent90, - FullWidth, } impl ToString for ItemSize { fn to_string(&self) -> String { String::from(match self { ItemSize::Default => "", - ItemSize::Percent10 => "flex__item-width-10", - ItemSize::Percent20 => "flex__item-width-20", - ItemSize::Percent25 => "flex__item-width-25", - ItemSize::Percent33 => "flex__item-width-33", - ItemSize::Percent40 => "flex__item-width-40", - ItemSize::Percent50 => "flex__item-width-50", - ItemSize::Percent60 => "flex__item-width-60", - ItemSize::Percent66 => "flex__item-width-66", - ItemSize::Percent75 => "flex__item-width-75", - ItemSize::Percent80 => "flex__item-width-80", - ItemSize::Percent90 => "flex__item-width-90", - ItemSize::FullWidth => "flex__item-fullwidth", + 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", }) } } diff --git a/src/base/component/flex/container.rs b/src/base/component/flex/container.rs index 4b825c5a..b35e4760 100644 --- a/src/base/component/flex/container.rs +++ b/src/base/component/flex/container.rs @@ -1,5 +1,16 @@ use crate::prelude::*; +#[derive(AutoDefault)] +pub enum ContainerType { + #[default] + Default, + Header, + Main, + Section, + Article, + Footer, +} + #[rustfmt::skip] #[derive(AutoDefault, ComponentClasses)] pub struct Container { @@ -7,12 +18,13 @@ pub struct Container { 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 : TypedComponents, + items : MixedComponents, } impl ComponentTrait for Container { @@ -50,23 +62,85 @@ impl ComponentTrait for Container { fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { let output = self.items().render(cx); - if !output.is_empty() { - let gap = match self.gap() { - flex::Gap::Default => None, - _ => Some(self.gap().to_string()), - }; - PrepareMarkup::With(html! { + if output.is_empty() { + return PrepareMarkup::None; + } + + let gap = match self.gap() { + flex::Gap::Default => None, + _ => Some(self.gap().to_string()), + }; + match self.container_type() { + ContainerType::Default => PrepareMarkup::With(html! { div id=[self.id()] class=[self.classes().get()] style=[gap] { (output) } - }) - } else { - PrepareMarkup::None + }), + ContainerType::Header => PrepareMarkup::With(html! { + header id=[self.id()] class=[self.classes().get()] style=[gap] { + (output) + } + }), + ContainerType::Main => PrepareMarkup::With(html! { + main id=[self.id()] class=[self.classes().get()] style=[gap] { + (output) + } + }), + ContainerType::Section => PrepareMarkup::With(html! { + section id=[self.id()] class=[self.classes().get()] style=[gap] { + (output) + } + }), + ContainerType::Article => PrepareMarkup::With(html! { + article id=[self.id()] class=[self.classes().get()] style=[gap] { + (output) + } + }), + ContainerType::Footer => PrepareMarkup::With(html! { + footer id=[self.id()] class=[self.classes().get()] style=[gap] { + (output) + } + }), } } } impl Container { + pub fn header() -> Self { + Container { + container_type: ContainerType::Header, + ..Default::default() + } + } + + pub fn main() -> Self { + Container { + container_type: ContainerType::Main, + ..Default::default() + } + } + + pub fn section() -> Self { + Container { + container_type: ContainerType::Section, + ..Default::default() + } + } + + pub fn article() -> Self { + Container { + container_type: ContainerType::Article, + ..Default::default() + } + } + + pub fn footer() -> Self { + Container { + container_type: ContainerType::Footer, + ..Default::default() + } + } + // Container BUILDER. #[fn_builder] @@ -119,18 +193,22 @@ impl Container { #[fn_builder] pub fn alter_items(&mut self, op: TypedOp) -> &mut Self { - self.items.alter_value(op); + self.items.alter_typed(op); self } #[rustfmt::skip] pub fn add_item(mut self, item: flex::Item) -> Self { - self.items.alter_value(TypedOp::Add(OneComponent::with(item))); + self.items.alter_value(AnyOp::Add(AnyComponent::with(item))); self } // Container GETTERS. + pub fn container_type(&self) -> &ContainerType { + &self.container_type + } + pub fn direction(&self) -> &flex::Direction { &self.direction } @@ -151,7 +229,7 @@ impl Container { &self.gap } - pub fn items(&self) -> &TypedComponents { + pub fn items(&self) -> &MixedComponents { &self.items } } diff --git a/src/base/component/flex/item.rs b/src/base/component/flex/item.rs index 5775cf2a..e02751d4 100644 --- a/src/base/component/flex/item.rs +++ b/src/base/component/flex/item.rs @@ -7,7 +7,6 @@ pub struct Item { weight : Weight, renderable : Renderable, classes : OptionClasses, - item_wide : flex::ItemWide, item_grow : flex::ItemGrow, item_shrink : flex::ItemShrink, item_size : flex::ItemSize, @@ -38,7 +37,6 @@ impl ComponentTrait for Item { ClassesOp::Prepend, [ String::from("flex__item"), - self.wide().to_string(), self.grow().to_string(), self.shrink().to_string(), self.size().to_string(), @@ -74,12 +72,6 @@ impl Item { Item::default().add_component(component) } - pub fn full(component: impl ComponentTrait) -> Self { - Item::default() - .with_wide(flex::ItemWide::Full) - .add_component(component) - } - // Item BUILDER. #[fn_builder] @@ -100,12 +92,6 @@ impl Item { self } - #[fn_builder] - pub fn alter_wide(&mut self, wide: flex::ItemWide) -> &mut Self { - self.item_wide = wide; - self - } - #[fn_builder] pub fn alter_grow(&mut self, grow: flex::ItemGrow) -> &mut Self { self.item_grow = grow; @@ -152,10 +138,6 @@ impl Item { // Item GETTERS. - pub fn wide(&self) -> &flex::ItemWide { - &self.item_wide - } - pub fn grow(&self) -> &flex::ItemGrow { &self.item_grow } diff --git a/src/base/component/layout.rs b/src/base/component/layout.rs index dc531307..490179b9 100644 --- a/src/base/component/layout.rs +++ b/src/base/component/layout.rs @@ -23,29 +23,31 @@ impl Layout { .with_id("body__wrapper") .with_direction(flex::Direction::Column(BreakPoint::None)) .with_items_align(flex::ItemAlign::Center) - .add_item(flex::Item::full(Region::named("header")).with_id("header")) - .add_item(flex::Item::full(Region::named("pagetop")).with_id("pagetop")) - .add_item(flex::Item::full( - flex::Container::new() - .with_id("content__wrapper") - .with_direction(flex::Direction::Row(BreakPoint::None)) - .add_item( - flex::Item::with(Region::named("sidebar_left")) - .with_id("sidebar_left") - .with_grow(flex::ItemGrow::Is1), - ) - .add_item( - flex::Item::with(Region::named("content")) - .with_id("content") - .with_grow(flex::ItemGrow::Is3), - ) - .add_item( - flex::Item::with(Region::named("sidebar_right")) - .with_id("sidebar_right") - .with_grow(flex::ItemGrow::Is1), - ), - )) - .add_item(flex::Item::full(Region::named("footer")).with_id("footer")) + .add_item(flex::Item::with(Region::named("header")).with_id("header")) + .add_item(flex::Item::with(Region::named("pagetop")).with_id("pagetop")) + .add_item( + flex::Item::with( + flex::Container::new() + .with_direction(flex::Direction::Row(BreakPoint::None)) + .add_item( + flex::Item::with(Region::named("sidebar_left")) + .with_id("sidebar_left") + .with_grow(flex::ItemGrow::Is1), + ) + .add_item( + flex::Item::with(Region::named("content")) + .with_id("content") + .with_grow(flex::ItemGrow::Is3), + ) + .add_item( + flex::Item::with(Region::named("sidebar_right")) + .with_id("sidebar_right") + .with_grow(flex::ItemGrow::Is1), + ), + ) + .with_id("content__wrapper"), + ) + .add_item(flex::Item::with(Region::named("footer")).with_id("footer")) .render(cx) } diff --git a/src/base/component/wrapper.rs b/src/base/component/wrapper.rs deleted file mode 100644 index 066fe83c..00000000 --- a/src/base/component/wrapper.rs +++ /dev/null @@ -1,148 +0,0 @@ -use crate::prelude::*; - -#[derive(AutoDefault)] -pub enum WrapperType { - #[default] - Container, - Header, - Footer, - Main, - Section, -} - -#[rustfmt::skip] -#[derive(AutoDefault, ComponentClasses)] -pub struct Wrapper { - id : OptionId, - weight : Weight, - renderable : Renderable, - classes : OptionClasses, - wrapper_type: WrapperType, - mixed : MixedComponents, -} - -impl ComponentTrait for Wrapper { - fn new() -> Self { - Wrapper::default().with_classes(ClassesOp::Add, "wrapper__container") - } - - fn id(&self) -> Option { - self.id.get() - } - - fn weight(&self) -> Weight { - self.weight - } - - fn is_renderable(&self, cx: &Context) -> bool { - (self.renderable.check)(cx) - } - - fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { - match self.wrapper_type() { - WrapperType::Container => PrepareMarkup::With(html! { - div id=[self.id()] class=[self.classes().get()] { - div class="wrapper__content" { - (self.components().render(cx)) - } - } - }), - WrapperType::Main => PrepareMarkup::With(html! { - main id=[self.id()] class=[self.classes().get()] { - div class="wrapper__content" { - (self.components().render(cx)) - } - } - }), - WrapperType::Section => PrepareMarkup::With(html! { - section id=[self.id()] class=[self.classes().get()] { - div class="wrapper__content" { - (self.components().render(cx)) - } - } - }), - WrapperType::Header => PrepareMarkup::With(html! { - header id=[self.id()] class=[self.classes().get()] { - div class="wrapper__content" { - (self.components().render(cx)) - } - } - }), - WrapperType::Footer => PrepareMarkup::With(html! { - footer id=[self.id()] class=[self.classes().get()] { - div class="wrapper__content" { - (self.components().render(cx)) - } - } - }), - } - } -} - -impl Wrapper { - pub fn main() -> Self { - let mut c = Wrapper::default().with_classes(ClassesOp::Add, "main__container"); - c.wrapper_type = WrapperType::Main; - c - } - - pub fn section() -> Self { - let mut c = Wrapper::default().with_classes(ClassesOp::Add, "section__container"); - c.wrapper_type = WrapperType::Section; - c - } - - pub fn header() -> Self { - let mut c = Wrapper::default().with_classes(ClassesOp::Add, "header__container"); - c.wrapper_type = WrapperType::Header; - c - } - - pub fn footer() -> Self { - let mut c = Wrapper::default().with_classes(ClassesOp::Add, "footer__container"); - c.wrapper_type = WrapperType::Footer; - c - } - - // Wrapper BUILDER. - - #[fn_builder] - pub fn alter_id(&mut self, id: impl Into) -> &mut Self { - self.id.alter_value(id); - self - } - - #[fn_builder] - pub fn alter_weight(&mut self, value: Weight) -> &mut Self { - self.weight = value; - self - } - - #[fn_builder] - pub fn alter_renderable(&mut self, check: FnIsRenderable) -> &mut Self { - self.renderable.check = check; - self - } - - #[fn_builder] - pub fn alter_components(&mut self, op: MixedOp) -> &mut Self { - self.mixed.alter_value(op); - self - } - - #[rustfmt::skip] - pub fn add_component(mut self, component: impl ComponentTrait) -> Self { - self.mixed.alter_value(MixedOp::Add(AnyComponent::with(component))); - self - } - - // Wrapper GETTERS. - - pub fn wrapper_type(&self) -> &WrapperType { - &self.wrapper_type - } - - pub fn components(&self) -> &MixedComponents { - &self.mixed - } -} diff --git a/src/base/package/welcome.rs b/src/base/package/welcome.rs index 2437689a..afd9898e 100644 --- a/src/base/package/welcome.rs +++ b/src/base/package/welcome.rs @@ -47,168 +47,194 @@ fn home(request: HttpRequest, lang: &'static LanguageIdentifier) -> ResultPage Wrapper { - Wrapper::header() +fn hello_world() -> flex::Container { + flex::Container::header() .with_classes(ClassesOp::Add, "hello-world") - .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!( - "{}", - &config::SETTINGS.app.name, + .with_content_justify(flex::ContentJustify::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!( + "{}", + &config::SETTINGS.app.name, + ), + )) + .with_font_size(FontSize::Medium), + ) + .add_component(Paragraph::fluent( + L10n::l("welcome_powered").with_arg( + "pagetop", + format!( + "{}", + "https://pagetop.cillero.es", "PageTop", + ), + ), + )) + .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!( - "{}", - "https://pagetop.cillero.es", "PageTop", - ), - ))) - .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::Item::with(Image::with("/base/images/header.svg")) + .with_classes(ClassesOp::Add, "hello-col-image") + .with_size(flex::ItemSize::Percent60), ), - ) - .add_item( - flex::Item::new() - .with_classes(ClassesOp::Add, "hello-col-image") - .with_size(flex::ItemSize::Percent60) - .add_component(Image::with("/base/images/header.svg")), ), ) } -fn welcome() -> Wrapper { - Wrapper::section() +fn welcome() -> flex::Container { + flex::Container::section() .with_id("welcome-page") .with_classes(ClassesOp::Add, "welcome") - .add_component(Heading::h2(L10n::l("welcome_page"))) - .add_component( - Heading::h3(L10n::l("welcome_subtitle").with_arg( - "app", - format!( - "{}", - &config::SETTINGS.app.name - ), - )) - .with_size(HeadingSize::Subtitle), - ) - .add_component(Paragraph::fluent(L10n::l("welcome_text1")).with_font_size(FontSize::Medium)) - .add_component(Paragraph::fluent(L10n::l("welcome_text2"))) -} - -fn about_pagetop() -> Wrapper { - Wrapper::new() - .with_classes(ClassesOp::Add, "pagetop") - .add_component( - flex::Container::new() - .with_direction(flex::Direction::Column(BreakPoint::SM)) - .add_item( - flex::Item::new() - .with_classes(ClassesOp::Add, "pagetop-col-image") - .with_size(flex::ItemSize::Percent40) - .add_component(Image::with("/base/images/about.svg")), - ) - .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() -> Wrapper { - Wrapper::new() - .with_classes(ClassesOp::Add, "promo") - .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!( - "{}", - "https://crates.io/crates/pagetop", "PageTop", - ), - )) - .with_font_size(FontSize::Medium), + .with_content_justify(flex::ContentJustify::Center) + .add_item( + flex::Item::new() + .with_size(flex::ItemSize::Percent80) + .add_component(Heading::h2(L10n::l("welcome_page"))) + .add_component( + Heading::h3(L10n::l("welcome_subtitle").with_arg( + "app", + format!( + "{}", + &config::SETTINGS.app.name ), + )) + .with_size(HeadingSize::Subtitle), ) - .add_item( - flex::Item::new() - .with_classes(ClassesOp::Add, "promo-col-image") - .with_size(flex::ItemSize::Percent50) - .add_component(Image::with("/base/images/pagetop.png")), + .add_component( + Paragraph::fluent(L10n::l("welcome_text1")).with_font_size(FontSize::Medium), + ) + .add_component(Paragraph::fluent(L10n::l("welcome_text2"))), + ) +} + +fn about_pagetop() -> flex::Container { + flex::Container::new() + .with_classes(ClassesOp::Add, "pagetop") + .with_content_justify(flex::ContentJustify::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 reporting_issues() -> Wrapper { - Wrapper::new() - .with_classes(ClassesOp::Add, "issues") - .add_component( - flex::Container::new() - .with_direction(flex::Direction::Column(BreakPoint::MD)) - .add_item( - flex::Item::new() - .with_classes(ClassesOp::Add, "issues-col-image") - .add_component(Image::with("/base/images/issues.jpg")), - ) - .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!( - "{}", - &config::SETTINGS.app.name, +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!( + "{}", + "https://crates.io/crates/pagetop", "PageTop", + ), + )) + .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), + ), + ), + ) +} + +fn reporting_issues() -> flex::Container { + flex::Container::new() + .with_classes(ClassesOp::Add, "issues") + .with_content_justify(flex::ContentJustify::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!( + "{}", + &config::SETTINGS.app.name, + ), + ), + )), + ), ), ) } diff --git a/static/base/css/flex.css b/static/base/css/flex.css index 3ba0a804..7e81dbfb 100644 --- a/static/base/css/flex.css +++ b/static/base/css/flex.css @@ -84,10 +84,11 @@ .flex__item { padding: 0 !important; -} -.flex__item.flex__full { width: 100%; } +[class*="flex__justify-"] .flex__item { + width: auto; +} .flex__item-grow-1 { flex-grow: 1; @@ -116,6 +117,9 @@ .flex__item-grow-9 { flex-grow: 9; } +[class*="flex__item-grow-"] { + width: auto; +} .flex__item-shrink-1 { flex-shrink: 1; @@ -144,54 +148,56 @@ .flex__item-shrink-9 { flex-shrink: 9; } +[class*="flex__item-shrink-"] { + width: auto; +} -.flex__item-width-10 { +.flex__item-size-10 { flex: 0 0 10%; max-width: 10%; } -.flex__item-width-20 { +.flex__item-size-20 { flex: 0 0 20%; max-width: 20%; } -.flex__item-width-25 { +.flex__item-size-25 { flex: 0 0 25%; max-width: 25%; } -.flex__item-width-33 { +.flex__item-size-33 { flex: 0 0 33.3333%; max-width: 33.3333%; } -.flex__item-width-40 { +.flex__item-size-40 { flex: 0 0 40%; max-width: 40%; } -.flex__item-width-50 { +.flex__item-size-50 { flex: 0 0 60%; max-width: 50%; } -.flex__item-width-60 { +.flex__item-size-60 { flex: 0 0 60%; max-width: 60%; } -.flex__item-width-66 { +.flex__item-size-66 { flex: 0 0 66.6666%; max-width: 66.6666%; } -.flex__item-width-75 { +.flex__item-size-75 { flex: 0 0 75%; max-width: 75%; } -.flex__item-width-80 { +.flex__item-size-80 { flex: 0 0 80%; max-width: 80%; } -.flex__item-width-90 { +.flex__item-size-90 { flex: 0 0 90%; max-width: 90%; } -.flex__item-fullwidth { - flex: 0 0 100%; - max-width: 100%; +[class*="flex__item-size-"] { + width: auto; } .flex__item-offset-10 { @@ -367,7 +373,7 @@ } } /* X2K - Applies <= 2560px */ -@media screen and (max-width: 120rem) { +@media screen and (max-width: 160rem) { .flex__row.bp__x2k { flex-direction: row; } diff --git a/static/base/css/menu.css b/static/base/css/menu.css index df12d1c4..b4461a3c 100644 --- a/static/base/css/menu.css +++ b/static/base/css/menu.css @@ -243,7 +243,7 @@ cursor: pointer; display: flex; align-items: center; - justify-content: center; + justify-content: center; } .menu__nav .menu__header .menu__close { font-size: 2.25rem; diff --git a/static/base/css/welcome.css b/static/base/css/welcome.css index faf6e797..37cec138 100644 --- a/static/base/css/welcome.css +++ b/static/base/css/welcome.css @@ -3,43 +3,37 @@ color: inherit; } -#welcome .hello-world, #welcome .welcome, #welcome .pagetop, #welcome .issues { - padding: 1.6rem 5%; -} -#welcome .promo { - padding: 0 5% 2rem; -} -#welcome .issues { - padding-top: 0; + margin: 3.2rem auto; } #welcome [class$="-col-text"] > .flex__content { - margin: 5% 5% 0; + margin: 5%; text-align: center; } + #welcome [class$="-col-image"] > .flex__content { margin: 1rem 5%; } -#welcome .welcome { - text-align: center; - margin: 0 5%; -} -#welcome .welcome > .wrapper__content { - padding: 2rem 1rem; +#welcome .welcome > .flex__item { border-radius: 28px; background: url("/base/images/welcome.jpg") center center no-repeat; background-size: auto; background-size: cover; color: #fff; } -#welcome .welcome > .wrapper__content > h2 { +#welcome .welcome > .flex__item > .flex__content { + margin: 2rem 1rem; + text-align: center; color: #fff; } -#welcome .welcome > .wrapper__content > h3 { +#welcome .welcome > .flex__item > .flex__content > h2 { + color: #fff; +} +#welcome .welcome > .flex__item > .flex__content > h3 { color: #ccc; } @@ -53,39 +47,34 @@ /* BREAKPOINTS */ -/* MD - Applies >= 768px */ -@media screen and (min-width: 48rem) { +/* MD - Applies > 768px */ +@media screen and (min-width: 48.0625rem) { + #welcome .hello-world { + margin-top: 2rem; + } + #welcome .promo-col-image > .flex__content { padding: 0; } - #welcome .issues { - padding-top: 1.6rem; - } #welcome .issues-col-text > .flex__content { text-align: left; } } -/* LG - Applies >= 992px */ -@media screen and (min-width: 62rem) { +/* LG - Applies > 992px */ +@media screen and (min-width: 62.0625rem) { #welcome .hello-col-text > .flex__content { - margin-top: 2rem; text-align: left; } - #welcome .promo { - padding: 0 15% 2rem; - } - #welcome .promo-col-text > .flex__content { margin-right: 0; text-align: right; } } -/* XL - Applies >= 1280px */ -@media screen and (min-width: 80rem) { +/* XL - Applies > 1280px */ +@media screen and (min-width: 80.0625rem) { #welcome .hello-col-text > .flex__content { - margin-top: 4rem; margin-left: 20%; }