From 4b50e043e02f8c1d18fb1dde84c7381331578a01 Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Sat, 2 May 2026 11:57:05 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=84=20(bootsier):=20A=C3=B1ade=20estil?= =?UTF-8?q?os=20y=20mejora=20docs=20de=20Form?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extensions/pagetop-bootsier/src/theme/form.rs | 36 +++++++++++-- .../src/theme/form/component.rs | 23 ++++---- .../pagetop-bootsier/src/theme/form/range.rs | 4 +- .../static/scss/_customs.scss | 52 +++++++++++++++++++ 4 files changed, 100 insertions(+), 15 deletions(-) diff --git a/extensions/pagetop-bootsier/src/theme/form.rs b/extensions/pagetop-bootsier/src/theme/form.rs index 7fa85a10..634dc48a 100644 --- a/extensions/pagetop-bootsier/src/theme/form.rs +++ b/extensions/pagetop-bootsier/src/theme/form.rs @@ -1,9 +1,39 @@ //! Definiciones para crear formularios ([`Form`]). +//! +//! # Ejemplo +//! +//! ```rust +//! use pagetop::prelude::*; +//! use pagetop_bootsier::prelude::*; +//! +//! let form_login = Form::new() +//! .with_id("login") +//! .with_action("/login") +//! .with_child( +//! form::input::Field::email() +//! .with_name("email") +//! .with_label(L10n::n("Email")) +//! .with_required(true), +//! ) +//! .with_child( +//! form::input::Field::password() +//! .with_name("password") +//! .with_label(L10n::n("Password")) +//! .with_required(true), +//! ) +//! .with_child( +//! form::Checkbox::check() +//! .with_name("remember") +//! .with_label(L10n::n("Remember me")), +//! ) +//! .with_child( +//! Button::submit(L10n::n("Sign in")) +//! .with_color(ButtonColor::Background(Color::Primary)), +//! ); +//! ``` mod props; -pub use props::Method; -pub use props::{Autocomplete, AutofillField}; -pub use props::CheckboxKind; +pub use props::{Autocomplete, AutofillField, CheckboxKind, Method}; mod component; pub use component::Form; diff --git a/extensions/pagetop-bootsier/src/theme/form/component.rs b/extensions/pagetop-bootsier/src/theme/form/component.rs index 10dd803c..dd655702 100644 --- a/extensions/pagetop-bootsier/src/theme/form/component.rs +++ b/extensions/pagetop-bootsier/src/theme/form/component.rs @@ -16,26 +16,29 @@ use crate::theme::form; /// /// # Ejemplo /// -/// ```ignore -/// use pagetop::prelude::*; -/// use crate::prelude::*; -/// -/// let form = Form::new() +/// ```rust +/// # use pagetop::prelude::*; +/// # use pagetop_bootsier::prelude::*; +/// let search = Form::new() /// .with_id("search") /// .with_action("/search") /// .with_method(form::Method::Get) -/// .with_classes(ClassesOp::Add, "mb-3") -/// .with_child(Input::new().with_name("q")); +/// .with_child(form::Input::search().with_name("q")); /// ``` #[derive(AutoDefault, Clone, Debug, Getters)] pub struct Form { #[getters(skip)] id: AttrId, + /// Devuelve las clases CSS del formulario. classes: Classes, + /// Devuelve la URL/ruta de destino del formulario. action: AttrValue, + /// Devuelve el método para enviar el formulario. method: form::Method, + /// Devuelve el juego de caracteres aceptado por el formulario. #[default(_code = "AttrValue::new(\"UTF-8\")")] charset: AttrValue, + /// Devuelve la lista de componentes del formulario. children: Children, } @@ -107,15 +110,15 @@ impl Form { /// Establece el juego de caracteres aceptado por el formulario. /// - /// Por defecto se usa `"UTF-8"`. + /// Por defecto se utiliza `"UTF-8"`. #[builder_fn] pub fn with_charset(mut self, charset: impl AsRef) -> Self { self.charset.alter_str(charset); self } - /// Añade un nuevo componente al formulario o modifica la lista de de componentes (`children`) - /// con una operación [`ChildOp`]. + /// Añade un nuevo componente al formulario o modifica la lista de componentes (`children`) con + /// una operación [`ChildOp`]. #[builder_fn] pub fn with_child(mut self, op: impl Into) -> Self { self.children.alter_child(op.into()); diff --git a/extensions/pagetop-bootsier/src/theme/form/range.rs b/extensions/pagetop-bootsier/src/theme/form/range.rs index 1f4799b1..40350479 100644 --- a/extensions/pagetop-bootsier/src/theme/form/range.rs +++ b/extensions/pagetop-bootsier/src/theme/form/range.rs @@ -11,9 +11,9 @@ use pagetop::prelude::*; /// ```rust /// # use pagetop::prelude::*; /// # use pagetop_bootsier::prelude::*; -/// let volumen = form::Range::new() +/// let volume = form::Range::new() /// .with_name("volume") -/// .with_label(L10n::n("Volumen")) +/// .with_label(L10n::n("Volume")) /// .with_min(Some(0.0)) /// .with_max(Some(100.0)) /// .with_step(Some(5.0)) diff --git a/extensions/pagetop-bootsier/static/scss/_customs.scss b/extensions/pagetop-bootsier/static/scss/_customs.scss index 45e41001..6d0aa4e6 100644 --- a/extensions/pagetop-bootsier/static/scss/_customs.scss +++ b/extensions/pagetop-bootsier/static/scss/_customs.scss @@ -18,6 +18,58 @@ $enable-cssgrid: true; --bs-text-opacity: 0.1; } +// FORMS + +// Required field indicator +.form-required { + color: var(--bs-danger); + margin: 0 0.25rem; +} + +// Form fields +.form-field { + margin-bottom: 1rem; + + &:last-child { + margin-bottom: 0; + } +} + +// Fieldset +fieldset { + position: relative; + background-color: var(--bs-body-bg); + border: var(--bs-border-width) solid var(--bs-border-color); + border-radius: var(--bs-border-radius); + padding: 2rem 1rem 1rem; + margin: 2rem 0 1rem; +} +fieldset > legend { + position: absolute; + top: 0; + left: 1rem; + transform: translateY(-50%); + background-color: var(--bs-body-bg); + border: var(--bs-border-width) solid var(--bs-border-color); + border-radius: var(--bs-border-radius); + padding: 0.125rem 0.75rem; + font-size: $font-size-sm; + line-height: 1.25; + width: fit-content; + max-width: 75%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.fieldset-description { + margin-bottom: 1rem; +} + +// Check buttons, gap between label and first inline check +.form-label + .form-check-inline { + margin-left: 1rem; +} + // Extending utilities $utilities: map-merge( $utilities,