@ajuarezso/sui-design-system 0.20.0 → 0.21.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.
- package/docs/INDEX.md +51 -51
- package/docs/sui-alert/README.md +13 -0
- package/docs/sui-badge/README.md +17 -0
- package/docs/sui-banner/README.md +190 -0
- package/docs/sui-breadcrumb-item/README.md +96 -0
- package/docs/sui-breadcrumbs/README.md +122 -0
- package/docs/sui-button/README.md +17 -0
- package/docs/sui-card/README.md +168 -0
- package/docs/sui-chart-legend/README.md +140 -0
- package/docs/sui-chart-legend-dot/README.md +118 -0
- package/docs/sui-checkbox-card/README.md +150 -0
- package/docs/sui-compact-select/README.md +127 -0
- package/docs/sui-compact-select-for-input/README.md +117 -0
- package/docs/sui-content-card/README.md +147 -0
- package/docs/sui-content-label/README.md +148 -0
- package/docs/sui-counter-input/README.md +145 -0
- package/docs/sui-date-selector/README.md +98 -0
- package/docs/sui-datepicker/README.md +193 -0
- package/docs/sui-day-cell/README.md +118 -0
- package/docs/sui-day-label/README.md +81 -0
- package/docs/sui-drawer-footer/README.md +127 -0
- package/docs/sui-drawer-header/README.md +140 -0
- package/docs/sui-empty-state/README.md +145 -0
- package/docs/sui-file-upload/README.md +154 -0
- package/docs/sui-file-upload-card/README.md +129 -0
- package/docs/sui-image-upload/README.md +200 -0
- package/docs/sui-image-upload-profile/README.md +145 -0
- package/docs/sui-inline-input/README.md +104 -0
- package/docs/sui-inline-select/README.md +101 -0
- package/docs/sui-input/README.md +244 -0
- package/docs/sui-integration-switch/README.md +142 -0
- package/docs/sui-notification/README.md +179 -0
- package/docs/sui-notification-footer/README.md +98 -0
- package/docs/sui-notification-tab-menu/README.md +112 -0
- package/docs/sui-otp-input/README.md +116 -0
- package/docs/sui-pagination/README.md +146 -0
- package/docs/sui-password-strength/README.md +99 -0
- package/docs/sui-period-range/README.md +93 -0
- package/docs/sui-popover/README.md +178 -0
- package/docs/sui-product-card/README.md +173 -0
- package/docs/sui-radio-card/README.md +160 -0
- package/docs/sui-rating/README.md +7 -6
- package/docs/sui-rich-editor/README.md +114 -0
- package/docs/sui-select/README.md +180 -0
- package/docs/sui-stepper/README.md +166 -0
- package/docs/sui-store-card/README.md +147 -0
- package/docs/sui-switch-card/README.md +149 -0
- package/docs/sui-tab-chips/README.md +185 -0
- package/docs/sui-tab-menu-horizontal/README.md +142 -0
- package/docs/sui-tab-menu-vertical/README.md +136 -0
- package/docs/sui-tag-input/README.md +120 -0
- package/docs/sui-textarea/README.md +157 -0
- package/docs/sui-time-picker/README.md +237 -0
- package/docs/sui-toast/README.md +190 -0
- package/docs/sui-tooltip/README.md +201 -0
- package/fesm2022/ajuarezso-sui-design-system.mjs +273 -231
- package/fesm2022/ajuarezso-sui-design-system.mjs.map +1 -1
- package/package.json +1 -1
- package/types/ajuarezso-sui-design-system.d.ts +208 -52
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sui-toast
|
|
3
|
+
selector: sui-toast-outlet
|
|
4
|
+
resumen: Aviso efímero que confirma el resultado de una acción y se va solo; se dispara con SuiToastService
|
|
5
|
+
alternativas: [sui-alert (aviso que se queda, en su contexto), sui-banner (toda la app), sui-notification (fila de la bandeja, con hora), sui-form-hint (error de un campo)]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# sui-toast
|
|
9
|
+
|
|
10
|
+
Story: [Molecules/Feedback/Toast](https://sui-design-system.web.app/?path=/docs/molecules-feedback-toast--docs)
|
|
11
|
+
|
|
12
|
+
No hay una etiqueta `<sui-toast>`: el toast son **dos piezas**. `SuiToastService` (se inyecta y se
|
|
13
|
+
llama: `toast.success(…)`) y `<sui-toast-outlet />`, que se monta **una sola vez** en la raíz de
|
|
14
|
+
la app y dibuja la pila. Cada toast es, por dentro, un `sui-alert` `size="large"`. El apilado, la
|
|
15
|
+
salida y los tiempos copian a Sonner (la librería de toasts que usa la guía del DS).
|
|
16
|
+
|
|
17
|
+
## Cuándo usarlo / cuándo no
|
|
18
|
+
|
|
19
|
+
**Úsalo** para el **resultado de algo que la persona acaba de hacer** («Cambios guardados», «No
|
|
20
|
+
se pudo eliminar el producto») y para un aviso que **llega mientras usa la app** y no necesita
|
|
21
|
+
quedarse (un push con la app abierta, «Nueva versión disponible»). Aparece, se lee y se va.
|
|
22
|
+
|
|
23
|
+
**No lo uses** para:
|
|
24
|
+
|
|
25
|
+
- Algo que tiene que seguir visible para que la persona actúe: un error que bloquea, un motivo
|
|
26
|
+
de rechazo, un «no puedes eliminar tu cuenta porque…». Eso es `sui-alert`, ahí mismo. Un toast
|
|
27
|
+
con `duration: Infinity` y sin acción es un alert mal puesto.
|
|
28
|
+
- Un **error al cargar** una pantalla: el toast se va y deja la pantalla vacía sin explicación.
|
|
29
|
+
Va un `sui-alert` `filled` o un `sui-empty-state` con «Reintentar».
|
|
30
|
+
- El error de un campo de formulario: `sui-form-hint` o el `errorMessage` del input.
|
|
31
|
+
- Algo de toda la app que dura (plan vencido): `sui-banner`.
|
|
32
|
+
|
|
33
|
+
Regla corta (canon, la misma del alert): **contexto → alert · toda la app → banner · efímero →
|
|
34
|
+
toast · bandeja → notification.**
|
|
35
|
+
|
|
36
|
+
## Qué variante usar
|
|
37
|
+
|
|
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
|
+
> 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**.
|
|
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.
|
|
45
|
+
|
|
46
|
+
### Lo que sí dice la guía del DS
|
|
47
|
+
|
|
48
|
+
- **Para qué es**: feedback **breve** en tamaño compacto; varios se pueden **apilar**.
|
|
49
|
+
- **Una línea**: lo arma con un alert `small` (título solo, sin descripción) de 360 px de ancho.
|
|
50
|
+
SUI lo arma con un alert `large`, que sí admite descripción.
|
|
51
|
+
- **Defaults**: relleno `stroke`, posición `bottom-center`, cerrable. SUI arranca en
|
|
52
|
+
`stroke-dark` y `bottom-right`.
|
|
53
|
+
- **Ojo con la palabra «notification»**: en la guía, una notification es un aviso temporal en una
|
|
54
|
+
esquina con título, descripción y acción (un pago, una actualización). En SUI ese caso **también
|
|
55
|
+
es un toast** (`description` + `action`); `sui-notification` es otra cosa: la fila de la bandeja.
|
|
56
|
+
|
|
57
|
+
### El tipo — qué método llamar
|
|
58
|
+
|
|
59
|
+
| método | cuándo | ejemplo real de la app | fuente |
|
|
60
|
+
|---|---|---|---|
|
|
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
|
+
| `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 |
|
|
66
|
+
| `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
|
+
### `style` — el relleno
|
|
69
|
+
|
|
70
|
+
| style | cuándo | fuente |
|
|
71
|
+
|---|---|---|
|
|
72
|
+
| `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 |
|
|
75
|
+
|
|
76
|
+
### Tiempo, cierre, acción y texto
|
|
77
|
+
|
|
78
|
+
| opción | valor | cuándo | fuente |
|
|
79
|
+
|---|---|---|---|
|
|
80
|
+
| `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` | `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
|
+
| `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 |
|
|
87
|
+
| `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 |
|
|
92
|
+
| `id` | texto | Para reemplazar un toast en curso o no repetir el mismo aviso. | según el componente |
|
|
93
|
+
|
|
94
|
+
### Usos de hoy que rompen la regla
|
|
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.
|
|
111
|
+
|
|
112
|
+
## Tamaño en mobile y en web
|
|
113
|
+
|
|
114
|
+
El toast **no tiene `size`**: siempre es un alert `large`.
|
|
115
|
+
|
|
116
|
+
| uso | mobile (≤ 767 px) | web | fuente |
|
|
117
|
+
|---|---|---|---|
|
|
118
|
+
| ancho | todo el ancho, con margen lateral | hasta 360 px, en la esquina | según el componente |
|
|
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 |
|
|
121
|
+
| la acción | link `medium` (20 px de alto) | link `medium` | según el componente |
|
|
122
|
+
|
|
123
|
+
No hay patrón `bp.isMobile()`: el outlet ya cambia solo por breakpoint. Lo que sí cambia por
|
|
124
|
+
plataforma es el largo del texto: en mobile el título envuelve antes, así que una sola idea por toast.
|
|
125
|
+
|
|
126
|
+
## «No usar»: por qué no hoy y cuándo sí
|
|
127
|
+
|
|
128
|
+
Nada se borra del DS. Si un flujo nuevo cae en la columna de la derecha, se usa.
|
|
129
|
+
|
|
130
|
+
| qué | por qué no hoy | cuándo sí, en un flujo nuevo |
|
|
131
|
+
|---|---|---|
|
|
132
|
+
| `feature()` | no hay novedades que se anuncien al activarlas | «Ya puedes programar tus pedidos», justo cuando se activa |
|
|
133
|
+
| `style` `stroke` | blanco sobre blanco | una pantalla de fondo oscuro (landing) |
|
|
134
|
+
| `style` `lighter`, `light`, `filled` | un toast que pesa más ya no es un toast | ninguno previsto: es un alert o un modal |
|
|
135
|
+
| `dismissible: false` | todo toast se puede quitar | un toast de progreso que se reemplaza con el mismo `id` |
|
|
136
|
+
| `position` distinta de la default | dos pilas en dos esquinas | una pantalla con barra fija abajo (`top-*`), o mover toda la app con `setDefaultPosition()` |
|
|
137
|
+
| `duration: Infinity` sin `action` | no se va y no hay nada que hacer | ninguno: eso es un alert |
|
|
138
|
+
|
|
139
|
+
## API
|
|
140
|
+
|
|
141
|
+
<!-- api:inicio -->
|
|
142
|
+
<!-- generada: no editar a mano — `npm run docs` -->
|
|
143
|
+
|
|
144
|
+
Inputs: ninguno.
|
|
145
|
+
|
|
146
|
+
Outputs: ninguno.
|
|
147
|
+
<!-- api:fin -->
|
|
148
|
+
|
|
149
|
+
## Trampas
|
|
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).
|
|
153
|
+
- **La app no usa el servicio del paquete.** `master-pedidos` tiene una copia local en
|
|
154
|
+
`src/app/components/sui/sui-toast/` y el outlet montado en `app.ts:66` es esa copia. La API es la
|
|
155
|
+
misma; la diferencia es que la copia lee la altura de la barra nativa desde `LiquidGlassService`,
|
|
156
|
+
y la del paquete desde el token `SUI_TAB_BAR`. Si inyectas `SuiToastService` del paquete en la
|
|
157
|
+
app, **no aparece nada**: su outlet no está montado. Migrar = importar del paquete y proveer
|
|
158
|
+
`SUI_TAB_BAR`.
|
|
159
|
+
- **El comentario de `style` miente:** dice `// default 'stroke'`, pero el código pone `'stroke-dark'`.
|
|
160
|
+
- **Sin outlet no hay toasts:** el temporizador de cierre vive en el outlet, no en el servicio. Si el
|
|
161
|
+
outlet no está montado, los toasts se acumulan en el signal y nunca se ven ni se van.
|
|
162
|
+
- `dismissible` arranca en `true` aquí y en `false` en `sui-alert` y `sui-banner`.
|
|
163
|
+
- La acción cierra el toast al tocarla, salvo `keepOpen: true`.
|
|
164
|
+
- 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
|
+
cerrar uno, para seguir tocando (patrón Sonner).
|
|
166
|
+
- La pila lleva `aria-live="polite"`: el lector de pantalla anuncia cada toast.
|
|
167
|
+
- El título es texto plano; la `description` del alert interno va por `innerHTML`: no le pases
|
|
168
|
+
texto escrito por el usuario sin sanear.
|
|
169
|
+
|
|
170
|
+
## Ejemplo
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
private readonly toast = inject(SuiToastService);
|
|
174
|
+
|
|
175
|
+
guardar() {
|
|
176
|
+
this.toast.success('Cambios guardados');
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
fallo() {
|
|
180
|
+
this.toast.error('No se pudo eliminar el producto', { description: 'Revisa tu conexión y vuelve a intentar.', duration: 6000 });
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
versionNueva(v: string) {
|
|
184
|
+
this.toast.info('Nueva versión disponible', {
|
|
185
|
+
description: `Actualiza para usar la versión ${v}.`,
|
|
186
|
+
duration: Infinity,
|
|
187
|
+
action: { label: 'Actualizar', onClick: () => location.reload() },
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
```
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sui-tooltip
|
|
3
|
+
selector: "[suiTooltip], [suiTooltipLarge]"
|
|
4
|
+
resumen: Directiva que muestra una ayuda corta al pasar el mouse o al enfocar un elemento; solo web, no sirve con el dedo
|
|
5
|
+
alternativas: [sui-form-hint (ayuda visible bajo un campo), sui-modal-sheet (explicación que se abre al tocar, en mobile), sui-popover (panel que señala algo y pide una acción)]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# sui-tooltip
|
|
9
|
+
|
|
10
|
+
Story: [Molecules/Tooltip](https://sui-design-system.web.app/?path=/docs/molecules-tooltip--docs)
|
|
11
|
+
|
|
12
|
+
Es una **directiva**, no una etiqueta: se pone sobre el elemento que explica
|
|
13
|
+
(`<button suiTooltip="Editar">`). El globo lo dibuja `sui-tooltip-panel` en el overlay del CDK.
|
|
14
|
+
|
|
15
|
+
## Cuándo usarlo / cuándo no
|
|
16
|
+
|
|
17
|
+
**Úsalo** en **web** para dar contexto a algo que se puede tocar o enfocar: el nombre de un botón
|
|
18
|
+
de solo ícono («Editar», «Exportar»), o qué significa un término al lado de un dato («Tarifa de
|
|
19
|
+
servicio»). Es un extra: la pantalla tiene que entenderse sin él.
|
|
20
|
+
|
|
21
|
+
**No lo uses** para:
|
|
22
|
+
|
|
23
|
+
- **Mobile.** No hay hover: la directiva solo escucha `mouseenter` y `focus`. Con el dedo depende de
|
|
24
|
+
cómo el navegador imite el mouse: a veces abre, se cierra al hacer scroll y no se cierra al tocar
|
|
25
|
+
afuera. En las pantallas del cliente y del repartidor, la explicación va **visible** (una línea bajo
|
|
26
|
+
el dato, `sui-form-hint`) o en un `sui-modal-sheet` que se abre al tocar el ícono.
|
|
27
|
+
- Información que hace falta para decidir (un precio, una condición): eso se escribe en la pantalla.
|
|
28
|
+
- Un elemento que no se puede enfocar (`<svg>`, `<span>`): con teclado nunca aparece. El host tiene
|
|
29
|
+
que ser un botón.
|
|
30
|
+
- Algo que pide una acción («Siguiente», «Entendido»): eso es `sui-popover`.
|
|
31
|
+
|
|
32
|
+
## Qué variante usar
|
|
33
|
+
|
|
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**.
|
|
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.
|
|
40
|
+
|
|
41
|
+
### Lo que sí dice la guía del DS
|
|
42
|
+
|
|
43
|
+
- **Para qué es**: agrega contexto a elementos **interactivos** y aparece al pasar el mouse o con el
|
|
44
|
+
**foco del teclado**. Por eso no sirve con el dedo.
|
|
45
|
+
- **Tres tamaños**, con nombres corridos un paso respecto a SUI (tabla abajo).
|
|
46
|
+
- **Default**: tema `dark` y tamaño intermedio. SUI arranca en tema `light`.
|
|
47
|
+
- La flecha siempre está; la posición sigue al espacio disponible.
|
|
48
|
+
|
|
49
|
+
### `size` (input `suiTooltipSize`) — equivalencia con la guía
|
|
50
|
+
|
|
51
|
+
| SUI | guía | qué es | cuándo | fuente |
|
|
52
|
+
|---|---|---|---|---|
|
|
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 |
|
|
55
|
+
| `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
|
+
| `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
|
+
### Contenido: `suiTooltip` o `suiTooltipLarge`
|
|
59
|
+
|
|
60
|
+
| input | cuándo | ejemplo real de la app | fuente |
|
|
61
|
+
|---|---|---|---|
|
|
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 |
|
|
65
|
+
|
|
66
|
+
### `theme`, `position` y el resto
|
|
67
|
+
|
|
68
|
+
| prop | valor | cuándo | fuente |
|
|
69
|
+
|---|---|---|---|
|
|
70
|
+
| `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` | `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
|
+
| `position` | `top` (default) | Siempre que haya espacio. Si no lo hay, el CDK lo da vuelta solo. | propuesta |
|
|
74
|
+
| `position` | `right` · `left` | Íconos de una barra lateral angosta (el sidebar colapsado). | propuesta |
|
|
75
|
+
| `position` | `bottom` · `*-start` · `*-end` | Un elemento pegado al borde de arriba o a un costado de la pantalla. | propuesta |
|
|
76
|
+
| `delay` | `200` (default) | Siempre: evita que se abra al cruzar con el mouse. | propuesta |
|
|
77
|
+
| `delay` | otro valor | No usar hoy. **Cuándo sí:** ninguno previsto. | propuesta |
|
|
78
|
+
| `disabled` | `true` | Cuando lo que dice ya está a la vista (el sidebar expandido muestra el nombre). | propuesta |
|
|
79
|
+
| `showArrow` | `true` (default) | Siempre: la flecha dice de qué elemento habla. | según la guía del DS |
|
|
80
|
+
| `showArrow` | `false` | No usar hoy. **Cuándo sí:** sobre un punto de un gráfico, donde la flecha tapa el dato. | propuesta |
|
|
81
|
+
|
|
82
|
+
### Usos de hoy que rompen la regla
|
|
83
|
+
|
|
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`.
|
|
92
|
+
|
|
93
|
+
## Tamaño en mobile y en web
|
|
94
|
+
|
|
95
|
+
| uso | mobile | web | fuente |
|
|
96
|
+
|---|---|---|---|
|
|
97
|
+
| nombre de un ícono | no aplica: el ícono lleva el nombre escrito o `aria-label` | `small` | propuesta |
|
|
98
|
+
| frase que explica | no aplica: el texto va visible bajo el dato (`sui-form-hint`) | `medium` | propuesta |
|
|
99
|
+
| explicación con título | no aplica: `sui-modal-sheet` al tocar el ícono | `large` (automático con `[suiTooltipLarge]`) | propuesta |
|
|
100
|
+
|
|
101
|
+
En pantallas que se usan en los dos (panel del local, super admin), el tooltip se apaga en mobile
|
|
102
|
+
y la ayuda se muestra de otra forma:
|
|
103
|
+
|
|
104
|
+
```html
|
|
105
|
+
<button class="info" type="button" aria-label="Qué es la tarifa de servicio"
|
|
106
|
+
[suiTooltipLarge]="tarifa" theme="auto" [disabled]="bp.isMobile()"
|
|
107
|
+
(click)="bp.isMobile() && abrirExplicacion()">
|
|
108
|
+
<sui-icon name="information-line" [size]="16" />
|
|
109
|
+
</button>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## «No usar»: por qué no hoy y cuándo sí
|
|
113
|
+
|
|
114
|
+
| qué | por qué no hoy | cuándo sí, en un flujo nuevo |
|
|
115
|
+
|---|---|---|
|
|
116
|
+
| cualquier tooltip en mobile | no hay hover; con el dedo abre de casualidad | nunca: texto visible o un sheet |
|
|
117
|
+
| `suiTooltipSize="xlarge"` | 280 px alcanzan para lo que hay | una explicación rica que en 280 px pasa de cuatro líneas |
|
|
118
|
+
| `dismissible: true` | queda abierto como un popover | en web, una explicación larga para leer con calma |
|
|
119
|
+
| `theme="light"` | sobre página clara parece una card | ya lo da `auto` en modo oscuro |
|
|
120
|
+
| `showArrow=false` | la flecha dice de qué habla | sobre un punto de un gráfico |
|
|
121
|
+
| `delay` distinto de 200 | se abriría al cruzar con el mouse | ninguno previsto |
|
|
122
|
+
|
|
123
|
+
## API
|
|
124
|
+
|
|
125
|
+
<!-- api:inicio -->
|
|
126
|
+
<!-- generada: no editar a mano — `npm run docs` -->
|
|
127
|
+
|
|
128
|
+
### `[suiTooltip], [suiTooltipLarge]`
|
|
129
|
+
|
|
130
|
+
| input | tipo | default |
|
|
131
|
+
|---|---|---|
|
|
132
|
+
| `suiTooltip` | `string` | `''` |
|
|
133
|
+
| `suiTooltipLarge` | `SuiTooltipLargeData \| null` | `null` |
|
|
134
|
+
| `position` | `'top' \| 'top-start' \| 'top-end' \| 'right' \| 'bottom' \| 'bottom-start' \| 'bottom-end' \| 'left'` | `'top'` |
|
|
135
|
+
| `suiTooltipSize` (propiedad `size`) | `'small' \| 'medium' \| 'large' \| 'xlarge'` | `'medium'` |
|
|
136
|
+
| `theme` | `'light' \| 'dark' \| 'auto'` | `'light'` |
|
|
137
|
+
| `delay` | `number` | `200` |
|
|
138
|
+
| `disabled` | `boolean` | `false` |
|
|
139
|
+
| `showArrow` | `boolean` | `true` |
|
|
140
|
+
|
|
141
|
+
Outputs: ninguno.
|
|
142
|
+
|
|
143
|
+
### `sui-tooltip-panel`
|
|
144
|
+
|
|
145
|
+
| input | tipo | default |
|
|
146
|
+
|---|---|---|
|
|
147
|
+
| `text` | `string` | `''` |
|
|
148
|
+
| `position` | `'top' \| 'top-start' \| 'top-end' \| 'right' \| 'bottom' \| 'bottom-start' \| 'bottom-end' \| 'left'` | `'top'` |
|
|
149
|
+
| `size` | `'small' \| 'medium' \| 'large' \| 'xlarge'` | `'medium'` |
|
|
150
|
+
| `theme` | `'light' \| 'dark'` | `'light'` |
|
|
151
|
+
| `showArrow` | `boolean` | `true` |
|
|
152
|
+
| `title` | `string \| null` | `null` |
|
|
153
|
+
| `description` | `string \| null` | `null` |
|
|
154
|
+
| `icon` | `string \| null` | `null` |
|
|
155
|
+
| `dismissible` | `boolean` | `false` |
|
|
156
|
+
|
|
157
|
+
| output | payload |
|
|
158
|
+
|---|---|
|
|
159
|
+
| `dismissed` | `void` |
|
|
160
|
+
<!-- api:fin -->
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
interface SuiTooltipLargeData {
|
|
164
|
+
title: string;
|
|
165
|
+
description?: string;
|
|
166
|
+
icon?: string; // RemixIcon sin el prefijo ri-
|
|
167
|
+
dismissible?: boolean; // true = se queda abierto hasta la X o Escape
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
`SuiTooltipPanel` (`sui-tooltip-panel`) es el globo que monta la directiva; también se exporta, pero
|
|
172
|
+
no se usa directo en pantallas.
|
|
173
|
+
|
|
174
|
+
## Trampas
|
|
175
|
+
|
|
176
|
+
- **El tamaño se pasa como `suiTooltipSize`**, no como `size`: así no choca con el `size` del
|
|
177
|
+
componente que lo lleva (`<sui-button size="small" suiTooltip="…">`).
|
|
178
|
+
- **`position`, `theme`, `delay` y `disabled` sí se llaman así, sin prefijo**: si el host es un
|
|
179
|
+
componente con un input del mismo nombre (`disabled` de `sui-button`), el valor llega a los dos.
|
|
180
|
+
- **`suiTooltipSize="large"` con `suiTooltip` de texto dibuja una caja vacía**: el tamaño rico solo
|
|
181
|
+
lee `suiTooltipLarge`. Con `[suiTooltipLarge]` el tamaño pasa a `large` solo.
|
|
182
|
+
- **Defaults distintos a la guía**: tema `light` (la guía, `dark`) y nombres de tamaño corridos un paso.
|
|
183
|
+
- Se cierra al hacer scroll en cualquier contenedor y con Escape. Con `dismissible`, no se cierra al
|
|
184
|
+
sacar el mouse.
|
|
185
|
+
- Pone `aria-describedby` en el host y le borra el `title` nativo (si no, saldría además el globo
|
|
186
|
+
gris del navegador).
|
|
187
|
+
- En `dark`, el ícono del tooltip rico usa un gris fijo del `.scss`, no un token.
|
|
188
|
+
|
|
189
|
+
## Ejemplo
|
|
190
|
+
|
|
191
|
+
```html
|
|
192
|
+
<!-- Nombre de un botón de solo ícono, en web -->
|
|
193
|
+
<sui-compact-button icon="download-2-line" ariaLabel="Exportar" suiTooltip="Exportar" theme="auto" />
|
|
194
|
+
|
|
195
|
+
<!-- Término con explicación, en web -->
|
|
196
|
+
<button type="button" aria-label="Qué es la tarifa de servicio"
|
|
197
|
+
[suiTooltipLarge]="{ title: 'Tarifa de servicio', description: 'Nos ayuda a mantener la plataforma funcionando.', icon: 'information-line' }"
|
|
198
|
+
theme="auto">
|
|
199
|
+
<sui-icon name="information-line" [size]="16" />
|
|
200
|
+
</button>
|
|
201
|
+
```
|