@ajuarezso/sui-design-system 0.25.0 → 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.
Files changed (118) hide show
  1. package/docs/sui-accordion/README.md +83 -9
  2. package/docs/sui-activity-feed/README.md +55 -1
  3. package/docs/sui-activity-filter/README.md +50 -1
  4. package/docs/sui-alert/README.md +54 -0
  5. package/docs/sui-app-store-badge/README.md +57 -3
  6. package/docs/sui-avatar/README.md +66 -6
  7. package/docs/sui-avatar-group/README.md +64 -2
  8. package/docs/sui-badge/README.md +79 -11
  9. package/docs/sui-banner/README.md +70 -5
  10. package/docs/sui-brand-logo/README.md +77 -14
  11. package/docs/sui-breadcrumb-item/README.md +51 -0
  12. package/docs/sui-breadcrumbs/README.md +48 -0
  13. package/docs/sui-button/README.md +68 -6
  14. package/docs/sui-button-group/README.md +70 -5
  15. package/docs/sui-button-group-item/README.md +68 -4
  16. package/docs/sui-card/README.md +97 -10
  17. package/docs/sui-chart-legend/README.md +53 -0
  18. package/docs/sui-chart-legend-dot/README.md +49 -0
  19. package/docs/sui-checkbox/README.md +106 -26
  20. package/docs/sui-checkbox-card/README.md +58 -2
  21. package/docs/sui-checkbox-label/README.md +89 -23
  22. package/docs/sui-circular-progress-bar/README.md +63 -5
  23. package/docs/sui-color-dot/README.md +61 -5
  24. package/docs/sui-color-picker/README.md +62 -4
  25. package/docs/sui-command-menu-footer/README.md +49 -0
  26. package/docs/sui-command-menu-item/README.md +63 -4
  27. package/docs/sui-command-menu-search/README.md +58 -4
  28. package/docs/sui-compact-avatar-group/README.md +61 -4
  29. package/docs/sui-compact-button/README.md +112 -28
  30. package/docs/sui-compact-select/README.md +58 -4
  31. package/docs/sui-compact-select-for-input/README.md +69 -5
  32. package/docs/sui-content-card/README.md +63 -2
  33. package/docs/sui-content-divider/README.md +49 -1
  34. package/docs/sui-content-label/README.md +83 -4
  35. package/docs/sui-counter-input/README.md +91 -7
  36. package/docs/sui-date-selector/README.md +61 -3
  37. package/docs/sui-datepicker/README.md +72 -5
  38. package/docs/sui-day-cell/README.md +60 -3
  39. package/docs/sui-day-label/README.md +52 -3
  40. package/docs/sui-divider/README.md +57 -5
  41. package/docs/sui-drawer-footer/README.md +63 -2
  42. package/docs/sui-drawer-header/README.md +60 -3
  43. package/docs/sui-dropdown-caption/README.md +53 -1
  44. package/docs/sui-dropdown-item/README.md +72 -6
  45. package/docs/sui-dropdown-menu/README.md +74 -5
  46. package/docs/sui-dropdown-search/README.md +57 -1
  47. package/docs/sui-emoji/README.md +82 -18
  48. package/docs/sui-empty-state/README.md +68 -4
  49. package/docs/sui-fancy-button/README.md +59 -1
  50. package/docs/sui-file-icon/README.md +56 -1
  51. package/docs/sui-file-upload/README.md +69 -9
  52. package/docs/sui-file-upload-card/README.md +53 -2
  53. package/docs/sui-filter/README.md +74 -5
  54. package/docs/sui-flag/README.md +62 -1
  55. package/docs/sui-form-hint/README.md +54 -5
  56. package/docs/sui-form-label/README.md +53 -1
  57. package/docs/sui-href/README.md +47 -0
  58. package/docs/sui-icon/README.md +69 -4
  59. package/docs/sui-image-upload/README.md +70 -3
  60. package/docs/sui-image-upload-profile/README.md +58 -0
  61. package/docs/sui-img-retry/README.md +49 -0
  62. package/docs/sui-inline-input/README.md +61 -3
  63. package/docs/sui-inline-select/README.md +60 -0
  64. package/docs/sui-input/README.md +77 -14
  65. package/docs/sui-integration-switch/README.md +69 -2
  66. package/docs/sui-kbd/README.md +71 -7
  67. package/docs/sui-key-icon/README.md +65 -6
  68. package/docs/sui-link-button/README.md +79 -13
  69. package/docs/sui-logo/README.md +74 -4
  70. package/docs/sui-modal/README.md +61 -2
  71. package/docs/sui-modal-footer/README.md +83 -9
  72. package/docs/sui-modal-header/README.md +56 -0
  73. package/docs/sui-modal-sheet/README.md +72 -10
  74. package/docs/sui-notification/README.md +71 -1
  75. package/docs/sui-notification-footer/README.md +51 -1
  76. package/docs/sui-notification-tab-menu/README.md +57 -1
  77. package/docs/sui-otp-input/README.md +67 -6
  78. package/docs/sui-page-header/README.md +83 -15
  79. package/docs/sui-pagination/README.md +60 -0
  80. package/docs/sui-password-strength/README.md +50 -1
  81. package/docs/sui-payment-icon/README.md +66 -7
  82. package/docs/sui-period-range/README.md +65 -6
  83. package/docs/sui-popover/README.md +73 -7
  84. package/docs/sui-product-card/README.md +76 -8
  85. package/docs/sui-progress-bar/README.md +72 -8
  86. package/docs/sui-progress-bar-label/README.md +69 -12
  87. package/docs/sui-radio/README.md +83 -6
  88. package/docs/sui-radio-card/README.md +58 -4
  89. package/docs/sui-radio-label/README.md +86 -19
  90. package/docs/sui-rating/README.md +81 -14
  91. package/docs/sui-rich-editor/README.md +45 -0
  92. package/docs/sui-segmented-control/README.md +83 -14
  93. package/docs/sui-select/README.md +72 -3
  94. package/docs/sui-sidebar/README.md +64 -9
  95. package/docs/sui-slider/README.md +68 -1
  96. package/docs/sui-social-button/README.md +63 -3
  97. package/docs/sui-status-badge/README.md +64 -6
  98. package/docs/sui-stepper/README.md +57 -0
  99. package/docs/sui-store-card/README.md +71 -8
  100. package/docs/sui-switch/README.md +80 -9
  101. package/docs/sui-switch-card/README.md +70 -6
  102. package/docs/sui-switch-label/README.md +90 -13
  103. package/docs/sui-tab-chips/README.md +79 -9
  104. package/docs/sui-tab-menu-horizontal/README.md +62 -1
  105. package/docs/sui-tab-menu-vertical/README.md +56 -3
  106. package/docs/sui-table/README.md +68 -7
  107. package/docs/sui-tag/README.md +75 -4
  108. package/docs/sui-tag-input/README.md +71 -7
  109. package/docs/sui-textarea/README.md +78 -11
  110. package/docs/sui-time-picker/README.md +70 -7
  111. package/docs/sui-toast/README.md +65 -5
  112. package/docs/sui-tooltip/README.md +61 -4
  113. package/docs/sui-topbar/README.md +57 -3
  114. package/docs/sui-topbar-button/README.md +57 -3
  115. package/docs/sui-topbar-item/README.md +61 -0
  116. package/docs/sui-topbar-user/README.md +56 -0
  117. package/package.json +1 -1
  118. package/types/ajuarezso-sui-design-system.d.ts +19 -19
@@ -45,7 +45,7 @@ de cambios de una versión.
45
45
 
46
46
  | valor | cuándo | ejemplo real de la app | fuente |
47
47
  |---|---|---|---|
48
- | `[leftIcon]="false"` | el caso normal: el título se explica solo | `pages/envios/envios.html:412` («Más detalles (opcional)») | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
48
+ | `[leftIcon]="false"` | el caso normal: el título se explica solo | `pages/envios/envios.html:413` («Más detalles (opcional)») | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
49
49
  | `true` (default, `question-line`) | **solo** si el título es una pregunta de ayuda | `pages/driver/driver-profile/driver-profile.html:156` («¿Por qué no me llegan pedidos?») | propuesta |
50
50
  | un nombre de ícono | el ícono dice de qué es la sección y hay varias juntas | `pages/notifications/notifications.html:72` (`settings-3-line`) | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
51
51
 
@@ -63,11 +63,12 @@ son preguntas y van sin ícono; las dos de ayuda dentro de la app, con. Elegir u
63
63
  | `description` | **una respuesta corta en texto** (FAQ): aparece al abrir, alineada con el título | según el Figma del DS |
64
64
  | contenido proyectado | cualquier otra cosa: campos, listas, cards, tablas | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
65
65
 
66
- **A revisar:** 4 accordions pasan un **resumen** en `description` (`resumenReto()`,
67
- `resumenVotaciones()`, `resumenDetalles()`…) que, por cómo funciona el componente, **solo se ve
68
- con el accordion abierto**. Si la idea era ver el resumen cerrado, hoy no se ve:
69
- `pages/driver/driver-dashboard/driver-dashboard.html:287` y `:486`,
70
- `pages/envios/envios.html:412`, `pages/customer/mandadito/mandadito.html:188`.
66
+ **A revisar:** 2 accordions pasan un **resumen** en `description` (`resumenDetallesEnvio()`,
67
+ `resumenDetalles()`) que, por cómo funciona el componente, **solo se ve con el accordion
68
+ abierto**. Si la idea era ver el resumen cerrado, hoy no se ve:
69
+ `pages/envios/envios.html:413` y `pages/customer/mandadito/mandadito.html:189`. Los dos del
70
+ dashboard del repartidor («Votaciones» y «Reto semanal») ya pasaron su resumen al `badge`
71
+ (05-10-2026), que sí se ve cerrado.
71
72
 
72
73
  ### `lazy` — cuándo diferir el contenido
73
74
 
@@ -79,15 +80,15 @@ con el accordion abierto**. Si la idea era ver el resumen cerrado, hoy no se ve:
79
80
 
80
81
  **Usos de hoy que no hacen lo que parecen:** 4 accordions usan `<ng-template suiAccordionContent>`
81
82
  **sin** `[lazy]="true"`, y sin `lazy` el template se crea al cargar igual que el contenido plano:
82
- `pages/envios/envios.html:418` y `:743`, `pages/customer/order-tracking/order-tracking.html:590`,
83
- `pages/customer/mandadito/mandadito.html:194`. Les falta `[lazy]="true"`.
83
+ `pages/envios/envios.html:413` y `:756`, `pages/customer/order-tracking/order-tracking.html:611`,
84
+ `pages/customer/mandadito/mandadito.html:189`. Les falta `[lazy]="true"`.
84
85
 
85
86
  ### `flipIcon` y `badge`
86
87
 
87
88
  | input | cuándo | fuente |
88
89
  |---|---|---|
89
90
  | `flipIcon="on"` | listas largas donde el «+» a la izquierda se escanea mejor que a la derecha. 0 usos hoy | según el Figma del DS (la variante existe) |
90
- | `badge` | marcar una sección como nueva o actualizada («Nuevo»). Extensión de SUI; 0 usos hoy | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
91
+ | `badge` | marcar una sección como nueva o actualizada («Nuevo»), o dejar a la vista con la fila cerrada un estado de una o dos palabras («Sin reto», «3 de 10»). Extensión de SUI; 2 usos hoy, los dos del segundo tipo: `pages/driver/driver-dashboard/driver-dashboard.html:332` y `:516` | «Nuevo»: canon (aprobado por el dueño, 05-10-2026, bloque B9) · estado con la fila cerrada: pedido del dueño, 05-10-2026 (`core/resumen-acordeones-repartidor.ts`) |
91
92
 
92
93
  ## Tamaño en mobile y en web
93
94
 
@@ -100,6 +101,35 @@ cómoda en mobile.
100
101
  | fila | ancho completo, 48 px | igual | componente |
101
102
  | texto | Label/Small 14 y Paragraph/Small 14 | igual | según el Figma del DS |
102
103
 
104
+ ### Por dispositivo (D16)
105
+
106
+ La fila no tiene `size`: mide 48 en todos los dispositivos, que ya pasa los 44 del dedo en el
107
+ celular y la tablet, y en la computadora no estorba. Lo único con tamaño es el **`badge`**, que
108
+ no se toca y sigue la fila de `badge` de D16. El accordion lo pinta en `small` si no le pasas
109
+ `size` (también con el atajo `badge="Nuevo"`), y D16 no deja nada en `small`:
110
+
111
+ | dispositivo | size del `badge` | nota |
112
+ |---|---|---|
113
+ | celular chico (< 380) | `medium` | lo que no se toca no sube en el celular chico |
114
+ | celular (380–767) | `large` | un paso más que en la computadora (P1 b). No `xlarge`: ver abajo |
115
+ | tablet táctil | `medium` | |
116
+ | computadora | `medium` | `medium` va sin MAYÚSCULAS |
117
+
118
+ Ultrawide: igual que la computadora. Fuente: D16, dueño 05-10-2026.
119
+
120
+ **Por qué `large` y no `xlarge` en el celular**, aunque el badge va en la fila del título
121
+ (`.sui-accordion__title-row`): la excepción «`xlarge` junto a un título» de D16 es para un título
122
+ de encabezado o un monto: según el README de `sui-badge`, en el celular el badge va al lado de
123
+ textos de 16. El título del accordion es
124
+ Label/Small 14/20, el mismo nivel que una fila de lista: un `xlarge` (28, texto 16) tendría letra
125
+ más grande que el título que acompaña, y `large` (24, texto 14) lo iguala. Es una lectura de D16,
126
+ no una decisión aparte del dueño; si se quiere `xlarge` aquí, lo decide él. `bp.sizeBadge()` ya da
127
+ `large`/`medium`, así que no hace falta otra expresión.
128
+
129
+ En master-pedidos: `[badge]="{ label: 'Nuevo', size: bp.sizeBadge() }"`. Hoy los dos badges del
130
+ dashboard del repartidor salen en `medium` fijo (`core/resumen-acordeones-repartidor.ts:19`):
131
+ en el celular les falta subir a `large`.
132
+
103
133
  ## API
104
134
 
105
135
  <!-- api:inicio -->
@@ -150,6 +180,50 @@ Slots: contenido plano (o con el atributo `sui-accordion-body`) y el template
150
180
  contenido cambia de alto estando abierto, acompaña.
151
181
  - El host borra el atributo `title` nativo (sin tooltip gris del navegador).
152
182
 
183
+ ## Bien y mal
184
+
185
+ Contenido diferido
186
+
187
+ ```html
188
+ <!-- ❌ mal: el template sin [lazy] se crea al cargar igual (pages/envios/envios.html:756) -->
189
+ <sui-accordion [title]="tituloDetalle(e)" [leftIcon]="false" [(open)]="detalleAbierto">
190
+ <ng-template suiAccordionContent>…</ng-template>
191
+ </sui-accordion>
192
+ ```
193
+
194
+ ```html
195
+ <!-- ✅ bien -->
196
+ <sui-accordion [title]="tituloDetalle(e)" [leftIcon]="false" [lazy]="true" [(open)]="detalleAbierto">
197
+ <ng-template suiAccordionContent>…</ng-template>
198
+ </sui-accordion>
199
+ ```
200
+
201
+ Resumen de la fila cerrada
202
+
203
+ ```html
204
+ <!-- ❌ mal: description solo se ve abierto; cerrado, el resumen no aparece (pages/envios/envios.html:413) -->
205
+ <sui-accordion title="Más detalles (opcional)" [description]="resumenDetallesEnvio()"
206
+ [leftIcon]="false" />
207
+ ```
208
+
209
+ ```html
210
+ <!-- ✅ bien: lo que tiene que verse cerrado va en el título, como en master-orders.html:673 -->
211
+ <sui-accordion [title]="'Más detalles · ' + resumenDetallesEnvio()" [leftIcon]="false" />
212
+ ```
213
+
214
+ Badge en la fila
215
+
216
+ ```html
217
+ <!-- ❌ mal: el atajo de string sale en small, y D16 no deja nada en small -->
218
+ <sui-accordion title="Reto semanal" badge="Nuevo" [leftIcon]="false" />
219
+ ```
220
+
221
+ ```html
222
+ <!-- ✅ bien -->
223
+ <sui-accordion title="Reto semanal" [badge]="{ label: 'Nuevo', size: bp.sizeBadge() }"
224
+ [leftIcon]="false" />
225
+ ```
226
+
153
227
  ## Ejemplo
154
228
 
155
229
  ```html
@@ -69,6 +69,16 @@ de texto **envuelve** (`flex-wrap`), así que en mobile un «Ana aprobó la reca
69
69
  En táctil, el botón de tres puntos y la descarga miden 20 y 28: por debajo del área cómoda. Si
70
70
  el feed va en mobile con acciones, esa es la primera mejora que pide el componente.
71
71
 
72
+ ### Por dispositivo (D16)
73
+
74
+ No aplica: el feed **no tiene `size`** y nada en él cambia por dispositivo (avatar o ícono de 32,
75
+ texto 14/20). Si va o no en el celular y la tablet táctil sigue **pendiente** (P59: antes hay que
76
+ decidir si el feed es solo de web), porque los tres puntos (20) y la descarga (28) no llegan a 44.
77
+ Lo que va alrededor sí sigue D16: el «Cargar más» es un `sui-button` con
78
+ `[size]="bp.sizeControl()"`. El avatar del leading lo fija el feed en 32 (`SuiActivityAvatarRef`
79
+ no tiene `size`), así que no sube un paso en el celular como pide D16 para `avatar`: cambiarlo es
80
+ código del DS.
81
+
72
82
  ## «No usar»: por qué no hoy y cuándo sí
73
83
 
74
84
  | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
@@ -130,13 +140,57 @@ interface SuiActivityTask { state: 'success' | 'warning' | 'pending' | 'error';
130
140
  - No hay estado vacío ni de carga: cuando `items` está vacío no se ve nada. Usa `sui-empty-state`
131
141
  afuera, y un skeleton mientras llega la primera página.
132
142
 
143
+ ## Bien y mal
144
+
145
+ Historial vacío
146
+
147
+ ```html
148
+ <!-- ❌ mal: con items vacío el feed no pinta nada y queda un hueco (Trampas) -->
149
+ <sui-activity-feed [items]="historial()" />
150
+ ```
151
+
152
+ ```html
153
+ <!-- ✅ bien -->
154
+ @if (historial().length) {
155
+ <sui-activity-feed [items]="historial()" />
156
+ } @else {
157
+ <sui-empty-state title="Todavía no hay actividad" />
158
+ }
159
+ ```
160
+
161
+ Descargar un archivo
162
+
163
+ ```html
164
+ <!-- ❌ mal: file.href no lo lee la plantilla; sin (fileDownload) el chip no baja nada -->
165
+ <sui-activity-feed [items]="comprobantes()" />
166
+ ```
167
+
168
+ ```html
169
+ <!-- ✅ bien -->
170
+ <sui-activity-feed [items]="comprobantes()" (fileDownload)="descargar($event.file)" />
171
+ ```
172
+
173
+ Menú de los tres puntos
174
+
175
+ ```html
176
+ <!-- ❌ mal: los outputs hacen stopPropagation; el (click) del padre no se entera -->
177
+ <div (click)="abrirMenu()">
178
+ <sui-activity-feed [items]="historial()" />
179
+ </div>
180
+ ```
181
+
182
+ ```html
183
+ <!-- ✅ bien -->
184
+ <sui-activity-feed [items]="historial()" (action)="abrirMenu($event.item)" />
185
+ ```
186
+
133
187
  ## Ejemplo
134
188
 
135
189
  ```html
136
190
  <sui-card>
137
191
  <sui-activity-feed [items]="historial()" (fileDownload)="descargar($event.file)" />
138
192
  @if (hayMas()) {
139
- <sui-button variant="stroke" color="neutral" [size]="bp.isMobile() ? 'large' : 'medium'"
193
+ <sui-button variant="stroke" color="neutral" [size]="bp.sizeControl()"
140
194
  (click)="cargarMas()">Cargar más</sui-button>
141
195
  }
142
196
  </sui-card>
@@ -46,10 +46,19 @@ igual que `sui-tab-chips`; así nadie se queda con un historial vacío por combi
46
46
 
47
47
  | uso | mobile | web | fuente |
48
48
  |---|---|---|---|
49
- | filtros del activity feed | no usar: 30 no llega al dedo; usar `sui-tab-chips` en `xlarge` (44) | `sui-activity-filter` | canon (aprobado por el dueño, 05-10-2026, bloque B13) |
49
+ | filtros del activity feed | no usar: 30 no llega al dedo; usar `sui-tab-chips` en `xlarge` (44). Vale también para la tablet táctil | `sui-activity-filter` | canon (aprobado por el dueño, 05-10-2026, bloque B13) · tablet: D16, dueño 05-10-2026 |
50
50
 
51
51
  La fila de chips la arma la pantalla: el componente no trae contenedor ni scroll lateral.
52
52
 
53
+ ### Por dispositivo (D16)
54
+
55
+ No aplica: no tiene `size` (mide 30 en todos lados), así que D16 no le elige tamaño sino **si
56
+ va**. Con 30 no llega a los 44 del dedo: en el celular (también el chico) y en la tablet táctil
57
+ va `sui-tab-chips`, con los sizes de su fila de D16 (B13); en la computadora y el ultrawide, este
58
+ chip. Fuente: D16, dueño 05-10-2026.
59
+
60
+ En master-pedidos: `@if (bp.tactil()) { <sui-tab-chips [size]="bp.sizeChips()" …/> } @else { <sui-activity-filter …> }`.
61
+
53
62
  ## «No usar»: por qué no hoy y cuándo sí
54
63
 
55
64
  | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
@@ -88,6 +97,46 @@ Slot: `<ng-content>` (el texto del chip).
88
97
  - El foco usa un `outline` de 2 px naranja, no el doble anillo de los inputs del DS.
89
98
  - Ya trae el arreglo de iOS para el `:active` pegado.
90
99
 
100
+ ## Bien y mal
101
+
102
+ Escuchar el toque
103
+
104
+ ```html
105
+ <!-- ❌ mal: con (click) el filtro no responde a Enter ni Espacio (Trampas) -->
106
+ <sui-activity-filter icon="chat-3-line" (click)="filtro.set('comentarios')">Comentarios</sui-activity-filter>
107
+ ```
108
+
109
+ ```html
110
+ <!-- ✅ bien -->
111
+ <sui-activity-filter icon="chat-3-line" [active]="filtro() === 'comentarios'" (clicked)="filtro.set('comentarios')">Comentarios</sui-activity-filter>
112
+ ```
113
+
114
+ El chip «Todos»
115
+
116
+ ```html
117
+ <!-- ❌ mal: sin icon sale el de archivos por defecto -->
118
+ <sui-activity-filter [active]="filtro() === 'todos'" (clicked)="filtro.set('todos')">Todos</sui-activity-filter>
119
+ ```
120
+
121
+ ```html
122
+ <!-- ✅ bien -->
123
+ <sui-activity-filter [icon]="null" [active]="filtro() === 'todos'" (clicked)="filtro.set('todos')">Todos</sui-activity-filter>
124
+ ```
125
+
126
+ En el celular o la tablet
127
+
128
+ ```html
129
+ <!-- ❌ mal: 30 de alto no llega al dedo (B13 y D16) -->
130
+ <sui-activity-filter icon="task-line" (clicked)="filtro.set('tareas')">Tareas</sui-activity-filter>
131
+ ```
132
+
133
+ ```html
134
+ <!-- ✅ bien -->
135
+ @if (bp.tactil()) {
136
+ <sui-tab-chips [chips]="filtros" [(value)]="filtro" [size]="bp.sizeChips()" />
137
+ } @else { … }
138
+ ```
139
+
91
140
  ## Ejemplo
92
141
 
93
142
  ```html
@@ -152,6 +152,16 @@ en mobile es el ancho: ocupa toda la columna.
152
152
  | la X de cerrar (`dismissible`) | se ve de 16 px en `xsmall`, 20 en `small`, 24 en `large`, 28 en `xlarge`; **se toca en 44 × 44** (`::before` invisible; en `xsmall`/`small` el alert mide 32/36 y recorta el área a su alto, y a la izquierda solo crece 4 para no pisar las acciones inline) | se ve igual, sin área extra | canon (dueño, 04-10-2026): piso táctil 44 en el teléfono |
153
153
  | las acciones (`actions[]`) | link de 20 px de alto en `large`/`xlarge`, 16 en `small`/`xsmall` | igual | según el componente |
154
154
 
155
+ ### Por dispositivo (D16)
156
+
157
+ No aplica: el `size` del alert lo elige el **contenido** (con descripción `large`, de una línea
158
+ `small`, dentro de un campo `xsmall`), no el dispositivo, y es el mismo en el celular, la tablet
159
+ y la computadora. Por eso no hay helper de `bp`: se escribe el literal. Queda **pendiente** si
160
+ `small`/`xsmall` chocan con el «nada en `small`» de D16: la hoja de decisiones las dejó fuera
161
+ porque ahí el `size` cambia el layout, no la escala. También queda pendiente el área de 44 de la
162
+ X en la **tablet táctil**: hoy se prende solo con `max-width: 767px`, y el arreglo (mixin
163
+ `sui-tactil` con `pointer: coarse`) espera el sí del dueño.
164
+
155
165
 
156
166
  ## API
157
167
 
@@ -219,6 +229,50 @@ Slot: `<ng-content select="[slot=action]">` — legado; solo se usa si `actions`
219
229
  - El slot de acción usa `slot=`; los de badge y button usan `data-slot=`.
220
230
  - El host borra el atributo `title` nativo (no aparece el tooltip gris del navegador).
221
231
 
232
+ ## Bien y mal
233
+
234
+ Aviso con descripción
235
+
236
+ ```html
237
+ <!-- ❌ mal: en small la descripción no se pinta (pages/super-admin/master-settings/master-settings.html:635) -->
238
+ <sui-alert size="small" title="Todavía no guardaste ninguna escala"
239
+ description="Estos son los niveles que trae la app." />
240
+ ```
241
+
242
+ ```html
243
+ <!-- ✅ bien -->
244
+ <sui-alert size="large" title="Todavía no guardaste ninguna escala"
245
+ description="Estos son los niveles que trae la app." />
246
+ ```
247
+
248
+ Aviso que solo informa
249
+
250
+ ```html
251
+ <!-- ❌ mal: filled compite con el botón principal y no frena nada (pages/driver/driver-earnings/driver-earnings.html:16) -->
252
+ <sui-alert variantStyle="filled" variant="info" title="Cobras por cada entrega"
253
+ description="Esto es lo que llevas ganado por las entregas que completaste." />
254
+ ```
255
+
256
+ ```html
257
+ <!-- ✅ bien -->
258
+ <sui-alert variant="info" title="Cobras por cada entrega"
259
+ description="Esto es lo que llevas ganado por las entregas que completaste." />
260
+ ```
261
+
262
+ Una sola acción
263
+
264
+ ```html
265
+ <!-- ❌ mal: la primera acción va subrayada y esta no (pages/notifications/notifications.ts:200) -->
266
+ <sui-alert variant="info" title="Activa las notificaciones"
267
+ [actions]="[{ label: 'Activar', onClick: activar }]" />
268
+ ```
269
+
270
+ ```html
271
+ <!-- ✅ bien -->
272
+ <sui-alert variant="info" title="Activa las notificaciones"
273
+ [actions]="[{ label: 'Activar', onClick: activar, underline: true }]" />
274
+ ```
275
+
222
276
  ## Ejemplo
223
277
 
224
278
  ```html
@@ -77,13 +77,23 @@ Regla del dueño, 03-10-2026.
77
77
  | footer de las landings, «Descarga la app» | `[height]="44"` | `[height]="40"` (default) | mobile: canon (decisión del dueño 04-10-2026, piso táctil 44) · web: propuesta |
78
78
 
79
79
  ```html
80
- <sui-app-store-badge company="app-store" [height]="bp.isMobile() ? 48 : 40" href="…" target="_blank"
80
+ <sui-app-store-badge company="app-store" [height]="bp.tactil() ? 48 : 40" href="…" target="_blank"
81
81
  ariaLabel="Descargar Master Pedidos en App Store" />
82
82
  ```
83
83
 
84
84
  Los dos sellos siempre a la misma altura. Hoy los 10 usan la altura default (40) también en mobile:
85
85
  quedan 4 px por debajo de los 44.
86
86
 
87
+ ### Por dispositivo (D16)
88
+
89
+ **No tiene `size`**: el alto va en px por `[height]`, así que no hay escala que repartir por
90
+ dispositivo. Lo que sí aplica es la regla de lo que se toca: el sello es un link, y en toda
91
+ pantalla táctil (celular, celular chico y tablet con `pointer: coarse`) va a **44 o más**; en la
92
+ computadora, 40. En el ultrawide, igual que en la computadora. Por eso la condición es
93
+ `bp.tactil()` y no `bp.isMobile()`: con `isMobile` el iPad se queda en 40.
94
+
95
+ En master-pedidos: `[height]="bp.tactil() ? 44 : 40"` (footer) · `[height]="bp.tactil() ? 48 : 40"` (hero, propuesta).
96
+
87
97
  ## «No usar»: por qué no hoy y cuándo sí
88
98
 
89
99
  Nada se borra del DS. Lo marcado «no usar» no tiene caso en la app de hoy; si un flujo nuevo cae
@@ -126,13 +136,57 @@ Outputs: ninguno.
126
136
  - `height` escala el sello entero; no le pongas `width` desde afuera o se deforma.
127
137
  - El hover baja la opacidad a 0.85, como recomienda Apple; no hay estado activo propio de las tiendas.
128
138
 
139
+ ## Bien y mal
140
+
141
+ Texto para el lector de pantalla
142
+
143
+ ```html
144
+ <!-- ❌ mal: alt genérico, no dice qué app (components/landing-footer/landing-footer.html:18) -->
145
+ <sui-app-store-badge company="app-store" appearance="alternative" href="…" target="_blank"
146
+ ariaLabel="Descargar en App Store" />
147
+ ```
148
+
149
+ ```html
150
+ <!-- ✅ bien -->
151
+ <sui-app-store-badge company="app-store" appearance="alternative" [height]="bp.tactil() ? 44 : 40"
152
+ href="…" target="_blank" ariaLabel="Descargar Master Pedidos en App Store" />
153
+ ```
154
+
155
+ Alto en una pantalla táctil
156
+
157
+ ```html
158
+ <!-- ❌ mal: sin [height] queda en 40 también en el celular, 4 px bajo el piso de 44 (pages/public/landing-customers/landing-customers.html:32) -->
159
+ <sui-app-store-badge company="google-play" appearance="preferred" href="…" target="_blank"
160
+ ariaLabel="Descargar Master Pedidos en Google Play" />
161
+ ```
162
+
163
+ ```html
164
+ <!-- ✅ bien: 44 es el piso táctil; en el hero, 48 si se aprueba esa propuesta -->
165
+ <sui-app-store-badge company="google-play" appearance="preferred" [height]="bp.tactil() ? 44 : 40"
166
+ href="…" target="_blank" ariaLabel="Descargar Master Pedidos en Google Play" />
167
+ ```
168
+
169
+ Sello que no lleva a ningún lado
170
+
171
+ ```html
172
+ <!-- ❌ mal: sin href pinta solo la imagen, sin foco ni clic (ver «Trampas») -->
173
+ <sui-app-store-badge company="app-store" ariaLabel="Descargar Master Pedidos en App Store" />
174
+ ```
175
+
176
+ ```html
177
+ <!-- ✅ bien -->
178
+ <sui-app-store-badge company="app-store" [height]="bp.tactil() ? 44 : 40"
179
+ href="https://apps.apple.com/pe/app/master-pedidos/id6764676191"
180
+ target="_blank" ariaLabel="Descargar Master Pedidos en App Store" />
181
+ ```
182
+
129
183
  ## Ejemplo
130
184
 
131
185
  ```html
132
- <sui-app-store-badge company="app-store"
186
+ <sui-app-store-badge company="app-store" [height]="bp.tactil() ? 44 : 40"
133
187
  href="https://apps.apple.com/pe/app/master-pedidos/id6764676191" target="_blank"
134
188
  ariaLabel="Descargar Master Pedidos en App Store" />
135
- <sui-app-store-badge company="google-play"
189
+ <sui-app-store-badge company="google-play" [height]="bp.tactil() ? 44 : 40"
136
190
  href="https://play.google.com/store/apps/details?id=com.masterpedidos.app" target="_blank"
137
191
  ariaLabel="Descargar Master Pedidos en Google Play" />
138
192
  ```
@@ -181,12 +181,32 @@ se migra todo ahora, no solo al tocar cada pantalla.
181
181
  | cabecera de una ficha | `3xl` (64) | `2xl` (56) |
182
182
 
183
183
  ```html
184
- <sui-avatar [size]="bp.isMobile() ? 'lg' : 'md'" color="blue" [initials]="c.nombre" [alt]="c.nombre" />
184
+ <sui-avatar [size]="bp.sizeAvatar('md')" color="blue" [initials]="c.nombre" [alt]="c.nombre" />
185
185
  ```
186
186
 
187
187
  El avatar no se toca solo: si la fila o la card es tocable, el área táctil (44 px o más) la da
188
- la fila, no el avatar. Hoy **ningún** avatar cambia de tamaño por breakpoint; las pantallas del
189
- cliente y del repartidor usan `lg` en las tarjetas, un paso por debajo de esta tabla.
188
+ la fila, no el avatar. Medido el 06-10-2026: 56 de los 57 avatares de la app ya van con
189
+ `bp.sizeAvatar(…)`; el único fijo es `pages/driver-onboarding/step-info/step-info.html:31`
190
+ (`3xl`, tu foto al registrarte).
191
+
192
+ ### Por dispositivo (D16)
193
+
194
+ El avatar no se toca: sube un paso **solo en el celular de 380 px o más**. Fuente: D16, dueño
195
+ 05-10-2026 (P1 b).
196
+
197
+ | dispositivo | size | nota |
198
+ |---|---|---|
199
+ | celular chico (< 380) | valor «web» (`md` en una fila) | no se toca: no sube aunque sea un celular |
200
+ | celular (380–767) | valor «mobile» (`lg` en una fila) | un paso más que en la computadora |
201
+ | tablet táctil (`pointer: coarse`) | valor «web» (`md` en una fila) | no se toca: el puntero no cambia nada |
202
+ | computadora (`pointer: fine`) | valor «web» (`md` en una fila) | |
203
+
204
+ En el ultrawide, igual que en la computadora: el espacio extra va a más columnas, no a avatares
205
+ más grandes.
206
+
207
+ En master-pedidos: `[size]="bp.sizeAvatar('md')"` — recibe el valor de la computadora y en el
208
+ celular devuelve el siguiente de la escala, con tope en `3xl` (no sube a `4xl`/`5xl`). No uses
209
+ `bp.isMobile() ? 'lg' : 'md'`: `isMobile` incluye el celular chico, que va con el valor de web.
190
210
 
191
211
  ## «No usar»: por qué no hoy y cuándo sí
192
212
 
@@ -252,15 +272,55 @@ interface SuiAvatarConfig {
252
272
  - **No tiene `title`, ni output, ni es clickeable.** Para tocarlo, envuélvelo en un botón o en
253
273
  la card que ya lo es.
254
274
 
275
+ ## Bien y mal
276
+
277
+ Estado de la cuenta de un empleado
278
+
279
+ ```html
280
+ <!-- ❌ mal: el punto es presencia (conectado ahora), no «cuenta activa»; y sin alt (pages/employees/employees.html:70) -->
281
+ <sui-avatar [size]="bp.sizeAvatar('lg')" color="orange" [initials]="employee.initials"
282
+ [status]="employee.status === 'Activo' ? 'online' : 'offline'" />
283
+ ```
284
+
285
+ ```html
286
+ <!-- ✅ bien -->
287
+ <sui-avatar [size]="bp.sizeAvatar('lg')" color="orange" [initials]="employee.initials" [alt]="employee.name" />
288
+ <sui-badge [size]="bp.sizeBadge()" color="green">Activo</sui-badge>
289
+ ```
290
+
291
+ Repartidor en una fila
292
+
293
+ ```html
294
+ <!-- ❌ mal: sin alt, el lector de pantalla no dice quién es; y en una fila (aquí, el ranking de rendimiento) la tabla de tamaños pide md en web, no lg (pages/super-admin/master-drivers/master-drivers.html:256) -->
295
+ <sui-avatar [size]="bp.sizeAvatar('lg')" color="green" [initials]="iniciales(d.nombre)" />
296
+ ```
297
+
298
+ ```html
299
+ <!-- ✅ bien -->
300
+ <sui-avatar [size]="bp.sizeAvatar('md')" color="green" [initials]="iniciales(d.nombre)" [alt]="d.nombre" />
301
+ ```
302
+
303
+ Color de una persona
304
+
305
+ ```html
306
+ <!-- ❌ mal: el color sale del vehículo, no del rol. El conductor queda blue, que es el color de cliente, y el motorizado purple, que no dice ningún rol. Los dos son postulantes a repartidor: green. Y falta el alt (pages/super-admin/master-solicitudes/master-solicitudes.html:24) -->
307
+ <sui-avatar [size]="bp.sizeAvatar('md')" [color]="f.tipo === 'conductor' ? 'blue' : 'purple'" [initials]="iniciales(f.nombre)" />
308
+ ```
309
+
310
+ ```html
311
+ <!-- ✅ bien -->
312
+ <sui-avatar [size]="bp.sizeAvatar('md')" color="green" [initials]="iniciales(f.nombre)" [alt]="f.nombre" />
313
+ ```
314
+
255
315
  ## Ejemplo
256
316
 
257
317
  ```html
258
318
  <!-- Tu repartidor, en la tarjeta del seguimiento -->
259
- <sui-avatar size="lg" color="green" [src]="driverPhotoUrl()" [initials]="driverName" [alt]="driverName" />
319
+ <sui-avatar [size]="bp.sizeAvatar('lg')" color="green" [src]="driverPhotoUrl()" [initials]="driverName" [alt]="driverName" />
260
320
 
261
321
  <!-- El local, en una fila -->
262
- <sui-avatar size="md" color="orange" [src]="tenantLogo" [initials]="tenantName" [alt]="tenantName" />
322
+ <sui-avatar [size]="bp.sizeAvatar('md')" color="orange" [src]="tenantLogo" [initials]="tenantName" [alt]="tenantName" />
263
323
 
264
324
  <!-- Todavía sin repartidor -->
265
- <sui-avatar size="md" color="gray" icon="e-bike-2-line" alt="Sin repartidor" />
325
+ <sui-avatar [size]="bp.sizeAvatar('md')" color="gray" icon="e-bike-2-line" alt="Sin repartidor" />
266
326
  ```
@@ -65,9 +65,29 @@ se migra todo ahora, no solo al tocar cada pantalla.
65
65
  | dentro de una card | `lg` (40) | `md` (32) |
66
66
 
67
67
  ```html
68
- <sui-avatar-group [size]="bp.isMobile() ? 'md' : 'sm'" [max]="3" [items]="equipo" />
68
+ <sui-avatar-group [size]="bp.sizeAvatar('sm')" [max]="3" [items]="equipo" />
69
69
  ```
70
70
 
71
+ ### Por dispositivo (D16)
72
+
73
+ El grupo no se toca: sigue la misma regla que `sui-avatar` y sube un paso **solo en el celular
74
+ de 380 px o más**. Fuente: D16, dueño 05-10-2026 (P1 b).
75
+
76
+ | dispositivo | size | nota |
77
+ |---|---|---|
78
+ | celular chico (< 380) | valor «web» (`sm` en una fila, `md` en una card) | no se toca: no sube aunque sea un celular |
79
+ | celular (380–767) | valor «mobile» (`md` en una fila, `lg` en una card) | un paso más que en la computadora |
80
+ | tablet táctil (`pointer: coarse`) | valor «web» | no se toca: el puntero no cambia nada |
81
+ | computadora (`pointer: fine`) | valor «web» | |
82
+
83
+ En el ultrawide, igual que en la computadora.
84
+
85
+ En master-pedidos: `[size]="bp.sizeAvatar('sm')"` (fila) · `[size]="bp.sizeAvatar('md')"` (card).
86
+ No hay un helper propio del grupo: `sizeAvatar` sirve porque usa la misma escala (`SuiAvatarSize`).
87
+ No uses `bp.isMobile() ? 'md' : 'sm'`: `isMobile` incluye el celular chico, que va con el valor
88
+ de web. Ojo: con `bp.sizeAvatar('lg')` (cabecera de un panel) el celular sale en `xl`, que arriba
89
+ está en «no usar» — pendiente de decidir si la cabecera se queda en `lg` también en el celular.
90
+
71
91
  ## «No usar»: por qué no hoy y cuándo sí
72
92
 
73
93
  | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
@@ -107,10 +127,52 @@ interface SuiAvatarGroupItem {
107
127
  - El solape cambia con el tamaño (−4 px en `xs`/`sm`, −16 px desde `2xl`): en `lg` las iniciales
108
128
  de dos letras quedan tapadas a medias.
109
129
 
130
+ ## Bien y mal
131
+
132
+ Hoy no hay usos en la app (0 el 06-10-2026): los pares salen de las reglas de arriba.
133
+
134
+ Color de cada persona
135
+
136
+ ```html
137
+ <!-- ❌ mal: items sin color caen a slate y no dicen el rol (ver «size y max») -->
138
+ <sui-avatar-group [size]="bp.sizeAvatar('md')" [max]="3"
139
+ [items]="[{ initials: 'Carlos Mamani', alt: 'Carlos Mamani' }, { initials: 'Ana Torres', alt: 'Ana Torres' }]" />
140
+ ```
141
+
142
+ ```html
143
+ <!-- ✅ bien -->
144
+ <sui-avatar-group [size]="bp.sizeAvatar('md')" [max]="3"
145
+ [items]="[{ initials: 'Carlos Mamani', color: 'green', alt: 'Carlos Mamani' }, { initials: 'Ana Torres', color: 'green', alt: 'Ana Torres' }]" />
146
+ ```
147
+
148
+ Grupo dentro de una fila
149
+
150
+ ```html
151
+ <!-- ❌ mal: en xs (20 px) el «+N» no se lee, y sin [max] salen 4 en vez de 3 -->
152
+ <sui-avatar-group size="xs" [items]="equipo" />
153
+ ```
154
+
155
+ ```html
156
+ <!-- ✅ bien -->
157
+ <sui-avatar-group [size]="bp.sizeAvatar('sm')" [max]="3" [items]="equipo" />
158
+ ```
159
+
160
+ Tamaño fijo en una pantalla que se ve en los dos
161
+
162
+ ```html
163
+ <!-- ❌ mal: md fijo en el panel; en el celular queda un paso por debajo (D16) -->
164
+ <sui-avatar-group size="md" [max]="3" [items]="equipo" />
165
+ ```
166
+
167
+ ```html
168
+ <!-- ✅ bien -->
169
+ <sui-avatar-group [size]="bp.sizeAvatar('md')" [max]="3" [items]="equipo" />
170
+ ```
171
+
110
172
  ## Ejemplo
111
173
 
112
174
  ```html
113
- <sui-avatar-group size="md" [max]="3" [items]="[
175
+ <sui-avatar-group [size]="bp.sizeAvatar('md')" [max]="3" [items]="[
114
176
  { initials: 'Carlos Mamani', color: 'green', alt: 'Carlos Mamani' },
115
177
  { src: repartidor2.avatarUrl, initials: repartidor2.nombre, color: 'green', alt: repartidor2.nombre },
116
178
  { initials: 'Luis Huamán', color: 'green', alt: 'Luis Huamán' },