From d20a1f5f627f66dd2e93dc5d84ac7ae114905371 Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Wed, 29 Apr 2026 23:42:29 +0200 Subject: [PATCH 1/3] =?UTF-8?q?=E2=9C=A8=20A=C3=B1ade=20ejemplo=20intro-co?= =?UTF-8?q?lors=20y=20actualiza=20paleta?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/intro-colors.rs | 80 ++++++++++++++++ .../pagetop-aliner/static/css/styles.css | 4 +- src/locale/en-US/sample.ftl | 10 ++ src/locale/es-ES/sample.ftl | 10 ++ static/css/basic.css | 4 + static/css/intro.css | 96 +++++++++---------- 6 files changed, 154 insertions(+), 50 deletions(-) create mode 100644 examples/intro-colors.rs diff --git a/examples/intro-colors.rs b/examples/intro-colors.rs new file mode 100644 index 00000000..7853d41e --- /dev/null +++ b/examples/intro-colors.rs @@ -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 { + 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 +} diff --git a/extensions/pagetop-aliner/static/css/styles.css b/extensions/pagetop-aliner/static/css/styles.css index 1cc2f5dc..85d0811a 100644 --- a/extensions/pagetop-aliner/static/css/styles.css +++ b/extensions/pagetop-aliner/static/css/styles.css @@ -29,12 +29,14 @@ h1, h2, h3, h4,h5, h6, p { } *::before, *::after { - background: #faa; border-radius: 3px; font: normal normal 400 10px/1.2 monospace; vertical-align: middle; padding: 1px 3px; margin: 0 3px; + background: #faa; + color: #fff; + -webkit-text-fill-color: currentColor; } *::before { content: "("; diff --git a/src/locale/en-US/sample.ftl b/src/locale/en-US/sample.ftl index ae5b9a7f..8bfa4cdf 100644 --- a/src/locale/en-US/sample.ftl +++ b/src/locale/en-US/sample.ftl @@ -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: #FFB84B — Amber gold. +sample_colors_val_2 = Background color: #FFC66F — Light golden. +sample_colors_val_3 = Background color: #FFD493 — Pale golden. +sample_colors_val_4 = Background color: #FFE3B7 — Light peach. +sample_colors_val_5 = Background color: #FFF1DB — Cream. +sample_colors_val_6 = Background color: #FFFFFF — White. + # menus.rs sample_menus_item_label = Label sample_menus_item_link = Link diff --git a/src/locale/es-ES/sample.ftl b/src/locale/es-ES/sample.ftl index 65785972..5a706851 100644 --- a/src/locale/es-ES/sample.ftl +++ b/src/locale/es-ES/sample.ftl @@ -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: #FFB84B — Ámbar dorado. +sample_colors_val_2 = Color de fondo: #FFC66F — Dorado claro. +sample_colors_val_3 = Color de fondo: #FFD493 — Dorado pálido. +sample_colors_val_4 = Color de fondo: #FFE3B7 — Melocotón claro. +sample_colors_val_5 = Color de fondo: #FFF1DB — Crema. +sample_colors_val_6 = Color de fondo: #FFFFFF — Blanco. + # menus.rs sample_menus_item_label = Etiqueta sample_menus_item_link = Enlace diff --git a/static/css/basic.css b/static/css/basic.css index 6ffe4c6e..9b23b272 100644 --- a/static/css/basic.css +++ b/static/css/basic.css @@ -15,6 +15,10 @@ --val-color--text: #212529; } +*, *::before, *::after { + box-sizing: border-box; +} + html { scroll-behavior: smooth; } diff --git a/static/css/intro.css b/static/css/intro.css index e3de4153..a182767f 100644 --- a/static/css/intro.css +++ b/static/css/intro.css @@ -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-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-color: #8c5919; - --intro-bg-block-1: #b689ff; - --intro-bg-block-2: #fecaca; - --intro-bg-block-3: #e6a9e2; - --intro-bg-block-4: #ffedca; - --intro-bg-block-5: #ffffff; + --intro-bg-color: #7a430e; + --intro-bg-block-1: #ffb84b; + --intro-bg-block-2: #ffc66f; + --intro-bg-block-3: #ffd493; + --intro-bg-block-4: #ffe3b7; + --intro-bg-block-5: #fff1db; + --intro-bg-block-6: #ffffff; --intro-color: #1a202c; - --intro-color-gray: #e4e4e7; - --intro-color-link: #1e4eae; + --intro-color-gray: #e8e3da; + --intro-color-link: #8b2500; --intro-focus-outline: 2px solid var(--intro-color-link); --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); @@ -102,7 +103,7 @@ body { font-size: clamp(2.25rem, 1.3177rem + 3.9779vw, 6.5rem); font-style: normal; font-weight: 700; - line-height: 110%; + line-height: 135%; text-shadow: none; } .intro-header__image { @@ -123,7 +124,7 @@ body { background-image: var(--intro-bg-img-set); } .intro-header__title { - padding: 1.2rem 2rem 2.6rem 2rem; + padding: 0 2rem 2.6rem 2rem; } .intro-header__image { justify-content: flex-end; @@ -140,10 +141,13 @@ body { .intro-content { height: auto; margin-top: 1.6rem; + width: 100%; } .intro-content__body { box-sizing: border-box; max-width: 80rem; + margin-left: auto; + margin-right: auto; } .intro-content__body:before, .intro-content__body:after { @@ -152,10 +156,10 @@ body { left: 0; right: 0; 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); opacity: 0.8; - inset: 11.75rem; + inset: unset; } .intro-content__body:before { top: -1rem; @@ -163,22 +167,22 @@ body { .intro-content__body:after { bottom: -1rem; } -@media (max-width: 48rem) { +@media (width <= 48rem) { .intro-content__body { margin-top: -9.8rem; } - .intro-content__body:before, - .intro-content__body:after { - inset: unset; - } } -@media (min-width: 64rem) { +@media (width >= 64rem) { .intro-content { margin-top: 0; } .intro-content__body { margin-top: -5.7rem; } + .intro-content__body:before, + .intro-content__body:after { + inset: 11.75rem; + } } .intro-button { @@ -307,7 +311,7 @@ body { .intro-button__link:hover span { animation-play-state: paused; } -@media (max-width: 48rem) { +@media (width <= 48rem) { .intro-header { padding-bottom: 9rem;; } @@ -321,7 +325,7 @@ body { padding-top: .5rem; } } -@media (min-width: 48rem) { +@media (width > 48rem) { .intro-button { position: absolute; top: 0; @@ -344,9 +348,6 @@ body { box-sizing: border-box; align-items: center; text-align: left; - font-size: 1.3125rem; - font-weight: 400; - line-height: 1.5; margin-bottom: 0; background: #fff; position: relative; @@ -354,24 +355,19 @@ body { .intro-text__children { padding: 2.5rem 1.063rem 0.75rem; overflow: hidden; + width: 100%; } .intro-text__children p { width: 100%; - line-height: 150%; - font-weight: 400; - font-size: 1.45rem; + font-size: 1.5rem; margin: 0 0 1.5rem; } -@media (min-width: 48rem) { - .intro-text { - font-size: 1.375rem; - line-height: 2rem; - } +@media (width > 48rem) { .intro-button + .intro-text__children { padding-top: 7rem; } } -@media (min-width: 64rem) { +@media (width >= 64rem) { .intro-header { padding-bottom: 9rem;; } @@ -399,7 +395,7 @@ body { .intro-text__children .block__title span { display: inline-block; padding: 10px 30px 14px; - margin: 30px 0 0 20px; + margin: 30px 20px 0; background: white; border: 5px solid; border-radius: 30px; @@ -422,36 +418,41 @@ body { } .intro-text__children .block__title:after { content: ""; - height: 70rem; + height: 120%; position: absolute; top: 42px; - left: -15%; - width: 130%; + left: -25%; + width: 150%; z-index: -10; background: var(--intro-bg-block-1); 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); } -.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); } -.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); } -.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); } -.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); } +.intro-text__children .block:nth-of-type(6n+6) .block__title:after { + background: var(--intro-bg-block-6); +} #intro-badges { display: none; - margin-bottom: 1.1rem; text-align: center; } +#intro-badges img { + margin-bottom: 1.1rem; +} /* * Intro Footer @@ -469,11 +470,8 @@ body { justify-content: center; flex-direction: column; margin: 0 auto; - padding: 0 10.625rem 2rem; + padding: 0 10.625rem; max-width: 80rem; - font-size: 1.15rem; - font-weight: 300; - line-height: 100%; } .intro-footer__body a:visited { color: var(--intro-color-gray); @@ -495,13 +493,13 @@ body { flex-wrap: wrap; margin-top: 2rem; } -@media (max-width: 48rem) { +@media (width <= 48rem) { .intro-footer__logo { display: none; } } -@media (max-width: 64rem) { +@media (width <= 64rem) { .intro-footer__body { - padding: 0 1rem 2rem; + padding: 0 1rem; } } From 69cd38cf1bf561e6cdc58b906eee7452456afc54 Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Wed, 29 Apr 2026 23:45:09 +0200 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=93=9D=20Correcciones=20menores=20de?= =?UTF-8?q?=20doc=20y=20comentarios?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/component/children.rs | 4 ++-- src/core/component/context.rs | 3 +-- src/core/component/message.rs | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/core/component/children.rs b/src/core/component/children.rs index 6a4fe070..617a783d 100644 --- a/src/core/component/children.rs +++ b/src/core/component/children.rs @@ -187,10 +187,10 @@ impl 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() { - /// 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`. /// ``` diff --git a/src/core/component/context.rs b/src/core/component/context.rs index e4a5c237..63b2daad 100644 --- a/src/core/component/context.rs +++ b/src/core/component/context.rs @@ -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 /// segmentos del *path*, entonces se usará el *path* completo. /// - /// Es útil para asignar identificadores HTML predecibles cuando el componente no recibe uno - /// explícito. + /// Es útil para asignar identificadores HTML cuando el componente no recibe uno explícito. pub fn required_id(&self, id: Option, parts: usize) -> String { if let Some(id) = id { return id; diff --git a/src/core/component/message.rs b/src/core/component/message.rs index d0f9d77b..9f6704a2 100644 --- a/src/core/component/message.rs +++ b/src/core/component/message.rs @@ -31,7 +31,7 @@ pub enum MessageLevel { /// let info = StatusMessage::new(MessageLevel::Info, L10n::l("saved-successfully")); /// /// // 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)] pub struct StatusMessage { From f359b361223f3f4b6bd2048c17c615471c4bf9ce Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Wed, 29 Apr 2026 23:46:03 +0200 Subject: [PATCH 3/3] =?UTF-8?q?=F0=9F=93=9D=20(pagetop-macros):=20Retoca?= =?UTF-8?q?=20texto=20de=20builder=5Ffn?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- helpers/pagetop-macros/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/helpers/pagetop-macros/src/lib.rs b/helpers/pagetop-macros/src/lib.rs index 1630137a..3a597bff 100644 --- a/helpers/pagetop-macros/src/lib.rs +++ b/helpers/pagetop-macros/src/lib.rs @@ -366,8 +366,8 @@ pub fn builder_fn(_: TokenStream, item: TokenStream) -> TokenStream { alter_name_str ); let with_alter_doc = concat!( - "Permite modificar la instancia actual (`&mut self`) con los mismos argumentos, ", - "sin consumirla." + "Permite modificar la instancia (`&mut self`) con los mismos argumentos ", + "pero sin consumirla." ); // Atributos completos que se aplican siempre a `with_...()`.