Field
Wrapper para label + control + hint/error. Componente slot-based : el control va dentro.
Copy
<div class="field">
<label class="field-label">
Nombre comercial
</label>
<div class="field-control">
<input id="name"
type="text"
name="name"
class="input" placeholder="Cafetería La Plaza">
</div>
</div>
Copy
{% from "input.jinja" import input %}
{% from "field.jinja" import field %}
{% call field("Nombre comercial") %}
{{ input("name", placeholder="Cafetería La Plaza") }}
{% endcall %}
Copy
<Field label="Nombre comercial">
<Input label="name" placeholder="Cafetería La Plaza" />
</Field>
Install the Jinja addon and import the component:
pip install outfitkit
Then in your template:
{% from "<component>.jinja" import <component> %}
{{ <component>(...) }}
Or with JinjaX:
<Component ... />
Copy
<div class="field">
<label class="field-label">
Email <span class="field-required" aria-label="obligatorio">*</span>
</label>
<div class="field-control">
<input id="email"
type="email"
name="email"
class="input" value="contacto@laplaza.es">
</div><span class="field-hint">Te avisaremos de eventos clave.</span>
</div>
Copy
{% from "input.jinja" import input %}
{% from "field.jinja" import field %}
{% call field("Email", required=True, hint="Te avisaremos de eventos clave.") %}
{{ input("email", type="email", value="contacto@laplaza.es") }}
{% endcall %}
Copy
<Field label="Email" required hint="Te avisaremos de eventos clave.">
<Input label="email" type="email" value="contacto@laplaza.es" />
</Field>
Install the Jinja addon and import the component:
pip install outfitkit
Then in your template:
{% from "<component>.jinja" import <component> %}
{{ <component>(...) }}
Or with JinjaX:
<Component ... />
Copy
<div class="field error">
<label class="field-label">
CIF
</label>
<div class="field-control">
<input id="cif"
type="text"
name="cif"
class="input invalid" value="X-1234">
<span class="field-error-icon" aria-hidden="true">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>
</span>
</div><span class="field-error" role="alert">Formato no válido (ej. B12345678).</span>
</div>
Copy
{% from "input.jinja" import input %}
{% from "field.jinja" import field %}
{% call field("CIF", error="Formato no válido (ej. B12345678).") %}
{{ input("cif", value="X-1234", invalid=True) }}
{% endcall %}
Copy
<Field label="CIF" error="Formato no válido (ej. B12345678).">
<Input label="cif" value="X-1234" invalid />
</Field>
Install the Jinja addon and import the component:
pip install outfitkit
Then in your template:
{% from "<component>.jinja" import <component> %}
{{ <component>(...) }}
Or with JinjaX:
<Component ... />
Copy
<div data-signals="{ company: 'Cafetería La Plaza' }">
<div class="field">
<label class="field-label">
Nombre comercial
</label>
<div class="field-control">
<input id="company"
type="text"
name="company"
class="input" data-bind-company="">
</div><span class="field-hint">Se guarda automáticamente.</span>
</div>
<p style="margin-top:8px;">Vista previa: <strong data-text="$company"></strong></p>
</div>
Copy
{% from "input.jinja" import input %}
{% from "field.jinja" import field %}
<div data-signals="{ company: 'Cafetería La Plaza' }">
{% call field("Nombre comercial", hint="Se guarda automáticamente.") %}
{{ input("company", attrs={"data-bind-company": ""}) }}
{% endcall %}
<p style="margin-top:8px;">Vista previa: <strong data-text="$company"></strong></p>
</div>
Copy
<div data-signals="{ company: 'Cafetería La Plaza' }">
<Field label="Nombre comercial" hint="Se guarda automáticamente.">
<Input label="company" data-bind-company="" />
</Field>
<p style="margin-top:8px;">Vista previa: <strong data-text="$company"></strong></p>
</div>
Install the Jinja addon and import the component:
pip install outfitkit
Then in your template:
{% from "<component>.jinja" import <component> %}
{{ <component>(...) }}
Or with JinjaX:
<Component ... />
API
Prop Tipo Default Descripción
labelstr — Texto del label.
requiredbool false Añade el asterisco rojo con aria-label="obligatorio".
hintstr "" Texto de ayuda bajo el control.
errorstr "" Texto de error (oculta el hint, añade icono de aviso al control).
attrsdict {} Atributos HTML extra.
(slot) — — Control de formulario.
Accesibilidad
El componente Field es slot-based : no renderiza el control interno, sólo el wrapper y el label.
Por eso el consumidor es responsable de añadir aria-required="true" al <input>/<select>/<textarea>
cuando required=True, así como aria-invalid="true" cuando error no está vacío.
El asterisco visual ya expone aria-label="obligatorio" a lectores de pantalla, y el icono de error
está marcado como aria-hidden="true" porque el mensaje textual de error es el que comunica el estado.