@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.
Files changed (120) hide show
  1. package/docs/sui-accordion/README.md +85 -11
  2. package/docs/sui-activity-feed/README.md +65 -11
  3. package/docs/sui-activity-filter/README.md +54 -5
  4. package/docs/sui-alert/README.md +54 -0
  5. package/docs/sui-app-store-badge/README.md +64 -10
  6. package/docs/sui-avatar/README.md +92 -29
  7. package/docs/sui-avatar-group/README.md +75 -9
  8. package/docs/sui-badge/README.md +85 -17
  9. package/docs/sui-banner/README.md +85 -20
  10. package/docs/sui-brand-logo/README.md +95 -31
  11. package/docs/sui-breadcrumb-item/README.md +54 -3
  12. package/docs/sui-breadcrumbs/README.md +54 -6
  13. package/docs/sui-button/README.md +76 -12
  14. package/docs/sui-button-group/README.md +91 -23
  15. package/docs/sui-button-group-item/README.md +81 -14
  16. package/docs/sui-card/README.md +105 -18
  17. package/docs/sui-chart-legend/README.md +63 -10
  18. package/docs/sui-chart-legend-dot/README.md +59 -10
  19. package/docs/sui-checkbox/README.md +109 -29
  20. package/docs/sui-checkbox-card/README.md +70 -14
  21. package/docs/sui-checkbox-label/README.md +92 -26
  22. package/docs/sui-circular-progress-bar/README.md +80 -19
  23. package/docs/sui-color-dot/README.md +72 -12
  24. package/docs/sui-color-picker/README.md +71 -13
  25. package/docs/sui-command-menu-footer/README.md +50 -1
  26. package/docs/sui-command-menu-item/README.md +74 -14
  27. package/docs/sui-command-menu-search/README.md +58 -3
  28. package/docs/sui-compact-avatar-group/README.md +73 -13
  29. package/docs/sui-compact-button/README.md +123 -34
  30. package/docs/sui-compact-select/README.md +61 -7
  31. package/docs/sui-compact-select-for-input/README.md +70 -6
  32. package/docs/sui-content-card/README.md +75 -14
  33. package/docs/sui-content-divider/README.md +67 -16
  34. package/docs/sui-content-label/README.md +99 -20
  35. package/docs/sui-counter-input/README.md +102 -18
  36. package/docs/sui-date-selector/README.md +69 -11
  37. package/docs/sui-datepicker/README.md +85 -18
  38. package/docs/sui-day-cell/README.md +75 -17
  39. package/docs/sui-day-label/README.md +56 -7
  40. package/docs/sui-divider/README.md +64 -9
  41. package/docs/sui-drawer-footer/README.md +63 -2
  42. package/docs/sui-drawer-header/README.md +69 -12
  43. package/docs/sui-dropdown-caption/README.md +58 -6
  44. package/docs/sui-dropdown-item/README.md +75 -9
  45. package/docs/sui-dropdown-menu/README.md +83 -14
  46. package/docs/sui-dropdown-search/README.md +60 -4
  47. package/docs/sui-emoji/README.md +94 -30
  48. package/docs/sui-empty-state/README.md +71 -7
  49. package/docs/sui-fancy-button/README.md +74 -14
  50. package/docs/sui-file-icon/README.md +70 -12
  51. package/docs/sui-file-upload/README.md +77 -17
  52. package/docs/sui-file-upload-card/README.md +64 -12
  53. package/docs/sui-filter/README.md +83 -14
  54. package/docs/sui-flag/README.md +73 -8
  55. package/docs/sui-form-hint/README.md +56 -7
  56. package/docs/sui-form-label/README.md +57 -5
  57. package/docs/sui-href/README.md +47 -0
  58. package/docs/sui-icon/README.md +86 -18
  59. package/docs/sui-image-upload/README.md +90 -22
  60. package/docs/sui-image-upload-profile/README.md +70 -11
  61. package/docs/sui-img-retry/README.md +50 -1
  62. package/docs/sui-inline-input/README.md +67 -9
  63. package/docs/sui-inline-select/README.md +62 -2
  64. package/docs/sui-input/README.md +90 -27
  65. package/docs/sui-integration-switch/README.md +84 -17
  66. package/docs/sui-kbd/README.md +73 -9
  67. package/docs/sui-key-icon/README.md +85 -23
  68. package/docs/sui-link-button/README.md +96 -27
  69. package/docs/sui-logo/README.md +93 -22
  70. package/docs/sui-modal/README.md +72 -13
  71. package/docs/sui-modal-footer/README.md +86 -12
  72. package/docs/sui-modal-header/README.md +57 -1
  73. package/docs/sui-modal-sheet/README.md +74 -12
  74. package/docs/sui-notification/README.md +81 -11
  75. package/docs/sui-notification-footer/README.md +55 -5
  76. package/docs/sui-notification-tab-menu/README.md +61 -5
  77. package/docs/sui-otp-input/README.md +70 -9
  78. package/docs/sui-page-header/README.md +89 -19
  79. package/docs/sui-pagination/README.md +73 -13
  80. package/docs/sui-password-strength/README.md +50 -1
  81. package/docs/sui-payment-icon/README.md +80 -18
  82. package/docs/sui-period-range/README.md +70 -11
  83. package/docs/sui-popover/README.md +81 -15
  84. package/docs/sui-product-card/README.md +89 -21
  85. package/docs/sui-progress-bar/README.md +82 -15
  86. package/docs/sui-progress-bar-label/README.md +79 -18
  87. package/docs/sui-radio/README.md +84 -7
  88. package/docs/sui-radio-card/README.md +70 -16
  89. package/docs/sui-radio-label/README.md +89 -22
  90. package/docs/sui-rating/README.md +101 -31
  91. package/docs/sui-rich-editor/README.md +47 -2
  92. package/docs/sui-segmented-control/README.md +90 -21
  93. package/docs/sui-select/README.md +80 -11
  94. package/docs/sui-sidebar/README.md +71 -16
  95. package/docs/sui-slider/README.md +75 -8
  96. package/docs/sui-social-button/README.md +71 -11
  97. package/docs/sui-status-badge/README.md +75 -14
  98. package/docs/sui-stepper/README.md +75 -18
  99. package/docs/sui-store-card/README.md +85 -22
  100. package/docs/sui-switch/README.md +82 -11
  101. package/docs/sui-switch-card/README.md +80 -16
  102. package/docs/sui-switch-label/README.md +91 -14
  103. package/docs/sui-tab-chips/README.md +93 -21
  104. package/docs/sui-tab-menu-horizontal/README.md +68 -7
  105. package/docs/sui-tab-menu-vertical/README.md +64 -11
  106. package/docs/sui-table/README.md +77 -16
  107. package/docs/sui-tag/README.md +86 -12
  108. package/docs/sui-tag-input/README.md +77 -13
  109. package/docs/sui-textarea/README.md +84 -17
  110. package/docs/sui-time-picker/README.md +96 -33
  111. package/docs/sui-toast/README.md +81 -20
  112. package/docs/sui-tooltip/README.md +80 -22
  113. package/docs/sui-topbar/README.md +64 -10
  114. package/docs/sui-topbar-button/README.md +61 -7
  115. package/docs/sui-topbar-item/README.md +68 -7
  116. package/docs/sui-topbar-user/README.md +61 -5
  117. package/fesm2022/ajuarezso-sui-design-system.mjs +15 -10
  118. package/fesm2022/ajuarezso-sui-design-system.mjs.map +1 -1
  119. package/package.json +1 -1
  120. package/types/ajuarezso-sui-design-system.d.ts +7 -3
@@ -38,7 +38,7 @@ es en desktop** (`size`) y **qué cabecera lleva** (`iconVariant` / `headerIcon`
38
38
  > trae el header (nodo 466:4778, tipos Basic / Left Icon / Error / Warning / Success / Info en
39
39
  > tamaños Small 56 y Medium 80), el footer (472:566), los Status Modals (480:1372) y el overlay
40
40
  > (480:2474). No trae do/don't. Lo marcado **canon** sale de `master-pedidos/CLAUDE.md` y
41
- > `docs/CANON-SUI.md`; lo marcado **propuesta** falta aprobar.
41
+ > `docs/CANON-SUI.md` o de la aprobación del dueño del 05-10-2026; lo marcado **propuesta** falta aprobar.
42
42
  >
43
43
  > Uso medido el 03-10-2026 en `master-pedidos/src/app`: 128 modales, sin contar prototipos ni
44
44
  > vitrinas (`master-preview`, `master-prototipos`, `mockup-sheets-*`, `dx/*`, `master-rutina`,
@@ -93,10 +93,10 @@ pantalla entera (fullscreen). Elegirlo es una decisión de desktop.
93
93
 
94
94
  | size | cuándo | ejemplo real de la app | fuente |
95
95
  |---|---|---|---|
96
- | `small` (400) | confirmación o aviso: título, una o dos frases y los botones | `pages/customer/order-tracking/order-tracking.html:756` | propuesta |
97
- | `medium` (440, default) | formulario corto (hasta ~5 campos) o un detalle simple | `pages/discounts/discounts.html:122` («Crear descuento») | propuesta |
98
- | `large` (560) | detalle con tabla o imagen: comprobantes, el detalle de un pedido | `pages/orders/orders.html:146` · `pages/super-admin/master-drivers/master-drivers.html:685` | propuesta |
99
- | `xlarge` (720) | mapa, formularios de dos columnas, listas largas de opciones | `components/address-picker-modal/address-picker-modal.html:1` · `pages/customer/checkout/checkout.html:1` | propuesta |
96
+ | `small` (400) | confirmación o aviso: título, una o dos frases y los botones | `pages/customer/order-tracking/order-tracking.html:756` | canon (aprobado por el dueño, 05-10-2026, bloque B1) |
97
+ | `medium` (440, default) | formulario corto (hasta ~5 campos) o un detalle simple | `pages/discounts/discounts.html:122` («Crear descuento») | canon (aprobado por el dueño, 05-10-2026, bloque B1) |
98
+ | `large` (560) | detalle con tabla o imagen: comprobantes, el detalle de un pedido | `pages/orders/orders.html:146` · `pages/super-admin/master-drivers/master-drivers.html:685` | canon (aprobado por el dueño, 05-10-2026, bloque B1) |
99
+ | `xlarge` (720) | mapa, formularios de dos columnas, listas largas de opciones | `components/address-picker-modal/address-picker-modal.html:1` · `pages/customer/checkout/checkout.html:1` | canon (aprobado por el dueño, 05-10-2026, bloque B1) |
100
100
 
101
101
  Hoy: 45 `small`, 63 `medium` (50 explícitos + 13 por default), 5 `large`, 14 `xlarge` y 1 que cambia según el caso.
102
102
 
@@ -104,22 +104,22 @@ Hoy: 45 `small`, 63 `medium` (50 explícitos + 13 por default), 5 `large`, 14 `x
104
104
 
105
105
  | input | qué dibuja | cuándo | fuente |
106
106
  |---|---|---|---|
107
- | ninguno (Basic) | solo título (+ descripción) y la X | el caso normal: un formulario o un detalle | propuesta |
108
- | `iconVariant` | círculo de color con el ícono del estado (`info`, `success`, `warning`, `error`) | el modal **es** un aviso de ese tipo: «Eliminar usuario» (`error`), «Estás a punto de cambiar de local» (`warning`) | propuesta |
109
- | `headerIcon` | círculo gris con un ícono propio (Remix) | identifica **qué se está editando**: `edit-line`, `user-add-line`, `time-line`. Gana sobre `iconVariant` | propuesta |
107
+ | ninguno (Basic) | solo título (+ descripción) y la X | el caso normal: un formulario o un detalle | canon (aprobado por el dueño, 05-10-2026, bloque B2) |
108
+ | `iconVariant` | círculo de color con el ícono del estado (`info`, `success`, `warning`, `error`) | el modal **es** un aviso de ese tipo: «Eliminar usuario» (`error`), «Estás a punto de cambiar de local» (`warning`) | canon (aprobado por el dueño, 05-10-2026, bloque B2) |
109
+ | `headerIcon` | círculo gris con un ícono propio (Remix) | identifica **qué se está editando**: `edit-line`, `user-add-line`, `time-line`. Gana sobre `iconVariant` | canon (aprobado por el dueño, 05-10-2026, bloque B2) |
110
110
  | `statusAlignment` | quita el header y pone ícono + texto dentro del body (`vertical` centrado, `horizontal` en fila) | pantallas de resultado («Pedido enviado») o confirmaciones con más peso visual. Requiere `iconVariant` o `headerIcon`. 0 usos hoy | según el Figma del DS (Status Modals) |
111
111
 
112
112
  **Usos de hoy que rompen el copy canon** (CANON-SUI: títulos en sentence case):
113
- `pages/super-admin/super-admin.html:353` «Suspender Negocio», `:471` «Evidencia de Pago»,
114
- `:487` «Rechazar Solicitud», `:557` «Rechazar Promoción».
113
+ `pages/super-admin/super-admin.html:364` «Suspender Negocio», `:484` «Evidencia de Pago»,
114
+ `:501` «Rechazar Solicitud», `:572` «Rechazar Promoción» (líneas al 06-10-2026).
115
115
 
116
116
  ### Cerrar
117
117
 
118
118
  | input | default | cuándo cambiarlo | fuente |
119
119
  |---|---|---|---|
120
- | `closeOnBackdrop` | `true` | `false` si el modal tiene un formulario a medio llenar o una operación en curso (`[closeOnBackdrop]="!guardando()"`): un toque fuera no debe tirar lo escrito. Hoy 42 en `false` y 5 dinámicos | propuesta |
121
- | `showClose` | `true` | `false` solo cuando la persona **tiene** que elegir un botón (actualización obligatoria, oferta de pedido al repartidor). Hoy 8 | propuesta |
122
- | `closeOnEscape` | `true` | casi nunca: es la salida por teclado en desktop | propuesta |
120
+ | `closeOnBackdrop` | `true` | `false` si el modal tiene un formulario a medio llenar o una operación en curso (`[closeOnBackdrop]="!guardando()"`): un toque fuera no debe tirar lo escrito. Hoy 42 en `false` y 5 dinámicos | canon (aprobado por el dueño, 05-10-2026, bloque B8) |
121
+ | `showClose` | `true` | `false` solo cuando la persona **tiene** que elegir un botón (actualización obligatoria, oferta de pedido al repartidor). Hoy 8 | canon (aprobado por el dueño, 05-10-2026, bloque B8) |
122
+ | `closeOnEscape` | `true` | `false` solo junto con `showClose` `false`, o mientras corre una operación; el resto, `true`: es la salida por teclado en desktop | canon (aprobado por el dueño, 05-10-2026, bloque B13) |
123
123
 
124
124
  ### `fullBody` — contenido a sangre
125
125
 
@@ -140,6 +140,17 @@ interno lo pone quien proyecta. Canon (CLAUDE.md, 2026-07-21).
140
140
 
141
141
  El modal **no tiene un size para mobile**: la decisión de mobile es `fullscreen`.
142
142
 
143
+ ### Por dispositivo (D16)
144
+
145
+ No aplica: `size` es el **ancho del modal centrado** y lo elige el contenido (tabla de arriba), no
146
+ el dispositivo; a 768 px o menos ni se usa, porque el modal toma el ancho completo (centrado o
147
+ fullscreen). En la tablet de 820 o 1024 px el modal se ve centrado con su `size`, igual que en la
148
+ computadora y el ultrawide. Lo que se toca adentro lleva su propio D16: el pie va `large` en todos
149
+ los dispositivos (D2) y los campos del body siguen la fila de `input`.
150
+
151
+ En master-pedidos: sin helper para el modal; `<sui-modal-footer>` sin `buttonSize` (ya es
152
+ `large`) y los campos del body con `[size]="bp.sizeControl()"`.
153
+
143
154
  ## API
144
155
 
145
156
  <!-- api:inicio -->
@@ -201,6 +212,54 @@ pinta una sombra sobre el footer).
201
212
  - `(closed)` se emite **después** de cerrar, por cualquier vía (X, backdrop, Escape o
202
213
  `open = false`). Para limpiar estado, escúchalo ahí y no en el botón.
203
214
 
215
+ ## Bien y mal
216
+
217
+ Confirmación de sí o no
218
+
219
+ ```html
220
+ <!-- ❌ mal: sin [fullscreen]="false", el 'auto' lo abre a pantalla completa en la app (components/confirm-dialog/confirm-dialog.html:1) -->
221
+ <sui-modal [(open)]="open" size="small"
222
+ [title]="title()" [description]="description()" [closeOnBackdrop]="false">
223
+ <sui-modal-footer slot="footer" secondaryButton="Cancelar" primaryButton="Confirmar" />
224
+ </sui-modal>
225
+ ```
226
+
227
+ ```html
228
+ <!-- ✅ bien -->
229
+ <sui-modal [(open)]="open" size="small" [fullscreen]="false"
230
+ [title]="title()" [description]="description()" [closeOnBackdrop]="false">
231
+ <sui-modal-footer slot="footer" secondaryButton="Cancelar" primaryButton="Confirmar" />
232
+ </sui-modal>
233
+ ```
234
+
235
+ Pie con los botones
236
+
237
+ ```html
238
+ <!-- ❌ mal: sin slot="footer" el pie cae dentro del body: doble padding y scrollea con el contenido -->
239
+ <sui-modal [(open)]="creando" title="Crear descuento">
240
+ <sui-modal-footer secondaryButton="Cancelar" primaryButton="Crear descuento" />
241
+ </sui-modal>
242
+ ```
243
+
244
+ ```html
245
+ <!-- ✅ bien -->
246
+ <sui-modal [(open)]="creando" title="Crear descuento">
247
+ <sui-modal-footer slot="footer" secondaryButton="Cancelar" primaryButton="Crear descuento" />
248
+ </sui-modal>
249
+ ```
250
+
251
+ Título del modal
252
+
253
+ ```html
254
+ <!-- ❌ mal: título en Title Case; el canon es sentence case (pages/super-admin/super-admin.html:364) -->
255
+ <sui-modal [(open)]="suspendiendo" iconVariant="error" title="Suspender Negocio" />
256
+ ```
257
+
258
+ ```html
259
+ <!-- ✅ bien -->
260
+ <sui-modal [(open)]="suspendiendo" iconVariant="error" title="Suspender negocio" />
261
+ ```
262
+
204
263
  ## Ejemplo
205
264
 
206
265
  ```html
@@ -49,8 +49,8 @@ peso de los botones** de toda la app: no solo de los modales.
49
49
  | acciones | cómo | ejemplo real de la app | fuente |
50
50
  |---|---|---|---|
51
51
  | **1** | solo `primaryButton`. Queda a la derecha, no a todo el ancho (para eso, `[stretch]="true"`) | `pages/super-admin/master-sonidos-push/master-sonidos-push.html:146` («Cerrar») | canon (CLAUDE.md) |
52
- | **2** | `secondaryButton` + `primaryButton`. El componente los pone en orden: secundario a la izquierda | `pages/driver/driver-dashboard/driver-dashboard.html:1574` («Cancelar» / «Enviar») | canon (CLAUDE.md) |
53
- | **3+** | **no hay tercer botón.** La tercera acción va como `sui-link-button` en el slot izquierdo | `components/add-product-modal/add-product-modal.html:332` («Vista previa») | canon (CLAUDE.md) |
52
+ | **2** | `secondaryButton` + `primaryButton`. El componente los pone en orden: secundario a la izquierda | `pages/driver/driver-dashboard/driver-dashboard.html:1691` («Cancelar» / «Enviar») | canon (CLAUDE.md) |
53
+ | **3+** | **no hay tercer botón.** La tercera acción va como `sui-link-button` en el slot izquierdo | `components/add-product-modal/add-product-modal.html:334` («Vista previa») | canon (CLAUDE.md) |
54
54
 
55
55
  ### El slot izquierdo
56
56
 
@@ -58,7 +58,7 @@ peso de los botones** de toda la app: no solo de los modales.
58
58
  |---|---|---|---|
59
59
  | `sui-link-button` | la tercera acción, de menos peso | `pages/central/central-gastos/central-gastos.html:97` | canon (CLAUDE.md) |
60
60
  | `sui-checkbox-label` / `sui-switch-label` | una opción que acompaña la confirmación («No volver a preguntar») | (sin uso hoy) | según el Figma del DS |
61
- | texto | un dato que se lee antes de confirmar («Llega a las 8:30») | `components/add-product-modal/add-product-modal.html:359` | según el Figma del DS |
61
+ | texto | un dato que se lee antes de confirmar («Llega a las 8:30») | `components/add-product-modal/add-product-modal.html:361` | según el Figma del DS |
62
62
  | `sui-counter-input` (stepper) | elegir cantidad junto al botón de agregar | `pages/customer/restaurant-menu/restaurant-menu.html:461` | según el Figma del DS |
63
63
 
64
64
  Con `stretch` y algo en el slot izquierdo, se reparte 50 % slot / 50 % botones.
@@ -79,17 +79,19 @@ Con `stretch` y algo en el slot izquierdo, se reparte 50 % slot / 50 % botones.
79
79
  | `false` (default) | modal centrado en desktop: botones a la derecha, del ancho de su texto | según el Figma del DS (tipo Basic) |
80
80
 
81
81
  El componente **no tiene `@media`**: `stretch` se ve igual en las dos plataformas. Hoy 95 de 121
82
- lo pasan fijo en `true`, así que también en desktop los botones van 50/50. Propuesta:
83
- `[stretch]="bp.isMobile()"` para que desktop vuelva al tipo Basic.
82
+ lo pasan fijo en `true`, así que también en desktop los botones van 50/50. Propuesta, falta
83
+ aprobación: `[stretch]="bp.isMobile()"` para que desktop vuelva al tipo Basic.
84
84
 
85
85
  **Usos de hoy que rompen el canon:**
86
86
 
87
- - **3 footers con un solo botón en `secondaryButton`** → pasarlo a `primaryButton`:
88
- `pages/driver/driver-dashboard/driver-dashboard.html:1272`, `:1419` y `:1555` (los tres
89
- «Cerrar»). Contraargumento a decidir: en un modal que solo informa, un «Cerrar» relleno de
87
+ - **4 footers con un solo botón en `secondaryButton`** → pasarlo a `primaryButton`:
88
+ `pages/driver/driver-dashboard/driver-dashboard.html:1390`, `:1537` y `:1673` (los tres
89
+ «Cerrar»), y `pages/central/central-gastos/central-gastos.html:97` cuando el gasto está
90
+ anulado (el primario pasa a `null` y queda solo «Cerrar»). Contraargumento a decidir: en un modal que solo informa, un «Cerrar» relleno de
90
91
  naranja grita más que el contenido; si se prefiere así, hay que escribirlo como excepción.
91
92
  - **1 pie hecho a mano** con dos `sui-button` en un `<div slot="footer">` →
92
- `sui-modal-footer`: `components/copy-text-dialog/copy-text-dialog.html:15`.
93
+ `sui-modal-footer`: `components/copy-text-dialog/copy-text-dialog.html:16`. Al migrarlo se
94
+ pierde el ícono del botón «Copiar» (`file-copy-line` → `check-line`): ver «Bien y mal».
93
95
  - Botones `sui-button` proyectados dentro del footer: 0.
94
96
 
95
97
  ## Tamaño en mobile y en web
@@ -97,13 +99,30 @@ lo pasan fijo en `true`, así que también en desktop los botones van 50/50. Pro
97
99
  | uso | mobile | web | fuente |
98
100
  |---|---|---|---|
99
101
  | botones | `large` (48) | `large` (48) | canon (CLAUDE.md, decisión de marca 2026-07-23; el Figma dibuja `small`) |
100
- | reparto | `[stretch]="true"`, 50/50 | botones a la derecha | canon en mobile (CANON-SUI §6.3), propuesta en web |
102
+ | reparto | `[stretch]="true"`, 50/50 | botones a la derecha | canon en mobile (CANON-SUI §6.3), propuesta en web (falta aprobación) |
101
103
  | borde de arriba | sin borde en el modal a pantalla completa | con borde | componente (`sui-modal.scss`) |
102
104
 
103
105
  `buttonSize` existe para un caso puntual, no para «achicar porque se ve grande». Hoy 0 usos.
104
106
 
105
- `CANON-SUI.md` §6.3 todavía dice «botones `small`»: quedó viejo frente a la decisión del
106
- 2026-07-23 y al default del componente.
107
+ `CANON-SUI.md` §6.3 ya dice lo mismo: footer de modal con botones `large` (48), por encima del
108
+ Figma que dibuja `small`.
109
+
110
+ ### Por dispositivo (D16)
111
+
112
+ D16 lo nombra en la fila de `button`: **footer de modal, `large` siempre** (D2). No baja a
113
+ `medium` en la computadora como los botones sueltos.
114
+
115
+ | dispositivo | size | nota |
116
+ |---|---|---|
117
+ | celular chico (< 380) | `large` | ya llega a 48, no necesita el área de 44 aparte |
118
+ | celular (380–767) | `large` | |
119
+ | tablet táctil | `large` | |
120
+ | computadora | `large` | D2 manda sobre la regla de `medium` en la computadora |
121
+
122
+ Ultrawide: igual, `large`. Fuente: D16, dueño 05-10-2026 (fila `button`) y D2.
123
+
124
+ En master-pedidos: no se pasa `buttonSize`; `null` ya resuelve a `large`. Nunca
125
+ `[buttonSize]="bp.sizeControl()"`: en la computadora bajaría a `medium`.
107
126
 
108
127
  ## API
109
128
 
@@ -154,6 +173,61 @@ Slot: `<ng-content>` sin selector → el bloque **izquierdo**.
154
173
  - Dentro de `sui-modal` el footer recibe una sombra arriba mientras el body tiene más contenido
155
174
  para scrollear (`scrollActive`).
156
175
 
176
+ ## Bien y mal
177
+
178
+ Un modal que solo informa
179
+
180
+ ```html
181
+ <!-- ❌ mal: la única acción va en el secundario (pages/driver/driver-dashboard/driver-dashboard.html:1390) -->
182
+ <sui-modal-footer slot="footer" secondaryButton="Cerrar"
183
+ (secondaryClick)="modalTope.set(false)" />
184
+ ```
185
+
186
+ ```html
187
+ <!-- ✅ bien -->
188
+ <sui-modal-footer slot="footer" primaryButton="Cerrar"
189
+ (primaryClick)="modalTope.set(false)" />
190
+ ```
191
+
192
+ Copiar un texto y cerrar
193
+
194
+ ```html
195
+ <!-- ❌ mal: pie hecho a mano con dos sui-button (components/copy-text-dialog/copy-text-dialog.html:16) -->
196
+ <div slot="footer">
197
+ <sui-button variant="stroke" color="neutral" size="large" (click)="close()">{{ closeLabel() }}</sui-button>
198
+ <sui-button variant="filled" color="primary" size="large" (click)="onCopy()">
199
+ <sui-icon data-slot="start" [name]="copied() ? 'check-line' : 'file-copy-line'" [size]="16" />
200
+ {{ copied() ? copiedLabel() : copyLabel() }}
201
+ </sui-button>
202
+ </div>
203
+ ```
204
+
205
+ ```html
206
+ <!-- ✅ bien: el label sigue al estado copiado -->
207
+ <sui-modal-footer slot="footer" [secondaryButton]="closeLabel()"
208
+ [primaryButton]="copied() ? copiedLabel() : copyLabel()"
209
+ (secondaryClick)="close()" (primaryClick)="onCopy()" />
210
+ ```
211
+
212
+ Lo que se pierde: el ícono. `SuiFooterButtonConfig` solo acepta `label`, `disabled` y `color`, así
213
+ que el footer no dibuja el `sui-icon` que hoy pasa de `file-copy-line` a `check-line`. El aviso de
214
+ «copiado» sigue llegando por el label («Copiar» → «Copiado»). Conservar el ícono pide un `icon` en
215
+ `SuiFooterButtonConfig`, que hoy no existe (**propuesta**, sin decidir); no es razón para volver al
216
+ pie a mano.
217
+
218
+ Botones del footer en la computadora
219
+
220
+ ```html
221
+ <!-- ❌ mal: D16 deja el footer en large siempre (D2); esto lo baja a medium en la computadora -->
222
+ <sui-modal-footer slot="footer" secondaryButton="Cancelar" primaryButton="Guardar"
223
+ [buttonSize]="bp.sizeControl()" />
224
+ ```
225
+
226
+ ```html
227
+ <!-- ✅ bien: sin buttonSize, resuelve a large -->
228
+ <sui-modal-footer slot="footer" secondaryButton="Cancelar" primaryButton="Guardar" />
229
+ ```
230
+
157
231
  ## Ejemplo
158
232
 
159
233
  ```html
@@ -51,7 +51,7 @@ componente **no la aplica solo**: si lo usas suelto, elige tú.
51
51
  |---|---|---|---|
52
52
  | ninguno | Basic: solo texto | el caso normal | según el Figma del DS |
53
53
  | `iconVariant` | ícono del estado en un círculo de su color | el panel **es** un aviso de error, advertencia, éxito o información | propuesta |
54
- | `icon` | ícono propio (Remix) en un círculo gris | identifica qué se edita (`edit-line`, `user-add-line`). Gana sobre `iconVariant` | propuesta |
54
+ | `icon` | ícono propio (Remix) en un círculo gris | identifica qué se edita (`edit-line`, `user-add-line`). Gana sobre `iconVariant` | canon (aprobado por el dueño, 05-10-2026, bloque B2) |
55
55
 
56
56
  ## Tamaño en mobile y en web
57
57
 
@@ -63,6 +63,17 @@ mobile y en web. La X mide 24 px en las dos (`sui-compact-button` `large`).
63
63
  | con descripción | `medium` | `medium` | según el Figma del DS |
64
64
  | solo título | `small` | `small` | según el Figma del DS |
65
65
 
66
+ ### Por dispositivo (D16)
67
+
68
+ No aplica: el `size` lo decide si hay `description` (56 solo título, 80 con descripción), no el
69
+ dispositivo, y D16 deja fuera este `small` porque cambia el layout y no la escala. Es igual en el
70
+ celular chico, el celular, la tablet, la computadora y el ultrawide. La X es un
71
+ `sui-compact-button` interno de 24 a la vista; su área de 44 se prende solo bajo 768 px
72
+ (`sui-modal-header.scss:119`), así que en la tablet táctil todavía no la tiene: eso espera el
73
+ mixin `sui-tactil` de la propuesta de D16, **pendiente** del sí del dueño.
74
+
75
+ En master-pedidos: `[size]="description ? 'medium' : 'small'"`, nunca una señal de `bp`.
76
+
66
77
  ## API
67
78
 
68
79
  <!-- api:inicio -->
@@ -98,6 +109,51 @@ mobile y en web. La X mide 24 px en las dos (`sui-compact-button` `large`).
98
109
  en `aria-labelledby`.
99
110
  - El host borra el atributo `title` nativo (sin tooltip gris del navegador).
100
111
 
112
+ ## Bien y mal
113
+
114
+ La cabecera de un modal
115
+
116
+ ```html
117
+ <!-- ❌ mal: sui-modal ya dibuja su header; quedan dos cabeceras -->
118
+ <sui-modal [(open)]="abierto" [fullscreen]="true">
119
+ <sui-modal-header title="Editar producto" icon="edit-line" (closed)="abierto.set(false)" />
120
+ </sui-modal>
121
+ ```
122
+
123
+ ```html
124
+ <!-- ✅ bien -->
125
+ <sui-modal [(open)]="abierto" [fullscreen]="true" title="Editar producto" headerIcon="edit-line">
126
+ </sui-modal>
127
+ ```
128
+
129
+ Cabecera con descripción
130
+
131
+ ```html
132
+ <!-- ❌ mal: con description va medium; en small el ícono pasa a plano de 24 -->
133
+ <sui-modal-header size="small" title="Filtros" description="Elige qué pedidos ver" icon="filter-line" />
134
+ ```
135
+
136
+ ```html
137
+ <!-- ✅ bien -->
138
+ <sui-modal-header size="medium" title="Filtros" description="Elige qué pedidos ver" icon="filter-line" />
139
+ ```
140
+
141
+ Un panel propio que hace de diálogo
142
+
143
+ ```html
144
+ <!-- ❌ mal: sin titleId el diálogo no tiene nombre accesible -->
145
+ <section class="panel" role="dialog">
146
+ <sui-modal-header size="small" title="Filtros" (closed)="cerrarPanel()" />
147
+ </section>
148
+ ```
149
+
150
+ ```html
151
+ <!-- ✅ bien -->
152
+ <section class="panel" role="dialog" aria-labelledby="filtros-titulo">
153
+ <sui-modal-header size="small" title="Filtros" titleId="filtros-titulo" (closed)="cerrarPanel()" />
154
+ </section>
155
+ ```
156
+
101
157
  ## Ejemplo
102
158
 
103
159
  ```html
@@ -29,7 +29,7 @@ Story: [Organisms/Modal/Modal Sheet](https://sui-design-system.web.app/?path=/do
29
29
 
30
30
  > **No está en la guía del DS: es extensión de SUI**, inspirada en el `ion-modal` en modo sheet
31
31
  > de Ionic y en las hojas de Apple Maps. No hay Figma que la legisle. Lo marcado **canon** sale
32
- > de `master-pedidos/CLAUDE.md`; lo demás es **propuesta** sacada del uso real.
32
+ > de `master-pedidos/CLAUDE.md` o de la aprobación del dueño (05-10-2026); lo demás es **propuesta** sacada del uso real.
33
33
  >
34
34
  > Uso medido el 03-10-2026 en `master-pedidos/src/app`: 13 sheets, sin contar prototipos ni
35
35
  > vitrinas (`master-preview`, `master-prototipos`, `mockup-sheets-*`, `dx/*`, `master-rutina`,
@@ -47,12 +47,13 @@ conviene copiar una de las dos en vez de inventar otra.
47
47
 
48
48
  | patrón | `breakpoints` | `initialBreakpoint` | `backdropBreakpoint` | cuándo | ejemplo real de la app | fuente |
49
49
  |---|---|---|---|---|---|---|
50
- | **Sobre un mapa** | `[0.25, 0.5, 0.7, 1]` (sin `0`) | `0.5` | `1` | el seguimiento: el mapa se usa a cualquier altura y la hoja no se puede cerrar | `pages/customer/order-tracking/order-tracking.html:130` · `pages/driver/driver-order-detail/driver-order-detail.html:60` | propuesta |
51
- | **Hoja de lectura** | `[0, 0.92]` | `0.92` | `0` | una lista o detalle que se abre y se cierra deslizando, con el fondo apagado | `pages/customer/order-tracking/order-tracking.html:809` (reseñas) · `pages/customer/checkout/checkout.html:448` (hora) | propuesta |
50
+ | **Sobre un mapa** | `[0.25, 0.5, 0.7, 1]` (sin `0`) | `0.5` | `1` | el seguimiento: el mapa se usa a cualquier altura y la hoja no se puede cerrar | `pages/customer/order-tracking/order-tracking.html:139` · `pages/driver/driver-order-detail/driver-order-detail.html:60` | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
51
+ | **Hoja de lectura** | `[0, 0.92]` | `0.92` | `0` | una lista o detalle que se abre y se cierra deslizando, con el fondo apagado | `pages/customer/order-tracking/order-tracking.html:836` (reseñas) · `pages/customer/checkout/checkout.html:449` (hora, con tope `0.96`) | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
52
52
 
53
- Hoy: 4 «sobre un mapa» (más 2 variantes con alturas propias: `pages/envios/envios.html:578` y
54
- `pages/customer/viaje/viaje.html:24`), 5 hojas de lectura en `0.92`–`0.96`, 2 en `[0, 1]` y 1 en
55
- `[0, 0.6, 0.95]`.
53
+ Hoy: 3 «sobre un mapa» (`order-tracking.html:139`, `driver-order-detail.html:60` y
54
+ `pages/super-admin/master-map-overview/master-map-overview.html:35`), más 2 variantes con alturas
55
+ propias (`pages/envios/envios.html:584` y `pages/customer/viaje/viaje.html:30`), 5 hojas de
56
+ lectura en `0.92`–`0.96`, 2 en `[0, 1]` y 1 en `[0, 0.6, 0.95]`. Suman los 13.
56
57
 
57
58
  | input | regla | fuente |
58
59
  |---|---|---|
@@ -60,14 +61,15 @@ Hoy: 4 «sobre un mapa» (más 2 variantes con alturas propias: `pages/envios/en
60
61
  | `initialBreakpoint` | Tiene que estar en `breakpoints`. | componente |
61
62
  | `backdropBreakpoint` | `0` = fondo apagado desde que abre. `1` = **nunca hay backdrop**: el mapa de atrás se toca siempre. | componente |
62
63
  | tope en las hojas de lectura | `0.92`, no `1`: deja ver arriba un borde de la pantalla de atrás, que es lo que dice «esto es una hoja». | propuesta |
63
- | `showHandle` | Déjalo en `true` siempre que la hoja se arrastre. Hoy nadie lo apaga. | propuesta |
64
+ | `showHandle` | Déjalo en `true` siempre que la hoja se arrastre. Hoy nadie lo apaga. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
64
65
  | `fullBody` | Solo para contenido a sangre (una foto, un mapa dentro de la hoja). | canon (CLAUDE.md, 2026-07-21) |
65
66
 
66
67
  **Usos de hoy a revisar:**
67
68
 
68
- - `pages/customer/viaje/viaje.html:24` reabre la hoja en `(closed)` (`hojaAbierta.set(true)`)
69
+ - `pages/customer/viaje/viaje.html:36` reabre la hoja en `(closed)` (`hojaAbierta.set(true)`)
69
70
  para que no se pueda cerrar. Sin `0` en `breakpoints` y con `[closeOnBackdrop]="false"` ya no se
70
- cierra; el reabrir sobra o tapa otro caso.
71
+ cierra con el dedo ni con el fondo; el caso que tapa es Escape (`closeOnEscape` sigue en `true`).
72
+ Con `[closeOnEscape]="false"` el reabrir sobra.
71
73
  - 2 footers de modal metidos en hojas: van sin `slot` (no hay slot de footer). Está bien, pero el
72
74
  botón scrollea con el contenido: `pages/customer/checkout/checkout.html:490`,
73
75
  `pages/super-admin/master-sonidos-push/master-sonidos-push.html:146`.
@@ -86,11 +88,22 @@ El sheet **no tiene `size`**. Mide lo que mide su contenido, con tope en el brea
86
88
 
87
89
  **El sheet no se acota en desktop.** La app lo arregla con CSS propio, cinco reglas en cuatro archivos:
88
90
  `components/store-ratings-modal/store-ratings-modal.scss:81`,
89
- `pages/driver/movimientos/movimientos-sheet.scss:24`,
90
- `pages/driver/driver-order-detail/driver-order-detail.scss:1028` y
91
- `pages/customer/order-tracking/order-tracking.scss:1175` y `:1238`, todos a 560 px. Propuesta:
91
+ `components/movimientos-saldo/movimientos-saldo-sheet.scss:25`,
92
+ `pages/driver/driver-order-detail/driver-order-detail.scss:1096` (las tres a 560 px) y
93
+ `pages/customer/order-tracking/order-tracking.scss:1175` y `:1238` (a 480 px). Propuesta:
92
94
  que el DS traiga ese tope (`max-width` desde 768 px, centrado) y se borren esos parches.
93
95
 
96
+ ### Por dispositivo (D16)
97
+
98
+ No aplica: el sheet **no tiene `size`**; mide lo que mide su contenido y se configura con alturas
99
+ (`breakpoints`), no con un tamaño. Es igual en el celular chico, el celular, la tablet táctil, la
100
+ computadora y el ultrawide. El tamaño de lo que va adentro (botones, campos) sigue su propia
101
+ fila de D16. Lo único que cambia por dispositivo es el ancho desde 768 px, y eso es P21
102
+ (**pendiente**: acotarlo a 560 en el DS o dejar los parches) y no se decide aquí.
103
+
104
+ En master-pedidos: sin `[size]`; en desktop, cuando hay sitio, la pantalla puede mostrar el
105
+ contenido en un panel en vez de la hoja (`pages/customer/viaje/viaje.html:25`, con `@if (escritorio())`).
106
+
94
107
  ## API
95
108
 
96
109
  <!-- api:inicio -->
@@ -145,6 +158,55 @@ Slot: un solo `<ng-content>`, el body. No hay header ni footer.
145
158
  ejemplo para centrarlo en desktop) sin romper el arrastre.
146
159
  - Pide ocultar la barra inferior de la app por `SUI_NAVBAR_VISIBILITY`, igual que `sui-modal`.
147
160
 
161
+ ## Bien y mal
162
+
163
+ Una hoja que no se puede cerrar
164
+
165
+ ```html
166
+ <!-- ❌ mal: la reabre en (closed) para tapar el cierre (pages/customer/viaje/viaje.html:36) -->
167
+ <sui-modal-sheet [(open)]="hojaAbierta" [breakpoints]="[0.35, 0.6, 0.92]"
168
+ [backdropBreakpoint]="1" [closeOnBackdrop]="false"
169
+ (closed)="hojaAbierta.set(true)">
170
+ ```
171
+
172
+ ```html
173
+ <!-- ✅ bien: sin 0 en breakpoints y sin Escape, no hay cierre que tapar -->
174
+ <sui-modal-sheet [(open)]="hojaAbierta" [breakpoints]="[0.35, 0.6, 0.92]"
175
+ [backdropBreakpoint]="1" [closeOnBackdrop]="false" [closeOnEscape]="false">
176
+ ```
177
+
178
+ Un formulario que hay que terminar
179
+
180
+ ```html
181
+ <!-- ❌ mal: un deslizón cierra la hoja y se pierde lo escrito -->
182
+ <sui-modal-sheet [(open)]="editando" [breakpoints]="[0, 0.92]" [initialBreakpoint]="0.92">
183
+ <sui-input label="Nombre del local" [(value)]="nombre" />
184
+ </sui-modal-sheet>
185
+ ```
186
+
187
+ ```html
188
+ <!-- ✅ bien -->
189
+ <sui-modal [(open)]="editando" [fullscreen]="true" title="Editar local">
190
+ <sui-input label="Nombre del local" [(value)]="nombre" />
191
+ </sui-modal>
192
+ ```
193
+
194
+ El margen del contenido
195
+
196
+ ```html
197
+ <!-- ❌ mal: el body ya trae 0 20px 20px; con el padding propio queda doble (el tracking del repartidor) -->
198
+ <sui-modal-sheet [(open)]="abierta" [breakpoints]="[0, 0.92]" [initialBreakpoint]="0.92">
199
+ <section style="padding: 16px 16px 48px">…</section>
200
+ </sui-modal-sheet>
201
+ ```
202
+
203
+ ```html
204
+ <!-- ✅ bien: la sección a 0, el margen lo pone el sheet -->
205
+ <sui-modal-sheet [(open)]="abierta" [breakpoints]="[0, 0.92]" [initialBreakpoint]="0.92">
206
+ <section>…</section>
207
+ </sui-modal-sheet>
208
+ ```
209
+
148
210
  ## Ejemplo
149
211
 
150
212
  ```html
@@ -53,30 +53,30 @@ toast · bandeja → notification.**
53
53
  | `avatar` | `{ initials }` | Solo si no hay foto. Ojo: sale en un círculo negro, **no** con el color por rol (ver Trampas). | según el componente |
54
54
  | `avatar` | el isotipo de la app | Avisos **del sistema** sin una persona detrás («Tu plan vence en 3 días»): así toda la bandeja queda en filas iguales. | propuesta |
55
55
  | `title` | frase corta | Qué pasó: «Tu pedido llegó». Sentence case, sin punto final. | canon (copy de la app) |
56
- | `description` | una o dos frases | El detalle que decide si abrirla: «Pollería El Dorado · S/ 42.50». | propuesta |
57
- | `timestamp` | texto ya formateado | **Siempre**: la hora es lo que hace bandeja a la bandeja. «Hace 5 min», «Ayer 18:40». | canon (bandeja con hora) · formato: propuesta |
56
+ | `description` | una o dos frases | El detalle que decide si abrirla: «Pollería El Dorado · S/ 42.50». | canon (aprobado por el dueño, 05-10-2026, bloque B4) |
57
+ | `timestamp` | texto ya formateado | **Siempre**: la hora es lo que hace bandeja a la bandeja. «Hace 5 min», «Ayer 18:40». | canon (bandeja con hora) · formato relativo: canon (CANON-SUI §5.5, «hace 4 min», nunca «4 min atrás») · «Ayer 18:40»: propuesta |
58
58
  | `unread` | `true` | Hasta que la persona la abre. El punto es naranja (el primario de la app). | según el componente |
59
- | `showMore` | `true` | No usar hoy: el botón ⋮ solo aparece con el mouse encima. **Cuándo sí:** en web, acciones por fila (marcar como leída, archivar). | propuesta |
60
- | `active` | `true` | No usar hoy: pinta la fila como si tuviera el mouse encima. **Cuándo sí:** navegar la bandeja con las flechas del teclado (ver `sui-notification-footer`). | propuesta |
61
- | `dismissible` | `true` | No usar hoy: los avisos de la bandeja se leen, no se cierran. **Cuándo sí:** una bandeja donde se borran avisos uno por uno. | propuesta |
59
+ | `showMore` | `true` | No usar hoy: el botón ⋮ solo aparece con el mouse encima. **Cuándo sí:** en web, acciones por fila (marcar como leída, archivar). | canon (aprobado por el dueño, 05-10-2026, bloque B6) |
60
+ | `active` | `true` | No usar hoy: pinta la fila como si tuviera el mouse encima. **Cuándo sí:** navegar la bandeja con las flechas del teclado (ver `sui-notification-footer`). | canon (aprobado por el dueño, 05-10-2026, bloque B6) |
61
+ | `dismissible` | `true` | No usar hoy: los avisos de la bandeja se leen, no se cierran. **Cuándo sí:** una bandeja donde se borran avisos uno por uno. | canon (aprobado por el dueño, 05-10-2026, bloque B6) |
62
62
 
63
63
  ### `type` — el cuerpo de la fila
64
64
 
65
65
  | type | cuándo | fuente |
66
66
  |---|---|---|
67
67
  | `basic` (default) | Todas las de hoy: título, descripción y hora. | según el componente |
68
- | `button` | No usar hoy. **Cuándo sí:** una solicitud que se resuelve desde la misma bandeja, con «Rechazar» / «Aprobar» en `slot="actions"` (por ejemplo, una invitación a un equipo). Secundario a la izquierda, primario a la derecha. | propuesta · orden: canon |
69
- | `message` | No usar hoy. **Cuándo sí:** el aviso trae lo que escribió otra persona (la nota del cliente, un mensaje del repartidor), en la burbuja. | propuesta |
70
- | `file` | No usar hoy: la app no manda adjuntos. **Cuándo sí:** un comprobante o una boleta adjunta. | propuesta |
68
+ | `button` | No usar hoy. **Cuándo sí:** una solicitud que se resuelve desde la misma bandeja, con «Rechazar» / «Aprobar» en `slot="actions"` (por ejemplo, una invitación a un equipo). Secundario a la izquierda, primario a la derecha. | canon (aprobado por el dueño, 05-10-2026, bloque B2) · orden: canon |
69
+ | `message` | No usar hoy. **Cuándo sí:** el aviso trae lo que escribió otra persona (la nota del cliente, un mensaje del repartidor), en la burbuja. | canon (aprobado por el dueño, 05-10-2026, bloque B2) |
70
+ | `file` | No usar hoy: la app no manda adjuntos. **Cuándo sí:** un comprobante o una boleta adjunta. | canon (aprobado por el dueño, 05-10-2026, bloque B2) |
71
71
 
72
72
  ### `variant` y `variantStyle` — el modelo de alert
73
73
 
74
74
  | prop | valor | cuándo | fuente |
75
75
  |---|---|---|---|
76
76
  | `variant` | `default` (default) | **Siempre** en la bandeja: el tipo lo dice la foto y el texto, no un color. | propuesta |
77
- | `variant` | `info` · `success` · `warning` · `error` · `feature` | No usar: con tipo y sin foto, la fila se vuelve un alert con borde y sombra. **Cuándo sí:** ninguno; ese aviso es un `sui-alert`. | propuesta (sigue la regla canon) |
77
+ | `variant` | `info` · `success` · `warning` · `error` · `feature` | No usar: con tipo y sin foto, la fila se vuelve un alert con borde y sombra. **Cuándo sí:** ninguno; ese aviso es un `sui-alert`. | canon (aprobado por el dueño, 05-10-2026, bloque B6) |
78
78
  | `variantStyle` | `stroke` (default) | Siempre. Con foto, la fila es plana: sin borde ni sombra. | según el componente |
79
- | `variantStyle` | `filled` · `light` · `lighter` | No usar: pintan la fila de color, que es lo que hace el alert. **Cuándo sí:** ninguno. | propuesta |
79
+ | `variantStyle` | `filled` · `light` · `lighter` | No usar: pintan la fila de color, que es lo que hace el alert. **Cuándo sí:** ninguno. | canon (aprobado por el dueño, 05-10-2026, bloque B6) |
80
80
  | `showIcon` | `true` (default) | No cambia nada con foto; el ícono de tipo solo sale en el modelo de alert. | según el componente |
81
81
 
82
82
  ### Slots
@@ -103,7 +103,23 @@ La fila **no tiene `size`**: foto de 40 px, 12 px de relleno, texto de 14.
103
103
  | la fila | toda la fila se toca para abrirla: mide 64 px o más | igual | según el componente |
104
104
  | ⋮ (`showMore`) | se ve de 24 y se toca en 44 × 44 cuando está visible (foco o fila activa); oculto no recibe toques | 24 px | canon (dueño, 04-10-2026): piso táctil 44 en el teléfono |
105
105
  | la X (`dismissible`) | se ve de 20 px; **se toca en 44 × 44** | se ve de 20; se toca en 40 × 40 | canon (dueño, 04-10-2026): piso táctil 44 en el teléfono (antes 40, pedido del dueño 03-10-2026): área táctil invisible, extensión SUI |
106
- | botones de `type="button"` | los pone quien la usa: `[size]="bp.isMobile() ? 'large' : 'xsmall'"` | `xsmall` | propuesta |
106
+ | botones de `type="button"` | los pone quien la usa: `[size]="bp.sizeControl()"` (`large`, también en la tablet táctil) | `medium` | mobile `large`: canon (decisión del dueño 04-10-2026, piso táctil 44) · web `medium` y tablet táctil `large`: D16, dueño 05-10-2026 (reemplaza el `xsmall` del bloque B1 y el `bp.isMobile()`, que dejaba la tablet en `medium`) |
107
+
108
+ ### Por dispositivo (D16)
109
+
110
+ Fila `notification` (botones) de la tabla D16 (dueño, 05-10-2026). La fila no tiene `size`: lo que
111
+ cambia por dispositivo son los `sui-button` de `slot="actions"` (`type="button"`), que se tocan.
112
+
113
+ | dispositivo | size | nota |
114
+ |---|---|---|
115
+ | celular chico (< 380 px) | `large` (48) | D16 pide `medium` con área tocable de 44; mientras el DS no estire el área de los `medium`, va `large` (interino) |
116
+ | celular (380–767 px) | `large` (48) | la X y el ⋮ se tocan en 44 × 44 |
117
+ | tablet táctil (`pointer: coarse`) | `large` (48) | la X queda en 40 × 40 y el ⋮ en 24: su área de 44 se prende solo con `max-width: 767px`. **Pendiente**: el mixin `sui-tactil` (`pointer: coarse`) espera el sí del dueño |
118
+ | computadora (`pointer: fine`) | `medium` (40) | `small`, `xsmall` y `2xsmall` no se usan |
119
+
120
+ Ultrawide (≥ 1920 px): igual que la computadora, `medium`.
121
+
122
+ En master-pedidos: `[size]="bp.sizeControl()"` en los `sui-button` de `slot="actions"`.
107
123
 
108
124
  ## «No usar»: por qué no hoy y cuándo sí
109
125
 
@@ -169,6 +185,60 @@ Slots: `[slot=company-logo]`, `[slot=file]`, `[slot=message]`, el contenido libr
169
185
  después de la hora («Hace 8 min ∙»).
170
186
  - Borra el `title` nativo del host.
171
187
 
188
+ ## Bien y mal
189
+
190
+ Botones de una solicitud (`type="button"`)
191
+
192
+ ```html
193
+ <!-- ❌ mal: xsmall (32) no llega al dedo y D16 no usa chicos (vitrina: pages/super-admin/master-preview/_guia-moleculas/avisos.ts:242) -->
194
+ <sui-notification [avatar]="{ initials: 'MR' }" type="button" title="Miguel Rojas te invitó a su equipo">
195
+ <span slot="actions">
196
+ <sui-button variant="stroke" color="neutral" size="xsmall">Rechazar</sui-button>
197
+ <sui-button size="xsmall">Aprobar</sui-button>
198
+ </span>
199
+ </sui-notification>
200
+ ```
201
+
202
+ ```html
203
+ <!-- ✅ bien -->
204
+ <sui-notification [avatar]="{ initials: 'MR' }" type="button" title="Miguel Rojas te invitó a su equipo">
205
+ <span slot="actions">
206
+ <sui-button variant="stroke" color="neutral" [size]="bp.sizeControl()">Rechazar</sui-button>
207
+ <sui-button [size]="bp.sizeControl()">Aprobar</sui-button>
208
+ </span>
209
+ </sui-notification>
210
+ ```
211
+
212
+ Aviso del sistema en la bandeja
213
+
214
+ ```html
215
+ <!-- ❌ mal: con tipo y sin foto la fila se vuelve un alert con borde y sombra (vitrina: avisos.ts:253) -->
216
+ <sui-notification variant="success" title="Recarga aprobada"
217
+ description="Ya tienes S/ 20.00 en tu saldo" timestamp="Hace 1 h" />
218
+ ```
219
+
220
+ ```html
221
+ <!-- ✅ bien: el isotipo de la app como foto, sin variant -->
222
+ <sui-notification [avatar]="isotipo" title="Recarga aprobada"
223
+ description="Ya tienes S/ 20.00 en tu saldo" timestamp="Hace 1 h" />
224
+ ```
225
+
226
+ Acciones de la fila
227
+
228
+ ```html
229
+ <!-- ❌ mal: el ⋮ y la X van los dos arriba a la derecha y se pisan -->
230
+ <sui-notification [avatar]="n.foto" title="Nuevo pedido" timestamp="Hace 5 min"
231
+ description="Pollería El Dorado · S/ 42.50"
232
+ [showMore]="true" [dismissible]="true" />
233
+ ```
234
+
235
+ ```html
236
+ <!-- ✅ bien: uno solo (aquí, la X; el ⋮ es solo para web con mouse) -->
237
+ <sui-notification [avatar]="n.foto" title="Nuevo pedido" timestamp="Hace 5 min"
238
+ description="Pollería El Dorado · S/ 42.50"
239
+ [dismissible]="true" (dismissed)="quitar(n)" />
240
+ ```
241
+
172
242
  ## Ejemplo
173
243
 
174
244
  ```html