refactor(web): filas de formulario con varios controles combinables
El mockup muestra que una fila es etiqueta + uno o varios controles en la misma línea (Cliente = input + "...", Canal / Zona = dos mitades, Serie + Número = 72 px + resto, select + número + botón) y que la cabecera tiene a lo sumo 2 columnas. Los campos de un solo control no lo permitían. - Controles sin etiqueta combinables dentro de sbo-field: sbo-input, sbo-textarea, sbo-number, sbo-date, sbo-select y el botón .sbo-btn; ocupan el espacio sobrante o un width fijo. - El primer control de la fila toma el id de la etiqueta (claimId); los demás se nombran con ariaLabel. El error de la fila marca todos sus controles (aria-invalid / aria-describedby). - Los campos con etiqueta (sbo-text-field, sbo-number-field, ..., sbo-lookup-field) pasan a ser atajos de un solo control con la misma API. - CSS global: .sbo-group y .sbo-btn reemplazan a .sbo-pick/.sbo-pair. - CLAUDE.md apunta al mockup renombrado (tools/oferta_venta.html). - Verificado en Chrome contra SAP real, con una cabecera que reproduce las filas compuestas del mockup. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
aa2c483723
commit
68caf401a7
16 files changed
+531
-298
No files matched your search
+21
-15
@@ -76,30 +76,36 @@ columns: VhColumn[] = [
|
||||
|
||||
### Campos de formulario (`shared/form`)
|
||||
|
||||
Cada campo trae su etiqueta (fila SBO: etiqueta a la izquierda, control a la derecha) y se enlaza con señales: `[(value)]`.
|
||||
|
||||
| Componente | Valor | Notas |
|
||||
|---|---|---|
|
||||
| `sbo-text-field` | `string` | `maxlength`, `placeholder` |
|
||||
| `sbo-textarea-field` | `string` | `rows` |
|
||||
| `sbo-number-field` | `number \| null` | `decimals`; muestra `1,234.50` fuera de foco y acepta `12,5` o `1,234.50` al escribir |
|
||||
| `sbo-date-field` | `string` ISO `yyyy-MM-dd` | selector nativo |
|
||||
| `sbo-select-field` | `string \| number \| null` | `[options]`, `placeholder`; devuelve el tipo original |
|
||||
| `sbo-lookup-field` | `string` | flecha dorada + botón "…" / F4 que abre `sbo-value-help` según `[lookup]` (`VhLookup`); emite `(picked)` con la fila; `linkable` + `(linkClick)` |
|
||||
|
||||
Comunes: `label`, `required`, `readonly`, `disabled`, `error` (borde rojo + mensaje). `sbo-field` es la fila vacía para proyectar cualquier otro control.
|
||||
Una **fila** (`sbo-field`) es: etiqueta + uno o varios controles en la misma línea. La cabecera de un formulario tiene **como máximo 2 columnas** (`.sbo-hdr` con dos `.sbo-col`). Las combinaciones del mockup (Cliente = input + "…", Canal / Zona = dos mitades, Serie + Número = 72 px + resto, select + número + botón) salen de combinar controles:
|
||||
|
||||
```html
|
||||
<div class="sbo-hdr">
|
||||
<div class="sbo-col">
|
||||
<sbo-lookup-field label="Cliente" required [(value)]="cardCode" [lookup]="bp" (picked)="onBp($event)" />
|
||||
<sbo-text-field label="Nombre" readonly [value]="cardName()" />
|
||||
<sbo-field label="Canal / Zona">
|
||||
<sbo-input readonly ariaLabel="Canal" [value]="canal()" />
|
||||
<sbo-input readonly ariaLabel="Zona" [value]="zona()" />
|
||||
</sbo-field>
|
||||
</div>
|
||||
<div class="sbo-col">
|
||||
<sbo-date-field label="Fecha" [(value)]="docDate" />
|
||||
<sbo-number-field label="Importe" [decimals]="2" [(value)]="total" />
|
||||
<sbo-field label="Número">
|
||||
<sbo-input width="72px" readonly ariaLabel="Serie" value="COT" />
|
||||
<sbo-input readonly ariaLabel="Número correlativo" [value]="numero()" />
|
||||
</sbo-field>
|
||||
<sbo-field label="Moneda / Importe">
|
||||
<sbo-select width="90px" ariaLabel="Moneda" [options]="monedas" [(value)]="moneda" />
|
||||
<sbo-number [decimals]="2" ariaLabel="Importe" [(value)]="importe" />
|
||||
<button type="button" class="sbo-btn">…</button>
|
||||
</sbo-field>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
Estilos globales en `styles/forms.css` (`.sbo-in`, `.sbo-sel`, `.sbo-ta`, `.sbo-pick`, `.sbo-hdr`, `.sbo-col`, `.sbo-pair`). El ancho de etiqueta se ajusta con `--label-w` (165 px por defecto).
|
||||
**Controles combinables** (sin etiqueta, dentro de `sbo-field`; ocupan el espacio sobrante o un `width` fijo): `sbo-input`, `sbo-textarea`, `sbo-number`, `sbo-date`, `sbo-select` y el botón nativo `<button class="sbo-btn">`. Todos con enlace por señales `[(value)]`, `readonly`, `disabled`, `required`, `width` y `ariaLabel` (obligatorio en los que no son el primero de la fila: el primero toma el `id` de la etiqueta). El `error` de la fila marca todos sus controles (borde rojo + mensaje, `aria-invalid`/`aria-describedby`).
|
||||
|
||||
**Atajos con etiqueta** (un control por fila): `sbo-text-field`, `sbo-textarea-field`, `sbo-number-field`, `sbo-date-field`, `sbo-select-field` y `sbo-lookup-field` (flecha dorada + botón "…" / F4 que abre `sbo-value-help` según `[lookup]` (`VhLookup`), emite `(picked)` con la fila; `linkable` + `(linkClick)`). Comunes: `label`, `required`, `readonly`, `disabled`, `error`.
|
||||
|
||||
Detalles: `sbo-number` muestra `1,234.50` fuera de foco y acepta `12,5` o `1,234.50` al escribir (`decimals` redondea); `sbo-date` usa texto ISO `yyyy-MM-dd`; `sbo-select` devuelve el valor con su tipo original.
|
||||
|
||||
Estilos globales en `styles/forms.css` (`.sbo-in`, `.sbo-sel`, `.sbo-ta`, `.sbo-btn`, `.sbo-group`, `.sbo-hdr`, `.sbo-col`). El ancho de etiqueta se ajusta con `--label-w` (165 px por defecto).
|
||||
Reference in new issue
Block a user