Anade sistema de estilos de formulario reutilizable

Los formularios usaban form.as_p (salida generica de Django) o bucles
manuales for field in form repetidos en cada plantilla, sin estilos
propios: inputs/selects/textareas sin padding, borde ni foco visibles,
y cada plantilla resolvia los errores/ayuda de campo a su manera.

Cambios:
- base.css: nuevas clases .app-form, .form-field (label + control en
  columna), estilos de input/select/textarea (incluye estado :focus
  con el color de foco del tema), .form-field-checkbox para campos
  booleanos y .form-help para el help_text de los campos.
- Nuevo parcial expenses/_form_fields.html: itera los campos del
  formulario y renderiza label, control, help_text y errores de forma
  consistente. Incluye un caso especial para el campo "tags" de gastos
  (CheckboxSelectMultiple), que se pinta como lista de chips en vez de
  checkboxes sueltos.

Este commit solo anade el estilo y el parcial; las plantillas que lo
adoptan van en el siguiente commit.
This commit is contained in:
JKuijperM 2026-09-03 17:59:01 +02:00
parent e29c2bc5f2
commit d70d0e4239
2 changed files with 79 additions and 0 deletions

View File

@ -694,10 +694,59 @@ tr:hover {
/* Forms */
/* ========================= */
.app-form {
display: flex;
flex-direction: column;
gap: 1rem;
max-width: 480px;
}
.form-field {
display: flex;
flex-direction: column;
gap: 0.35rem;
margin-bottom: 1rem;
}
.form-field label {
font-weight: 600;
font-size: 0.9rem;
}
.form-field input:not([type="checkbox"]):not([type="radio"]),
.form-field select,
.form-field textarea {
width: 100%;
padding: 0.5rem 0.75rem;
border: 1px solid var(--color-border);
border-radius: 6px;
background-color: var(--color-surface);
color: var(--color-text);
font: inherit;
}
.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus {
outline: 2px solid var(--color-focus-ring);
outline-offset: 1px;
border-color: var(--color-primary);
}
.form-field-checkbox {
flex-direction: row;
align-items: center;
}
.form-field-checkbox input[type="checkbox"] {
accent-color: var(--color-primary);
}
.form-help {
font-size: 0.8rem;
color: var(--color-text-muted);
}
.form-errors {
color: var(--color-danger-accent);
font-size: 0.85rem;

View File

@ -0,0 +1,30 @@
{% for field in form %}
<div class="form-field {% if field.field.widget.input_type == 'checkbox' %}form-field-checkbox{% endif %}">
{% if field.name == "tags" %}
{{ field.label_tag }}
<div class="tag-chip-list">
{% for checkbox in field %}
<label class="tag-chip">
{{ checkbox.tag }}
<span>{{ checkbox.choice_label }}</span>
</label>
{% endfor %}
</div>
{% else %}
{{ field.label_tag }}
{{ field }}
{% endif %}
{% if field.help_text %}
<small class="form-help">{{ field.help_text }}</small>
{% endif %}
{% if field.errors %}
<div class="form-errors">{{ field.errors }}</div>
{% endif %}
</div>
{% endfor %}
{% if form.non_field_errors %}
<div class="form-errors">{{ form.non_field_errors }}</div>
{% endif %}