@ajuarezso/sui-design-system 0.24.1 → 0.25.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/sui-accordion/README.md +85 -11
- package/docs/sui-activity-feed/README.md +65 -11
- package/docs/sui-activity-filter/README.md +54 -5
- package/docs/sui-alert/README.md +54 -0
- package/docs/sui-app-store-badge/README.md +64 -10
- package/docs/sui-avatar/README.md +92 -29
- package/docs/sui-avatar-group/README.md +75 -9
- package/docs/sui-badge/README.md +85 -17
- package/docs/sui-banner/README.md +85 -20
- package/docs/sui-brand-logo/README.md +95 -31
- package/docs/sui-breadcrumb-item/README.md +54 -3
- package/docs/sui-breadcrumbs/README.md +54 -6
- package/docs/sui-button/README.md +76 -12
- package/docs/sui-button-group/README.md +91 -23
- package/docs/sui-button-group-item/README.md +81 -14
- package/docs/sui-card/README.md +105 -18
- package/docs/sui-chart-legend/README.md +63 -10
- package/docs/sui-chart-legend-dot/README.md +59 -10
- package/docs/sui-checkbox/README.md +109 -29
- package/docs/sui-checkbox-card/README.md +70 -14
- package/docs/sui-checkbox-label/README.md +92 -26
- package/docs/sui-circular-progress-bar/README.md +80 -19
- package/docs/sui-color-dot/README.md +72 -12
- package/docs/sui-color-picker/README.md +71 -13
- package/docs/sui-command-menu-footer/README.md +50 -1
- package/docs/sui-command-menu-item/README.md +74 -14
- package/docs/sui-command-menu-search/README.md +58 -3
- package/docs/sui-compact-avatar-group/README.md +73 -13
- package/docs/sui-compact-button/README.md +123 -34
- package/docs/sui-compact-select/README.md +61 -7
- package/docs/sui-compact-select-for-input/README.md +70 -6
- package/docs/sui-content-card/README.md +75 -14
- package/docs/sui-content-divider/README.md +67 -16
- package/docs/sui-content-label/README.md +99 -20
- package/docs/sui-counter-input/README.md +102 -18
- package/docs/sui-date-selector/README.md +69 -11
- package/docs/sui-datepicker/README.md +85 -18
- package/docs/sui-day-cell/README.md +75 -17
- package/docs/sui-day-label/README.md +56 -7
- package/docs/sui-divider/README.md +64 -9
- package/docs/sui-drawer-footer/README.md +63 -2
- package/docs/sui-drawer-header/README.md +69 -12
- package/docs/sui-dropdown-caption/README.md +58 -6
- package/docs/sui-dropdown-item/README.md +75 -9
- package/docs/sui-dropdown-menu/README.md +83 -14
- package/docs/sui-dropdown-search/README.md +60 -4
- package/docs/sui-emoji/README.md +94 -30
- package/docs/sui-empty-state/README.md +71 -7
- package/docs/sui-fancy-button/README.md +74 -14
- package/docs/sui-file-icon/README.md +70 -12
- package/docs/sui-file-upload/README.md +77 -17
- package/docs/sui-file-upload-card/README.md +64 -12
- package/docs/sui-filter/README.md +83 -14
- package/docs/sui-flag/README.md +73 -8
- package/docs/sui-form-hint/README.md +56 -7
- package/docs/sui-form-label/README.md +57 -5
- package/docs/sui-href/README.md +47 -0
- package/docs/sui-icon/README.md +86 -18
- package/docs/sui-image-upload/README.md +90 -22
- package/docs/sui-image-upload-profile/README.md +70 -11
- package/docs/sui-img-retry/README.md +50 -1
- package/docs/sui-inline-input/README.md +67 -9
- package/docs/sui-inline-select/README.md +62 -2
- package/docs/sui-input/README.md +90 -27
- package/docs/sui-integration-switch/README.md +84 -17
- package/docs/sui-kbd/README.md +73 -9
- package/docs/sui-key-icon/README.md +85 -23
- package/docs/sui-link-button/README.md +96 -27
- package/docs/sui-logo/README.md +93 -22
- package/docs/sui-modal/README.md +72 -13
- package/docs/sui-modal-footer/README.md +86 -12
- package/docs/sui-modal-header/README.md +57 -1
- package/docs/sui-modal-sheet/README.md +74 -12
- package/docs/sui-notification/README.md +81 -11
- package/docs/sui-notification-footer/README.md +55 -5
- package/docs/sui-notification-tab-menu/README.md +61 -5
- package/docs/sui-otp-input/README.md +70 -9
- package/docs/sui-page-header/README.md +89 -19
- package/docs/sui-pagination/README.md +73 -13
- package/docs/sui-password-strength/README.md +50 -1
- package/docs/sui-payment-icon/README.md +80 -18
- package/docs/sui-period-range/README.md +70 -11
- package/docs/sui-popover/README.md +81 -15
- package/docs/sui-product-card/README.md +89 -21
- package/docs/sui-progress-bar/README.md +82 -15
- package/docs/sui-progress-bar-label/README.md +79 -18
- package/docs/sui-radio/README.md +84 -7
- package/docs/sui-radio-card/README.md +70 -16
- package/docs/sui-radio-label/README.md +89 -22
- package/docs/sui-rating/README.md +101 -31
- package/docs/sui-rich-editor/README.md +47 -2
- package/docs/sui-segmented-control/README.md +90 -21
- package/docs/sui-select/README.md +80 -11
- package/docs/sui-sidebar/README.md +71 -16
- package/docs/sui-slider/README.md +75 -8
- package/docs/sui-social-button/README.md +71 -11
- package/docs/sui-status-badge/README.md +75 -14
- package/docs/sui-stepper/README.md +75 -18
- package/docs/sui-store-card/README.md +85 -22
- package/docs/sui-switch/README.md +82 -11
- package/docs/sui-switch-card/README.md +80 -16
- package/docs/sui-switch-label/README.md +91 -14
- package/docs/sui-tab-chips/README.md +93 -21
- package/docs/sui-tab-menu-horizontal/README.md +68 -7
- package/docs/sui-tab-menu-vertical/README.md +64 -11
- package/docs/sui-table/README.md +77 -16
- package/docs/sui-tag/README.md +86 -12
- package/docs/sui-tag-input/README.md +77 -13
- package/docs/sui-textarea/README.md +84 -17
- package/docs/sui-time-picker/README.md +96 -33
- package/docs/sui-toast/README.md +81 -20
- package/docs/sui-tooltip/README.md +80 -22
- package/docs/sui-topbar/README.md +64 -10
- package/docs/sui-topbar-button/README.md +61 -7
- package/docs/sui-topbar-item/README.md +68 -7
- package/docs/sui-topbar-user/README.md +61 -5
- package/fesm2022/ajuarezso-sui-design-system.mjs +15 -10
- package/fesm2022/ajuarezso-sui-design-system.mjs.map +1 -1
- package/package.json +1 -1
- package/types/ajuarezso-sui-design-system.d.ts +7 -3
|
@@ -34,40 +34,46 @@ tab-chips · secciones → tab menu.**
|
|
|
34
34
|
>
|
|
35
35
|
> Uso medido el 03-10-2026 en `master-pedidos/src/app` (misma exclusión que `sui-badge`):
|
|
36
36
|
> **5 usos en 4 archivos**. Tamaños: 3 `small`, 1 `medium`, 1 sin `size` (`medium`). 1 con solo
|
|
37
|
-
> íconos (vista cuadrícula / lista del catálogo).
|
|
37
|
+
> íconos (vista cuadrícula / lista del catálogo). El 06-10-2026 ya eran **9 usos en 7 archivos**
|
|
38
|
+
> (ver «Usos de hoy» abajo).
|
|
38
39
|
|
|
39
40
|
### `size`
|
|
40
41
|
|
|
41
42
|
| size | cuándo | fuente |
|
|
42
43
|
|---|---|---|
|
|
43
|
-
| `
|
|
44
|
-
| `
|
|
45
|
-
| `
|
|
46
|
-
| `
|
|
44
|
+
| `2xlarge` | Celular y tablet táctil: el único que llega a 44 px por segmento. | canon (dueño, 04-10-2026: piso táctil 44 en el teléfono) y D16, dueño 05-10-2026 |
|
|
45
|
+
| `xlarge` | No se usa: 40 px no llega a 44 en el teléfono y sobra en la computadora. Ninguna pantalla de la app lo usa (medido el 06-10-2026; solo aparece en la vitrina `master-preview`). | D16, dueño 05-10-2026 (antes «mobile», 28-09-2026) |
|
|
46
|
+
| `large` | No aporta: 32 px, chico para el dedo y grande para web. | canon (aprobado por el dueño, 05-10-2026, bloque B6) |
|
|
47
|
+
| `medium` (default) | Computadora: junto a títulos o filtros, también solo íconos en una barra. | canon (dueño, 05-10-2026, D16); el valor exacto, canon (aprobado por el dueño, 05-10-2026, bloque B1) |
|
|
48
|
+
| `small` | No usar: es chico. Los íconos de una barra (cuadrícula / lista) van en `medium`. | canon (dueño, 05-10-2026, D16) |
|
|
47
49
|
|
|
48
50
|
### Ítems (`tabs`)
|
|
49
51
|
|
|
50
52
|
| qué | cuándo | fuente |
|
|
51
53
|
|---|---|---|
|
|
52
54
|
| texto | Lo normal. Una o dos palabras por segmento («Por distancia», «Precio único»). | según la guía del DS (ejemplos con texto) |
|
|
53
|
-
| `icon` + texto | Cuando el ícono ayuda a reconocer el modo rápido. |
|
|
54
|
-
| `iconOnly` | Solo para modos universales (cuadrícula / lista). El `label` pasa a ser el nombre accesible: escríbelo igual. |
|
|
55
|
-
| `disabled` (por ítem) | Un modo que existe pero no aplica todavía. |
|
|
55
|
+
| `icon` + texto | Cuando el ícono ayuda a reconocer el modo rápido. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
|
|
56
|
+
| `iconOnly` | Solo para modos universales (cuadrícula / lista). El `label` pasa a ser el nombre accesible: escríbelo igual. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
|
|
57
|
+
| `disabled` (por ítem) | Un modo que existe pero no aplica todavía. | canon (aprobado por el dueño, 05-10-2026, bloque B8) |
|
|
56
58
|
|
|
57
59
|
**Usos de hoy que rompen las reglas:**
|
|
58
60
|
|
|
59
61
|
- **2 dentro de un borrador que se guarda después (a discutir):**
|
|
60
|
-
`pages/super-admin/master-settings/master-settings.html:
|
|
61
|
-
«Precio único») y `:
|
|
62
|
+
`pages/super-admin/master-settings/master-settings.html:281` (modo de envío: «Por distancia» /
|
|
63
|
+
«Precio único») y `:314` («Por calle» / «En línea recta»). La guía dice que se aplica de
|
|
62
64
|
inmediato; aquí la elección espera al «Guardar». Es trabajo de `sui-radio-card`.
|
|
63
|
-
- **1 con textos largos, a verificar en mobile:** `pages/super-admin/master-roles/master-roles.html:
|
|
65
|
+
- **1 con textos largos, a verificar en mobile:** `pages/super-admin/master-roles/master-roles.html:48`
|
|
64
66
|
(«Administrador de ciudad» / «Jefe de operaciones»). Por ancho de texto quedan apretados cerca
|
|
65
67
|
del borde a 390 px; no se midió en la pantalla real.
|
|
66
|
-
- **2 en `small` con texto** (
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
- **2 en `small` con texto** (D16: `small` no se usa): `master-settings.html:281` y `:314`. El
|
|
69
|
+
tercero, `pages/products/products.html:83`, va en `small` en la computadora con solo íconos: con
|
|
70
|
+
D16 también pasa a `medium`.
|
|
71
|
+
- **Sin tamaño por dispositivo** (revisado el 06-10-2026): `master-roles.html:48` (sin `size`) y
|
|
72
|
+
`pages/super-admin/master-categorias/master-categorias.html:124` (`medium` fijo) se quedan en 28
|
|
73
|
+
en el teléfono; `master-settings.html:224` usa `tallaServicio()` (`master-settings.ts:452`), que
|
|
74
|
+
da `large` (32) en el teléfono. Los que cortan con `bp.isMobile()`
|
|
75
|
+
(`pages/driver/driver-schedule/driver-schedule.html:31`, `pages/overview/overview.html:45`,
|
|
76
|
+
`pages/driver/driver-dashboard/driver-dashboard.html:865`) dejan la tablet táctil en `medium`.
|
|
71
77
|
|
|
72
78
|
## Tamaño en mobile y en web
|
|
73
79
|
|
|
@@ -80,18 +86,36 @@ En large, xlarge y 2xlarge el texto sube a 16 px (regla del 03-10-2026): Label/M
|
|
|
80
86
|
`large` el padding del segmento con texto bajó de 6 a 4 para que siga midiendo 32.
|
|
81
87
|
|
|
82
88
|
**`2xlarge` es el size del teléfono**: 44 px por segmento, con texto o solo ícono (canon (dueño,
|
|
83
|
-
04-10-2026): piso táctil 44 en el teléfono). `xlarge` (40) no
|
|
84
|
-
|
|
89
|
+
04-10-2026): piso táctil 44 en el teléfono). `xlarge` (40) no se usa: no llega a 44 y ninguna
|
|
90
|
+
pantalla de la app lo tiene.
|
|
85
91
|
|
|
86
92
|
| uso | mobile | web | fuente |
|
|
87
93
|
|---|---|---|---|
|
|
88
94
|
| modos con texto (local del horario, rol) | `2xlarge` (segmento de 44 px) | `medium` | canon (dueño, 04-10-2026): piso táctil 44 en el teléfono |
|
|
89
|
-
| solo íconos en una barra (cuadrícula / lista) | `2xlarge` (44) | `
|
|
95
|
+
| solo íconos en una barra (cuadrícula / lista) | `2xlarge` (44) | `medium` | mobile: canon (dueño, 04-10-2026): piso táctil 44 en el teléfono · web: canon (dueño, 05-10-2026, D16), antes `small` |
|
|
90
96
|
|
|
91
97
|
```html
|
|
92
|
-
<sui-segmented-control [size]="bp.
|
|
98
|
+
<sui-segmented-control [size]="bp.tactil() ? '2xlarge' : 'medium'" … />
|
|
93
99
|
```
|
|
94
100
|
|
|
101
|
+
### Por dispositivo (D16)
|
|
102
|
+
|
|
103
|
+
Fila de `segmented-control` en la tabla de D16 (dueño, 05-10-2026): se toca, y el size que llega a
|
|
104
|
+
44 es `2xlarge`.
|
|
105
|
+
|
|
106
|
+
| dispositivo | size | nota |
|
|
107
|
+
|---|---|---|
|
|
108
|
+
| celular chico (< 380 px) | `2xlarge` (44) | D16 pide `medium` con área de 44, pero el DS todavía no estira el área de los `medium` (nota ¹ de D16): hasta entonces se queda el grande |
|
|
109
|
+
| celular (380–767 px) | `2xlarge` (44) | con texto o solo íconos |
|
|
110
|
+
| tablet táctil (`pointer: coarse`) | `2xlarge` (44) | Apple pide 44 también en el iPad |
|
|
111
|
+
| computadora (`pointer: fine`) | `medium` (28) | también solo íconos en una barra; nunca `small` |
|
|
112
|
+
|
|
113
|
+
Ultrawide (≥ 1920 px): igual que la computadora, `medium`; el espacio extra va al `max-width`, no a
|
|
114
|
+
segmentos más altos.
|
|
115
|
+
|
|
116
|
+
En master-pedidos: `[size]="bp.tactil() ? '2xlarge' : 'medium'"`. No hay helper: `bp.sizeChips()`
|
|
117
|
+
llega a `xlarge` (40) y `bp.sizeControl()` a `large` (32), y ninguno de los dos da 44 aquí.
|
|
118
|
+
|
|
95
119
|
## «No usar»: por qué no hoy y cuándo sí
|
|
96
120
|
|
|
97
121
|
| qué | por qué no hoy | cuándo sí, en un flujo nuevo |
|
|
@@ -145,12 +169,57 @@ interface SuiSegmentedControlItem<T = string> {
|
|
|
145
169
|
- Los tamaños son extensión de SUI: la guía tiene uno solo. Su versión redondeada (`Rounded`)
|
|
146
170
|
no existe en SUI.
|
|
147
171
|
|
|
172
|
+
## Bien y mal
|
|
173
|
+
|
|
174
|
+
Vista cuadrícula / lista
|
|
175
|
+
|
|
176
|
+
```html
|
|
177
|
+
<!-- ❌ mal: `small` en la computadora; D16 no usa `small` (pages/products/products.html:83) -->
|
|
178
|
+
<sui-segmented-control [size]="bp.isMobile() ? '2xlarge' : 'small'"
|
|
179
|
+
[tabs]="viewToggleItems" [(active)]="viewMode" />
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
```html
|
|
183
|
+
<!-- ✅ bien -->
|
|
184
|
+
<sui-segmented-control [size]="bp.tactil() ? '2xlarge' : 'medium'"
|
|
185
|
+
[tabs]="viewToggleItems" [(active)]="viewMode" />
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Modo del servicio en el panel
|
|
189
|
+
|
|
190
|
+
```html
|
|
191
|
+
<!-- ❌ mal: `large` (32) en el teléfono no llega a 44 (master-settings.html:224, tallaServicio en master-settings.ts:452) -->
|
|
192
|
+
<sui-segmented-control [size]="bp.isMobile() ? 'large' : 'medium'"
|
|
193
|
+
ariaLabel="Cómo se cobra la tarifa de servicio"
|
|
194
|
+
[tabs]="MODOS_SERVICIO" [active]="borrador().servicioModo" (tabChange)="setModoServicio($event)" />
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
```html
|
|
198
|
+
<!-- ✅ bien -->
|
|
199
|
+
<sui-segmented-control [size]="bp.tactil() ? '2xlarge' : 'medium'"
|
|
200
|
+
ariaLabel="Cómo se cobra la tarifa de servicio"
|
|
201
|
+
[tabs]="MODOS_SERVICIO" [active]="borrador().servicioModo" (tabChange)="setModoServicio($event)" />
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Rol a invitar
|
|
205
|
+
|
|
206
|
+
```html
|
|
207
|
+
<!-- ❌ mal: sin `size` ni `ariaLabel`: 28 px también en el teléfono y el grupo sin nombre (pages/super-admin/master-roles/master-roles.html:48) -->
|
|
208
|
+
<sui-segmented-control [tabs]="rolesCiudad" [active]="rolStaff()" (activeChange)="rolStaff.set($any($event))" />
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
```html
|
|
212
|
+
<!-- ✅ bien -->
|
|
213
|
+
<sui-segmented-control [size]="bp.tactil() ? '2xlarge' : 'medium'" ariaLabel="Rol"
|
|
214
|
+
[tabs]="rolesCiudad" [active]="rolStaff()" (activeChange)="rolStaff.set($any($event))" />
|
|
215
|
+
```
|
|
216
|
+
|
|
148
217
|
## Ejemplo
|
|
149
218
|
|
|
150
219
|
```html
|
|
151
220
|
<div style="max-width: 320px">
|
|
152
221
|
<sui-segmented-control
|
|
153
|
-
[size]="bp.
|
|
222
|
+
[size]="bp.tactil() ? '2xlarge' : 'medium'"
|
|
154
223
|
[tabs]="[{ value: 'grid', label: 'Vista cuadrícula', icon: 'layout-grid-line', iconOnly: true },
|
|
155
224
|
{ value: 'list', label: 'Vista lista', icon: 'list-unordered', iconOnly: true }]"
|
|
156
225
|
[(active)]="vista" />
|
|
@@ -46,7 +46,7 @@ Regla corta: **sale de datos o son más de 6 → select · 2–6 fijas → radio
|
|
|
46
46
|
| La lista sale de datos (ubigeo, repartidores, categorías, planes) | `sui-select` | según la guía del DS (elegir una opción de un menú) |
|
|
47
47
|
| Más de ~6 opciones fijas | `sui-select` | derivado del README de `sui-radio` («más de ~6 → select»), falta confirmación |
|
|
48
48
|
| 2 a 6 opciones fijas en un formulario | `sui-radio-label` / `sui-radio-card` | propuesta, falta aprobación (sale del umbral de `sui-radio`) |
|
|
49
|
-
| 2 a 4 modos que se aplican al instante | `sui-segmented-control` | según la guía del DS («aplicarla de inmediato», ver README de `sui-segmented-control`); el tope de 4
|
|
49
|
+
| 2 a 4 modos que se aplican al instante | `sui-segmented-control` | según la guía del DS («aplicarla de inmediato», ver README de `sui-segmented-control`); el tope de 4: canon (decisión del dueño 04-10-2026: 2 a 4 opciones excluyentes → segmented, 5 o más → tab-chips) |
|
|
50
50
|
| Filtro de una barra con 5 o más opciones | `sui-select` sin label (o `sui-compact-select` en web) | propuesta, falta aprobación |
|
|
51
51
|
|
|
52
52
|
**Candidatos de hoy** (no rompen nada; se verían mejor con radios o segmented):
|
|
@@ -69,11 +69,11 @@ Regla corta: **sale de datos o son más de 6 → select · 2–6 fijas → radio
|
|
|
69
69
|
|---|---|---|
|
|
70
70
|
| `type="basic"` (default) sin ícono | Todo select de la app hoy. | según la guía del DS |
|
|
71
71
|
| `type="avatar"` + `imageUrl` | Elegir un **repartidor**: la foto de quien quedó elegido en el campo. Hoy `pages/orders/orders.html:257` muestra solo el nombre. | según la guía del DS (ejemplo «User»); el caso es propuesta |
|
|
72
|
-
| `type="provider"` + `imageUrl` | Método de pago con logo (Yape, Plin). | según la guía del DS (ejemplo «Payment Method»); el caso
|
|
72
|
+
| `type="provider"` + `imageUrl` | Método de pago con logo (Yape, Plin). | según la guía del DS (ejemplo «Payment Method»); el caso, canon (aprobado por el dueño, 05-10-2026, bloque B2) |
|
|
73
73
|
| `leadingIcon` (`true` o nombre RemixIcon) | Un ícono que ayuda a reconocer el campo en un formulario largo. Hoy sin caso. | según la guía del DS (ejemplo «Icons») |
|
|
74
74
|
| `type="country"` + `flag` | No usar hoy: todo es Perú. | según la guía del DS (ejemplo «Country») |
|
|
75
|
-
| `type="brand"` / `"company"` | No usar hoy. |
|
|
76
|
-
| `badge` | No usar hoy. |
|
|
75
|
+
| `type="brand"` / `"company"` | No usar hoy. | canon (aprobado por el dueño, 05-10-2026, bloque B6) |
|
|
76
|
+
| `badge` | No usar hoy. | canon (aprobado por el dueño, 05-10-2026, bloque B6) |
|
|
77
77
|
|
|
78
78
|
### Las piezas
|
|
79
79
|
|
|
@@ -109,15 +109,37 @@ y las opciones de la lista; el alto no cambia (las opciones bajan 2 de padding p
|
|
|
109
109
|
|
|
110
110
|
| uso | mobile | web | fuente |
|
|
111
111
|
|---|---|---|---|
|
|
112
|
-
| campo de formulario | `large` (48) | `medium` (40) |
|
|
113
|
-
| filtro de una barra | `large` (48) | `
|
|
114
|
-
| dentro de una tabla
|
|
115
|
-
| `xlarge` (52) | no usar | no usar |
|
|
112
|
+
| campo de formulario | `large` (48) | `medium` (40) | mobile `large`: canon (decisión del dueño 04-10-2026, piso táctil 44: `medium` 40 no llega y `large` 48 es el primer size que sí) · web `medium`: canon (aprobado por el dueño, 05-10-2026, bloque B1) |
|
|
113
|
+
| filtro de una barra | `large` (48) | `medium` (40) | mobile `large`: canon (decisión del dueño 04-10-2026, piso táctil 44: `large` 48 es el primer size que llega) · web `medium`: canon (dueño, 05-10-2026, D16) (el `small` de `pages/orders/orders.html:257` ya se migró a `bp.sizeControl()`) |
|
|
114
|
+
| dentro de una tabla | no aplica | `medium` (40) | canon (dueño, 05-10-2026, D16): nada en `xsmall` (la guía del DS lo usa en tablas densas) |
|
|
115
|
+
| `xlarge` (52) | no usar | no usar | canon (aprobado por el dueño, 05-10-2026, bloque B6): queda más alto que el botón `large` del footer |
|
|
116
116
|
|
|
117
117
|
```html
|
|
118
|
-
<sui-select [size]="bp.
|
|
118
|
+
<sui-select [size]="bp.sizeControl()" label="Distrito" … /> <!-- bp = BreakpointsService · D16, dueño 05-10-2026 -->
|
|
119
119
|
```
|
|
120
120
|
|
|
121
|
+
### Por dispositivo (D16)
|
|
122
|
+
|
|
123
|
+
Fila `select` de la tabla D16 (dueño, 05-10-2026): se decide por el tipo de puntero además del ancho.
|
|
124
|
+
|
|
125
|
+
| dispositivo | size | nota |
|
|
126
|
+
|---|---|---|
|
|
127
|
+
| celular chico (< 380 px) | `large` (48) | interino: D16 pide `medium` con área tocable de 44; hasta que el DS la estire, se queda el grande (nota ¹ de D16) |
|
|
128
|
+
| celular (380–767 px) | `large` (48) | el primer size que llega al piso táctil de 44 |
|
|
129
|
+
| tablet táctil (`pointer: coarse`) | `large` (48) | Apple pide 44 pt también en iPad; con `bp.isMobile()` el iPad quedaba en `medium` 40 |
|
|
130
|
+
| computadora (`pointer: fine`) | `medium` (40) | también en filtros de barra y dentro de tablas; nunca `small` ni `xsmall` |
|
|
131
|
+
|
|
132
|
+
Ultrawide (≥ 1920 px): igual que la computadora, `medium`. El espacio extra va a ancho máximo y columnas, no a un campo más alto.
|
|
133
|
+
|
|
134
|
+
En master-pedidos: `[size]="bp.sizeControl()"`. Re-medido el 06-10-2026: 52 de 56 `<sui-select>` ya lo usan. Faltan 4:
|
|
135
|
+
|
|
136
|
+
- `pages/driver/driver-dashboard/driver-dashboard.html:1507`: `size="large"` fijo por pedido del dueño (22-09-2026),
|
|
137
|
+
pendiente de confirmar si D16 lo reemplaza.
|
|
138
|
+
- `pages/super-admin/master-preview/master-preview.html:807` y `:813`: sin `size`, salen en `medium` (el default) en
|
|
139
|
+
todos los dispositivos. Es la vitrina del super admin.
|
|
140
|
+
- `pages/super-admin/master-preview/_ruta-pedido/ruta-pedido.html:12`: sin `size`, sale en `medium`. Es la pantalla de
|
|
141
|
+
diagnóstico `/dx/ruta-pedido` (auditor de rutas del super admin), no una vitrina.
|
|
142
|
+
|
|
121
143
|
## «No usar»: por qué no hoy y cuándo sí
|
|
122
144
|
|
|
123
145
|
| qué | por qué no hoy | cuándo sí, en un flujo nuevo |
|
|
@@ -126,7 +148,7 @@ y las opciones de la lista; el alto no cambia (las opciones bajan 2 de padding p
|
|
|
126
148
|
| `type="brand"` / `"company"` | no hay listas de marcas o empresas | elegir la marca de un producto envasado o la empresa de una flota |
|
|
127
149
|
| `leadingIcon` | ningún formulario lo necesita para reconocerse | un formulario largo del panel con varios selects seguidos |
|
|
128
150
|
| `badge` | no hay valores que marcar | marcar el plan elegido como «Recomendado» |
|
|
129
|
-
| `size="xsmall"` |
|
|
151
|
+
| `size="xsmall"` | es chico (D16, 05-10-2026) | nunca: cambiar el estado de una fila va con un select `medium` |
|
|
130
152
|
| `size="xlarge"` | queda más alto que el botón del footer | un select solo, como acción principal de la pantalla |
|
|
131
153
|
|
|
132
154
|
## API
|
|
@@ -176,12 +198,59 @@ decoración propia del campo (gana sobre ícono, imagen y bandera).
|
|
|
176
198
|
label, con el placeholder), apunta al listbox abierto (`aria-controls`) y anuncia la opción
|
|
177
199
|
resaltada con las flechas (`aria-activedescendant`). Hint y error van en `aria-describedby`.
|
|
178
200
|
|
|
201
|
+
## Bien y mal
|
|
202
|
+
|
|
203
|
+
**Filtro de período con 3 opciones**
|
|
204
|
+
|
|
205
|
+
```html
|
|
206
|
+
<!-- ❌ mal: 3 opciones excluyentes que se aplican al tocar, escondidas en un menú (pages/discounts/discounts.html:49) -->
|
|
207
|
+
<sui-select [size]="bp.sizeControl()" placeholder="Período"
|
|
208
|
+
[options]="periodOptions" [value]="selectedPeriod()"
|
|
209
|
+
(valueChange)="selectedPeriod.set($event ?? '7days')" />
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
```html
|
|
213
|
+
<!-- ✅ bien: 2 a 4 opciones excluyentes → sui-segmented-control (canon, dueño 04-10-2026) -->
|
|
214
|
+
<sui-segmented-control [size]="bp.tactil() ? '2xlarge' : 'medium'"
|
|
215
|
+
[tabs]="periodos" [(active)]="periodo" />
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**El valor que vuelve del select**
|
|
219
|
+
|
|
220
|
+
```html
|
|
221
|
+
<!-- ❌ mal: `$any` es un `any` disfrazado y además deja pasar el `null` (pages/super-admin/super-admin.html:317) -->
|
|
222
|
+
<sui-select [size]="bp.sizeControl()" label="Plan" placeholder="Elige…"
|
|
223
|
+
[options]="planSelectOptions()" [value]="subPlan()"
|
|
224
|
+
(valueChange)="subPlan.set($any($event))" />
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
```html
|
|
228
|
+
<!-- ✅ bien: opciones tipadas (SuiSelectOption<string>[]) y el null resuelto en el template -->
|
|
229
|
+
<sui-select [size]="bp.sizeControl()" label="Plan" placeholder="Elige…"
|
|
230
|
+
[options]="planSelectOptions()" [value]="subPlan()"
|
|
231
|
+
(valueChange)="subPlan.set($event ?? 'crecimiento')" />
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**El size por dispositivo**
|
|
235
|
+
|
|
236
|
+
```html
|
|
237
|
+
<!-- ❌ mal: solo mira el ancho; el iPad (≥ 768, táctil) recibe `medium` 40, bajo el piso de 44 -->
|
|
238
|
+
<sui-select [size]="bp.isMobile() ? 'large' : 'medium'" label="Distrito"
|
|
239
|
+
placeholder="Elige el distrito" [options]="distritos()" />
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
```html
|
|
243
|
+
<!-- ✅ bien: el helper de D16 (`large` en celular y tablet táctil, `medium` en la computadora) -->
|
|
244
|
+
<sui-select [size]="bp.sizeControl()" label="Distrito"
|
|
245
|
+
placeholder="Elige el distrito" [options]="distritos()" />
|
|
246
|
+
```
|
|
247
|
+
|
|
179
248
|
## Ejemplo
|
|
180
249
|
|
|
181
250
|
```html
|
|
182
251
|
<sui-select label="Distrito" [required]="true" placeholder="Elige tu distrito"
|
|
183
252
|
[options]="distritos()" [disabled]="!provinciaId()"
|
|
184
253
|
[error]="intentado() && !distritoId()" errorMessage="Elige tu distrito"
|
|
185
|
-
[size]="bp.
|
|
254
|
+
[size]="bp.sizeControl()"
|
|
186
255
|
[value]="distritoId()" (valueChange)="distritoId.set($event ?? '')" />
|
|
187
256
|
```
|
|
@@ -31,8 +31,8 @@ Regla corta: **navegación del rol → sidebar · secciones de una pantalla →
|
|
|
31
31
|
> **La guía del DS no tiene página del sidebar.** El componente sale del Figma de SUI (Sidebar
|
|
32
32
|
> [Navigation], node 3802:11759) y el cajón de mobile no existe en ese Figma: se portó del layout
|
|
33
33
|
> del super admin. Lo de abajo es **práctica de la app** (los 4 usos están homologados desde el
|
|
34
|
-
> 25-07-2026) o **propuesta, falta aprobación**; lo marcado «canon» sale de `docs/CANON-SUI.md
|
|
35
|
-
>
|
|
34
|
+
> 25-07-2026) o **propuesta, falta aprobación**; lo marcado «canon» sale de `docs/CANON-SUI.md`,
|
|
35
|
+
> de `master-pedidos/CLAUDE.md` o de la aprobación del dueño del 05-10-2026.
|
|
36
36
|
>
|
|
37
37
|
> Uso medido el 03-10-2026 en `master-pedidos/src/app`: **4 sidebars**, sin contar vitrinas
|
|
38
38
|
> (`master-preview` tiene el quinto).
|
|
@@ -44,11 +44,11 @@ Regla corta: **navegación del rol → sidebar · secciones de una pantalla →
|
|
|
44
44
|
| `brand` | `{ name: 'Master Pedidos', subtitle: '<Rol>', logo: 'assets/app-icon.png', fallback: 'M' }`. En empresa, el nombre del local. | práctica de la app (4 de 4) |
|
|
45
45
|
| `showHeaderButton` + `headerButtonActive` + panel `[header-panel]` | El botón del header abre el **cambio de rol** (o de negocio/sucursal en empresa). El panel se proyecta con `<div header-panel>` y adentro van `sui-dropdown-item mode="option" size="large"`. El cliente lo muestra solo en mobile. | práctica de la app (4 de 4) |
|
|
46
46
|
| tres secciones con rótulo | `items` + `itemsLabel` (lo de todos los días), `secondaryItems` + `secondaryItemsLabel` (dinero o crecimiento), `supportingItems` + `supportingItemsLabel` (cuenta, administración: va anclado abajo). Rótulos en sentence case: «Operación», «Dinero», «Cuenta». | práctica de la app (4 de 4) |
|
|
47
|
-
| `activeRoute` |
|
|
47
|
+
| `activeRoute` | No hace falta si los items de navegación llevan `route`: el `<a>` usa `routerLinkActive` y marca por prefijo (`/cliente/pedidos/123` deja «Mis pedidos» activo). `activeRoute` solo marca items **sin** `route`, y por `value` exacto (`activeRoute="pedidos"`), para demos sin router (`sui-sidebar.ts:369-412`). Los 4 layouts pasan `[activeRoute]="currentUrl()"`, pero no cambia nada: todos sus items de navegación tienen `route` y la URL nunca es igual al `value` de un item-acción. | comportamiento del `.ts` · práctica de la app (4 de 4 lo pasan, sin efecto) |
|
|
48
48
|
| `profile` | Nombre + `avatarUrl` (nunca `photoURL`) + correo. | canon (CLAUDE.md, «Fotos de otra persona»: el campo correcto es `avatarUrl`) |
|
|
49
49
|
| cerrar sesión | Hoy **ningún** item usa `action: 'logout'`: el cierre real vive en el selector de rol y el «salir» del panel solo cambia de rol (`components/sidebar/sidebar.ts:367`). Los 4 layouts dejan `(logoutClicked)` conectado por si se agrega. | práctica de la app |
|
|
50
|
-
| `[(mobileOpen)]` + `closeOnItemClick` | Siempre los dos. Más `cerrarAlNavegar(...)` en el constructor del layout (ver Trampas). | canon (CANON-SUI §1.1) |
|
|
51
|
-
| `search` | `{
|
|
50
|
+
| `[(mobileOpen)]` + `closeOnItemClick` | Siempre los dos (`closeOnItemClick` ya es `true` por defecto; los 4 layouts lo pasan explícito). Más `cerrarAlNavegar(...)` en el constructor del layout (ver Trampas). | canon (CANON-SUI §1.1) |
|
|
51
|
+
| `search` | `{ shortcut: '⌘K' }` (el placeholder por defecto ya es «Buscar…», con elipsis) y el layout **filtra** los items con `searchValue` (el componente no filtra). | buscador: práctica de la app (4 de 4) · `shortcut: '⌘K'`: práctica de la app (3 de 4; el cliente no lo pasa, `layouts/customer/customer-layout.html:12`) · la elipsis «…»: canon (CANON-SUI, copy); los 4 layouts todavía pasan «Buscar...» (ver «Bien y mal») |
|
|
52
52
|
| `indicatorColor` | Default `brand` (naranja). No se cambia. | canon del DS (accent = marca) |
|
|
53
53
|
| `collapsed` | Solo el cliente lo usa, con un item «colapsar», y **solo en web**: `[collapsed]="colapsado() && !bp.isMobile()"`. | práctica de la app (1 uso) |
|
|
54
54
|
|
|
@@ -56,12 +56,12 @@ Regla corta: **navegación del rol → sidebar · secciones de una pantalla →
|
|
|
56
56
|
|
|
57
57
|
| prop | cuándo | fuente |
|
|
58
58
|
|---|---|---|
|
|
59
|
-
| `icon` | Siempre, RemixIcon `-line`. Sin ícono, el modo colapsado queda vacío. |
|
|
59
|
+
| `icon` | Siempre, RemixIcon `-line`. Sin ícono, el modo colapsado queda vacío. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
|
|
60
60
|
| `route` | Navegación normal (usa `routerLink`). | práctica de la app |
|
|
61
61
|
| sin `route` | Acción, no navegación (abrir Configuración, colapsar): `action` o solo `value`, y se escucha `(itemClicked)`. | práctica de la app |
|
|
62
|
-
| `badge` | Un contador que pide acción: notificaciones sin leer, con tope «99+» (`components/sidebar/sidebar.ts:129`). Nunca un «NEW» decorativo. | práctica de la app
|
|
63
|
-
| `variant: 'danger'` | Solo «Cerrar sesión» o salidas destructivas. |
|
|
64
|
-
| `shortcut`, `colorDot` | No usar (ver «No usar»). |
|
|
62
|
+
| `badge` | Un contador que pide acción: notificaciones sin leer, con tope «99+» (`components/sidebar/sidebar.ts:129`). Nunca un «NEW» decorativo. | práctica de la app · el «nunca NEW»: canon (aprobado por el dueño, 05-10-2026, bloque B9) |
|
|
63
|
+
| `variant: 'danger'` | Solo «Cerrar sesión» o salidas destructivas. | «Cerrar sesión» en rojo: canon (decisión del dueño 04-10-2026, salida destructiva en `color error` aunque sea un link; `danger` pinta `--sui-state-error-base`) · el «solo» (ningún otro item en rojo): canon (aprobado por el dueño, 05-10-2026, bloque B3) |
|
|
64
|
+
| `shortcut`, `colorDot` | No usar (ver «No usar»). | canon (aprobado por el dueño, 05-10-2026, bloque B6) |
|
|
65
65
|
|
|
66
66
|
## Tamaño en mobile y en web
|
|
67
67
|
|
|
@@ -78,7 +78,7 @@ El sidebar **no tiene `size`**. El ancho lo decide el viewport:
|
|
|
78
78
|
|---|---|---|---|
|
|
79
79
|
| navegación del rol | cajón `drawer`, cerrado por defecto | columna fija de 272 | práctica de la app (4 de 4) |
|
|
80
80
|
| colapsar | nunca (`!bp.isMobile()`) | opcional, a pedido de la persona | práctica de la app |
|
|
81
|
-
| `sheet` | no usar (0 usos) | — |
|
|
81
|
+
| `sheet` | no usar (0 usos) | — | canon (aprobado por el dueño, 05-10-2026, bloque B6) |
|
|
82
82
|
|
|
83
83
|
**Qué pasa en mobile (≤ 767 px):** el sidebar sale del flujo y queda `position: fixed` fuera de la
|
|
84
84
|
pantalla. Lo abre la acción `toggle-sidebar` de la **barra inferior** («Más»), que el layout
|
|
@@ -87,6 +87,16 @@ con el fondo, con Escape, al tocar un item (`closeOnItemClick`) y —por el help
|
|
|
87
87
|
al terminar cualquier navegación. Cerrado queda `inert` y `aria-hidden`: el foco no se mete.
|
|
88
88
|
Respeta las safe areas de arriba, izquierda y abajo.
|
|
89
89
|
|
|
90
|
+
### Por dispositivo (D16)
|
|
91
|
+
|
|
92
|
+
El sidebar **no tiene `size`**: D16 (dueño, 05-10-2026) no le da un tamaño que pasar. El alto de los items lo pone el DS por
|
|
93
|
+
ancho: 52 en el cajón (≤ 767 px, `padding: 14px` + ícono 24) y 36 en la columna (> 767 px). Hueco conocido: una tablet táctil
|
|
94
|
+
(iPad, ≥ 768 px y `pointer: coarse`) recibe la columna con items de 36, bajo el piso de 44 que D16 pide para lo que se toca.
|
|
95
|
+
Queda **pendiente del DS** (el mixin `sui-tactil` de la propuesta de D16, que todavía espera el sí del dueño); desde la app no
|
|
96
|
+
se corrige.
|
|
97
|
+
|
|
98
|
+
En master-pedidos: no se pasa `size`; lo único que depende del dispositivo es `[collapsed]="colapsado() && !bp.isMobile()"`.
|
|
99
|
+
|
|
90
100
|
## «No usar»: por qué no hoy y cuándo sí
|
|
91
101
|
|
|
92
102
|
| qué | por qué no hoy | cuándo sí, en un flujo nuevo |
|
|
@@ -170,16 +180,62 @@ Slots: `[header-panel]` (debajo del header: el switcher), `[feature-card]` (al f
|
|
|
170
180
|
filtra los items (`master-layout.ts:125`). Su placeholder por defecto es «Buscar…» (en español desde el 04-10-2026).
|
|
171
181
|
- **`collapsed` no mira el viewport.** Con `collapsed` en `true`, el cajón de mobile también sale
|
|
172
182
|
de 80 px. Condiciónalo: `[collapsed]="colapsado() && !bp.isMobile()"`.
|
|
173
|
-
- Un item con `route`
|
|
174
|
-
`
|
|
175
|
-
|
|
176
|
-
|
|
183
|
+
- Un item con `route` (y sin `action`) queda activo **solo** por `routerLinkActive`, por prefijo:
|
|
184
|
+
`isItemActive()` devuelve `false` para todo item con `route` (`sui-sidebar.ts:411`), así que
|
|
185
|
+
`activeRoute` no lo toca. Un item sin `route` solo por `activeRoute`, y por `value` exacto
|
|
186
|
+
(`sui-sidebar.ts:379`): pasarle la URL actual no lo marca nunca.
|
|
187
|
+
- Cualquier `action` (no solo `'logout'`) anula el `route`: el item se pinta como `<button>`, no navega y
|
|
188
|
+
tampoco se marca activo (tiene `route`, así que `isItemActive()` da `false`, y no hay `routerLinkActive`).
|
|
177
189
|
- El `title` nativo del host se borra (sin tooltip gris); en colapsado el tooltip va en cada item.
|
|
178
190
|
- El cajón tiene `z-index: 300` sobre la barra inferior (200). Mientras está abierto el layout
|
|
179
191
|
esconde la barra (`customer-layout.ts:66`); si armas un layout nuevo, haz lo mismo.
|
|
180
192
|
- El comentario de cabecera del `.ts` todavía dice 240 px; el ancho real es 272 (`sui-sidebar.scss:50`).
|
|
181
193
|
- Los items ya traen el arreglo de iOS del `:active` pegado: no lo agregues.
|
|
182
194
|
|
|
195
|
+
## Bien y mal
|
|
196
|
+
|
|
197
|
+
**El buscador**
|
|
198
|
+
|
|
199
|
+
```html
|
|
200
|
+
<!-- ❌ mal: tres puntos sueltos en vez de elipsis. Así en components/sidebar/sidebar.html:48, layouts/driver/driver-layout.html:9 y layouts/master/master-layout.html:10; layouts/customer/customer-layout.html:12 pasa el mismo «Buscar...» sin `shortcut` -->
|
|
201
|
+
<sui-sidebar [search]="{ placeholder: 'Buscar...', shortcut: '⌘K' }"
|
|
202
|
+
[(searchValue)]="busqueda" [items]="items()" />
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
```html
|
|
206
|
+
<!-- ✅ bien: sin placeholder sale «Buscar…»; el layout filtra `items()` con `busqueda` -->
|
|
207
|
+
<sui-sidebar [search]="{ shortcut: '⌘K' }"
|
|
208
|
+
[(searchValue)]="busqueda" [items]="items()" />
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**Colapsar**
|
|
212
|
+
|
|
213
|
+
```html
|
|
214
|
+
<!-- ❌ mal: `collapsed` no mira el viewport; el cajón de mobile también sale de 80 px, solo íconos -->
|
|
215
|
+
<sui-sidebar [collapsed]="colapsado()" [items]="items()" [(mobileOpen)]="menuAbierto" />
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
```html
|
|
219
|
+
<!-- ✅ bien: se colapsa solo en web (layouts/customer/customer-layout.html:7) -->
|
|
220
|
+
<sui-sidebar [collapsed]="colapsado() && !bp.isMobile()" [items]="items()" [(mobileOpen)]="menuAbierto" />
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**El item activo**
|
|
224
|
+
|
|
225
|
+
```ts
|
|
226
|
+
// ❌ mal: navegar con `action` + `(itemClicked)` y `router.navigate`. El item se pinta como `<button>`,
|
|
227
|
+
// no como `<a routerLink>`, y nunca queda activo: sin `route`, `activeRoute` solo lo marca si es igual
|
|
228
|
+
// a su `value` (`sui-sidebar.ts:379`), y `[activeRoute]="currentUrl()"` nunca lo es
|
|
229
|
+
{ value: 'pedidos', label: 'Mis pedidos', icon: 'time-line', action: 'ir-a-pedidos' }
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
// ✅ bien: con `route` (y sin `action`) el item es un `<a routerLink>` y `routerLinkActive` lo marca por
|
|
234
|
+
// prefijo: `/cliente/pedidos/123` deja «Mis pedidos» activo sin pasar `activeRoute`
|
|
235
|
+
// (layouts/customer/customer-layout.ts:287)
|
|
236
|
+
{ value: 'pedidos', label: 'Mis pedidos', icon: 'time-line', route: '/cliente/pedidos' }
|
|
237
|
+
```
|
|
238
|
+
|
|
183
239
|
## Ejemplo
|
|
184
240
|
|
|
185
241
|
```html
|
|
@@ -188,12 +244,11 @@ Slots: `[header-panel]` (debajo del header: el switcher), `[feature-card]` (al f
|
|
|
188
244
|
[showHeaderButton]="true"
|
|
189
245
|
[headerButtonActive]="switcherOpen()"
|
|
190
246
|
(headerButtonClicked)="switcherOpen.set(!switcherOpen())"
|
|
191
|
-
[search]="{
|
|
247
|
+
[search]="{ shortcut: '⌘K' }"
|
|
192
248
|
[(searchValue)]="busqueda"
|
|
193
249
|
itemsLabel="Operación" [items]="items()"
|
|
194
250
|
secondaryItemsLabel="Dinero" [secondaryItems]="itemsDinero()"
|
|
195
251
|
supportingItemsLabel="Cuenta" [supportingItems]="itemsCuenta()"
|
|
196
|
-
[activeRoute]="currentUrl()"
|
|
197
252
|
[profile]="perfil()"
|
|
198
253
|
[(mobileOpen)]="menuAbierto"
|
|
199
254
|
[closeOnItemClick]="true"
|
|
@@ -38,19 +38,19 @@ Regla corta: **escala con tope y la posición importa → slider · número exac
|
|
|
38
38
|
| type | cuándo | fuente |
|
|
39
39
|
|---|---|---|
|
|
40
40
|
| `single` (default) | Un valor: radio de cobertura, porcentaje. | según la guía del DS |
|
|
41
|
-
| `range` | Un mínimo y un máximo en la misma escala: rango de precios de un filtro. Una sola barra con dos manijas, nunca dos sliders. | según la guía del DS (existe); el «cuándo
|
|
41
|
+
| `range` | Un mínimo y un máximo en la misma escala: rango de precios de un filtro. Una sola barra con dos manijas, nunca dos sliders. | según la guía del DS (existe); el «cuándo», canon (aprobado por el dueño, 05-10-2026, bloque B2) |
|
|
42
42
|
|
|
43
43
|
### Las piezas
|
|
44
44
|
|
|
45
45
|
| prop | cuándo | fuente |
|
|
46
46
|
|---|---|---|
|
|
47
|
-
| `label` | Siempre que el slider no esté dentro de un campo que ya lo titula. Sin `label` desaparece toda la fila de arriba, `amount` incluido. |
|
|
48
|
-
| `amount` | El valor con su unidad, a la derecha del label: «12 km», «S/ 10 – S/ 40». Sin `amount` escribe el número pelado. |
|
|
49
|
-
| `sublabel` | Una precisión corta junto al label: «(máximo 15)». |
|
|
50
|
-
| `tooltip` | Solo **sin** `amount`: el número flota sobre la manija mientras se arrastra. Con `amount` repite el valor y sin unidad. | según la guía del DS (existe); el «cuándo
|
|
51
|
-
| `tooltipAlways` | No usar (ver abajo). |
|
|
47
|
+
| `label` | Siempre que el slider no esté dentro de un campo que ya lo titula. Sin `label` desaparece toda la fila de arriba, `amount` incluido. | canon (aprobado por el dueño, 05-10-2026, bloque B4) |
|
|
48
|
+
| `amount` | El valor con su unidad, a la derecha del label: «12 km», «S/ 10 – S/ 40». Sin `amount` escribe el número pelado. | canon (aprobado por el dueño, 05-10-2026, bloque B4) |
|
|
49
|
+
| `sublabel` | Una precisión corta junto al label: «(máximo 15)». | canon (aprobado por el dueño, 05-10-2026, bloque B4) |
|
|
50
|
+
| `tooltip` | Solo **sin** `amount`: el número flota sobre la manija mientras se arrastra. Con `amount` repite el valor y sin unidad. | según la guía del DS (existe); el «cuándo», canon (aprobado por el dueño, 05-10-2026, bloque B9) |
|
|
51
|
+
| `tooltipAlways` | No usar (ver abajo). | canon (aprobado por el dueño, 05-10-2026, bloque B6) |
|
|
52
52
|
| `min` / `max` / `step` | La escala real del negocio (1–15 km, paso 1). | API |
|
|
53
|
-
| `disabled` | La escala existe pero hoy no se puede mover (falta un dato antes). |
|
|
53
|
+
| `disabled` | La escala existe pero hoy no se puede mover (falta un dato antes). | canon (aprobado por el dueño, 05-10-2026, bloque B8) |
|
|
54
54
|
| `size` | `medium` (default, Figma): manija 16, riel 6, label 12/16. `large`: manija 24, riel 8, punto interno 8, label 14/20 — para mobile. | `medium`: según la guía del DS · `large`: canon (aprobado por el dueño, 03-10-2026), extensión SUI |
|
|
55
55
|
|
|
56
56
|
**Usos de hoy que rompen la propuesta:**
|
|
@@ -73,7 +73,8 @@ va un tamaño más chico. La app ya lo resuelve con `BreakpointsService`
|
|
|
73
73
|
| slider con label (radio de cobertura, filtro de precio) | `large` (manija 24, riel 8) | `medium` (manija 16, riel 6) | canon (aprobado por el dueño, 03-10-2026) |
|
|
74
74
|
|
|
75
75
|
```html
|
|
76
|
-
|
|
76
|
+
<!-- D16, dueño 05-10-2026: `large` en todo lo táctil, `medium` con mouse -->
|
|
77
|
+
<sui-slider [size]="(bp.isMobile() || bp.toque()) ? 'large' : 'medium'" label="Radio de cobertura" amount="12 km"
|
|
77
78
|
[min]="1" [max]="15" [(value)]="radioKm" />
|
|
78
79
|
```
|
|
79
80
|
|
|
@@ -82,6 +83,24 @@ manija. Igual la barra mide menos de 44: el slider necesita aire arriba y abajo
|
|
|
82
83
|
manija en 0 o en 100 sobresale media manija (12 px en `large`) del borde de la barra: el
|
|
83
84
|
contenedor tiene que tener margen lateral.
|
|
84
85
|
|
|
86
|
+
### Por dispositivo (D16)
|
|
87
|
+
|
|
88
|
+
Fila `slider` de la tabla D16 (dueño, 05-10-2026). A diferencia del botón o el campo, el slider **no** tiene la excepción
|
|
89
|
+
«`medium` + área 44» en el celular chico: va `large` en todo lo que se toca.
|
|
90
|
+
|
|
91
|
+
| dispositivo | size | nota |
|
|
92
|
+
|---|---|---|
|
|
93
|
+
| celular chico (< 380 px) | `large` | manija 24, riel 8; con `medium` la manija de 16 es difícil de agarrar |
|
|
94
|
+
| celular (380–767 px) | `large` | |
|
|
95
|
+
| tablet táctil (`pointer: coarse`) | `large` | también se arrastra con el dedo |
|
|
96
|
+
| computadora (`pointer: fine`) | `medium` | manija 16, riel 6 (el de la guía del DS) |
|
|
97
|
+
|
|
98
|
+
Ultrawide (≥ 1920 px): igual que la computadora, `medium`.
|
|
99
|
+
|
|
100
|
+
En master-pedidos: `[size]="(bp.isMobile() || bp.toque()) ? 'large' : 'medium'"`. No hay helper propio. Hoy da lo mismo que
|
|
101
|
+
`bp.tactil()`, pero el servicio anuncia que `tactil` dejará fuera al celular chico cuando el DS estire el área de los
|
|
102
|
+
`medium`, y el slider tiene que seguir en `large` ahí.
|
|
103
|
+
|
|
85
104
|
## «No usar»: por qué no hoy y cuándo sí
|
|
86
105
|
|
|
87
106
|
| qué | por qué no hoy | cuándo sí, en un flujo nuevo |
|
|
@@ -138,10 +157,58 @@ Implementa `ControlValueAccessor` **solo para `single`**.
|
|
|
138
157
|
El lector lee el valor con su unidad: en single, el texto de `amount` («12 km»); en range (o sin
|
|
139
158
|
`amount`), el número + `unit`. En range cada manija se anuncia «<label>, mínimo» / «…, máximo».
|
|
140
159
|
|
|
160
|
+
## Bien y mal
|
|
161
|
+
|
|
162
|
+
**El valor arriba y flotando a la vez**
|
|
163
|
+
|
|
164
|
+
```html
|
|
165
|
+
<!-- ❌ mal: `amount` muestra «12 km» y el tooltip repite «12» sin unidad (components/driver-coverage-modal/driver-coverage-modal.html:83) -->
|
|
166
|
+
<sui-slider label="Radio de cobertura" [amount]="radiusKm() + ' km'"
|
|
167
|
+
[min]="minKm" [max]="maxKm" [tooltip]="true"
|
|
168
|
+
[value]="radiusKm()" (valueChange)="onRadiusChange($event)" />
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
```html
|
|
172
|
+
<!-- ✅ bien: con `amount`, sin tooltip -->
|
|
173
|
+
<sui-slider [size]="(bp.isMobile() || bp.toque()) ? 'large' : 'medium'"
|
|
174
|
+
label="Radio de cobertura" [amount]="radiusKm() + ' km'" [min]="minKm" [max]="maxKm"
|
|
175
|
+
[value]="radiusKm()" (valueChange)="onRadiusChange($event)" />
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**El size en una pantalla del repartidor**
|
|
179
|
+
|
|
180
|
+
```html
|
|
181
|
+
<!-- ❌ mal: sin `size` sale `medium` (manija 16) en el teléfono (components/driver-coverage-modal/driver-coverage-modal.html:83) -->
|
|
182
|
+
<sui-slider label="Radio de cobertura" [amount]="radiusKm() + ' km'" [min]="minKm" [max]="maxKm"
|
|
183
|
+
[value]="radiusKm()" (valueChange)="onRadiusChange($event)" />
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
```html
|
|
187
|
+
<!-- ✅ bien: D16, `large` en todo lo táctil -->
|
|
188
|
+
<sui-slider [size]="(bp.isMobile() || bp.toque()) ? 'large' : 'medium'"
|
|
189
|
+
label="Radio de cobertura" [amount]="radiusKm() + ' km'" [min]="minKm" [max]="maxKm"
|
|
190
|
+
[value]="radiusKm()" (valueChange)="onRadiusChange($event)" />
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Un mínimo y un máximo**
|
|
194
|
+
|
|
195
|
+
```html
|
|
196
|
+
<!-- ❌ mal: dos sliders sueltos para un rango; nada impide que el mínimo pase al máximo -->
|
|
197
|
+
<sui-slider label="Precio mínimo" [min]="0" [max]="100" [(value)]="precioMin" />
|
|
198
|
+
<sui-slider label="Precio máximo" [min]="0" [max]="100" [(value)]="precioMax" />
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
```html
|
|
202
|
+
<!-- ✅ bien: una barra con dos manijas -->
|
|
203
|
+
<sui-slider type="range" label="Precio" [amount]="'S/ ' + precioMin() + ' – S/ ' + precioMax()"
|
|
204
|
+
[min]="0" [max]="100" [(minValue)]="precioMin" [(maxValue)]="precioMax" />
|
|
205
|
+
```
|
|
206
|
+
|
|
141
207
|
## Ejemplo
|
|
142
208
|
|
|
143
209
|
```html
|
|
144
210
|
<sui-slider
|
|
211
|
+
[size]="(bp.isMobile() || bp.toque()) ? 'large' : 'medium'"
|
|
145
212
|
label="Radio de cobertura"
|
|
146
213
|
[amount]="radioKm() + ' km'"
|
|
147
214
|
[min]="1" [max]="15" [step]="1"
|