diff --git a/src/base/component/flex.rs b/src/base/component/flex.rs index db68c217..3bbd8149 100644 --- a/src/base/component/flex.rs +++ b/src/base/component/flex.rs @@ -22,19 +22,19 @@ impl ToString for Direction { fn to_string(&self) -> String { match self { Direction::Default => concat_string!( - "flex__container flex__row ", BreakPoint::default().to_string() + "flex__row ", BreakPoint::default().to_string() ), Direction::Row(breakpoint) => concat_string!( - "flex__container flex__row ", breakpoint.to_string() + "flex__row ", breakpoint.to_string() ), Direction::RowReverse(breakpoint) => concat_string!( - "flex__container flex__row flex__reverse ", breakpoint.to_string() + "flex__row flex__reverse ", breakpoint.to_string() ), Direction::Column(breakpoint) => concat_string!( - "flex__container flex__col ", breakpoint.to_string() + "flex__col ", breakpoint.to_string() ), Direction::ColumnReverse(breakpoint) => concat_string!( - "flex__container flex__col flex__reverse ", breakpoint.to_string() + "flex__col flex__reverse ", breakpoint.to_string() ), } } @@ -139,11 +139,11 @@ 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", + 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", }) } } @@ -175,6 +175,24 @@ 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] @@ -190,20 +208,19 @@ pub enum ItemGrow { Is9, } -#[rustfmt::skip] 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", + 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", }) } } @@ -225,20 +242,19 @@ pub enum ItemShrink { Is9, } -#[rustfmt::skip] 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", + 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", }) } } @@ -260,24 +276,25 @@ pub enum ItemSize { Percent75, Percent80, Percent90, + FullWidth, } -#[rustfmt::skip] 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::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", }) } } @@ -301,22 +318,21 @@ pub enum ItemOffset { Offset90, } -#[rustfmt::skip] 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", + 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", }) } } diff --git a/src/base/component/flex/container.rs b/src/base/component/flex/container.rs index 6518a067..4b825c5a 100644 --- a/src/base/component/flex/container.rs +++ b/src/base/component/flex/container.rs @@ -7,12 +7,12 @@ pub struct Container { weight : Weight, renderable : Renderable, classes : OptionClasses, - items : TypedComponents, direction : flex::Direction, wrap_align : flex::WrapAlign, content_justify: flex::ContentJustify, items_align : flex::ItemAlign, gap : flex::Gap, + items : TypedComponents, } impl ComponentTrait for Container { @@ -36,6 +36,7 @@ impl ComponentTrait for Container { self.alter_classes( ClassesOp::Prepend, [ + String::from("flex__container"), self.direction().to_string(), self.wrap_align().to_string(), self.content_justify().to_string(), @@ -48,16 +49,20 @@ impl ComponentTrait for Container { } fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { - let gap = match self.gap() { - flex::Gap::Default => None, - _ => Some(self.gap().to_string()), - }; - - PrepareMarkup::With(html! { - div id=[self.id()] class=[self.classes().get()] style=[gap] { - (self.items().render(cx)) - } - }) + 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! { + div id=[self.id()] class=[self.classes().get()] style=[gap] { + (output) + } + }) + } else { + PrepareMarkup::None + } } } @@ -82,18 +87,6 @@ impl Container { self } - #[rustfmt::skip] - pub fn add_item(mut self, item: flex::Item) -> Self { - self.items.alter_value(TypedOp::Add(OneComponent::with(item))); - self - } - - #[fn_builder] - pub fn alter_items(&mut self, op: TypedOp) -> &mut Self { - self.items.alter_value(op); - self - } - #[fn_builder] pub fn alter_direction(&mut self, direction: flex::Direction) -> &mut Self { self.direction = direction; @@ -124,12 +117,20 @@ impl Container { self } - // Container GETTERS. - - pub fn items(&self) -> &TypedComponents { - &self.items + #[fn_builder] + pub fn alter_items(&mut self, op: TypedOp) -> &mut Self { + self.items.alter_value(op); + self } + #[rustfmt::skip] + pub fn add_item(mut self, item: flex::Item) -> Self { + self.items.alter_value(TypedOp::Add(OneComponent::with(item))); + self + } + + // Container GETTERS. + pub fn direction(&self) -> &flex::Direction { &self.direction } @@ -149,4 +150,8 @@ impl Container { pub fn gap(&self) -> &flex::Gap { &self.gap } + + pub fn items(&self) -> &TypedComponents { + &self.items + } } diff --git a/src/base/component/flex/item.rs b/src/base/component/flex/item.rs index 07074f28..4b91dcdd 100644 --- a/src/base/component/flex/item.rs +++ b/src/base/component/flex/item.rs @@ -7,6 +7,7 @@ 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, @@ -36,7 +37,8 @@ impl ComponentTrait for Item { self.alter_classes( ClassesOp::Prepend, [ - "flex-item__container".to_owned(), + String::from("flex__item"), + self.wide().to_string(), self.grow().to_string(), self.shrink().to_string(), self.size().to_string(), @@ -48,17 +50,22 @@ impl ComponentTrait for Item { } fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { - let order = match self.weight() { - 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-item__content" { - (self.components().render(cx)) + let output = self.components().render(cx); + if !output.is_empty() { + let order = match self.weight() { + 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" { + (output) + } } - } - }) + }) + } else { + PrepareMarkup::None + } } } @@ -67,6 +74,12 @@ 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] @@ -87,6 +100,12 @@ 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; @@ -100,6 +119,8 @@ impl Item { } #[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; self @@ -131,6 +152,10 @@ 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/static/base/css/flex.css b/static/base/css/flex.css index d8487428..3ba0a804 100644 --- a/static/base/css/flex.css +++ b/static/base/css/flex.css @@ -67,173 +67,180 @@ justify-content: space-evenly; } -.flex__container.flex-item__end { +.flex__container.flex__item-end { align-items: flex-end; } -.flex__container.flex-item__center { +.flex__container.flex__item-center { align-items: center; } -.flex__container.flex-item__stretch { +.flex__container.flex__item-stretch { align-items: stretch; } -.flex__container.flex-item__baseline { +.flex__container.flex__item-baseline { align-items: baseline; } /* ITEMS */ -.flex-item__container { +.flex__item { padding: 0 !important; } +.flex__item.flex__full { + width: 100%; +} -.flex-item__grow-1 { +.flex__item-grow-1 { flex-grow: 1; } -.flex-item__grow-2 { +.flex__item-grow-2 { flex-grow: 2; } -.flex-item__grow-3 { +.flex__item-grow-3 { flex-grow: 3; } -.flex-item__grow-4 { +.flex__item-grow-4 { flex-grow: 4; } -.flex-item__grow-5 { +.flex__item-grow-5 { flex-grow: 5; } -.flex-item__grow-6 { +.flex__item-grow-6 { flex-grow: 6; } -.flex-item__grow-7 { +.flex__item-grow-7 { flex-grow: 7; } -.flex-item__grow-8 { +.flex__item-grow-8 { flex-grow: 8; } -.flex-item__grow-9 { +.flex__item-grow-9 { flex-grow: 9; } -.flex-item__shrink-1 { +.flex__item-shrink-1 { flex-shrink: 1; } -.flex-item__shrink-2 { +.flex__item-shrink-2 { flex-shrink: 2; } -.flex-item__shrink-3 { +.flex__item-shrink-3 { flex-shrink: 3; } -.flex-item__shrink-4 { +.flex__item-shrink-4 { flex-shrink: 4; } -.flex-item__shrink-5 { +.flex__item-shrink-5 { flex-shrink: 5; } -.flex-item__shrink-6 { +.flex__item-shrink-6 { flex-shrink: 6; } -.flex-item__shrink-7 { +.flex__item-shrink-7 { flex-shrink: 7; } -.flex-item__shrink-8 { +.flex__item-shrink-8 { flex-shrink: 8; } -.flex-item__shrink-9 { +.flex__item-shrink-9 { flex-shrink: 9; } -.flex-item__width-10 { +.flex__item-width-10 { flex: 0 0 10%; max-width: 10%; } -.flex-item__width-20 { +.flex__item-width-20 { flex: 0 0 20%; max-width: 20%; } -.flex-item__width-25 { +.flex__item-width-25 { flex: 0 0 25%; max-width: 25%; } -.flex-item__width-33 { +.flex__item-width-33 { flex: 0 0 33.3333%; max-width: 33.3333%; } -.flex-item__width-40 { +.flex__item-width-40 { flex: 0 0 40%; max-width: 40%; } -.flex-item__width-50 { +.flex__item-width-50 { flex: 0 0 60%; max-width: 50%; } -.flex-item__width-60 { +.flex__item-width-60 { flex: 0 0 60%; max-width: 60%; } -.flex-item__width-66 { +.flex__item-width-66 { flex: 0 0 66.6666%; max-width: 66.6666%; } -.flex-item__width-75 { +.flex__item-width-75 { flex: 0 0 75%; max-width: 75%; } -.flex-item__width-80 { +.flex__item-width-80 { flex: 0 0 80%; max-width: 80%; } -.flex-item__width-90 { +.flex__item-width-90 { flex: 0 0 90%; max-width: 90%; } +.flex__item-fullwidth { + flex: 0 0 100%; + max-width: 100%; +} -.flex-item__offset-10 { +.flex__item-offset-10 { margin-left: 10%; } -.flex-item__offset-20 { +.flex__item-offset-20 { margin-left: 20%; } -.flex-item__offset-25 { +.flex__item-offset-25 { margin-left: 25%; } -.flex-item__offset-33 { +.flex__item-offset-33 { margin-left: 33.3333%; } -.flex-item__offset-40 { +.flex__item-offset-40 { margin-left: 40%; } -.flex-item__offset-50 { +.flex__item-offset-50 { margin-left: 50%; } -.flex-item__offset-60 { +.flex__item-offset-60 { margin-left: 60%; } -.flex-item__offset-66 { +.flex__item-offset-66 { margin-left: 66.6666%; } -.flex-item__offset-75 { +.flex__item-offset-75 { margin-left: 75%; } -.flex-item__offset-80 { +.flex__item-offset-80 { margin-left: 80%; } -.flex-item__offset-90 { +.flex__item-offset-90 { margin-left: 90%; } -.flex-item__container.flex-item__start { +.flex__item.flex__item-start { align-self: flex-start; } -.flex-item__container.flex-item__end { +.flex__item.flex__item-end { align-self: flex-end; } -.flex-item__container.flex-item__center { +.flex__item.flex__item-center { align-self: center; } -.flex-item__container.flex-item__stretch { +.flex__item.flex__item-stretch { align-self: stretch; } -.flex-item__container.flex-item__baseline { +.flex__item.flex__item-baseline { align-self: baseline; } @@ -253,7 +260,7 @@ .flex__col.flex__reverse.bp__sm { flex-direction: column-reverse; } - .flex__col.bp__sm .flex-item__container { + .flex__col.bp__sm .flex__item { flex: 1 1 auto; max-width: 100%; margin-left: 0; @@ -273,7 +280,7 @@ .flex__col.flex__reverse.bp__md { flex-direction: column-reverse; } - .flex__col.bp__md .flex-item__container { + .flex__col.bp__md .flex__item { flex: 1 1 auto; max-width: 100%; margin-left: 0; @@ -293,7 +300,7 @@ .flex__col.flex__reverse.bp__lg { flex-direction: column-reverse; } - .flex__col.bp__lg .flex-item__container { + .flex__col.bp__lg .flex__item { flex: 1 1 auto; max-width: 100%; margin-left: 0; @@ -313,7 +320,7 @@ .flex__col.flex__reverse.bp__xl { flex-direction: column-reverse; } - .flex__col.bp__xl .flex-item__container { + .flex__col.bp__xl .flex__item { flex: 1 1 auto; max-width: 100%; margin-left: 0; @@ -333,7 +340,7 @@ .flex__col.flex__reverse.bp__x2l { flex-direction: column-reverse; } - .flex__col.bp__x2l .flex-item__container { + .flex__col.bp__x2l .flex__item { flex: 1 1 auto; max-width: 100%; margin-left: 0; @@ -353,7 +360,7 @@ .flex__col.flex__reverse.bp__x3l { flex-direction: column-reverse; } - .flex__col.bp__x3l .flex-item__container { + .flex__col.bp__x3l .flex__item { flex: 1 1 auto; max-width: 100%; margin-left: 0; @@ -373,7 +380,7 @@ .flex__col.flex__reverse.bp__x2k { flex-direction: column-reverse; } - .flex__col.bp__x2k .flex-item__container { + .flex__col.bp__x2k .flex__item { flex: 1 1 auto; max-width: 100%; margin-left: 0; diff --git a/static/base/css/inception.css b/static/base/css/inception.css index f3e7cd3d..fb54d69c 100644 --- a/static/base/css/inception.css +++ b/static/base/css/inception.css @@ -73,36 +73,24 @@ a:active { /* LAYOUT */ -.body__wrapper { - width: 100%; - display: flex; - flex-direction: column; - align-items: center; -} -#header, -#pagetop, -.content__wrapper, -#footer { - width: 100%; +#body__wrapper > .flex__item { max-width: var(--val-max-width); background: var(--val-color--white); } -#header > .region__content /*, -#pagetop > .region__content */ { +#header > .flex__content { margin: var(--val-gap); } -#footer { +#body__wrapper > #footer { max-width: 100%; background: linear-gradient(180deg, var(--val-color--gray-5) 0%, var(--val-color--gray-10) 100%); } -#footer > .region__content { - width: 100%; +#footer > .flex__content { max-width: var(--val-max-width); margin: 0 auto; color: var(--val-color--gray-65); background: var(--val-color--gray-20); padding: calc(3 * var(--val-gap)) 0 calc(12 * var(--val-gap)); } -#footer > .region__content a { +#footer > .flex__content a { color: var(--val-color--white); } diff --git a/static/base/css/welcome.css b/static/base/css/welcome.css index 75e14f05..faf6e797 100644 --- a/static/base/css/welcome.css +++ b/static/base/css/welcome.css @@ -16,11 +16,11 @@ padding-top: 0; } -#welcome [class$="-col-text"] > .flex-item__content { +#welcome [class$="-col-text"] > .flex__content { margin: 5% 5% 0; text-align: center; } -#welcome [class$="-col-image"] > .flex-item__content { +#welcome [class$="-col-image"] > .flex__content { margin: 1rem 5%; } @@ -43,11 +43,11 @@ color: #ccc; } -#welcome .promo-col-image > .flex-item__content { +#welcome .promo-col-image > .flex__content { padding: 0 5%; } -#welcome .issues-col-image > .flex-item__content img { +#welcome .issues-col-image > .flex__content img { border-radius: 40px; } @@ -55,20 +55,20 @@ /* MD - Applies >= 768px */ @media screen and (min-width: 48rem) { - #welcome .promo-col-image > .flex-item__content { + #welcome .promo-col-image > .flex__content { padding: 0; } #welcome .issues { padding-top: 1.6rem; } - #welcome .issues-col-text > .flex-item__content { + #welcome .issues-col-text > .flex__content { text-align: left; } } /* LG - Applies >= 992px */ @media screen and (min-width: 62rem) { - #welcome .hello-col-text > .flex-item__content { + #welcome .hello-col-text > .flex__content { margin-top: 2rem; text-align: left; } @@ -77,19 +77,19 @@ padding: 0 15% 2rem; } - #welcome .promo-col-text > .flex-item__content { + #welcome .promo-col-text > .flex__content { margin-right: 0; text-align: right; } } /* XL - Applies >= 1280px */ @media screen and (min-width: 80rem) { - #welcome .hello-col-text > .flex-item__content { + #welcome .hello-col-text > .flex__content { margin-top: 4rem; margin-left: 20%; } - #welcome .pagetop-col-text > .flex-item__content { + #welcome .pagetop-col-text > .flex__content { text-align: left; } }