@ajuarezso/sui-design-system 0.19.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 +136 -0
- package/docs/sui-alert/README.md +229 -0
- package/docs/sui-app-store-badge/README.md +137 -0
- package/docs/sui-avatar/README.md +263 -0
- package/docs/sui-avatar-group/README.md +115 -0
- package/docs/sui-badge/README.md +229 -0
- package/docs/sui-banner/README.md +190 -0
- package/docs/sui-brand-logo/README.md +143 -0
- package/docs/sui-breadcrumb-item/README.md +96 -0
- package/docs/sui-breadcrumbs/README.md +122 -0
- package/docs/sui-button/README.md +209 -0
- package/docs/sui-button-group/README.md +178 -0
- package/docs/sui-button-group-item/README.md +102 -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/README.md +147 -0
- package/docs/sui-checkbox-card/README.md +150 -0
- package/docs/sui-checkbox-label/README.md +143 -0
- package/docs/sui-circular-progress-bar/README.md +131 -0
- package/docs/sui-color-dot/README.md +112 -0
- package/docs/sui-color-picker/README.md +124 -0
- package/docs/sui-compact-avatar-group/README.md +103 -0
- package/docs/sui-compact-button/README.md +190 -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-divider/README.md +124 -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-divider/README.md +102 -0
- package/docs/sui-drawer-footer/README.md +127 -0
- package/docs/sui-drawer-header/README.md +140 -0
- package/docs/sui-emoji/README.md +138 -0
- package/docs/sui-empty-state/README.md +145 -0
- package/docs/sui-fancy-button/README.md +148 -0
- package/docs/sui-file-icon/README.md +103 -0
- package/docs/sui-file-upload/README.md +154 -0
- package/docs/sui-file-upload-card/README.md +129 -0
- package/docs/sui-flag/README.md +99 -0
- package/docs/sui-form-hint/README.md +124 -0
- package/docs/sui-form-label/README.md +148 -0
- package/docs/sui-icon/README.md +135 -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-kbd/README.md +97 -0
- package/docs/sui-key-icon/README.md +125 -0
- package/docs/sui-link-button/README.md +221 -0
- package/docs/sui-logo/README.md +152 -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-payment-icon/README.md +98 -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-progress-bar/README.md +132 -0
- package/docs/sui-progress-bar-label/README.md +143 -0
- package/docs/sui-radio/README.md +134 -0
- package/docs/sui-radio-card/README.md +160 -0
- package/docs/sui-radio-label/README.md +137 -0
- package/docs/sui-rating/README.md +199 -0
- package/docs/sui-rich-editor/README.md +114 -0
- package/docs/sui-segmented-control/README.md +144 -0
- package/docs/sui-select/README.md +180 -0
- package/docs/sui-slider/README.md +143 -0
- package/docs/sui-social-button/README.md +158 -0
- package/docs/sui-status-badge/README.md +164 -0
- package/docs/sui-stepper/README.md +166 -0
- package/docs/sui-store-card/README.md +147 -0
- package/docs/sui-switch/README.md +146 -0
- package/docs/sui-switch-card/README.md +149 -0
- package/docs/sui-switch-label/README.md +139 -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/README.md +145 -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 +466 -279
- package/fesm2022/ajuarezso-sui-design-system.mjs.map +1 -1
- package/package.json +1 -1
- package/types/ajuarezso-sui-design-system.d.ts +367 -72
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sui-notification
|
|
3
|
+
selector: sui-notification
|
|
4
|
+
resumen: Fila de la bandeja de notificaciones, con quién, qué pasó, hace cuánto y si ya se leyó
|
|
5
|
+
alternativas: [sui-toast (aviso efímero, incluido el «notification» de esquina de la guía), sui-alert (aviso que se queda en su contexto), sui-banner (toda la app)]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# sui-notification
|
|
9
|
+
|
|
10
|
+
Story: [Molecules/Feedback/Notification](https://sui-design-system.web.app/?path=/docs/molecules-feedback-notification--docs)
|
|
11
|
+
|
|
12
|
+
## Primero: dos cosas distintas con el mismo nombre
|
|
13
|
+
|
|
14
|
+
- **En la guía del DS**, una «notification» es un aviso **temporal en una esquina** con título,
|
|
15
|
+
descripción y una acción (un pago, una actualización). En SUI ese caso **es un `sui-toast`** con
|
|
16
|
+
`description` y `action`.
|
|
17
|
+
- **En SUI**, `sui-notification` es la **fila de la bandeja**: el panel de la campana del Figma del
|
|
18
|
+
DS (foto, título, descripción, hora, punto de no leída). Este README es sobre eso.
|
|
19
|
+
|
|
20
|
+
El componente además arrastra un tercer uso: un aviso con tipo y relleno (`variant`, `variantStyle`)
|
|
21
|
+
igual al de `sui-alert`. Ese uso no va: para eso está el alert.
|
|
22
|
+
|
|
23
|
+
## Cuándo usarlo / cuándo no
|
|
24
|
+
|
|
25
|
+
**Úsalo** para cada aviso de una **bandeja** que la persona revisa cuando quiere: «Tu pedido llegó»,
|
|
26
|
+
«Nuevo pedido de Pollería El Dorado», «Recarga aprobada». Lleva **la hora**, se marca como leído y
|
|
27
|
+
se puede volver a abrir.
|
|
28
|
+
|
|
29
|
+
**No lo uses** para:
|
|
30
|
+
|
|
31
|
+
- Avisar algo en el momento: `sui-toast` (aunque tenga título, descripción y acción).
|
|
32
|
+
- Un aviso dentro de una pantalla: `sui-alert`.
|
|
33
|
+
- Una lista de actividad sin leído/no leído (el historial de un pedido): `sui-activity-feed`.
|
|
34
|
+
|
|
35
|
+
Regla corta (canon, la misma del alert): **contexto → alert · toda la app → banner · efímero →
|
|
36
|
+
toast · bandeja → notification.**
|
|
37
|
+
|
|
38
|
+
## Qué variante usar
|
|
39
|
+
|
|
40
|
+
> La guía del DS no tiene esta fila (su «notification» es otra cosa, ver arriba). Lo de abajo sale
|
|
41
|
+
> del Figma del DS y del componente («según el componente»), de lo ya aprobado («canon») o es
|
|
42
|
+
> **propuesta**.
|
|
43
|
+
>
|
|
44
|
+
> Uso medido el 03-10-2026 en `master-pedidos/src/app`: **0 usos**. La bandeja de la app
|
|
45
|
+
> (`pages/notifications/notifications.html:98`, la misma pantalla en las rutas de los 4 roles) dibuja
|
|
46
|
+
> sus filas a mano.
|
|
47
|
+
|
|
48
|
+
### Qué lleva cada fila
|
|
49
|
+
|
|
50
|
+
| prop | valor | cuándo | fuente |
|
|
51
|
+
|---|---|---|---|
|
|
52
|
+
| `avatar` | `src` con la foto | **Siempre**: la cara o el logo de quien generó el aviso (el local del pedido, el repartidor que lo lleva). Una foto se reconoce antes que un texto. | propuesta |
|
|
53
|
+
| `avatar` | `{ initials }` | Solo si no hay foto. Ojo: sale en un círculo negro, **no** con el color por rol (ver Trampas). | según el componente |
|
|
54
|
+
| `avatar` | el isotipo de la app | Avisos **del sistema** sin una persona detrás («Tu plan vence en 3 días»): así toda la bandeja queda en filas iguales. | propuesta |
|
|
55
|
+
| `title` | frase corta | Qué pasó: «Tu pedido llegó». Sentence case, sin punto final. | canon (copy de la app) |
|
|
56
|
+
| `description` | una o dos frases | El detalle que decide si abrirla: «Pollería El Dorado · S/ 42.50». | propuesta |
|
|
57
|
+
| `timestamp` | texto ya formateado | **Siempre**: la hora es lo que hace bandeja a la bandeja. «Hace 5 min», «Ayer 18:40». | canon (bandeja con hora) · formato: propuesta |
|
|
58
|
+
| `unread` | `true` | Hasta que la persona la abre. El punto es naranja (el primario de la app). | según el componente |
|
|
59
|
+
| `showMore` | `true` | No usar hoy: el botón ⋮ solo aparece con el mouse encima. **Cuándo sí:** en web, acciones por fila (marcar como leída, archivar). | propuesta |
|
|
60
|
+
| `active` | `true` | No usar hoy: pinta la fila como si tuviera el mouse encima. **Cuándo sí:** navegar la bandeja con las flechas del teclado (ver `sui-notification-footer`). | propuesta |
|
|
61
|
+
| `dismissible` | `true` | No usar hoy: los avisos de la bandeja se leen, no se cierran. **Cuándo sí:** una bandeja donde se borran avisos uno por uno. | propuesta |
|
|
62
|
+
|
|
63
|
+
### `type` — el cuerpo de la fila
|
|
64
|
+
|
|
65
|
+
| type | cuándo | fuente |
|
|
66
|
+
|---|---|---|
|
|
67
|
+
| `basic` (default) | Todas las de hoy: título, descripción y hora. | según el componente |
|
|
68
|
+
| `button` | No usar hoy. **Cuándo sí:** una solicitud que se resuelve desde la misma bandeja, con «Rechazar» / «Aprobar» en `slot="actions"` (por ejemplo, una invitación a un equipo). Secundario a la izquierda, primario a la derecha. | propuesta · orden: canon |
|
|
69
|
+
| `message` | No usar hoy. **Cuándo sí:** el aviso trae lo que escribió otra persona (la nota del cliente, un mensaje del repartidor), en la burbuja. | propuesta |
|
|
70
|
+
| `file` | No usar hoy: la app no manda adjuntos. **Cuándo sí:** un comprobante o una boleta adjunta. | propuesta |
|
|
71
|
+
|
|
72
|
+
### `variant` y `variantStyle` — el modelo de alert
|
|
73
|
+
|
|
74
|
+
| prop | valor | cuándo | fuente |
|
|
75
|
+
|---|---|---|---|
|
|
76
|
+
| `variant` | `default` (default) | **Siempre** en la bandeja: el tipo lo dice la foto y el texto, no un color. | propuesta |
|
|
77
|
+
| `variant` | `info` · `success` · `warning` · `error` · `feature` | No usar: con tipo y sin foto, la fila se vuelve un alert con borde y sombra. **Cuándo sí:** ninguno; ese aviso es un `sui-alert`. | propuesta (sigue la regla canon) |
|
|
78
|
+
| `variantStyle` | `stroke` (default) | Siempre. Con foto, la fila es plana: sin borde ni sombra. | según el componente |
|
|
79
|
+
| `variantStyle` | `filled` · `light` · `lighter` | No usar: pintan la fila de color, que es lo que hace el alert. **Cuándo sí:** ninguno. | propuesta |
|
|
80
|
+
| `showIcon` | `true` (default) | No cambia nada con foto; el ícono de tipo solo sale en el modelo de alert. | según el componente |
|
|
81
|
+
|
|
82
|
+
### Slots
|
|
83
|
+
|
|
84
|
+
| slot | cuándo | fuente |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| `slot="company-logo"` | Logo de 16 px antes de la descripción: el local, cuando la foto es la del repartidor. | propuesta |
|
|
87
|
+
| `slot="actions"` | Los dos botones de `type="button"`. | según el componente |
|
|
88
|
+
| `slot="message"` · `slot="file"` | El cuerpo de `type="message"` y `type="file"`. | según el componente |
|
|
89
|
+
|
|
90
|
+
### Usos de hoy que romperían la regla
|
|
91
|
+
|
|
92
|
+
- **La bandeja dibuja sus filas a mano — 1 pantalla, 4 rutas:** `pages/notifications/notifications.html:98`
|
|
93
|
+
(ícono de color por tipo, fila teñida si no se leyó, punto a la derecha). **A discutir**: no es un
|
|
94
|
+
cambio 1:1. Con el componente, el tipo se ve en la foto y no en un ícono de color, y la no leída
|
|
95
|
+
lleva solo el punto, sin teñir la fila.
|
|
96
|
+
|
|
97
|
+
## Tamaño en mobile y en web
|
|
98
|
+
|
|
99
|
+
La fila **no tiene `size`**: foto de 40 px, 12 px de relleno, texto de 14.
|
|
100
|
+
|
|
101
|
+
| uso | mobile | web | fuente |
|
|
102
|
+
|---|---|---|---|
|
|
103
|
+
| la fila | toda la fila se toca para abrirla: mide 64 px o más | igual | según el componente |
|
|
104
|
+
| ⋮ (`showMore`) | no aplica: aparece con el mouse | 24 px | según el componente |
|
|
105
|
+
| la X (`dismissible`) | 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 |
|
|
106
|
+
| botones de `type="button"` | los pone quien la usa: `[size]="bp.isMobile() ? 'large' : 'xsmall'"` | `xsmall` | propuesta |
|
|
107
|
+
|
|
108
|
+
## «No usar»: por qué no hoy y cuándo sí
|
|
109
|
+
|
|
110
|
+
| qué | por qué no hoy | cuándo sí, en un flujo nuevo |
|
|
111
|
+
|---|---|---|
|
|
112
|
+
| el modelo de alert (`variant` ≠ `default`, rellenos de color) | duplica a `sui-alert` | ninguno: es un alert |
|
|
113
|
+
| `type="button"` | nada se resuelve desde la bandeja | aceptar o rechazar una solicitud (una invitación a un equipo) desde la bandeja |
|
|
114
|
+
| `type="message"` | los avisos no traen texto de otra persona | la nota del cliente o un mensaje del repartidor |
|
|
115
|
+
| `type="file"` | no hay adjuntos | un comprobante o una boleta |
|
|
116
|
+
| `showMore` | solo se ve con mouse | acciones por fila en web |
|
|
117
|
+
| `active` | no se navega con teclado | bandeja con flechas del teclado |
|
|
118
|
+
| `dismissible` | se leen, no se cierran | una bandeja donde se borra aviso por aviso |
|
|
119
|
+
|
|
120
|
+
## API
|
|
121
|
+
|
|
122
|
+
<!-- api:inicio -->
|
|
123
|
+
<!-- generada: no editar a mano — `npm run docs` -->
|
|
124
|
+
|
|
125
|
+
| input | tipo | default |
|
|
126
|
+
|---|---|---|
|
|
127
|
+
| `variant` | `'info' \| 'success' \| 'warning' \| 'error' \| 'feature' \| 'default'` | `'default'` |
|
|
128
|
+
| `variantStyle` | `'filled' \| 'light' \| 'lighter' \| 'stroke'` | `'stroke'` |
|
|
129
|
+
| `title` | `string \| null` | `null` |
|
|
130
|
+
| `description` | `string \| null` | `null` |
|
|
131
|
+
| `timestamp` | `string \| null` | `null` |
|
|
132
|
+
| `avatar` | `SuiAvatarConfig \| string \| null` | `null` |
|
|
133
|
+
| `showIcon` | `boolean` | `true` |
|
|
134
|
+
| `dismissible` | `boolean` | `false` |
|
|
135
|
+
| `unread` | `boolean` | `false` |
|
|
136
|
+
| `type` | `'basic' \| 'file' \| 'button' \| 'message'` | `'basic'` |
|
|
137
|
+
| `showMore` | `boolean` | `false` |
|
|
138
|
+
| `active` | `boolean` | `false` |
|
|
139
|
+
|
|
140
|
+
| output | payload |
|
|
141
|
+
|---|---|
|
|
142
|
+
| `dismissed` | `void` |
|
|
143
|
+
| `moreClicked` | `MouseEvent` |
|
|
144
|
+
<!-- api:fin -->
|
|
145
|
+
|
|
146
|
+
Slots: `[slot=company-logo]`, `[slot=file]`, `[slot=message]`, el contenido libre, `[slot=actions]`.
|
|
147
|
+
|
|
148
|
+
## Trampas
|
|
149
|
+
|
|
150
|
+
- **La X se toca en 40 × 40** aunque se vea de 20 (un `::before` invisible sobre su `<button>`,
|
|
151
|
+
desde 03-10-2026): en una fila que se toca entera, el toque a 10 px de la X la cierra en vez de
|
|
152
|
+
abrirla.
|
|
153
|
+
- **Es el avatar el que decide el modelo**: con `avatar` es una fila plana (`role="article"`); sin
|
|
154
|
+
`avatar` es un alert con borde y sombra (`role="status"`, que el lector de pantalla anuncia).
|
|
155
|
+
- **El avatar no es `sui-avatar`**: lo dibuja la fila, en un círculo **negro** con iniciales.
|
|
156
|
+
Ignora `color`, así que no respeta el color por rol de la app (local naranja, repartidor verde,
|
|
157
|
+
cliente azul). Con foto no se nota; sin foto, sí.
|
|
158
|
+
- **La hora cambia de lugar**: sin avatar va a la derecha del título; con avatar, delante de la
|
|
159
|
+
descripción («Hace 5 min ∙ …»).
|
|
160
|
+
- `timestamp` es texto: el formato («Hace 5 min») lo arma quien la usa.
|
|
161
|
+
- `feature` usa `sparkling-fill` aquí y en el alert, y `magic-fill` en el banner.
|
|
162
|
+
- `dismissible` solo emite `(dismissed)`: la fila **no se esconde sola** (a diferencia de alert y
|
|
163
|
+
banner). La saca quien la usa.
|
|
164
|
+
- El ⋮ de `showMore` se ve solo con el mouse encima o con `active`: en mobile no aparece.
|
|
165
|
+
- **`showMore` y `dismissible` juntos se pisan**: el ⋮ y la X van los dos arriba a la derecha.
|
|
166
|
+
- Con avatar (o con `type` distinto de `basic`) y **sin `description`**, queda un «∙» colgando
|
|
167
|
+
después de la hora («Hace 8 min ∙»).
|
|
168
|
+
- Borra el `title` nativo del host.
|
|
169
|
+
|
|
170
|
+
## Ejemplo
|
|
171
|
+
|
|
172
|
+
```html
|
|
173
|
+
<div role="list">
|
|
174
|
+
<sui-notification role="listitem"
|
|
175
|
+
[avatar]="pedido.localLogo" title="Tu pedido llegó"
|
|
176
|
+
description="Pollería El Dorado · S/ 42.50" timestamp="Hace 5 min" [unread]="!n.read"
|
|
177
|
+
(click)="abrir(n)" />
|
|
178
|
+
</div>
|
|
179
|
+
```
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sui-notification-footer
|
|
3
|
+
selector: sui-notification-footer
|
|
4
|
+
resumen: Pie del panel desplegable de notificaciones (web): ayuda de teclado a la izquierda y un link a los ajustes a la derecha
|
|
5
|
+
alternativas: [sui-link-button (un link suelto a los ajustes), sui-drawer-footer (pie de un panel lateral), sui-modal-footer (pie con botones)]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# sui-notification-footer
|
|
9
|
+
|
|
10
|
+
Story: [Molecules/Feedback/Notification Footer](https://sui-design-system.web.app/?path=/docs/molecules-feedback-notification-footer--docs)
|
|
11
|
+
|
|
12
|
+
## Cuándo usarlo / cuándo no
|
|
13
|
+
|
|
14
|
+
**Úsalo** solo como **pie del panel de la campana** en web: el desplegable que abre la bandeja desde
|
|
15
|
+
la barra superior, con filas `sui-notification` y la cabecera `sui-notification-tab-menu`. Dice
|
|
16
|
+
«Usa ↑ ↓ para moverte» y lleva el link a los ajustes de notificaciones.
|
|
17
|
+
|
|
18
|
+
**No lo uses** para:
|
|
19
|
+
|
|
20
|
+
- La pantalla de notificaciones (la bandeja a pantalla completa): ahí los ajustes ya están en la
|
|
21
|
+
misma pantalla y nadie navega con flechas.
|
|
22
|
+
- Mobile: la mitad del componente es una ayuda de **teclado**.
|
|
23
|
+
- El pie de cualquier otro panel: `sui-drawer-footer` o `sui-modal-footer`.
|
|
24
|
+
|
|
25
|
+
## Qué variante usar
|
|
26
|
+
|
|
27
|
+
> La guía del DS no tiene página para este componente: sale del Figma del DS (pie del panel de
|
|
28
|
+
> notificaciones). Todo lo de abajo es **propuesta**, salvo lo marcado «según el componente».
|
|
29
|
+
>
|
|
30
|
+
> Uso medido el 03-10-2026 en `master-pedidos/src/app`: **0 usos**. La app no tiene panel
|
|
31
|
+
> desplegable de campana: su bandeja es una pantalla (`pages/notifications/`).
|
|
32
|
+
|
|
33
|
+
| prop | valor | cuándo | fuente |
|
|
34
|
+
|---|---|---|---|
|
|
35
|
+
| `usePrefix` · `useSuffix` | `'Usa'` · `'para moverte'` | Ya son los defaults (03-10-2026); no hace falta pasarlos. | canon (copy de la app: tuteo, español) |
|
|
36
|
+
| `manage` | `'Ajustes de notificaciones'` | El link a los ajustes. Emite `(manageClick)`. | propuesta |
|
|
37
|
+
| `manage` | `{ label, href }` | Cuando los ajustes son otra ruta: se dibuja un `<a>` de verdad. | según el componente |
|
|
38
|
+
| `manage` | `true` (default) | Dice «Administrar notificaciones» (en español desde 03-10-2026). | propuesta |
|
|
39
|
+
| `manage` | `false` · `null` | Cuando los ajustes ya están a la vista en el mismo panel. | propuesta |
|
|
40
|
+
|
|
41
|
+
## Tamaño en mobile y en web
|
|
42
|
+
|
|
43
|
+
**No tiene `size`**: texto de 12 y link `small` (16 px de alto).
|
|
44
|
+
|
|
45
|
+
| uso | mobile | web | fuente |
|
|
46
|
+
|---|---|---|---|
|
|
47
|
+
| el pie entero | no aplica: es ayuda de teclado; en mobile no se muestra | unos 48 px de alto | propuesta |
|
|
48
|
+
| el link de ajustes | si hiciera falta, un `sui-link-button` `large` suelto | `small` (16 px) | propuesta |
|
|
49
|
+
|
|
50
|
+
```html
|
|
51
|
+
@if (!bp.isMobile()) {
|
|
52
|
+
<sui-notification-footer usePrefix="Usa" useSuffix="para moverte"
|
|
53
|
+
manage="Ajustes de notificaciones" (manageClick)="abrirAjustes()" />
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## «No usar»: por qué no hoy y cuándo sí
|
|
58
|
+
|
|
59
|
+
| qué | por qué no hoy | cuándo sí, en un flujo nuevo |
|
|
60
|
+
|---|---|---|
|
|
61
|
+
| el componente | no hay panel de campana | si el panel del local o el super admin suman una campana con la bandeja desplegable en la barra superior (web) |
|
|
62
|
+
| `manage` con el texto por defecto | está en inglés | nunca: siempre un texto propio |
|
|
63
|
+
|
|
64
|
+
## API
|
|
65
|
+
|
|
66
|
+
<!-- api:inicio -->
|
|
67
|
+
<!-- generada: no editar a mano — `npm run docs` -->
|
|
68
|
+
|
|
69
|
+
| input | tipo | default |
|
|
70
|
+
|---|---|---|
|
|
71
|
+
| `usePrefix` | `string` | `'Usa'` |
|
|
72
|
+
| `useSuffix` | `string` | `'para moverte'` |
|
|
73
|
+
| `manage` | `SuiLinkConfig \| string \| boolean \| null` | `true` |
|
|
74
|
+
|
|
75
|
+
| output | payload |
|
|
76
|
+
|---|---|
|
|
77
|
+
| `manageClick` | `MouseEvent` |
|
|
78
|
+
<!-- api:fin -->
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
interface SuiLinkConfig { label: string; href?: string; target?: string; rel?: string; }
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Trampas
|
|
85
|
+
|
|
86
|
+
- **Textos por defecto en español** desde 03-10-2026: «Usa ↑ ↓ para moverte» y «Administrar
|
|
87
|
+
notificaciones» (antes «Use», «to navigate» y «Manage Notification»).
|
|
88
|
+
- Las teclas ↑ ↓ están fijas: no se pueden cambiar por otras.
|
|
89
|
+
- Con `href` y `target="_blank"` agrega `rel="noopener noreferrer"` solo.
|
|
90
|
+
- Ocupa el 100 % del ancho de su contenedor (el Figma lo dibuja de 540 px).
|
|
91
|
+
- Borra el `title` nativo del host.
|
|
92
|
+
|
|
93
|
+
## Ejemplo
|
|
94
|
+
|
|
95
|
+
```html
|
|
96
|
+
<sui-notification-footer usePrefix="Usa" useSuffix="para moverte"
|
|
97
|
+
[manage]="{ label: 'Ajustes de notificaciones', href: '/empresa/notificaciones' }" />
|
|
98
|
+
```
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sui-notification-tab-menu
|
|
3
|
+
selector: sui-notification-tab-menu
|
|
4
|
+
resumen: Cabecera con pestañas del panel desplegable de notificaciones (web), con conteo de no leídas y botón de filtro
|
|
5
|
+
alternativas: [sui-tab-chips (pestañas de la bandeja a pantalla completa, en mobile), sui-tab-menu-horizontal (pestañas de una pantalla), sui-segmented-control (cambiar de vista con 2–4 opciones)]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# sui-notification-tab-menu
|
|
9
|
+
|
|
10
|
+
Story: [Molecules/Feedback/Notification Tab Menu](https://sui-design-system.web.app/?path=/docs/molecules-feedback-notification-tab-menu--docs)
|
|
11
|
+
|
|
12
|
+
## Cuándo usarlo / cuándo no
|
|
13
|
+
|
|
14
|
+
**Úsalo** solo como **cabecera del panel de la campana** en web: «Todas · No leídas (3) · Pedidos |
|
|
15
|
+
Archivadas» con el filtro a la derecha, encima de las filas `sui-notification`.
|
|
16
|
+
|
|
17
|
+
**No lo uses** para:
|
|
18
|
+
|
|
19
|
+
- La bandeja a pantalla completa y en mobile: la app usa `sui-tab-chips` («Todas», «No leídas (3)»)
|
|
20
|
+
en `pages/notifications/notifications.html:47`, que se toca mejor con el dedo. Es lo correcto.
|
|
21
|
+
- Las pestañas de cualquier otra pantalla: `sui-tab-menu-horizontal`.
|
|
22
|
+
|
|
23
|
+
## Qué variante usar
|
|
24
|
+
|
|
25
|
+
> La guía del DS no tiene página para este componente: sale del Figma del DS (cabecera del panel
|
|
26
|
+
> de notificaciones). Todo lo de abajo es **propuesta**, salvo lo marcado «según el componente».
|
|
27
|
+
>
|
|
28
|
+
> Uso medido el 03-10-2026 en `master-pedidos/src/app`: **0 usos** (no hay panel de campana).
|
|
29
|
+
|
|
30
|
+
| prop | valor | cuándo | fuente |
|
|
31
|
+
|---|---|---|---|
|
|
32
|
+
| `tabs` | 2 a 4 pestañas | «Todas» primero, luego «No leídas» y los grupos del rol (Pedidos, Promos, Encargos…). Más de 4 no caben en el panel. | propuesta |
|
|
33
|
+
| `tabs[].badge` | número > 0 | El conteo de **no leídas**, solo en la pestaña donde importa. Es un `sui-badge` rojo lleno: un conteo que pide acción. | según el componente · regla de badge: canon |
|
|
34
|
+
| `tabs[].dividerBefore` | `true` | Separa lo que no es bandeja activa: «Archivadas» al final. | según el componente (Figma) |
|
|
35
|
+
| `[(active)]` | el `value` de la pestaña | Siempre enlazado: es un model de dos vías. | según el componente |
|
|
36
|
+
| `showFilter` | `true` (default) | Solo si el panel tiene filtros de verdad (por local, por fecha). | propuesta |
|
|
37
|
+
| `showFilter` | `false` | Lo normal: sin filtros, un botón que no hace nada estorba. | propuesta |
|
|
38
|
+
| `filterLabel` | texto | El nombre del botón de filtro para el lector de pantalla. Default «Filtrar». | según el componente |
|
|
39
|
+
|
|
40
|
+
## Tamaño en mobile y en web
|
|
41
|
+
|
|
42
|
+
**No tiene `size`**: la fila mide 48 px, pero cada pestaña es un botón de **20 px de alto** (solo el
|
|
43
|
+
texto) y el filtro es un compact-button de 24 px.
|
|
44
|
+
|
|
45
|
+
| uso | mobile | web | fuente |
|
|
46
|
+
|---|---|---|---|
|
|
47
|
+
| las pestañas | **no alcanza**: 20 px de alto para el dedo. Usar `sui-tab-chips` | 20 px de alto, en una fila de 48 | sin tamaño suficiente (no se cambia aquí) |
|
|
48
|
+
| el filtro | 24 px, **bajo el mínimo de 32 px** en mobile | 24 px | sin tamaño suficiente |
|
|
49
|
+
|
|
50
|
+
```html
|
|
51
|
+
@if (bp.isMobile()) {
|
|
52
|
+
<sui-tab-chips [chips]="pestanas" [value]="activa()" (valueChange)="activa.set($event)" />
|
|
53
|
+
} @else {
|
|
54
|
+
<sui-notification-tab-menu [tabs]="pestanas" [(active)]="activa" [showFilter]="false" />
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## «No usar»: por qué no hoy y cuándo sí
|
|
59
|
+
|
|
60
|
+
| qué | por qué no hoy | cuándo sí, en un flujo nuevo |
|
|
61
|
+
|---|---|---|
|
|
62
|
+
| el componente | no hay panel de campana; la bandeja es una pantalla con `sui-tab-chips` | si el panel del local o el super admin suman la campana con bandeja desplegable en web |
|
|
63
|
+
| `showFilter` | no hay filtros en la bandeja | filtrar avisos por local (central con varios locales) o por fecha |
|
|
64
|
+
| `dividerBefore` | no hay «Archivadas» | si se agrega archivar avisos |
|
|
65
|
+
|
|
66
|
+
## API
|
|
67
|
+
|
|
68
|
+
<!-- api:inicio -->
|
|
69
|
+
<!-- generada: no editar a mano — `npm run docs` -->
|
|
70
|
+
|
|
71
|
+
| input | tipo | default |
|
|
72
|
+
|---|---|---|
|
|
73
|
+
| `tabs` | `SuiNotificationTab<T>[]` | — (requerido) |
|
|
74
|
+
| `active` · model, `[(active)]` | `T` | `undefined` |
|
|
75
|
+
| `showFilter` | `boolean` | `true` |
|
|
76
|
+
| `filterLabel` | `string` | `'Filtrar'` |
|
|
77
|
+
|
|
78
|
+
| output | payload |
|
|
79
|
+
|---|---|
|
|
80
|
+
| `tabChange` | `T` |
|
|
81
|
+
| `filterClick` | `MouseEvent` |
|
|
82
|
+
<!-- api:fin -->
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
interface SuiNotificationTab<T = string> {
|
|
86
|
+
value: T;
|
|
87
|
+
label: string;
|
|
88
|
+
badge?: number; // > 0 lo muestra
|
|
89
|
+
dividerBefore?: boolean; // línea vertical antes de esta pestaña
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Trampas
|
|
94
|
+
|
|
95
|
+
- **`showFilter` arranca en `true`**: si no pasas `false`, aparece un botón de filtro.
|
|
96
|
+
- `tabs` es **obligatorio** y `active` es un model: `[(active)]`, no `[value]` como en `sui-tab-chips`.
|
|
97
|
+
- La raya de la pestaña activa usa el primario de la app (naranja), no el azul del Figma.
|
|
98
|
+
- El badge no tiene tope: 120 sale «120». Si hace falta, el texto lo recorta quien lo usa («99+» va
|
|
99
|
+
en `label`, no en `badge`, porque `badge` es un número).
|
|
100
|
+
- El host lleva `role="tablist"` y cada pestaña `role="tab"` con `aria-selected`; no hay panel `tabpanel` asociado: lo arma quien lo usa.
|
|
101
|
+
|
|
102
|
+
## Ejemplo
|
|
103
|
+
|
|
104
|
+
```html
|
|
105
|
+
<sui-notification-tab-menu [showFilter]="false" [(active)]="pestana"
|
|
106
|
+
[tabs]="[
|
|
107
|
+
{ value: 'todas', label: 'Todas' },
|
|
108
|
+
{ value: 'no-leidas', label: 'No leídas', badge: 3 },
|
|
109
|
+
{ value: 'pedidos', label: 'Pedidos' },
|
|
110
|
+
{ value: 'archivadas', label: 'Archivadas', dividerBefore: true },
|
|
111
|
+
]" />
|
|
112
|
+
```
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sui-otp-input
|
|
3
|
+
selector: sui-otp-input
|
|
4
|
+
resumen: Código de verificación dígito por dígito, una celda por número (SMS, código de entrega)
|
|
5
|
+
alternativas: [sui-input (un código largo o que se pega entero), sui-input type="password-toggle" (una clave que no se ve)]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# sui-otp-input
|
|
9
|
+
|
|
10
|
+
Story: [Molecules/Input/Otp Input](https://sui-design-system.web.app/?path=/docs/molecules-input-otp-input--docs)
|
|
11
|
+
|
|
12
|
+
## Cuándo usarlo / cuándo no
|
|
13
|
+
|
|
14
|
+
**Úsalo** para un código corto que llega por otro canal y se copia dígito por dígito: un código
|
|
15
|
+
por SMS o WhatsApp, o un código de entrega que el cliente le dicta al repartidor. Salta solo a la
|
|
16
|
+
celda siguiente, retrocede con borrar, reparte lo que se pega y avisa con `(completed)` cuando
|
|
17
|
+
está lleno. La primera celda pide `autocomplete="one-time-code"` (el teléfono sugiere el código
|
|
18
|
+
del SMS).
|
|
19
|
+
|
|
20
|
+
**No lo uses** para:
|
|
21
|
+
|
|
22
|
+
- Una contraseña o PIN que se elige: `sui-input type="password-toggle"`.
|
|
23
|
+
- Un código de más de 6 caracteres o con letras y guiones (un cupón): `sui-input`.
|
|
24
|
+
|
|
25
|
+
Regla corta: **código corto que llega por otro canal → otp · cupón o clave → input.**
|
|
26
|
+
|
|
27
|
+
## Qué variante usar
|
|
28
|
+
|
|
29
|
+
> **La guía del DS lo define como el campo para escribir códigos de un solo uso dígito por dígito,
|
|
30
|
+
> pensado para flujos de verificación** con códigos numéricos cortos. Muestra error, deshabilitado
|
|
31
|
+
> y celdas cuadradas. No dice cuántas celdas.
|
|
32
|
+
>
|
|
33
|
+
> Uso medido el 03-10-2026 en `master-pedidos/src/app`: **0 usos**. Hoy no hay login por SMS ni
|
|
34
|
+
> código de entrega.
|
|
35
|
+
|
|
36
|
+
| prop / evento | cuándo | fuente |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| `type="number"` (default) | Códigos numéricos: teclado de números. | según la guía del DS (códigos numéricos) |
|
|
39
|
+
| `type="text"` | No usar hoy: un código con letras se tipea mejor en un `sui-input`. | propuesta, falta aprobación |
|
|
40
|
+
| `length` | `6` para un SMS (lo que manda Firebase); `4` para un código de entrega dictado en voz alta. | propuesta, falta aprobación |
|
|
41
|
+
| `error` | El código no coincide. Pinta todas las celdas; el mensaje va aparte, debajo. | según la guía del DS (ejemplo con error) |
|
|
42
|
+
| `disabled` | Mientras se verifica el código. | según la guía del DS (ejemplo deshabilitado) |
|
|
43
|
+
| `ariaLabel` | Qué código es: «Código que te llegó por SMS». El default es «Código de verificación». | propuesta, falta aprobación |
|
|
44
|
+
| `(completed)` | Verificar apenas se llena, sin botón «Continuar». | propuesta, falta aprobación |
|
|
45
|
+
|
|
46
|
+
## Tamaño en mobile y en web
|
|
47
|
+
|
|
48
|
+
Tiene `size` (extensión SUI) para la celda. `large` es el de la guía y el default: **80 × 64** con 8
|
|
49
|
+
px entre celdas (6 celdas = 520 px). Para el teléfono, **`medium` (52 × 56)**: 6 celdas miden 352
|
|
50
|
+
px y entran en los 358 útiles de una pantalla de 390. `small` (44 × 48, dígito de 20) queda para
|
|
51
|
+
360 px o un código dentro de una tarjeta.
|
|
52
|
+
|
|
53
|
+
Además, **el componente nunca es más ancho que su contenedor**: si las celdas no entran, se achican
|
|
54
|
+
parejo en vez de salirse de la pantalla (un `large` de 6 en 390 queda en celdas de 53 × 64). Es la red
|
|
55
|
+
de seguridad, no el tamaño a elegir: se ve angosto y alto.
|
|
56
|
+
|
|
57
|
+
| size | celda | 6 celdas | fuente |
|
|
58
|
+
|---|---|---|---|
|
|
59
|
+
| `large` (default) | 80 × 64 · dígito 24 | 520 px | según la guía del DS |
|
|
60
|
+
| `medium` | 52 × 56 · dígito 24 | 352 px | canon (aprobado por el dueño, 03-10-2026), extensión SUI |
|
|
61
|
+
| `small` | 44 × 48 · dígito 20 | 304 px | canon (aprobado por el dueño, 03-10-2026), extensión SUI |
|
|
62
|
+
|
|
63
|
+
| uso | mobile (390) | web | fuente |
|
|
64
|
+
|---|---|---|---|
|
|
65
|
+
| código de 6 dígitos | `medium` | `large` | propuesta, falta aprobación |
|
|
66
|
+
| código de 4 dígitos | `large` (344 px, entra) | `large` | propuesta, falta aprobación |
|
|
67
|
+
|
|
68
|
+
```html
|
|
69
|
+
<sui-otp-input [length]="6" [size]="bp.isMobile() ? 'medium' : 'large'" [(value)]="codigo" />
|
|
70
|
+
<!-- bp = BreakpointsService -->
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## «No usar»: por qué no hoy y cuándo sí
|
|
74
|
+
|
|
75
|
+
| qué | por qué no hoy | cuándo sí, en un flujo nuevo |
|
|
76
|
+
|---|---|---|
|
|
77
|
+
| el componente entero (0 usos) | no hay verificación por código | verificar el teléfono del cliente por SMS, o un código de entrega de 4 dígitos que el cliente le dicta al repartidor |
|
|
78
|
+
| `type="text"` | los códigos que llegan son numéricos | un código alfanumérico corto de una campaña |
|
|
79
|
+
| `size="small"` | `medium` ya entra en 390 | pantallas de 360 px o un código dentro de una tarjeta |
|
|
80
|
+
|
|
81
|
+
## API
|
|
82
|
+
|
|
83
|
+
<!-- api:inicio -->
|
|
84
|
+
<!-- generada: no editar a mano — `npm run docs` -->
|
|
85
|
+
|
|
86
|
+
| input | tipo | default |
|
|
87
|
+
|---|---|---|
|
|
88
|
+
| `length` | `number` | `6` |
|
|
89
|
+
| `size` | `'large' \| 'medium' \| 'small'` | `'large'` |
|
|
90
|
+
| `type` | `'number' \| 'text'` | `'number'` |
|
|
91
|
+
| `disabled` · model, `[(disabled)]` | `boolean` | `false` |
|
|
92
|
+
| `error` | `boolean` | `false` |
|
|
93
|
+
| `ariaLabel` | `string` | `'Código de verificación'` |
|
|
94
|
+
| `value` · model, `[(value)]` | `string` | `''` |
|
|
95
|
+
|
|
96
|
+
| output | payload |
|
|
97
|
+
|---|---|
|
|
98
|
+
| `completed` | `string` |
|
|
99
|
+
<!-- api:fin -->
|
|
100
|
+
|
|
101
|
+
`value` y `disabled` son `model`. Implementa `ControlValueAccessor`.
|
|
102
|
+
|
|
103
|
+
## Trampas
|
|
104
|
+
|
|
105
|
+
- **6 celdas `large` no entran en un teléfono** (520 px): se achican solas, pero en mobile va
|
|
106
|
+
`size="medium"`. Ver «Tamaño en mobile y en web».
|
|
107
|
+
- `error` no trae mensaje: el texto va debajo, con `sui-form-hint` en variante error.
|
|
108
|
+
- `disabled` es un `model`: si el formulario lo deshabilita, el componente lo escribe de vuelta.
|
|
109
|
+
- No hay grupos (3-3): si se necesitan, son dos componentes.
|
|
110
|
+
|
|
111
|
+
## Ejemplo
|
|
112
|
+
|
|
113
|
+
```html
|
|
114
|
+
<sui-otp-input [length]="4" ariaLabel="Código de entrega" [error]="codigoMalo()"
|
|
115
|
+
[(value)]="codigo" (completed)="verificar($event)" />
|
|
116
|
+
```
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sui-pagination
|
|
3
|
+
selector: sui-pagination
|
|
4
|
+
resumen: Números de página para recorrer una tabla larga en web cuando todos los datos ya están cargados
|
|
5
|
+
alternativas: [scroll infinito (directiva appInfiniteScroll de la app, para listas de Firestore), sui-stepper (pasos de un flujo), sui-tab-chips (filtrar en vez de paginar)]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# sui-pagination
|
|
9
|
+
|
|
10
|
+
Story: [Molecules/Pagination](https://sui-design-system.web.app/?path=/docs/molecules-pagination--docs)
|
|
11
|
+
|
|
12
|
+
## Cuándo usarlo / cuándo no
|
|
13
|
+
|
|
14
|
+
**Úsalo** en **web**, debajo de una **tabla larga cuyos datos ya están en memoria** (un reporte, un
|
|
15
|
+
export, una tabla filtrada en el navegador), cuando ayuda saber «voy por la 3 de 12» o saltar a una
|
|
16
|
+
página.
|
|
17
|
+
|
|
18
|
+
**No lo uses** para:
|
|
19
|
+
|
|
20
|
+
- **Mobile**: las listas se recorren con el dedo. Va scroll infinito (la directiva
|
|
21
|
+
`appInfiniteScroll` que ya usan productos, clientes y equipo).
|
|
22
|
+
- **Listas que se leen de Firestore por cursor** (`getCollectionPage`): con cursores solo se puede
|
|
23
|
+
pedir la página siguiente. Saltar a la página 7 obliga a leer las 6 anteriores, y Firestore las
|
|
24
|
+
cobra igual. El canon de la app para esas listas es scroll infinito (CLAUDE.md, «Performance —
|
|
25
|
+
Firestore reads»).
|
|
26
|
+
- Pasos de un flujo: `sui-stepper`.
|
|
27
|
+
- Pocas filas (una sola página): no se muestra.
|
|
28
|
+
|
|
29
|
+
Regla corta: **tabla con todo cargado en web → pagination · lista de Firestore o mobile → scroll infinito.**
|
|
30
|
+
|
|
31
|
+
## Qué variante usar
|
|
32
|
+
|
|
33
|
+
> **Lo que dice la guía del DS**: es un conjunto horizontal de enlaces para **navegar contenido
|
|
34
|
+
> paginado**. Trae tres formas: `basic`, `rounded` (en SUI, `full-radius`) y `group`, más botones
|
|
35
|
+
> de primera/última y anterior/siguiente, y la página actual marcada. No trae do/don't ni dice
|
|
36
|
+
> cuándo cada forma.
|
|
37
|
+
>
|
|
38
|
+
> Uso medido el 03-10-2026 en `master-pedidos/src/app` (misma exclusión que `sui-badge`): **0 usos**.
|
|
39
|
+
> Las 3 listas largas de la app (`pages/products/products.html:242`, `pages/customers/customers.html:161`,
|
|
40
|
+
> `pages/settings/team/team.ts:347`) usan scroll infinito.
|
|
41
|
+
|
|
42
|
+
### `type`
|
|
43
|
+
|
|
44
|
+
| type | cuándo | fuente |
|
|
45
|
+
|---|---|---|
|
|
46
|
+
| `basic` (default) | El normal, debajo de una tabla con bordes. | según la guía del DS (es su default); el cuándo es propuesta |
|
|
47
|
+
| `group` | Cuando la tabla va dentro de una card y la paginación se apoya en su borde: un solo bloque se lee como parte de la tabla. | según la guía del DS (la forma existe); el cuándo es propuesta |
|
|
48
|
+
| `full-radius` | No: el resto de los controles de la app (botones, inputs) tienen esquinas de 8-10, no círculos. | según la guía del DS (la forma existe); el no es propuesta |
|
|
49
|
+
|
|
50
|
+
### `size`
|
|
51
|
+
|
|
52
|
+
| size | qué mide | cuándo | fuente |
|
|
53
|
+
|---|---|---|---|
|
|
54
|
+
| `medium` (default) | celdas de 32 px | Web, debajo de una tabla. | extensión de SUI (la guía tiene un tamaño); el cuándo es propuesta |
|
|
55
|
+
| `small` | celdas de 28 px | Web, en una tabla dentro de un modal o panel angosto. | propuesta, falta aprobación |
|
|
56
|
+
|
|
57
|
+
### Botones y texto
|
|
58
|
+
|
|
59
|
+
| input | valor | cuándo | fuente |
|
|
60
|
+
|---|---|---|---|
|
|
61
|
+
| `nextPrevious` | `true` (default) | Siempre. | según la guía del DS |
|
|
62
|
+
| `firstLast` | `false` (default) | Lo normal: con las elipsis ya se ve la primera y la última. | propuesta, falta aprobación |
|
|
63
|
+
| `firstLast` | `true` | Más de 20 páginas, donde ir al final es un caso de uso (la última semana de un export). | según la guía del DS (los botones existen); el cuándo es propuesta |
|
|
64
|
+
| `siblingCount` | `1` (default) | Siempre. Más números a cada lado ensanchan sin ayudar. | propuesta, falta aprobación |
|
|
65
|
+
| `showInfo` | `true` (default) | Con `infoFormat="items"`: «Mostrando 11-20 de 134». | propuesta, falta aprobación |
|
|
66
|
+
| `infoFormat` | `'items'` (default) | El único en español. | según el código |
|
|
67
|
+
| `infoFormat` | `'pages'` | Imprime «Página 2 de 14» (en español desde 03-10-2026). Cuando no se sabe el total de ítems o no importa. | propuesta, falta aprobación |
|
|
68
|
+
| `pageSizeOptions` | `[]` (default) | Lo normal: sin selector de filas por página. | propuesta, falta aprobación |
|
|
69
|
+
| `pageSizeOptions` | `[10, 25, 50]` | Las opciones dicen «10 / página» (en español desde 03-10-2026). | propuesta, falta aprobación |
|
|
70
|
+
|
|
71
|
+
Usos de hoy que rompen las reglas: **0** (no se usa).
|
|
72
|
+
|
|
73
|
+
## Tamaño en mobile y en web
|
|
74
|
+
|
|
75
|
+
**No tiene tamaño para mobile**: la celda más grande mide 32 px, por debajo de los 44 tocables. En
|
|
76
|
+
mobile no se usa.
|
|
77
|
+
|
|
78
|
+
| uso | mobile | web | fuente |
|
|
79
|
+
|---|---|---|---|
|
|
80
|
+
| debajo de una tabla | no se usa: scroll infinito | `medium` (32) | propuesta, falta aprobación |
|
|
81
|
+
| tabla en un panel angosto | no se usa | `small` (28) | propuesta, falta aprobación |
|
|
82
|
+
|
|
83
|
+
```html
|
|
84
|
+
@if (!bp.isMobile()) {
|
|
85
|
+
<sui-pagination [total]="filas().length" [(currentPage)]="pagina" [pageSize]="25" />
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## «No usar»: por qué no hoy y cuándo sí
|
|
90
|
+
|
|
91
|
+
| qué | por qué no hoy | cuándo sí, en un flujo nuevo |
|
|
92
|
+
|---|---|---|
|
|
93
|
+
| el componente entero | las listas de la app leen de Firestore por cursor y usan scroll infinito | una tabla de web con todos los datos ya cargados (un reporte de 300 filas filtrado en el navegador) |
|
|
94
|
+
| `full-radius` | no combina con las esquinas del resto de la app | nunca, salvo que la app pase a botones redondos |
|
|
95
|
+
| `infoFormat="pages"` | sale en inglés | cuando el DS lo traduzca («Página 2 de 14») |
|
|
96
|
+
| `firstLast` | ninguna tabla tiene 20+ páginas | un export largo donde ir al final es habitual |
|
|
97
|
+
|
|
98
|
+
## API
|
|
99
|
+
|
|
100
|
+
<!-- api:inicio -->
|
|
101
|
+
<!-- generada: no editar a mano — `npm run docs` -->
|
|
102
|
+
|
|
103
|
+
| input | tipo | default |
|
|
104
|
+
|---|---|---|
|
|
105
|
+
| `total` | `number` | — (requerido) |
|
|
106
|
+
| `pageSize` · model, `[(pageSize)]` | `number` | `10` |
|
|
107
|
+
| `siblingCount` | `number` | `1` |
|
|
108
|
+
| `showInfo` | `boolean` | `true` |
|
|
109
|
+
| `size` | `'small' \| 'medium'` | `'medium'` |
|
|
110
|
+
| `type` | `'basic' \| 'full-radius' \| 'group'` | `'basic'` |
|
|
111
|
+
| `firstLast` | `boolean` | `false` |
|
|
112
|
+
| `nextPrevious` | `boolean` | `true` |
|
|
113
|
+
| `infoFormat` | `'items' \| 'pages'` | `'items'` |
|
|
114
|
+
| `pageSizeOptions` | `readonly number[]` | `[]` |
|
|
115
|
+
| `currentPage` · model, `[(currentPage)]` | `number` | `1` |
|
|
116
|
+
|
|
117
|
+
| output | payload |
|
|
118
|
+
|---|---|
|
|
119
|
+
| `pageChange` | `number` |
|
|
120
|
+
| `pageSizeChange` | `number` |
|
|
121
|
+
<!-- api:fin -->
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
type SuiPaginationType = 'basic' | 'full-radius' | 'group';
|
|
125
|
+
type SuiPaginationSize = 'small' | 'medium';
|
|
126
|
+
type SuiPaginationInfoFormat = 'items' | 'pages';
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Trampas
|
|
130
|
+
|
|
131
|
+
- **`total` es la cantidad de ítems, no de páginas.** Las páginas salen de `total / pageSize`.
|
|
132
|
+
- **`currentPage` arranca en 1** (el stepper arranca en 0).
|
|
133
|
+
- **`currentPage` y `pageSize` son `model`**: con `[(currentPage)]` no hace falta `(pageChange)`.
|
|
134
|
+
- **No carga datos**: solo dice qué página se pidió. Cortar las filas lo hace la pantalla.
|
|
135
|
+
- **Textos en español** desde 03-10-2026: «Página X de Y» (`infoFormat="pages"`), «N / página»
|
|
136
|
+
(`pageSizeOptions`) y el default «Mostrando X-Y de Z».
|
|
137
|
+
- **La página actual se pinta con `bg-weak-50`**, el mismo gris de las superficies de fondo: sobre
|
|
138
|
+
una card gris o un fondo `weak-50` no se distingue cuál es. Ponla sobre blanco.
|
|
139
|
+
- **Con `total` en 0 no dibuja el texto**, pero sí los botones (una sola página «1»). Ocúltalo tú.
|
|
140
|
+
- Las flechas son `<i class="ri-…">`: necesitan la fuente de Remix Icon cargada.
|
|
141
|
+
|
|
142
|
+
## Ejemplo
|
|
143
|
+
|
|
144
|
+
```html
|
|
145
|
+
<sui-pagination [total]="134" [pageSize]="10" [(currentPage)]="pagina" type="group" />
|
|
146
|
+
```
|