@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,178 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sui-popover
|
|
3
|
+
selector: sui-popover
|
|
4
|
+
resumen: Panel con flecha que señala un elemento de la pantalla y explica algo nuevo, con una o dos acciones; sirve para recorridos de bienvenida
|
|
5
|
+
alternativas: [sui-tooltip (ayuda corta al pasar el mouse, sin acciones), sui-alert (aviso dentro del contenido), sui-modal (algo que pide decidir antes de seguir)]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# sui-popover
|
|
9
|
+
|
|
10
|
+
Story: [Molecules/Popover](https://sui-design-system.web.app/?path=/docs/molecules-popover--docs)
|
|
11
|
+
|
|
12
|
+
Es **solo el panel**: no se abre solo, no se ancla al elemento ni se cierra al tocar afuera. Quien
|
|
13
|
+
lo usa decide cuándo mostrarlo y dónde ponerlo (un overlay del CDK, o posicionado a mano junto al
|
|
14
|
+
elemento). `position` solo mueve la flecha.
|
|
15
|
+
|
|
16
|
+
## Cuándo usarlo / cuándo no
|
|
17
|
+
|
|
18
|
+
**Úsalo** para **señalar una parte de la pantalla** y decir algo que la persona todavía no sabe,
|
|
19
|
+
con un paso a seguir: el recorrido de bienvenida del panel del local la primera vez que entra, o
|
|
20
|
+
una función nueva que conviene mostrar donde está («Aquí programas tus pedidos»).
|
|
21
|
+
|
|
22
|
+
**No lo uses** para:
|
|
23
|
+
|
|
24
|
+
- La explicación de un ícono o un término sin acción: en web es `sui-tooltip`; en mobile, texto
|
|
25
|
+
visible o un `sui-modal-sheet`.
|
|
26
|
+
- Un aviso que no señala nada en particular: `sui-alert` o `sui-toast`.
|
|
27
|
+
- Pedir una decisión que bloquea («¿Cancelar el pedido?»): `sui-modal`.
|
|
28
|
+
- Un menú de opciones: `sui-dropdown-menu`.
|
|
29
|
+
|
|
30
|
+
## Qué variante usar
|
|
31
|
+
|
|
32
|
+
> La guía del DS dice para qué es, pero no cuándo va cada pie ni cada posición. Lo marcado «según la
|
|
33
|
+
> guía del DS» sale de su texto; «canon» es lo ya aprobado en la app; el resto es **propuesta**.
|
|
34
|
+
>
|
|
35
|
+
> Uso medido el 03-10-2026 en `master-pedidos/src/app`: **0 usos**, y ningún recorrido de
|
|
36
|
+
> bienvenida hecho a mano. Todo lo de abajo es para el primer flujo que lo necesite.
|
|
37
|
+
|
|
38
|
+
### Lo que sí dice la guía del DS
|
|
39
|
+
|
|
40
|
+
- **Para qué es**: llamar la atención sobre **elementos específicos** de la interfaz.
|
|
41
|
+
- Se posiciona arriba, abajo o a los costados del elemento que señala.
|
|
42
|
+
- La guía no dice nada del pie con pasos; eso viene del Figma del DS (pie con puntos, con texto o
|
|
43
|
+
con dos botones a lo ancho).
|
|
44
|
+
|
|
45
|
+
### `footer` — el pie
|
|
46
|
+
|
|
47
|
+
| footer | cuándo | fuente |
|
|
48
|
+
|---|---|---|
|
|
49
|
+
| `stretch` (default) | Un aviso suelto con dos salidas a lo ancho: «Ahora no» / «Probar». Con `doubleButton=false`, una sola: «Entendido». | propuesta |
|
|
50
|
+
| `stepper` | Un **recorrido de varios pasos**: los puntos dicen en cuál va y cuántos faltan. | propuesta |
|
|
51
|
+
| `none` | Solo informa y se cierra con la X: «Aquí ves lo que ganaste hoy». | propuesta |
|
|
52
|
+
| `text-stepper` | Recorridos de más de 5 pasos, donde los puntos ya no se cuentan: «Paso 3 de 7» (en español desde 03-10-2026). | propuesta |
|
|
53
|
+
|
|
54
|
+
### Botones del pie
|
|
55
|
+
|
|
56
|
+
| prop | valor | cuándo | fuente |
|
|
57
|
+
|---|---|---|---|
|
|
58
|
+
| `doubleButton` | `true` (default) | Desde el segundo paso de un recorrido («Atrás» / «Siguiente»), o un aviso suelto con «Ahora no» / «Probar». | propuesta |
|
|
59
|
+
| `doubleButton` | `false` | El primer paso de un recorrido o un aviso suelto con una sola salida («Entendido»). | propuesta |
|
|
60
|
+
| `backLabel` · `nextLabel` | texto en español | Los defaults ya son «Atrás» y «Siguiente» (03-10-2026); el último paso pasa `nextLabel="Listo"`. | canon (copy de la app: tuteo, sentence case) |
|
|
61
|
+
| orden | secundario a la izquierda, primario a la derecha | Ya lo hace el componente (stroke neutral + filled primary), igual que `sui-modal-footer`. | canon (orden de botones de la app) |
|
|
62
|
+
| `step` | `{ current, total }` | Con `stepper`. Sin `step`, el componente asume **1 de 4**. | propuesta |
|
|
63
|
+
|
|
64
|
+
### Flecha, ícono, texto y cierre
|
|
65
|
+
|
|
66
|
+
| prop | valor | cuándo | fuente |
|
|
67
|
+
|---|---|---|---|
|
|
68
|
+
| `tail` | `true` (default) | Siempre que señala algo: la flecha es lo que dice «es esto». | según la guía del DS (se posiciona junto al elemento) |
|
|
69
|
+
| `tail` | `false` | No usar hoy. **Cuándo sí:** la bienvenida inicial de un recorrido, centrada, sin elemento al que apuntar. | propuesta |
|
|
70
|
+
| `position` | `top-*` | El popover va **debajo** del elemento (la flecha arriba). Lo normal: el elemento sigue a la vista. | propuesta |
|
|
71
|
+
| `position` | `bottom-*` | El elemento está abajo (la barra de pestañas): el popover va encima. | propuesta |
|
|
72
|
+
| `position` | `left-*` · `right-*` | Elementos de una barra lateral (el sidebar del panel). | propuesta |
|
|
73
|
+
| `position` | `*-left` · `*-center` · `*-right` | Alinea la flecha con el elemento cuando el popover no puede centrarse sobre él (está cerca de un borde). | propuesta |
|
|
74
|
+
| `icon` | el de lo que se explica | Siempre uno que diga el tema (`calendar-schedule-line` para programar). El default es un ícono de persona. | propuesta |
|
|
75
|
+
| `icon` | `null` | Cuando el texto ya basta y el ícono sería decoración. | propuesta |
|
|
76
|
+
| `title` | frase corta | Qué es, en sentence case y sin punto final. | canon (copy de la app) |
|
|
77
|
+
| `description` | una o dos frases | Qué hace o por qué importa. | propuesta |
|
|
78
|
+
| `dismissIcon` | `true` (default) | Siempre: un recorrido se puede saltar. | propuesta |
|
|
79
|
+
| `dismissIcon` | `false` | No usar hoy. **Cuándo sí:** un paso que no se puede saltar porque sin él no funciona lo siguiente. | propuesta |
|
|
80
|
+
| `[data-slot=body]` | contenido propio | No usar hoy. **Cuándo sí:** el paso necesita una imagen o una lista en vez de título y texto. | propuesta |
|
|
81
|
+
|
|
82
|
+
## Tamaño en mobile y en web
|
|
83
|
+
|
|
84
|
+
El panel mide **320 px** de ancho fijo: cabe en un teléfono de 360 px o más con 16 px de margen a
|
|
85
|
+
cada lado; en uno más angosto se sale. El `size` cambia **los botones del pie**:
|
|
86
|
+
|
|
87
|
+
| size | botones del pie | fuente |
|
|
88
|
+
|---|---|---|
|
|
89
|
+
| `small` (default) | 36 px (`sui-button` `small`) | Figma |
|
|
90
|
+
| `medium` | 40 px (`sui-button` `medium`) | canon (aprobado por el dueño, 03-10-2026): extensión SUI |
|
|
91
|
+
|
|
92
|
+
La X se ve de 24 y **se toca en 40 × 40** en los dos (un `::before` invisible sobre su botón,
|
|
93
|
+
extensión SUI 03-10-2026).
|
|
94
|
+
|
|
95
|
+
| uso | mobile | web | fuente |
|
|
96
|
+
|---|---|---|---|
|
|
97
|
+
| el panel | 320 px (cabe desde 352 px de pantalla) | 320 px | según el componente |
|
|
98
|
+
| botones del pie | `medium` (40) | `small` (36) | propuesta: el tamaño es extensión SUI aprobada (03-10-2026); el «cuándo» falta aprobarlo |
|
|
99
|
+
| la X | se ve de 24, se toca en 40 | igual | canon (aprobado por el dueño, 03-10-2026) |
|
|
100
|
+
|
|
101
|
+
```html
|
|
102
|
+
<sui-popover footer="stretch" [size]="bp.isMobile() ? 'medium' : 'small'" … />
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
En mobile, si el recorrido es la bienvenida de la app, conviene una pantalla o un
|
|
106
|
+
`sui-modal-sheet` por paso en vez del popover (propuesta, falta aprobación).
|
|
107
|
+
|
|
108
|
+
## «No usar»: por qué no hoy y cuándo sí
|
|
109
|
+
|
|
110
|
+
Hoy el popover entero tiene **0 usos**; esto es lo que no se usaría aunque llegue un flujo nuevo.
|
|
111
|
+
|
|
112
|
+
| qué | por qué no hoy | cuándo sí, en un flujo nuevo |
|
|
113
|
+
|---|---|---|
|
|
114
|
+
| el componente | no hay recorridos ni funciones nuevas que señalar | el recorrido de bienvenida del panel del local; mostrar dónde está una función nueva |
|
|
115
|
+
| `footer="text-stepper"` | ningún recorrido largo hoy | recorridos de más de 5 pasos, donde los puntos ya no se cuentan («Paso 3 de 7») |
|
|
116
|
+
| `tail=false` | todo popover señala algo | la bienvenida inicial, centrada |
|
|
117
|
+
| `dismissIcon=false` | un recorrido siempre se puede saltar | un paso sin el que no funciona el siguiente |
|
|
118
|
+
| `[data-slot=body]` | título y texto alcanzan | un paso con imagen o lista |
|
|
119
|
+
|
|
120
|
+
## API
|
|
121
|
+
|
|
122
|
+
<!-- api:inicio -->
|
|
123
|
+
<!-- generada: no editar a mano — `npm run docs` -->
|
|
124
|
+
|
|
125
|
+
| input | tipo | default |
|
|
126
|
+
|---|---|---|
|
|
127
|
+
| `position` | `'top-left' \| 'top-center' \| 'top-right' \| 'bottom-left' \| 'bottom-center' \| 'bottom-right' \| 'right-top' \| 'right-center' \| 'right-bottom' \| 'left-top' \| 'left-center' \| 'left-bottom'` | `'top-left'` |
|
|
128
|
+
| `tail` | `boolean` | `true` |
|
|
129
|
+
| `icon` | `string \| null` | `'user-6-line'` |
|
|
130
|
+
| `title` | `string` | `''` |
|
|
131
|
+
| `description` | `string \| null` | `null` |
|
|
132
|
+
| `dismissIcon` | `boolean` | `true` |
|
|
133
|
+
| `footer` | `'none' \| 'stretch' \| 'text-stepper' \| 'stepper'` | `'stretch'` |
|
|
134
|
+
| `backLabel` | `string` | `'Atrás'` |
|
|
135
|
+
| `nextLabel` | `string` | `'Siguiente'` |
|
|
136
|
+
| `doubleButton` | `boolean` | `true` |
|
|
137
|
+
| `step` | `{ current: number; total: number } \| null` | `null` |
|
|
138
|
+
| `size` | `'small' \| 'medium'` | `'small'` |
|
|
139
|
+
|
|
140
|
+
| output | payload |
|
|
141
|
+
|---|---|
|
|
142
|
+
| `dismissed` | `void` |
|
|
143
|
+
| `back` | `void` |
|
|
144
|
+
| `next` | `void` |
|
|
145
|
+
<!-- api:fin -->
|
|
146
|
+
|
|
147
|
+
Slot: `[data-slot=body]` reemplaza título y descripción.
|
|
148
|
+
|
|
149
|
+
## Trampas
|
|
150
|
+
|
|
151
|
+
- **Textos por defecto en español** (desde 03-10-2026): «Atrás», «Siguiente» y, en `text-stepper`,
|
|
152
|
+
«Paso X de N» (este último no se puede cambiar).
|
|
153
|
+
- **El ícono por defecto es una persona** (`user-6-line`). Si no quieres ícono, `[icon]="null"`.
|
|
154
|
+
- **`step` vacío = 1 de 4**: con `stepper` o `text-stepper`, pásalo siempre.
|
|
155
|
+
- **No se posiciona solo**: `position` cambia dónde sale la flecha, no dónde aparece el panel.
|
|
156
|
+
Tampoco se cierra al tocar afuera ni con Escape; cierra quien escucha `(dismissed)`.
|
|
157
|
+
- `position` se lee «borde de la flecha, luego su lugar»: `top-left` es flecha **arriba a la
|
|
158
|
+
izquierda**, o sea, el popover queda **debajo** del elemento.
|
|
159
|
+
- El host lleva `role="dialog"` con `aria-label` = `title` y borra el `title` nativo.
|
|
160
|
+
- Los botones del pie no tienen `disabled`: si un paso no puede avanzar, se maneja desde `(next)`.
|
|
161
|
+
- **`stretch` reparte el ancho entre los dos botones** y en los steppers miden 80 px como mínimo
|
|
162
|
+
(crecen si el texto no entra). Hasta el 03-10-2026 no pasaba: el `.scss` apuntaba a
|
|
163
|
+
`.sui-popover__btn` y el template pone `.sui-popover__action`.
|
|
164
|
+
|
|
165
|
+
## Ejemplo
|
|
166
|
+
|
|
167
|
+
```html
|
|
168
|
+
<!-- Paso 2 de 3 de un recorrido -->
|
|
169
|
+
<sui-popover position="top-left" icon="calendar-schedule-line"
|
|
170
|
+
title="Programa tus pedidos" description="Elige el día y la hora, y el pedido entra solo a la cocina."
|
|
171
|
+
footer="stepper" [step]="{ current: 2, total: 3 }"
|
|
172
|
+
backLabel="Atrás" nextLabel="Siguiente"
|
|
173
|
+
(back)="anterior()" (next)="siguiente()" (dismissed)="saltar()" />
|
|
174
|
+
|
|
175
|
+
<!-- Aviso suelto con una sola salida -->
|
|
176
|
+
<sui-popover position="bottom-center" icon="wallet-3-line" title="Aquí ves lo que ganaste hoy"
|
|
177
|
+
[doubleButton]="false" nextLabel="Entendido" (next)="cerrar()" (dismissed)="cerrar()" />
|
|
178
|
+
```
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sui-product-card
|
|
3
|
+
selector: sui-product-card
|
|
4
|
+
resumen: Tarjeta de un producto de la carta con foto, nombre, descripción, precio y el botón para agregar (o editar)
|
|
5
|
+
alternativas: [sui-store-card (un local, no un producto), sui-card (cualquier otro contenido), sui-content-card (un producto en una fila, sin foto grande)]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# sui-product-card
|
|
9
|
+
|
|
10
|
+
Story: [Molecules/Product Card](https://sui-design-system.web.app/?path=/docs/molecules-product-card--docs)
|
|
11
|
+
|
|
12
|
+
## Cuándo usarlo / cuándo no
|
|
13
|
+
|
|
14
|
+
**Úsalo** para cada producto en una grilla de la carta: la carta del local que ve el cliente y la
|
|
15
|
+
grilla de productos que ve el dueño del local (con el lápiz).
|
|
16
|
+
|
|
17
|
+
**No lo uses** para:
|
|
18
|
+
|
|
19
|
+
- Un producto dentro del carrito, del checkout o del detalle de un pedido: ahí va una fila (sin
|
|
20
|
+
foto grande, con cantidad y subtotal).
|
|
21
|
+
- Un local: `sui-store-card`.
|
|
22
|
+
- Una promo o una campaña: tienen su propio carrusel.
|
|
23
|
+
|
|
24
|
+
Regla corta: **producto en la grilla de la carta → product-card · producto en una lista de pedido
|
|
25
|
+
→ fila.**
|
|
26
|
+
|
|
27
|
+
## Qué variante usar
|
|
28
|
+
|
|
29
|
+
> **La guía del DS no tiene página de la product card.** Es un componente propio de SUI, portado
|
|
30
|
+
> de la carta de la app. La card **dibuja, no decide**: el precio, si se vende ahora y la
|
|
31
|
+
> etiqueta de no disponible le llegan ya resueltos.
|
|
32
|
+
>
|
|
33
|
+
> Uso medido el 03-10-2026 en `master-pedidos/src/app` (misma exclusión que `sui-card`): **3
|
|
34
|
+
> product-cards en 2 archivos**: la carta del cliente
|
|
35
|
+
> (`pages/customer/restaurant-menu/restaurant-menu.html:324` y `:387`) y la grilla del local
|
|
36
|
+
> (`pages/products/products.html:145`, con `action="edit"`).
|
|
37
|
+
|
|
38
|
+
### Las piezas
|
|
39
|
+
|
|
40
|
+
| prop | cuándo | fuente |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| `name`, `price` (obligatorios) | Siempre. El precio sale con 2 decimales y punto: «S/ 35.00». | propuesta |
|
|
43
|
+
| `description` | Una línea que diga qué trae: «Con hierbas aromáticas y papas nativas». | propuesta |
|
|
44
|
+
| `image` como objeto `{ url, fallbackUrl, position }` | Lo normal: `url` = la miniatura, `fallbackUrl` = la foto grande por si la miniatura no carga, `position` = encuadre vertical guardado. | propuesta (así lo hace la carta) |
|
|
45
|
+
| `image` como string | Solo la url, sin respaldo. | propuesta |
|
|
46
|
+
| `image = null` + `fallback` | Sin foto: banda de color con el nombre (default). La carta pasa `{ color }` para variar el color por visita con `SUI_PRODUCT_FALLBACK_COLORS`. | propuesta |
|
|
47
|
+
| `available=false` + `unavailableLabel` | Agotado o fuera de horario; la etiqueta dice cuál («Agotado», «Desde las 12 m.»). Se atenúa y pierde el «+». | propuesta |
|
|
48
|
+
| `quantity` | Cuántos hay en el carrito: con más de 0, el «+» pasa a stepper (− / cantidad / +). | propuesta |
|
|
49
|
+
| `closed` | El local no recibe pedidos: se ve, no se agrega. | propuesta |
|
|
50
|
+
| `action="add"` (default) | La carta del cliente. | propuesta |
|
|
51
|
+
| `action="edit"` | La grilla del dueño: lápiz siempre (también en agotado, que es justo el que quiere tocar), nunca stepper. | propuesta |
|
|
52
|
+
| `currencySymbol` | Default `S/`. No se cambia: la app cobra en soles. | propuesta |
|
|
53
|
+
| `fallback.variant="icon"` | Ver «No usar». | propuesta |
|
|
54
|
+
|
|
55
|
+
Outputs: `openDetail` (toque en la card), `add`, `increment`, `decrement`, `edit`.
|
|
56
|
+
|
|
57
|
+
**Usos de hoy que rompen las reglas:** 0. **Falta en el DS:** el precio tachado y la chapa de
|
|
58
|
+
descuento. La carta los dibuja afuera (`pages/customer/restaurant-menu/restaurant-menu.scss:426`,
|
|
59
|
+
deuda anotada): cuando se pueda publicar, va un input `precioLista`.
|
|
60
|
+
|
|
61
|
+
## Tamaño en mobile y en web
|
|
62
|
+
|
|
63
|
+
El ancho lo da la grilla y la card llena su celda. El `size` cambia **los botones del pie**
|
|
64
|
+
(«+», lápiz y stepper), en la escala del `sui-button`:
|
|
65
|
+
|
|
66
|
+
| size | «+» / lápiz | stepper (cada lado) | glyph | fuente |
|
|
67
|
+
|---|---|---|---|---|
|
|
68
|
+
| `small` (default) | 36 × 36 | 34 × 36 | 18 / 16 | lo que había en el DS |
|
|
69
|
+
| `medium` | 40 × 40 | 40 × 40 (pill de 104) | 20 | canon (aprobado por el dueño, 03-10-2026): extensión SUI |
|
|
70
|
+
|
|
71
|
+
En `medium` el stepper (104 px) no entra al lado del precio en la grilla de 2 columnas de mobile:
|
|
72
|
+
el pie envuelve y el stepper baja a su propia línea, a la derecha. El «+» y el lápiz sí siguen al
|
|
73
|
+
lado del precio.
|
|
74
|
+
|
|
75
|
+
| uso | mobile | web | fuente |
|
|
76
|
+
|---|---|---|---|
|
|
77
|
+
| grilla de la carta | 2 columnas (`1fr 1fr`, gap 12) | `repeat(auto-fill, minmax(220px, 1fr))` desde 600 px y `minmax(180px, 1fr)` en desktop | lo que hay en la app |
|
|
78
|
+
| botón «+», lápiz, stepper | `medium` (40) | `small` (36) | propuesta: el tamaño es extensión SUI aprobada (03-10-2026); el «cuándo» falta aprobarlo |
|
|
79
|
+
|
|
80
|
+
```html
|
|
81
|
+
<sui-product-card [size]="bp.isMobile() ? 'medium' : 'small'" … />
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Precio con descuento
|
|
85
|
+
|
|
86
|
+
`precioLista` es el precio de referencia. Si es **mayor** que `price`, la card pinta el precio en
|
|
87
|
+
rojo con la chapa del ahorro al lado (`-25%`, calculada: no se pasa) y el de referencia tachado
|
|
88
|
+
debajo. Igual o menor, o `null`, se ignora. Rojo `--sui-red-700` (5.26:1 sobre blanco, AA) y en
|
|
89
|
+
oscuro `--sui-red-400`; no `--sui-state-error-base`, que da 3.66:1. Propuesta, falta aprobación
|
|
90
|
+
del dueño: reemplaza el bloque que la app dibuja afuera en `restaurant-menu.scss` (precio tachado
|
|
91
|
+
por `::after` y chapa por `::before` sobre `.product__price`), que se borra al migrar.
|
|
92
|
+
|
|
93
|
+
## «No usar»: por qué no hoy y cuándo sí
|
|
94
|
+
|
|
95
|
+
| qué | por qué no hoy | cuándo sí, en un flujo nuevo |
|
|
96
|
+
|---|---|---|
|
|
97
|
+
| `fallback: { variant: 'icon' }` | la banda con el nombre dice más que un ícono | una carta de códigos (repuestos, ferretería) donde el nombre no ayuda a reconocerlo |
|
|
98
|
+
| `currencySymbol` distinto de `S/` | la app solo cobra en soles | si algún día se cobra en dólares |
|
|
99
|
+
|
|
100
|
+
## API
|
|
101
|
+
|
|
102
|
+
<!-- api:inicio -->
|
|
103
|
+
<!-- generada: no editar a mano — `npm run docs` -->
|
|
104
|
+
|
|
105
|
+
| input | tipo | default |
|
|
106
|
+
|---|---|---|
|
|
107
|
+
| `name` | `string` | — (requerido) |
|
|
108
|
+
| `description` | `string` | `''` |
|
|
109
|
+
| `price` | `number` | — (requerido) |
|
|
110
|
+
| `image` | `SuiProductCardImage \| string \| null` | `null` |
|
|
111
|
+
| `available` | `boolean` | `true` |
|
|
112
|
+
| `quantity` | `number` | `0` |
|
|
113
|
+
| `closed` | `boolean` | `false` |
|
|
114
|
+
| `currencySymbol` | `string` | `'S/'` |
|
|
115
|
+
| `fallback` | `SuiProductCardFallback \| null` | `null` |
|
|
116
|
+
| `unavailableLabel` | `string` | `'Agotado'` |
|
|
117
|
+
| `action` | `'add' \| 'edit'` | `'add'` |
|
|
118
|
+
| `precioLista` | `number \| null` | `null` |
|
|
119
|
+
| `size` | `'small' \| 'medium'` | `'small'` |
|
|
120
|
+
|
|
121
|
+
| output | payload |
|
|
122
|
+
|---|---|
|
|
123
|
+
| `openDetail` | `void` |
|
|
124
|
+
| `add` | `void` |
|
|
125
|
+
| `increment` | `void` |
|
|
126
|
+
| `decrement` | `void` |
|
|
127
|
+
| `edit` | `void` |
|
|
128
|
+
<!-- api:fin -->
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
interface SuiProductCardImage { url: string; fallbackUrl?: string; position?: number; }
|
|
132
|
+
interface SuiProductCardFallback { variant?: 'name' | 'icon'; color?: string | null; }
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
`SUI_PRODUCT_FALLBACK_COLORS` (exportada): los colores `--sui-state-*-base` para la banda.
|
|
136
|
+
|
|
137
|
+
## Trampas
|
|
138
|
+
|
|
139
|
+
- **El host lleva `content-visibility: auto`**: las cards fuera de pantalla no se pintan. Al
|
|
140
|
+
imprimir ya no pasa (el componente lo apaga en `@media print`). En una captura de página
|
|
141
|
+
completa (shot-scraper `--full`) sí pueden salir en blanco: el opt-out es
|
|
142
|
+
`sui-product-card { content-visibility: visible; }` desde afuera.
|
|
143
|
+
- **Necesita una celda con alto**: el host es `height: 100%` y la foto usa `NgOptimizedImage`
|
|
144
|
+
`fill`. En un contenedor sin alto la card colapsa; ponla en una grilla.
|
|
145
|
+
- **La card es un `<div>`, no un `<button>`** (desde 03-10-2026): lo que abre el detalle es
|
|
146
|
+
`.product__hit`, un botón invisible estirado sobre toda la card con el nombre como
|
|
147
|
+
`aria-label`; los botones del pie van por encima (`z-index` 2). Así no hay un botón dentro de
|
|
148
|
+
otro. Un estilo de afuera que apunte a `button.product` ya no engancha.
|
|
149
|
+
- **La app pinta hoy el descuento por fuera** con `::before`/`::after` sobre `.product__price`: si
|
|
150
|
+
se pasa `precioLista` hay que borrar ese bloque en el mismo cambio, o salen dos tachados.
|
|
151
|
+
- Con `quantity === 1` el «−» pasa a basurero («Quitar del carrito»).
|
|
152
|
+
- El color sin foto es determinista por nombre: el mismo producto siempre sale del mismo color,
|
|
153
|
+
salvo que pases `fallback.color`.
|
|
154
|
+
- Cada url nueva vuelve a mostrar el barrido de carga; si la miniatura falla, intenta con
|
|
155
|
+
`fallbackUrl` antes de apagarlo.
|
|
156
|
+
|
|
157
|
+
## Ejemplo
|
|
158
|
+
|
|
159
|
+
```html
|
|
160
|
+
<sui-product-card
|
|
161
|
+
[name]="p.name"
|
|
162
|
+
[description]="p.description ?? ''"
|
|
163
|
+
[price]="p.price"
|
|
164
|
+
[image]="p.thumbnailUrl ? { url: p.thumbnailUrl, fallbackUrl: p.imageUrl, position: p.imagePosition ?? 50 } : null"
|
|
165
|
+
[available]="disponibleAhora(p)"
|
|
166
|
+
[unavailableLabel]="etiquetaNoDisponible(p)"
|
|
167
|
+
[quantity]="cantidadEnCarrito(p)"
|
|
168
|
+
[closed]="noSePuedePedir()"
|
|
169
|
+
(openDetail)="abrirDetalle(p)"
|
|
170
|
+
(add)="agregar(p)"
|
|
171
|
+
(increment)="sumar(p)"
|
|
172
|
+
(decrement)="restar(p)" />
|
|
173
|
+
```
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sui-radio-card
|
|
3
|
+
selector: sui-radio-card
|
|
4
|
+
resumen: Opción con tarjeta (ícono o foto, título, descripción y el radio) para elegir UNA de una lista corta
|
|
5
|
+
alternativas: [sui-radio-label (la misma elección sin tarjeta, en un formulario denso), sui-select (lista larga o que no entra en pantalla), sui-segmented-control (2–4 vistas de la misma pantalla), sui-checkbox-card (se pueden elegir varias), sui-switch-card (se prende o se apaga un ajuste)]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# sui-radio-card
|
|
9
|
+
|
|
10
|
+
Story: [Molecules/Card/Radio Card](https://sui-design-system.web.app/?path=/docs/molecules-card-radio-card--docs)
|
|
11
|
+
|
|
12
|
+
## Cuándo usarlo / cuándo no
|
|
13
|
+
|
|
14
|
+
**Úsalo** para elegir una sola opción de una lista corta cuando cada opción merece explicarse:
|
|
15
|
+
«Delivery / Recojo en tienda», cómo cobrar («A mi saldo / Por Yape»), el medio de pago, el motivo
|
|
16
|
+
de una cancelación, el modo de asignación de repartidores.
|
|
17
|
+
|
|
18
|
+
**No lo uses** para:
|
|
19
|
+
|
|
20
|
+
- Varias opciones que se suman: `sui-checkbox-card`.
|
|
21
|
+
- Un ajuste que se prende o se apaga: `sui-switch-card`.
|
|
22
|
+
- Una lista larga (más de 6–7 opciones) o que crece con los datos: `sui-select`.
|
|
23
|
+
- Cambiar de vista dentro de la misma pantalla: `sui-segmented-control` o tabs.
|
|
24
|
+
|
|
25
|
+
Regla corta: **una de pocas, con explicación → radio-card · una de muchas → select · varias →
|
|
26
|
+
checkbox-card.**
|
|
27
|
+
|
|
28
|
+
## Qué variante usar
|
|
29
|
+
|
|
30
|
+
> **La guía del DS no tiene página de la radio card.** De la guía sale solo lo del radio que lleva
|
|
31
|
+
> adentro: **«para elegir una sola opción de una lista corta»**. El resto es práctica de la app
|
|
32
|
+
> («propuesta») o regla ya aprobada («canon»).
|
|
33
|
+
>
|
|
34
|
+
> Uso medido el 03-10-2026 en `master-pedidos/src/app` (misma exclusión que `sui-card`): **31
|
|
35
|
+
> radio-cards en 14 archivos**. Tipos: 23 `left-icon` (3 de ellos con emoji animado por
|
|
36
|
+
> `iconSrc`), 6 `basic`, 1 `avatar`, 1 `company`. Tamaños: 24 `bp.controlSize()`, 4 `medium`, 1
|
|
37
|
+
> `xlarge` fijo, 1 dinámico, 1 sin `size`. 6 con `sublabel`, 3 con `disabled`, 1 con `badge`.
|
|
38
|
+
|
|
39
|
+
### `type` (el leading)
|
|
40
|
+
|
|
41
|
+
| type | cuándo | fuente |
|
|
42
|
+
|---|---|---|
|
|
43
|
+
| `left-icon` con `icon` | Lo normal: un ícono Remix que dice de qué va la opción (`truck-line` Delivery, `store-2-line` Recojo). | propuesta (práctica de la app) |
|
|
44
|
+
| `left-icon` con `iconSrc` | Emoji animado cuando la elección es de las grandes del rol (el vehículo del repartidor, el rol al registrarse, el tipo de mandadito). Los emojis van de `assets/emojis/` o `FLUENT_EMOJI_ANIM`. | propuesta |
|
|
45
|
+
| `left-icon` con `emoji` | Lo mismo con un nombre de `SuiEmoji` en vez de una URL. Hoy 0 usos; vale igual. | propuesta |
|
|
46
|
+
| `basic` | Opciones de texto puro: motivos de cancelación, quién paga el envío, los premios de una meta. | propuesta |
|
|
47
|
+
| `avatar` (`imageUrl`) | El logo redondo de un medio de pago (Yape, Plin, efectivo en el checkout). | propuesta |
|
|
48
|
+
| `company` (`imageUrl`) | Elegir entre tus locales (cambiar de negocio en mi-negocio). | propuesta |
|
|
49
|
+
| `brand`, `card-provider` | Ver «No usar». | propuesta |
|
|
50
|
+
|
|
51
|
+
### Las piezas
|
|
52
|
+
|
|
53
|
+
| prop | cuándo | fuente |
|
|
54
|
+
|---|---|---|
|
|
55
|
+
| `value` (obligatorio) | Siempre, aunque no haya grupo. Es lo que emite `selected`. | propuesta |
|
|
56
|
+
| `label` | Siempre. El nombre de la opción, corto: «Delivery», «Lo antes posible». | propuesta |
|
|
57
|
+
| `description` | Casi siempre: la consecuencia de elegirla («Lo revisamos y te transferimos. Puede tardar unas horas.»). | propuesta |
|
|
58
|
+
| `sublabel` | Una precisión corta entre paréntesis («(canal estable)», «(sin OTA)»). Nunca la explicación: eso es `description`. | propuesta |
|
|
59
|
+
| `badge` | Marca una opción frente a las otras: «Por defecto». Con string sale azul `light`; pasa el objeto con el color que corresponda según el badge (un «Por defecto» es `gray`). | propuesta |
|
|
60
|
+
| `disabled` | La opción existe pero hoy no se puede: di por qué en la `description` («El local está cerrado ahora»). | propuesta |
|
|
61
|
+
| `checked` / `[(ngModel)]` / `sui-radio-group` | El estado: `[checked]` + `(selected)` sueltos (lo normal en la app), o `ngModel` con `name` (checkout), o dentro de un `sui-radio-group`. | propuesta |
|
|
62
|
+
|
|
63
|
+
### `size` (el radio de adentro)
|
|
64
|
+
|
|
65
|
+
| size | cuándo | fuente |
|
|
66
|
+
|---|---|---|
|
|
67
|
+
| `xlarge` (28) | Mobile, vía `bp.controlSize()`. | canon (aprobado por el dueño, 28-09-2026: «componentes grandes») |
|
|
68
|
+
| `large` (24) | Desktop, vía `bp.controlSize()`. | canon (aprobado por el dueño, 28-09-2026) |
|
|
69
|
+
| `medium` (20, default) | No usar en pantallas nuevas. | canon (aprobado por el dueño, 28-09-2026) |
|
|
70
|
+
|
|
71
|
+
**Usos de hoy que rompen las reglas:**
|
|
72
|
+
|
|
73
|
+
- **5 sin el size del breakpoint**: `components/por-cobrar-card/por-cobrar-card.html:38` y `:48`,
|
|
74
|
+
`pages/driver/driver-dashboard/driver-dashboard.html:581`,
|
|
75
|
+
`pages/super-admin/master-orders/master-orders.html:720` (los cuatro en `medium`) y
|
|
76
|
+
`pages/mi-negocio/mi-negocio.html:22` (sin `size`). Además `pages/customer/mandadito/mandadito.html:30`
|
|
77
|
+
va en `xlarge` fijo (en web debería ser `large`).
|
|
78
|
+
- **A revisar:** `pages/super-admin/master-orders/master-orders.html:720` lista a los repartidores
|
|
79
|
+
candidatos, una lista que crece con la flota (con muchos, `sui-select` o una lista con búsqueda).
|
|
80
|
+
`pages/role-selector/role-selector.html:24` usa la radio como botón: elegir ya avanza, sin
|
|
81
|
+
`[checked]`.
|
|
82
|
+
|
|
83
|
+
## Tamaño en mobile y en web
|
|
84
|
+
|
|
85
|
+
La card entera es el área táctil (≥ 72 de alto con descripción, 16 de padding): llega al piso de
|
|
86
|
+
44 sola. El `size` cambia solo el radio.
|
|
87
|
+
|
|
88
|
+
| uso | mobile | web |
|
|
89
|
+
|---|---|---|
|
|
90
|
+
| toda radio-card | `xlarge` (radio 28) | `large` (radio 24) |
|
|
91
|
+
|
|
92
|
+
```html
|
|
93
|
+
<sui-radio-card [size]="bp.controlSize()" … /> <!-- isMobile() ? 'xlarge' : 'large' -->
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## «No usar»: por qué no hoy y cuándo sí
|
|
97
|
+
|
|
98
|
+
| qué | por qué no hoy | cuándo sí, en un flujo nuevo |
|
|
99
|
+
|---|---|---|
|
|
100
|
+
| `type="brand"` (0 usos) | no hay servicios de terceros que elegir | elegir el canal por el que te contactamos (WhatsApp, correo) con su logo (`brand`) |
|
|
101
|
+
| `type="card-provider"` (0 usos) | no hay pago con tarjeta guardada | elegir una tarjeta guardada en el checkout, cuando entre Culqi / Niubiz |
|
|
102
|
+
| `size="medium"` | el radio de 20 se pierde en el teléfono | una tabla densa solo de desktop |
|
|
103
|
+
|
|
104
|
+
## API
|
|
105
|
+
|
|
106
|
+
<!-- api:inicio -->
|
|
107
|
+
<!-- generada: no editar a mano — `npm run docs` -->
|
|
108
|
+
|
|
109
|
+
| input | tipo | default |
|
|
110
|
+
|---|---|---|
|
|
111
|
+
| `type` | `'basic' \| 'left-icon' \| 'avatar' \| 'card-provider' \| 'brand' \| 'company'` | `'basic'` |
|
|
112
|
+
| `size` | `'medium' \| 'large' \| 'xlarge'` | `'medium'` |
|
|
113
|
+
| `value` | `string` | — (requerido) |
|
|
114
|
+
| `label` | `string` | `''` |
|
|
115
|
+
| `sublabel` | `string \| null` | `null` |
|
|
116
|
+
| `description` | `string \| null` | `null` |
|
|
117
|
+
| `icon` | `string \| null` | `null` |
|
|
118
|
+
| `emoji` | `SuiEmojiName \| null` | `null` |
|
|
119
|
+
| `iconSrc` | `string \| null` | `null` |
|
|
120
|
+
| `imageUrl` | `string \| null` | `null` |
|
|
121
|
+
| `brand` | `SuiBrandLogoCompany \| null` | `null` |
|
|
122
|
+
| `badge` | `SuiBadgeConfig \| string \| null` | `null` |
|
|
123
|
+
| `disabled` | `boolean` | `false` |
|
|
124
|
+
| `checked` · model, `[(checked)]` | `boolean` | `false` |
|
|
125
|
+
|
|
126
|
+
| output | payload |
|
|
127
|
+
|---|---|
|
|
128
|
+
| `selected` | `string` |
|
|
129
|
+
<!-- api:fin -->
|
|
130
|
+
|
|
131
|
+
Implementa `ControlValueAccessor` (el valor del form es el `value` elegido). Dentro de un
|
|
132
|
+
`sui-radio-group`, el grupo decide cuál está marcada.
|
|
133
|
+
|
|
134
|
+
## Trampas
|
|
135
|
+
|
|
136
|
+
- **`value` es obligatorio** aunque la uses suelta: sin él Angular tira error de input requerido.
|
|
137
|
+
- **Precedencia del leading en `left-icon`: `icon` > `emoji` > `iconSrc`.** Si pasas `icon` y
|
|
138
|
+
`iconSrc`, gana el ícono.
|
|
139
|
+
- Con `iconSrc` el círculo pasa a modo «relleno» (sin padding): el emoji ocupa los 40 × 40.
|
|
140
|
+
- `avatar`, `company` y `card-provider` leen la imagen de **`imageUrl`**; `brand` lee `brand` (o
|
|
141
|
+
`imageUrl` si la marca no está en el catálogo). No hay slot para proyectar el leading (a
|
|
142
|
+
diferencia de `sui-checkbox-card`).
|
|
143
|
+
- Suelta (sin grupo), elegirla la marca pero **no desmarca a las otras**: el padre tiene que
|
|
144
|
+
bindear `[checked]` de todas a la misma señal.
|
|
145
|
+
- `badge` con string sale **azul `light` `small`** (en `sui-content-label` sale naranja).
|
|
146
|
+
- `size` cambia solo el radio, no el padding ni el alto de la card.
|
|
147
|
+
|
|
148
|
+
## Ejemplo
|
|
149
|
+
|
|
150
|
+
```html
|
|
151
|
+
<sui-radio-card
|
|
152
|
+
[size]="bp.controlSize()"
|
|
153
|
+
type="left-icon"
|
|
154
|
+
value="pickup"
|
|
155
|
+
icon="store-2-line"
|
|
156
|
+
label="Recojo en tienda"
|
|
157
|
+
description="Lo recoges en el local"
|
|
158
|
+
[checked]="modo() === 'pickup'"
|
|
159
|
+
(selected)="modo.set('pickup')" />
|
|
160
|
+
```
|
|
@@ -90,11 +90,11 @@ lista cargada, que viene con tope. La fórmula depende de `n`: otro denominador
|
|
|
90
90
|
| `reviewCount` | número | **No usar** (ver abajo). | propuesta, falta aprobación |
|
|
91
91
|
| `emojis` | lista | Dejar el default (cinco caras, de triste a feliz). Cambiarlo rompe la lectura de la escala. | propuesta, falta aprobación |
|
|
92
92
|
| `ariaLabel` | texto | Decir qué se califica: «Califica al repartidor», «Nota del local». El default es «Calificación». | propuesta, falta aprobación |
|
|
93
|
-
| `reason` / `reasonPlaceholder` / `reasonRows` | — | Solo en `bar-area`.
|
|
93
|
+
| `reason` / `reasonPlaceholder` / `reasonRows` | — | Solo en `bar-area`. El placeholder por defecto es «Cuéntanos por qué» (03-10-2026). | propuesta, falta aprobación |
|
|
94
94
|
|
|
95
95
|
**Usos de hoy que rompen la regla:**
|
|
96
96
|
|
|
97
|
-
- **1 `reviewCount`** (
|
|
97
|
+
- **1 `reviewCount`** (hasta el 03-10-2026 pintaba «Ratings» en inglés; ahora «calificaciones»):
|
|
98
98
|
`pages/super-admin/master-users/master-user-sheet.html:142`.
|
|
99
99
|
- **1 rating usado como ícono** (`type="heart"` con `max=1` para los favoritos):
|
|
100
100
|
`components/ratings-detail/ratings-detail.html:45`. Va `sui-icon name="heart-3-fill"`.
|
|
@@ -110,7 +110,7 @@ lista cargada, que viene con tope. La fórmula depende de `n`: otro denominador
|
|
|
110
110
|
| `type="heart"` | La app califica con estrellas; el corazón es favoritos. | «¿Cuánto te gustó?» de una campaña, donde una estrella se leería como la nota del local. |
|
|
111
111
|
| `type="number"` | No hay encuestas de 1 a 10. | «¿Qué tan probable es que nos recomiendes?» con `max=10` (ocupa 640 px de ancho). |
|
|
112
112
|
| `showValue` | Escribe «4.7» con punto; la app escribe «4,7». | Si el DS formatea en `es-PE`. |
|
|
113
|
-
| `reviewCount` |
|
|
113
|
+
| `reviewCount` | Abrevia «1.2K calificaciones» (la etiqueta está en español desde 03-10-2026). | Una lista de locales donde el conteo exacto no importa. |
|
|
114
114
|
| `alignment="vertical"` | Solo ordena `showValue` y `reviewCount`, que no se usan. | Junto con esos dos, si se arreglan. |
|
|
115
115
|
|
|
116
116
|
## Tamaño en mobile y en web
|
|
@@ -160,7 +160,7 @@ plataforma solo se elige en `inline`.
|
|
|
160
160
|
| `emojis` | `string[]` | `[ 'pensive-face', 'confused-face', 'neutral-face', 'slightly-smiling-face', 'grinning-face-smiling-eyes', ]` |
|
|
161
161
|
| `ariaLabel` | `string` | `'Calificación'` |
|
|
162
162
|
| `reason` · model, `[(reason)]` | `string` | `''` |
|
|
163
|
-
| `reasonPlaceholder` | `string` | `'
|
|
163
|
+
| `reasonPlaceholder` | `string` | `'Cuéntanos por qué'` |
|
|
164
164
|
| `reasonRows` | `number` | `3` |
|
|
165
165
|
|
|
166
166
|
| output | payload |
|
|
@@ -175,8 +175,9 @@ Implementa `ControlValueAccessor` sobre `value` (sirve con `formControlName`). `
|
|
|
175
175
|
|
|
176
176
|
- **`showValue`, `reviewCount` y `reviewLink` solo se ven con `alignment="horizontal"` o
|
|
177
177
|
`"vertical"`.** Con el default `inline` no aparecen.
|
|
178
|
-
- **`reviewCount` agrega «
|
|
179
|
-
|
|
178
|
+
- **`reviewCount` agrega «calificaciones»** (en singular con 1; antes «Ratings») y `showValue`
|
|
179
|
+
formatea con punto.
|
|
180
|
+
- **`reasonPlaceholder` por defecto dice «Cuéntanos por qué»** (hasta el 03-10-2026, «Tell us why!»).
|
|
180
181
|
- **`halfStep` solo funciona en `inline` + `readonly`.** En un input no hay medias.
|
|
181
182
|
- **En `bar` el `size` no hace nada** (íconos de 20, celdas de 64); en `cell` los íconos miden 32.
|
|
182
183
|
- **En `bar` y `bar-area` se pinta solo la celda elegida**, no las anteriores: no es una fila de
|