Compare commits

..

3 commits

10 changed files with 160 additions and 57 deletions

80
examples/intro-colors.rs Normal file
View file

@ -0,0 +1,80 @@
use pagetop::prelude::*;
struct IntroColors;
impl Extension for IntroColors {
fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {
scfg.route("/", service::web::get().to(intro_colors));
}
}
async fn intro_colors(request: HttpRequest) -> ResultPage<Markup, ErrorPage> {
Page::new(request)
.with_child(
Intro::default()
.with_opening(IntroOpening::Custom)
.with_title(L10n::n("PageTop"))
.with_slogan(L10n::l("sample_colors_slogan"))
.with_button(None::<(L10n, FnPathByContext)>)
.with_child(
Block::new()
.with_title(L10n::l("sample_colors_block").with_arg("n", "1"))
.with_child(Html::with(|cx| {
html! {
p { (L10n::l("sample_colors_val_1").using(cx)) }
}
})),
)
.with_child(
Block::new()
.with_title(L10n::l("sample_colors_block").with_arg("n", "2"))
.with_child(Html::with(|cx| {
html! {
p { (L10n::l("sample_colors_val_2").using(cx)) }
}
})),
)
.with_child(
Block::new()
.with_title(L10n::l("sample_colors_block").with_arg("n", "3"))
.with_child(Html::with(|cx| {
html! {
p { (L10n::l("sample_colors_val_3").using(cx)) }
}
})),
)
.with_child(
Block::new()
.with_title(L10n::l("sample_colors_block").with_arg("n", "4"))
.with_child(Html::with(|cx| {
html! {
p { (L10n::l("sample_colors_val_4").using(cx)) }
}
})),
)
.with_child(
Block::new()
.with_title(L10n::l("sample_colors_block").with_arg("n", "5"))
.with_child(Html::with(|cx| {
html! {
p { (L10n::l("sample_colors_val_5").using(cx)) }
}
})),
)
.with_child(
Block::new()
.with_title(L10n::l("sample_colors_block").with_arg("n", "6"))
.with_child(Html::with(|cx| {
html! {
p { (L10n::l("sample_colors_val_6").using(cx)) }
}
})),
),
)
.render()
}
#[pagetop::main]
async fn main() -> std::io::Result<()> {
Application::prepare(&IntroColors).run()?.await
}

View file

@ -29,12 +29,14 @@ h1, h2, h3, h4,h5, h6, p {
} }
*::before, *::after { *::before, *::after {
background: #faa;
border-radius: 3px; border-radius: 3px;
font: normal normal 400 10px/1.2 monospace; font: normal normal 400 10px/1.2 monospace;
vertical-align: middle; vertical-align: middle;
padding: 1px 3px; padding: 1px 3px;
margin: 0 3px; margin: 0 3px;
background: #faa;
color: #fff;
-webkit-text-fill-color: currentColor;
} }
*::before { *::before {
content: "("; content: "(";

View file

@ -366,8 +366,8 @@ pub fn builder_fn(_: TokenStream, item: TokenStream) -> TokenStream {
alter_name_str alter_name_str
); );
let with_alter_doc = concat!( let with_alter_doc = concat!(
"Permite modificar la instancia actual (`&mut self`) con los mismos argumentos, ", "Permite modificar la instancia (`&mut self`) con los mismos argumentos ",
"sin consumirla." "pero sin consumirla."
); );
// Atributos completos que se aplican siempre a `with_...()`. // Atributos completos que se aplican siempre a `with_...()`.

View file

@ -187,10 +187,10 @@ impl<C: Component> Embed<C> {
/// } /// }
/// }; // El *guard* se libera aquí, antes del *drop* de `embed`. /// }; // El *guard* se libera aquí, antes del *drop* de `embed`.
/// ///
/// let embed = Embed::with(Block::new().with_title(L10n::n("Título"))); /// let embed = Embed::with(Block::new().with_title(L10n::n("Title")));
/// { /// {
/// if let Some(mut component) = embed.get() { /// if let Some(mut component) = embed.get() {
/// component.alter_title(L10n::n("Nuevo título")); /// component.alter_title(L10n::n("New Title"));
/// } /// }
/// }; // El *guard* se libera aquí, antes del *drop* de `embed`. /// }; // El *guard* se libera aquí, antes del *drop* de `embed`.
/// ``` /// ```

View file

@ -385,8 +385,7 @@ impl Context {
/// Con `parts = 1` se usa el nombre corto del tipo. Si `parts` es `0` o supera el número de /// Con `parts = 1` se usa el nombre corto del tipo. Si `parts` es `0` o supera el número de
/// segmentos del *path*, entonces se usará el *path* completo. /// segmentos del *path*, entonces se usará el *path* completo.
/// ///
/// Es útil para asignar identificadores HTML predecibles cuando el componente no recibe uno /// Es útil para asignar identificadores HTML cuando el componente no recibe uno explícito.
/// explícito.
pub fn required_id<C: Component>(&self, id: Option<String>, parts: usize) -> String { pub fn required_id<C: Component>(&self, id: Option<String>, parts: usize) -> String {
if let Some(id) = id { if let Some(id) = id {
return id; return id;

View file

@ -31,7 +31,7 @@ pub enum MessageLevel {
/// let info = StatusMessage::new(MessageLevel::Info, L10n::l("saved-successfully")); /// let info = StatusMessage::new(MessageLevel::Info, L10n::l("saved-successfully"));
/// ///
/// // Aviso con texto literal sin traducción. /// // Aviso con texto literal sin traducción.
/// let warn = StatusMessage::new(MessageLevel::Warning, L10n::n("Formulario incompleto.")); /// let warn = StatusMessage::new(MessageLevel::Warning, L10n::n("Incomplete form."));
/// ``` /// ```
#[derive(Debug, Getters)] #[derive(Debug, Getters)]
pub struct StatusMessage { pub struct StatusMessage {

View file

@ -1,3 +1,13 @@
# intro-colors.rs
sample_colors_slogan = Chromatic intro test
sample_colors_block = Block { $n } — intro-bg-block-{ $n }
sample_colors_val_1 = Background color: <code style="color: #8b2500">#FFB84B</code> — Amber gold.
sample_colors_val_2 = Background color: <code style="color: #8b2500">#FFC66F</code> — Light golden.
sample_colors_val_3 = Background color: <code style="color: #8b2500">#FFD493</code> — Pale golden.
sample_colors_val_4 = Background color: <code style="color: #8b2500">#FFE3B7</code> — Light peach.
sample_colors_val_5 = Background color: <code style="color: #8b2500">#FFF1DB</code> — Cream.
sample_colors_val_6 = Background color: <code style="color: #8b2500">#FFFFFF</code> — White.
# menus.rs # menus.rs
sample_menus_item_label = Label sample_menus_item_label = Label
sample_menus_item_link = Link sample_menus_item_link = Link

View file

@ -1,3 +1,13 @@
# intro-colors.rs
sample_colors_slogan = Prueba de intro cromática
sample_colors_block = Bloque { $n } — intro-bg-block-{ $n }
sample_colors_val_1 = Color de fondo: <code style="color: #8b2500">#FFB84B</code> — Ámbar dorado.
sample_colors_val_2 = Color de fondo: <code style="color: #8b2500">#FFC66F</code> — Dorado claro.
sample_colors_val_3 = Color de fondo: <code style="color: #8b2500">#FFD493</code> — Dorado pálido.
sample_colors_val_4 = Color de fondo: <code style="color: #8b2500">#FFE3B7</code> — Melocotón claro.
sample_colors_val_5 = Color de fondo: <code style="color: #8b2500">#FFF1DB</code> — Crema.
sample_colors_val_6 = Color de fondo: <code style="color: #8b2500">#FFFFFF</code> — Blanco.
# menus.rs # menus.rs
sample_menus_item_label = Etiqueta sample_menus_item_label = Etiqueta
sample_menus_item_link = Enlace sample_menus_item_link = Enlace

View file

@ -15,6 +15,10 @@
--val-color--text: #212529; --val-color--text: #212529;
} }
*, *::before, *::after {
box-sizing: border-box;
}
html { html {
scroll-behavior: smooth; scroll-behavior: smooth;
} }

View file

@ -3,15 +3,16 @@
--intro-bg-img-set: image-set(url('/img/intro-header.avif') type('image/avif'), url('/img/intro-header.webp') type('image/webp'), var(--intro-bg-img) type('image/jpeg')); --intro-bg-img-set: image-set(url('/img/intro-header.avif') type('image/avif'), url('/img/intro-header.webp') type('image/webp'), var(--intro-bg-img) type('image/jpeg'));
--intro-bg-img-sm: url('/img/intro-header-sm.jpg'); --intro-bg-img-sm: url('/img/intro-header-sm.jpg');
--intro-bg-img-sm-set: image-set(url('/img/intro-header-sm.avif') type('image/avif'), url('/img/intro-header-sm.webp') type('image/webp'), var(--intro-bg-img-sm) type('image/jpeg')); --intro-bg-img-sm-set: image-set(url('/img/intro-header-sm.avif') type('image/avif'), url('/img/intro-header-sm.webp') type('image/webp'), var(--intro-bg-img-sm) type('image/jpeg'));
--intro-bg-color: #8c5919; --intro-bg-color: #7a430e;
--intro-bg-block-1: #b689ff; --intro-bg-block-1: #ffb84b;
--intro-bg-block-2: #fecaca; --intro-bg-block-2: #ffc66f;
--intro-bg-block-3: #e6a9e2; --intro-bg-block-3: #ffd493;
--intro-bg-block-4: #ffedca; --intro-bg-block-4: #ffe3b7;
--intro-bg-block-5: #ffffff; --intro-bg-block-5: #fff1db;
--intro-bg-block-6: #ffffff;
--intro-color: #1a202c; --intro-color: #1a202c;
--intro-color-gray: #e4e4e7; --intro-color-gray: #e8e3da;
--intro-color-link: #1e4eae; --intro-color-link: #8b2500;
--intro-focus-outline: 2px solid var(--intro-color-link); --intro-focus-outline: 2px solid var(--intro-color-link);
--intro-focus-outline-offset: 2px; --intro-focus-outline-offset: 2px;
--intro-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); --intro-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
@ -102,7 +103,7 @@ body {
font-size: clamp(2.25rem, 1.3177rem + 3.9779vw, 6.5rem); font-size: clamp(2.25rem, 1.3177rem + 3.9779vw, 6.5rem);
font-style: normal; font-style: normal;
font-weight: 700; font-weight: 700;
line-height: 110%; line-height: 135%;
text-shadow: none; text-shadow: none;
} }
.intro-header__image { .intro-header__image {
@ -123,7 +124,7 @@ body {
background-image: var(--intro-bg-img-set); background-image: var(--intro-bg-img-set);
} }
.intro-header__title { .intro-header__title {
padding: 1.2rem 2rem 2.6rem 2rem; padding: 0 2rem 2.6rem 2rem;
} }
.intro-header__image { .intro-header__image {
justify-content: flex-end; justify-content: flex-end;
@ -140,10 +141,13 @@ body {
.intro-content { .intro-content {
height: auto; height: auto;
margin-top: 1.6rem; margin-top: 1.6rem;
width: 100%;
} }
.intro-content__body { .intro-content__body {
box-sizing: border-box; box-sizing: border-box;
max-width: 80rem; max-width: 80rem;
margin-left: auto;
margin-right: auto;
} }
.intro-content__body:before, .intro-content__body:before,
.intro-content__body:after { .intro-content__body:after {
@ -152,10 +156,10 @@ body {
left: 0; left: 0;
right: 0; right: 0;
background: linear-gradient(130deg, rgba(13, 44, 91, 0) 0%, #ddff95 77.4%); background: linear-gradient(130deg, rgba(13, 44, 91, 0) 0%, #ddff95 77.4%);
margin: 0 -10.375rem; margin: 0 -1.2rem;
filter: blur(2.75rem); filter: blur(2.75rem);
opacity: 0.8; opacity: 0.8;
inset: 11.75rem; inset: unset;
} }
.intro-content__body:before { .intro-content__body:before {
top: -1rem; top: -1rem;
@ -163,22 +167,22 @@ body {
.intro-content__body:after { .intro-content__body:after {
bottom: -1rem; bottom: -1rem;
} }
@media (max-width: 48rem) { @media (width <= 48rem) {
.intro-content__body { .intro-content__body {
margin-top: -9.8rem; margin-top: -9.8rem;
} }
.intro-content__body:before,
.intro-content__body:after {
inset: unset;
}
} }
@media (min-width: 64rem) { @media (width >= 64rem) {
.intro-content { .intro-content {
margin-top: 0; margin-top: 0;
} }
.intro-content__body { .intro-content__body {
margin-top: -5.7rem; margin-top: -5.7rem;
} }
.intro-content__body:before,
.intro-content__body:after {
inset: 11.75rem;
}
} }
.intro-button { .intro-button {
@ -307,7 +311,7 @@ body {
.intro-button__link:hover span { .intro-button__link:hover span {
animation-play-state: paused; animation-play-state: paused;
} }
@media (max-width: 48rem) { @media (width <= 48rem) {
.intro-header { .intro-header {
padding-bottom: 9rem;; padding-bottom: 9rem;;
} }
@ -321,7 +325,7 @@ body {
padding-top: .5rem; padding-top: .5rem;
} }
} }
@media (min-width: 48rem) { @media (width > 48rem) {
.intro-button { .intro-button {
position: absolute; position: absolute;
top: 0; top: 0;
@ -344,9 +348,6 @@ body {
box-sizing: border-box; box-sizing: border-box;
align-items: center; align-items: center;
text-align: left; text-align: left;
font-size: 1.3125rem;
font-weight: 400;
line-height: 1.5;
margin-bottom: 0; margin-bottom: 0;
background: #fff; background: #fff;
position: relative; position: relative;
@ -354,24 +355,19 @@ body {
.intro-text__children { .intro-text__children {
padding: 2.5rem 1.063rem 0.75rem; padding: 2.5rem 1.063rem 0.75rem;
overflow: hidden; overflow: hidden;
width: 100%;
} }
.intro-text__children p { .intro-text__children p {
width: 100%; width: 100%;
line-height: 150%; font-size: 1.5rem;
font-weight: 400;
font-size: 1.45rem;
margin: 0 0 1.5rem; margin: 0 0 1.5rem;
} }
@media (min-width: 48rem) { @media (width > 48rem) {
.intro-text {
font-size: 1.375rem;
line-height: 2rem;
}
.intro-button + .intro-text__children { .intro-button + .intro-text__children {
padding-top: 7rem; padding-top: 7rem;
} }
} }
@media (min-width: 64rem) { @media (width >= 64rem) {
.intro-header { .intro-header {
padding-bottom: 9rem;; padding-bottom: 9rem;;
} }
@ -399,7 +395,7 @@ body {
.intro-text__children .block__title span { .intro-text__children .block__title span {
display: inline-block; display: inline-block;
padding: 10px 30px 14px; padding: 10px 30px 14px;
margin: 30px 0 0 20px; margin: 30px 20px 0;
background: white; background: white;
border: 5px solid; border: 5px solid;
border-radius: 30px; border-radius: 30px;
@ -422,36 +418,41 @@ body {
} }
.intro-text__children .block__title:after { .intro-text__children .block__title:after {
content: ""; content: "";
height: 70rem; height: 120%;
position: absolute; position: absolute;
top: 42px; top: 42px;
left: -15%; left: -25%;
width: 130%; width: 150%;
z-index: -10; z-index: -10;
background: var(--intro-bg-block-1); background: var(--intro-bg-block-1);
transform: rotate(2deg); transform: rotate(2deg);
} }
.intro-text__children .block:nth-of-type(5n+1) .block__title:after { .intro-text__children .block:nth-of-type(6n+1) .block__title:after {
background: var(--intro-bg-block-1); background: var(--intro-bg-block-1);
} }
.intro-text__children .block:nth-of-type(5n+2) .block__title:after { .intro-text__children .block:nth-of-type(6n+2) .block__title:after {
background: var(--intro-bg-block-2); background: var(--intro-bg-block-2);
} }
.intro-text__children .block:nth-of-type(5n+3) .block__title:after { .intro-text__children .block:nth-of-type(6n+3) .block__title:after {
background: var(--intro-bg-block-3); background: var(--intro-bg-block-3);
} }
.intro-text__children .block:nth-of-type(5n+4) .block__title:after { .intro-text__children .block:nth-of-type(6n+4) .block__title:after {
background: var(--intro-bg-block-4); background: var(--intro-bg-block-4);
} }
.intro-text__children .block:nth-of-type(5n+5) .block__title:after { .intro-text__children .block:nth-of-type(6n+5) .block__title:after {
background: var(--intro-bg-block-5); background: var(--intro-bg-block-5);
} }
.intro-text__children .block:nth-of-type(6n+6) .block__title:after {
background: var(--intro-bg-block-6);
}
#intro-badges { #intro-badges {
display: none; display: none;
margin-bottom: 1.1rem;
text-align: center; text-align: center;
} }
#intro-badges img {
margin-bottom: 1.1rem;
}
/* /*
* Intro Footer * Intro Footer
@ -469,11 +470,8 @@ body {
justify-content: center; justify-content: center;
flex-direction: column; flex-direction: column;
margin: 0 auto; margin: 0 auto;
padding: 0 10.625rem 2rem; padding: 0 10.625rem;
max-width: 80rem; max-width: 80rem;
font-size: 1.15rem;
font-weight: 300;
line-height: 100%;
} }
.intro-footer__body a:visited { .intro-footer__body a:visited {
color: var(--intro-color-gray); color: var(--intro-color-gray);
@ -495,13 +493,13 @@ body {
flex-wrap: wrap; flex-wrap: wrap;
margin-top: 2rem; margin-top: 2rem;
} }
@media (max-width: 48rem) { @media (width <= 48rem) {
.intro-footer__logo { .intro-footer__logo {
display: none; display: none;
} }
} }
@media (max-width: 64rem) { @media (width <= 64rem) {
.intro-footer__body { .intro-footer__body {
padding: 0 1rem 2rem; padding: 0 1rem;
} }
} }