@ajuarezso/sui-design-system 0.20.0 → 0.22.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 +75 -80
- package/docs/sui-accordion/README.md +171 -0
- package/docs/sui-activity-feed/README.md +155 -0
- package/docs/sui-activity-filter/README.md +100 -0
- 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 +36 -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-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-select/README.md +130 -0
- package/docs/sui-compact-select-for-input/README.md +120 -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 +148 -0
- package/docs/sui-date-selector/README.md +98 -0
- package/docs/sui-datepicker/README.md +197 -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-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-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-filter/README.md +181 -0
- package/docs/sui-href/README.md +85 -0
- package/docs/sui-image-upload/README.md +200 -0
- package/docs/sui-image-upload-profile/README.md +145 -0
- package/docs/sui-img-retry/README.md +107 -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 +247 -0
- package/docs/sui-integration-switch/README.md +142 -0
- 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 +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-page-header/README.md +123 -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-segmented-control/README.md +3 -0
- package/docs/sui-select/README.md +183 -0
- package/docs/sui-sidebar/README.md +217 -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-switch-label/README.md +3 -0
- package/docs/sui-tab-chips/README.md +188 -0
- package/docs/sui-tab-menu-horizontal/README.md +142 -0
- package/docs/sui-tab-menu-vertical/README.md +136 -0
- package/docs/sui-table/README.md +264 -0
- package/docs/sui-tag-input/README.md +123 -0
- package/docs/sui-textarea/README.md +160 -0
- package/docs/sui-time-picker/README.md +240 -0
- package/docs/sui-toast/README.md +190 -0
- package/docs/sui-tooltip/README.md +201 -0
- 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 +291 -246
- package/fesm2022/ajuarezso-sui-design-system.mjs.map +1 -1
- package/package.json +1 -1
- package/types/ajuarezso-sui-design-system.d.ts +208 -50
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sui-content-card
|
|
3
|
+
selector: sui-content-card
|
|
4
|
+
resumen: Fila «cara + nombre + detalle» dentro de su propia cajita, con badge y una X opcional para quitarla
|
|
5
|
+
alternativas: [sui-content-label (la misma fila sin caja, dentro de una card que ya existe), sui-card (contenido libre), sui-radio-card / sui-checkbox-card (la fila se elige)]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# sui-content-card
|
|
9
|
+
|
|
10
|
+
Story: [Molecules/Card/Content Card](https://sui-design-system.web.app/?path=/docs/molecules-card-content-card--docs)
|
|
11
|
+
|
|
12
|
+
## Cuándo usarlo / cuándo no
|
|
13
|
+
|
|
14
|
+
**Úsalo** para una fila suelta que representa a alguien o algo, con su propia caja: el top de
|
|
15
|
+
locales, clientes y repartidores del resumen del super admin, una persona del equipo que se puede
|
|
16
|
+
quitar, un método de pago guardado.
|
|
17
|
+
|
|
18
|
+
**No lo uses** para:
|
|
19
|
+
|
|
20
|
+
- Filas dentro de una card que ya pone el borde: `sui-content-label` (si no, queda caja dentro de
|
|
21
|
+
caja).
|
|
22
|
+
- Una fila que se elige: `sui-radio-card` o `sui-checkbox-card`.
|
|
23
|
+
- Una fila que se toca para abrir un detalle: hoy no tiene `interactive`; usa `sui-card
|
|
24
|
+
[interactive]` con un `sui-content-label` adentro.
|
|
25
|
+
|
|
26
|
+
Regla corta: **fila suelta con caja → content-card · filas dentro de una card → content-label ·
|
|
27
|
+
se elige → card de selección.**
|
|
28
|
+
|
|
29
|
+
## Qué variante usar
|
|
30
|
+
|
|
31
|
+
> **La guía del DS no tiene página de la content card.** Es un `sui-content-label size="medium"`
|
|
32
|
+
> envuelto en una card con la X. Lo que sigue es práctica de la app («propuesta») salvo lo
|
|
33
|
+
> aprobado («canon»).
|
|
34
|
+
>
|
|
35
|
+
> Uso medido el 03-10-2026 en `master-pedidos/src/app` (misma exclusión que `sui-card`): **4
|
|
36
|
+
> content-cards, todas en `pages/super-admin/master-overview/master-overview.html`**. Tipos:
|
|
37
|
+
> `avatar` (o `left-icon` cuando el local no tiene logo). Las 4 con `[dismissible]="false"`; 1 con
|
|
38
|
+
> `badge` (la nota del local).
|
|
39
|
+
|
|
40
|
+
### `type` (el leading)
|
|
41
|
+
|
|
42
|
+
| type | cuándo | fuente |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| `avatar` (`avatar`) | Una persona o un local con foto. El color de las iniciales va por rol: local `orange`, repartidor `green`, cliente `blue`. | canon (avatar por rol); el uso es propuesta |
|
|
45
|
+
| `left-icon` (`icon`) | La misma fila cuando no hay foto: `store-2-line` para el local sin logo. | propuesta (precedente `master-overview.html:224`) |
|
|
46
|
+
| `basic` | Ver «No usar». | propuesta |
|
|
47
|
+
| `company` (`avatar` + `companyLogoSrc`) | Ver «No usar». | propuesta |
|
|
48
|
+
| `brand` (`brand`) | Ver «No usar». | propuesta |
|
|
49
|
+
| `card-provider` (`brand`) | Ver «No usar». | propuesta |
|
|
50
|
+
|
|
51
|
+
### Las piezas
|
|
52
|
+
|
|
53
|
+
| prop | cuándo | fuente |
|
|
54
|
+
|---|---|---|
|
|
55
|
+
| `title` | Siempre. El nombre, nunca un id (regla de la pasada de UX). | canon (CLAUDE.md, «un identificador nunca es el título») |
|
|
56
|
+
| `subtitle` | El dato que se compara entre filas: «214 pedidos este mes», «38 calificaciones». | propuesta |
|
|
57
|
+
| `badge` | Un dato chico que se compara de un vistazo (la nota). El color sigue el significado del badge: `red` si está mal. | propuesta (badge: canon de colores) |
|
|
58
|
+
| `dismissible` | La X solo cuando quitar la fila ES la acción (sacar a alguien del equipo, borrar una tarjeta). **El default es `true`**: pasa `false` siempre que no. | propuesta |
|
|
59
|
+
| `dismissAriaLabel` | Siempre que haya X: «Quitar a Rosa del equipo», no el default «Descartar». | propuesta |
|
|
60
|
+
| `sublabel` | Ver «No usar». | propuesta |
|
|
61
|
+
| `disabled` | Ver «No usar». | propuesta |
|
|
62
|
+
|
|
63
|
+
**Usos de hoy que rompen las reglas:** 0. Las 4 apagan la X a mano: el default de `dismissible`
|
|
64
|
+
no le sirve a ningún uso de hoy.
|
|
65
|
+
|
|
66
|
+
## Tamaño en mobile y en web
|
|
67
|
+
|
|
68
|
+
La fila mide 72 (leading de 40 + padding 16) en las dos. El `size` cambia **solo la X de quitar**:
|
|
69
|
+
|
|
70
|
+
| size | X visible | área táctil | glyph | fuente |
|
|
71
|
+
|---|---|---|---|---|
|
|
72
|
+
| `medium` (default) | 20 × 20 | 20 × 20 | 20 | Figma |
|
|
73
|
+
| `large` | 32 × 32 (radius 8 al hover) | 40 × 40 (`::before` invisible) | 20 | canon (aprobado por el dueño, 03-10-2026): extensión SUI |
|
|
74
|
+
|
|
75
|
+
En `large` el glyph queda en el mismo lugar que en `medium` (la caja grande se come el aire del
|
|
76
|
+
gap con margen negativo), así que la fila se ve igual: lo que crece es dónde se puede tocar.
|
|
77
|
+
|
|
78
|
+
| uso | mobile | web | fuente |
|
|
79
|
+
|---|---|---|---|
|
|
80
|
+
| fila | 72, sin cambio | 72, sin cambio | Figma |
|
|
81
|
+
| X para quitar | `large` (32, área 40) | `medium` (20) | propuesta: el tamaño es extensión SUI aprobada (03-10-2026); el «cuándo» falta aprobarlo |
|
|
82
|
+
|
|
83
|
+
```html
|
|
84
|
+
<sui-content-card … [size]="bp.isMobile() ? 'large' : 'medium'" (dismiss)="quitar(item)" />
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## «No usar»: por qué no hoy y cuándo sí
|
|
88
|
+
|
|
89
|
+
| qué | por qué no hoy | cuándo sí, en un flujo nuevo |
|
|
90
|
+
|---|---|---|
|
|
91
|
+
| `type="basic"` (0 usos) | las 4 filas tienen cara | un dato sin cara: una dirección guardada |
|
|
92
|
+
| `type="company"` (0 usos) | no se listan empleados | un empleado con el logo de su local en la esquina |
|
|
93
|
+
| `type="brand"` (0 usos) | no hay servicios conectados | WhatsApp o Mapbox conectado, con su logo |
|
|
94
|
+
| `type="card-provider"` (0 usos) | no hay pago con tarjeta guardada | una tarjeta guardada, cuando entre Culqi / Niubiz |
|
|
95
|
+
| `sublabel` (0 usos) | ninguna fila lo pide | «(tú)» en la lista del equipo |
|
|
96
|
+
| `disabled` (0 usos) | ninguna fila está apagada | un repartidor suspendido en la lista de su local |
|
|
97
|
+
| `dismissible` en mobile con `size="medium"` | la X mide 20 | nunca: en mobile va `size="large"` |
|
|
98
|
+
|
|
99
|
+
## API
|
|
100
|
+
|
|
101
|
+
<!-- api:inicio -->
|
|
102
|
+
<!-- generada: no editar a mano — `npm run docs` -->
|
|
103
|
+
|
|
104
|
+
| input | tipo | default |
|
|
105
|
+
|---|---|---|
|
|
106
|
+
| `type` | `'basic' \| 'left-icon' \| 'avatar' \| 'card-provider' \| 'brand' \| 'company'` | `'basic'` |
|
|
107
|
+
| `title` | `string` | `''` |
|
|
108
|
+
| `sublabel` | `string` | `''` |
|
|
109
|
+
| `subtitle` | `string` | `''` |
|
|
110
|
+
| `badge` | `SuiBadgeConfig \| string \| null` | `null` |
|
|
111
|
+
| `icon` | `string \| null` | `null` |
|
|
112
|
+
| `avatar` | `SuiAvatarConfig \| string \| null` | `null` |
|
|
113
|
+
| `companyLogoSrc` | `string \| null` | `null` |
|
|
114
|
+
| `brand` | `SuiBrandLogoCompany \| null` | `null` |
|
|
115
|
+
| `dismissible` | `boolean` | `true` |
|
|
116
|
+
| `dismissAriaLabel` | `string` | `'Descartar'` |
|
|
117
|
+
| `size` | `'medium' \| 'large'` | `'medium'` |
|
|
118
|
+
| `disabled` | `boolean` | `false` |
|
|
119
|
+
|
|
120
|
+
| output | payload |
|
|
121
|
+
|---|---|
|
|
122
|
+
| `dismiss` | `MouseEvent` |
|
|
123
|
+
<!-- api:fin -->
|
|
124
|
+
|
|
125
|
+
## Trampas
|
|
126
|
+
|
|
127
|
+
- **`dismissible` arranca en `true`**: sin `[dismissible]="false"` aparece una X que no hace nada.
|
|
128
|
+
- **Aquí se llama `title` / `subtitle`**; en `sui-content-label` la misma fila es `label` /
|
|
129
|
+
`description`.
|
|
130
|
+
- **`badge` con string sale naranja `lighter` `small`** (en MAYÚSCULAS); en el content-label el
|
|
131
|
+
mismo string sale `medium`.
|
|
132
|
+
- `card-provider` toma el logo de `brand` y lo pone en una cajita de 32 × 24 (no hay assets de
|
|
133
|
+
tarjetas en el DS).
|
|
134
|
+
- No tiene `interactive` ni output de toque: la fila no se puede tocar entera.
|
|
135
|
+
- El host borra el atributo `title` del DOM y lleva `role="group"` con `aria-label` = `title`.
|
|
136
|
+
|
|
137
|
+
## Ejemplo
|
|
138
|
+
|
|
139
|
+
```html
|
|
140
|
+
<sui-content-card
|
|
141
|
+
type="avatar"
|
|
142
|
+
[avatar]="{ src: local.logo, initials: 'SA', color: 'orange' }"
|
|
143
|
+
[title]="local.nombre"
|
|
144
|
+
[subtitle]="local.pedidos + ' pedidos este mes'"
|
|
145
|
+
[badge]="{ label: '4.6 ★', color: 'orange', variant: 'lighter', size: 'small' }"
|
|
146
|
+
[dismissible]="false" />
|
|
147
|
+
```
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sui-content-label
|
|
3
|
+
selector: sui-content-label
|
|
4
|
+
resumen: Fila sin caja con ícono, foto o logo a la izquierda, título, descripción y un badge opcional
|
|
5
|
+
alternativas: [sui-content-card (la misma fila dentro de su propia cajita, con X), sui-switch-label (un ajuste que se prende o apaga), sui-alert (un aviso con color), sui-card (para agrupar las filas)]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# sui-content-label
|
|
9
|
+
|
|
10
|
+
Story: [Molecules/Card/Content Label](https://sui-design-system.web.app/?path=/docs/molecules-card-content-label--docs)
|
|
11
|
+
|
|
12
|
+
## Cuándo usarlo / cuándo no
|
|
13
|
+
|
|
14
|
+
**Úsalo** para una fila de lectura dentro de una superficie que ya pone el borde (una card, un
|
|
15
|
+
sheet): los consejos del perfil del repartidor y de mi-negocio, el resumen «dato → estado» al
|
|
16
|
+
terminar un registro, un negocio en una lista, «Contactar soporte».
|
|
17
|
+
|
|
18
|
+
**No lo uses** para:
|
|
19
|
+
|
|
20
|
+
- Una fila que necesita su propia caja o una X para quitarla: `sui-content-card`.
|
|
21
|
+
- Un ajuste que se prende o se apaga: `sui-switch-label` con `flip` (no el `toggle` de este).
|
|
22
|
+
- Un aviso que tiene que llamar la atención: `sui-alert`.
|
|
23
|
+
- Una opción que se elige: las cards de selección.
|
|
24
|
+
|
|
25
|
+
Regla corta: **fila de lectura dentro de una card → content-label · fila suelta con caja →
|
|
26
|
+
content-card · ajuste → switch-label.**
|
|
27
|
+
|
|
28
|
+
## Qué variante usar
|
|
29
|
+
|
|
30
|
+
> **La guía del DS no tiene página del content label.** Lo que sigue es práctica de la app
|
|
31
|
+
> («propuesta») salvo lo que ya está aprobado («canon»).
|
|
32
|
+
>
|
|
33
|
+
> Uso medido el 03-10-2026 en `master-pedidos/src/app` (misma exclusión que `sui-card`): **18
|
|
34
|
+
> content-labels en 4 archivos**. Tipos: 14 `left-icon`, 3 `basic`, 1 `avatar`. Tamaños: 13
|
|
35
|
+
> `large` (los consejos), 1 `medium` explícito, 4 sin `size`. 4 con `badge` (3 a la derecha, 1 en
|
|
36
|
+
> el título). 0 con `toggle`, `sublabel` o `disabled`.
|
|
37
|
+
|
|
38
|
+
### `type` (el leading)
|
|
39
|
+
|
|
40
|
+
| type | cuándo | fuente |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| `left-icon` (`icon`) | El ícono dice de qué va la fila: los consejos («Revisa tu zona de cobertura»), «Contactar soporte». Sale en un círculo con borde (`sui-key-icon` stroke). | propuesta (14 de 18) |
|
|
43
|
+
| `basic` | Fila de dato sin cara, casi siempre con badge: «Datos personales → Completados». | propuesta |
|
|
44
|
+
| `avatar` (`avatar`) | Una persona o un local. El color de las iniciales va por rol: local `orange`, repartidor `green`, cliente `blue`. | canon (avatar por rol) |
|
|
45
|
+
| `company` (`avatar` + `companyLogoSrc`) | Ver «No usar». | propuesta |
|
|
46
|
+
| `brand` (`brand`) | Ver «No usar». | propuesta |
|
|
47
|
+
|
|
48
|
+
### `size`
|
|
49
|
+
|
|
50
|
+
| size | cuándo | fuente |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| `large` (leading 48, título 16) | Consejos y pasos que se leen, con descripción larga (los 13 de hoy). | propuesta |
|
|
53
|
+
| `medium` (leading 40, título 14, default) | Filas de dato en una lista: el negocio del repartidor, el resumen del registro. | propuesta |
|
|
54
|
+
|
|
55
|
+
### Las piezas
|
|
56
|
+
|
|
57
|
+
| prop | cuándo | fuente |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| `label` | Siempre. En los consejos, una instrucción («Ponle foto a tus productos»); en los datos, el nombre del dato. | propuesta |
|
|
60
|
+
| `description` | La explicación o el detalle. En los consejos, el porqué. | propuesta |
|
|
61
|
+
| `badge` trailing (default) | El estado del dato a la derecha. Pasa el objeto con el color del badge: con string sale naranja. | propuesta |
|
|
62
|
+
| `badgePlacement="title"` | El badge pegado al nombre, cuando la derecha queda libre o es angosta («Sabores Andinos · Propio»). | propuesta |
|
|
63
|
+
| `sublabel` | Ver «No usar». | propuesta |
|
|
64
|
+
| `toggle` / `toggleChecked` | Ver «No usar». | propuesta |
|
|
65
|
+
| `disabled` | Ver «No usar». | propuesta |
|
|
66
|
+
|
|
67
|
+
**Usos de hoy que rompen las reglas:** 0. A mirar: los 3 badges de
|
|
68
|
+
`pages/driver-onboarding/step-complete/step-complete.html:48`–`:58` dicen estados de ciclo
|
|
69
|
+
(«Completados», «Esperando vinculación»); el README de `sui-badge` deja esos en
|
|
70
|
+
`sui-status-badge`, pero el content-label solo recibe la config del badge.
|
|
71
|
+
|
|
72
|
+
## Tamaño en mobile y en web
|
|
73
|
+
|
|
74
|
+
No se toca, así que no tiene que llegar a 44. El `size` es de lectura, no de dedo.
|
|
75
|
+
|
|
76
|
+
| uso | mobile | web |
|
|
77
|
+
|---|---|---|
|
|
78
|
+
| consejos y pasos | `large` | `large` |
|
|
79
|
+
| filas de dato | `medium` | `medium` |
|
|
80
|
+
| fila que se toca (soporte) | `large`, o dale a la fila un alto mínimo de 44 | `medium` |
|
|
81
|
+
|
|
82
|
+
```html
|
|
83
|
+
<sui-content-label [size]="bp.isMobile() ? 'large' : 'medium'" … /> <!-- solo si la fila se toca -->
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## «No usar»: por qué no hoy y cuándo sí
|
|
87
|
+
|
|
88
|
+
| qué | por qué no hoy | cuándo sí, en un flujo nuevo |
|
|
89
|
+
|---|---|---|
|
|
90
|
+
| `toggle` (0 usos) | el switch es `medium` fijo (32 × 20) y la fila no se toca entera | nunca para un ajuste (es `sui-switch-label` con `flip`); un resumen de solo lectura en web |
|
|
91
|
+
| `sublabel` (0 usos) | ninguna fila lo pide | una precisión corta junto al nombre: «(opcional)», «(9 a. m. a 9 p. m.)» |
|
|
92
|
+
| `disabled` (0 usos) | ninguna fila está apagada | un paso del onboarding que todavía no aplica |
|
|
93
|
+
| `type="company"` (0 usos) | no se muestran empleados con su local | la fila de un empleado con el logo de su local |
|
|
94
|
+
| `type="brand"` (0 usos) | no hay servicios externos | un canal de contacto externo con su logo (WhatsApp) |
|
|
95
|
+
|
|
96
|
+
## API
|
|
97
|
+
|
|
98
|
+
<!-- api:inicio -->
|
|
99
|
+
<!-- generada: no editar a mano — `npm run docs` -->
|
|
100
|
+
|
|
101
|
+
| input | tipo | default |
|
|
102
|
+
|---|---|---|
|
|
103
|
+
| `type` | `'basic' \| 'left-icon' \| 'avatar' \| 'brand' \| 'company'` | `'basic'` |
|
|
104
|
+
| `size` | `'medium' \| 'large'` | `'medium'` |
|
|
105
|
+
| `label` | `string` | `''` |
|
|
106
|
+
| `sublabel` | `string` | `''` |
|
|
107
|
+
| `description` | `string` | `''` |
|
|
108
|
+
| `icon` | `string \| null` | `null` |
|
|
109
|
+
| `avatar` | `SuiAvatarConfig \| string \| null` | `null` |
|
|
110
|
+
| `companyLogoSrc` | `string \| null` | `null` |
|
|
111
|
+
| `brand` | `SuiBrandLogoCompany \| null` | `null` |
|
|
112
|
+
| `badge` | `SuiBadgeConfig \| string \| null` | `null` |
|
|
113
|
+
| `badgePlacement` | `'trailing' \| 'title'` | `'trailing'` |
|
|
114
|
+
| `toggle` | `boolean` | `false` |
|
|
115
|
+
| `toggleChecked` | `boolean` | `false` |
|
|
116
|
+
| `disabled` | `boolean` | `false` |
|
|
117
|
+
|
|
118
|
+
| output | payload |
|
|
119
|
+
|---|---|
|
|
120
|
+
| `toggleCheckedChange` | `boolean` |
|
|
121
|
+
<!-- api:fin -->
|
|
122
|
+
|
|
123
|
+
## Trampas
|
|
124
|
+
|
|
125
|
+
- **Aquí se llama `label` / `description`**; en `sui-content-card` la misma fila se llama
|
|
126
|
+
`title` / `subtitle`.
|
|
127
|
+
- **`badge` con string sale naranja `lighter` `medium`** (sin mayúsculas). En la content-card el
|
|
128
|
+
mismo string sale `small` (en MAYÚSCULAS).
|
|
129
|
+
- `avatar` acepta string (es el `src`) o `{ src, initials, color }`; sin `color` las iniciales
|
|
130
|
+
salen `slate`, no el color del rol.
|
|
131
|
+
- `left-icon` sin `icon` no dibuja nada a la izquierda.
|
|
132
|
+
- El `toggle` es un `sui-switch` `medium` fijo y solo el interruptor se toca, no la fila.
|
|
133
|
+
- El host lleva `role="group"` y `aria-label` = `label`.
|
|
134
|
+
|
|
135
|
+
## Ejemplo
|
|
136
|
+
|
|
137
|
+
```html
|
|
138
|
+
<!-- Consejo -->
|
|
139
|
+
<sui-content-label
|
|
140
|
+
type="left-icon"
|
|
141
|
+
size="large"
|
|
142
|
+
icon="camera-line"
|
|
143
|
+
label="Ponle foto a tus productos"
|
|
144
|
+
description="Desde dos productos con foto tu negocio sube en la lista. Las cargas en Productos." />
|
|
145
|
+
|
|
146
|
+
<!-- Dato con estado -->
|
|
147
|
+
<sui-content-label label="Datos personales" [badge]="{ label: 'Completados', color: 'green', variant: 'lighter' }" />
|
|
148
|
+
```
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sui-counter-input
|
|
3
|
+
selector: sui-counter-input
|
|
4
|
+
resumen: Cantidad con − y + a los lados, con mínimo y máximo (unidades en el carrito, pasajeros)
|
|
5
|
+
alternativas: [sui-input type="number" (un número que se tipea, sin pasos de a uno), sui-slider (un valor de un rango continuo), sui-select (elegir una cantidad de una lista corta)]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# sui-counter-input
|
|
9
|
+
|
|
10
|
+
Story: [Molecules/Input/Counter Input](https://sui-design-system.web.app/?path=/docs/molecules-input-counter-input--docs)
|
|
11
|
+
|
|
12
|
+
## Cuándo usarlo / cuándo no
|
|
13
|
+
|
|
14
|
+
**Úsalo** para una cantidad chica que se ajusta de a uno y tiene tope: unidades de un producto
|
|
15
|
+
(carrito, detalle del producto), pasajeros de un viaje. Los botones se apagan solos al llegar al
|
|
16
|
+
mínimo o al máximo.
|
|
17
|
+
|
|
18
|
+
**No lo uses** para:
|
|
19
|
+
|
|
20
|
+
- Un número que se tipea entero (minutos, kilómetros, un monto): `sui-input` (`number` o `amount`).
|
|
21
|
+
- Una cantidad que arranca en cero y aparece al tocar «+» (los extras de un producto): hoy es un
|
|
22
|
+
armado propio con dos `sui-compact-button` en `components/product-detail-view/product-detail-view.html:169`,
|
|
23
|
+
y está bien así; el contador del DS siempre muestra los dos botones y el número.
|
|
24
|
+
- Quitar el producto: el contador baja hasta `min` y para. Borrar es otro botón (el tacho).
|
|
25
|
+
|
|
26
|
+
Regla corta: **se ajusta de a uno y tiene tope → counter · se tipea → input.**
|
|
27
|
+
|
|
28
|
+
## Qué variante usar
|
|
29
|
+
|
|
30
|
+
> **La guía del DS lo muestra como un ejemplo de su página del input** (un campo «Counter Input*»
|
|
31
|
+
> con − y + a los lados) y no dice cuándo usarlo. Todo lo de abajo es **propuesta, falta
|
|
32
|
+
> aprobación**, salvo lo que se indica.
|
|
33
|
+
>
|
|
34
|
+
> Uso medido el 03-10-2026 en `master-pedidos/src/app` (misma exclusión que `sui-badge`, más
|
|
35
|
+
> `master-ejercicios`): **4 usos en 4 archivos**, todos con `min=1`. Tamaños: 2 `large`, 2 `medium`.
|
|
36
|
+
> 1 con `label`, 2 con `ariaLabel`, 2 sin ninguno de los dos.
|
|
37
|
+
|
|
38
|
+
| prop | cuándo | fuente |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| `min` | `1` en cantidades de compra: en 1 el − se apaga y quitar queda en el tacho (evita borrar por error). | propuesta (ya es práctica en los 4 usos: `pages/customer/cart/cart.html:82`) |
|
|
41
|
+
| `max` | Siempre el tope real: stock, tope por pedido, cupo del viaje. Sin dato, 99. | propuesta (ya es práctica: `pages/customer/restaurant-menu/restaurant-menu.html:480`) |
|
|
42
|
+
| `step` | `1`. Otro paso no tiene caso hoy. | propuesta, falta aprobación |
|
|
43
|
+
| `label` | Cuando es un campo de un formulario («Pasajeros»). | según la guía del DS (su ejemplo lleva label) |
|
|
44
|
+
| `hint` | El tope dicho en palabras: «Hasta 4 pasajeros». | propuesta (ya es práctica: `components/cambiar-pasajeros/cambiar-pasajeros.html:7`) |
|
|
45
|
+
| `ariaLabel` | **Obligatorio si no hay `label`**: en el carrito o en una fila donde el texto está al lado. «Cantidad de Pollo a la brasa 1/4». | propuesta, falta aprobación |
|
|
46
|
+
| `decrementLabel` / `incrementLabel` | Los defaults («Disminuir», «Aumentar») sirven. Cambiarlos solo si el contexto pide otro verbo («Quitar un pasajero»). | propuesta, falta aprobación |
|
|
47
|
+
| `disabled` | El producto se agotó mientras estaba en el carrito. | propuesta, falta aprobación |
|
|
48
|
+
| `error` + `errorMessage` | No usar hoy: el contador no deja salir del rango. | — |
|
|
49
|
+
| `required` · `sublabel` · `tooltip` | No usar hoy: una cantidad siempre tiene valor. | — |
|
|
50
|
+
|
|
51
|
+
**Usos de hoy que rompen la regla:**
|
|
52
|
+
|
|
53
|
+
- **2 sin `label` ni `ariaLabel`** (el lector de pantalla dice solo «grupo»):
|
|
54
|
+
`pages/customer/cart/cart.html:82`, `pages/customer/restaurant-menu/restaurant-menu.html:480`.
|
|
55
|
+
- **2 en `medium` en pantallas del teléfono** → `large`: `pages/customer/cart/cart.html:82`,
|
|
56
|
+
`pages/customer/viaje/viaje.html:190`.
|
|
57
|
+
|
|
58
|
+
## Tamaño en mobile y en web
|
|
59
|
+
|
|
60
|
+
El campo llega a la escala completa del botón (2xsmall 28 · xsmall 32 · small 36 · medium 40 ·
|
|
61
|
+
large 48 · xlarge 52; la guía solo tiene 40, 36 y 32). **Los botones − y + crecen con el campo en
|
|
62
|
+
los tamaños de mobile**: 24 × 24 de `2xsmall` a `medium` (como la guía, el default no cambia), **40
|
|
63
|
+
× 40 en `large`** y **44 × 44 en `xlarge`**, ocupando todo el alto útil del campo (3 px de aire
|
|
64
|
+
dentro de la píldora). El ícono es de 20 hasta `large` y de 24 en `xlarge`.
|
|
65
|
+
|
|
66
|
+
| size | campo | botón − / + | fuente |
|
|
67
|
+
|---|---|---|---|
|
|
68
|
+
| `xlarge` | 52 | 44 | canon (aprobado por el dueño, 03-10-2026), extensión SUI |
|
|
69
|
+
| `large` | 48 | 40 | canon (aprobado por el dueño, 03-10-2026), extensión SUI |
|
|
70
|
+
| `medium` (default) · `small` · `xsmall` | 40 · 36 · 32 | 24 | según la guía del DS |
|
|
71
|
+
| `2xsmall` | 28 | 24 | extensión SUI |
|
|
72
|
+
|
|
73
|
+
En large y xlarge el texto sube a 16 px (regla del 03-10-2026): el número va en 16/24; el alto del
|
|
74
|
+
campo no cambia (lo ponen los botones).
|
|
75
|
+
|
|
76
|
+
| uso | mobile | web | fuente |
|
|
77
|
+
|---|---|---|---|
|
|
78
|
+
| cantidad junto al CTA (detalle del producto) | `large` (48), igual que el botón | `large` | propuesta (ya es práctica en `restaurant-menu.html:480`) |
|
|
79
|
+
| cantidad en una fila (carrito, pasajeros) | `large` (48) | `medium` (40) | propuesta, falta aprobación |
|
|
80
|
+
|
|
81
|
+
```html
|
|
82
|
+
<sui-counter-input [size]="bp.isMobile() ? 'large' : 'medium'" … /> <!-- bp = BreakpointsService -->
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## «No usar»: por qué no hoy y cuándo sí
|
|
86
|
+
|
|
87
|
+
| qué | por qué no hoy | cuándo sí, en un flujo nuevo |
|
|
88
|
+
|---|---|---|
|
|
89
|
+
| `size` `2xsmall`, `xsmall`, `small` | en la app la cantidad se toca con el dedo | una tabla del panel donde se ajusta el stock de varios productos |
|
|
90
|
+
| `size="xlarge"` | el CTA de al lado es `large` | si el CTA del detalle pasa a `xlarge` |
|
|
91
|
+
| `step` distinto de 1 | no hay productos que se vendan de a varios | huevos por media docena, gaseosas por pack de 6 |
|
|
92
|
+
| `error` | el contador no deja salir del rango | el stock bajó con el carrito abierto y la cantidad ya no alcanza |
|
|
93
|
+
| `tooltip` · `sublabel` · `required` | una cantidad siempre tiene valor | — |
|
|
94
|
+
|
|
95
|
+
## API
|
|
96
|
+
|
|
97
|
+
<!-- api:inicio -->
|
|
98
|
+
<!-- generada: no editar a mano — `npm run docs` -->
|
|
99
|
+
|
|
100
|
+
| input | tipo | default |
|
|
101
|
+
|---|---|---|
|
|
102
|
+
| `size` | `'2xsmall' \| 'xsmall' \| 'small' \| 'medium' \| 'large' \| 'xlarge'` | `'medium'` |
|
|
103
|
+
| `label` | `string \| null` | `null` |
|
|
104
|
+
| `sublabel` | `string \| null` | `null` |
|
|
105
|
+
| `required` | `boolean` | `false` |
|
|
106
|
+
| `tooltip` | `string \| null` | `null` |
|
|
107
|
+
| `hint` | `string \| null` | `null` |
|
|
108
|
+
| `error` | `boolean` | `false` |
|
|
109
|
+
| `errorMessage` | `string \| null` | `null` |
|
|
110
|
+
| `value` | `number` | `0` |
|
|
111
|
+
| `min` | `number` | `Number.NEGATIVE_INFINITY` |
|
|
112
|
+
| `max` | `number` | `Number.POSITIVE_INFINITY` |
|
|
113
|
+
| `step` | `number` | `1` |
|
|
114
|
+
| `disabled` | `boolean` | `false` |
|
|
115
|
+
| `ariaLabel` | `string \| null` | `null` |
|
|
116
|
+
| `decrementLabel` | `string` | `'Disminuir'` |
|
|
117
|
+
| `incrementLabel` | `string` | `'Aumentar'` |
|
|
118
|
+
|
|
119
|
+
| output | payload |
|
|
120
|
+
|---|---|
|
|
121
|
+
| `valueChange` | `number` |
|
|
122
|
+
<!-- api:fin -->
|
|
123
|
+
|
|
124
|
+
`value` es un `input` y `valueChange` un `output`: `[(value)]` funciona. Implementa
|
|
125
|
+
`ControlValueAccessor`.
|
|
126
|
+
|
|
127
|
+
## Trampas
|
|
128
|
+
|
|
129
|
+
- **Es controlado**: al tocar − o + no cambia su número; emite `valueChange` con el valor nuevo
|
|
130
|
+
(ya recortado a `min`/`max`) y el padre lo aplica. Con solo `[value]` y sin `(valueChange)` el
|
|
131
|
+
número no se mueve.
|
|
132
|
+
- `min` y `max` arrancan en −∞ y +∞: sin pasarlos, el contador baja a negativos.
|
|
133
|
+
- Los botones de 24 px de `medium` para abajo no llegan a los 40 de un dedo: en mobile, `large`
|
|
134
|
+
o `xlarge` (ver «Tamaño en mobile y en web»).
|
|
135
|
+
- Sin `label` ni `ariaLabel` el grupo no tiene nombre para el lector de pantalla.
|
|
136
|
+
- El campo es una píldora (radio completo), decisión de SUI; el Figma de origen usa 10/8 px.
|
|
137
|
+
|
|
138
|
+
## Ejemplo
|
|
139
|
+
|
|
140
|
+
```html
|
|
141
|
+
<!-- En el detalle del producto, al lado del CTA -->
|
|
142
|
+
<sui-counter-input size="large" [min]="1" [max]="pdv.topeCantidad()"
|
|
143
|
+
ariaLabel="Cantidad" [value]="pdv.qty()" (valueChange)="pdv.setQty($event)" />
|
|
144
|
+
|
|
145
|
+
<!-- Campo de formulario -->
|
|
146
|
+
<sui-counter-input label="Pasajeros" hint="Hasta 4 pasajeros" [min]="1" [max]="4"
|
|
147
|
+
[size]="bp.isMobile() ? 'large' : 'medium'" [(value)]="pasajeros" />
|
|
148
|
+
```
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sui-date-selector
|
|
3
|
+
selector: sui-date-selector
|
|
4
|
+
resumen: La cabecera de un calendario con el mes y las flechas de anterior y siguiente
|
|
5
|
+
alternativas: [sui-datepicker (el calendario completo, que ya la trae), sui-tab-chips (elegir entre pocos días: hoy, mañana, sábado)]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# sui-date-selector
|
|
9
|
+
|
|
10
|
+
Story: [Molecules/Date & Time/Date Selector](https://sui-design-system.web.app/?path=/docs/molecules-date-time-date-selector--docs)
|
|
11
|
+
|
|
12
|
+
## Cuándo usarlo / cuándo no
|
|
13
|
+
|
|
14
|
+
**Úsalo** como cabecera de un **calendario armado a mano** o de una vista que se recorre por
|
|
15
|
+
mes o por semana: «Octubre 2026» con flechas para ir al mes anterior o al siguiente (los gastos
|
|
16
|
+
del mes, las ganancias del repartidor por mes).
|
|
17
|
+
|
|
18
|
+
**No lo uses** para:
|
|
19
|
+
|
|
20
|
+
- Un calendario completo: `sui-datepicker` ya lo trae adentro.
|
|
21
|
+
- Elegir entre pocos días: `sui-tab-chips` (como la hoja de pedido programado).
|
|
22
|
+
- Cambiar entre períodos fijos («Hoy», «Esta semana», «Este mes»): `sui-tab-chips`, como el super admin.
|
|
23
|
+
|
|
24
|
+
## Qué variante usar
|
|
25
|
+
|
|
26
|
+
> **La guía del DS no tiene página para este componente** (vive dentro del datepicker). Todo es
|
|
27
|
+
> **propuesta, falta aprobación**.
|
|
28
|
+
>
|
|
29
|
+
> Uso medido el 03-10-2026 en `master-pedidos/src/app`: **0 usos directos**. Lo usa por dentro
|
|
30
|
+
> `sui-datepicker`.
|
|
31
|
+
|
|
32
|
+
| input | valor | cuándo | fuente |
|
|
33
|
+
|---|---|---|---|
|
|
34
|
+
| `label` | texto | El período visible, con mayúscula inicial y sin abreviar: «Octubre 2026», «Semana del 6 al 12 de octubre». | propuesta |
|
|
35
|
+
| `leftIcon` + `rightIcon` | `true` / `true` (default) | Lo normal: se puede ir atrás y adelante. | propuesta |
|
|
36
|
+
| `rightIcon` | `false` | Ya se está en el período actual y no hay futuro que mirar (ganancias, gastos). Mejor que dejar la flecha y que no haga nada. | propuesta |
|
|
37
|
+
| `leftIcon` | `false` | Ya se está en el primer período con datos (el mes en que se abrió el local). | propuesta |
|
|
38
|
+
| los dos en `false` | — | No usar: sin flechas es un título; va un texto. | no usar |
|
|
39
|
+
| `disabled` | `true` | Mientras carga el período nuevo, para que no se encadenen toques. | propuesta |
|
|
40
|
+
|
|
41
|
+
Usos de hoy que rompen la regla: **0**.
|
|
42
|
+
|
|
43
|
+
## Tamaño en mobile y en web
|
|
44
|
+
|
|
45
|
+
**No tiene `size`.** Mide 288 × 36 y las flechas son `sui-compact-button` `large` de **24 px**:
|
|
46
|
+
en mobile **no llegan** a los 44 px.
|
|
47
|
+
|
|
48
|
+
| uso | mobile | web | fuente |
|
|
49
|
+
|---|---|---|---|
|
|
50
|
+
| cabecera de un período | — **no hay tamaño** | 288 × 36, flechas de 24 | medido |
|
|
51
|
+
|
|
52
|
+
```html
|
|
53
|
+
<!-- Web -->
|
|
54
|
+
<sui-date-selector label="Octubre 2026" [rightIcon]="!esMesActual()" (prev)="mesAnterior()" (next)="mesSiguiente()" />
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Sin tamaño suficiente para mobile.** En el celular, hasta que el DS le sume un `size`, se arma
|
|
58
|
+
con `sui-compact-button` `xlarge` (o `sui-button` `onlyIcon` `large`) a los lados de un título.
|
|
59
|
+
|
|
60
|
+
## «No usar»: por qué no hoy y cuándo sí
|
|
61
|
+
|
|
62
|
+
| qué | por qué no hoy | cuándo sí, en un flujo nuevo |
|
|
63
|
+
|---|---|---|
|
|
64
|
+
| todo el componente suelto (0 usos) | no hay vistas que se recorran mes a mes | ganancias del repartidor o gastos del super admin «por mes», en web |
|
|
65
|
+
| los dos íconos apagados | sin flechas es un título | ninguno |
|
|
66
|
+
|
|
67
|
+
## API
|
|
68
|
+
|
|
69
|
+
<!-- api:inicio -->
|
|
70
|
+
<!-- generada: no editar a mano — `npm run docs` -->
|
|
71
|
+
|
|
72
|
+
| input | tipo | default |
|
|
73
|
+
|---|---|---|
|
|
74
|
+
| `label` | `string` | — (requerido) |
|
|
75
|
+
| `leftIcon` | `boolean` | `true` |
|
|
76
|
+
| `rightIcon` | `boolean` | `true` |
|
|
77
|
+
| `disabled` | `boolean` | `false` |
|
|
78
|
+
|
|
79
|
+
| output | payload |
|
|
80
|
+
|---|---|
|
|
81
|
+
| `prev` | `void` |
|
|
82
|
+
| `next` | `void` |
|
|
83
|
+
<!-- api:fin -->
|
|
84
|
+
|
|
85
|
+
## Trampas
|
|
86
|
+
|
|
87
|
+
- **`leftIcon` y `rightIcon` son booleanos**, no nombres de ícono: prenden o apagan las flechas.
|
|
88
|
+
- **Ancho fijo de 288 px** (`max-width` incluido): no se estira con el contenedor.
|
|
89
|
+
- Con una flecha apagada queda un hueco de 24 px para que el texto siga centrado.
|
|
90
|
+
- El componente **no sabe de fechas**: el texto lo arma quien lo usa y las flechas solo emiten.
|
|
91
|
+
- Los `aria-label` de las flechas dicen «Mes anterior» y «Mes siguiente» aunque el período sea
|
|
92
|
+
una semana.
|
|
93
|
+
|
|
94
|
+
## Ejemplo
|
|
95
|
+
|
|
96
|
+
```html
|
|
97
|
+
<sui-date-selector label="Octubre 2026" [rightIcon]="false" (prev)="mesAnterior()" />
|
|
98
|
+
```
|