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:
parent
e29c2bc5f2
commit
d70d0e4239
@ -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;
|
||||
|
||||
@ -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 %}
|
||||
Loading…
Reference in New Issue
Block a user