@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
package/docs/sui-icon/README.md
CHANGED
|
@@ -26,8 +26,8 @@ propios del DS (`info-custom-fill`, `heart-half-fill`…) también pasan por aqu
|
|
|
26
26
|
|
|
27
27
|
> **La guía del DS no tiene página para el ícono**: usa RemixIcon en todos sus ejemplos, sin
|
|
28
28
|
> reglas de tamaño. La escala de abajo sale de los tokens del DS (`--sui-icon-size-*` y
|
|
29
|
-
> `--sui-icon-*` en `sui-tokens.scss`). Lo marcado «canon» ya es regla del proyecto;
|
|
30
|
-
> **propuesta
|
|
29
|
+
> `--sui-icon-*` en `sui-tokens.scss`). Lo marcado «canon» ya es regla del proyecto; lo que sigue
|
|
30
|
+
> en **propuesta** espera decisión.
|
|
31
31
|
>
|
|
32
32
|
> Uso medido el 03-10-2026 en `master-pedidos/src/app`: 406 íconos en 95 archivos, sin contar
|
|
33
33
|
> prototipos ni vitrinas. 331 `-line`, 43 `-fill`. Ninguno usa el input `color`.
|
|
@@ -36,14 +36,14 @@ propios del DS (`info-custom-fill`, `heart-half-fill`…) también pasan por aqu
|
|
|
36
36
|
|
|
37
37
|
| valor | tamaño de hoy | cuándo | fuente |
|
|
38
38
|
|---|---|---|---|
|
|
39
|
-
| `12` | 5 | Dentro de un badge `small`. |
|
|
40
|
-
| `16` | 69 | Junto a texto chico: metadatos, botones `2xsmall`/`xsmall`, dentro de un kbd. |
|
|
41
|
-
| `20` (default) | 114 | El normal: botones, inputs, filas, navegación. |
|
|
42
|
-
| `24` | 5 | Cabeceras y acciones sueltas. |
|
|
43
|
-
| `32` | 2 | Ícono protagonista. Si va dentro de un círculo, es `sui-key-icon`. |
|
|
39
|
+
| `12` | 5 | Dentro de un badge `small`. | canon (aprobado por el dueño, 05-10-2026, bloque B1), token `--sui-icon-size-xs` |
|
|
40
|
+
| `16` | 69 | Junto a texto chico: metadatos, botones `2xsmall`/`xsmall`, dentro de un kbd. | canon (aprobado por el dueño, 05-10-2026, bloque B1), token `--sui-icon-size-sm` |
|
|
41
|
+
| `20` (default) | 114 | El normal: botones, inputs, filas, navegación. | canon (aprobado por el dueño, 05-10-2026, bloque B1), token `--sui-icon-size-md` |
|
|
42
|
+
| `24` | 5 | Cabeceras y acciones sueltas. | canon (aprobado por el dueño, 05-10-2026, bloque B1), token `--sui-icon-size-lg` |
|
|
43
|
+
| `32` | 2 | Ícono protagonista. Si va dentro de un círculo, es `sui-key-icon`. | canon (aprobado por el dueño, 05-10-2026, bloque B1), token `--sui-icon-size-xl` |
|
|
44
44
|
| `26` | 7 | Solo el ícono del hero de los onboarding (`ob__hero-icon`). | canon (`CLAUDE.md`, patrón de los pasos de onboarding) |
|
|
45
45
|
| `14`, `18` | 149 | Fuera de la escala, pero el DS mismo los usa (tabs, product-card). **A discutir**: no migrar en masa. | propuesta |
|
|
46
|
-
| `13`, `22`, `28`, `44`… | 49 | Sin regla: van al más cercano de la escala. |
|
|
46
|
+
| `13`, `22`, `28`, `44`… | 49 | Sin regla: van al más cercano de la escala. | canon (aprobado por el dueño, 05-10-2026, bloque B1) |
|
|
47
47
|
|
|
48
48
|
**Usos de hoy fuera de la escala sin regla: 49.** `22` (20 usos: `components/ota-quick-fab/ota-quick-fab.html:11`,
|
|
49
49
|
`pages/schedule/schedule.html:10`), `13` (14: `pages/super-admin/master-drivers/master-drivers.html:359`, `:419`),
|
|
@@ -56,18 +56,18 @@ propios del DS (`info-custom-fill`, `heart-half-fill`…) también pasan por aqu
|
|
|
56
56
|
|
|
57
57
|
| valor | cuándo | fuente |
|
|
58
58
|
|---|---|---|
|
|
59
|
-
| `-line` | El normal. |
|
|
60
|
-
| `-fill` | El seleccionado (el tab activo) o un glifo chico sobre color. |
|
|
61
|
-
| propios del DS (`info-custom-fill`, `heart-half-fill`, `building-skyline`, `avatar-placeholder`) | Los usan componentes del DS; en la app no hacen falta. |
|
|
59
|
+
| `-line` | El normal. | canon (aprobado por el dueño, 05-10-2026, bloque B2) |
|
|
60
|
+
| `-fill` | El seleccionado (el tab activo) o un glifo chico sobre color. | canon (aprobado por el dueño, 05-10-2026, bloque B2) |
|
|
61
|
+
| propios del DS (`info-custom-fill`, `heart-half-fill`, `building-skyline`, `avatar-placeholder`) | Los usan componentes del DS; en la app no hacen falta. | canon (aprobado por el dueño, 05-10-2026, bloque B6) |
|
|
62
62
|
|
|
63
63
|
### `color`
|
|
64
64
|
|
|
65
65
|
| valor | cuándo | fuente |
|
|
66
66
|
|---|---|---|
|
|
67
|
-
| sin `color` (default) | El normal: hereda el color del texto. Casi siempre es lo que se quiere. |
|
|
68
|
-
| `var(--sui-icon-sub-600)` | Ícono de apoyo junto a un texto principal. |
|
|
69
|
-
| `var(--sui-icon-soft-400)` | Decorativo, metadatos. |
|
|
70
|
-
| `var(--sui-icon-disabled-300)` | Deshabilitado. |
|
|
67
|
+
| sin `color` (default) | El normal: hereda el color del texto. Casi siempre es lo que se quiere. | canon (aprobado por el dueño, 05-10-2026, bloque B3) |
|
|
68
|
+
| `var(--sui-icon-sub-600)` | Ícono de apoyo junto a un texto principal. | canon (CANON-SUI §4.1: los íconos siguen la semántica del texto; sub-600 = secundario que igual se lee) |
|
|
69
|
+
| `var(--sui-icon-soft-400)` | Decorativo, metadatos. | canon (CANON-SUI §4.1: soft-400 = lo que no es contenido, metadata terciaria) |
|
|
70
|
+
| `var(--sui-icon-disabled-300)` | Deshabilitado. | canon (CANON-SUI §4.1: disabled-300 solo para disabled) |
|
|
71
71
|
| `var(--sui-icon-white-0)` | Sobre fondo oscuro o de color. | propuesta |
|
|
72
72
|
| un hex o un color de estado | No usar: si el ícono dice un estado, va en `sui-key-icon` `lighter`. | propuesta |
|
|
73
73
|
|
|
@@ -76,7 +76,10 @@ propios del DS (`info-custom-fill`, `heart-half-fill`…) también pasan por aqu
|
|
|
76
76
|
En mobile se lee y se toca con el dedo, así que va más grande; en web, más chico. En las
|
|
77
77
|
pantallas que se usan en los dos (panel del local, super admin) se elige con el servicio de
|
|
78
78
|
breakpoints de la app (`bp`, en `services/breakpoints.service.ts`); en las que solo existen en
|
|
79
|
-
el celular (cliente, repartidor)
|
|
79
|
+
el celular (cliente, repartidor) también se usa `bp`, porque el celular chico va con el valor de
|
|
80
|
+
web. No se toca, así que la tablet va con el valor de web, y el celular chico (< 380 px) también (D16).
|
|
81
|
+
Es **canon (dueño, 05-10-2026, P1 b)**: un paso más grande en el celular que en computadora, y
|
|
82
|
+
se migra todo ahora, no solo al tocar cada pantalla.
|
|
80
83
|
|
|
81
84
|
| uso | mobile | web |
|
|
82
85
|
|---|---|---|
|
|
@@ -86,12 +89,36 @@ el celular (cliente, repartidor) va directo el valor de mobile. Todo es **propue
|
|
|
86
89
|
| dentro de un botón o un input | lo decide el componente | igual |
|
|
87
90
|
|
|
88
91
|
```html
|
|
89
|
-
<sui-icon name="store-2-line" [size]="bp.
|
|
92
|
+
<sui-icon name="store-2-line" [size]="bp.celular() ? 20 : 16" />
|
|
90
93
|
```
|
|
91
94
|
|
|
92
95
|
Un ícono suelto **nunca** es el área táctil: si se toca, va en `sui-compact-button` o
|
|
93
96
|
`sui-button` `onlyIcon`, que dan los 44 px. Hoy solo 2 íconos cambian por breakpoint
|
|
94
|
-
(`pages/discounts/discounts.html:103` y `:108`, con `bp.isTablet() ? 20 : 16`)
|
|
97
|
+
(`pages/discounts/discounts.html:103` y `:108`, con `bp.isTablet() ? 20 : 16`), y los dos están
|
|
98
|
+
mal: van dentro de un `sui-button`, que ya le da al ícono una caja de 20, así que no llevan
|
|
99
|
+
`size`. Hasta 1024 px dibujan 20 y llenan la caja (no se nota); en una computadora de más de
|
|
100
|
+
1024 px dibujan 16 y el glifo queda chico dentro de esa caja. Además `isTablet` no es un corte
|
|
101
|
+
de D16 (ver «Bien y mal»).
|
|
102
|
+
|
|
103
|
+
### Por dispositivo (D16)
|
|
104
|
+
|
|
105
|
+
El ícono no se toca: sube un paso **solo en el celular de 380 px o más**. Fuente: D16, dueño
|
|
106
|
+
05-10-2026 (P1 b).
|
|
107
|
+
|
|
108
|
+
| dispositivo | size | nota |
|
|
109
|
+
|---|---|---|
|
|
110
|
+
| celular chico (< 380) | valor «web» (`16` en una fila, `24` protagonista) | no se toca: no sube aunque sea un celular |
|
|
111
|
+
| celular (380–767) | valor «mobile» (`20` junto al texto de una fila, `32` protagonista) | un paso más que en la computadora |
|
|
112
|
+
| tablet táctil (`pointer: coarse`) | valor «web» (`16` en una fila, `24` protagonista) | no se toca: el puntero no cambia nada |
|
|
113
|
+
| computadora (`pointer: fine`) | valor «web» (`16` en una fila, `24` protagonista) | |
|
|
114
|
+
|
|
115
|
+
En el ultrawide, igual que en la computadora: el espacio extra va a más columnas, no a íconos
|
|
116
|
+
más grandes. Dentro de un botón o un input no se pasa `size`: lo decide el componente.
|
|
117
|
+
|
|
118
|
+
En master-pedidos no hay helper: `[size]="bp.celular() ? 20 : 16"` (fila) o
|
|
119
|
+
`[size]="bp.celular() ? 32 : 24"` (protagonista). No uses `bp.isMobile()` (incluye el celular
|
|
120
|
+
chico) ni `bp.isTablet()` (incluye la tablet y la laptop de hasta 1024 px): los dos van con el
|
|
121
|
+
valor de web.
|
|
95
122
|
|
|
96
123
|
## «No usar»: por qué no hoy y cuándo sí
|
|
97
124
|
|
|
@@ -128,6 +155,47 @@ Outputs: ninguno.
|
|
|
128
155
|
el paquete del DS no la trae.
|
|
129
156
|
- Dentro de un `sui-kbd`, el kbd le fuerza el color `text-sub-600`.
|
|
130
157
|
|
|
158
|
+
## Bien y mal
|
|
159
|
+
|
|
160
|
+
Ícono de una acción en una tabla
|
|
161
|
+
|
|
162
|
+
```html
|
|
163
|
+
<!-- ❌ mal: el botón ya le da al ícono su caja de 20 y no hace falta size; en la computadora de más de 1024 px isTablet dibuja el glifo en 16 dentro de ella (pages/discounts/discounts.html:103) -->
|
|
164
|
+
<sui-button variant="ghost" color="neutral" [size]="bp.sizeControl()" [onlyIcon]="true" aria-label="Editar">
|
|
165
|
+
<sui-icon data-slot="start" name="edit-2-line" [size]="bp.isTablet() ? 20 : 16" />
|
|
166
|
+
</sui-button>
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
```html
|
|
170
|
+
<!-- ✅ bien -->
|
|
171
|
+
<sui-button variant="ghost" color="neutral" [size]="bp.sizeControl()" [onlyIcon]="true"
|
|
172
|
+
leftIcon="edit-2-line" aria-label="Editar" />
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Ícono protagonista
|
|
176
|
+
|
|
177
|
+
```html
|
|
178
|
+
<!-- ❌ mal: 28 está fuera de la escala y no cambia por dispositivo (pages/envios/envios.html:712) -->
|
|
179
|
+
<sui-icon class="seg__buscando-icono" name="e-bike-2-line" [size]="28" />
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
```html
|
|
183
|
+
<!-- ✅ bien -->
|
|
184
|
+
<sui-icon class="seg__buscando-icono" name="e-bike-2-line" [size]="bp.celular() ? 32 : 24" />
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Tamaño como texto
|
|
188
|
+
|
|
189
|
+
```html
|
|
190
|
+
<!-- ❌ mal: un string sin unidad no es un tamaño CSS válido; el ícono no toma tamaño (Trampas) -->
|
|
191
|
+
<sui-icon name="time-line" size="20" />
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
```html
|
|
195
|
+
<!-- ✅ bien -->
|
|
196
|
+
<sui-icon name="time-line" [size]="20" />
|
|
197
|
+
```
|
|
198
|
+
|
|
131
199
|
## Ejemplo
|
|
132
200
|
|
|
133
201
|
```html
|
|
@@ -27,8 +27,9 @@ El archivo que entrega **no se sube tal cual**: pasa por `ImageCompressorService
|
|
|
27
27
|
## Qué variante usar
|
|
28
28
|
|
|
29
29
|
> **La guía del DS no tiene página para este componente** (el «Image Upload» del Figma de origen
|
|
30
|
-
> es otra cosa: la foto con botones, que en SUI es `sui-image-upload-profile`).
|
|
31
|
-
>
|
|
30
|
+
> es otra cosa: la foto con botones, que en SUI es `sui-image-upload-profile`). Las reglas
|
|
31
|
+
> marcadas canon están aprobadas y las de «según el código» describen el componente; lo que sigue
|
|
32
|
+
> en **propuesta** espera decisión.
|
|
32
33
|
>
|
|
33
34
|
> Uso medido el 03-10-2026 en `master-pedidos/src/app` (sin prototipos ni vitrinas): **13 usos en
|
|
34
35
|
> 10 pantallas**. `shape`: 11 `rect`, 2 `circle`. `size`: 7 `xl`, 3 `lg`, 3 sin size (fluidos).
|
|
@@ -38,16 +39,16 @@ El archivo que entrega **no se sube tal cual**: pasa por `ImageCompressorService
|
|
|
38
39
|
|
|
39
40
|
| valor | cuándo | fuente |
|
|
40
41
|
|---|---|---|
|
|
41
|
-
| `circle` (default) | **Solo la foto de una persona** (perfil del cliente, del repartidor, del usuario del local). Así se ve después en `sui-avatar`. |
|
|
42
|
-
| `rect` | **Todo lo demás**: el logo del local (en el home se ve como cuadrado redondeado), la portada, la foto del producto, comprobantes, QR, banners. |
|
|
42
|
+
| `circle` (default) | **Solo la foto de una persona** (perfil del cliente, del repartidor, del usuario del local). Así se ve después en `sui-avatar`. | canon (aprobado por el dueño, 05-10-2026, bloque B2) |
|
|
43
|
+
| `rect` | **Todo lo demás**: el logo del local (en el home se ve como cuadrado redondeado), la portada, la foto del producto, comprobantes, QR, banners. | canon (aprobado por el dueño, 05-10-2026, bloque B2) |
|
|
43
44
|
|
|
44
45
|
### `size` y `fluid` — según la forma de la imagen
|
|
45
46
|
|
|
46
47
|
| valor | px | cuándo | fuente |
|
|
47
48
|
|---|---|---|---|
|
|
48
|
-
| `fluid` | ancho del contenedor, alto hasta 320 | **Capturas y documentos** (comprobante, Yape, QR) y **imágenes apaisadas** (portada 16:9, banner). Una captura de celular es vertical: en un cuadrado se recorta. |
|
|
49
|
-
| `xl` | 200 | **Imágenes cuadradas**: logo, foto del producto, foto de perfil. |
|
|
50
|
-
| `lg` (default) | 160 | Imagen cuadrada al lado de otra cosa en la misma fila (el logo junto al nombre del local en web). |
|
|
49
|
+
| `fluid` | ancho del contenedor, alto hasta 320 | **Capturas y documentos** (comprobante, Yape, QR) y **imágenes apaisadas** (portada 16:9, banner). Una captura de celular es vertical: en un cuadrado se recorta. | canon (aprobado por el dueño, 05-10-2026, bloque B2) |
|
|
50
|
+
| `xl` | 200 | **Imágenes cuadradas**: logo, foto del producto, foto de perfil. | canon (aprobado por el dueño, 05-10-2026, bloque B1) |
|
|
51
|
+
| `lg` (default) | 160 | Imagen cuadrada al lado de otra cosa en la misma fila (el logo junto al nombre del local en web). | canon (aprobado por el dueño, 05-10-2026, bloque B1) |
|
|
51
52
|
| `md` | 120 | No usar: chico para ver si la foto quedó bien. | no usar |
|
|
52
53
|
| `sm` | 80 | No usar: no entra el texto (el subtítulo se esconde). | no usar |
|
|
53
54
|
|
|
@@ -55,25 +56,25 @@ El archivo que entrega **no se sube tal cual**: pasa por `ImageCompressorService
|
|
|
55
56
|
|
|
56
57
|
| valor | cuándo | fuente |
|
|
57
58
|
|---|---|---|
|
|
58
|
-
| `true` | **Siempre.** Con imagen muestra dos botones a la vista: lápiz y tacho. El lápiz emite `editRequested`: si la pantalla tiene recortador, lo abre (`app-image-cropper`); si no, llama a `abrirSelector()` para elegir otra (como el Yape del repartidor). |
|
|
59
|
+
| `true` | **Siempre.** Con imagen muestra dos botones a la vista: lápiz y tacho. El lápiz emite `editRequested`: si la pantalla tiene recortador, lo abre (`app-image-cropper`); si no, llama a `abrirSelector()` para elegir otra (como el Yape del repartidor). | canon (aprobado por el dueño, 05-10-2026, bloque B8) |
|
|
59
60
|
| `false` (default) | No usar: con imagen, el lápiz aparece **solo al pasar el mouse** (en el celular no se ve) y el «Quitar» de abajo es un botón aparte (32 px). | no usar |
|
|
60
61
|
|
|
61
62
|
### Textos: `title`, `subtitle`
|
|
62
63
|
|
|
63
64
|
| input | cuándo | fuente |
|
|
64
65
|
|---|---|---|
|
|
65
|
-
| `title` | Verbo + qué: «
|
|
66
|
-
| `subtitle` | Formatos y tamaño, **solo los que el componente acepta** (JPG, PNG, WebP, GIF o HEIC), o el encuadre que se va a aplicar («se recorta a 16:9»). Mientras procesa: «Procesando…». |
|
|
66
|
+
| `title` | Verbo en imperativo con tuteo + qué: «Sube tu logo», «Sube el comprobante», «Sube la captura del pago». Sin `title`: «Sube tu foto» (`circle`) o «Sube tu logo» (`rect`). | canon (dueño, 05-10-2026, P4 a); el default cambió en la 0.25.0 (antes «Subir foto» / «Subir logo») |
|
|
67
|
+
| `subtitle` | Formatos y tamaño, **solo los que el componente acepta** (JPG, PNG, WebP, GIF o HEIC), o el encuadre que se va a aplicar («se recorta a 16:9»). Mientras procesa: «Procesando…». | canon (aprobado por el dueño, 05-10-2026, bloque B4) |
|
|
67
68
|
|
|
68
69
|
### `maxSize`, `disabled`, `src`
|
|
69
70
|
|
|
70
71
|
| input | cuándo | fuente |
|
|
71
72
|
|---|---|---|
|
|
72
|
-
| `maxSize` | Siempre, en **bytes**. 10 MB para capturas y comprobantes, 20–50 MB para fotos que se van a comprimir. |
|
|
73
|
-
| `disabled` | Mientras se comprime o se sube (`subiendo()`), para que no se elija otra encima. |
|
|
74
|
-
| `src` (model) | La URL guardada, o la vista previa local mientras se sube. Con `[(src)]` el componente la pone solo al elegir. |
|
|
73
|
+
| `maxSize` | Siempre, en **bytes**. 10 MB para capturas y comprobantes, 20–50 MB para fotos que se van a comprimir. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
|
|
74
|
+
| `disabled` | Mientras se comprime o se sube (`subiendo()`), para que no se elija otra encima. | canon (aprobado por el dueño, 05-10-2026, bloque B8) |
|
|
75
|
+
| `src` (model) | La URL guardada, o la vista previa local mientras se sube. Con `[(src)]` el componente la pone solo al elegir. | según el código |
|
|
75
76
|
|
|
76
|
-
### Usos de hoy que rompen la
|
|
77
|
+
### Usos de hoy que rompen la regla
|
|
77
78
|
|
|
78
79
|
- **5 subtítulos prometen HEIC**: hasta el 03-10-2026 el componente lo rechazaba; desde la 0.22.0
|
|
79
80
|
(la que usa la app) ya lo acepta, así que **ya no rompen nada**. Lo que queda es la vista previa en
|
|
@@ -99,8 +100,8 @@ El archivo que entrega **no se sube tal cual**: pasa por `ImageCompressorService
|
|
|
99
100
|
En mobile se toca con el dedo: lo que se toca mide **44 px o más** (canon (dueño, 04-10-2026): piso táctil 44 en el teléfono). El área vacía se
|
|
100
101
|
toca entera (80 a 200 px), así que pasa. Los botones con imagen se **ven** de 40 (lápiz y tacho) y
|
|
101
102
|
32 («Quitar»), pero en el teléfono (≤ 767 px) **se tocan en 44 de alto** con un `::before`
|
|
102
|
-
invisible (04-10-2026).
|
|
103
|
-
(
|
|
103
|
+
invisible (04-10-2026). Aquí `bp` no elige nada: `size` va por la forma de la imagen y lo que se
|
|
104
|
+
toca ya tiene su área sola (ver «Por dispositivo (D16)»).
|
|
104
105
|
|
|
105
106
|
**Por qué no hay un size nuevo**: aquí `size` (`sm`/`md`/`lg`/`xl`) es el tamaño de la **foto**, no
|
|
106
107
|
el de los botones. Un `2xl` agrandaría la imagen sin que nadie lo pida; el área invisible lleva lo
|
|
@@ -108,14 +109,14 @@ que se toca a 44 sin cambiar el dibujo ni los sizes de hoy.
|
|
|
108
109
|
|
|
109
110
|
| uso | mobile | web | fuente |
|
|
110
111
|
|---|---|---|---|
|
|
111
|
-
| comprobante, captura, QR, portada, banner | `fluid` | `fluid` (en una columna de ≤ 480 px) |
|
|
112
|
-
| logo, foto de producto, foto de perfil | `xl` (200) | `xl` (200), o `lg` (160) al lado del nombre |
|
|
112
|
+
| comprobante, captura, QR, portada, banner | `fluid` | `fluid` (en una columna de ≤ 480 px) | canon (aprobado por el dueño, 05-10-2026, bloque B1) |
|
|
113
|
+
| logo, foto de producto, foto de perfil | `xl` (200) | `xl` (200), o `lg` (160) al lado del nombre | canon (aprobado por el dueño, 05-10-2026, bloque B1) |
|
|
113
114
|
| lápiz y tacho (`editable`) | se ven de 40 (32 en `sm`), se tocan en 44 de alto; a los lados el área crece la mitad del espacio entre los dos (3; 2 en `sm`) para no pisarse | 40 px | canon (dueño, 04-10-2026): piso táctil 44 en el teléfono (área) · canon (aprobado por el dueño, 03-10-2026), extensión SUI (40) |
|
|
114
115
|
| «Quitar» (sin `editable`) | se ve de 32 (`sui-button` `xsmall`), se toca en 44 de alto: crece 4 hacia la foto (la mitad del gap de 8) y 8 hacia abajo | 32 px | canon (dueño, 04-10-2026): piso táctil 44 en el teléfono (área) · canon (aprobado por el dueño, 03-10-2026) |
|
|
115
116
|
|
|
116
117
|
```html
|
|
117
|
-
<sui-image-upload shape="rect"
|
|
118
|
-
[src]="logo()" [maxSize]="50 * 1024 * 1024" title="
|
|
118
|
+
<sui-image-upload shape="rect" size="xl" [editable]="true"
|
|
119
|
+
[src]="logo()" [maxSize]="50 * 1024 * 1024" title="Sube tu logo"
|
|
119
120
|
subtitle="JPG, PNG o WebP — máx 50 MB"
|
|
120
121
|
(imageSelected)="alElegirLogo($event)" (editRequested)="abrirRecortador()"
|
|
121
122
|
(removed)="quitarLogo()" />
|
|
@@ -126,6 +127,27 @@ de 40 y quedan en 32) y el «Quitar» es un `sui-button` `xsmall` de **32** (ant
|
|
|
126
127
|
los dos botones van centrados abajo, dentro del círculo. Lo que haya justo debajo del «Quitar»
|
|
127
128
|
pierde 8 px de toque en el teléfono: no pegarle otro control sin margen.
|
|
128
129
|
|
|
130
|
+
### Por dispositivo (D16)
|
|
131
|
+
|
|
132
|
+
D16 (dueño, 05-10-2026) no mueve `size`: aquí `size` es el tamaño de la **foto**, no el de lo que
|
|
133
|
+
se toca, así que no sigue la escala «lo que se toca / lo que no se toca». Se elige por la forma de
|
|
134
|
+
la imagen (`xl` para lo cuadrado, `fluid` para capturas y apaisadas) y por el layout, igual que en
|
|
135
|
+
la tabla de arriba: `xl` en una columna, que es lo que hay en el celular, el celular chico y la
|
|
136
|
+
tablet; `lg` solo cuando la foto comparte la fila con el nombre (hoy ninguna pantalla lo hace:
|
|
137
|
+
los 3 `lg` medidos son el logo del onboarding y el banner y el comprobante de promociones, que
|
|
138
|
+
además van `fluid`; ninguno está en una fila).
|
|
139
|
+
Lo que decide entre `xl` y `lg` es si hay fila, no el dispositivo: cuando una pantalla arme esa
|
|
140
|
+
fila según el ancho, la condición es el mismo corte del layout de la pantalla, no
|
|
141
|
+
`bp.celular()` ni `bp.tactil()`.
|
|
142
|
+
|
|
143
|
+
Lo que se toca (lápiz, tacho, «Quitar») ya llega a 44 de alto en el celular y en el celular chico
|
|
144
|
+
con el área invisible (`@media (max-width: 767px)`). En la **tablet táctil** (`pointer: coarse`,
|
|
145
|
+
más de 767 px) esa área no se prende y quedan en 40 y 32: **pendiente**, espera el mixin
|
|
146
|
+
`sui-tactil` del DS que propone §0 de las decisiones (sin el sí del dueño todavía).
|
|
147
|
+
|
|
148
|
+
En master-pedidos: no hay helper de D16; `size="xl"` para lo cuadrado y `[fluid]="true"` para
|
|
149
|
+
capturas y apaisadas. `lg` solo en la fila del nombre, con la condición del layout de esa pantalla.
|
|
150
|
+
|
|
129
151
|
## «No usar»: por qué no hoy y cuándo sí
|
|
130
152
|
|
|
131
153
|
Nada se borra del DS. Lo marcado «no usar» no tiene caso en la app de hoy; si un flujo nuevo cae
|
|
@@ -194,19 +216,65 @@ recortador; se llama con una referencia: `#qr` → `qr.abrirSelector()`).
|
|
|
194
216
|
- El atributo `title` del host se borra solo (no sale el tooltip gris del navegador).
|
|
195
217
|
- Ya trae el arreglo de iOS para el `:active` pegado.
|
|
196
218
|
|
|
219
|
+
## Bien y mal
|
|
220
|
+
|
|
221
|
+
Logo del local
|
|
222
|
+
|
|
223
|
+
```html
|
|
224
|
+
<!-- ❌ mal: el logo se ve cuadrado en el home, no en círculo; en 160 (lg) en una columna, donde va xl; y sin lápiz (pages/business-onboarding/step-info/step-info.html:42) -->
|
|
225
|
+
<sui-image-upload shape="circle" size="lg" [(src)]="logoPreview" title="Subir logo"
|
|
226
|
+
(imageSelected)="onLogoSelected($event)" />
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
```html
|
|
230
|
+
<!-- ✅ bien -->
|
|
231
|
+
<sui-image-upload shape="rect" size="xl" [editable]="true" [(src)]="logoPreview" title="Sube tu logo"
|
|
232
|
+
(imageSelected)="onLogoSelected($event)" (editRequested)="abrirRecortador()" />
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Comprobante de pago
|
|
236
|
+
|
|
237
|
+
```html
|
|
238
|
+
<!-- ❌ mal: una captura vertical se recorta en el cuadrado de 200 y el «Quitar» queda en 32 (pages/central/central-gastos/central-gastos.html:118) -->
|
|
239
|
+
<sui-image-upload shape="rect" size="xl" [src]="vistaComprobante()" [maxSize]="10 * 1024 * 1024"
|
|
240
|
+
title="Subir comprobante" (imageSelected)="onComprobante($event)" (removed)="quitarComprobante()" />
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
```html
|
|
244
|
+
<!-- ✅ bien -->
|
|
245
|
+
<sui-image-upload #comprobante shape="rect" [fluid]="true" [editable]="true" [src]="vistaComprobante()"
|
|
246
|
+
[maxSize]="10 * 1024 * 1024" title="Sube el comprobante" (imageSelected)="onComprobante($event)"
|
|
247
|
+
(editRequested)="comprobante.abrirSelector()" (removed)="quitarComprobante()" />
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Banner apaisado
|
|
251
|
+
|
|
252
|
+
```html
|
|
253
|
+
<!-- ❌ mal: con fluid, size no hace nada; y sin editable (pages/promociones/promociones.html:186) -->
|
|
254
|
+
<sui-image-upload shape="rect" size="lg" [fluid]="true" [src]="campaignBannerPreview()"
|
|
255
|
+
title="Subir banner" (imageSelected)="onBannerImage($event)" />
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
```html
|
|
259
|
+
<!-- ✅ bien -->
|
|
260
|
+
<sui-image-upload #banner shape="rect" [fluid]="true" [editable]="true" [src]="campaignBannerPreview()"
|
|
261
|
+
title="Sube el banner" (imageSelected)="onBannerImage($event)"
|
|
262
|
+
(editRequested)="banner.abrirSelector()" (removed)="onBannerRemoved()" />
|
|
263
|
+
```
|
|
264
|
+
|
|
197
265
|
## Ejemplo
|
|
198
266
|
|
|
199
267
|
```html
|
|
200
268
|
<!-- Comprobante: ancho completo, el lápiz elige otra captura -->
|
|
201
269
|
<sui-image-upload #comprobante shape="rect" [fluid]="true" [editable]="true"
|
|
202
270
|
[src]="vistaPrevia()" [maxSize]="10 * 1024 * 1024"
|
|
203
|
-
title="
|
|
271
|
+
title="Sube el comprobante" subtitle="Captura del Yape o del banco — máx 10 MB"
|
|
204
272
|
(imageSelected)="alElegir($event)" (editRequested)="comprobante.abrirSelector()"
|
|
205
273
|
(removed)="quitar()" />
|
|
206
274
|
|
|
207
275
|
<!-- Foto del producto: cuadrada, el lápiz abre el recortador -->
|
|
208
276
|
<sui-image-upload shape="rect" size="xl" [editable]="true" [src]="foto()"
|
|
209
|
-
title="
|
|
277
|
+
title="Sube tu foto" subtitle="JPG, PNG o WebP — se comprime sola"
|
|
210
278
|
(imageSelected)="alElegir($event)" (editRequested)="abrirRecortador()"
|
|
211
279
|
(removed)="quitarFoto()" />
|
|
212
280
|
```
|
|
@@ -27,7 +27,8 @@ chico (56–64 px) con su texto y los botones al lado, en una fila de un formula
|
|
|
27
27
|
## Qué variante usar
|
|
28
28
|
|
|
29
29
|
> **La guía del DS no tiene página para este componente** (existe en el Figma de origen, sin
|
|
30
|
-
> texto de uso).
|
|
30
|
+
> texto de uso). Las reglas marcadas canon están aprobadas y las de «según el código» describen
|
|
31
|
+
> el componente; lo que sigue en **propuesta** espera decisión.
|
|
31
32
|
>
|
|
32
33
|
> Uso medido el 03-10-2026 en `master-pedidos/src/app`: **0 usos**. La foto de perfil va con
|
|
33
34
|
> `app-avatar-editor` (3 pantallas).
|
|
@@ -36,27 +37,27 @@ chico (56–64 px) con su texto y los botones al lado, en una fila de un formula
|
|
|
36
37
|
|
|
37
38
|
| valor | cuándo | fuente |
|
|
38
39
|
|---|---|---|
|
|
39
|
-
| `avatar` (default) | La foto de una persona. Vacío muestra una silueta. |
|
|
40
|
-
| `company` | Un negocio. Vacío muestra edificios. Ojo: lo muestra en círculo. |
|
|
40
|
+
| `avatar` (default) | La foto de una persona. Vacío muestra una silueta. | canon (aprobado por el dueño, 05-10-2026, bloque B2) |
|
|
41
|
+
| `company` | Un negocio. Vacío muestra edificios. Ojo: lo muestra en círculo. | canon (aprobado por el dueño, 05-10-2026, bloque B2) |
|
|
41
42
|
|
|
42
43
|
### `alignment`
|
|
43
44
|
|
|
44
45
|
| valor | cuándo | fuente |
|
|
45
46
|
|---|---|---|
|
|
46
|
-
| `vertical` (default) | Con texto: título y requisitos («Mín. 400 × 400 px, PNG o JPEG»), avatar de 64. |
|
|
47
|
-
| `horizontal` | Sin texto, solo los botones al lado del avatar de 56. Cuando el label ya está arriba (`sui-form-label`). |
|
|
47
|
+
| `vertical` (default) | Con texto: título y requisitos («Mín. 400 × 400 px, PNG o JPEG»), avatar de 64. | canon (aprobado por el dueño, 05-10-2026, bloque B2) |
|
|
48
|
+
| `horizontal` | Sin texto, solo los botones al lado del avatar de 56. Cuando el label ya está arriba (`sui-form-label`). | canon (aprobado por el dueño, 05-10-2026, bloque B2) |
|
|
48
49
|
|
|
49
50
|
### Textos y estados
|
|
50
51
|
|
|
51
52
|
| input | cuándo | fuente |
|
|
52
53
|
|---|---|---|
|
|
53
|
-
| `title` | Qué es: «Tu foto», «Foto de perfil». Solo se ve en `vertical`. |
|
|
54
|
-
| `subtitle` | Requisitos reales: formatos que se aceptan y para qué se usa («La ve el cliente cuando llevas su pedido»). |
|
|
54
|
+
| `title` | Qué es: «Tu foto», «Foto de perfil». Solo se ve en `vertical`. | canon (aprobado por el dueño, 05-10-2026, bloque B4) |
|
|
55
|
+
| `subtitle` | Requisitos reales: formatos que se aceptan y para qué se usa («La ve el cliente cuando llevas su pedido»). | canon (aprobado por el dueño, 05-10-2026, bloque B4) |
|
|
55
56
|
| `labels` | Ya vienen en español con tuteo (Subir, Eliminar, Cambiar). Cambiarlos solo si el contexto pide otro verbo («Quitar»). | propuesta |
|
|
56
|
-
| `imageUrl` | La URL guardada. Con imagen muestra Eliminar + Cambiar. |
|
|
57
|
-
| `companyLogoSrc` | Solo con `type="company"`: el logo, que gana sobre `imageUrl`. |
|
|
58
|
-
| `loading` | **Siempre** mientras se comprime y se sube: deshabilita los botones y atenúa la foto. |
|
|
59
|
-
| `disabled` | La persona no puede cambiarla (cuenta verificada con foto bloqueada). |
|
|
57
|
+
| `imageUrl` | La URL guardada. Con imagen muestra Eliminar + Cambiar. | según el código |
|
|
58
|
+
| `companyLogoSrc` | Solo con `type="company"`: el logo, que gana sobre `imageUrl`. | según el código |
|
|
59
|
+
| `loading` | **Siempre** mientras se comprime y se sube: deshabilita los botones y atenúa la foto. | canon (aprobado por el dueño, 05-10-2026, bloque B8) |
|
|
60
|
+
| `disabled` | La persona no puede cambiarla (cuenta verificada con foto bloqueada). | canon (aprobado por el dueño, 05-10-2026, bloque B8) |
|
|
60
61
|
|
|
61
62
|
Usos de hoy que rompen la regla: **0**.
|
|
62
63
|
|
|
@@ -80,6 +81,22 @@ Usos de hoy que rompen la regla: **0**.
|
|
|
80
81
|
**Sin tamaño suficiente para mobile.** Hace falta en el DS un `size` que lleve los botones a
|
|
81
82
|
`large` (48 px). Mientras tanto, en el celular va `sui-image-upload` `circle` `xl`.
|
|
82
83
|
|
|
84
|
+
### Por dispositivo (D16)
|
|
85
|
+
|
|
86
|
+
No aplica: **no tiene `size`** y nada cambia por dispositivo (avatar de 64/56 y botones `xsmall`
|
|
87
|
+
de 32 fijos). Con D16 (dueño, 05-10-2026) lo que se toca va `large` en el celular y en la tablet
|
|
88
|
+
táctil, y esos botones no llegan a 44, así que en una pantalla táctil no se usa:
|
|
89
|
+
|
|
90
|
+
| dispositivo | qué va | ¿llega a 44? |
|
|
91
|
+
|---|---|---|
|
|
92
|
+
| celular y celular chico (≤ 767) | `sui-image-upload` `circle` `xl` con `[editable]="true"` | sí: su lápiz y su tacho se tocan en 44 con el área invisible |
|
|
93
|
+
| tablet táctil (`pointer: coarse`, > 767) | `sui-image-upload` `circle` `xl` con `[editable]="true"` (40 contra 32, el que más se acerca) | **no, pendiente**: el área de 44 de `sui-image-upload` se prende solo hasta 767 px y en la tablet quedan en 40; espera el mixin `sui-tactil` del DS (§0 de las decisiones, sin el sí del dueño todavía) |
|
|
94
|
+
| computadora y ultrawide | este componente, botones de 32 | no hace falta 44; se queda en 32 porque solo tiene ese tamaño de botón. Subirlo a `medium` es código del DS (un `size`), **pendiente** |
|
|
95
|
+
|
|
96
|
+
En master-pedidos: no lleva `[size]`; si la pantalla se usa en un dispositivo táctil,
|
|
97
|
+
`@if (!bp.tactil())` para este componente y `sui-image-upload` en el otro caso (con la tablet
|
|
98
|
+
todavía en 40, ver la tabla).
|
|
99
|
+
|
|
83
100
|
## «No usar»: por qué no hoy y cuándo sí
|
|
84
101
|
|
|
85
102
|
Nada se borra del DS. Lo marcado «no usar» no tiene caso en la app de hoy; si un flujo nuevo cae
|
|
@@ -136,6 +153,48 @@ interface SuiImageUploadProfileLabels { upload?: string; remove?: string; change
|
|
|
136
153
|
- El atributo `title` del host se borra solo (no sale el tooltip gris del navegador); el `title`
|
|
137
154
|
sí se usa como `alt` de la foto.
|
|
138
155
|
|
|
156
|
+
## Bien y mal
|
|
157
|
+
|
|
158
|
+
Logo del local
|
|
159
|
+
|
|
160
|
+
```html
|
|
161
|
+
<!-- ❌ mal: company lo muestra en círculo y el logo se ve cuadrado en el home (vitrina: pages/super-admin/master-preview/_guia-moleculas/fechas.ts:233) -->
|
|
162
|
+
<sui-image-upload-profile type="company" title="Logo del local" subtitle="JPG o PNG, cuadrado" />
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
```html
|
|
166
|
+
<!-- ✅ bien -->
|
|
167
|
+
<sui-image-upload shape="rect" size="xl" [editable]="true" [src]="logo()" title="Sube tu logo"
|
|
168
|
+
(imageSelected)="alElegirLogo($event)" (editRequested)="abrirRecortador()" />
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Subir la foto
|
|
172
|
+
|
|
173
|
+
```html
|
|
174
|
+
<!-- ❌ mal: no tiene input de archivo; «Subir» y «Cambiar» solo emiten y no abren nada (Trampas) -->
|
|
175
|
+
<sui-image-upload-profile title="Foto de perfil" [imageUrl]="foto()" (upload)="subir()" />
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
```html
|
|
179
|
+
<!-- ✅ bien -->
|
|
180
|
+
<sui-image-upload-profile title="Foto de perfil" [imageUrl]="foto()" [loading]="subiendo()"
|
|
181
|
+
(upload)="input.click()" (change)="input.click()" (remove)="quitar()" />
|
|
182
|
+
<input #input type="file" accept="image/jpeg,image/png,image/webp" hidden (change)="alElegir($event)" />
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Foto de perfil en el celular
|
|
186
|
+
|
|
187
|
+
```html
|
|
188
|
+
<!-- ❌ mal: los botones miden 32 y en una pantalla táctil no llegan a 44 (D16) -->
|
|
189
|
+
<sui-image-upload-profile title="Tu foto" [imageUrl]="foto()" (upload)="input.click()" />
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
```html
|
|
193
|
+
<!-- ✅ bien -->
|
|
194
|
+
<sui-image-upload shape="circle" size="xl" [editable]="true" [src]="foto()" title="Sube tu foto"
|
|
195
|
+
(imageSelected)="alElegir($event)" (editRequested)="abrirRecortador()" />
|
|
196
|
+
```
|
|
197
|
+
|
|
139
198
|
## Ejemplo
|
|
140
199
|
|
|
141
200
|
```html
|
|
@@ -45,13 +45,19 @@ No tiene variantes ni inputs. Lo que hace:
|
|
|
45
45
|
|
|
46
46
|
| dónde | regla | fuente |
|
|
47
47
|
|---|---|---|
|
|
48
|
-
| imágenes del Storage en el home y los listados del cliente | siempre con la directiva |
|
|
48
|
+
| imágenes del Storage en el home y los listados del cliente | siempre con la directiva | canon (aprobado por el dueño, 05-10-2026, bloque B9) — es donde está hoy, y donde se vio el bug del 10-07-2026: portadas grises tras un corte |
|
|
49
49
|
| el resto de `<img>` remotos | sumarla cuando la imagen sea parte de la decisión (la foto del producto en la carta) | propuesta |
|
|
50
50
|
|
|
51
51
|
## Tamaño en mobile y en web
|
|
52
52
|
|
|
53
53
|
No aplica: es una directiva, no dibuja nada. El tamaño es el del `<img>`.
|
|
54
54
|
|
|
55
|
+
### Por dispositivo (D16)
|
|
56
|
+
|
|
57
|
+
No aplica: no tiene `size` ni escala que repartir por dispositivo (D16, dueño 05-10-2026). El
|
|
58
|
+
`<img>` mide lo que diga el CSS de la pantalla o el componente que lo contiene (`sui-avatar` con
|
|
59
|
+
`bp.sizeAvatar()`, la tarjeta del local), y la directiva se pone igual en todos los dispositivos.
|
|
60
|
+
|
|
55
61
|
## API
|
|
56
62
|
|
|
57
63
|
<!-- api:inicio -->
|
|
@@ -89,6 +95,49 @@ Solo se aplica a `<img>` (`selector: img[suiImgRetry]`). El `src` se pone como s
|
|
|
89
95
|
- **No borra el cache completo** a propósito: solo la entrada de esa URL. Borrarlo todo mataría
|
|
90
96
|
la ventaja de no volver a bajar nada.
|
|
91
97
|
- Funciona igual con `loading="lazy"` y `decoding="async"`.
|
|
98
|
+
- **Con `srcset` no**: el reintento y el `fetch` van sobre `img.src`, no sobre la candidata que el
|
|
99
|
+
navegador eligió (`currentSrc`), así que purgaría la URL equivocada. Va un `src` único (en el home,
|
|
100
|
+
la portada chica de 800 px; ver `master-pedidos/src/app/core/services/state.service.ts:45`).
|
|
101
|
+
|
|
102
|
+
## Bien y mal
|
|
103
|
+
|
|
104
|
+
Logo en las sugerencias de búsqueda
|
|
105
|
+
|
|
106
|
+
```html
|
|
107
|
+
<!-- ❌ mal: listado del cliente sin la directiva; tras un corte el logo queda roto (pages/customer/favorites/favorites.html:32; la misma sugerencia del home sí la lleva) -->
|
|
108
|
+
<img class="favorites__suggestion-img" [src]="s.logoUrl" [alt]="s.name" loading="lazy" />
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
```html
|
|
112
|
+
<!-- ✅ bien (con las reglas de sui-img-loaded y data-sui-img-dead en el scss) -->
|
|
113
|
+
<img class="favorites__suggestion-img" suiImgRetry [src]="s.logoUrl" [alt]="s.name"
|
|
114
|
+
loading="lazy" decoding="async" />
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Logo del local con inicial de respaldo
|
|
118
|
+
|
|
119
|
+
```html
|
|
120
|
+
<!-- ❌ mal: el (error) a mano esconde la imagen al primer fallo, sin reintento ni inicial (pages/customer/order-history/order-history.html:168) -->
|
|
121
|
+
<img [src]="logo" [alt]="order.tenantName ?? 'Local'" (error)="$any($event).target.style.display='none'" />
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
```html
|
|
125
|
+
<!-- ✅ bien: logo con iniciales de respaldo → sui-avatar, no la directiva -->
|
|
126
|
+
<sui-avatar [size]="bp.sizeAvatar('md')" [src]="logo" [initials]="storeInitial(order)"
|
|
127
|
+
[alt]="order.tenantName ?? 'Local'" />
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Portada con varias resoluciones
|
|
131
|
+
|
|
132
|
+
```html
|
|
133
|
+
<!-- ❌ mal: la directiva reintenta sobre img.src; con srcset purga la candidata equivocada (lo documenta pages/customer/store-browser/store-browser.html:332) -->
|
|
134
|
+
<img class="fila__img" suiImgRetry [src]="store.coverThumbUrl" [srcset]="portadaSrcset(store)" [alt]="store.name" />
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
```html
|
|
138
|
+
<!-- ✅ bien: src único, del tamaño que pide la tarjeta -->
|
|
139
|
+
<img class="fila__img" suiImgRetry [src]="store.coverThumbUrl" [alt]="store.name" decoding="async" />
|
|
140
|
+
```
|
|
92
141
|
|
|
93
142
|
## Ejemplo
|
|
94
143
|
|