@ajuarezso/sui-design-system 0.22.0 → 0.23.0

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 (99) hide show
  1. package/docs/INDEX.md +8 -8
  2. package/docs/sui-accordion/README.md +2 -2
  3. package/docs/sui-activity-feed/README.md +1 -2
  4. package/docs/sui-alert/README.md +28 -19
  5. package/docs/sui-app-store-badge/README.md +5 -4
  6. package/docs/sui-avatar/README.md +16 -16
  7. package/docs/sui-avatar-group/README.md +4 -4
  8. package/docs/sui-badge/README.md +27 -9
  9. package/docs/sui-banner/README.md +10 -9
  10. package/docs/sui-brand-logo/README.md +3 -3
  11. package/docs/sui-breadcrumbs/README.md +1 -1
  12. package/docs/sui-button/README.md +48 -24
  13. package/docs/sui-button-group/README.md +6 -4
  14. package/docs/sui-button-group-item/README.md +3 -3
  15. package/docs/sui-card/README.md +17 -19
  16. package/docs/sui-chart-legend/README.md +8 -7
  17. package/docs/sui-checkbox/README.md +11 -6
  18. package/docs/sui-checkbox-card/README.md +24 -19
  19. package/docs/sui-checkbox-label/README.md +32 -10
  20. package/docs/sui-circular-progress-bar/README.md +2 -0
  21. package/docs/sui-color-dot/README.md +1 -1
  22. package/docs/sui-color-picker/README.md +22 -7
  23. package/docs/sui-command-menu-footer/README.md +8 -8
  24. package/docs/sui-command-menu-search/README.md +2 -2
  25. package/docs/sui-compact-avatar-group/README.md +4 -3
  26. package/docs/sui-compact-button/README.md +41 -44
  27. package/docs/sui-compact-select/README.md +9 -5
  28. package/docs/sui-compact-select-for-input/README.md +2 -2
  29. package/docs/sui-content-card/README.md +6 -5
  30. package/docs/sui-content-divider/README.md +4 -4
  31. package/docs/sui-content-label/README.md +11 -6
  32. package/docs/sui-counter-input/README.md +19 -18
  33. package/docs/sui-date-selector/README.md +16 -12
  34. package/docs/sui-datepicker/README.md +46 -32
  35. package/docs/sui-day-cell/README.md +17 -8
  36. package/docs/sui-day-label/README.md +2 -2
  37. package/docs/sui-divider/README.md +5 -5
  38. package/docs/sui-drawer-footer/README.md +19 -5
  39. package/docs/sui-dropdown-search/README.md +3 -3
  40. package/docs/sui-emoji/README.md +6 -6
  41. package/docs/sui-empty-state/README.md +13 -23
  42. package/docs/sui-fancy-button/README.md +24 -18
  43. package/docs/sui-file-icon/README.md +1 -1
  44. package/docs/sui-file-upload/README.md +3 -0
  45. package/docs/sui-file-upload-card/README.md +8 -7
  46. package/docs/sui-filter/README.md +5 -5
  47. package/docs/sui-flag/README.md +3 -2
  48. package/docs/sui-form-hint/README.md +12 -8
  49. package/docs/sui-form-label/README.md +11 -16
  50. package/docs/sui-icon/README.md +4 -3
  51. package/docs/sui-image-upload/README.md +28 -16
  52. package/docs/sui-inline-input/README.md +7 -6
  53. package/docs/sui-inline-select/README.md +8 -5
  54. package/docs/sui-input/README.md +26 -35
  55. package/docs/sui-integration-switch/README.md +14 -7
  56. package/docs/sui-kbd/README.md +4 -4
  57. package/docs/sui-key-icon/README.md +6 -2
  58. package/docs/sui-link-button/README.md +21 -17
  59. package/docs/sui-modal-footer/README.md +1 -1
  60. package/docs/sui-notification/README.md +8 -6
  61. package/docs/sui-notification-footer/README.md +2 -2
  62. package/docs/sui-notification-tab-menu/README.md +5 -3
  63. package/docs/sui-pagination/README.md +8 -5
  64. package/docs/sui-password-strength/README.md +1 -1
  65. package/docs/sui-period-range/README.md +18 -14
  66. package/docs/sui-popover/README.md +13 -7
  67. package/docs/sui-product-card/README.md +14 -10
  68. package/docs/sui-progress-bar/README.md +4 -2
  69. package/docs/sui-progress-bar-label/README.md +2 -0
  70. package/docs/sui-radio/README.md +14 -7
  71. package/docs/sui-radio-card/README.md +12 -12
  72. package/docs/sui-radio-label/README.md +36 -11
  73. package/docs/sui-rating/README.md +28 -9
  74. package/docs/sui-rich-editor/README.md +3 -3
  75. package/docs/sui-segmented-control/README.md +32 -21
  76. package/docs/sui-select/README.md +35 -31
  77. package/docs/sui-sidebar/README.md +1 -2
  78. package/docs/sui-slider/README.md +7 -0
  79. package/docs/sui-social-button/README.md +24 -11
  80. package/docs/sui-status-badge/README.md +7 -3
  81. package/docs/sui-stepper/README.md +30 -17
  82. package/docs/sui-store-card/README.md +9 -4
  83. package/docs/sui-switch/README.md +16 -11
  84. package/docs/sui-switch-card/README.md +18 -16
  85. package/docs/sui-switch-label/README.md +22 -11
  86. package/docs/sui-tab-chips/README.md +55 -41
  87. package/docs/sui-tab-menu-horizontal/README.md +19 -11
  88. package/docs/sui-tab-menu-vertical/README.md +10 -5
  89. package/docs/sui-tag/README.md +25 -11
  90. package/docs/sui-tag-input/README.md +24 -14
  91. package/docs/sui-textarea/README.md +21 -21
  92. package/docs/sui-time-picker/README.md +38 -32
  93. package/docs/sui-toast/README.md +27 -22
  94. package/docs/sui-tooltip/README.md +14 -17
  95. package/docs/sui-topbar-button/README.md +2 -2
  96. package/fesm2022/ajuarezso-sui-design-system.mjs +1067 -236
  97. package/fesm2022/ajuarezso-sui-design-system.mjs.map +1 -1
  98. package/package.json +1 -1
  99. package/types/ajuarezso-sui-design-system.d.ts +601 -267
@@ -23,8 +23,8 @@ de pago · Repartidores»), el perfil del super admin.
23
23
  - 2 a 4 secciones arriba del contenido: `sui-tab-menu-horizontal`.
24
24
  - Filtros de una lista: `sui-tab-chips`.
25
25
 
26
- Regla corta: **secciones de una página de ajustes en web → tab menu vertical · en mobile → lista de
27
- filas que abren pantalla.**
26
+ Regla corta (propuesta, falta aprobación): **secciones de una página de ajustes en web → tab menu
27
+ vertical · en mobile → lista de filas que abren pantalla.**
28
28
 
29
29
  ## Qué variante usar
30
30
 
@@ -63,7 +63,8 @@ Usos de hoy que rompen las reglas: **0** (no se usa).
63
63
 
64
64
  ## Tamaño en mobile y en web
65
65
 
66
- Ítem de **36 px** (8 + 20 + 8), ícono de 20. **No tiene `size`** y no tiene tamaño para mobile.
66
+ Ítem de **36 px** (padding 8 + `line-height` 20 + padding 8; el ícono de 20 entra en la línea).
67
+ **No tiene `size`** y no tiene tamaño para mobile: no llega a los 44 px del dedo.
67
68
 
68
69
  | uso | mobile | web | fuente |
69
70
  |---|---|---|---|
@@ -114,12 +115,16 @@ type SuiTabMenuVerticalStyle = 'card' | 'list';
114
115
 
115
116
  ## Trampas
116
117
 
117
- - **El estilo se llama `menuStyle`**, no `style` ni `variant` (ni `verticalStyle`, que era el nombre
118
- viejo de `sui-tabs`).
118
+ - **El estilo se llama `menuStyle`**, no `style` ni `variant` (ni `verticalStyle`, el input de
119
+ `sui-tabs variant="vertical"`, el componente que existió hasta la v0.2.x y ya no está en el DS).
119
120
  - **Sin `active` no se marca ningún ítem.** Pásale un valor inicial.
120
121
  - **Ocupa el ancho del padre**: dale un ancho fijo a la columna (240-280 px).
121
122
  - **El ícono activo es naranja** (`primary-base`); en el tab menu horizontal es negro. Es a propósito.
122
123
  - **Emite dos veces**: `tabChange` y `activeChange`.
124
+ - **Teclado (04-10-2026):** `role="tablist"` con `aria-orientation="vertical"` y un solo tab
125
+ stop. ↑ ↓ mueven el foco **y activan**, con vuelta al inicio y saltando los deshabilitados;
126
+ Home/End a los extremos. Con `dividerLabel`, ese texto es el nombre del grupo
127
+ (`aria-labelledby`).
123
128
  - `role="tablist"`: si cada ítem navega a una ruta, el lector de pantalla lo anuncia mal; para
124
129
  navegación entre rutas, `sui-sidebar`.
125
130
 
@@ -2,7 +2,7 @@
2
2
  name: sui-tag
3
3
  selector: sui-tag
4
4
  resumen: Chip neutro que nombra algo elegido o aplicado y que la persona puede quitar
5
- alternativas: [sui-badge (etiqueta de solo lectura, con color y significado), sui-status-badge (resultado de un ciclo), sui-tab-chips / sui-filter (chips para elegir), sui-tag-input (campo que junta tags)]
5
+ alternativas: [sui-badge (etiqueta de solo lectura, con color y significado), sui-status-badge (resultado de un ciclo), sui-tab-chips (chips para elegir), sui-tag-input (campo que junta tags)]
6
6
  ---
7
7
 
8
8
  # sui-tag
@@ -22,12 +22,13 @@ El tag **no tiene color**: es siempre gris neutro, así que nunca dice un estado
22
22
  - Una etiqueta de solo lectura sin nada a la izquierda: `sui-badge` gray (más liviano, va al lado
23
23
  de un nombre).
24
24
  - Algo con significado de color (pendiente, error, nuevo): `sui-badge` o `sui-status-badge`.
25
- - **Elegir** entre opciones (chips que se prenden y apagan): `sui-tab-chips`, `sui-filter` o
26
- `sui-segmented-control`. El tag no tiene estado «seleccionado».
25
+ - **Elegir** entre opciones (chips que se prenden y apagan): `sui-tab-chips` o
26
+ `sui-segmented-control`. El tag no tiene estado «seleccionado». (`sui-filter` no es un chip: es
27
+ la barra y el panel de filtros de una tabla.)
27
28
  - Escribir varios valores en un campo: `sui-tag-input`.
28
29
 
29
30
  Regla corta: **se quita o lleva avatar/logo/bandera → tag · solo se lee → badge · se elige →
30
- tab-chips o filter.**
31
+ tab-chips o segmented-control.**
31
32
 
32
33
  ## Qué variante usar
33
34
 
@@ -73,13 +74,23 @@ de la app.
73
74
 
74
75
  | size | alto | texto | leading | X de quitar (área táctil) |
75
76
  |---|---|---|---|---|
76
- | `medium` (default) | 24 px | `label-xs` 12/16 | 16 | 16 (16) |
77
- | `large` | 32 px | `label-sm` 14/20 | 20 | 20 (32) |
78
- | `xlarge` | 40 px | `label-md` 16/24 | 20 | 24 (40) |
77
+ | `medium` (default) | 24 px | `label-xs` 12/16 | 16 | 16 (16×16) |
78
+ | `large` | 32 px | `label-sm` 14/20 | 20 | 20 (32×32) |
79
+ | `xlarge` | 40 px | `label-md` 16/24 | 20 | 24 (40×40; **44×44 en el teléfono**) |
79
80
 
80
- `medium` es el de Figma; `large` y `xlarge` son extensión SUI (03-10-2026), en la escala del
81
- `sui-button` (32 · 40). En los dos grandes la X tiene un área táctil invisible que llega al alto
82
- del tag, sin cambiar cómo se ve.
81
+ `medium` es el de Figma; `large` y `xlarge` son extensión SUI (03-10-2026). El **alto** sigue la
82
+ escala del `sui-button` (32 · 40); el **texto** sigue al `sui-badge` (14 en `large`, 16 en
83
+ `xlarge`) y no la regla general del 03-10-2026 (16 en los dos): excepción documentada, canon
84
+ (dueño, 04-10-2026) — la escala de badge (12/14/16) se mantiene.
85
+
86
+ En los dos grandes la X tiene un área táctil invisible (`::before` con `inset` −6 / −8) de
87
+ 32×32 y 40×40. En el teléfono (≤ 767 px) la de `xlarge` sube a **44×44** (`inset` −10): canon (dueño, 04-10-2026): piso táctil 44 en el teléfono.
88
+ No hace falta un size nuevo: el tag ya mide 40 y lo que se toca es la X. El área sobresale 2 px
89
+ arriba y abajo del tag; el dibujo no cambia.
90
+
91
+ Hasta el 04-10-2026 el host llevaba `overflow: clip` y recortaba esa área a la caja interior
92
+ (30 / 38). El recorte pasó al label (`.sui-tag__label`): un texto largo en un tag con ancho
93
+ máximo se sigue cortando, y la X queda siempre visible.
83
94
 
84
95
  | uso | mobile | web | fuente |
85
96
  |---|---|---|---|
@@ -124,10 +135,13 @@ Slots: `[data-slot=start]` (avatar, logo, bandera o ícono de 16 px) y `<ng-cont
124
135
  - El estilo se llama **`tagStyle`** (en badge es `variant`, en status-badge `appearance`).
125
136
  - **No tiene `color`**. Si hace falta color, no es un tag.
126
137
  - El tag no saca nada de la lista: `(dismiss)` avisa y la pantalla lo quita.
138
+ - **`interactive` lo vuelve botón** (desde el 04-10-2026): `role="button"`, entra al Tab y
139
+ Enter/Espacio hacen click. Antes solo prendía los estilos de hover y el tag no se alcanzaba con
140
+ teclado. No lo combines con `dismissible`: quedaría la X (otro botón) dentro del botón.
127
141
  - `disabled` bloquea también la X.
128
142
  - Un avatar o una bandera proyectados no se ponen grises con `disabled`: los atenúa la pantalla.
129
143
  - `sui-avatar` no tiene 16 px: el `xs` (20) se escala por CSS dentro del slot.
130
- - Radio de 6 px, 24 px de alto, sin mayúsculas: no es un badge (radio completo).
144
+ - Radio de 6 px, 24 px de alto en `medium`, sin mayúsculas: no es un badge (radio completo).
131
145
 
132
146
  ## Ejemplo
133
147
 
@@ -28,14 +28,14 @@ Regla corta: **varios valores libres → tag-input · varias opciones fijas →
28
28
  > **En la guía del DS es un ejemplo de su página del input** («With Tags»: un campo con los chips
29
29
  > Berlin, London, Paris debajo). No dice cuándo usarlo.
30
30
  >
31
- > Uso medido el 03-10-2026 en `master-pedidos/src/app`: **0 usos**. Candidato: «Rubros que entran»
32
- > en `pages/super-admin/master-settings/master-settings.html:134`, un `sui-input` donde se escriben
31
+ > Uso medido el 04-10-2026 en `master-pedidos/src/app`: **0 usos**. Candidato: «Rubros que entran»
32
+ > en `pages/super-admin/master-settings/master-settings.html:136`, un `sui-input` donde se escriben
33
33
  > palabras separadas por coma («ferreteria, ferretería, construcción») y la pantalla las parte a mano.
34
34
 
35
35
  | prop / evento | cuándo | fuente |
36
36
  |---|---|---|
37
37
  | `label` · `required` · `sublabel` · `tooltip` · `hint` | Igual que `sui-input`. El hint dice cómo se agrega: «Escribe y presiona Enter». | según la guía del DS (ejemplo con label «Tag Input») |
38
- | `placeholder` | **Siempre**: el default es «Add tags...». «Agrega una palabra…». | propuesta, falta aprobación |
38
+ | `placeholder` | **Siempre** que el default genérico («Agrega una etiqueta…», 04-10-2026) no diga qué se agrega: «Agrega una palabra…». | propuesta, falta aprobación |
39
39
  | `commaSeparator` | `true` cuando la gente ya escribe con comas (rubros, sinónimos). | propuesta, falta aprobación |
40
40
  | `addOnBlur` | `true` en mobile: si sale del campo sin Enter, lo escrito no se pierde. | propuesta, falta aprobación |
41
41
  | `maxTags` | Cuando hay un tope real. Hoy no hay. | propuesta, falta aprobación |
@@ -47,27 +47,35 @@ Regla corta: **varios valores libres → tag-input · varias opciones fijas →
47
47
 
48
48
  ## Tamaño en mobile y en web
49
49
 
50
- Publicado (0.19.0): `xsmall` (32), `small` (36), `medium` (40). **En el repo del DS, sin publicar:**
51
- `large` (48) y `xlarge` (52), los mismos altos de `sui-input`, y el texto a 16 px en mobile (en
52
- 0.19.0 queda en 14). Los chips de abajo son `sui-tag` de tamaño fijo: **la ✕ para quitar un chip
53
- no crece** con el campo.
50
+ Tiene `xsmall` (32), `small` (36), `medium` (40), `large` (48) y `xlarge` (52), los mismos altos de
51
+ `sui-input` (los cinco publicados; la app usa 0.22.0). En mobile (≤ 767 px) lo que se escribe va en
52
+ 16 px en cualquier tamaño, como en `sui-input`. Los chips de abajo son `sui-tag` y, desde el
53
+ 04-10-2026 (canon (dueño, 04-10-2026): piso táctil 44 en el teléfono), **acompañan al campo**:
54
54
 
55
- En large y xlarge el texto sube a 16 px (regla del 03-10-2026): lo que se escribe va en 16/24 también
56
- en web; el alto sigue en 48/52. Los chips de abajo no cambian.
55
+ | size del campo | chip | X para quitar (área táctil) |
56
+ |---|---|---|
57
+ | `xsmall` · `small` · `medium` | `medium` (24) | 16 × 16 |
58
+ | `large` | `large` (32) | 20 (32 × 32) |
59
+ | `xlarge` | `xlarge` (40) | 24 (40 × 40; **44 × 44 en el teléfono**) |
60
+
61
+ Antes los chips iban siempre en `medium` y la ✕ medía 16 aunque el campo fuera grande.
62
+
63
+ En large y xlarge el texto sube a 16 px (canon, aprobado por el dueño el 03-10-2026): lo que se escribe va en 16/24 también
64
+ en web; el alto sigue en 48/52.
57
65
 
58
66
  | uso | mobile | web | fuente |
59
67
  |---|---|---|---|
60
- | campo de formulario | `large` (48) **cuando se publique**; hasta entonces `medium` (40) | `medium` (40) | propuesta, falta aprobación |
68
+ | campo de formulario | `xlarge` (52, chips de 40 con X tocable en 44) | `medium` (40) | canon (dueño, 04-10-2026): piso táctil 44 en el teléfono (el 44 lo da la X del chip `xlarge`) |
61
69
 
62
70
  ```html
63
- <sui-tag-input [size]="bp.isMobile() ? 'large' : 'medium'" … /> <!-- 'large' desde la próxima versión -->
71
+ <sui-tag-input [size]="bp.isMobile() ? 'xlarge' : 'medium'" … /> <!-- bp = BreakpointsService -->
64
72
  ```
65
73
 
66
74
  ## «No usar»: por qué no hoy y cuándo sí
67
75
 
68
76
  | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
69
77
  |---|---|---|
70
- | el componente entero (0 usos) | nadie carga listas de palabras | «Rubros que entran» de una categoría del home (`master-settings.html:134`), o sinónimos de un producto para el buscador |
78
+ | el componente entero (0 usos) | nadie carga listas de palabras | «Rubros que entran» de una categoría del home (`master-settings.html:136`), o sinónimos de un producto para el buscador |
71
79
  | `rightIcon` | el hint explica mejor | — |
72
80
  | `maxTags` | no hay topes | un máximo de 5 palabras clave por producto |
73
81
  | `allowDuplicates` | repetir no sirve | — |
@@ -81,7 +89,7 @@ en web; el alto sigue en 48/52. Los chips de abajo no cambian.
81
89
  | input | tipo | default |
82
90
  |---|---|---|
83
91
  | `size` | `'xsmall' \| 'small' \| 'medium' \| 'large' \| 'xlarge'` | `'medium'` |
84
- | `placeholder` | `string` | `'Add tags...'` |
92
+ | `placeholder` | `string` | `'Agrega una etiqueta…'` |
85
93
  | `disabled` | `boolean` | `false` |
86
94
  | `error` | `boolean` | `false` |
87
95
  | `errorMessage` | `string \| null` | `null` |
@@ -108,11 +116,13 @@ no es parte del valor. Slot `[slot=right]` para un contenido propio a la derecha
108
116
 
109
117
  ## Trampas
110
118
 
111
- - **Placeholder en inglés por default** («Add tags...»). Pásalo siempre.
119
+ - El placeholder por default es genérico («Agrega una etiqueta…», en español desde el 04-10-2026).
112
120
  - Sin `commaSeparator` la coma es un carácter más: «a, b» queda como un solo chip.
113
121
  - Sin `addOnBlur`, lo que se escribió y no se confirmó con Enter se pierde al salir.
114
122
  - Los chips van **debajo** del campo, no adentro.
115
123
  - El hover quita el borde (a diferencia de `sui-input`, que lo oscurece).
124
+ - **Accesibilidad (04-10-2026)**: el control trae su `id`; el `label` interno apunta a él con `for`,
125
+ el hint o el error se enlazan con `aria-describedby` y `error` pone `aria-invalid`.
116
126
 
117
127
  ## Ejemplo
118
128
 
@@ -17,11 +17,13 @@ comentario al calificar.
17
17
 
18
18
  **No lo uses** para:
19
19
 
20
- - Un dato de una línea (nombre, referencia corta, URL, un slug): `sui-input`. Hoy hay uno así:
21
- «Personaliza tu url» en `pages/mi-negocio/mi-negocio.html:706`.
20
+ - Un dato de una línea (nombre, referencia corta, URL, un slug): `sui-input`. Hoy hay 4 así:
21
+ «Personaliza tu url» en `pages/mi-negocio/mi-negocio.html:713` (a propósito, para que envuelva en
22
+ mobile, según su comentario) y 3 URL de imagen: `pages/mi-negocio/mi-negocio.html:534`, `:588` y
23
+ `components/add-product-modal/add-product-modal.html:72`.
22
24
  - Un motivo que se puede elegir de una lista cerrada: radios o `sui-select`, y la opción «Otro»
23
- abre el textarea (como ya hace `pages/envios/envios.html:819`, que además corta a 200 a mano con
24
- `.slice(0, 200)` en vez de `[maxLength]="200"`).
25
+ abre el textarea (como ya hace `pages/envios/envios.html:822`, con `[maxLength]="200"`; el
26
+ `.slice(0, 200)` del `(valueChange)` sobra).
25
27
  - Texto con negritas o enlaces: no hay caso hoy (ver `sui-rich-editor`).
26
28
  - Un `<textarea>` nativo: queda **1** (`pages/products/add-product/add-product.html:155`).
27
29
 
@@ -32,9 +34,9 @@ Regla corta: **se redacta y puede pasar de una línea → textarea · una línea
32
34
  > **La guía del DS lo presenta con contador de caracteres y su propia manija para agrandarlo**
33
35
  > («78/200»), y aparte una versión simple sin contador. No dice cuándo va cada una.
34
36
  >
35
- > Uso medido el 03-10-2026 en `master-pedidos/src/app` (misma exclusión que `sui-badge`, más
36
- > `master-ejercicios`): **50 usos en 29 archivos**. `rows`: 32 en 3, 13 en 2, 4 en 4, 1 en 8.
37
- > Con `maxLength`: 8. Con `resizable=false`: 2. 38 con label, 12 sin.
37
+ > Uso medido el 04-10-2026 en `master-pedidos/src/app` (misma exclusión que `sui-badge`, más
38
+ > `master-ejercicios`): **50 usos en 29 archivos**. `rows`: 30 en 3, 13 en 2, 4 en 4, 1 en 8 y 2 sin
39
+ > `rows` (default 4). Con `maxLength`: 43. Con `resizable=false`: 2. 38 con label, 12 sin. Con `size`: 0.
38
40
 
39
41
  | prop | cuándo | fuente |
40
42
  |---|---|---|
@@ -47,25 +49,21 @@ Regla corta: **se redacta y puede pasar de una línea → textarea · una línea
47
49
  | `placeholder` | Un ejemplo de lo que se espera: «Ej. frágil, tocar el timbre, entregar en recepción». Elipsis `…`. | canon (CANON-SUI §5.2) |
48
50
  | `maxLength` | **Siempre que otro lo va a leer** (cliente, repartidor, local) o se guarda en la base: muestra «n/200» y corta el exceso. 200 para motivos y notas; 500 para descripciones. | según la guía del DS (su ejemplo principal lleva contador); los topes son propuesta |
49
51
  | `size` | El mismo de los inputs del formulario: `large` en mobile, `medium` en web. Ver «Tamaño en mobile y en web». | canon (aprobado por el dueño, 03-10-2026), extensión SUI; el «cuándo» es propuesta, falta aprobación |
50
- | `rows` | `3` por defecto (motivos, notas). `2` para una nota corta en un formulario largo. `4` o más solo para una descripción larga. | propuesta, falta aprobación |
52
+ | `rows` | `3` para motivos y notas (el default del componente es `4`). `2` para una nota corta en un formulario largo. `4` o más solo para una descripción larga. | propuesta, falta aprobación |
51
53
  | `resizable` | `true` en web. En mobile **`false`**: la manija no se puede arrastrar con el dedo y parece un adorno. | según la guía del DS (versión con y sin manija); el «cuándo» es propuesta |
52
54
  | `readonly` | Mostrar un texto ya enviado con la misma forma del campo (copiar un mensaje). | propuesta, falta aprobación |
53
55
  | `disabled` | Mientras se envía. | según la guía del DS |
54
56
  | `autocomplete` | No hace falta: ningún texto libre se autocompleta. | propuesta, falta aprobación |
55
57
 
56
- **Usos de hoy que rompen la regla:**
58
+ **Usos de hoy que rompen la regla** (medido el 04-10-2026; los `sublabel` sin paréntesis, los
59
+ «(opcional)» en el label y los placeholders con `...` ya se corrigieron en la app, commits
60
+ `ce4a2d12` y `e0470b34`, y 35 textos pasaron a tener `maxLength` en `d14694fd`):
57
61
 
58
- - **3 `sublabel="Opcional"` sin paréntesis** (se lee «Notas adicionalesOpcional») → «(Opcional)»:
59
- `pages/customer/checkout/checkout.html:209`, `pages/self-delivery/self-delivery.html:101`,
60
- `components/add-product-modal/add-product-modal.html:184`.
61
- - **9 «(opcional)» dentro del label** → `sublabel="(Opcional)"`: `pages/super-admin/super-admin.html:333`
62
- («Notas (opcional)»), `pages/super-admin/master-orders/master-orders.html:795`,
63
- `components/cuenta-bloqueada/cuenta-bloqueada.html:21`.
64
- - **Textos que lee otra persona sin `maxLength`** (42 de 50 no lo tienen). Los que más importan:
65
- `pages/envios/envios.html:419` («Nota para el repartidor»), `pages/customer/checkout/checkout.html:209`
66
- («Notas adicionales»), `pages/super-admin/master-users/master-users.html:266` («Motivo (lo va a leer)»).
67
- - **4 placeholders con `...`**: `pages/customer/checkout/checkout.html:209`,
68
- `pages/self-delivery/self-delivery.html:101`, `pages/driver/driver-order-detail/driver-order-detail.html:823`.
62
+ - **7 sin `maxLength`**: 4 son las URL de una línea de arriba y 1 es de solo lectura
63
+ (`components/copy-text-dialog/copy-text-dialog.html:9`); quedan 2 «Notas» que se guardan en la base:
64
+ `pages/super-admin/super-admin.html:334`, `pages/super-admin/master-gastos/master-gastos.html:228`.
65
+ - **Ninguno lleva `size`**: los 50 quedan en `medium` también en el teléfono, aunque los inputs del
66
+ mismo formulario ya vayan en `large`.
69
67
 
70
68
  ## Tamaño en mobile y en web
71
69
 
@@ -87,7 +85,7 @@ evita el zoom de iOS al enfocar y el textarea deja de verse más chico que los c
87
85
  eso cada fila mide 24 px en el teléfono y 20 en web (3 filas ≈ 72 + padding en mobile, 60 + padding
88
86
  en web): el área que se toca siempre pasa los 44 px.
89
87
 
90
- En large y xlarge el texto sube a 16 px (regla del 03-10-2026): en esos dos tamaños va en 16/24
88
+ En large y xlarge el texto sube a 16 px (canon, aprobado por el dueño el 03-10-2026): en esos dos tamaños va en 16/24
91
89
  también en web, así que cada fila mide 24 en las dos plataformas.
92
90
 
93
91
  | uso | mobile | web | fuente |
@@ -146,6 +144,8 @@ Outputs: ninguno.
146
144
  - El hint lleva siempre el ícono `information-fill`, también el neutro (así está en el Figma).
147
145
  - El `size` no cambia el alto: eso lo deciden las `rows`. Lo que alinea con el input es el padding.
148
146
  - `error` sin `errorMessage` pinta el borde y no dice qué falta.
147
+ - **Accesibilidad (04-10-2026)**: el control trae su `id`; el `label` interno apunta a él con `for`,
148
+ el hint o el error se enlazan con `aria-describedby` y `error` pone `aria-invalid`.
149
149
 
150
150
  ## Ejemplo
151
151
 
@@ -20,7 +20,7 @@ cierre del local, el turno del repartidor, «Cerrar hasta las 9:30 PM».
20
20
  **franja** que el local puede cumplir. Va la hoja del checkout (`sui-tab-chips` para el día y
21
21
  `sui-radio-label` con `flip` para cada franja). Es la maqueta aprobada, y el propio código
22
22
  descartó `sui-time-picker-item` para esas filas porque son densas y sin separación
23
- (`checkout.html:475`).
23
+ (`checkout.html:469`).
24
24
  - Pocas horas fijas («12:00», «13:00», «14:00»): `sui-select`.
25
25
  - Una duración («30 min», «1 h»): no hay componente de duración; un `sui-select` o
26
26
  `sui-tab-chips` con los valores (ver Trampas: los presets de este componente no son duraciones).
@@ -44,23 +44,23 @@ pocas horas → select.**
44
44
  | valor | cuándo | fuente |
45
45
  |---|---|---|
46
46
  | `12h` (default) | Siempre: en Perú la hora se dice «9:30 PM». Los 7 usos lo llevan. | propuesta |
47
- | `24h` | No usar en la app. | no usar |
47
+ | `24h` | No usar en la app. | propuesta |
48
48
 
49
49
  ### `step`
50
50
 
51
51
  | valor | cuándo | fuente |
52
52
  |---|---|---|
53
- | `5` (default) | Horas reales que la persona conoce al minuto: apertura y cierre del local, «cerrar hasta». Con saltos de 30 se redondeaban cierres reales (comentario en `weekly-schedule-editor.html:41`). | propuesta |
54
- | `30` | Bloques de un turno, que se planifican por media hora (`driver-schedule.html:142`). | propuesta |
53
+ | `5` (default) | Horas reales que la persona conoce al minuto: apertura y cierre del local, «cerrar hasta». Con saltos de 30 se redondeaban cierres reales (comentario en `weekly-schedule-editor.html:37`). | propuesta |
54
+ | `30` | Bloques de un turno, que se planifican por media hora (`driver-schedule.html:140`). | propuesta |
55
55
  | `15` | Citas o reservas en cuartos de hora. Sin caso hoy. | propuesta |
56
- | `1` | No usar: 60 opciones en la columna para una precisión que nadie pide. | no usar |
56
+ | `1` | No usar: 60 opciones en la columna para una precisión que nadie pide. | propuesta |
57
57
 
58
58
  ### `durationPresets`, `showFooter`, `inline`
59
59
 
60
60
  | input | valor | cuándo | fuente |
61
61
  |---|---|---|---|
62
- | `durationPresets` | `[]` | **Siempre.** Los presets de fábrica (15 min, 30 min, 45 min, 1 h) ponen la hora como «tiempo desde la medianoche»: «30 min» deja 12:30 AM. Los 7 usos los apagan. | propuesta |
63
- | `durationPresets` | lista propia | No usar mientras se lean como hora del día. | no usar |
62
+ | `durationPresets` | `[]` (default desde el 04-10-2026) | **Siempre.** Los presets (15 min, 30 min, 45 min, 1 h) ponen la hora como «tiempo desde la medianoche»: «30 min» deja 12:30 AM. Por eso el default pasó a `[]`; los 7 usos de la app ya los apagaban. | propuesta |
63
+ | `durationPresets` | lista propia | No usar mientras se lean como hora del día. | propuesta |
64
64
  | `showFooter` | `true` (default) | Cancelar/Aplicar: la hora no cambia hasta confirmar. Es lo correcto cuando la hora se guarda o publica algo (el horario del local). | propuesta |
65
65
  | `showFooter` | `false` | Se aplica al tocar cada columna. Solo dentro de un formulario que ya tiene su propio «Guardar». | propuesta |
66
66
  | `inline` | `true` | El panel es el contenido, dentro de un `sui-modal` (sin campo ni popover). | propuesta |
@@ -69,7 +69,7 @@ pocas horas → select.**
69
69
 
70
70
  | input | cuándo | fuente |
71
71
  |---|---|---|
72
- | `size="medium"` (40 px, default) | Siempre: es el más grande que hay (ver «Tamaño»). | propuesta |
72
+ | `size="medium"` (40 px, default) | Web. En mobile va `large` (48), que existe desde el 03-10-2026 (ver «Tamaño»). | propuesta |
73
73
  | `size="small"` (36 px) | Filas densas en web. | propuesta |
74
74
  | `label` | Siempre, corto y en verbo o momento: «Abre», «Cierra», «Inicio», «Cerrar hasta». | propuesta |
75
75
  | `sublabel` / `tooltip` | «Opcional» o una aclaración que no entra en el label. | propuesta |
@@ -79,15 +79,18 @@ pocas horas → select.**
79
79
  | `disabled` | Mientras se guarda (como hacen el horario y los turnos). | propuesta |
80
80
  | `placeholder` | Lo que se elige: «Hora de cierre». El default «Seleccionar hora» sirve. | propuesta |
81
81
 
82
- Usos de hoy que rompen la regla: **0**. Los 7 cumplen `12h`, `durationPresets=[]` y `label`.
82
+ Usos de hoy que rompen la regla: los 7 cumplen `12h`, `durationPresets=[]` y `label`, pero **los 7
83
+ van con `size="medium"` fijo**, también en pantallas del teléfono (turnos y votaciones del
84
+ repartidor): campo de 40, contra el `large` de la tabla de «Tamaño». Cancelar / Aplicar ya salen en
85
+ 48 en el teléfono desde el 04-10-2026 (el componente los fuerza en mobile).
83
86
 
84
87
  ### Las piezas que trae (exportadas, sin carpeta ni story propias)
85
88
 
86
89
  | pieza | qué es | cuándo suelta | fuente |
87
90
  |---|---|---|---|
88
- | `sui-time-picker-item` | una fila de la columna (36 px) | No usar: para filas de horario que se tocan con el pulgar va `sui-radio-label` (`checkout.html:475`). | no usar |
89
- | `sui-time-picker-duration` | la pastilla de un preset | No usar: es la de los presets de duración. | no usar |
90
- | `sui-time-picker-status` | pastilla Disponible/Ocupado/En reunión/Desconectado | No usar: sus textos de fábrica están en inglés y el estado del repartidor ya tiene su badge. | no usar |
91
+ | `sui-time-picker-item` | una fila de la columna (36 px) | No usar: para filas de horario que se tocan con el pulgar va `sui-radio-label` (`checkout.html:469`). | propuesta |
92
+ | `sui-time-picker-duration` | la pastilla de un preset | No usar: es la de los presets de duración. | propuesta |
93
+ | `sui-time-picker-status` | pastilla Disponible/Ocupado/En reunión/Desconectado | No usar: el estado del repartidor ya tiene su badge. | propuesta |
91
94
 
92
95
  ## Tamaño en mobile y en web
93
96
 
@@ -95,23 +98,25 @@ En mobile se toca con el dedo: lo que se toca mide **44 px o más**. En web, con
95
98
  chico. En pantallas de los dos se elige con el servicio de breakpoints de la app (`bp`, en
96
99
  `services/breakpoints.service.ts`).
97
100
 
98
- `size` tiene `small` (36), `medium` (40, default) y **`large` (48)**, extensión SUI: mide lo mismo
99
- que `sui-input` y `sui-select` `large`, que van al lado en los formularios de horario. Con `large`
100
- el panel también crece: **filas de 44** y **Cancelar / Aplicar en `large` (48)**. En mobile
101
- (≤ 767 px) las filas miden 44 con cualquier `size`.
101
+ `size` tiene `small` (36), `medium` (40, default), **`large` (48)**, extensión SUI: mide lo mismo
102
+ que `sui-input` y `sui-select` `large`, que van al lado en los formularios de horario, y **`xlarge`
103
+ (52)**, el de `sui-input` `xlarge`. Con `large` y `xlarge` el panel también crece: **filas de 44** y
104
+ **Cancelar / Aplicar en `large` (48)**. En mobile (≤ 767 px), con cualquier `size`, las filas miden
105
+ 44 y **Cancelar / Aplicar van en `large`** (fix 04-10-2026: antes, con el campo en `medium`, el pie
106
+ quedaba en 36; ahora hace lo mismo que el `sui-datepicker`).
102
107
 
103
- | pieza | `small` · `medium` en web | `large` | mobile (cualquier size) | fuente |
104
- |---|---|---|---|---|
105
- | campo (trigger) | 36 · 40 | 48 | el del `size` | 36/40: medido · 48: canon (aprobado por el dueño, 03-10-2026), extensión SUI |
106
- | fila de la columna | 36 | 44 | 44 | 36: Figma · 44: canon (aprobado por el dueño, 03-10-2026), extensión SUI |
107
- | Cancelar / Aplicar | 36 | 48 | el del `size` | canon (aprobado por el dueño, 03-10-2026), extensión SUI |
108
+ | pieza | `small` · `medium` en web | `large` | **`xlarge`** | mobile (cualquier size) | fuente |
109
+ |---|---|---|---|---|---|
110
+ | campo (trigger) | 36 · 40 | 48 | **52** | el del `size` | 36/40: medido · 48: canon (aprobado por el dueño, 03-10-2026), extensión SUI · 52: canon (dueño, 04-10-2026): piso táctil 44 en el teléfono |
111
+ | fila de la columna | 36 | 44 | 44 | 44 | 36: Figma · 44: canon (aprobado por el dueño, 03-10-2026), extensión SUI |
112
+ | Cancelar / Aplicar | 36 | 48 | 48 | **48** | 48 en large: canon (aprobado por el dueño, 03-10-2026) · 48 en mobile con cualquier size: canon (dueño, 04-10-2026): piso táctil 44 en el teléfono |
108
113
 
109
- En large y xlarge el texto sube a 16 px (regla del 03-10-2026): con `large`, la hora del campo y la
110
- de las filas van en 16/24; la fila sigue en 44 (el padding bajó de 12 a 10).
114
+ En large y xlarge el texto sube a 16 px (regla del 03-10-2026): con `large` y `xlarge`, la hora del
115
+ campo y la de las filas van en 16/24; la fila sigue en 44 (el padding bajó de 12 a 10).
111
116
 
112
117
  | uso | mobile | web | fuente |
113
118
  |---|---|---|---|
114
- | horario en un formulario | `large` | `medium`, o `small` en filas densas | propuesta, falta aprobación |
119
+ | horario en un formulario | `large` (48) o `xlarge` (52) si va junto a campos xlarge | `medium`, o `small` en filas densas | mobile: canon (dueño, 04-10-2026): piso táctil 44 en el teléfono · web: propuesta, falta aprobación |
115
120
 
116
121
  ```html
117
122
  <sui-time-picker label="Cierra" format="12h" [step]="5" [durationPresets]="[]"
@@ -131,7 +136,7 @@ en la columna de la derecha, se usa (aprobado por el dueño, 03-10-2026).
131
136
  | `durationPresets` (cualquiera) | se leen como hora desde la medianoche, no como duración | si el DS los cambia para sumar sobre la hora elegida («en 30 min») |
132
137
  | `sui-time-picker-item` suelto | fila de 36 px, densa | una lista desplegable de horas en web |
133
138
  | `sui-time-picker-duration` suelto | es parte de los presets | — |
134
- | `sui-time-picker-status` | textos en inglés; el estado del repartidor ya tiene su badge | un panel de disponibilidad del equipo del local, con los textos en español |
139
+ | `sui-time-picker-status` | el estado del repartidor ya tiene su badge | un panel de disponibilidad del equipo del local |
135
140
 
136
141
  ## API
137
142
 
@@ -151,10 +156,10 @@ en la columna de la derecha, se usa (aprobado por el dueño, 03-10-2026).
151
156
  | `error` | `boolean` | `false` |
152
157
  | `placeholder` | `string` | `'Seleccionar hora'` |
153
158
  | `disabled` | `boolean` | `false` |
154
- | `size` | `'small' \| 'medium' \| 'large'` | `'medium'` |
159
+ | `size` | `'small' \| 'medium' \| 'large' \| 'xlarge'` | `'medium'` |
155
160
  | `format` | `'12h' \| '24h'` | `'12h'` |
156
161
  | `step` | `number` | `5` |
157
- | `durationPresets` | `readonly SuiTimeDurationPreset[]` | `DEFAULT_DURATION_PRESETS` |
162
+ | `durationPresets` | `readonly SuiTimeDurationPreset[]` | `[]` |
158
163
  | `inline` | `boolean` | `false` |
159
164
  | `showFooter` | `boolean` | `true` |
160
165
  | `value` · model, `[(value)]` | `SuiTimeValue \| null` | `null` |
@@ -213,16 +218,17 @@ interface SuiTimeDurationPreset { label: string; minutes: number; }
213
218
 
214
219
  ## Trampas
215
220
 
216
- - **Los presets de duración no son duraciones**: «30 min» pone la hora en 00:30 (12:30 AM). Por eso
217
- se pasan siempre `[durationPresets]="[]"`. Sin eso, el panel muestra cuatro pastillas que
218
- rompen la hora.
221
+ - **Los presets de duración no son duraciones**: «30 min» pone la hora en 00:30 (12:30 AM). Desde
222
+ el 04-10-2026 el default es `[]` y el panel no los muestra; pasarlos (`DEFAULT_DURATION_PRESETS`
223
+ sigue exportado) los vuelve a poner con ese mismo comportamiento.
219
224
  - **`value.hours` va de 0 a 23** aunque se muestre en 12h: 9:30 PM es `{ hours: 21, minutes: 30 }`.
220
225
  - **Al abrir sin valor arranca en 9:00 AM**, no vacío.
221
226
  - **Cerrar con clic afuera o Escape descarta** lo elegido, igual que Cancelar.
222
227
  - Con `step` que no contiene el minuto guardado (21:37 con step 5), la columna de minutos no
223
228
  marca ninguno.
224
- - Cancelar / Aplicar solo crecen con `size="large"`: con `medium` en mobile siguen en 36. En el
225
- teléfono va `large`.
229
+ - Cancelar / Aplicar van en `large` (48) con `size="large"`/`"xlarge"` y, desde el 04-10-2026,
230
+ siempre en mobile (≤ 767 px), igual que el `sui-datepicker`. En web con `small`/`medium`
231
+ siguen en 36.
226
232
  - El panel flota con el overlay del DS (como `sui-select`): se da vuelta si no entra abajo.
227
233
  - `sui-time-picker-status` dice «Disponible», «Ocupado», «En reunión» y «Desconectado» por
228
234
  defecto (antes venían en inglés del Figma); `label` sigue sirviendo para cambiarlo.
@@ -39,9 +39,9 @@ toast · bandeja → notification.**
39
39
  > DS» sale de su texto o de su código publicado; «canon» es lo ya aprobado (README de `sui-alert`,
40
40
  > `docs/CANON-SUI.md` o un pedido del dueño escrito en el código); el resto es **propuesta**.
41
41
  >
42
- > Uso medido el 03-10-2026 en `master-pedidos/src/app` (sin prototipos, vitrinas ni tests):
43
- > **~700 llamadas en 106 archivos**; de ellas, **560 con título fijo** (en 102 archivos) — 348 `error`,
44
- > 179 `success`, 23 `info`, 10 `warning`, 0 `feature` — más 3 `show()`. El resto arma el título con variables.
42
+ > Uso medido el 04-10-2026 en `master-pedidos/src/app` (sin prototipos, vitrinas ni tests):
43
+ > **705 llamadas en 108 archivos**, todas con el `SuiToastService` de la copia local. El desglose
44
+ > por tipo está abajo, en «Usos de hoy que rompen la regla».
45
45
 
46
46
  ### Lo que sí dice la guía del DS
47
47
 
@@ -93,21 +93,21 @@ toast · bandeja → notification.**
93
93
 
94
94
  ### Usos de hoy que rompen la regla
95
95
 
96
- - **Rompen el canon — 3 toasts de error que no se van y no tienen acción → `sui-alert`** en el
97
- modal de eliminar cuenta: `pages/empresa/about/about.ts:103`, `pages/repartidor/about/about.ts:97`,
98
- `pages/customer/about/about.ts:135` («No puedes eliminar tu cuenta» + el motivo, `duration: Infinity`).
99
- - **Rompen el canon de copy — 104 errores que empiezan con «Error…»** («Error al cargar productos»)
100
- → «No se pudo…»: `pages/products/products.ts:415`, `pages/customers/customers.ts:244`,
101
- `pages/settings/team/team.ts:315`. Y **26** que concatenan `e.message` al texto (puede salir
102
- texto técnico o en inglés).
103
- - **Rompen el canon de copy — 5 títulos en minúscula:** `pages/driver/driver-profile/driver-profile.ts:538`
104
- («ubicación activada»), `:552`, `:597`, `:614`, `pages/driver/driver-order-detail/driver-order-detail.ts:438`.
105
- - **Romperían la propuesta — 47 errores al cargar como toast** → alert o empty state con
106
- «Reintentar»: `pages/products/products.ts:415`, `pages/driver/driver-history/driver-history.ts:198`.
107
- - **Romperían la propuesta — 126 títulos con punto final**, casi todos dos frases en una →
108
- título + `description`: `components/map-picker-modal/map-picker-modal.ts:260` («Permiso denegado.
109
- Usa la barra de búsqueda…»), `core/services/compartir-viaje.service.ts:78`. 62 pasan de 60
110
- caracteres.
96
+ Medido de nuevo el 04-10-2026: 705 llamadas en 108 archivos. Con el título escrito entre comillas
97
+ simples: 328 `error`, 123 `success`, 18 `info`, 5 `warning`, 0 `feature`, más 3 `show()`; el resto
98
+ arma el título con variables. La pasada de copy del 03-10-2026 en la app ya corrigió casi todos los
99
+ «Error al…», los títulos en minúscula, los títulos con punto final y los 3 toasts sin acción y con
100
+ `duration: Infinity` de «Acerca de» (ahora duran 6 s). Queda:
101
+
102
+ - **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
+ - **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`).
108
+ - **Romperían la propuesta — 57 errores al cargar como toast** («No se pudo cargar…») → alert o
109
+ empty state con «Reintentar»: `pages/driver/driver-history/driver-history.ts:200`,
110
+ `pages/settings/team/team.ts:307`.
111
111
 
112
112
  ## Tamaño en mobile y en web
113
113
 
@@ -117,7 +117,7 @@ El toast **no tiene `size`**: siempre es un alert `large`.
117
117
  |---|---|---|---|
118
118
  | ancho | todo el ancho, con margen lateral | hasta 360 px, en la esquina | según el componente |
119
119
  | dónde | abajo, por encima de la barra inferior (nativa en iOS) | abajo a la derecha | según el componente |
120
- | la X de cerrar | se ve de 20 px; **se toca en 40 × 40** | igual | canon (aprobado por el dueño, 03-10-2026): área táctil invisible, extensión SUI |
120
+ | la X de cerrar | 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 |
121
121
  | la acción | link `medium` (20 px de alto) | link `medium` | según el componente |
122
122
 
123
123
  No hay patrón `bp.isMobile()`: el outlet ya cambia solo por breakpoint. Lo que sí cambia por
@@ -148,14 +148,17 @@ Outputs: ninguno.
148
148
 
149
149
  ## Trampas
150
150
 
151
- - **La X se toca en 40 × 40** aunque se vea de 20 (un `::before` invisible sobre su `<button>`,
152
- desde 03-10-2026). Solo llega a la app cuando deje de usar su copia local del toast (ver abajo).
151
+ - **La X se toca en 44 × 44 en el teléfono** (40 × 40 en web) aunque se vea de 20 (un `::before`
152
+ invisible sobre su `<button>`; 44 desde el 04-10-2026). La copia local de la app tiene el mismo arreglo (commit 2c637a19).
153
153
  - **La app no usa el servicio del paquete.** `master-pedidos` tiene una copia local en
154
154
  `src/app/components/sui/sui-toast/` y el outlet montado en `app.ts:66` es esa copia. La API es la
155
155
  misma; la diferencia es que la copia lee la altura de la barra nativa desde `LiquidGlassService`,
156
156
  y la del paquete desde el token `SUI_TAB_BAR`. Si inyectas `SuiToastService` del paquete en la
157
157
  app, **no aparece nada**: su outlet no está montado. Migrar = importar del paquete y proveer
158
158
  `SUI_TAB_BAR`.
159
+ - **`CLAUDE.md` de la app dice que el toast es `ngx-sonner`: está desactualizado.** `ngx-sonner`
160
+ no está instalado y nadie lo importa; las 705 llamadas usan el `SuiToastService` de la copia
161
+ local. Ese es el canon en la app hoy (`toast.success(…)`, el mismo nombre de método que Sonner).
159
162
  - **El comentario de `style` miente:** dice `// default 'stroke'`, pero el código pone `'stroke-dark'`.
160
163
  - **Sin outlet no hay toasts:** el temporizador de cierre vive en el outlet, no en el servicio. Si el
161
164
  outlet no está montado, los toasts se acumulan en el signal y nunca se ven ni se van.
@@ -163,7 +166,9 @@ Outputs: ninguno.
163
166
  - La acción cierra el toast al tocarla, salvo `keepOpen: true`.
164
167
  - Al pasar el dedo o el mouse por la pila se abre en abanico y se queda abierta 1,2 s después de
165
168
  cerrar uno, para seguir tocando (patrón Sonner).
166
- - La pila lleva `aria-live="polite"`: el lector de pantalla anuncia cada toast.
169
+ - La pila lleva `aria-live="polite"`: el lector de pantalla anuncia cada toast, una vez. El
170
+ `sui-alert` de adentro va con `ariaRole="none"` (desde el 04-10-2026): antes llevaba su propio
171
+ `role="alert"` y el toast se podía anunciar dos veces y de forma asertiva.
167
172
  - El título es texto plano; la `description` del alert interno va por `innerHTML`: no le pases
168
173
  texto escrito por el usuario sin sanear.
169
174
 
@@ -34,9 +34,10 @@ servicio»). Es un extra: la pantalla tiene que entenderse sin él.
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
35
  > marcado «según la guía del DS» sale de su texto o su código publicado; el resto es **propuesta**.
36
36
  >
37
- > Uso medido el 03-10-2026 en `master-pedidos/src/app` (sin prototipos ni vitrinas): **6 tooltips**
38
- > en 6 archivos — 2 `suiTooltip` de texto en el panel del local y 4 `suiTooltipLarge` en el flujo de
39
- > compra del cliente.
37
+ > Uso medido el 04-10-2026 en `master-pedidos/src/app` (sin prototipos ni vitrinas): **0 tooltips**.
38
+ > Los 6 que había el 03-10-2026 (2 `suiTooltip` sobre un `<svg>` en el panel del local y 4
39
+ > `suiTooltipLarge` en el flujo de compra del cliente) pasaron a texto visible en el commit
40
+ > `77ac547a` de la app.
40
41
 
41
42
  ### Lo que sí dice la guía del DS
42
43
 
@@ -50,8 +51,8 @@ servicio»). Es un extra: la pantalla tiene que entenderse sin él.
50
51
 
51
52
  | SUI | guía | qué es | cuándo | fuente |
52
53
  |---|---|---|---|---|
53
- | `small` (24 px de alto, 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 |
54
- | `medium` (34 px, 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 |
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 |
55
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 |
56
57
  | `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 |
57
58
 
@@ -59,16 +60,16 @@ servicio»). Es un extra: la pantalla tiene que entenderse sin él.
59
60
 
60
61
  | input | cuándo | ejemplo real de la app | fuente |
61
62
  |---|---|---|---|
62
- | `suiTooltip="…"` | Una frase, sin punto final. | `components/customer-segments/customer-segments.html:8` («Ingresos por tipo de cliente») | propuesta |
63
- | `[suiTooltipLarge]="{ title, description, icon }"` | Un término que necesita título y explicación. | `core/service-fee.ts:33` («Tarifa de servicio») | propuesta |
64
- | `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. | `core/service-fee.ts:39` (hoy en `true`, en pantallas solo de mobile) | propuesta |
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 |
65
66
 
66
67
  ### `theme`, `position` y el resto
67
68
 
68
69
  | prop | valor | cuándo | fuente |
69
70
  |---|---|---|---|
70
71
  | `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) |
71
- | `theme` | `dark` | Igual que `auto` en modo claro, pero no se invierte en modo oscuro. Hoy lo usan los 4 del cliente. | según la guía del DS (default) |
72
+ | `theme` | `dark` | Igual que `auto` en modo claro, pero no se invierte en modo oscuro. | según la guía del DS (default) |
72
73
  | `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 |
73
74
  | `position` | `top` (default) | Siempre que haya espacio. Si no lo hay, el CDK lo da vuelta solo. | propuesta |
74
75
  | `position` | `right` · `left` | Íconos de una barra lateral angosta (el sidebar colapsado). | propuesta |
@@ -81,14 +82,10 @@ servicio»). Es un extra: la pantalla tiene que entenderse sin él.
81
82
 
82
83
  ### Usos de hoy que rompen la regla
83
84
 
84
- - **4 tooltips en pantallas que solo existen en el celular** (la explicación de la tarifa de
85
- servicio del cliente): `pages/customer/cart/cart.html:177`, `pages/customer/checkout/checkout.html:366`,
86
- `pages/customer/confirmation/confirmation.html:188`, `pages/customer/order-tracking/order-tracking.html:684`.
87
- Rompen la guía (hover o foco). Pasarían a un `sui-modal-sheet` al tocar el ícono, con el mismo
88
- texto de `core/service-fee.ts`.
89
- - **2 tooltips sobre un `<svg>` que no se puede enfocar** (y con `#a3a3a3` suelto):
90
- `components/customer-segments/customer-segments.html:8`, `components/product-categories/product-categories.html:8`.
91
- Ni el teclado ni el dedo llegan. El host pasaría a un botón de solo ícono con `aria-label`.
85
+ Ninguno (04-10-2026). Los 6 que rompían la regla ya se corrigieron en la app (commit `77ac547a`):
86
+ la tarifa de servicio del cliente se explica con una línea visible (`core/service-fee.ts:31`) y los
87
+ dos `<svg>` con tooltip del panel del local pasaron a subtítulo
88
+ (`components/customer-segments/customer-segments.html:6`, `components/product-categories/product-categories.html:6`).
92
89
 
93
90
  ## Tamaño en mobile y en web
94
91