diff --git a/examples/form-controls.rs b/examples/form-controls.rs index 350efd37..8bb3112d 100644 --- a/examples/form-controls.rs +++ b/examples/form-controls.rs @@ -142,7 +142,7 @@ async fn form_controls(request: HttpRequest) -> Result { .with_child( Container::new() .with_flex( - Flex::row() + Flex::new() .with_wrap(flex::Behavior::Wrap) .with_gap(flex::Gap::Both(UnitValue::RelRem(0.5))), ) @@ -262,7 +262,7 @@ async fn form_controls(request: HttpRequest) -> Result { .with_child( Container::new() .with_flex( - Flex::row() + Flex::new() .with_wrap(flex::Behavior::Wrap) .with_gap(flex::Gap::Both(UnitValue::RelRem(0.5))), ) @@ -442,7 +442,7 @@ fn form_lists() -> Form { .with_child( Container::new() .with_flex( - Flex::row() + Flex::new() .with_wrap(flex::Behavior::Wrap) .with_gap(flex::Gap::Both(UnitValue::RelRem(0.5))), ) diff --git a/examples/intro-flex.rs b/examples/intro-flex.rs index 53e051ff..a5e54e30 100644 --- a/examples/intro-flex.rs +++ b/examples/intro-flex.rs @@ -40,21 +40,21 @@ fn direction_block() -> Block { let mut block = Block::new().with_title(Lc::t("flex_block_title_direction", &LOC)); let direction_variants: [(&str, Flex, &str); 4] = [ - ("flex_title_direction_row", Flex::row(), "Flex::row()"), + ("flex_title_direction_row", Flex::new(), "Flex::new()"), ( "flex_title_direction_row_reverse", - Flex::row().with_direction(flex::Direction::RowReverse), - "Flex::row().with_direction(Direction::RowReverse)", + Flex::new().with_direction(flex::Direction::RowReverse), + "Flex::new().with_direction(Direction::RowReverse)", ), ( "flex_title_direction_column", - Flex::column(), - "Flex::column()", + Flex::new().with_direction(flex::Direction::Column), + "Flex::new().with_direction(Direction::Column)", ), ( "flex_title_direction_column_reverse", - Flex::column().with_direction(flex::Direction::ColumnReverse), - "Flex::column().with_direction(Direction::ColumnReverse)", + Flex::new().with_direction(flex::Direction::ColumnReverse), + "Flex::new().with_direction(Direction::ColumnReverse)", ), ]; for (title_key, flex, code) in direction_variants { @@ -77,32 +77,32 @@ fn justify_block() -> Block { ( "flex_title_justify_start", flex::ContentJustify::Start, - "Flex::row().with_justify(ContentJustify::Start)", + "Flex::new().with_justify(ContentJustify::Start)", ), ( "flex_title_justify_center", flex::ContentJustify::Center, - "Flex::row().with_justify(ContentJustify::Center)", + "Flex::new().with_justify(ContentJustify::Center)", ), ( "flex_title_justify_end", flex::ContentJustify::End, - "Flex::row().with_justify(ContentJustify::End)", + "Flex::new().with_justify(ContentJustify::End)", ), ( "flex_title_justify_between", flex::ContentJustify::SpaceBetween, - "Flex::row().with_justify(ContentJustify::SpaceBetween)", + "Flex::new().with_justify(ContentJustify::SpaceBetween)", ), ( "flex_title_justify_around", flex::ContentJustify::SpaceAround, - "Flex::row().with_justify(ContentJustify::SpaceAround)", + "Flex::new().with_justify(ContentJustify::SpaceAround)", ), ( "flex_title_justify_evenly", flex::ContentJustify::SpaceEvenly, - "Flex::row().with_justify(ContentJustify::SpaceEvenly)", + "Flex::new().with_justify(ContentJustify::SpaceEvenly)", ), ]; for (title_key, justify, code) in justify_variants { @@ -110,7 +110,7 @@ fn justify_block() -> Block { .with_child(caption(Lc::t(title_key, &LOC), Lc::n(code))) .with_child( demo_row( - Flex::row() + Flex::new() .with_justify(justify) .with_gap(flex::Gap::Both(UnitValue::RelRem(0.5))), ) @@ -129,22 +129,22 @@ fn align_block() -> Block { ( "flex_title_align_start", flex::Align::Start, - "Flex::row().with_align(Align::Start)", + "Flex::new().with_align(Align::Start)", ), ( "flex_title_align_center", flex::Align::Center, - "Flex::row().with_align(Align::Center)", + "Flex::new().with_align(Align::Center)", ), ( "flex_title_align_end", flex::Align::End, - "Flex::row().with_align(Align::End)", + "Flex::new().with_align(Align::End)", ), ( "flex_title_align_stretch", flex::Align::Stretch, - "Flex::row().with_align(Align::Stretch)", + "Flex::new().with_align(Align::Stretch)", ), ]; for (title_key, align, code) in align_variants { @@ -152,7 +152,7 @@ fn align_block() -> Block { .with_child(caption(Lc::t(title_key, &LOC), Lc::n(code))) .with_child( demo_row( - Flex::row() + Flex::new() .with_align(align) .with_gap(flex::Gap::Both(UnitValue::RelRem(0.5))), ) @@ -164,11 +164,11 @@ fn align_block() -> Block { block .with_child(caption( Lc::t("flex_title_align_baseline", &LOC), - Lc::n("Flex::row().with_align(Align::Baseline)"), + Lc::n("Flex::new().with_align(Align::Baseline)"), )) .with_child( demo_row( - Flex::row() + Flex::new() .with_align(flex::Align::Baseline) .with_gap(flex::Gap::Both(UnitValue::RelRem(0.5))), ) @@ -211,7 +211,7 @@ fn align_self_block() -> Block { .with_child(caption(Lc::t(title_key, &LOC), Lc::n(code))) .with_child( demo_row( - Flex::row() + Flex::new() .with_align(flex::Align::Start) .with_gap(flex::Gap::Both(UnitValue::RelRem(0.5))), ) @@ -229,7 +229,7 @@ fn align_self_block() -> Block { )) .with_child( demo_row( - Flex::row() + Flex::new() .with_align(flex::Align::Start) .with_gap(flex::Gap::Both(UnitValue::RelRem(0.5))), ) @@ -251,42 +251,42 @@ fn align_content_block() -> Block { ( "flex_title_align_content_start", flex::AlignContent::Start, - "Flex::row().with_wrap(Behavior::Wrap).with_align_content(AlignContent::Start)", + "Flex::new().with_wrap(Behavior::Wrap).with_align_content(AlignContent::Start)", ), ( "flex_title_align_content_end", flex::AlignContent::End, - "Flex::row().with_wrap(Behavior::Wrap).with_align_content(AlignContent::End)", + "Flex::new().with_wrap(Behavior::Wrap).with_align_content(AlignContent::End)", ), ( "flex_title_align_content_center", flex::AlignContent::Center, - "Flex::row().with_wrap(Behavior::Wrap).with_align_content(AlignContent::Center)", + "Flex::new().with_wrap(Behavior::Wrap).with_align_content(AlignContent::Center)", ), ( "flex_title_align_content_between", flex::AlignContent::SpaceBetween, - "Flex::row().with_wrap(Behavior::Wrap).with_align_content(AlignContent::SpaceBetween)", + "Flex::new().with_wrap(Behavior::Wrap).with_align_content(AlignContent::SpaceBetween)", ), ( "flex_title_align_content_around", flex::AlignContent::SpaceAround, - "Flex::row().with_wrap(Behavior::Wrap).with_align_content(AlignContent::SpaceAround)", + "Flex::new().with_wrap(Behavior::Wrap).with_align_content(AlignContent::SpaceAround)", ), ( "flex_title_align_content_evenly", flex::AlignContent::SpaceEvenly, - "Flex::row().with_wrap(Behavior::Wrap).with_align_content(AlignContent::SpaceEvenly)", + "Flex::new().with_wrap(Behavior::Wrap).with_align_content(AlignContent::SpaceEvenly)", ), ( "flex_title_align_content_stretch", flex::AlignContent::Stretch, - "Flex::row().with_wrap(Behavior::Wrap).with_align_content(AlignContent::Stretch)", + "Flex::new().with_wrap(Behavior::Wrap).with_align_content(AlignContent::Stretch)", ), ]; for (title_key, align_content, code) in align_content_variants { let mut row = demo_row( - Flex::row() + Flex::new() .with_wrap(flex::Behavior::Wrap) .with_align_content(align_content) .with_gap(flex::Gap::Both(UnitValue::RelRem(0.5))), @@ -314,7 +314,7 @@ fn grow_shrink_block() -> Block { Lc::n("FlexItem::new().with_grow(flex::ItemGrow::Is1)"), )) .with_child( - demo_row(Flex::row().with_gap(flex::Gap::Both(UnitValue::RelRem(0.5)))) + demo_row(Flex::new().with_gap(flex::Gap::Both(UnitValue::RelRem(0.5)))) .with_child(demo_box(Lc::t("flex_box_fixed", &LOC))) .with_child( demo_box(Lc::t("flex_box_grows", &LOC)).with_prop(PropsOp::flex_item( @@ -328,7 +328,7 @@ fn grow_shrink_block() -> Block { Lc::n("FlexItem::new().with_shrink(flex::ItemShrink::Is0)"), )) .with_child( - demo_row(Flex::row().with_gap(flex::Gap::Both(UnitValue::RelRem(0.5)))) + demo_row(Flex::new().with_gap(flex::Gap::Both(UnitValue::RelRem(0.5)))) .with_prop(PropsOp::add_style("max-width", "31rem")) .with_child( demo_box(flex_item("1")).with_prop(PropsOp::add_style("width", "10.5rem")), @@ -355,14 +355,16 @@ fn other_block() -> Block { Lc::n("FlexItem::push_end()"), )) .with_child( - demo_row(Flex::row().with_gap(flex::Gap::Both(UnitValue::RelRem(0.5)))) + demo_row(Flex::new().with_gap(flex::Gap::Both(UnitValue::RelRem(0.5)))) .with_child(demo_box(Lc::t("flex_box_start_1", &LOC))) .with_child(demo_box(Lc::t("flex_box_start_2", &LOC))) - .with_child(demo_box(Lc::t("flex_box_end", &LOC)).with_prop(FlexItem::push_end())), + .with_child( + demo_box(Lc::t("flex_box_end", &LOC)).with_prop(FlexItem::push_end().into()), + ), ); let mut wrap_row = demo_row( - Flex::row() + Flex::new() .with_wrap(flex::Behavior::Wrap) .with_align_content(flex::AlignContent::SpaceBetween) .with_gap(flex::Gap::Both(UnitValue::RelRem(0.5))), @@ -379,7 +381,7 @@ fn other_block() -> Block { .with_child(caption( Lc::t("flex_title_wrap", &LOC), Lc::n(concat!( - "Flex::row()", + "Flex::new()", ".with_wrap(Behavior::Wrap)", ".with_align_content(AlignContent::SpaceBetween)", )), @@ -390,7 +392,7 @@ fn other_block() -> Block { Lc::n("FlexItem::new().with_order(ItemOrder::First) / .with_order(ItemOrder::Last)"), )) .with_child( - demo_row(Flex::row().with_gap(flex::Gap::Both(UnitValue::RelRem(0.5)))) + demo_row(Flex::new().with_gap(flex::Gap::Both(UnitValue::RelRem(0.5)))) .with_child(demo_box(Lc::n("A")).with_prop(PropsOp::flex_item( FlexItem::new().with_order(flex::ItemOrder::Last), ))) @@ -403,20 +405,20 @@ fn other_block() -> Block { ) .with_child(caption( Lc::t("flex_title_gap_none", &LOC), - Lc::n("Flex::row() (Gap::None por defecto)"), + Lc::n("Flex::new() (Gap::None por defecto)"), )) .with_child( - demo_row(Flex::row()) + demo_row(Flex::new()) .with_child(demo_box(flex_item("1"))) .with_child(demo_box(flex_item("2"))) .with_child(demo_box(flex_item("3"))), ) .with_child(caption( Lc::t("flex_title_gap_some", &LOC), - Lc::n("Flex::row().with_gap(flex::Gap::Both(UnitValue::RelRem(1.5)))"), + Lc::n("Flex::new().with_gap(flex::Gap::Both(UnitValue::RelRem(1.5)))"), )) .with_child( - demo_row(Flex::row().with_gap(flex::Gap::Both(UnitValue::RelRem(1.5)))) + demo_row(Flex::new().with_gap(flex::Gap::Both(UnitValue::RelRem(1.5)))) .with_child(demo_box(flex_item("1"))) .with_child(demo_box(flex_item("2"))) .with_child(demo_box(flex_item("3"))), @@ -426,7 +428,7 @@ fn other_block() -> Block { Lc::n("FlexItem::new().with_size(flex::ItemSize::Percent33)"), )) .with_child( - demo_row(Flex::row()) + demo_row(Flex::new()) .with_child(demo_box(Lc::n("1/3")).with_prop(PropsOp::flex_item( FlexItem::new().with_size(flex::ItemSize::Percent33), ))) @@ -446,7 +448,7 @@ fn other_block() -> Block { )), )) .with_child( - demo_row(Flex::row()).with_child( + demo_row(Flex::new()).with_child( demo_box(Lc::t("flex_box_half_centered", &LOC)).with_prop(PropsOp::flex_item( FlexItem::new() .with_size(flex::ItemSize::Percent50) @@ -460,14 +462,16 @@ fn other_block() -> Block { )) .with_child( demo_row( - Flex::row() + Flex::new() .with_align(flex::Align::Center) .with_gap(flex::Gap::Both(UnitValue::RelRem(0.5))), ) .with_child(demo_box(Lc::t("flex_box_file", &LOC))) .with_child(demo_box(Lc::t("flex_box_edit", &LOC))) .with_child(demo_box(Lc::t("flex_box_view", &LOC))) - .with_child(demo_box(Lc::t("flex_box_profile", &LOC)).with_prop(FlexItem::push_end())) + .with_child( + demo_box(Lc::t("flex_box_profile", &LOC)).with_prop(FlexItem::push_end().into()), + ) .with_child(demo_box(Lc::t("flex_box_logout", &LOC))), ) } diff --git a/examples/intro-responsive.rs b/examples/intro-responsive.rs new file mode 100644 index 00000000..f01a7ebb --- /dev/null +++ b/examples/intro-responsive.rs @@ -0,0 +1,261 @@ +use pagetop::prelude::*; + +include_locales!(LOC from "examples/locale"); + +struct IntroResponsive; + +#[async_trait] +impl Extension for IntroResponsive { + fn dependencies(&self) -> Vec { + vec![&pagetop_bootsier::Bootsier] + } + + fn configure_router(&self, router: Router) -> Router { + router.route("/", web::get(intro_responsive)) + } +} + +async fn intro_responsive(request: HttpRequest) -> Result { + Page::new(request) + .with_assets(AssetsOp::AddStyleSheet(demo_styles())) + .with_child( + Intro::default() + .with_opening(IntroOpening::Custom) + .with_title(Lc::n("PageTop")) + .with_slogan(Lc::t("responsive_slogan", &LOC)) + .with_button(None::<(Lc, Route)>) + .with_child(Html::with(|cx| { + html! { + p class="intro-text-lead" { + (Lc::t("responsive_note", &LOC).using(cx)) + } + } + })) + .with_child(activation_block()) + .with_child(direction_block()) + .with_child(grid_block()) + .with_child(justify_align_block()) + .with_child(order_block()) + .with_child(gap_grow_block()), + ) + .render() + .await +} + +fn activation_block() -> Block { + Block::new() + .with_title(Lc::t("responsive_block_title_activation", &LOC)) + .with_child(caption( + Lc::t("responsive_title_activation", &LOC), + Lc::n("Flex::at(Breakpoint::Md)"), + )) + .with_child( + demo_row(Flex::at(Breakpoint::Md).with_gap(flex::Gap::Both(UnitValue::RelRem(0.5)))) + .with_child(demo_box(Lc::t("responsive_box_nav_home", &LOC))) + .with_child(demo_box(Lc::t("responsive_box_nav_products", &LOC))) + .with_child(demo_box(Lc::t("responsive_box_nav_about", &LOC))) + .with_child(demo_box(Lc::t("responsive_box_nav_contact", &LOC))), + ) +} + +fn direction_block() -> Block { + Block::new() + .with_title(Lc::t("responsive_block_title_direction", &LOC)) + .with_child(caption( + Lc::t("responsive_title_direction", &LOC), + Lc::n(concat!( + "Flex::new()", + ".with_direction(Direction::Column)", + ".with_direction_at(Breakpoint::Md, Direction::RowReverse)", + )), + )) + .with_child( + demo_row( + Flex::new() + .with_direction(flex::Direction::Column) + .with_direction_at(Breakpoint::Md, flex::Direction::RowReverse) + .with_gap(flex::Gap::Both(UnitValue::RelRem(0.5))), + ) + .with_child(sized_box( + Lc::t("responsive_box_image", &LOC), + "2.5rem 1rem", + )) + .with_child(demo_box(Lc::t("responsive_box_text", &LOC))), + ) +} + +fn grid_block() -> Block { + let mut row = demo_row(Flex::new().with_wrap(flex::Behavior::Wrap)); + for n in 1..=6 { + row = row.with_child( + Container::new() + .with_prop(PropsOp::add_style("padding", "0.25rem")) + .with_prop(PropsOp::flex_item( + FlexItem::new() + .with_size(flex::ItemSize::Percent100) + .with_size_at(Breakpoint::Sm, flex::ItemSize::Percent50) + .with_size_at(Breakpoint::Md, flex::ItemSize::Percent33), + )) + .with_child(demo_box(card_label(n))), + ); + } + Block::new() + .with_title(Lc::t("responsive_block_title_grid", &LOC)) + .with_child(caption( + Lc::t("responsive_title_grid", &LOC), + Lc::n(concat!( + "FlexItem::new()", + ".with_size(ItemSize::Percent100)", + ".with_size_at(Breakpoint::Sm, ItemSize::Percent50)", + ".with_size_at(Breakpoint::Md, ItemSize::Percent33)", + )), + )) + .with_child(row) +} + +fn justify_align_block() -> Block { + Block::new() + .with_title(Lc::t("responsive_block_title_justify_align", &LOC)) + .with_child(caption( + Lc::t("responsive_title_justify_align", &LOC), + Lc::n(concat!( + "Flex::new()", + ".with_justify(ContentJustify::Center)", + ".with_justify_at(Breakpoint::Md, ContentJustify::SpaceBetween)", + ".with_align(Align::Center)", + )), + )) + .with_child( + demo_row( + Flex::new() + .with_justify(flex::ContentJustify::Center) + .with_justify_at(Breakpoint::Md, flex::ContentJustify::SpaceBetween) + .with_align(flex::Align::Center) + .with_gap(flex::Gap::Both(UnitValue::RelRem(0.5))), + ) + .with_child(demo_box(Lc::t("responsive_box_logo", &LOC))) + .with_child(demo_box(Lc::t("responsive_box_menu", &LOC))), + ) +} + +fn order_block() -> Block { + Block::new() + .with_title(Lc::t("responsive_block_title_order", &LOC)) + .with_child(caption( + Lc::t("responsive_title_order", &LOC), + Lc::n(concat!( + "Flex::at(Breakpoint::Lg)", + " + FlexItem::new().with_order_at(Breakpoint::Lg, ItemOrder::First)", + )), + )) + .with_child( + demo_row(Flex::at(Breakpoint::Lg).with_gap(flex::Gap::Both(UnitValue::RelRem(0.5)))) + .with_child(demo_box(Lc::t("responsive_box_content", &LOC))) + .with_child(demo_box(Lc::t("responsive_box_sidebar", &LOC)).with_prop( + PropsOp::flex_item( + FlexItem::new().with_order_at(Breakpoint::Lg, flex::ItemOrder::First), + ), + )), + ) +} + +fn gap_grow_block() -> Block { + Block::new() + .with_title(Lc::t("responsive_block_title_gap_grow", &LOC)) + .with_child(caption( + Lc::t("responsive_title_gap_grow", &LOC), + Lc::n(concat!( + "Flex::new()", + ".with_gap(Gap::Both(RelRem(0.5)))", + ".with_gap_at(Breakpoint::Md, Gap::Both(RelRem(1.5)))", + " + FlexItem::new().with_grow_at(Breakpoint::Md, ItemGrow::Is1)", + )), + )) + .with_child( + demo_row( + Flex::new() + .with_gap(flex::Gap::Both(UnitValue::RelRem(0.5))) + .with_gap_at(Breakpoint::Md, flex::Gap::Both(UnitValue::RelRem(1.5))), + ) + .with_child(demo_box(Lc::t("responsive_box_file", &LOC))) + .with_child(demo_box(Lc::t("responsive_box_edit", &LOC))) + .with_child(demo_box(Lc::t("responsive_box_search", &LOC)).with_prop( + PropsOp::flex_item( + FlexItem::new().with_grow_at(Breakpoint::Md, flex::ItemGrow::Is1), + ), + )), + ) +} + +// **< HELPERS >************************************************************************************ + +// Aspecto fijo de las cajas y filas de muestra. +fn demo_styles() -> StyleSheet { + StyleSheet::inline("intro-responsive", |_| { + util::indoc!( + r#" + .flex-demo-box { + background-color: #0d6efd; + color: #fff; + min-width: 3rem; + width: auto; + max-width: none; + margin: 0; + border-radius: 0.375rem; + text-align: center; + } + .flex-demo-row { + background-color: #f1f3f5; + width: 100%; + max-width: none; + margin: 0 0 1.5rem; + padding: 0.75rem; + } + code { + overflow-wrap: anywhere; + } + "# + ) + .to_string() + }) +} + +// Caja con fondo azul y relleno vertical configurable, para mostrar diferencias de altura. +fn sized_box(label: Lc, padding: &'static str) -> Container { + Container::new() + .with_prop(PropsOp::add_classes("flex-demo-box")) + .with_prop(PropsOp::add_style("padding", padding)) + .with_child(Html::with(move |cx| html! { (label.using(cx)) })) +} + +// Caja con el relleno vertical estandar del resto de ejemplos. +fn demo_box(label: Lc) -> Container { + sized_box(label, "0.5rem 1rem") +} + +// Etiqueta "Tarjeta N" para las cajas de la rejilla responsive. +fn card_label(n: usize) -> Lc { + Lc::t("responsive_box_card", &LOC).with_arg("n", n.to_string()) +} + +// Fila de demostracion con fondo gris para visualizar los limites del propio contenedor flex. +fn demo_row(flex: Flex) -> Container { + Container::new() + .with_prop(PropsOp::add_classes("flex-demo-row")) + .with_flex(flex) +} + +// Titulo y fragmento de codigo que introducen cada demostracion. +fn caption(title: Lc, code: Lc) -> Html { + Html::with(move |cx| { + html! { + h3 { (title.using(cx)) } + p { code { (code.using(cx)) } } + } + }) +} + +#[pagetop::main] +async fn main() -> std::io::Result<()> { + Application::prepare(&IntroResponsive).await.run().await +} diff --git a/examples/locale/en-US/intro-responsive.ftl b/examples/locale/en-US/intro-responsive.ftl new file mode 100644 index 00000000..f12e6bb8 --- /dev/null +++ b/examples/locale/en-US/intro-responsive.ftl @@ -0,0 +1,36 @@ +responsive_slogan = Responsive behavior with Flex +responsive_note = Resize your browser window to see how the boxes below react. The breakpoints used are the usual Bootstrap ones: sm from 576px, md from 768px, lg from 992px. + +responsive_block_title_activation = Flex activation at a breakpoint +responsive_block_title_direction = Direction change +responsive_block_title_grid = Column grid +responsive_block_title_justify_align = Justify and align +responsive_block_title_order = Visual order +responsive_block_title_gap_grow = Spacing and growth + +responsive_title_activation = Stacked menu on mobile, in a row from md +responsive_title_direction = Image and text stacked on mobile; in a row, image on the right, from md +responsive_title_grid = From one column on mobile to three on desktop +responsive_title_justify_align = Centered header on mobile, spread out from md +responsive_title_order = Sidebar after the content on mobile, before it from lg +responsive_title_gap_grow = Growing spacing and a search box that only grows from md + +responsive_box_nav_home = Home +responsive_box_nav_products = Products +responsive_box_nav_about = About +responsive_box_nav_contact = Contact + +responsive_box_image = Image +responsive_box_text = Text + +responsive_box_card = Card { $n } + +responsive_box_logo = Logo +responsive_box_menu = Menu + +responsive_box_content = Content +responsive_box_sidebar = Sidebar + +responsive_box_file = File +responsive_box_edit = Edit +responsive_box_search = Search diff --git a/examples/locale/es-ES/intro-responsive.ftl b/examples/locale/es-ES/intro-responsive.ftl new file mode 100644 index 00000000..e7a8a0a6 --- /dev/null +++ b/examples/locale/es-ES/intro-responsive.ftl @@ -0,0 +1,36 @@ +responsive_slogan = Comportamiento responsive con Flex +responsive_note = Cambia el ancho de la ventana del navegador para ver cómo reaccionan las siguientes cajas. Los puntos de corte usados son los habituales de Bootstrap: sm a partir de 576px, md a partir de 768px, lg a partir de 992px. + +responsive_block_title_activation = Activación de Flex por punto de corte +responsive_block_title_direction = Cambio de dirección +responsive_block_title_grid = Rejilla de columnas +responsive_block_title_justify_align = Justificación y alineación +responsive_block_title_order = Orden visual +responsive_block_title_gap_grow = Espaciado y crecimiento + +responsive_title_activation = Menú apilado en móvil, en fila a partir de md +responsive_title_direction = Imagen y texto apilados en móvil; en fila, con la imagen a la derecha, a partir de md +responsive_title_grid = De una columna en móvil a tres en escritorio +responsive_title_justify_align = Cabecera centrada en móvil, distribuida a partir de md +responsive_title_order = Barra lateral después del contenido en móvil, antes a partir de lg +responsive_title_gap_grow = Espaciado creciente y buscador que sólo crece a partir de md + +responsive_box_nav_home = Inicio +responsive_box_nav_products = Productos +responsive_box_nav_about = Nosotros +responsive_box_nav_contact = Contacto + +responsive_box_image = Imagen +responsive_box_text = Texto + +responsive_box_card = Tarjeta { $n } + +responsive_box_logo = Logotipo +responsive_box_menu = Menú + +responsive_box_content = Contenido +responsive_box_sidebar = Barra lateral + +responsive_box_file = Archivo +responsive_box_edit = Editar +responsive_box_search = Buscador diff --git a/examples/navbar-menus.rs b/examples/navbar-menus.rs index eb2fecaf..cbaf0829 100644 --- a/examples/navbar-menus.rs +++ b/examples/navbar-menus.rs @@ -83,7 +83,7 @@ impl Extension for SuperMenu { .with_item(bs::navbar::Item::nav( bs::Nav::new() // Empuja este menú (y lo que le siga) al extremo final de la barra. - .with_prop(FlexItem::push_end()) + .with_prop(FlexItem::push_end().into()) .with_item(bs::nav::Item::link( Lc::t("menus_item_sign_up", &LOC), "/auth/sign-up", diff --git a/extensions/pagetop-user/src/handlers/admin/users.rs b/extensions/pagetop-user/src/handlers/admin/users.rs index a8edbb80..b77023c3 100644 --- a/extensions/pagetop-user/src/handlers/admin/users.rs +++ b/extensions/pagetop-user/src/handlers/admin/users.rs @@ -363,7 +363,7 @@ fn edit_actions( let mut container = Container::new() .with_flex( - Flex::row() + Flex::new() .with_wrap(flex::Behavior::Wrap) .with_align(flex::Align::Center) .with_gap(flex::Gap::Both(UnitValue::RelRem(0.5))), diff --git a/src/base/component/container.rs b/src/base/component/container.rs index 4fbce6c4..d5e6abd0 100644 --- a/src/base/component/container.rs +++ b/src/base/component/container.rs @@ -49,7 +49,7 @@ pub struct Container { kind: Kind, /// Devuelve el posicionamiento Flexbox como contenedor, si tiene alguno. #[getters(copy)] - flex: Option, + flex: Flex, /// Devuelve la lista de componentes (`children`) del contenedor. children: Children, } @@ -64,25 +64,20 @@ impl Component for Container { self.props.get_id() } - fn setup(&mut self, _cx: &mut Context) { - if let Some(flex) = self.flex() { - flex.apply_to(&mut self.props); - } - } - #[rustfmt::skip] async fn prepare(&self, cx: &mut Context) -> Result { let output = self.children().render(cx).await; if output.is_empty() { return Ok(html! {}); } + let container_props = self.props().unpack_with_flex(cx, self.flex()); Ok(match self.kind() { - Kind::Default => html! { div (self.props().unpack(cx)) { (output) } }, - Kind::Main => html! { main (self.props().unpack(cx)) { (output) } }, - Kind::Header => html! { header (self.props().unpack(cx)) { (output) } }, - Kind::Footer => html! { footer (self.props().unpack(cx)) { (output) } }, - Kind::Section => html! { section (self.props().unpack(cx)) { (output) } }, - Kind::Article => html! { article (self.props().unpack(cx)) { (output) } }, + Kind::Default => html! { div (container_props) { (output) } }, + Kind::Main => html! { main (container_props) { (output) } }, + Kind::Header => html! { header (container_props) { (output) } }, + Kind::Footer => html! { footer (container_props) { (output) } }, + Kind::Section => html! { section (container_props) { (output) } }, + Kind::Article => html! { article (container_props) { (output) } }, }) } } @@ -145,7 +140,7 @@ impl Container { /// Establece el posicionamiento Flexbox como contenedor (usa `None` para quitarlo). pub fn with_flex(mut self, flex: impl Into>) -> Self { - self.flex = flex.into(); + self.flex = self.flex.merge(flex); self } diff --git a/src/base/component/navbar/component.rs b/src/base/component/navbar/component.rs index 7ba5cb99..42a2ba6e 100644 --- a/src/base/component/navbar/component.rs +++ b/src/base/component/navbar/component.rs @@ -83,7 +83,7 @@ pub struct Navbar { layout: navbar::Layout, /// Devuelve el posicionamiento Flexbox como contenedor, si tiene alguno. #[getters(copy)] - flex: Option, + flex: Flex, /// Devuelve la lista de contenidos. items: Children, } @@ -106,21 +106,6 @@ impl Component for Navbar { } async fn prepare(&self, cx: &mut Context) -> Result { - // Botón de despliegue para el contenido colapsable de la barra. - fn button(cx: &mut Context, id_content: &str) -> Markup { - html! { - button - type="button" - class="navbar-toggle" - aria-expanded="false" - aria-controls=(id_content) - aria-label=[Lc::l("navbar_toggle").lookup(cx)] - { - span class="navbar-toggle-icon" {} - } - } - } - // Si no hay contenidos, no tiene sentido mostrar una barra vacía. let items = self.items().render(cx).await; if items.is_empty() { @@ -131,44 +116,53 @@ impl Component for Navbar { let id = self.id().unwrap(); let id_content = util::join!(id, "-content"); + // Botón de despliegue para el contenido colapsable de la barra. + let button = html! { + button + type="button" + class="navbar-toggle" + aria-expanded="false" + aria-controls=(&id_content) + aria-label=[Lc::l("navbar_toggle").lookup(cx)] + { + span class="navbar-toggle-icon" {} + } + }; + // Posicionamiento Flexbox opcional (no del `