@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
@@ -37,7 +37,8 @@ toast · bandeja → notification.**
37
37
 
38
38
  > La guía del DS define el toast pero no dice cuándo va cada tipo. Lo marcado «según la guía del
39
39
  > DS» sale de su texto o de su código publicado; «canon» es lo ya aprobado (README de `sui-alert`,
40
- > `docs/CANON-SUI.md` o un pedido del dueño escrito en el código); el resto es **propuesta**.
40
+ > `docs/CANON-SUI.md`, un pedido del dueño escrito en el código o su aprobación del 05-10-2026); lo que
41
+ > quede en **propuesta** espera decisión.
41
42
  >
42
43
  > Uso medido el 04-10-2026 en `master-pedidos/src/app` (sin prototipos, vitrinas ni tests):
43
44
  > **705 llamadas en 108 archivos**, todas con el `SuiToastService` de la copia local. El desglose
@@ -58,11 +59,11 @@ toast · bandeja → notification.**
58
59
 
59
60
  | método | cuándo | ejemplo real de la app | fuente |
60
61
  |---|---|---|---|
61
- | `success()` | La acción salió como se esperaba. Dice **qué** quedó hecho. | `pages/sales-channels/instagram/instagram.ts:102` («Cambios guardados») | propuesta (sigue la regla canon del alert) |
62
+ | `success()` | La acción salió como se esperaba. Dice **qué** quedó hecho. | `pages/sales-channels/instagram/instagram.ts:102` («Cambios guardados») | canon (aprobado por el dueño, 05-10-2026, bloque B2; sigue la regla canon del alert) |
62
63
  | `error()` | La acción **no** salió. Dice qué no se pudo, nunca «Error al…» ni el mensaje técnico. | `pages/driver/driver-profile/driver-profile.ts:516` («No se pudo guardar el vehículo») | canon (copy: `docs/CANON-SUI.md` §5.7) |
63
- | `warning()` | Salió, **pero** con un pero que la persona tiene que saber. | `pages/super-admin/master-promos/master-promos.ts:171` («Push enviada, pero ningún cliente está dentro del radio») | propuesta |
64
- | `info()` | Algo que **llega** y no es el resultado de lo que hiciste: un push con la app abierta, una versión nueva. | `core/services/aviso-unico.service.ts:52` · `core/services/update.service.ts:59` | propuesta |
65
- | `feature()` | No usar hoy (0 usos). **Cuándo sí:** avisar una función nueva en el momento en que se activa («Ya puedes programar tus pedidos»). | — | propuesta |
64
+ | `warning()` | Salió, **pero** con un pero que la persona tiene que saber. | `pages/super-admin/master-promos/master-promos.ts:171` («Push enviada, pero ningún cliente está dentro del radio») | canon (aprobado por el dueño, 05-10-2026, bloque B2) |
65
+ | `info()` | Algo que **llega** y no es el resultado de lo que hiciste: un push con la app abierta, una versión nueva. | `core/services/aviso-unico.service.ts:52` · `core/services/update.service.ts:59` | canon (aprobado por el dueño, 05-10-2026, bloque B2) |
66
+ | `feature()` | No usar hoy (0 usos). **Cuándo sí:** avisar una función nueva en el momento en que se activa («Ya puedes programar tus pedidos»). | — | canon (aprobado por el dueño, 05-10-2026, bloque B6) |
66
67
  | `show({ variant })` | Lo mismo que los de arriba, cuando hace falta pasar todo junto. | `pages/empresa/about/about.ts:103` | según el componente |
67
68
 
68
69
  ### `style` — el relleno
@@ -70,25 +71,25 @@ toast · bandeja → notification.**
70
71
  | style | cuándo | fuente |
71
72
  |---|---|---|
72
73
  | `stroke-dark` (default SUI) | **Siempre.** Flota sobre cualquier pantalla y el oscuro contrasta con todas. | canon (README de `sui-alert`: «default del toast») |
73
- | `stroke` (default de la guía) | No usar hoy: blanco sobre blanco se confunde con el contenido. **Cuándo sí:** una pantalla de fondo oscuro (una landing), donde el oscuro se pierde. | propuesta |
74
- | `lighter` · `light` · `filled` | No usar hoy: un toast que pesa más que el oscuro compite con el botón principal, y si tiene que pesar más, no es un toast. **Cuándo sí:** ninguno previsto; ese caso es un alert o un modal. | propuesta |
74
+ | `stroke` (default de la guía) | No usar hoy: blanco sobre blanco se confunde con el contenido. **Cuándo sí:** una pantalla de fondo oscuro (una landing), donde el oscuro se pierde. | canon (aprobado por el dueño, 05-10-2026, bloque B6) |
75
+ | `lighter` · `light` · `filled` | No usar hoy: un toast que pesa más que el oscuro compite con el botón principal, y si tiene que pesar más, no es un toast. **Cuándo sí:** ninguno previsto; ese caso es un alert o un modal. | canon (aprobado por el dueño, 05-10-2026, bloque B6) |
75
76
 
76
77
  ### Tiempo, cierre, acción y texto
77
78
 
78
79
  | opción | valor | cuándo | fuente |
79
80
  |---|---|---|---|
80
81
  | `duration` | `4000` (default) | Un título corto. | según el componente (valor de Sonner) |
81
- | `duration` | `6000` | Título más `description`, o un título largo que no se alcanza a leer en 4 s. | propuesta |
82
+ | `duration` | `6000` | Título más `description`, o un título largo que no se alcanza a leer en 4 s. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
82
83
  | `duration` | `60_000` | Los avisos de un pedido que llegan con la app abierta: tiempo de verlos sin quedarse tapando. | canon (pedido del dueño, 28-09-2026, en `aviso-unico.service.ts`) |
83
- | `duration` | `Infinity` | **Solo con `action`**: hay algo que hacer y no se puede perder («Actualizar»). Sin acción, es un alert. | propuesta |
84
+ | `duration` | `Infinity` | **Solo con `action`**: hay algo que hacer y no se puede perder («Actualizar»). Sin acción, es un alert. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
84
85
  | `dismissible` | `true` (default) | Siempre: la X permite quitarlo antes. La guía lo trae cerrable por defecto. | según la guía del DS |
85
- | `dismissible` | `false` | No usar hoy. **Cuándo sí:** un toast de progreso que se reemplaza solo usando el mismo `id` («Subiendo foto…» → «Foto subida»). | propuesta (la guía muestra un ejemplo no cerrable) |
86
- | `action` | `{ label, onClick, keepOpen? }` | **Una** acción corta que resuelve ahí mismo: «Actualizar», «Deshacer», «Reintentar». Se dibuja como link subrayado. | propuesta |
86
+ | `dismissible` | `false` | No usar hoy. **Cuándo sí:** un toast de progreso que se reemplaza solo usando el mismo `id` («Subiendo foto…» → «Foto subida»). | canon (aprobado por el dueño, 05-10-2026, bloque B6; la guía muestra un ejemplo no cerrable) |
87
+ | `action` | `{ label, onClick, keepOpen? }` | **Una** acción corta que resuelve ahí mismo: «Actualizar», «Deshacer», «Reintentar». Se dibuja como link subrayado. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
87
88
  | `title` | frase corta | Qué pasó, en sentence case, **sin punto final**. Una idea. | canon (copy de la app) |
88
- | `description` | segunda frase | Si hace falta una segunda frase, va aquí y no pegada al título con un punto. | propuesta |
89
- | `position` | `bottom-right` (default) | Siempre. En mobile toda posición pasa a ancho completo; las `bottom-*` quedan abajo, por encima de la barra inferior. | propuesta |
90
- | `position` | `top-*` | No usar hoy. **Cuándo sí:** una pantalla con una barra de acción fija abajo que el toast taparía. | propuesta |
91
- | `position` | `bottom-left` · `bottom-center` | No usar hoy: dos esquinas abren dos pilas. **Cuándo sí:** si se decide cambiar la esquina de toda la app, con `setDefaultPosition()`, una sola vez. | propuesta |
89
+ | `description` | segunda frase | Si hace falta una segunda frase, va aquí y no pegada al título con un punto. | canon (CLAUDE.md «Canon de UI» → `docs/VOZ-Y-ESCRITURA.md` «Toasts: la regla completa»: dos frases nunca en el título; D10) |
90
+ | `position` | `bottom-right` (default) | Siempre. En mobile toda posición pasa a ancho completo; las `bottom-*` quedan abajo, por encima de la barra inferior. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
91
+ | `position` | `top-*` | No usar hoy. **Cuándo sí:** una pantalla con una barra de acción fija abajo que el toast taparía. | canon (aprobado por el dueño, 05-10-2026, bloque B6) |
92
+ | `position` | `bottom-left` · `bottom-center` | No usar hoy: dos esquinas abren dos pilas. **Cuándo sí:** si se decide cambiar la esquina de toda la app, con `setDefaultPosition()`, una sola vez. | canon (aprobado por el dueño, 05-10-2026, bloque B6) |
92
93
  | `id` | texto | Para reemplazar un toast en curso o no repetir el mismo aviso. | según el componente |
93
94
 
94
95
  ### Usos de hoy que rompen la regla
@@ -100,14 +101,15 @@ arma el título con variables. La pasada de copy del 03-10-2026 en la app ya cor
100
101
  `duration: Infinity` de «Acerca de» (ahora duran 6 s). Queda:
101
102
 
102
103
  - **Rompe el canon de copy — 1 error que empieza con «Error…»:**
103
- `pages/driver/driver-order-detail/driver-order-detail.ts:1548` («Error al cancelar el pedido»).
104
+ `pages/driver/driver-order-detail/driver-order-detail.ts:1647` («Error al cancelar el pedido»; línea al 06-10-2026).
104
105
  - **Rompen el canon de copy — 18 errores que muestran `e.message`** cuando existe (puede salir
105
- texto técnico o en inglés): `components/transfer-tenant-modal/transfer-tenant-modal.ts:82`,
106
- `pages/driver/driver-dashboard/driver-dashboard.ts:1601`, `pages/central/central-gastos/central-gastos.ts:183`.
107
- Algunos de esos textos de respaldo además llevan punto final (`pages/super-admin/master-viajes/master-viajes.ts:82`).
106
+ texto técnico o en inglés): `components/transfer-tenant-modal/transfer-tenant-modal.ts:84`,
107
+ `pages/driver/driver-dashboard/driver-dashboard.ts:1706`, `pages/central/central-gastos/central-gastos.ts:185`
108
+ (y `:205`). Algunos de esos textos de respaldo además llevan punto final
109
+ (`pages/super-admin/master-viajes/master-viajes.ts:243`, «No se pudo habilitar.»; líneas al 06-10-2026).
108
110
  - **Romperían la propuesta — 57 errores al cargar como toast** («No se pudo cargar…») → alert o
109
111
  empty state con «Reintentar»: `pages/driver/driver-history/driver-history.ts:200`,
110
- `pages/settings/team/team.ts:307`.
112
+ `pages/settings/team/team.ts:308`.
111
113
 
112
114
  ## Tamaño en mobile y en web
113
115
 
@@ -123,6 +125,26 @@ El toast **no tiene `size`**: siempre es un alert `large`.
123
125
  No hay patrón `bp.isMobile()`: el outlet ya cambia solo por breakpoint. Lo que sí cambia por
124
126
  plataforma es el largo del texto: en mobile el título envuelve antes, así que una sola idea por toast.
125
127
 
128
+ ### Por dispositivo (D16)
129
+
130
+ El toast no tiene `size` (siempre es un alert `large`): no hay size que elegir por dispositivo ni
131
+ nada que pasar desde la app (en master-pedidos no lleva `bp`). Ancho y posición los resuelve el
132
+ outlet solo, por ancho, y está bien así.
133
+
134
+ Lo que **sí** queda corto es la X de cerrar, que se toca:
135
+
136
+ | dispositivo | área de la X hoy | D16 pide |
137
+ |---|---|---|
138
+ | celular chico y celular (≤ 767 px) | 44 × 44 | 44 × 44 (cumple) |
139
+ | tablet táctil (`pointer: coarse`, más de 767 px) | **40 × 40** | 44 × 44 |
140
+ | computadora (`pointer: fine`) | 40 × 40 | sin piso de 44 (cumple) |
141
+
142
+ **Pendiente del DS**, no de la app: el área de 44 se prende con `@media (max-width: 767px)`
143
+ (`sui-toast-outlet.scss:182`), así que el iPad apaisado y la tablet ancha se quedan en 40. Se
144
+ arregla con el mixin `sui-tactil` (`@media (max-width: 767px), (pointer: coarse)`) que propone la
145
+ sección 0 de las decisiones D16; mientras no exista, no hay nada que la app pueda pasar para
146
+ corregirlo.
147
+
126
148
  ## «No usar»: por qué no hoy y cuándo sí
127
149
 
128
150
  Nada se borra del DS. Si un flujo nuevo cae en la columna de la derecha, se usa.
@@ -172,6 +194,45 @@ Outputs: ninguno.
172
194
  - El título es texto plano; la `description` del alert interno va por `innerHTML`: no le pases
173
195
  texto escrito por el usuario sin sanear.
174
196
 
197
+ ## Bien y mal
198
+
199
+ El copy del error
200
+
201
+ ```ts
202
+ // ❌ mal: «Error al…» en vez de decir qué no se pudo (pages/driver/driver-order-detail/driver-order-detail.ts:1647)
203
+ this.toast.error('Error al cancelar el pedido');
204
+ ```
205
+
206
+ ```ts
207
+ // ✅ bien
208
+ this.toast.error('No se pudo cancelar el pedido');
209
+ ```
210
+
211
+ El mensaje técnico en el título
212
+
213
+ ```ts
214
+ // ❌ mal: e.message puede ser técnico o en inglés (pages/driver/driver-dashboard/driver-dashboard.ts:1706)
215
+ this.toast.error((e instanceof Error && e.message) || 'No se pudo abrir la votación');
216
+ ```
217
+
218
+ ```ts
219
+ // ✅ bien: el detalle va a la consola; la persona lee qué no se pudo
220
+ console.error('[votación]', e);
221
+ this.toast.error('No se pudo abrir la votación');
222
+ ```
223
+
224
+ Un error al cargar la pantalla (sigue en propuesta: ver «Usos de hoy que rompen la regla»)
225
+
226
+ ```ts
227
+ // ❌ mal: el toast se va y deja la lista vacía sin explicación (pages/driver/driver-history/driver-history.ts:200)
228
+ this.toast.error('No se pudo cargar el historial');
229
+ ```
230
+
231
+ ```ts
232
+ // ✅ bien: la pantalla queda con un sui-alert o un sui-empty-state con «Reintentar»
233
+ this.errorAlCargar.set(true);
234
+ ```
235
+
175
236
  ## Ejemplo
176
237
 
177
238
  ```ts
@@ -32,7 +32,8 @@ servicio»). Es un extra: la pantalla tiene que entenderse sin él.
32
32
  ## Qué variante usar
33
33
 
34
34
  > La guía del DS dice para qué es y cómo se llaman sus tamaños, pero no cuándo va cada uno. Lo
35
- > marcado «según la guía del DS» sale de su texto o su código publicado; el resto es **propuesta**.
35
+ > marcado «según la guía del DS» sale de su texto o su código publicado; lo marcado canon lo aprobó
36
+ > el dueño (05-10-2026); lo que sigue en **propuesta** espera decisión.
36
37
  >
37
38
  > Uso medido el 04-10-2026 en `master-pedidos/src/app` (sin prototipos ni vitrinas): **0 tooltips**.
38
39
  > Los 6 que había el 03-10-2026 (2 `suiTooltip` sobre un `<svg>` en el panel del local y 4
@@ -51,18 +52,18 @@ servicio»). Es un extra: la pantalla tiene que entenderse sin él.
51
52
 
52
53
  | SUI | guía | qué es | cuándo | fuente |
53
54
  |---|---|---|---|---|
54
- | `small` (caja de 20 px en `dark`, 22 en `light` por el borde; 24 con la flecha; texto 12) | `xsmall` | texto de una línea, chico | El nombre de un ícono en una tabla o barra densa. | escala según la guía del DS · cuándo: propuesta |
55
- | `medium` (caja de 28 px en `dark`, 30 en `light`; 34 con la flecha; texto 14) — default SUI | `small` (default de la guía) | texto de una línea | Lo normal: una frase corta que explica. | escala según la guía del DS · cuándo: propuesta |
56
- | `large` (280 px, título + descripción + ícono) | `medium` | contenido rico | Explicar un término con título y una o dos frases. Se activa solo al usar `[suiTooltipLarge]`. | escala según la guía del DS · cuándo: propuesta |
55
+ | `small` (caja de 20 px en `dark`, 22 en `light` por el borde; 24 con la flecha; texto 12) | `xsmall` | texto de una línea, chico | No usar: es chico. El nombre de un ícono también va en `medium`. | escala según la guía del DS · no usarlo: canon (dueño, 05-10-2026, D16), reemplaza el «cuándo» del bloque B1 |
56
+ | `medium` (caja de 28 px en `dark`, 30 en `light`; 34 con la flecha; texto 14) — default SUI | `small` (default de la guía) | texto de una línea | Lo normal: una frase corta que explica, o el nombre de un ícono. | escala según la guía del DS · cuándo: canon (aprobado por el dueño, 05-10-2026, bloque B1) · el nombre de un ícono: canon (dueño, 05-10-2026, D16) |
57
+ | `large` (280 px, título + descripción + ícono) | `medium` | contenido rico | Explicar un término con título y una o dos frases. Se activa solo al usar `[suiTooltipLarge]`. | escala según la guía del DS · cuándo: canon (aprobado por el dueño, 05-10-2026, bloque B1) |
57
58
  | `xlarge` (320 px) | — | rico, más ancho | No usar hoy. Extensión de SUI. **Cuándo sí:** una explicación rica que en 280 px queda en más de cuatro líneas. | propuesta |
58
59
 
59
60
  ### Contenido: `suiTooltip` o `suiTooltipLarge`
60
61
 
61
62
  | input | cuándo | ejemplo real de la app | fuente |
62
63
  |---|---|---|---|
63
- | `suiTooltip="…"` | Una frase, sin punto final. | (sin uso hoy) | propuesta |
64
- | `[suiTooltipLarge]="{ title, description, icon }"` | Un término que necesita título y explicación. | (sin uso hoy) | propuesta |
65
- | `suiTooltipLarge.dismissible: true` | No usar hoy: lo deja abierto hasta tocar la X o Escape, que es lo que hace un popover. **Cuándo sí:** en web, una explicación larga que la persona lee con calma mientras mueve el mouse. | (sin uso hoy) | propuesta |
64
+ | `suiTooltip="…"` | Una frase, sin punto final. | (sin uso hoy) | canon (aprobado por el dueño, 05-10-2026, bloque B4) |
65
+ | `[suiTooltipLarge]="{ title, description, icon }"` | Un término que necesita título y explicación. | (sin uso hoy) | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
66
+ | `suiTooltipLarge.dismissible: true` | No usar hoy: lo deja abierto hasta tocar la X o Escape, que es lo que hace un popover. **Cuándo sí:** en web, una explicación larga que la persona lee con calma mientras mueve el mouse. | (sin uso hoy) | canon (aprobado por el dueño, 05-10-2026, bloque B6) |
66
67
 
67
68
  ### `theme`, `position` y el resto
68
69
 
@@ -71,14 +72,14 @@ servicio»). Es un extra: la pantalla tiene que entenderse sin él.
71
72
  | `theme` | `auto` | **Siempre.** Oscuro sobre la app en claro (lo que pide la guía) y claro sobre la app en oscuro. | propuesta (la guía: `dark` por default) |
72
73
  | `theme` | `dark` | Igual que `auto` en modo claro, pero no se invierte en modo oscuro. | según la guía del DS (default) |
73
74
  | `theme` | `light` (default SUI) | No usar hoy: sobre una página clara parece una card más. **Cuándo sí:** ya lo da `auto` en modo oscuro. | propuesta |
74
- | `position` | `top` (default) | Siempre que haya espacio. Si no lo hay, el CDK lo da vuelta solo. | propuesta |
75
- | `position` | `right` · `left` | Íconos de una barra lateral angosta (el sidebar colapsado). | propuesta |
76
- | `position` | `bottom` · `*-start` · `*-end` | Un elemento pegado al borde de arriba o a un costado de la pantalla. | propuesta |
77
- | `delay` | `200` (default) | Siempre: evita que se abra al cruzar con el mouse. | propuesta |
78
- | `delay` | otro valor | No usar hoy. **Cuándo sí:** ninguno previsto. | propuesta |
79
- | `disabled` | `true` | Cuando lo que dice ya está a la vista (el sidebar expandido muestra el nombre). | propuesta |
75
+ | `position` | `top` (default) | Siempre que haya espacio. Si no lo hay, el CDK lo da vuelta solo. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
76
+ | `position` | `right` · `left` | Íconos de una barra lateral angosta (el sidebar colapsado). | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
77
+ | `position` | `bottom` · `*-start` · `*-end` | Un elemento pegado al borde de arriba o a un costado de la pantalla. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
78
+ | `delay` | `200` (default) | Siempre: evita que se abra al cruzar con el mouse. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
79
+ | `delay` | otro valor | No usar hoy. **Cuándo sí:** ninguno previsto. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
80
+ | `disabled` | `true` | Cuando lo que dice ya está a la vista (el sidebar expandido muestra el nombre). | canon (aprobado por el dueño, 05-10-2026, bloque B8) |
80
81
  | `showArrow` | `true` (default) | Siempre: la flecha dice de qué elemento habla. | según la guía del DS |
81
- | `showArrow` | `false` | No usar hoy. **Cuándo sí:** sobre un punto de un gráfico, donde la flecha tapa el dato. | propuesta |
82
+ | `showArrow` | `false` | No usar hoy. **Cuándo sí:** sobre un punto de un gráfico, donde la flecha tapa el dato. | canon (aprobado por el dueño, 05-10-2026, bloque B6) |
82
83
 
83
84
  ### Usos de hoy que rompen la regla
84
85
 
@@ -91,21 +92,38 @@ dos `<svg>` con tooltip del panel del local pasaron a subtítulo
91
92
 
92
93
  | uso | mobile | web | fuente |
93
94
  |---|---|---|---|
94
- | nombre de un ícono | no aplica: el ícono lleva el nombre escrito o `aria-label` | `small` | propuesta |
95
- | frase que explica | no aplica: el texto va visible bajo el dato (`sui-form-hint`) | `medium` | propuesta |
96
- | explicación con título | no aplica: `sui-modal-sheet` al tocar el ícono | `large` (automático con `[suiTooltipLarge]`) | propuesta |
95
+ | nombre de un ícono | no aplica: el ícono lleva el nombre escrito o `aria-label` | `medium` | mobile: canon (aprobado por el dueño, 05-10-2026, bloque B7) · web: canon (dueño, 05-10-2026, D16), antes `small` |
96
+ | frase que explica | no aplica: el texto va visible bajo el dato (`sui-form-hint`) | `medium` | canon (aprobado por el dueño, 05-10-2026, bloque B7) |
97
+ | explicación con título | no aplica: `sui-modal-sheet` al tocar el ícono | `large` (automático con `[suiTooltipLarge]`) | canon (aprobado por el dueño, 05-10-2026, bloque B7) |
97
98
 
98
- En pantallas que se usan en los dos (panel del local, super admin), el tooltip se apaga en mobile
99
- y la ayuda se muestra de otra forma:
99
+ En pantallas que se usan en los dos (panel del local, super admin), el tooltip se apaga en el
100
+ celular y en la tablet táctil, y la ayuda se muestra de otra forma:
100
101
 
101
102
  ```html
102
103
  <button class="info" type="button" aria-label="Qué es la tarifa de servicio"
103
- [suiTooltipLarge]="tarifa" theme="auto" [disabled]="bp.isMobile()"
104
- (click)="bp.isMobile() && abrirExplicacion()">
104
+ [suiTooltipLarge]="tarifa" theme="auto" [disabled]="bp.tactil()"
105
+ (click)="bp.tactil() && abrirExplicacion()">
105
106
  <sui-icon name="information-line" [size]="16" />
106
107
  </button>
107
108
  ```
108
109
 
110
+ ### Por dispositivo (D16)
111
+
112
+ Fila `tooltip` de la tabla D16 (dueño, 05-10-2026). Solo existe donde hay mouse: con el dedo no hay
113
+ hover, y eso incluye la tablet aunque sea ancha.
114
+
115
+ | dispositivo | size | nota |
116
+ |---|---|---|
117
+ | celular chico (< 380 px) | no aplica | sin hover: texto visible o un `sui-modal-sheet` al tocar |
118
+ | celular (380–767 px) | no aplica | igual que el celular chico |
119
+ | tablet táctil (`pointer: coarse`) | no aplica | también sin hover; `bp.isMobile()` no la apaga (mide más de 767), `bp.tactil()` sí |
120
+ | computadora (`pointer: fine`) | `medium` (default) | también el nombre de un ícono; `large` sale solo con `[suiTooltipLarge]`; `small` no se usa |
121
+
122
+ Ultrawide (≥ 1920 px): igual que la computadora.
123
+
124
+ En master-pedidos: sin helper de tamaño (`medium` es el default, no se pasa `suiTooltipSize`); se
125
+ apaga con `[disabled]="bp.tactil()"` y la ayuda va por otro lado.
126
+
109
127
  ## «No usar»: por qué no hoy y cuándo sí
110
128
 
111
129
  | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
@@ -171,7 +189,7 @@ no se usa directo en pantallas.
171
189
  ## Trampas
172
190
 
173
191
  - **El tamaño se pasa como `suiTooltipSize`**, no como `size`: así no choca con el `size` del
174
- componente que lo lleva (`<sui-button size="small" suiTooltip="…">`).
192
+ componente que lo lleva (`<sui-button size="medium" suiTooltip="…">`).
175
193
  - **`position`, `theme`, `delay` y `disabled` sí se llaman así, sin prefijo**: si el host es un
176
194
  componente con un input del mismo nombre (`disabled` de `sui-button`), el valor llega a los dos.
177
195
  - **`suiTooltipSize="large"` con `suiTooltip` de texto dibuja una caja vacía**: el tamaño rico solo
@@ -183,6 +201,46 @@ no se usa directo en pantallas.
183
201
  gris del navegador).
184
202
  - En `dark`, el ícono del tooltip rico usa un gris fijo del `.scss`, no un token.
185
203
 
204
+ ## Bien y mal
205
+
206
+ Tooltip sobre un ícono suelto
207
+
208
+ ```html
209
+ <!-- ❌ mal: un <svg> no se enfoca (con teclado nunca aparece) y en el celular no hay hover (components/customer-segments/customer-segments.html, antes de 77ac547a) -->
210
+ <svg suiTooltip="Ingresos por tipo de cliente" position="top" width="16" height="16" viewBox="0 0 16 16">…</svg>
211
+ ```
212
+
213
+ ```html
214
+ <!-- ✅ bien: si es una aclaración del título, va escrita -->
215
+ <p class="customer-segments__subtitle">Ingresos por tipo de cliente</p>
216
+ ```
217
+
218
+ Explicación en una pantalla del cliente
219
+
220
+ ```html
221
+ <!-- ❌ mal: el carrito se usa en el celular, sin hover; la tarifa queda sin explicar (pages/customer/cart/cart.html, antes de 77ac547a) -->
222
+ <button type="button" aria-label="Qué es la tarifa de servicio" [suiTooltipLarge]="serviceFeeTooltip" theme="dark">
223
+ <sui-icon name="information-line" [size]="14" />
224
+ </button>
225
+ ```
226
+
227
+ ```html
228
+ <!-- ✅ bien: la explicación va visible bajo el dato -->
229
+ <span class="cart__fee-hint">{{ serviceFeeExplicacion }}</span>
230
+ ```
231
+
232
+ Tamaño rico con texto plano
233
+
234
+ ```html
235
+ <!-- ❌ mal: suiTooltipSize="large" solo lee suiTooltipLarge: con texto dibuja una caja vacía (ver Trampas) -->
236
+ <sui-compact-button icon="download-2-line" ariaLabel="Exportar" suiTooltip="Exportar" suiTooltipSize="large" theme="auto" />
237
+ ```
238
+
239
+ ```html
240
+ <!-- ✅ bien: el nombre de un ícono va en medium, el default -->
241
+ <sui-compact-button icon="download-2-line" ariaLabel="Exportar" suiTooltip="Exportar" theme="auto" />
242
+ ```
243
+
186
244
  ## Ejemplo
187
245
 
188
246
  ```html
@@ -21,7 +21,7 @@ Compone las tres piezas de la familia (`sui-topbar-item`, `sui-topbar-button`,
21
21
  - La navegación de los roles de la app (empresa, cliente, repartidor, super admin): es
22
22
  `sui-sidebar`, y en el teléfono la barra inferior. Hoy la topbar tiene **0 usos** en la app.
23
23
  - El título de una pantalla con sus acciones: `sui-page-header`.
24
- - Nada que se vea en un teléfono: el componente no tiene versión mobile (ver «Tamaño»).
24
+ - Nada que se vea en un celular o una tablet táctil: el componente no tiene versión mobile (ver «Tamaño»).
25
25
 
26
26
  Regla corta: **navegación de la app → sidebar · título de pantalla → page header · web de escritorio
27
27
  navegada por arriba → topbar.**
@@ -30,20 +30,20 @@ navegada por arriba → topbar.**
30
30
 
31
31
  > **La guía del DS no tiene página de la topbar.** El componente sale del Figma de SUI (Topbar
32
32
  > [Navigation], frame 3814:25274, cuatro ejemplos: con y sin íconos, con buscador abierto o en
33
- > botón). Sin uso en la app, **todo lo de abajo es propuesta, falta aprobación**, salvo lo que el
34
- > componente ya fija.
33
+ > botón). Sin uso en la app. Las reglas marcadas canon están aprobadas (05-10-2026) y no queda
34
+ > ninguna en propuesta; lo marcado «Figma» lo fija el componente.
35
35
  >
36
36
  > Uso medido el 03-10-2026 en `master-pedidos/src/app`: `sui-topbar`, `sui-topbar-item` y
37
37
  > `sui-topbar-user` tienen 0 usos; `sui-topbar-button`, 1 en la vitrina de variantes.
38
38
 
39
39
  | decisión | opción | cuándo | fuente |
40
40
  |---|---|---|---|
41
- | items | sin `icon` | El caso normal: 3-6 secciones con nombre corto. | propuesta, falta aprobación |
42
- | items | con `icon` | Si **todos** llevan ícono. Mezclar con y sin se lee desordenado. | propuesta, falta aprobación |
43
- | item con `rightIcon: 'arrow-down-s-line'` | — | Un «Más ⌄» que abre un menú. El menú lo pones tú (`sui-dropdown-menu`) al escuchar `(itemClicked)`. | propuesta, falta aprobación |
41
+ | items | sin `icon` | El caso normal: 3-6 secciones con nombre corto. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
42
+ | items | con `icon` | Si **todos** llevan ícono. Mezclar con y sin se lee desordenado. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
43
+ | item con `rightIcon: 'arrow-down-s-line'` | — | Un «Más ⌄» que abre un menú. El menú lo pones tú (`sui-dropdown-menu`) al escuchar `(itemClicked)`. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
44
44
  | `search` | objeto con `placeholder` | Buscador abierto de 232 px cuando buscar es la acción principal. | Figma (Type=Default) |
45
45
  | `search` | `{ compact: true }` | Ícono de lupa en la zona de acciones; tú abres el buscador real (`sui-modal` o una paleta de comandos) en `(searchClicked)`. | Figma (Type=With Icon) |
46
- | `actions` | 1-3 íconos | Avisos, ayuda, acciones rápidas. `dot: true` = hay algo nuevo. | propuesta, falta aprobación |
46
+ | `actions` | 1-3 íconos | Avisos, ayuda, acciones rápidas. `dot: true` = hay algo nuevo. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
47
47
  | `user` | config | El chip abre el menú de la cuenta: pásale `[userOpen]` mientras el menú está abierto. | Figma |
48
48
  | `accent` | `brand` (default) | Siempre. `information` es el azul del Figma original. | canon del DS (accent = marca) |
49
49
 
@@ -55,14 +55,27 @@ oculto si no entra.
55
55
 
56
56
  | uso | mobile | web | fuente |
57
57
  |---|---|---|---|
58
- | navegación de una web de escritorio | **no usar** | `sui-topbar` | propuesta, falta aprobación |
58
+ | navegación de una web de escritorio | **no usar** | `sui-topbar` | canon (aprobado por el dueño, 05-10-2026, bloque B7) |
59
59
 
60
60
  **Qué pasa en mobile:** nada se adapta. Los 44 px laterales se comen el ancho, los items se
61
61
  esconden detrás de un scroll lateral sin pista visual, el buscador no se achica y no hay
62
62
  `safe-area-inset-top` (en la app nativa queda debajo del notch). En mobile se usa el patrón de la
63
- app: barra inferior + cajón `sui-sidebar`. Si algún día hace falta topbar en el teléfono, primero
63
+ app: barra inferior + cajón `sui-sidebar`. Si algún día hace falta topbar en celular o tablet táctil, primero
64
64
  hay que agregarle al componente un modo mobile (menú hamburguesa, buscador en botón, safe area).
65
65
 
66
+ ### Por dispositivo (D16)
67
+
68
+ No aplica una tabla: no tiene input `size` y sus piezas tienen tamaño fijo (items de 36, íconos y
69
+ chip de 40, buscador de 40). Como se toca y no tiene un size que llegue a 44, B7 lo saca de todo lo
70
+ táctil: en el celular chico, el celular y la tablet táctil **no se usa**; solo en la computadora
71
+ (`pointer: fine`) y en el ultrawide, igual que en la computadora, con el ancho extra para el
72
+ contenido y no para la barra. La columna «mobile» de D16 incluye la tablet en lo que se toca, así
73
+ que el «no usar en mobile» de B7 la cubre.
74
+
75
+ En master-pedidos: sin `[size]` ni helper; si algún día se monta, va detrás de `@if (!bp.tactil())`
76
+ (`isMobile() || toque()`: todo celular por ancho y toda pantalla táctil). No `!bp.isMobile()`: ese
77
+ es solo por ancho (≤ 768) y deja pasar un iPad de 769 a 1024 con `pointer: coarse`.
78
+
66
79
  ## «No usar»: por qué no hoy y cuándo sí
67
80
 
68
81
  | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
@@ -129,6 +142,47 @@ Slot: `<ng-content select="[topbar-logo]">` — el logo (una `<img>` directa se
129
142
  - El chip de usuario no abre ningún menú: emite `(userClicked)` y solo cambia de aspecto con
130
143
  `userOpen`.
131
144
  - El host lleva `role="banner"`: una sola por página.
145
+ - `count` en `0` **se muestra** («0» rojo), igual que en `sui-topbar-item`: pasa
146
+ `pendientes() || undefined`.
147
+
148
+ ## Bien y mal
149
+
150
+ El contador de un item
151
+
152
+ ```html
153
+ <!-- ❌ mal: sin pendientes sale un «0» rojo -->
154
+ <sui-topbar [items]="[{ value: 'pedidos', label: 'Pedidos', count: pendientes() }]" />
155
+ ```
156
+
157
+ ```html
158
+ <!-- ✅ bien -->
159
+ <sui-topbar [items]="[{ value: 'pedidos', label: 'Pedidos', count: pendientes() || undefined }]" />
160
+ ```
161
+
162
+ Las acciones de ícono
163
+
164
+ ```html
165
+ <!-- ❌ mal: sin ariaLabel, el lector de pantalla lee el value («notifications») -->
166
+ <sui-topbar [actions]="[{ value: 'notifications', icon: 'notification-3-line', dot: hayAvisos() }]" />
167
+ ```
168
+
169
+ ```html
170
+ <!-- ✅ bien -->
171
+ <sui-topbar [actions]="[{ value: 'avisos', icon: 'notification-3-line',
172
+ ariaLabel: 'Avisos', dot: hayAvisos() }]" />
173
+ ```
174
+
175
+ El item activo en una ruta con id
176
+
177
+ ```html
178
+ <!-- ❌ mal: en /pedidos/123 la url nunca es igual a 'pedidos'; no se marca ninguno -->
179
+ <sui-topbar [items]="items" [activeValue]="router.url" (itemClicked)="ir($event.value)" />
180
+ ```
181
+
182
+ ```html
183
+ <!-- ✅ bien: seccion() saca 'pedidos' del primer tramo de la ruta -->
184
+ <sui-topbar [items]="items" [activeValue]="seccion()" (itemClicked)="ir($event.value)" />
185
+ ```
132
186
 
133
187
  ## Ejemplo
134
188
 
@@ -136,7 +190,7 @@ Slot: `<ng-content select="[topbar-logo]">` — el logo (una `<img>` directa se
136
190
  <sui-topbar
137
191
  [items]="[
138
192
  { value: 'tablero', label: 'Tablero' },
139
- { value: 'pedidos', label: 'Pedidos', count: pendientes() },
193
+ { value: 'pedidos', label: 'Pedidos', count: pendientes() || undefined },
140
194
  { value: 'mas', label: 'Más', rightIcon: 'arrow-down-s-line' }
141
195
  ]"
142
196
  [activeValue]="seccion()"
@@ -26,24 +26,36 @@ armada a mano que quiera verse como la topbar.
26
26
 
27
27
  > **La guía del DS no tiene página de este botón.** Sale del Figma de SUI (Topbar Item Button
28
28
  > [Topbar], set 3814:25156: Default, Hover, Active). Uso medido el 03-10-2026: **0 usos** en la
29
- > app, 1 en la vitrina de variantes (`master-preview/_guia-variantes`). Lo de abajo es
30
- > **propuesta, falta aprobación**.
29
+ > app, 1 en la vitrina de variantes (`master-preview/_guia-variantes`). Las reglas marcadas
30
+ > canon están aprobadas (05-10-2026) y no queda ninguna en propuesta.
31
31
 
32
32
  | prop | cuándo | fuente |
33
33
  |---|---|---|
34
- | `dot` | Hay algo nuevo detrás del ícono (avisos sin leer). Se apaga cuando la persona lo abre. Si el número importa, no alcanza: va un contador en otro lado. | propuesta, falta aprobación |
34
+ | `dot` | Hay algo nuevo detrás del ícono (avisos sin leer). Se apaga cuando la persona lo abre. Si el número importa, no alcanza: va un contador en otro lado. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
35
35
  | `active` | Mientras el panel que abre el botón está abierto (pinta el ícono naranja y `aria-pressed`). | Figma (State=Active) |
36
36
  | `accent` | `brand` (default). `information` es el azul del Figma original: no usar. | canon del DS (accent = marca) |
37
37
 
38
38
  ## Tamaño en mobile y en web
39
39
 
40
- **No tiene `size`**: mide siempre 40×40 (padding 10 + ícono de 20), radio 10. En mobile 40 es el
41
- mínimo táctil aceptable, pero el botón vive en la topbar, que hoy es solo de escritorio (ver
42
- `sui-topbar`).
40
+ **No tiene `size`**: mide siempre 40×40 (padding 10 + ícono de 20), radio 10. 40 queda debajo de
41
+ los 44 que D1 y D16 piden para lo que se toca, y por eso no va en mobile (B7): vive en la topbar,
42
+ que es solo de computadora (ver `sui-topbar`).
43
43
 
44
44
  | uso | mobile | web | fuente |
45
45
  |---|---|---|---|
46
- | ícono de la barra superior | no usar (no hay topbar en mobile) | 40×40 | propuesta, falta aprobación |
46
+ | ícono de la barra superior | no usar (no hay topbar en mobile) | 40×40 | canon (aprobado por el dueño, 05-10-2026, bloque B7) |
47
+
48
+ ### Por dispositivo (D16)
49
+
50
+ No aplica una tabla: no tiene input `size` y mide 40×40 en todos los dispositivos. Como se toca y no
51
+ tiene un size que llegue a 44, B7 lo saca de todo lo táctil: en el celular chico, el celular y la
52
+ tablet táctil **no se usa**; solo en la computadora (`pointer: fine`) y en el ultrawide, igual que
53
+ en la computadora. La columna «mobile» de D16 incluye la tablet en lo que se toca, así que el «no
54
+ usar en mobile» de B7 la cubre.
55
+
56
+ En master-pedidos: sin `[size]` ni helper; si algún día se monta, va detrás de `@if (!bp.tactil())`
57
+ (`isMobile() || toque()`: todo celular por ancho y toda pantalla táctil). No `!bp.isMobile()`: ese
58
+ es solo por ancho (≤ 768) y deja pasar un iPad de 769 a 1024 con `pointer: coarse`.
47
59
 
48
60
  ## «No usar»: por qué no hoy y cuándo sí
49
61
 
@@ -83,6 +95,48 @@ mínimo táctil aceptable, pero el botón vive en la topbar, que hoy es solo de
83
95
  de pantalla. Si importa, dilo en `ariaLabel` («Avisos, hay nuevos»).
84
96
  - Ya trae el arreglo de iOS para el `:active` pegado.
85
97
 
98
+ ## Bien y mal
99
+
100
+ El ícono de avisos
101
+
102
+ ```html
103
+ <!-- ❌ mal: el lector de pantalla dice «notifications» y no se entera del punto rojo -->
104
+ <sui-topbar-button icon="notification-3-line" ariaLabel="notifications" [dot]="hayAvisos()" />
105
+ ```
106
+
107
+ ```html
108
+ <!-- ✅ bien -->
109
+ <sui-topbar-button icon="notification-3-line" [dot]="hayAvisos()"
110
+ [ariaLabel]="hayAvisos() ? 'Avisos, hay nuevos' : 'Avisos'" />
111
+ ```
112
+
113
+ El panel abierto
114
+
115
+ ```html
116
+ <!-- ❌ mal: azul del Figma original y (click) en vez de la API -->
117
+ <sui-topbar-button icon="question-line" ariaLabel="Ayuda" accent="information"
118
+ [active]="panelAyuda()" (click)="panelAyuda.set(!panelAyuda())" />
119
+ ```
120
+
121
+ ```html
122
+ <!-- ✅ bien -->
123
+ <sui-topbar-button icon="question-line" ariaLabel="Ayuda"
124
+ [active]="panelAyuda()" (clicked)="panelAyuda.set(!panelAyuda())" />
125
+ ```
126
+
127
+ Un ícono en una card
128
+
129
+ ```html
130
+ <!-- ❌ mal: es el botón de la barra superior; en una card desentona (radio 10, 40 fijo) -->
131
+ <sui-topbar-button icon="more-2-line" ariaLabel="Opciones" (clicked)="abrirMenu()" />
132
+ ```
133
+
134
+ ```html
135
+ <!-- ✅ bien -->
136
+ <sui-button variant="ghost" color="neutral" [size]="bp.sizeControl()" [onlyIcon]="true"
137
+ leftIcon="more-2-line" aria-label="Opciones" (click)="abrirMenu()" />
138
+ ```
139
+
86
140
  ## Ejemplo
87
141
 
88
142
  ```html
@@ -25,18 +25,18 @@ igual.
25
25
  ## Qué variante usar
26
26
 
27
27
  > **La guía del DS no tiene página de este item.** Sale del Figma de SUI (Topbar Items [Topbar],
28
- > set 3802:24588: Default, Hover, Active). Uso medido el 03-10-2026: **0 usos** en la app. Lo de
29
- > abajo es **propuesta, falta aprobación**.
28
+ > set 3802:24588: Default, Hover, Active). Uso medido el 03-10-2026: **0 usos** en la app. Las reglas
29
+ > marcadas canon están aprobadas (05-10-2026) y no queda ninguna en propuesta.
30
30
 
31
31
  | prop | cuándo | fuente |
32
32
  |---|---|---|
33
- | solo `label` | El caso normal. Una o dos palabras, sentence case. | propuesta, falta aprobación |
34
- | `icon` | Si **todos** los items de la barra lo llevan. | propuesta, falta aprobación |
33
+ | solo `label` | El caso normal. Una o dos palabras, sentence case. | canon (aprobado por el dueño, 05-10-2026, bloque B4) |
34
+ | `icon` | Si **todos** los items de la barra lo llevan. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
35
35
  | `rightIcon: 'arrow-down-s-line'` | El item abre un menú («Más ⌄»). El menú lo pones tú. | Figma |
36
36
  | `count` | Pendientes que piden acción («3» pedidos por aceptar). Número rojo. | Figma (notification=true) |
37
37
  | `badge` | Un «Nuevo» temporal en una sección recién lanzada. String = badge naranja `light` `small`. | Figma (badge=true) |
38
- | `href` | El item es un link: con ruta interna navega por el router; con `target="_blank"` abre otra pestaña con `rel` seguro. | propuesta, falta aprobación |
39
- | sin `href` | Es un `<button>`: navegas tú en `(clicked)`. | propuesta, falta aprobación |
38
+ | `href` | El item es un link: con ruta interna navega por el router; con `target="_blank"` abre otra pestaña con `rel` seguro. | según el código |
39
+ | sin `href` | Es un `<button>`: navegas tú en `(clicked)`. | según el código |
40
40
  | `active` | La sección actual (fondo gris, texto oscuro, ícono naranja y `aria-current="page"`). Uno solo por barra. | Figma (State=Active) |
41
41
 
42
42
  ## Tamaño en mobile y en web
@@ -46,11 +46,31 @@ topbar, que hoy es solo de escritorio.
46
46
 
47
47
  | uso | mobile | web | fuente |
48
48
  |---|---|---|---|
49
- | sección de la barra superior | no usar (no hay topbar en mobile) | tamaño único | propuesta, falta aprobación |
49
+ | sección de la barra superior | no usar (no hay topbar en mobile) | tamaño único | canon (aprobado por el dueño, 05-10-2026, bloque B7) |
50
50
 
51
51
  En mobile, 36 de alto queda por debajo del área táctil cómoda (44): si algún día se usa ahí, la
52
52
  barra tendría que darle más aire.
53
53
 
54
+ ### Por dispositivo (D16)
55
+
56
+ No aplica una tabla: no tiene input `size` y mide 36 de alto en todos los dispositivos. Como se toca
57
+ y no tiene un size que llegue a 44, B7 lo saca de todo lo táctil: en el celular chico, el celular y
58
+ la tablet táctil **no se usa**; solo en la computadora (`pointer: fine`) y en el ultrawide, igual
59
+ que en la computadora. La columna «mobile» de D16 incluye la tablet en lo que se toca, así que el
60
+ «no usar en mobile» de B7 la cubre.
61
+
62
+ Badges internos: el `count` va en `small` fijo (hardcodeado en el template, no se puede cambiar). El
63
+ `badge` cae en `small` cuando no se le pasa `size` (el shorthand string siempre); con
64
+ `SuiBadgeConfig` sí acepta `size`, y en la computadora va `medium`, que es lo que D16 da a lo que no
65
+ se toca (lo mismo que devuelve `bp.sizeBadge()` fuera del celular):
66
+ `[badge]="{ label: 'Nuevo', size: 'medium' }"`. Los dos `small` chocan con «nada en `small`» de D16:
67
+ cambiar el default del badge y el `count` fijo es código del DS, **pendiente** («internos del DS en
68
+ chico» en el doc de decisiones).
69
+
70
+ En master-pedidos: sin `[size]` ni helper; si algún día se monta, va detrás de `@if (!bp.tactil())`
71
+ (`isMobile() || toque()`: todo celular por ancho y toda pantalla táctil). No `!bp.isMobile()`: ese
72
+ es solo por ancho (≤ 768) y deja pasar un iPad de 769 a 1024 con `pointer: coarse`.
73
+
54
74
  ## API
55
75
 
56
76
  <!-- api:inicio -->
@@ -85,6 +105,47 @@ barra tendría que darle más aire.
85
105
  - `accent="information"` es el azul del Figma original: en esta app no se usa.
86
106
  - Ya trae el arreglo de iOS para el `:active` pegado.
87
107
 
108
+ ## Bien y mal
109
+
110
+ Pedidos por aceptar
111
+
112
+ ```html
113
+ <!-- ❌ mal: sin pendientes sale un «0» rojo; solo null lo oculta -->
114
+ <sui-topbar-item label="Pedidos" [count]="pendientes()" (clicked)="ir('pedidos')" />
115
+ ```
116
+
117
+ ```html
118
+ <!-- ✅ bien -->
119
+ <sui-topbar-item label="Pedidos" [count]="pendientes() || null" (clicked)="ir('pedidos')" />
120
+ ```
121
+
122
+ Un item que es link
123
+
124
+ ```html
125
+ <!-- ❌ mal: con href el item ya navega y (clicked) navega otra vez -->
126
+ <sui-topbar-item label="Reportes" href="/reportes" [active]="seccion() === 'reportes'"
127
+ (clicked)="router.navigateByUrl('/reportes')" />
128
+ ```
129
+
130
+ ```html
131
+ <!-- ✅ bien -->
132
+ <sui-topbar-item label="Reportes" href="/reportes" [active]="seccion() === 'reportes'" />
133
+ ```
134
+
135
+ Íconos en la barra
136
+
137
+ ```html
138
+ <!-- ❌ mal: unos con ícono y otros sin; se lee desordenado -->
139
+ <sui-topbar-item label="Tablero" icon="layout-grid-line" [active]="true" />
140
+ <sui-topbar-item label="Pedidos" />
141
+ ```
142
+
143
+ ```html
144
+ <!-- ✅ bien: todos sin ícono (el caso normal), o todos con -->
145
+ <sui-topbar-item label="Tablero" [active]="true" />
146
+ <sui-topbar-item label="Pedidos" />
147
+ ```
148
+
88
149
  ## Ejemplo
89
150
 
90
151
  ```html