544 lines
20 KiB
Rust
544 lines
20 KiB
Rust
use pagetop::prelude::*;
|
|
|
|
include_locales!(LOC from "examples/locale");
|
|
|
|
struct IntroGrid;
|
|
|
|
#[async_trait]
|
|
impl Extension for IntroGrid {
|
|
fn dependencies(&self) -> Vec<ExtensionRef> {
|
|
vec![&pagetop_bootsier::Bootsier]
|
|
}
|
|
|
|
fn configure_router(&self, router: Router) -> Router {
|
|
router.route("/", web::get(intro_grid))
|
|
}
|
|
}
|
|
|
|
async fn intro_grid(request: HttpRequest) -> Result<Markup, ErrorPage> {
|
|
Page::new(request)
|
|
.with_assets(demo_box_styles())
|
|
.with_assets(demo_row_styles())
|
|
.with_child(
|
|
Intro::default()
|
|
.with_opening(IntroOpening::Custom)
|
|
.with_title(Lc::n("PageTop"))
|
|
.with_slogan(Lc::t("grid_slogan", &LOC))
|
|
.with_button(None::<(Lc, Route)>)
|
|
.with_child(columns_block())
|
|
.with_child(rows_gap_block())
|
|
.with_child(placement_block())
|
|
.with_child(alignment_block())
|
|
.with_child(content_alignment_block())
|
|
.with_child(item_alignment_block())
|
|
.with_child(auto_flow_block())
|
|
.with_child(auto_tracks_block())
|
|
.with_child(responsive_block())
|
|
.with_child(layout_block()),
|
|
)
|
|
.render()
|
|
.await
|
|
}
|
|
|
|
fn columns_block() -> Block {
|
|
Block::new()
|
|
.with_title(Lc::t("grid_block_title_columns", &LOC))
|
|
.with_child(caption(
|
|
Lc::t("grid_title_columns_thirds", &LOC),
|
|
Lc::n("Grid::new().with_columns(Tracks::repeat(3, AxisTrack::Fraction(1.0)))"),
|
|
))
|
|
.with_child(
|
|
demo_grid(
|
|
Grid::new()
|
|
.with_columns(grid::Tracks::repeat(3, grid::AxisTrack::Fraction(1.0)))
|
|
.with_gap(align::Gap::Both(UnitValue::RelRem(0.5))),
|
|
)
|
|
.with_child(demo_box(grid_box("1")))
|
|
.with_child(demo_box(grid_box("2")))
|
|
.with_child(demo_box(grid_box("3"))),
|
|
)
|
|
.with_child(caption(
|
|
Lc::t("grid_title_columns_sidebar", &LOC),
|
|
Lc::n(concat!(
|
|
"Grid::new().with_columns(Tracks::new()",
|
|
".with_track(AxisTrack::Fixed(UnitValue::Px(140)))",
|
|
".with_track(AxisTrack::Fraction(1.0)))",
|
|
)),
|
|
))
|
|
.with_child(
|
|
demo_grid(
|
|
Grid::new()
|
|
.with_columns(
|
|
grid::Tracks::new()
|
|
.with_track(grid::AxisTrack::Fixed(UnitValue::Px(140)))
|
|
.with_track(grid::AxisTrack::Fraction(1.0)),
|
|
)
|
|
.with_gap(align::Gap::Both(UnitValue::RelRem(0.5))),
|
|
)
|
|
.with_child(demo_box(Lc::t("grid_box_sidebar", &LOC)))
|
|
.with_child(demo_box(Lc::t("grid_box_content", &LOC))),
|
|
)
|
|
.with_child(caption(
|
|
Lc::t("grid_title_columns_min_max", &LOC),
|
|
Lc::n(concat!(
|
|
"Grid::new().with_columns(Tracks::new()",
|
|
".with_track(AxisTrack::MinContent)",
|
|
".with_track(AxisTrack::Fraction(1.0))",
|
|
".with_track(AxisTrack::MaxContent))",
|
|
)),
|
|
))
|
|
.with_child(
|
|
demo_grid(
|
|
Grid::new()
|
|
.with_columns(
|
|
grid::Tracks::new()
|
|
.with_track(grid::AxisTrack::MinContent)
|
|
.with_track(grid::AxisTrack::Fraction(1.0))
|
|
.with_track(grid::AxisTrack::MaxContent),
|
|
)
|
|
.with_gap(align::Gap::Both(UnitValue::RelRem(0.5))),
|
|
)
|
|
.with_child(demo_box(Lc::t("grid_box_min_content", &LOC)))
|
|
.with_child(demo_box(Lc::t("grid_box_fraction", &LOC)))
|
|
.with_child(demo_box(Lc::t("grid_box_max_content", &LOC))),
|
|
)
|
|
}
|
|
|
|
fn rows_gap_block() -> Block {
|
|
Block::new()
|
|
.with_title(Lc::t("grid_block_title_rows_gap", &LOC))
|
|
.with_child(caption(
|
|
Lc::t("grid_title_rows", &LOC),
|
|
Lc::n(concat!(
|
|
"Grid::new()",
|
|
".with_columns(Tracks::repeat(2, AxisTrack::Fraction(1.0)))",
|
|
".with_rows(Tracks::repeat(2, AxisTrack::Fixed(UnitValue::RelRem(3.0))))",
|
|
)),
|
|
))
|
|
.with_child(
|
|
demo_grid(
|
|
Grid::new()
|
|
.with_columns(grid::Tracks::repeat(2, grid::AxisTrack::Fraction(1.0)))
|
|
.with_rows(grid::Tracks::repeat(
|
|
2,
|
|
grid::AxisTrack::Fixed(UnitValue::RelRem(3.0)),
|
|
))
|
|
.with_gap(align::Gap::Both(UnitValue::RelRem(0.5))),
|
|
)
|
|
.with_child(demo_box(grid_box("1")))
|
|
.with_child(demo_box(grid_box("2")))
|
|
.with_child(demo_box(grid_box("3")))
|
|
.with_child(demo_box(grid_box("4"))),
|
|
)
|
|
.with_child(caption(
|
|
Lc::t("grid_title_gap_distinct", &LOC),
|
|
Lc::n(concat!(
|
|
"Grid::new().with_gap(align::Gap::Distinct {",
|
|
" row: UnitValue::RelRem(1.5), column: UnitValue::RelRem(0.25) })",
|
|
)),
|
|
))
|
|
.with_child(
|
|
demo_grid(
|
|
Grid::new()
|
|
.with_columns(grid::Tracks::repeat(3, grid::AxisTrack::Fraction(1.0)))
|
|
.with_gap(align::Gap::Distinct {
|
|
row: UnitValue::RelRem(1.5),
|
|
column: UnitValue::RelRem(0.25),
|
|
}),
|
|
)
|
|
.with_child(demo_box(grid_box("1")))
|
|
.with_child(demo_box(grid_box("2")))
|
|
.with_child(demo_box(grid_box("3")))
|
|
.with_child(demo_box(grid_box("4")))
|
|
.with_child(demo_box(grid_box("5")))
|
|
.with_child(demo_box(grid_box("6"))),
|
|
)
|
|
}
|
|
|
|
fn placement_block() -> Block {
|
|
Block::new()
|
|
.with_title(Lc::t("grid_block_title_placement", &LOC))
|
|
.with_child(caption(
|
|
Lc::t("grid_title_placement", &LOC),
|
|
Lc::n(concat!(
|
|
"GridItem::new().with_column(ItemPlacement::Span(2))",
|
|
" / .with_column(ItemPlacement::Range(2, 4))",
|
|
)),
|
|
))
|
|
.with_child(
|
|
demo_grid(
|
|
Grid::new()
|
|
.with_columns(grid::Tracks::repeat(4, grid::AxisTrack::Fraction(1.0)))
|
|
.with_gap(align::Gap::Both(UnitValue::RelRem(0.5))),
|
|
)
|
|
.with_child(demo_box(Lc::t("grid_box_plain", &LOC)))
|
|
.with_child(
|
|
demo_box(Lc::t("grid_box_span_2", &LOC))
|
|
.with_prop(GridItem::new().with_column(grid::ItemPlacement::Span(2))),
|
|
)
|
|
.with_child(demo_box(Lc::t("grid_box_plain", &LOC)))
|
|
.with_child(
|
|
demo_box(Lc::t("grid_box_range", &LOC)).with_prop(
|
|
GridItem::new()
|
|
.with_column(grid::ItemPlacement::Range(2, 4))
|
|
.with_row(grid::ItemPlacement::Line(2)),
|
|
),
|
|
),
|
|
)
|
|
}
|
|
|
|
fn alignment_block() -> Block {
|
|
let mut block = Block::new().with_title(Lc::t("grid_block_title_alignment", &LOC));
|
|
|
|
let variants: [(&str, grid::DefaultJustify, align::Items, &str); 4] = [
|
|
(
|
|
"grid_title_alignment_start",
|
|
grid::DefaultJustify::Start,
|
|
align::Items::Start,
|
|
concat!(
|
|
"Grid::new().with_justify_items(DefaultJustify::Start)",
|
|
".with_align_items(align::Items::Start)",
|
|
),
|
|
),
|
|
(
|
|
"grid_title_alignment_center",
|
|
grid::DefaultJustify::Center,
|
|
align::Items::Center,
|
|
concat!(
|
|
"Grid::new().with_justify_items(DefaultJustify::Center)",
|
|
".with_align_items(align::Items::Center)",
|
|
),
|
|
),
|
|
(
|
|
"grid_title_alignment_end",
|
|
grid::DefaultJustify::End,
|
|
align::Items::End,
|
|
concat!(
|
|
"Grid::new().with_justify_items(DefaultJustify::End)",
|
|
".with_align_items(align::Items::End)",
|
|
),
|
|
),
|
|
(
|
|
"grid_title_alignment_stretch",
|
|
grid::DefaultJustify::Stretch,
|
|
align::Items::Stretch,
|
|
concat!(
|
|
"Grid::new().with_justify_items(DefaultJustify::Stretch)",
|
|
".with_align_items(align::Items::Stretch)",
|
|
),
|
|
),
|
|
];
|
|
for (title_key, justify_items, align_items, code) in variants {
|
|
block = block
|
|
.with_child(caption(Lc::t(title_key, &LOC), Lc::n(code)))
|
|
.with_child(
|
|
demo_grid(
|
|
Grid::new()
|
|
.with_columns(grid::Tracks::repeat(
|
|
3,
|
|
grid::AxisTrack::Fixed(UnitValue::Px(96)),
|
|
))
|
|
.with_rows(grid::Tracks::repeat(
|
|
1,
|
|
grid::AxisTrack::Fixed(UnitValue::RelRem(4.5)),
|
|
))
|
|
.with_justify_items(justify_items)
|
|
.with_align_items(align_items)
|
|
.with_gap(align::Gap::Both(UnitValue::RelRem(0.5))),
|
|
)
|
|
.with_child(demo_box(grid_box("1")))
|
|
.with_child(demo_box(grid_box("2")))
|
|
.with_child(demo_box(grid_box("3"))),
|
|
);
|
|
}
|
|
block
|
|
}
|
|
|
|
fn content_alignment_block() -> Block {
|
|
let mut block = Block::new().with_title(Lc::t("grid_block_title_content_alignment", &LOC));
|
|
|
|
let variants: [(&str, grid::ContentJustify, &str); 4] = [
|
|
(
|
|
"grid_title_content_alignment_start",
|
|
grid::ContentJustify::Start,
|
|
"Grid::new().with_justify_content(ContentJustify::Start)",
|
|
),
|
|
(
|
|
"grid_title_content_alignment_center",
|
|
grid::ContentJustify::Center,
|
|
"Grid::new().with_justify_content(ContentJustify::Center)",
|
|
),
|
|
(
|
|
"grid_title_content_alignment_between",
|
|
grid::ContentJustify::SpaceBetween,
|
|
"Grid::new().with_justify_content(ContentJustify::SpaceBetween)",
|
|
),
|
|
(
|
|
"grid_title_content_alignment_evenly",
|
|
grid::ContentJustify::SpaceEvenly,
|
|
"Grid::new().with_justify_content(ContentJustify::SpaceEvenly)",
|
|
),
|
|
];
|
|
for (title_key, justify_content, code) in variants {
|
|
block = block
|
|
.with_child(caption(Lc::t(title_key, &LOC), Lc::n(code)))
|
|
.with_child(
|
|
demo_grid(
|
|
Grid::new()
|
|
.with_columns(grid::Tracks::repeat(
|
|
3,
|
|
grid::AxisTrack::Fixed(UnitValue::Px(72)),
|
|
))
|
|
.with_justify_content(justify_content)
|
|
.with_gap(align::Gap::Both(UnitValue::RelRem(0.5))),
|
|
)
|
|
.with_prop(PropsOp::add_style("max-width", "26rem"))
|
|
.with_child(demo_box(grid_box("1")))
|
|
.with_child(demo_box(grid_box("2")))
|
|
.with_child(demo_box(grid_box("3"))),
|
|
);
|
|
}
|
|
block
|
|
}
|
|
|
|
fn item_alignment_block() -> Block {
|
|
Block::new()
|
|
.with_title(Lc::t("grid_block_title_item_alignment", &LOC))
|
|
.with_child(caption(
|
|
Lc::t("grid_title_item_alignment", &LOC),
|
|
Lc::n(concat!(
|
|
"GridItem::new()",
|
|
".with_justify_self(ItemJustify::End)",
|
|
".with_align_self(align::ItemSelf::End)",
|
|
)),
|
|
))
|
|
.with_child(
|
|
demo_grid(
|
|
Grid::new()
|
|
.with_columns(grid::Tracks::repeat(
|
|
3,
|
|
grid::AxisTrack::Fixed(UnitValue::Px(96)),
|
|
))
|
|
.with_rows(grid::Tracks::repeat(
|
|
1,
|
|
grid::AxisTrack::Fixed(UnitValue::RelRem(4.5)),
|
|
))
|
|
.with_gap(align::Gap::Both(UnitValue::RelRem(0.5))),
|
|
)
|
|
.with_child(demo_box(grid_box("1")))
|
|
.with_child(
|
|
demo_box(Lc::t("grid_box_overridden", &LOC)).with_prop(
|
|
GridItem::new()
|
|
.with_justify_self(grid::ItemJustify::End)
|
|
.with_align_self(align::ItemSelf::End),
|
|
),
|
|
)
|
|
.with_child(demo_box(grid_box("3"))),
|
|
)
|
|
}
|
|
|
|
fn auto_flow_block() -> Block {
|
|
Block::new()
|
|
.with_title(Lc::t("grid_block_title_auto_flow", &LOC))
|
|
.with_child(caption(
|
|
Lc::t("grid_title_auto_flow_row", &LOC),
|
|
Lc::n("Grid::new().with_auto_flow(AutoFlow::Row) (por defecto)"),
|
|
))
|
|
.with_child(dense_demo(grid::AutoFlow::Row))
|
|
.with_child(caption(
|
|
Lc::t("grid_title_auto_flow_dense", &LOC),
|
|
Lc::n("Grid::new().with_auto_flow(AutoFlow::RowDense)"),
|
|
))
|
|
.with_child(dense_demo(grid::AutoFlow::RowDense))
|
|
}
|
|
|
|
fn dense_demo(auto_flow: grid::AutoFlow) -> Grid {
|
|
demo_grid(
|
|
Grid::new()
|
|
.with_columns(grid::Tracks::repeat(4, grid::AxisTrack::Fraction(1.0)))
|
|
.with_auto_flow(auto_flow)
|
|
.with_gap(align::Gap::Both(UnitValue::RelRem(0.5))),
|
|
)
|
|
.with_child(
|
|
demo_box(Lc::t("grid_box_span_2", &LOC))
|
|
.with_prop(GridItem::new().with_column(grid::ItemPlacement::Span(2))),
|
|
)
|
|
.with_child(
|
|
demo_box(Lc::t("grid_box_span_2", &LOC))
|
|
.with_prop(GridItem::new().with_column(grid::ItemPlacement::Span(2))),
|
|
)
|
|
.with_child(demo_box(grid_box("1")))
|
|
.with_child(demo_box(grid_box("2")))
|
|
.with_child(demo_box(grid_box("3")))
|
|
}
|
|
|
|
fn auto_tracks_block() -> Block {
|
|
Block::new()
|
|
.with_title(Lc::t("grid_block_title_auto_tracks", &LOC))
|
|
.with_child(caption(
|
|
Lc::t("grid_title_auto_tracks", &LOC),
|
|
Lc::n(concat!(
|
|
"Grid::new()",
|
|
".with_columns(Tracks::repeat(3, AxisTrack::Fraction(1.0)))",
|
|
".with_auto_rows(AxisTrack::Fixed(UnitValue::RelRem(3.0)))",
|
|
)),
|
|
))
|
|
.with_child(
|
|
demo_grid(
|
|
Grid::new()
|
|
.with_columns(grid::Tracks::repeat(3, grid::AxisTrack::Fraction(1.0)))
|
|
.with_auto_rows(grid::AxisTrack::Fixed(UnitValue::RelRem(3.0)))
|
|
.with_gap(align::Gap::Both(UnitValue::RelRem(0.5))),
|
|
)
|
|
.with_child(demo_box(grid_box("1")))
|
|
.with_child(demo_box(grid_box("2")))
|
|
.with_child(demo_box(grid_box("3")))
|
|
.with_child(demo_box(grid_box("4")))
|
|
.with_child(demo_box(grid_box("5")))
|
|
.with_child(demo_box(grid_box("6"))),
|
|
)
|
|
}
|
|
|
|
fn responsive_block() -> Block {
|
|
let mut row = demo_grid(
|
|
Grid::new()
|
|
.with_columns(grid::Tracks::repeat(1, grid::AxisTrack::Fraction(1.0)))
|
|
.with_columns_at(
|
|
Breakpoint::Sm,
|
|
grid::Tracks::repeat(2, grid::AxisTrack::Fraction(1.0)),
|
|
)
|
|
.with_columns_at(
|
|
Breakpoint::Md,
|
|
grid::Tracks::repeat(3, grid::AxisTrack::Fraction(1.0)),
|
|
)
|
|
.with_gap(align::Gap::Both(UnitValue::RelRem(0.5))),
|
|
);
|
|
for n in 1..=6 {
|
|
row = row.with_child(demo_box(card_label(n)));
|
|
}
|
|
Block::new()
|
|
.with_title(Lc::t("grid_block_title_responsive", &LOC))
|
|
.with_child(caption(
|
|
Lc::t("grid_title_responsive", &LOC),
|
|
Lc::n(concat!(
|
|
"Grid::new()",
|
|
".with_columns(Tracks::repeat(1, AxisTrack::Fraction(1.0)))",
|
|
".with_columns_at(Breakpoint::Sm, Tracks::repeat(2, AxisTrack::Fraction(1.0)))",
|
|
".with_columns_at(Breakpoint::Md, Tracks::repeat(3, AxisTrack::Fraction(1.0)))",
|
|
)),
|
|
))
|
|
.with_child(row)
|
|
}
|
|
|
|
fn layout_block() -> Block {
|
|
Block::new()
|
|
.with_title(Lc::t("grid_block_title_layout", &LOC))
|
|
.with_child(caption(
|
|
Lc::t("grid_title_layout", &LOC),
|
|
Lc::t("grid_desc_layout", &LOC),
|
|
))
|
|
.with_child(
|
|
demo_grid(
|
|
Grid::new()
|
|
.with_columns(
|
|
grid::Tracks::new()
|
|
.with_track(grid::AxisTrack::Fixed(UnitValue::Px(120)))
|
|
.with_track(grid::AxisTrack::Fraction(1.0))
|
|
.with_track(grid::AxisTrack::Fixed(UnitValue::Px(120))),
|
|
)
|
|
.with_rows(
|
|
grid::Tracks::new()
|
|
.with_track(grid::AxisTrack::Auto)
|
|
.with_track(grid::AxisTrack::Fraction(1.0))
|
|
.with_track(grid::AxisTrack::Auto),
|
|
)
|
|
.with_gap(align::Gap::Both(UnitValue::RelRem(0.5))),
|
|
)
|
|
.with_prop(PropsOp::add_style("min-height", "18rem"))
|
|
.with_child(
|
|
demo_box(Lc::t("grid_box_header", &LOC))
|
|
.with_prop(GridItem::new().with_column(grid::ItemPlacement::Span(3))),
|
|
)
|
|
.with_child(demo_box(Lc::t("grid_box_nav", &LOC)))
|
|
.with_child(demo_box(Lc::t("grid_box_content", &LOC)))
|
|
.with_child(demo_box(Lc::t("grid_box_aside", &LOC)))
|
|
.with_child(
|
|
demo_box(Lc::t("grid_box_footer", &LOC))
|
|
.with_prop(GridItem::new().with_column(grid::ItemPlacement::Span(3))),
|
|
),
|
|
)
|
|
}
|
|
|
|
// **< HELPERS >************************************************************************************
|
|
|
|
// Aspecto fijo de las cajas de muestra: esquinas rectas y borde claro, a diferencia de las cajas
|
|
// redondeadas de `intro-flex.rs`, para distinguir a simple vista los ejemplos de Grid de los de Flex.
|
|
fn demo_box_styles() -> AssetsOp {
|
|
AssetsOp::add_responsive_styles(
|
|
None,
|
|
"grid-demo-box",
|
|
[
|
|
("background-color", "#0d6efd"),
|
|
("color", "#fff"),
|
|
("border", "2px solid #6ea8fe"),
|
|
("min-width", "3rem"),
|
|
("width", "auto"),
|
|
("max-width", "none"),
|
|
("margin", "0"),
|
|
("text-align", "center"),
|
|
],
|
|
)
|
|
}
|
|
|
|
// Aspecto fijo de las filas de muestra.
|
|
fn demo_row_styles() -> AssetsOp {
|
|
AssetsOp::add_responsive_styles(
|
|
None,
|
|
"grid-demo-row",
|
|
[
|
|
("background-color", "#f1f3f5"),
|
|
("width", "100%"),
|
|
("max-width", "none"),
|
|
("margin", "0 0 1.5rem"),
|
|
("padding", "0.75rem"),
|
|
],
|
|
)
|
|
}
|
|
|
|
// Caja con el relleno vertical estandar del resto de ejemplos.
|
|
fn demo_box(label: Lc) -> Container {
|
|
Container::new()
|
|
.with_prop(PropsOp::add_classes("grid-demo-box"))
|
|
.with_prop(PropsOp::add_style("padding", "0.5rem 1rem"))
|
|
.with_child(Html::with(move |cx| html! { (label.using(cx)) }))
|
|
}
|
|
|
|
// Etiqueta "Box N" para las cajas que sólo se distinguen por su posición.
|
|
fn grid_box(n: impl Into<CowStr>) -> Lc {
|
|
Lc::t("grid_box_label", &LOC).with_arg("n", n)
|
|
}
|
|
|
|
// Etiqueta "Tarjeta N" para las cajas de la rejilla responsive.
|
|
fn card_label(n: usize) -> Lc {
|
|
Lc::t("grid_box_card", &LOC).with_arg("n", n.to_string())
|
|
}
|
|
|
|
// Rejilla de demostracion con fondo gris para visualizar los limites del propio contenedor grid.
|
|
fn demo_grid(grid: Grid) -> Grid {
|
|
grid.with_prop(PropsOp::add_classes("grid-demo-row"))
|
|
}
|
|
|
|
// 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(&IntroGrid).await.run().await
|
|
}
|