@ajuarezso/sui-design-system 0.20.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/INDEX.md +51 -51
- package/docs/sui-alert/README.md +13 -0
- package/docs/sui-badge/README.md +17 -0
- package/docs/sui-banner/README.md +190 -0
- package/docs/sui-breadcrumb-item/README.md +96 -0
- package/docs/sui-breadcrumbs/README.md +122 -0
- package/docs/sui-button/README.md +17 -0
- package/docs/sui-card/README.md +168 -0
- package/docs/sui-chart-legend/README.md +140 -0
- package/docs/sui-chart-legend-dot/README.md +118 -0
- package/docs/sui-checkbox-card/README.md +150 -0
- package/docs/sui-compact-select/README.md +127 -0
- package/docs/sui-compact-select-for-input/README.md +117 -0
- package/docs/sui-content-card/README.md +147 -0
- package/docs/sui-content-label/README.md +148 -0
- package/docs/sui-counter-input/README.md +145 -0
- package/docs/sui-date-selector/README.md +98 -0
- package/docs/sui-datepicker/README.md +193 -0
- package/docs/sui-day-cell/README.md +118 -0
- package/docs/sui-day-label/README.md +81 -0
- package/docs/sui-drawer-footer/README.md +127 -0
- package/docs/sui-drawer-header/README.md +140 -0
- package/docs/sui-empty-state/README.md +145 -0
- package/docs/sui-file-upload/README.md +154 -0
- package/docs/sui-file-upload-card/README.md +129 -0
- package/docs/sui-image-upload/README.md +200 -0
- package/docs/sui-image-upload-profile/README.md +145 -0
- package/docs/sui-inline-input/README.md +104 -0
- package/docs/sui-inline-select/README.md +101 -0
- package/docs/sui-input/README.md +244 -0
- package/docs/sui-integration-switch/README.md +142 -0
- package/docs/sui-notification/README.md +179 -0
- package/docs/sui-notification-footer/README.md +98 -0
- package/docs/sui-notification-tab-menu/README.md +112 -0
- package/docs/sui-otp-input/README.md +116 -0
- package/docs/sui-pagination/README.md +146 -0
- package/docs/sui-password-strength/README.md +99 -0
- package/docs/sui-period-range/README.md +93 -0
- package/docs/sui-popover/README.md +178 -0
- package/docs/sui-product-card/README.md +173 -0
- package/docs/sui-radio-card/README.md +160 -0
- package/docs/sui-rating/README.md +7 -6
- package/docs/sui-rich-editor/README.md +114 -0
- package/docs/sui-select/README.md +180 -0
- package/docs/sui-stepper/README.md +166 -0
- package/docs/sui-store-card/README.md +147 -0
- package/docs/sui-switch-card/README.md +149 -0
- package/docs/sui-tab-chips/README.md +185 -0
- package/docs/sui-tab-menu-horizontal/README.md +142 -0
- package/docs/sui-tab-menu-vertical/README.md +136 -0
- package/docs/sui-tag-input/README.md +120 -0
- package/docs/sui-textarea/README.md +157 -0
- package/docs/sui-time-picker/README.md +237 -0
- package/docs/sui-toast/README.md +190 -0
- package/docs/sui-tooltip/README.md +201 -0
- package/fesm2022/ajuarezso-sui-design-system.mjs +273 -231
- package/fesm2022/ajuarezso-sui-design-system.mjs.map +1 -1
- package/package.json +1 -1
- package/types/ajuarezso-sui-design-system.d.ts +208 -52
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sui-checkbox-card
|
|
3
|
+
selector: sui-checkbox-card
|
|
4
|
+
resumen: Opción con tarjeta (ícono o foto, título, descripción y la casilla) para elegir VARIAS que se guardan después
|
|
5
|
+
alternativas: [sui-checkbox-label (la misma casilla sin tarjeta, en un formulario denso), sui-switch-card (un ajuste que se aplica al toque, sin «Guardar»), sui-radio-card (se elige solo una), sui-tag-input (valores que la persona escribe)]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# sui-checkbox-card
|
|
9
|
+
|
|
10
|
+
Story: [Molecules/Card/Checkbox Card](https://sui-design-system.web.app/?path=/docs/molecules-card-checkbox-card--docs)
|
|
11
|
+
|
|
12
|
+
## Cuándo usarlo / cuándo no
|
|
13
|
+
|
|
14
|
+
**Úsalo** para elegir varias opciones que se suman y que se confirman con «Guardar»: las formas
|
|
15
|
+
de entrega del local («Recojo en tienda» + «Delivery»), los métodos de pago que acepta, los días
|
|
16
|
+
de atención.
|
|
17
|
+
|
|
18
|
+
**No lo uses** para:
|
|
19
|
+
|
|
20
|
+
- Un ajuste que tiene efecto al toque, sin botón de guardar: `sui-switch-card`.
|
|
21
|
+
- Elegir una sola: `sui-radio-card`.
|
|
22
|
+
- Una lista larga de casillas en un formulario: `sui-checkbox-label` (sin tarjeta, ocupa menos).
|
|
23
|
+
- Aceptar términos o confirmar algo: `sui-checkbox-label`.
|
|
24
|
+
|
|
25
|
+
Regla corta: **varias que se guardan después → checkbox-card · se aplica al toque → switch-card ·
|
|
26
|
+
una → radio-card.**
|
|
27
|
+
|
|
28
|
+
## Qué variante usar
|
|
29
|
+
|
|
30
|
+
> **La guía del DS no tiene página de la checkbox card.** De la guía sale solo lo del checkbox que
|
|
31
|
+
> lleva adentro: **«para selecciones simples y múltiples»**. La frontera con el switch («se
|
|
32
|
+
> confirma después con Guardar → checkbox») ya es canon desde el README de `sui-switch-label`.
|
|
33
|
+
>
|
|
34
|
+
> Uso medido el 03-10-2026 en `master-pedidos/src/app` (misma exclusión que `sui-card`): **3
|
|
35
|
+
> checkbox-cards en 2 archivos**, los 3 `left-icon` con ícono y descripción (formas de entrega en
|
|
36
|
+
> mi-negocio y en locales administrados). 2 con `bp.controlSize()`, 1 sin `size`. Hay **5
|
|
37
|
+
> `sui-switch-card` que deberían ser este componente** (los métodos de pago de mi-negocio).
|
|
38
|
+
|
|
39
|
+
### `type` (el leading)
|
|
40
|
+
|
|
41
|
+
| type | cuándo | fuente |
|
|
42
|
+
|---|---|---|
|
|
43
|
+
| `left-icon` (`icon`, `emoji` o `iconSrc`) | Lo normal: un ícono que dice de qué va la opción. | propuesta (los 3 de hoy) |
|
|
44
|
+
| `basic` | Ver «No usar». | propuesta |
|
|
45
|
+
| `avatar` (`imageUrl`) | Ver «No usar». | propuesta |
|
|
46
|
+
| `card-provider`, `brand`, `company` | Ver «No usar». El logo lo proyectas tú con `slot="leading"`. | propuesta |
|
|
47
|
+
|
|
48
|
+
### Las piezas
|
|
49
|
+
|
|
50
|
+
| prop | cuándo | fuente |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| `label` | Siempre. El nombre de la opción: «Delivery». | propuesta |
|
|
53
|
+
| `description` | Lo que significa elegirla: «Llevas los pedidos a la dirección del cliente». | propuesta (los 3 de hoy) |
|
|
54
|
+
| `sublabel` | Precisión corta entre paréntesis. | propuesta |
|
|
55
|
+
| `badge` | Marca una opción frente a las otras («Nuevo»). Con string sale azul `light`. | propuesta |
|
|
56
|
+
| `indeterminate` | Una casilla que resume a otras («Todos los días» con algunos marcados). | propuesta |
|
|
57
|
+
| `disabled` | La opción no aplica hoy; di por qué en la `description`. | propuesta |
|
|
58
|
+
| `checked` | `[checked]` + `(checkedChange)`, o `[(checked)]`, o `formControlName`. | propuesta |
|
|
59
|
+
|
|
60
|
+
### `size` (la casilla de adentro)
|
|
61
|
+
|
|
62
|
+
| size | cuándo | fuente |
|
|
63
|
+
|---|---|---|
|
|
64
|
+
| `xlarge` | Mobile, vía `bp.controlSize()`. | canon (aprobado por el dueño, 28-09-2026: «componentes grandes») |
|
|
65
|
+
| `large` | Desktop, vía `bp.controlSize()`. | canon (aprobado por el dueño, 28-09-2026) |
|
|
66
|
+
| `medium` (default), `small` | No usar en pantallas nuevas. | canon (aprobado por el dueño, 28-09-2026) |
|
|
67
|
+
|
|
68
|
+
**Usos de hoy que rompen las reglas:**
|
|
69
|
+
|
|
70
|
+
- **1 sin `size`**: `pages/super-admin/master-administrados/master-administrados.html:172`.
|
|
71
|
+
- **5 `sui-switch-card` que se guardan con «Guardar cambios»** y por lo tanto van aquí: los métodos
|
|
72
|
+
de pago de `pages/mi-negocio/mi-negocio.html:1181`, `:1190`, `:1199`, `:1208`, `:1217`
|
|
73
|
+
(«Puedes seleccionar varias», dice la misma pantalla).
|
|
74
|
+
|
|
75
|
+
## Tamaño en mobile y en web
|
|
76
|
+
|
|
77
|
+
La card entera es el área táctil (≥ 72 con descripción): llega al piso de 44 sola. El `size`
|
|
78
|
+
cambia solo la casilla.
|
|
79
|
+
|
|
80
|
+
| uso | mobile | web |
|
|
81
|
+
|---|---|---|
|
|
82
|
+
| toda checkbox-card | `xlarge` | `large` |
|
|
83
|
+
|
|
84
|
+
```html
|
|
85
|
+
<sui-checkbox-card [size]="bp.controlSize()" … /> <!-- isMobile() ? 'xlarge' : 'large' -->
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## «No usar»: por qué no hoy y cuándo sí
|
|
89
|
+
|
|
90
|
+
| qué | por qué no hoy | cuándo sí, en un flujo nuevo |
|
|
91
|
+
|---|---|---|
|
|
92
|
+
| `type="basic"` (0 usos) | las opciones de hoy llevan ícono | opciones de texto que se suman (los días de atención, los tamaños de un producto) |
|
|
93
|
+
| `type="avatar"` (0 usos) | no se elige gente de a varios | elegir a varios repartidores para mandarles un aviso |
|
|
94
|
+
| `type="brand"` / `"company"` / `"card-provider"` (0 usos) | no hay integraciones ni tarjetas | prender varias integraciones a la vez (logo proyectado), varias sucursales de un local |
|
|
95
|
+
| `size="medium"` / `"small"` | la casilla se pierde en el teléfono | una tabla densa solo de desktop |
|
|
96
|
+
|
|
97
|
+
## API
|
|
98
|
+
|
|
99
|
+
<!-- api:inicio -->
|
|
100
|
+
<!-- generada: no editar a mano — `npm run docs` -->
|
|
101
|
+
|
|
102
|
+
| input | tipo | default |
|
|
103
|
+
|---|---|---|
|
|
104
|
+
| `type` | `'basic' \| 'left-icon' \| 'avatar' \| 'card-provider' \| 'brand' \| 'company'` | `'basic'` |
|
|
105
|
+
| `size` | `'small' \| 'medium' \| 'large' \| 'xlarge'` | `'medium'` |
|
|
106
|
+
| `label` | `string` | `''` |
|
|
107
|
+
| `sublabel` | `string \| null` | `null` |
|
|
108
|
+
| `description` | `string \| null` | `null` |
|
|
109
|
+
| `icon` | `string \| null` | `null` |
|
|
110
|
+
| `emoji` | `SuiEmojiName \| null` | `null` |
|
|
111
|
+
| `iconSrc` | `string \| null` | `null` |
|
|
112
|
+
| `imageUrl` | `string \| null` | `null` |
|
|
113
|
+
| `badge` | `SuiBadgeConfig \| string \| null` | `null` |
|
|
114
|
+
| `indeterminate` | `boolean` | `false` |
|
|
115
|
+
| `disabled` | `boolean` | `false` |
|
|
116
|
+
| `checked` · model, `[(checked)]` | `boolean` | `false` |
|
|
117
|
+
|
|
118
|
+
| output | payload |
|
|
119
|
+
|---|---|
|
|
120
|
+
| `checkedChange2` | `boolean` |
|
|
121
|
+
<!-- api:fin -->
|
|
122
|
+
|
|
123
|
+
Slot: `[slot=leading]` (solo para `card-provider`, `brand` y `company`). Implementa
|
|
124
|
+
`ControlValueAccessor` (valor `boolean`).
|
|
125
|
+
|
|
126
|
+
## Trampas
|
|
127
|
+
|
|
128
|
+
- **Hay dos outputs con el mismo dato**: `checkedChange` (lo crea el `model`) y `checkedChange2`
|
|
129
|
+
(el explícito, nombre de compatibilidad). Usa `(checkedChange)` o `[(checked)]`, como la app.
|
|
130
|
+
- **Es no controlada**: el toque cambia el estado adentro aunque no actualices nada afuera (al
|
|
131
|
+
revés que `sui-switch-card`). Si tu señal no se entera, el visual y tu estado se separan.
|
|
132
|
+
- **El leading de `card-provider`, `brand` y `company` se proyecta** con `slot="leading"`
|
|
133
|
+
(atributo `slot=`, no `sui-…-leading` como en la switch-card). Sin proyección queda el hueco.
|
|
134
|
+
- Con `avatar`, si `imageUrl` falla salen las iniciales del `label`.
|
|
135
|
+
- El leading de 40 × 40 ya trae `box-sizing: border-box` (el proyecto no tiene reset global): si
|
|
136
|
+
proyectas una imagen con padding o borde propios, ponle `box-sizing` tú.
|
|
137
|
+
- `badge` con string sale **azul `light` `small`**.
|
|
138
|
+
|
|
139
|
+
## Ejemplo
|
|
140
|
+
|
|
141
|
+
```html
|
|
142
|
+
<sui-checkbox-card
|
|
143
|
+
[size]="bp.controlSize()"
|
|
144
|
+
type="left-icon"
|
|
145
|
+
icon="store-2-line"
|
|
146
|
+
label="Recojo en tienda"
|
|
147
|
+
description="El cliente recoge su pedido en tu local"
|
|
148
|
+
[checked]="ofreceRecojo()"
|
|
149
|
+
(checkedChange)="ofreceRecojo.set($event)" />
|
|
150
|
+
```
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sui-compact-select
|
|
3
|
+
selector: sui-compact-select
|
|
4
|
+
resumen: Select chico que se ajusta al ancho de su texto, para filtros sueltos y paginación
|
|
5
|
+
alternativas: [sui-select (campo de formulario a todo el ancho, con label), sui-inline-select (dentro de una frase, sin caja), sui-compact-select-for-input (dentro de un sui-input), sui-segmented-control (2 a 4 modos a la vista)]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# sui-compact-select
|
|
9
|
+
|
|
10
|
+
Story: [Molecules/Select/Compact Select](https://sui-design-system.web.app/?path=/docs/molecules-select-compact-select--docs)
|
|
11
|
+
|
|
12
|
+
## Cuándo usarlo / cuándo no
|
|
13
|
+
|
|
14
|
+
**Úsalo** para un filtro suelto en una barra de herramientas del panel, donde el campo debe medir
|
|
15
|
+
lo que mide su texto («Todos los roles ▾», «20 por página ▾»), sin label encima.
|
|
16
|
+
|
|
17
|
+
**No lo uses** para:
|
|
18
|
+
|
|
19
|
+
- Un campo de formulario con label, hint y error: `sui-select` (este no tiene label ni hint).
|
|
20
|
+
- Algo dentro de un `sui-input` (moneda, país del teléfono): `sui-compact-select-for-input`.
|
|
21
|
+
- Un valor dentro de una frase: `sui-inline-select`.
|
|
22
|
+
- 2 a 4 modos que se ven todos (Hoy · Semana · Mes): `sui-segmented-control`.
|
|
23
|
+
|
|
24
|
+
Regla corta: **filtro suelto en una barra, ancho al texto → compact · campo con label → select.**
|
|
25
|
+
|
|
26
|
+
## Qué variante usar
|
|
27
|
+
|
|
28
|
+
> **En la guía del DS es la variante `compact` del select**, con tres ejemplos: paginación
|
|
29
|
+
> («filas por página»), país y tamaños. No dice cuándo usarla. Lo de abajo es **propuesta, falta
|
|
30
|
+
> aprobación**, salvo lo marcado.
|
|
31
|
+
>
|
|
32
|
+
> Uso medido el 03-10-2026 en `master-pedidos/src/app`: **0 usos**. Los filtros de las barras del
|
|
33
|
+
> panel usan `sui-select` sin label (6: `pages/customers/customers.html:38`,
|
|
34
|
+
> `pages/settings/team/team.html:66`, `pages/drivers/drivers.html:72`…), que se estira a todo el ancho.
|
|
35
|
+
|
|
36
|
+
| prop | cuándo | fuente |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| `type="basic"` (default) | Texto + flecha: «Todos los roles», «20 por página». | según la guía del DS (ejemplo de paginación) |
|
|
39
|
+
| `type="icon"` | Solo el ícono de la opción elegida, sin texto: un selector de vista en una barra muy apretada. Hoy sin caso. | según la guía del DS |
|
|
40
|
+
| `type="country"` + `flag` | No usar hoy: todo es Perú. | según la guía del DS (ejemplo «Country») |
|
|
41
|
+
| `items` | La lista: `{ value, label, sublabel?, icon?, flag?, disabled? }`. A diferencia de `sui-select`, cada opción **sí** puede llevar ícono o bandera. | API |
|
|
42
|
+
| `selected` / `selectedChange` | La opción elegida (objeto entero). O `formControlName`, nunca los dos. | API |
|
|
43
|
+
| `placeholder` | El filtro sin elegir: «Todos». Corto. | propuesta, falta aprobación |
|
|
44
|
+
| `value` / `icon` | Lo que muestra el campo cuando no hay `items` (modo «solo campo», el menú lo arma la pantalla). | API |
|
|
45
|
+
| `error` | No usar hoy: un filtro no tiene error. | — |
|
|
46
|
+
| `disabled` | Mientras carga la lista. | según la guía del DS |
|
|
47
|
+
| `clicked` | Solo si la pantalla arma su propio menú (sin `items`). | API |
|
|
48
|
+
|
|
49
|
+
**Candidatos de hoy:** los 6 filtros de barra del panel en web (arriba). En mobile siguen como
|
|
50
|
+
`sui-select` `large` a todo el ancho, porque este no pasa de 40 px.
|
|
51
|
+
|
|
52
|
+
## Tamaño en mobile y en web
|
|
53
|
+
|
|
54
|
+
Tiene los tres tamaños de la guía —`medium` (40), `small` (36), `xsmall` (32)— y **`large` (48)**,
|
|
55
|
+
extensión SUI para mobile: mide lo mismo que un `sui-button` `large` de la misma barra. En `large`
|
|
56
|
+
crece el aire (padding 14 · 12, radio 12); el texto y los íconos siguen en 14/20 y 20.
|
|
57
|
+
|
|
58
|
+
Las opciones del menú siguen al `size` como en `sui-select`: 36 hasta `medium`, **44 en `large`**, y
|
|
59
|
+
**44 en mobile (≤ 767 px) con cualquier tamaño**.
|
|
60
|
+
|
|
61
|
+
| size | alto | opción del menú (web · mobile) | fuente |
|
|
62
|
+
|---|---|---|---|
|
|
63
|
+
| `large` | 48 | 44 · 44 | canon (aprobado por el dueño, 03-10-2026), extensión SUI |
|
|
64
|
+
| `medium` (default) | 40 | 36 · 44 | según la guía del DS; 44 en mobile: canon (aprobado por el dueño, 03-10-2026) |
|
|
65
|
+
| `small` | 36 | 36 · 44 | ídem |
|
|
66
|
+
| `xsmall` | 32 | 36 · 44 | ídem |
|
|
67
|
+
|
|
68
|
+
| uso | mobile | web | fuente |
|
|
69
|
+
|---|---|---|---|
|
|
70
|
+
| filtro de una barra del panel | `large` (48), junto a botones `large` | `small` (36) | propuesta, falta aprobación |
|
|
71
|
+
| paginación al pie de una tabla | no aplica | `xsmall` (32) | según la guía del DS (ejemplo de paginación); el tamaño es propuesta |
|
|
72
|
+
|
|
73
|
+
```html
|
|
74
|
+
<sui-compact-select [size]="bp.isMobile() ? 'large' : 'small'" placeholder="Todos los roles"
|
|
75
|
+
[items]="roles" [(selected)]="rolElegido" /> <!-- bp = BreakpointsService -->
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## «No usar»: por qué no hoy y cuándo sí
|
|
79
|
+
|
|
80
|
+
| qué | por qué no hoy | cuándo sí, en un flujo nuevo |
|
|
81
|
+
|---|---|---|
|
|
82
|
+
| el componente entero (0 usos) | los filtros usan `sui-select` | filtros del panel en web, y «20 por página» si las tablas pasan a paginar |
|
|
83
|
+
| `type="country"` | todo es Perú | si se abre otro país |
|
|
84
|
+
| `type="icon"` | ninguna barra está tan apretada | un selector de vista (cuadrícula o lista) en la barra de productos |
|
|
85
|
+
| `error` | un filtro no tiene error | — |
|
|
86
|
+
|
|
87
|
+
## API
|
|
88
|
+
|
|
89
|
+
<!-- api:inicio -->
|
|
90
|
+
<!-- generada: no editar a mano — `npm run docs` -->
|
|
91
|
+
|
|
92
|
+
| input | tipo | default |
|
|
93
|
+
|---|---|---|
|
|
94
|
+
| `type` | `'basic' \| 'icon' \| 'country'` | `'basic'` |
|
|
95
|
+
| `size` | `'large' \| 'medium' \| 'small' \| 'xsmall'` | `'medium'` |
|
|
96
|
+
| `value` | `string` | `''` |
|
|
97
|
+
| `placeholder` | `string` | `''` |
|
|
98
|
+
| `icon` | `string \| null` | `null` |
|
|
99
|
+
| `flag` | `SuiFlagName \| null` | `null` |
|
|
100
|
+
| `items` | `readonly SuiCompactSelectItem<T>[]` | `[]` |
|
|
101
|
+
| `selected` · model, `[(selected)]` | `SuiCompactSelectItem<T> \| null` | `null` |
|
|
102
|
+
| `error` | `boolean` | `false` |
|
|
103
|
+
| `disabled` | `boolean` | `false` |
|
|
104
|
+
|
|
105
|
+
| output | payload |
|
|
106
|
+
|---|---|
|
|
107
|
+
| `clicked` | `Event` |
|
|
108
|
+
| `selectedChange` | `SuiCompactSelectItem<T>` |
|
|
109
|
+
<!-- api:fin -->
|
|
110
|
+
|
|
111
|
+
Implementa `ControlValueAccessor` (el valor es el `value` de la opción).
|
|
112
|
+
|
|
113
|
+
## Trampas
|
|
114
|
+
|
|
115
|
+
- **No mezclar `[(selected)]` con `formControlName`**: son dos fuentes de verdad y el formulario no
|
|
116
|
+
se entera de lo que escribe `selected`.
|
|
117
|
+
- Sin `items` no abre nada: solo emite `(clicked)`.
|
|
118
|
+
- `type="icon"` **no muestra texto**: solo el ícono de la opción elegida.
|
|
119
|
+
- El menú mide al menos 200 px aunque el campo sea más angosto.
|
|
120
|
+
- Las opciones miden 36 px en web hasta `medium`; 44 en `large` y en mobile (ver «Tamaño»).
|
|
121
|
+
|
|
122
|
+
## Ejemplo
|
|
123
|
+
|
|
124
|
+
```html
|
|
125
|
+
<sui-compact-select size="small" placeholder="Todos los roles" [items]="roles"
|
|
126
|
+
[(selected)]="rolElegido" />
|
|
127
|
+
```
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sui-compact-select-for-input
|
|
3
|
+
selector: sui-compact-select-for-input
|
|
4
|
+
resumen: Selector chico que vive DENTRO de un sui-input, para elegir moneda o código de país sin salir del campo
|
|
5
|
+
alternativas: [sui-select (el valor se elige aparte, con su propio label), sui-compact-select (filtro suelto con caja propia), sui-inline-select (dentro de una frase)]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# sui-compact-select-for-input
|
|
9
|
+
|
|
10
|
+
Story: [Molecules/Select/Compact Select For Input](https://sui-design-system.web.app/?path=/docs/molecules-select-compact-select-for-input--docs)
|
|
11
|
+
|
|
12
|
+
## Cuándo usarlo / cuándo no
|
|
13
|
+
|
|
14
|
+
**Úsalo** cuando un dato del campo depende de una elección corta que va pegada a él: la moneda de
|
|
15
|
+
un monto (`S/` o `$`) o el código de país de un teléfono. Se proyecta en el `[data-slot=start]`
|
|
16
|
+
de un `sui-input` con `[leadingControl]="true"`, que dibuja el divisor.
|
|
17
|
+
|
|
18
|
+
**No lo uses** para:
|
|
19
|
+
|
|
20
|
+
- Un select con label propio: `sui-select`.
|
|
21
|
+
- Suelto, fuera de un `sui-input`: no tiene borde ni foco propios. Para eso, `sui-compact-select`.
|
|
22
|
+
- Un prefijo fijo (`S/` siempre): eso es `prefix="S/"` del `sui-input`, no un selector.
|
|
23
|
+
|
|
24
|
+
Regla corta: **el campo cambia según una elección corta pegada a él → este · siempre igual → `prefix`.**
|
|
25
|
+
|
|
26
|
+
## Qué variante usar
|
|
27
|
+
|
|
28
|
+
> **En la guía del DS es la variante `compactForInput` del select**, con dos ejemplos: un monto
|
|
29
|
+
> con su moneda («€») y los tamaños. Y la página del input lo usa en «With Select». No dice cuándo.
|
|
30
|
+
>
|
|
31
|
+
> Uso medido el 03-10-2026 en `master-pedidos/src/app`: **0 usos**. Candidato: el gasto del super
|
|
32
|
+
> admin pone «Monto» (`type="number"`) y «Moneda» (PEN/USD) como dos campos separados,
|
|
33
|
+
> `pages/super-admin/master-gastos/master-gastos.html:193` y `:200`.
|
|
34
|
+
|
|
35
|
+
| prop | cuándo | fuente |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| `items` | Las opciones: `{ value, label, sublabel?, flag?, disabled? }`. | API |
|
|
38
|
+
| `selected` / `selectedChange` | La opción elegida. O `formControlName`, nunca los dos. | API |
|
|
39
|
+
| `country` (default `true`) | Con bandera (teléfono). `false` para una moneda, que no lleva bandera. | según la guía del DS (ejemplo con moneda sin bandera) |
|
|
40
|
+
| `flag` | Bandera a mostrar sin opción elegida. Hoy no aplica. | API |
|
|
41
|
+
| `value` | Texto que se ve si no hay `selected` («S/»). | API |
|
|
42
|
+
| `size` | El mismo tamaño que el `sui-input` que lo contiene, hasta `medium`. | según la guía del DS (ejemplo de tamaños) |
|
|
43
|
+
| `disabled` | Cuando el campo entero está deshabilitado. | API |
|
|
44
|
+
| `clicked` | Solo si la pantalla arma su propio menú. | API |
|
|
45
|
+
|
|
46
|
+
## Tamaño en mobile y en web
|
|
47
|
+
|
|
48
|
+
Tiene `medium` (40), `small` (36) y `xsmall` (32) de la guía, y **`large`** para el `sui-input`
|
|
49
|
+
`large` (48) de mobile (extensión SUI). Va siempre con **el mismo `size` que el input que lo
|
|
50
|
+
contiene**: el selector ocupa todo el alto interior del campo (46 · 38 · 34 · 30), así que lo que se
|
|
51
|
+
toca (y su hover) cubre el campo de arriba a abajo. Sus opciones miden 44 en `large` y en mobile
|
|
52
|
+
(≤ 767 px); 36 en el resto, como en `sui-select`.
|
|
53
|
+
|
|
54
|
+
| size del input y del selector | campo | fuente |
|
|
55
|
+
|---|---|---|
|
|
56
|
+
| `large` | 48 | canon (aprobado por el dueño, 03-10-2026), extensión SUI |
|
|
57
|
+
| `medium` (default) · `small` · `xsmall` | 40 · 36 · 32 | según la guía del DS |
|
|
58
|
+
|
|
59
|
+
| uso | mobile | web | fuente |
|
|
60
|
+
|---|---|---|---|
|
|
61
|
+
| moneda dentro del monto | `sui-input` `large` + este `large` | `sui-input` `medium` + este `medium` | propuesta, falta aprobación |
|
|
62
|
+
|
|
63
|
+
Arreglo del 03-10-2026: antes el selector medía 40/36/32 y empujaba el campo a 42/38/34 (el padding
|
|
64
|
+
de la guía no descontaba el borde del input). Ahora el campo mide exacto.
|
|
65
|
+
|
|
66
|
+
## «No usar»: por qué no hoy y cuándo sí
|
|
67
|
+
|
|
68
|
+
| qué | por qué no hoy | cuándo sí, en un flujo nuevo |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| el componente entero (0 usos) | todo es en soles y con +51 | la moneda de un gasto (`master-gastos.html:193`) o teléfonos de otro país |
|
|
71
|
+
| `country` con bandera | solo hay teléfonos de Perú | repartidores o clientes con número extranjero |
|
|
72
|
+
|
|
73
|
+
## API
|
|
74
|
+
|
|
75
|
+
<!-- api:inicio -->
|
|
76
|
+
<!-- generada: no editar a mano — `npm run docs` -->
|
|
77
|
+
|
|
78
|
+
| input | tipo | default |
|
|
79
|
+
|---|---|---|
|
|
80
|
+
| `size` | `'large' \| 'medium' \| 'small' \| 'xsmall'` | `'medium'` |
|
|
81
|
+
| `value` | `string` | `''` |
|
|
82
|
+
| `country` | `boolean` | `true` |
|
|
83
|
+
| `flag` | `SuiFlagName \| null` | `null` |
|
|
84
|
+
| `items` | `readonly SuiCompactSelectForInputItem<T>[]` | `[]` |
|
|
85
|
+
| `selected` · model, `[(selected)]` | `SuiCompactSelectForInputItem<T> \| null` | `null` |
|
|
86
|
+
| `disabled` | `boolean` | `false` |
|
|
87
|
+
|
|
88
|
+
| output | payload |
|
|
89
|
+
|---|---|
|
|
90
|
+
| `clicked` | `Event` |
|
|
91
|
+
| `selectedChange` | `SuiCompactSelectForInputItem<T>` |
|
|
92
|
+
<!-- api:fin -->
|
|
93
|
+
|
|
94
|
+
Implementa `ControlValueAccessor`.
|
|
95
|
+
|
|
96
|
+
## Trampas
|
|
97
|
+
|
|
98
|
+
- **Va en `data-slot="start"`, no en `slot="prefix"`** (`slot="prefix"` no proyecta). El
|
|
99
|
+
`sui-input` necesita además `[leadingControl]="true"` (suelta el bloqueo de ícono decorativo y
|
|
100
|
+
dibuja el divisor).
|
|
101
|
+
- El `size` tiene que ser el mismo del `sui-input`: uno `large` dentro de un input `medium` lo
|
|
102
|
+
agranda.
|
|
103
|
+
- `country` arranca en `true`: para una moneda hay que apagarlo.
|
|
104
|
+
- No tiene estado de error: lo pinta el `sui-input` que lo contiene.
|
|
105
|
+
- **Riesgo en iPhone (no verificado en dispositivo):** el host escucha `touchend` y hace `blur()`.
|
|
106
|
+
En `sui-compact-select` ese mismo patrón cancelaba el clic de iOS y el menú no abría; ahí se
|
|
107
|
+
movió el clic a un div interno. Aquí sigue en el host. Probar en un iPhone antes del primer uso.
|
|
108
|
+
- No mezclar `[(selected)]` con `formControlName`.
|
|
109
|
+
|
|
110
|
+
## Ejemplo
|
|
111
|
+
|
|
112
|
+
```html
|
|
113
|
+
<sui-input label="Monto" type="amount" placeholder="0.00" [leadingControl]="true" [(value)]="monto">
|
|
114
|
+
<sui-compact-select-for-input data-slot="start" size="medium" [country]="false"
|
|
115
|
+
[items]="monedas" [(selected)]="moneda" />
|
|
116
|
+
</sui-input>
|
|
117
|
+
```
|
|
@@ -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
|
+
```
|