@ajuarezso/sui-design-system 0.21.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.
- package/docs/INDEX.md +30 -35
- package/docs/sui-accordion/README.md +171 -0
- package/docs/sui-activity-feed/README.md +154 -0
- package/docs/sui-activity-filter/README.md +100 -0
- package/docs/sui-alert/README.md +28 -19
- package/docs/sui-app-store-badge/README.md +5 -4
- package/docs/sui-avatar/README.md +16 -16
- package/docs/sui-avatar-group/README.md +4 -4
- package/docs/sui-badge/README.md +27 -9
- package/docs/sui-banner/README.md +10 -9
- package/docs/sui-brand-logo/README.md +3 -3
- package/docs/sui-breadcrumbs/README.md +1 -1
- package/docs/sui-button/README.md +64 -21
- package/docs/sui-button-group/README.md +6 -4
- package/docs/sui-button-group-item/README.md +3 -3
- package/docs/sui-card/README.md +17 -19
- package/docs/sui-chart-legend/README.md +8 -7
- package/docs/sui-checkbox/README.md +11 -6
- package/docs/sui-checkbox-card/README.md +24 -19
- package/docs/sui-checkbox-label/README.md +32 -10
- package/docs/sui-circular-progress-bar/README.md +2 -0
- package/docs/sui-color-dot/README.md +1 -1
- package/docs/sui-color-picker/README.md +22 -7
- package/docs/sui-command-menu-footer/README.md +100 -0
- package/docs/sui-command-menu-item/README.md +140 -0
- package/docs/sui-command-menu-search/README.md +105 -0
- package/docs/sui-compact-avatar-group/README.md +4 -3
- package/docs/sui-compact-button/README.md +41 -44
- package/docs/sui-compact-select/README.md +12 -5
- package/docs/sui-compact-select-for-input/README.md +5 -2
- package/docs/sui-content-card/README.md +6 -5
- package/docs/sui-content-divider/README.md +4 -4
- package/docs/sui-content-label/README.md +11 -6
- package/docs/sui-counter-input/README.md +21 -17
- package/docs/sui-date-selector/README.md +16 -12
- package/docs/sui-datepicker/README.md +46 -28
- package/docs/sui-day-cell/README.md +17 -8
- package/docs/sui-day-label/README.md +2 -2
- package/docs/sui-divider/README.md +5 -5
- package/docs/sui-drawer-footer/README.md +19 -5
- package/docs/sui-dropdown-caption/README.md +92 -0
- package/docs/sui-dropdown-item/README.md +163 -0
- package/docs/sui-dropdown-menu/README.md +196 -0
- package/docs/sui-dropdown-search/README.md +113 -0
- package/docs/sui-emoji/README.md +6 -6
- package/docs/sui-empty-state/README.md +13 -23
- package/docs/sui-fancy-button/README.md +24 -18
- package/docs/sui-file-icon/README.md +1 -1
- package/docs/sui-file-upload/README.md +3 -0
- package/docs/sui-file-upload-card/README.md +8 -7
- package/docs/sui-filter/README.md +181 -0
- package/docs/sui-flag/README.md +3 -2
- package/docs/sui-form-hint/README.md +12 -8
- package/docs/sui-form-label/README.md +11 -16
- package/docs/sui-href/README.md +85 -0
- package/docs/sui-icon/README.md +4 -3
- package/docs/sui-image-upload/README.md +28 -16
- package/docs/sui-img-retry/README.md +107 -0
- package/docs/sui-inline-input/README.md +7 -6
- package/docs/sui-inline-select/README.md +8 -5
- package/docs/sui-input/README.md +27 -33
- package/docs/sui-integration-switch/README.md +14 -7
- package/docs/sui-kbd/README.md +4 -4
- package/docs/sui-key-icon/README.md +6 -2
- package/docs/sui-link-button/README.md +21 -17
- package/docs/sui-modal/README.md +238 -0
- package/docs/sui-modal-footer/README.md +178 -0
- package/docs/sui-modal-header/README.md +115 -0
- package/docs/sui-modal-sheet/README.md +170 -0
- package/docs/sui-notification/README.md +8 -6
- package/docs/sui-notification-footer/README.md +2 -2
- package/docs/sui-notification-tab-menu/README.md +5 -3
- package/docs/sui-page-header/README.md +123 -0
- package/docs/sui-pagination/README.md +8 -5
- package/docs/sui-password-strength/README.md +1 -1
- package/docs/sui-period-range/README.md +18 -14
- package/docs/sui-popover/README.md +13 -7
- package/docs/sui-product-card/README.md +14 -10
- package/docs/sui-progress-bar/README.md +4 -2
- package/docs/sui-progress-bar-label/README.md +2 -0
- package/docs/sui-radio/README.md +14 -7
- package/docs/sui-radio-card/README.md +12 -12
- package/docs/sui-radio-label/README.md +36 -11
- package/docs/sui-rating/README.md +28 -9
- package/docs/sui-rich-editor/README.md +3 -3
- package/docs/sui-segmented-control/README.md +33 -19
- package/docs/sui-select/README.md +40 -33
- package/docs/sui-sidebar/README.md +216 -0
- package/docs/sui-slider/README.md +7 -0
- package/docs/sui-social-button/README.md +24 -11
- package/docs/sui-status-badge/README.md +7 -3
- package/docs/sui-stepper/README.md +30 -17
- package/docs/sui-store-card/README.md +9 -4
- package/docs/sui-switch/README.md +16 -11
- package/docs/sui-switch-card/README.md +18 -16
- package/docs/sui-switch-label/README.md +25 -11
- package/docs/sui-tab-chips/README.md +56 -39
- package/docs/sui-tab-menu-horizontal/README.md +19 -11
- package/docs/sui-tab-menu-vertical/README.md +10 -5
- package/docs/sui-table/README.md +264 -0
- package/docs/sui-tag/README.md +25 -11
- package/docs/sui-tag-input/README.md +25 -12
- package/docs/sui-textarea/README.md +23 -20
- package/docs/sui-time-picker/README.md +39 -30
- package/docs/sui-toast/README.md +27 -22
- package/docs/sui-tooltip/README.md +14 -17
- package/docs/sui-topbar/README.md +153 -0
- package/docs/sui-topbar-button/README.md +95 -0
- package/docs/sui-topbar-item/README.md +97 -0
- package/docs/sui-topbar-user/README.md +83 -0
- package/fesm2022/ajuarezso-sui-design-system.mjs +1076 -242
- package/fesm2022/ajuarezso-sui-design-system.mjs.map +1 -1
- package/package.json +1 -1
- package/types/ajuarezso-sui-design-system.d.ts +616 -280
|
@@ -28,40 +28,30 @@ algo que avisar → alert.**
|
|
|
28
28
|
## Qué variante usar
|
|
29
29
|
|
|
30
30
|
> **La guía del DS no tiene página del empty state.** El componente de SUI se construyó a
|
|
31
|
-
> propósito con Fluent Emoji animados en vez de ilustraciones: es una decisión del proyecto
|
|
32
|
-
> (
|
|
31
|
+
> propósito con Fluent Emoji animados en vez de ilustraciones: es una decisión del proyecto, escrita
|
|
32
|
+
> en CANON-SUI §5.6 (ilustración = Fluent Emoji animado, default el zorro).
|
|
33
33
|
>
|
|
34
|
-
> Uso medido el
|
|
35
|
-
> empty-states en 40 archivos**.
|
|
36
|
-
>
|
|
37
|
-
> que el componente no tiene.
|
|
34
|
+
> Uso medido el 04-10-2026 en `master-pedidos/src/app` (misma exclusión que `sui-card`): **66
|
|
35
|
+
> empty-states en 40 archivos**. 29 con `action` (10 con `route`). 8 con `emoji` propio y 58 sin
|
|
36
|
+
> `emoji` (sale el zorro). 0 con `icon`, 0 con la URL del zorro pegada, 0 con `size`.
|
|
38
37
|
|
|
39
38
|
### Las piezas
|
|
40
39
|
|
|
41
40
|
| prop | cuándo | fuente |
|
|
42
41
|
|---|---|---|
|
|
43
|
-
| `emoji` vacío (default: el zorro) | Lo normal. El zorro es la mascota de los empty states y sale solo: **no pegues su URL**. | canon (
|
|
44
|
-
| `emoji` propio | Cuando el emoji dice algo del caso: el reloj de arena en «Aún no tienes facturas» (se está esperando algo), el chef en los avisos del local. Siempre de `FLUENT_EMOJI_ANIM` (`core/fluent-emoji.ts`) o de `assets/emoji-anim/`. | canon (
|
|
45
|
-
| `title` (obligatorio) | Qué pasa,
|
|
46
|
-
| `subtitle` |
|
|
42
|
+
| `emoji` vacío (default: el zorro) | Lo normal. El zorro es la mascota de los empty states y sale solo: **no pegues su URL**. | canon (CANON-SUI §5.6) |
|
|
43
|
+
| `emoji` propio | Cuando el emoji dice algo del caso: el reloj de arena en «Aún no tienes facturas» (se está esperando algo), el chef en los avisos del local. Siempre de `FLUENT_EMOJI_ANIM` (`core/fluent-emoji.ts`) o de `assets/emoji-anim/`. | canon (CANON-SUI §5.6: Fluent Emoji animado) |
|
|
44
|
+
| `title` (obligatorio) | Qué pasa, sin punto y en 2 a 4 palabras, con uno de tres patrones: «Todavía no hay <cosa>», «Sin <cosa>», «Tu <cosa> está vacío» («Tu carrito está vacío», «Sin pedidos aún»). En una búsqueda, repetir lo buscado («Nada con “pollo broaster”») queda fuera de esos patrones. | canon (CANON-SUI §5.6) · lo de la búsqueda: propuesta, falta aprobación |
|
|
45
|
+
| `subtitle` | Una oración con punto, en futuro tranquilizador: «Cuando hagas tu primer pedido, aparecerá aquí.» | canon (CANON-SUI §5.6) |
|
|
47
46
|
| `action` como string + `(actionClicked)` | La salida es algo de esta misma pantalla: «Reintentar», «Ver todo el catálogo», «Activar captura». | propuesta |
|
|
48
47
|
| `action` como `{ label, route }` | La salida es otra pantalla: «Ver negocios» → `/cliente/inicio`. | propuesta |
|
|
49
48
|
| sin `action` | No hay un paso obvio, o la pantalla ya tiene el botón para llenarla (el «Nuevo local» de arriba). | propuesta |
|
|
50
49
|
| error de carga | Siempre con `action="Reintentar"`. Excepción: la pantalla reintenta sola y lo dice («Seguimos intentando»). | propuesta |
|
|
51
50
|
|
|
52
|
-
**Usos de hoy que rompen las reglas:**
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
`pages/customer/order-history/order-history.html:20`. Se borra.
|
|
57
|
-
- **22 con la URL del zorro pegada** (`emoji="…/Animals/Fox.png"`), que ya es el default:
|
|
58
|
-
`pages/customers/customers.html:65`, `pages/products/products.html:113`,
|
|
59
|
-
`pages/locations/locations.html:16`. Se borra.
|
|
60
|
-
- **4 errores de carga sin «Reintentar»**:
|
|
61
|
-
`pages/driver/driver-dashboard/driver-dashboard.html:1071`,
|
|
62
|
-
`pages/customer/order-history/order-history.html:20`,
|
|
63
|
-
`pages/super-admin/master-drivers/master-drivers.html:524` y `:754`.
|
|
64
|
-
(`pages/public/pedido-en-vivo/pedido-en-vivo.html:50` no cuenta: reintenta solo.)
|
|
51
|
+
**Usos de hoy que rompen las reglas:** 0. Los 29 `icon="…"` (que no es un input), las 22 URL del
|
|
52
|
+
zorro pegadas a mano y los 4 errores de carga sin «Reintentar» se corrigieron el 03-10-2026 (commit
|
|
53
|
+
`461efbec` de la app). `pages/public/pedido-en-vivo/pedido-en-vivo.html:50` sigue sin «Reintentar»
|
|
54
|
+
a propósito: reintenta solo y lo dice.
|
|
65
55
|
|
|
66
56
|
## Tamaño en mobile y en web
|
|
67
57
|
|
|
@@ -38,7 +38,7 @@ marketing: brillo arriba, borde interior claro y un anillo del color del botón.
|
|
|
38
38
|
|
|
39
39
|
- **Para qué es**: un botón normal con un acabado más vistoso.
|
|
40
40
|
- **Default**: `neutral` (negro) en la guía; **`primary` en SUI**.
|
|
41
|
-
- **Tamaños**: `medium` (40), `small` (36) y `xsmall` (32).
|
|
41
|
+
- **Tamaños**: `medium` (40), `small` (36) y `xsmall` (32). SUI agrega `large` (48) para el teléfono (04-10-2026).
|
|
42
42
|
- **Hover**: el brillo se aclara, no se oscurece. `basic` pasa a fondo gris plano.
|
|
43
43
|
- **Deshabilitado**: fondo gris plano, sin brillo, sin anillo ni sombra, igual en los cuatro tipos.
|
|
44
44
|
|
|
@@ -55,6 +55,7 @@ marketing: brillo arriba, borde interior claro y un anillo del color del botón.
|
|
|
55
55
|
|
|
56
56
|
| size | cuándo | fuente |
|
|
57
57
|
|---|---|---|
|
|
58
|
+
| `large` (48) | El CTA en el teléfono. Texto 16. | canon (dueño, 04-10-2026): piso táctil 44 en el teléfono; extensión de SUI, la guía no lo tiene |
|
|
58
59
|
| `medium` (40, default) | El CTA de la landing en desktop. | escala y default según la guía del DS · cuándo: propuesta |
|
|
59
60
|
| `small` (36) | Un CTA dentro de una card de la landing (la card de un plan). | escala según la guía del DS · cuándo: propuesta |
|
|
60
61
|
| `xsmall` (32) | Sin caso: en una landing el CTA nunca es tan chico. | escala según la guía del DS · cuándo: propuesta |
|
|
@@ -70,27 +71,32 @@ marketing: brillo arriba, borde interior claro y un anillo del color del botón.
|
|
|
70
71
|
|
|
71
72
|
## Tamaño en mobile y en web
|
|
72
73
|
|
|
73
|
-
En mobile se toca con el dedo: el área táctil tiene que medir **44 px o más
|
|
74
|
-
va un tamaño más chico. La app ya lo resuelve con `BreakpointsService`
|
|
75
|
-
(`src/app/services/breakpoints.service.ts`, mobile = hasta 767 px)
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
En mobile se toca con el dedo: el área táctil tiene que medir **44 px o más** (canon (dueño, 04-10-2026): piso táctil 44 en el teléfono). En web,
|
|
75
|
+
con mouse, va un tamaño más chico. La app ya lo resuelve con `BreakpointsService`
|
|
76
|
+
(`src/app/services/breakpoints.service.ts`, mobile = hasta 767 px).
|
|
77
|
+
|
|
78
|
+
| size | alto | texto | cuándo | fuente |
|
|
79
|
+
|---|---|---|---|---|
|
|
80
|
+
| `large` | 48 | 16 (Label/Medium) | CTA en el teléfono | canon (dueño, 04-10-2026): piso táctil 44 en el teléfono. Size nuevo del 04-10-2026 |
|
|
81
|
+
| `medium` (default) | 40 | 14 | CTA en web | Figma |
|
|
82
|
+
| `small` | 36 | 14 | CTA dentro de una card en web | Figma |
|
|
83
|
+
| `xsmall` | 32 | 14 | — | Figma |
|
|
84
|
+
|
|
85
|
+
**Por qué `large` = 48 y no 44**: el fancy es «el mismo botón con otro acabado» que `sui-button` y su
|
|
86
|
+
escala lo espeja tal cual (medium 40 / small 36 / xsmall 32). El siguiente es `large`, y el
|
|
87
|
+
`large` de sui-button mide 48: el fancy en el teléfono queda del mismo alto que el botón normal
|
|
88
|
+
que va al lado. El texto sube a 16 (regla de tamaños del 03-10-2026); los íconos siguen en 20.
|
|
78
89
|
|
|
79
90
|
| uso | mobile | web | fuente |
|
|
80
91
|
|---|---|---|---|
|
|
81
|
-
| CTA principal de una landing |
|
|
82
|
-
| CTA dentro de la card de un plan |
|
|
92
|
+
| CTA principal de una landing | `large` (48) | `medium` (40) | propuesta |
|
|
93
|
+
| CTA dentro de la card de un plan | `large` (48) | `small` (36) | propuesta |
|
|
83
94
|
|
|
84
95
|
```html
|
|
85
|
-
|
|
86
|
-
<sui-button size="large">Empieza gratis</sui-button>
|
|
87
|
-
} @else {
|
|
88
|
-
<sui-fancy-button type="primary" size="medium">Empieza gratis</sui-fancy-button>
|
|
89
|
-
}
|
|
96
|
+
<sui-fancy-button type="primary" [size]="bp.isMobile() ? 'large' : 'medium'">Empieza gratis</sui-fancy-button>
|
|
90
97
|
```
|
|
91
98
|
|
|
92
|
-
|
|
93
|
-
va con `sui-button` `large`. Hoy no hay usos (todo el componente está en «no usar»).
|
|
99
|
+
Hoy no hay usos (todo el componente está en «no usar»).
|
|
94
100
|
|
|
95
101
|
## «No usar»: por qué no hoy y cuándo sí
|
|
96
102
|
|
|
@@ -110,7 +116,7 @@ en la columna de la derecha, se usa (aprobado por el dueño, 03-10-2026).
|
|
|
110
116
|
| input | tipo | default |
|
|
111
117
|
|---|---|---|
|
|
112
118
|
| `type` | `'primary' \| 'neutral' \| 'basic' \| 'destructive'` | `'primary'` |
|
|
113
|
-
| `size` | `'medium' \| 'small' \| 'xsmall'` | `'medium'` |
|
|
119
|
+
| `size` | `'large' \| 'medium' \| 'small' \| 'xsmall'` | `'medium'` |
|
|
114
120
|
| `leftIcon` | `string \| null` | `null` |
|
|
115
121
|
| `rightIcon` | `string \| null` | `null` |
|
|
116
122
|
| `disabled` | `boolean` | `false` |
|
|
@@ -132,8 +138,8 @@ El clic se escucha con `(clicked)`. Slots: `<ng-content>` (el texto).
|
|
|
132
138
|
- **`type` es el relleno**, no el `type` HTML: ese se llama **`htmlType`**. `type="submit"` no
|
|
133
139
|
compila (no es un tipo válido) y no hace un submit.
|
|
134
140
|
- **El radio es 10 px, no pill.** Al lado de un `sui-button` (pill en SUI) se ven de dos familias.
|
|
135
|
-
-
|
|
136
|
-
|
|
141
|
+
- **`large` (48) es de SUI** (04-10-2026), no de la guía: en el teléfono va ese, del mismo alto que
|
|
142
|
+
el `large` de `sui-button`. No hay `xlarge`.
|
|
137
143
|
- **El default es `primary`**; en la guía es `neutral`.
|
|
138
144
|
- El anillo del `neutral` es un hex crudo (`#242628`): no hay token para ese gris.
|
|
139
145
|
- Ya trae el arreglo de iOS para el `:active` pegado: no lo agregues.
|
|
@@ -92,7 +92,7 @@ Outputs: ninguno.
|
|
|
92
92
|
|
|
93
93
|
- **La extensión se corta a 4 letras** y va en mayúsculas: `.jpeg` → `JPEG`, `.numbers` → `NUMB`.
|
|
94
94
|
- **`extension` gana sobre `filename`.**
|
|
95
|
-
-
|
|
95
|
+
- El nombre para el lector de pantalla es «Archivo PDF» (en español desde el 04-10-2026) y no se puede cambiar.
|
|
96
96
|
- `size` es `xsmall` o `medium`: no hay `small` ni `large`.
|
|
97
97
|
|
|
98
98
|
## Ejemplo
|
|
@@ -132,6 +132,9 @@ en la columna de la derecha, se usa (aprobado por el dueño, 03-10-2026).
|
|
|
132
132
|
## Trampas
|
|
133
133
|
|
|
134
134
|
- `browseLabel` dice «Buscar archivo» por defecto (antes «Browse File»).
|
|
135
|
+
- **Con teclado el control es «Buscar archivo»**, no el área. Desde el 04-10-2026 el host ya no
|
|
136
|
+
es `role="button"` ni entra en el Tab (era un control con otro adentro y Enter pedía el selector
|
|
137
|
+
dos veces). Con el mouse o el dedo, tocar cualquier parte del área sigue abriendo el selector.
|
|
135
138
|
- **Llena el ancho del contenedor** desde el 03-10-2026 (antes medía 400 fijo y había que forzar
|
|
136
139
|
`style="width: 100%"`). Las pantallas que lo dejaban en 400 en un contenedor ancho ahora se
|
|
137
140
|
estiran; para un ancho fijo, se lo pone el consumer al host.
|
|
@@ -41,7 +41,7 @@ subiendo con su barra, listo, o falló con «Reintentar».
|
|
|
41
41
|
| input | cuándo | fuente |
|
|
42
42
|
|---|---|---|
|
|
43
43
|
| `file` | El nombre real del archivo (`'carta-octubre.pdf'`). La extensión da el ícono y el color. | propuesta |
|
|
44
|
-
| `description` | **Siempre** se pasa: el default es un texto de ejemplo («0 KB de 120 KB»). Subiendo: «1
|
|
44
|
+
| `description` | **Siempre** se pasa: el default es un texto de ejemplo («0 KB de 120 KB»). Subiendo: «1.2 MB de 3.4 MB»; listo: «3.4 MB» (punto decimal, como el «10.0 MB» que arma `sui-file-upload`). | propuesta |
|
|
45
45
|
| `progress` | 0–100, solo en `in-progress`. | propuesta |
|
|
46
46
|
| `statusText` | Los defaults ya están en español («Subiendo…», «Completado», «Falló»); en error, mejor el motivo: «Se cortó la conexión». | propuesta |
|
|
47
47
|
| `showStatus=false` | Solo en `success`, cuando el check sobra porque la lista ya dice «Archivos subidos». | propuesta |
|
|
@@ -52,14 +52,15 @@ Usos de hoy que rompen la regla: **0**.
|
|
|
52
52
|
## Tamaño en mobile y en web
|
|
53
53
|
|
|
54
54
|
**No tiene `size`.** Llena el ancho del contenedor (antes 400 fijo) y la X o el tacho de la derecha
|
|
55
|
-
es un `sui-compact-button` `2xlarge` de **32 px** (Figma: 24)
|
|
56
|
-
|
|
57
|
-
alto: en mobile conviene que la fila entera también
|
|
55
|
+
es un `sui-compact-button` `2xlarge` de **32 px** (Figma: 24): queda debajo de los 44 del dedo. La
|
|
56
|
+
fila mide 74 sin barra (ícono de 40 + padding 16 × 2 + borde 1 × 2; no hay `min-height`).
|
|
57
|
+
«Reintentar» sigue siendo un link de 20 px de alto: en mobile conviene que la fila entera también
|
|
58
|
+
reintente.
|
|
58
59
|
|
|
59
60
|
| pieza | mobile | web | fuente |
|
|
60
61
|
|---|---|---|---|
|
|
61
62
|
| ancho | el del contenedor | el del contenedor | canon (aprobado por el dueño, 03-10-2026), extensión SUI |
|
|
62
|
-
| X / tacho | 32 px | 32 px | canon (aprobado por el dueño, 03-10-2026), extensión SUI |
|
|
63
|
+
| X / tacho | 32 px — **no llega** a 44 | 32 px | canon (aprobado por el dueño, 03-10-2026), extensión SUI |
|
|
63
64
|
| «Reintentar» | link de 20 px — **no llega** | link | medido |
|
|
64
65
|
|
|
65
66
|
```html
|
|
@@ -122,8 +123,8 @@ interface SuiFileUploadCardFile { filename: string; extension?: string; }
|
|
|
122
123
|
|
|
123
124
|
```html
|
|
124
125
|
<sui-file-upload-card file="carta-octubre.pdf" state="in-progress" [progress]="45"
|
|
125
|
-
description="1
|
|
126
|
-
<sui-file-upload-card file="carta-octubre.pdf" state="error" description="2
|
|
126
|
+
description="1.2 MB de 2.6 MB" statusText="Subiendo…" />
|
|
127
|
+
<sui-file-upload-card file="carta-octubre.pdf" state="error" description="2.6 MB"
|
|
127
128
|
statusText="Se cortó la conexión" retryLabel="Reintentar"
|
|
128
129
|
(retryClicked)="reintentar()" (actionClicked)="quitar()" />
|
|
129
130
|
```
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sui-filter
|
|
3
|
+
selector: sui-filter-bar, sui-filter-item, sui-filter-panel-header, sui-filter-panel-footer
|
|
4
|
+
resumen: Piezas de filtros de una lista o tabla del panel; la barra horizontal (buscador, vista, orden) y el panel vertical (fila, cabecera con «Limpiar», pie con «Limpiar» / «Aplicar»)
|
|
5
|
+
alternativas: [sui-segmented-control (2 a 4 vistas que se aplican al instante), sui-compact-select (un filtro suelto), sui-tab-chips (filtros rápidos con chips), sui-activity-filter (filtro del feed de actividad), sui-modal-sheet (el panel de filtros en mobile)]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# sui-filter
|
|
9
|
+
|
|
10
|
+
Story: [Organisms/Filter Bar](https://sui-design-system.web.app/?path=/docs/organisms-filter-bar--docs)
|
|
11
|
+
|
|
12
|
+
Son **cuatro componentes** en una carpeta, sin uno llamado `sui-filter`:
|
|
13
|
+
|
|
14
|
+
- `sui-filter-bar`: la **barra horizontal** arriba de una tabla. Es solo layout: un lado
|
|
15
|
+
izquierdo (`slot="start"`) y uno derecho (`slot="end"`); los controles se proyectan.
|
|
16
|
+
- `sui-filter-item`: una **fila** del panel vertical (una categoría de filtro: «Estado», «Local»).
|
|
17
|
+
- `sui-filter-panel-header`: la **cabecera** del panel, con un link «Limpiar» opcional.
|
|
18
|
+
- `sui-filter-panel-footer`: el **pie** del panel, con «Limpiar» y «Aplicar».
|
|
19
|
+
|
|
20
|
+
El panel vertical **no existe como contenedor**: se arma con header + items + footer dentro de un
|
|
21
|
+
`sui-dropdown-menu` (web) o de un `sui-modal-sheet` (mobile).
|
|
22
|
+
|
|
23
|
+
## Cuándo usarlo / cuándo no
|
|
24
|
+
|
|
25
|
+
**Úsalo** en las listas y tablas del panel del local o del super admin que necesitan filtrar
|
|
26
|
+
(pedidos, productos, repartidores): la barra arriba con el buscador, la vista y el orden; el panel
|
|
27
|
+
cuando hay varias categorías de filtro que se combinan y se aplican juntas.
|
|
28
|
+
|
|
29
|
+
**No lo uses** para:
|
|
30
|
+
|
|
31
|
+
- 2 a 4 vistas que se aplican al tocar (Hoy · Semana · Mes): `sui-segmented-control` solo, sin barra.
|
|
32
|
+
- Un único filtro: un `sui-compact-select` o `sui-select` suelto.
|
|
33
|
+
- Filtros rápidos de un toque en mobile (Todos · Pendientes · Entregados): `sui-tab-chips`.
|
|
34
|
+
- El feed de actividad: `sui-activity-filter`.
|
|
35
|
+
|
|
36
|
+
Regla corta: **barra arriba de una tabla → filter-bar · varias categorías que se aplican juntas →
|
|
37
|
+
panel (header + items + footer) · un filtro suelto → compact-select.**
|
|
38
|
+
|
|
39
|
+
## Qué variante usar
|
|
40
|
+
|
|
41
|
+
> **La guía del DS no tiene página de filtros**: estas piezas salen solo del Figma del DS
|
|
42
|
+
> («Filters»: HorizontalFilter y VerticalFilter). Todo lo de abajo es **propuesta, falta
|
|
43
|
+
> aprobación**, salvo lo marcado canon.
|
|
44
|
+
>
|
|
45
|
+
> Uso medido el 03-10-2026 en `master-pedidos/src/app` (misma exclusión que `sui-dropdown-menu`):
|
|
46
|
+
> **0 usos**. Solo aparecen en la vitrina `master-preview`.
|
|
47
|
+
|
|
48
|
+
### `sui-filter-bar`
|
|
49
|
+
|
|
50
|
+
| variant | cuándo | fuente |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| `table` (default) | Arriba de una tabla: a la izquierda la vista (`sui-segmented-control`), a la derecha el buscador (`sui-input type="search"`) y el orden (`sui-select` o `sui-compact-select`). | propuesta (composición del Figma) |
|
|
53
|
+
| `calendar` | Arriba de una vista por fechas: a la izquierda «Hoy» + el rango (`sui-button-group`), a la derecha el buscador. | propuesta (composición del Figma) |
|
|
54
|
+
|
|
55
|
+
`variant` solo marca el host (`data-sui-variant`): **no cambia el layout**. Lo que se ve lo deciden
|
|
56
|
+
los controles que se proyectan.
|
|
57
|
+
|
|
58
|
+
### El panel: `sui-filter-item` + header + footer
|
|
59
|
+
|
|
60
|
+
| pieza | regla | fuente |
|
|
61
|
+
|---|---|---|
|
|
62
|
+
| `sui-filter-item` `active` | La categoría abierta (la que muestra sus opciones al lado): fondo gris, texto negro, flecha a la derecha. | propuesta (estados del Figma) |
|
|
63
|
+
| `sui-filter-item` `leftIcon` | Un ícono por categoría si ayuda a ubicarla («Estado», «Local», «Repartidor»). | propuesta |
|
|
64
|
+
| `sui-filter-panel-header` `clear` | `clear=true` dice «Limpiar» (en español desde el 04-10-2026); un string lo cambia. | canon (CANON-SUI §5: copy en español) |
|
|
65
|
+
| `sui-filter-panel-footer` | «Limpiar» a la izquierda (`stroke neutral`), «Aplicar» a la derecha (`filled primary`), mitad y mitad. | canon (orden de `sui-modal-footer`, CLAUDE.md «Botones») |
|
|
66
|
+
| «Limpiar» en header **y** footer | Elegir uno. Con el footer, el header va sin link. | propuesta |
|
|
67
|
+
| `applyButton` deshabilitado | `{ label: 'Aplicar', disabled: !cambio() }` mientras no se toca nada. | propuesta |
|
|
68
|
+
|
|
69
|
+
## Tamaño en mobile y en web
|
|
70
|
+
|
|
71
|
+
Ninguna pieza cambia sola en mobile, salvo la barra, que apila sus dos lados por debajo de 640 px.
|
|
72
|
+
|
|
73
|
+
| pieza | mobile | web | fuente |
|
|
74
|
+
|---|---|---|---|
|
|
75
|
+
| `sui-filter-bar` | sin tamaño; los controles adentro van `large` (48) | sin tamaño; los controles `small` (36) | propuesta (igual que `sui-compact-select` en una barra) |
|
|
76
|
+
| `sui-filter-item` | 36 de alto, no se puede cambiar: debajo de los 44 del dedo | 36 | propuesta |
|
|
77
|
+
| `sui-filter-panel-footer` | `medium` (40) es lo más grande que tiene; en mobile, mejor `sui-modal-footer` (48) dentro de un `sui-modal-sheet` | `small` (36, default) | canon para el 48 de mobile (CLAUDE.md: footer de modal `large`); el resto, propuesta |
|
|
78
|
+
| `sui-filter-panel-header` | sin tamaño | sin tamaño | — |
|
|
79
|
+
|
|
80
|
+
```html
|
|
81
|
+
<sui-filter-bar>
|
|
82
|
+
<sui-segmented-control slot="start" … />
|
|
83
|
+
<div slot="end">
|
|
84
|
+
<sui-input type="search" [size]="bp.isMobile() ? 'large' : 'small'" placeholder="Buscar pedido…" … />
|
|
85
|
+
</div>
|
|
86
|
+
</sui-filter-bar>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## API
|
|
90
|
+
|
|
91
|
+
<!-- api:inicio -->
|
|
92
|
+
<!-- generada: no editar a mano — `npm run docs` -->
|
|
93
|
+
|
|
94
|
+
### `sui-filter-bar`
|
|
95
|
+
|
|
96
|
+
| input | tipo | default |
|
|
97
|
+
|---|---|---|
|
|
98
|
+
| `variant` | `'calendar' \| 'table'` | `'table'` |
|
|
99
|
+
|
|
100
|
+
Outputs: ninguno.
|
|
101
|
+
|
|
102
|
+
### `sui-filter-item`
|
|
103
|
+
|
|
104
|
+
| input | tipo | default |
|
|
105
|
+
|---|---|---|
|
|
106
|
+
| `active` | `boolean` | `false` |
|
|
107
|
+
| `disabled` | `boolean` | `false` |
|
|
108
|
+
| `leftIcon` | `string \| null` | `null` |
|
|
109
|
+
| `activeIcon` | `string` | `'arrow-right-s-line'` |
|
|
110
|
+
|
|
111
|
+
| output | payload |
|
|
112
|
+
|---|---|
|
|
113
|
+
| `selected` | `Event` |
|
|
114
|
+
|
|
115
|
+
### `sui-filter-panel-footer`
|
|
116
|
+
|
|
117
|
+
| input | tipo | default |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| `clearButton` | `SuiFooterButtonConfig \| string` | `'Limpiar'` |
|
|
120
|
+
| `applyButton` | `SuiFooterButtonConfig \| string` | `'Aplicar'` |
|
|
121
|
+
| `size` | `'small' \| 'medium'` | `'small'` |
|
|
122
|
+
|
|
123
|
+
| output | payload |
|
|
124
|
+
|---|---|
|
|
125
|
+
| `clear` | `void` |
|
|
126
|
+
| `apply` | `void` |
|
|
127
|
+
|
|
128
|
+
### `sui-filter-panel-header`
|
|
129
|
+
|
|
130
|
+
| input | tipo | default |
|
|
131
|
+
|---|---|---|
|
|
132
|
+
| `label` | `string` | `''` |
|
|
133
|
+
| `leftIcon` | `string \| null` | `null` |
|
|
134
|
+
| `clear` | `string \| boolean` | `false` |
|
|
135
|
+
|
|
136
|
+
| output | payload |
|
|
137
|
+
|---|---|
|
|
138
|
+
| `clearClick` | `void` |
|
|
139
|
+
<!-- api:fin -->
|
|
140
|
+
|
|
141
|
+
Slots de `sui-filter-bar`: `[slot=start]`, `[slot=end]` y el contenido por defecto (fila única si no
|
|
142
|
+
se usan los slots). El label de `sui-filter-item` es su contenido proyectado. `clearButton` y
|
|
143
|
+
`applyButton` aceptan un string o `SuiFooterButtonConfig` (`{ label, disabled? }`, la misma interfaz
|
|
144
|
+
de `sui-drawer-footer`).
|
|
145
|
+
|
|
146
|
+
## Trampas
|
|
147
|
+
|
|
148
|
+
- Los textos por defecto son «Limpiar» y «Aplicar» en el footer y «Limpiar» en el header con
|
|
149
|
+
`clear=true` (en español desde el 04-10-2026).
|
|
150
|
+
- **La barra apila a 640 px; la app cambia a mobile a 767.** Entre 641 y 767 px la app ya está en
|
|
151
|
+
mobile y la barra sigue en una fila.
|
|
152
|
+
- **Varios controles en un lado van en un contenedor.** Cada slot es una fila con 12 px de separación,
|
|
153
|
+
pero un solo elemento por `slot` queda más ordenado (`<div slot="end">`), como en el Figma.
|
|
154
|
+
- **`sui-filter-item` tiene `role="option"`**: el contenedor tiene que llevar `role="listbox"`.
|
|
155
|
+
- **`active` no es «elegido»**: marca la categoría abierta, no un valor aplicado. Para decir que una
|
|
156
|
+
categoría tiene un filtro puesto no hay prop (un `sui-badge` en el label es lo más cercano).
|
|
157
|
+
- **El footer separa sus botones 16 px** (del Figma); el canon de la app entre botones hermanos es 12
|
|
158
|
+
(CANON-SUI §0, `sui-modal-footer`).
|
|
159
|
+
- El footer no llega a `large`: en mobile queda más chico que el footer de cualquier modal.
|
|
160
|
+
- `disabled` del item usa opacidad (no está en el Figma).
|
|
161
|
+
|
|
162
|
+
## Ejemplo
|
|
163
|
+
|
|
164
|
+
```html
|
|
165
|
+
<!-- Panel de filtros en web, anclado a un botón «Filtros» -->
|
|
166
|
+
<sui-dropdown-menu #filtros="suiDropdownMenu" [minWidth]="320">
|
|
167
|
+
<sui-button trigger variant="stroke" color="neutral" size="small">Filtros</sui-button>
|
|
168
|
+
<ng-template suiDropdownPanel>
|
|
169
|
+
<sui-filter-panel-header label="Filtros" leftIcon="equalizer-line" />
|
|
170
|
+
<div role="listbox" aria-label="Categorías de filtro">
|
|
171
|
+
<sui-filter-item leftIcon="checkbox-circle-line" [active]="cat() === 'estado'"
|
|
172
|
+
(selected)="cat.set('estado')">Estado</sui-filter-item>
|
|
173
|
+
<sui-filter-item leftIcon="store-2-line" [active]="cat() === 'local'"
|
|
174
|
+
(selected)="cat.set('local')">Local</sui-filter-item>
|
|
175
|
+
</div>
|
|
176
|
+
<sui-filter-panel-footer clearButton="Limpiar"
|
|
177
|
+
[applyButton]="{ label: 'Aplicar', disabled: !cambio() }"
|
|
178
|
+
(clear)="limpiar()" (apply)="filtros.close(); aplicar()" />
|
|
179
|
+
</ng-template>
|
|
180
|
+
</sui-dropdown-menu>
|
|
181
|
+
```
|
package/docs/sui-flag/README.md
CHANGED
|
@@ -22,8 +22,9 @@ nada a nadie.
|
|
|
22
22
|
> **La guía del DS no tiene este componente.** Todo es **propuesta, falta aprobación**.
|
|
23
23
|
>
|
|
24
24
|
> Uso medido el 03-10-2026 en `master-pedidos/src/app`: **0 usos directos**. Lo usan por dentro
|
|
25
|
-
> `sui-select`, `sui-compact-select`, `sui-
|
|
26
|
-
> `sui-command-menu-item`.
|
|
25
|
+
> `sui-select`, `sui-compact-select`, `sui-compact-select-for-input`, `sui-inline-select`,
|
|
26
|
+
> `sui-dropdown-item` y `sui-command-menu-item`. `sui-tag` no la trae: la recibe proyectada en
|
|
27
|
+
> `[data-slot=start]`.
|
|
27
28
|
|
|
28
29
|
### `size`
|
|
29
30
|
|
|
@@ -12,7 +12,7 @@ Story: [Atoms/Form/Form Hint](https://sui-design-system.web.app/?path=/docs/atom
|
|
|
12
12
|
## Cuándo usarlo / cuándo no
|
|
13
13
|
|
|
14
14
|
**Úsalo** para una línea debajo de un campo o grupo **que no trae la suya**: cómo se llena
|
|
15
|
-
(«Como aparece en tu DNI
|
|
15
|
+
(«Como aparece en tu DNI»), un contador («120/200»), o qué falló («Selecciona un método de
|
|
16
16
|
pago»). Va pegado al control que explica.
|
|
17
17
|
|
|
18
18
|
**No lo uses** para:
|
|
@@ -31,7 +31,8 @@ Regla corta: **ayuda o error de un control sin hint propio → form-hint · camp
|
|
|
31
31
|
> trae tres estados: normal, deshabilitado y con error (`hasError`). El ícono es una pieza aparte
|
|
32
32
|
> y opcional. No da reglas de largo ni de copy.
|
|
33
33
|
>
|
|
34
|
-
> Uso medido el 03-10-2026 en `master-pedidos/src/app` (misma exclusión que `sui-badge
|
|
34
|
+
> Uso medido el 03-10-2026 en `master-pedidos/src/app` (misma exclusión que `sui-badge`; las cifras
|
|
35
|
+
> siguen iguales el 04-10-2026, las líneas de abajo están actualizadas a esa fecha):
|
|
35
36
|
> **36 usos en 18 archivos**: 11 `error`, 25 `neutral` (24 por default y 1 explícito), 0
|
|
36
37
|
> `disabled`; 2 con `icon` propio (`information-line`). Hay además **al menos 14 hints escritos a
|
|
37
38
|
> mano** con clases propias (`__form-hint`, `__hint`).
|
|
@@ -48,7 +49,7 @@ Regla corta: **ayuda o error de un control sin hint propio → form-hint · camp
|
|
|
48
49
|
|
|
49
50
|
| qué | regla | fuente |
|
|
50
51
|
|---|---|---|
|
|
51
|
-
| `message` | Hasta 8 palabras (mediana 6). Si no cabe, es un `sui-alert`.
|
|
52
|
+
| `message` | Hasta 8 palabras (mediana 6). Si no cabe, es un `sui-alert`. Sin punto final si es una frase corta; con punto si son dos oraciones. | canon (`docs/CANON-SUI.md` §5.4 el largo; `docs/VOZ-Y-ESCRITURA.md` el punto) |
|
|
52
53
|
| `icon` sin pasar | El de la variante (ninguno en `neutral`, info en `error` y `disabled`). | según la guía del DS (ícono opcional); default de SUI |
|
|
53
54
|
| `icon="…"` en `neutral` | Solo cuando la ayuda es una advertencia que conviene notar («No reconocimos el distrito…»). | propuesta, falta aprobación (2 usos hoy) |
|
|
54
55
|
| `[icon]="null"` | Quita el ícono también en `error`. No usar: el error necesita algo más que el color. | propuesta, falta aprobación |
|
|
@@ -62,14 +63,14 @@ Regla corta: **ayuda o error de un control sin hint propio → form-hint · camp
|
|
|
62
63
|
Bien usado, en cambio, `step-vehicle.html:43`: el error de un grupo de `sui-radio-card`.
|
|
63
64
|
- **4 como subtítulo de una sección, no de un campo:** `pages/schedule/schedule.html:17`
|
|
64
65
|
(«Pausa tu sucursal…», bajo el título de la card), `:61`, `pages/drivers/drivers.html:29`,
|
|
65
|
-
`pages/driver/driver-schedule/driver-schedule.html:
|
|
66
|
+
`pages/driver/driver-schedule/driver-schedule.html:92`.
|
|
66
67
|
- **12 de más de 8 palabras** (4 son los subtítulos de arriba) → acortar, o `sui-alert` si de
|
|
67
68
|
verdad hace falta todo: `pages/super-admin/master-users/master-users.html:66` (26 palabras),
|
|
68
|
-
`pages/orders/orders.html:
|
|
69
|
-
`pages/envios/envios.html:
|
|
70
|
-
- **Al menos 14 hints a mano** con clases propias. Ejemplos: `pages/discounts/discounts.html:
|
|
69
|
+
`pages/orders/orders.html:589` (23), `pages/driver/driver-order-detail/driver-order-detail.html:868` (23),
|
|
70
|
+
`pages/envios/envios.html:401` (15).
|
|
71
|
+
- **Al menos 14 hints a mano** con clases propias. Ejemplos: `pages/discounts/discounts.html:205`
|
|
71
72
|
(`discounts__form-hint`), `components/settings-panel/settings-panel.html:93`,
|
|
72
|
-
`pages/promociones/promociones.html:
|
|
73
|
+
`pages/promociones/promociones.html:181`.
|
|
73
74
|
|
|
74
75
|
## Tamaño en mobile y en web
|
|
75
76
|
|
|
@@ -110,6 +111,9 @@ Outputs: ninguno.
|
|
|
110
111
|
- **Sin `message` no ocupa lugar**: no hace falta envolverlo en `@if`.
|
|
111
112
|
- En `error` el ícono es `information-fill` en rojo, no `error-warning-line`.
|
|
112
113
|
- Letra fija de 12/16 px; el ícono mide 16 px y se alinea con la primera línea.
|
|
114
|
+
- `variant="error"` con mensaje lleva `role="alert"`: el lector lo anuncia al aparecer
|
|
115
|
+
(04-10-2026). Para enlazarlo a un control propio, pon `id` en el host y apúntalo con
|
|
116
|
+
`aria-describedby`; los campos del DS ya lo hacen solos.
|
|
113
117
|
|
|
114
118
|
## Ejemplo
|
|
115
119
|
|
|
@@ -19,7 +19,8 @@ Story: [Atoms/Form/Form Label](https://sui-design-system.web.app/?path=/docs/ato
|
|
|
19
19
|
|
|
20
20
|
- **Encima de un `sui-input`, `sui-select` o `sui-textarea`**: esos ya dibujan su label, asterisco,
|
|
21
21
|
sublabel y tooltip con `[label]`, `[required]`, `[sublabel]`, `[tooltip]`. Ponerle uno afuera
|
|
22
|
-
duplica la pieza y
|
|
22
|
+
duplica la pieza y deja el `required` y el error separados del campo. El label interno sí
|
|
23
|
+
lleva `for` al `id` del control (desde el 04-10-2026); uno puesto afuera no lo conoce.
|
|
23
24
|
- El texto de un solo checkbox, radio o switch: `sui-checkbox-label`, `sui-radio-label`,
|
|
24
25
|
`sui-switch-label`.
|
|
25
26
|
- Un título de sección o de card («Datos personales»): `sui-page-header`, `sui-content-label` o
|
|
@@ -35,8 +36,8 @@ Regla corta: **campo de texto → su propio `[label]` · grupo o control sin lab
|
|
|
35
36
|
> es «Last Name*(Optional)»: el opcional va **entre paréntesis** en el sub. Tiene un solo tamaño y
|
|
36
37
|
> un estado deshabilitado. Info (tooltip) y el link de la derecha vienen del Figma del componente.
|
|
37
38
|
>
|
|
38
|
-
> Uso medido el
|
|
39
|
-
> **37 usos en 13 archivos**: 13 con `required`,
|
|
39
|
+
> Uso medido el 04-10-2026 en `master-pedidos/src/app` (misma exclusión que `sui-badge`):
|
|
40
|
+
> **37 usos en 13 archivos**: 13 con `required`, 7 con `sublabel="(Opcional)"`, 2 con `link`
|
|
40
41
|
> («Cambiar»), 0 con `tooltip`, 0 con `disabled`; 6 con `size="medium"` explícito, el resto en el
|
|
41
42
|
> default (`medium`).
|
|
42
43
|
|
|
@@ -63,27 +64,21 @@ Regla corta: **campo de texto → su propio `[label]` · grupo o control sin lab
|
|
|
63
64
|
La regla de controles grandes del dueño (28-09-2026) no aplica aquí: el `size` del label es
|
|
64
65
|
tipografía, no área táctil.
|
|
65
66
|
|
|
66
|
-
**Usos de hoy que rompen las reglas
|
|
67
|
+
**Usos de hoy que rompen las reglas** (medido el 04-10-2026; los sublabels sin paréntesis, el
|
|
68
|
+
«(opcional)» en el label, el número de paso en los labels de promociones y el Title Case de
|
|
69
|
+
`drivers.html:28` ya se corrigieron en la app, commits `ce4a2d12` y `8128dc03`):
|
|
67
70
|
|
|
68
71
|
- **8 encima de un campo que ya trae su label → pasar a `[label]` del campo:**
|
|
69
72
|
`pages/driver-onboarding/step-info/step-info.html:37` («Nombre completo»), `:56`, `:77`;
|
|
70
73
|
`pages/customer-onboarding/step-address/step-address.html:70` («Departamento», sobre
|
|
71
74
|
`sui-select`), `:87`, `:106`; `pages/driver-onboarding/step-vehicle/step-vehicle.html:49`, `:62`.
|
|
72
75
|
En esos mismos campos el `sui-form-hint` de abajo también es el `[hint]` del input.
|
|
73
|
-
- **5 con `sublabel="Opcional"` sin paréntesis** → se lee «ImagenOpcional» (1 px de separación).
|
|
74
|
-
Pasar a «(Opcional)»: `components/add-product-modal/add-product-modal.html:42`, `:195`;
|
|
75
|
-
`pages/promociones/promociones.html:200`; `pages/business-onboarding/step-info/step-info.html:41`, `:54`.
|
|
76
|
-
- **2 con «(opcional)» dentro del label → `sublabel`:** `pages/driver-onboarding/step-vehicle/step-vehicle.html:49`
|
|
77
|
-
(«Placa del vehículo (opcional)») y `:62`.
|
|
78
76
|
- **2 como título de sección → heading o `sui-content-label`:** `pages/customer/checkout/checkout.html:187`
|
|
79
77
|
(«Datos personales») y `:35` («Recoges en el local»).
|
|
80
|
-
- **
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
- **1 en Title Case:** `pages/drivers/drivers.html:28` («Modo de Asignación» → «Modo de asignación»).
|
|
85
|
-
- **3 con un switch armado a mano al lado → `sui-switch-label`:** `pages/discounts/discounts.html:195`,
|
|
86
|
-
`:299`; `components/add-product-modal/add-product-modal.html:195`.
|
|
78
|
+
- **1 encima de un `sui-textarea`**, que ya trae su `[label]`: `pages/promociones/promociones.html:201`
|
|
79
|
+
(«Descripción»).
|
|
80
|
+
- **3 con un switch armado a mano al lado → `sui-switch-label`:** `pages/discounts/discounts.html:204`,
|
|
81
|
+
`:316`; `components/add-product-modal/add-product-modal.html:204`.
|
|
87
82
|
|
|
88
83
|
## Tamaño en mobile y en web
|
|
89
84
|
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sui-href
|
|
3
|
+
selector: a[suiHref]
|
|
4
|
+
resumen: Directiva para los <a> del DS que reciben un href configurable; los links internos navegan con el Router sin recargar la app
|
|
5
|
+
alternativas: [routerLink (link interno escrito en la plantilla de la app), sui-link-button (acción con forma de link, ya usa suiHref por dentro)]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# sui-href
|
|
9
|
+
|
|
10
|
+
Story: [Utilities/Href](https://sui-design-system.web.app/?path=/docs/utilities-href--docs)
|
|
11
|
+
|
|
12
|
+
## Cuándo usarlo / cuándo no
|
|
13
|
+
|
|
14
|
+
**Úsalo** dentro de un componente del DS que recibe un `href` por input y lo pinta en un `<a>`:
|
|
15
|
+
en vez de `[attr.href]="href()"`, `[suiHref]="href()"`. Así un `href="/cliente/pedidos"` que
|
|
16
|
+
viene de la app navega **sin recargar el WebView** (en Capacitor, una recarga pierde el estado y
|
|
17
|
+
tarda segundos) y uno externo se abre normal.
|
|
18
|
+
|
|
19
|
+
Ya lo usan `sui-link-button`, `sui-compact-button`, `sui-fancy-button`, `sui-social-button`,
|
|
20
|
+
`sui-breadcrumb-item`, `sui-topbar-item`, `sui-brand-logo`, `sui-app-store-badge`, `sui-rating` y
|
|
21
|
+
`sui-progress-bar-label`.
|
|
22
|
+
|
|
23
|
+
**No lo uses** para:
|
|
24
|
+
|
|
25
|
+
- Un link interno que escribes en una plantilla de la app: `routerLink`. Es lo que usa la app
|
|
26
|
+
(98 usos, 0 de `suiHref` el 03-10-2026) y además marca el link activo.
|
|
27
|
+
- Un botón que ejecuta algo: `sui-button` o `sui-link-button` con `(clicked)`.
|
|
28
|
+
|
|
29
|
+
## Qué variante usar
|
|
30
|
+
|
|
31
|
+
> **No está en la guía del DS: es una utilidad de SUI**, sin Figma ni variantes.
|
|
32
|
+
|
|
33
|
+
No tiene variantes. Lo que decide qué hace es la URL:
|
|
34
|
+
|
|
35
|
+
| `suiHref` | qué hace al tocarlo | fuente |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| empieza con `/` (no `//`) | `router.navigateByUrl()`: navegación dentro de la app, conserva query y `#` | componente |
|
|
38
|
+
| `https://…`, `mailto:`, `tel:`, `#…`, `//host` | lo que haga el navegador | componente |
|
|
39
|
+
| cualquiera, con `target` distinto de `_self` | lo que haga el navegador (nueva pestaña) | componente |
|
|
40
|
+
| cualquiera, con cmd/ctrl/shift/alt o botón del medio | lo que haga el navegador | componente |
|
|
41
|
+
| `null` o `''` | el `<a>` queda **sin** `href` (no navegable) | componente |
|
|
42
|
+
|
|
43
|
+
## Tamaño en mobile y en web
|
|
44
|
+
|
|
45
|
+
No aplica: es una directiva, no dibuja nada. El tamaño es el del componente que la usa.
|
|
46
|
+
|
|
47
|
+
## API
|
|
48
|
+
|
|
49
|
+
<!-- api:inicio -->
|
|
50
|
+
<!-- generada: no editar a mano — `npm run docs` -->
|
|
51
|
+
|
|
52
|
+
| input | tipo | default |
|
|
53
|
+
|---|---|---|
|
|
54
|
+
| `suiHref` | `string \| null` | `null` |
|
|
55
|
+
|
|
56
|
+
Outputs: ninguno.
|
|
57
|
+
<!-- api:fin -->
|
|
58
|
+
|
|
59
|
+
Solo se aplica a `<a>` (`selector: a[suiHref]`).
|
|
60
|
+
|
|
61
|
+
## Trampas
|
|
62
|
+
|
|
63
|
+
- **El atributo `href` real queda puesto**: el clic del medio, «copiar enlace» y «abrir en
|
|
64
|
+
pestaña nueva» siguen funcionando. Solo el clic normal se intercepta.
|
|
65
|
+
- **Sin Router no intercepta nada**: en Storybook o en una app sin `provideRouter` es un `href`
|
|
66
|
+
común y corriente (recarga la página).
|
|
67
|
+
- **Si el componente ya hizo `preventDefault()`** en su propio `(click)`, la directiva no navega.
|
|
68
|
+
Útil para un link que a veces solo emite un evento.
|
|
69
|
+
- **No marca el link activo** (`routerLinkActive` no lo ve). Para menús de la app, `routerLink`.
|
|
70
|
+
- Un `href` relativo sin `/` inicial (`pedidos/123`) **no** se intercepta: lo resuelve el
|
|
71
|
+
navegador contra la URL actual y recarga. Pasa rutas absolutas.
|
|
72
|
+
|
|
73
|
+
## Ejemplo
|
|
74
|
+
|
|
75
|
+
```html
|
|
76
|
+
<!-- Dentro del template de un componente del DS -->
|
|
77
|
+
<a class="sui-link-button" [suiHref]="href()" [attr.target]="target()">
|
|
78
|
+
<ng-content />
|
|
79
|
+
</a>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
```html
|
|
83
|
+
<!-- Desde la app: el componente del DS ya lo resuelve -->
|
|
84
|
+
<sui-link-button href="/cliente/pedidos">Ver mis pedidos</sui-link-button>
|
|
85
|
+
```
|
package/docs/sui-icon/README.md
CHANGED
|
@@ -91,7 +91,7 @@ el celular (cliente, repartidor) va directo el valor de mobile. Todo es **propue
|
|
|
91
91
|
|
|
92
92
|
Un ícono suelto **nunca** es el área táctil: si se toca, va en `sui-compact-button` o
|
|
93
93
|
`sui-button` `onlyIcon`, que dan los 44 px. Hoy solo 2 íconos cambian por breakpoint
|
|
94
|
-
(`pages/discounts/discounts.html:
|
|
94
|
+
(`pages/discounts/discounts.html:103` y `:108`, con `bp.isTablet() ? 20 : 16`).
|
|
95
95
|
|
|
96
96
|
## «No usar»: por qué no hoy y cuándo sí
|
|
97
97
|
|
|
@@ -121,8 +121,9 @@ Outputs: ninguno.
|
|
|
121
121
|
- **`size` acepta número o string**: `[size]="20"` son px; `size="1.25em"` es CSS. Con
|
|
122
122
|
`size="20"` (string sin unidad) el ícono no toma tamaño.
|
|
123
123
|
- **El nombre no se valida**: si no existe en RemixIcon, sale vacío sin error.
|
|
124
|
-
- **No tiene `aria-label
|
|
125
|
-
`<i>`
|
|
124
|
+
- **No tiene `aria-label` y es decorativo siempre**: el SVG propio y el `<i>` de RemixIcon llevan
|
|
125
|
+
`aria-hidden="true"` (el `<i>` desde el 04-10-2026; antes el lector podía leer el glifo como un
|
|
126
|
+
símbolo raro). Si el ícono es lo único que dice algo, el texto va al lado o en el contenedor.
|
|
126
127
|
- **La app necesita la fuente de RemixIcon** (`remixicon/fonts/remixicon.css` en `styles.scss`):
|
|
127
128
|
el paquete del DS no la trae.
|
|
128
129
|
- Dentro de un `sui-kbd`, el kbd le fuerza el color `text-sub-600`.
|