♻️ (pagetop): Sustituye Attr<T> por Option<T>

`Attr<T>` no aportaba nada sobre `Option<T>` directo: `Getters` ya trata
los campos `Option<T>` como caso especial (`Option<&T>`, o `Option<T>`
con `#[getters(copy)]`) y `#[builder_fn]` funciona igual sobre ellos.
This commit is contained in:
Manuel Cillero 2026-08-17 05:28:12 +02:00
parent 213aa18b12
commit bf4c635e59
21 changed files with 171 additions and 245 deletions

View file

@ -63,9 +63,9 @@ pub(crate) fn render(field: &Field, cx: &mut Context) -> Result<Markup, Componen
let strict = field.kind().is_strict();
let masked = *field.kind() == Kind::StrictPassword;
let autocomplete = if strict {
Some(form::Autocomplete::Off)
Some(&form::Autocomplete::Off)
} else {
field.autocomplete().get()
field.autocomplete()
};
// La etiqueta flotante requiere `placeholder` para animar la etiqueta.
@ -100,12 +100,12 @@ pub(crate) fn render(field: &Field, cx: &mut Context) -> Result<Markup, Componen
type=(field.kind())
id=[input_id.as_deref()]
class=(input_class)
name=[field.name().get()]
value=[field.value().get()]
minlength=[field.minlength().get()]
maxlength=[field.maxlength().get()]
name=[field.name().as_deref()]
value=[field.value().as_deref()]
minlength=[field.minlength()]
maxlength=[field.maxlength()]
placeholder=[placeholder]
inputmode=[field.inputmode().get()]
inputmode=[field.inputmode()]
autocomplete=[autocomplete]
spellcheck=[strict.then_some("false")]
autocorrect=[strict.then_some("off")]

View file

@ -85,10 +85,10 @@ pub(crate) fn render(field: &Field, cx: &mut Context) -> Result<Markup, Componen
select
id=[select_id.as_deref()]
class="form-select"
name=[field.name().get()]
name=[field.name().as_deref()]
multiple[*field.multiple()]
size=[field.rows().get()]
autocomplete=[field.autocomplete().get()]
size=[field.rows()]
autocomplete=[field.autocomplete()]
autofocus[*field.autofocus()]
required[*field.required()]
disabled[*field.disabled()]
@ -97,7 +97,7 @@ pub(crate) fn render(field: &Field, cx: &mut Context) -> Result<Markup, Componen
@match entry {
form::select::Entry::Item(opt) => {
option
value=(opt.value().as_str().unwrap_or(""))
value=(opt.value().as_deref().unwrap_or(""))
selected[*opt.selected()]
disabled[*opt.disabled()]
{
@ -111,7 +111,7 @@ pub(crate) fn render(field: &Field, cx: &mut Context) -> Result<Markup, Componen
{
@for opt in group.items() {
option
value=(opt.value().as_str().unwrap_or(""))
value=(opt.value().as_deref().unwrap_or(""))
selected[*opt.selected()]
disabled[*opt.disabled()]
{

View file

@ -91,18 +91,18 @@ pub(crate) fn render(field: &Textarea, cx: &mut Context) -> Result<Markup, Compo
textarea
id=[textarea_id.as_deref()]
class="form-control"
name=[field.name().get()]
rows=[field.rows().get()]
minlength=[field.minlength().get()]
maxlength=[field.maxlength().get()]
name=[field.name().as_deref()]
rows=[field.rows()]
minlength=[field.minlength()]
maxlength=[field.maxlength()]
placeholder=[placeholder]
autocomplete=[field.autocomplete().get()]
autocomplete=[field.autocomplete()]
autofocus[*field.autofocus()]
readonly[*field.readonly()]
required[*field.required()]
disabled[*field.disabled()]
{
@if let Some(value) = field.value().get() { (value) }
@if let Some(value) = field.value().as_deref() { (value) }
}
@if floating { (label) }
@if let Some(description) = field.help_text().lookup(cx) {