@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.
Files changed (85) hide show
  1. package/docs/INDEX.md +75 -80
  2. package/docs/sui-accordion/README.md +171 -0
  3. package/docs/sui-activity-feed/README.md +155 -0
  4. package/docs/sui-activity-filter/README.md +100 -0
  5. package/docs/sui-alert/README.md +13 -0
  6. package/docs/sui-badge/README.md +17 -0
  7. package/docs/sui-banner/README.md +190 -0
  8. package/docs/sui-breadcrumb-item/README.md +96 -0
  9. package/docs/sui-breadcrumbs/README.md +122 -0
  10. package/docs/sui-button/README.md +36 -0
  11. package/docs/sui-card/README.md +168 -0
  12. package/docs/sui-chart-legend/README.md +140 -0
  13. package/docs/sui-chart-legend-dot/README.md +118 -0
  14. package/docs/sui-checkbox-card/README.md +150 -0
  15. package/docs/sui-command-menu-footer/README.md +100 -0
  16. package/docs/sui-command-menu-item/README.md +140 -0
  17. package/docs/sui-command-menu-search/README.md +105 -0
  18. package/docs/sui-compact-select/README.md +130 -0
  19. package/docs/sui-compact-select-for-input/README.md +120 -0
  20. package/docs/sui-content-card/README.md +147 -0
  21. package/docs/sui-content-label/README.md +148 -0
  22. package/docs/sui-counter-input/README.md +148 -0
  23. package/docs/sui-date-selector/README.md +98 -0
  24. package/docs/sui-datepicker/README.md +197 -0
  25. package/docs/sui-day-cell/README.md +118 -0
  26. package/docs/sui-day-label/README.md +81 -0
  27. package/docs/sui-drawer-footer/README.md +127 -0
  28. package/docs/sui-drawer-header/README.md +140 -0
  29. package/docs/sui-dropdown-caption/README.md +92 -0
  30. package/docs/sui-dropdown-item/README.md +163 -0
  31. package/docs/sui-dropdown-menu/README.md +196 -0
  32. package/docs/sui-dropdown-search/README.md +113 -0
  33. package/docs/sui-empty-state/README.md +145 -0
  34. package/docs/sui-file-upload/README.md +154 -0
  35. package/docs/sui-file-upload-card/README.md +129 -0
  36. package/docs/sui-filter/README.md +181 -0
  37. package/docs/sui-href/README.md +85 -0
  38. package/docs/sui-image-upload/README.md +200 -0
  39. package/docs/sui-image-upload-profile/README.md +145 -0
  40. package/docs/sui-img-retry/README.md +107 -0
  41. package/docs/sui-inline-input/README.md +104 -0
  42. package/docs/sui-inline-select/README.md +101 -0
  43. package/docs/sui-input/README.md +247 -0
  44. package/docs/sui-integration-switch/README.md +142 -0
  45. package/docs/sui-modal/README.md +238 -0
  46. package/docs/sui-modal-footer/README.md +178 -0
  47. package/docs/sui-modal-header/README.md +115 -0
  48. package/docs/sui-modal-sheet/README.md +170 -0
  49. package/docs/sui-notification/README.md +179 -0
  50. package/docs/sui-notification-footer/README.md +98 -0
  51. package/docs/sui-notification-tab-menu/README.md +112 -0
  52. package/docs/sui-otp-input/README.md +116 -0
  53. package/docs/sui-page-header/README.md +123 -0
  54. package/docs/sui-pagination/README.md +146 -0
  55. package/docs/sui-password-strength/README.md +99 -0
  56. package/docs/sui-period-range/README.md +93 -0
  57. package/docs/sui-popover/README.md +178 -0
  58. package/docs/sui-product-card/README.md +173 -0
  59. package/docs/sui-radio-card/README.md +160 -0
  60. package/docs/sui-rating/README.md +7 -6
  61. package/docs/sui-rich-editor/README.md +114 -0
  62. package/docs/sui-segmented-control/README.md +3 -0
  63. package/docs/sui-select/README.md +183 -0
  64. package/docs/sui-sidebar/README.md +217 -0
  65. package/docs/sui-stepper/README.md +166 -0
  66. package/docs/sui-store-card/README.md +147 -0
  67. package/docs/sui-switch-card/README.md +149 -0
  68. package/docs/sui-switch-label/README.md +3 -0
  69. package/docs/sui-tab-chips/README.md +188 -0
  70. package/docs/sui-tab-menu-horizontal/README.md +142 -0
  71. package/docs/sui-tab-menu-vertical/README.md +136 -0
  72. package/docs/sui-table/README.md +264 -0
  73. package/docs/sui-tag-input/README.md +123 -0
  74. package/docs/sui-textarea/README.md +160 -0
  75. package/docs/sui-time-picker/README.md +240 -0
  76. package/docs/sui-toast/README.md +190 -0
  77. package/docs/sui-tooltip/README.md +201 -0
  78. package/docs/sui-topbar/README.md +153 -0
  79. package/docs/sui-topbar-button/README.md +95 -0
  80. package/docs/sui-topbar-item/README.md +97 -0
  81. package/docs/sui-topbar-user/README.md +83 -0
  82. package/fesm2022/ajuarezso-sui-design-system.mjs +291 -246
  83. package/fesm2022/ajuarezso-sui-design-system.mjs.map +1 -1
  84. package/package.json +1 -1
  85. package/types/ajuarezso-sui-design-system.d.ts +208 -50
@@ -0,0 +1,168 @@
1
+ ---
2
+ name: sui-card
3
+ selector: sui-card
4
+ resumen: Superficie con borde, radio y sombra que agrupa contenido, con slots de header, cuerpo, media y footer
5
+ alternativas: [sui-content-card (una fila «cara + nombre + detalle» dentro de su cajita), sui-radio-card / sui-checkbox-card / sui-switch-card (la card ES la opción que se elige), sui-product-card (un producto de la carta), sui-store-card (un local en un listado del cliente), sui-modal-sheet (contenido encima de la pantalla)]
6
+ ---
7
+
8
+ # sui-card
9
+
10
+ Story: [Molecules/Card/Card](https://sui-design-system.web.app/?path=/docs/molecules-card-card--docs)
11
+
12
+ ## Cuándo usarlo / cuándo no
13
+
14
+ **Úsalo** como la superficie de una sección o de un ítem: un bloque de KPIs, un gráfico con su
15
+ título, una fila de lista que se toca, un formulario corto dentro de una página.
16
+
17
+ **No lo uses** para:
18
+
19
+ - Una fila «foto o ícono + nombre + detalle»: eso es `sui-content-card` (o `sui-content-label`
20
+ dentro de una card que ya existe).
21
+ - Una opción que se elige: `sui-radio-card`, `sui-checkbox-card` o `sui-switch-card` ya traen la
22
+ card, el estado elegido y el área táctil.
23
+ - Un producto de la carta o un local del listado del cliente: `sui-product-card` y
24
+ `sui-store-card`.
25
+ - Contenido que aparece encima de la pantalla: `sui-modal` / `sui-modal-sheet`.
26
+
27
+ Regla corta: **agrupa contenido → card · es una fila con cara → content-card · se elige → card de
28
+ selección.**
29
+
30
+ ## Qué variante usar
31
+
32
+ > **La guía del DS no tiene página de la card.** Nada de lo que sigue sale de una guía: lo
33
+ > marcado «propuesta» sale de cómo la usa la app y falta el ok del dueño; lo «canon» ya está
34
+ > aprobado.
35
+ >
36
+ > Uso medido el 03-10-2026 en `master-pedidos/src/app` (sin `master-preview`,
37
+ > `master-prototipos`, `mockup-*`, `dx/*`, `_guia-*`, `master-rutina`, `master-medico`,
38
+ > `master-ejercicios`): **253 cards en 79 archivos**. Variantes: 227 `default` explícito, 24 sin
39
+ > `variant` (también default), 2 `elevated`, 0 `flat`. Tamaños: 95 `small`, 123 `medium`
40
+ > explícito + 21 sin `size`, 14 `large`, 0 `xlarge`. 9 con `[interactive]`. Slots: 23
41
+ > `sui-card-header`, 11 `sui-card-footer`, 4 `sui-card-media`.
42
+
43
+ ### `variant`
44
+
45
+ | variant | cuándo | fuente |
46
+ |---|---|---|
47
+ | `default` | Lo normal: la card sobre el fondo de la app (borde + sombra x-small). 251 de 253. | propuesta (práctica de la app) |
48
+ | `elevated` | La card flota sobre un mapa, una foto o un fondo de color, donde el borde se pierde y hace falta la sombra media. Precedente: el seguimiento público del pedido (`pages/public/pedido-en-vivo/pedido-en-vivo.html:19`, `:69`). | propuesta |
49
+ | `flat` | Ver «No usar». | propuesta |
50
+
51
+ ### `size` (padding × gap entre slots)
52
+
53
+ | size | medidas | cuándo | fuente |
54
+ |---|---|---|---|
55
+ | `small` | 16 / 12 | Filas de una lista de cards, KPIs chicos, cards tocables. **Toda card en mobile.** | propuesta |
56
+ | `medium` (default) | 20 / 16 | Secciones en web. | propuesta |
57
+ | `large` | 24 / 20 | La sección principal de una pantalla de web (los 14 de hoy son gráficos de reportes y los pasos del onboarding). | propuesta |
58
+ | `xlarge` | 28 / 24 | Ver «No usar». Extensión SUI (no está en Figma). | propuesta |
59
+
60
+ ### `interactive`
61
+
62
+ | valor | cuándo | fuente |
63
+ |---|---|---|
64
+ | `true` | La card entera es **una** acción: abre un detalle o lleva a otra pantalla («Mis direcciones», una factura). Da cursor, hover, foco y el arreglo de iOS. | propuesta |
65
+ | `false` (default) | La card tiene 2 acciones o más adentro, o ninguna. Las acciones van como botones dentro. | propuesta |
66
+
67
+ ### Slots
68
+
69
+ | slot | cuándo | fuente |
70
+ |---|---|---|
71
+ | `[sui-card-header]` | Título de la card a la izquierda y, si hace falta, una acción chica a la derecha (`sui-link-button` «Ver todo»). | propuesta |
72
+ | cuerpo (sin atributo) | El contenido. **Con 2 bloques o más, envuélvelos en un div propio con `display:flex; flex-direction:column; gap`** (ver Trampas). | canon (memoria del proyecto, 10-05-2026) |
73
+ | `[sui-card-media]` | Gráfico, mapa o foto de borde a borde, al final. Si después va un footer, la media deja de comerse el borde inferior. | propuesta |
74
+ | `[sui-card-footer]` | La acción de la card o un resumen. Si son dos botones, siguen el orden de `sui-modal-footer` (secundario a la izquierda, primario a la derecha). | canon (orden de botones, CLAUDE.md) |
75
+
76
+ **Usos de hoy que rompen las reglas:**
77
+
78
+ - **18 cards en 6 archivos con `gap` puesto en la clase del `sui-card`**, que no llega a los hijos
79
+ del cuerpo: `pages/central/central-inicio/central-inicio.html:36` (×6),
80
+ `pages/super-admin/master-semanas/master-semanas.html:21` (×4),
81
+ `pages/central/central-ingresos/central-ingresos.html:36` (×3), `pages/invoices/invoices.html:19`
82
+ (×2), `pages/driver/driver-history/driver-history.html:17` (×2) y
83
+ `pages/driver/driver-wallet/driver-wallet.html:154` (ahí además el `flex-direction: row` del host
84
+ no pone el badge al lado del monto: el cuerpo es un solo hijo).
85
+ - **3 cards tocables armadas a mano** (`(click)` o `routerLink` sin `[interactive]`): sin foco, sin
86
+ hover y sin el arreglo de iOS. `pages/super-admin/master-users/master-users.html:156` (con
87
+ `role="button"` y `touchstart` a mano), `pages/super-admin/master-settings/master-settings.html:601`,
88
+ `pages/driver/driver-dashboard/driver-dashboard.html:990`.
89
+
90
+ ## Tamaño en mobile y en web
91
+
92
+ El `size` de la card es su padding, no un área táctil: no tiene que llegar a 44. Lo que importa en
93
+ mobile es no perder ancho.
94
+
95
+ | uso | mobile | web |
96
+ |---|---|---|
97
+ | sección, KPI, gráfico | `small` (16) | `medium` (20) |
98
+ | sección principal de un reporte | `small` | `large` (24) |
99
+ | fila de lista tocable | `small` | `small` |
100
+
101
+ ```html
102
+ <sui-card [size]="bp.isMobile() ? 'small' : 'medium'"> … </sui-card>
103
+ ```
104
+
105
+ `bp` es el `BreakpointsService` de la app. Va al ritmo de los gaps de página (12 / 16 / 20 por
106
+ breakpoint). Si la card es tocable, el alto de la fila (≥ 44) lo da su contenido, no el `size`.
107
+
108
+ ## «No usar»: por qué no hoy y cuándo sí
109
+
110
+ | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
111
+ |---|---|---|
112
+ | `variant="flat"` (0 usos) | la app siempre pone la card sobre el fondo gris, donde la sombra ayuda | una card dentro de otra superficie blanca (un sheet, otra card), donde la sombra dobla el borde |
113
+ | `size="xlarge"` (0 usos) | ninguna pantalla lo pide; no está en Figma | un hero de desktop (la portada de un reporte impreso) |
114
+
115
+ ## API
116
+
117
+ <!-- api:inicio -->
118
+ <!-- generada: no editar a mano — `npm run docs` -->
119
+
120
+ | input | tipo | default |
121
+ |---|---|---|
122
+ | `variant` | `'default' \| 'elevated' \| 'flat'` | `'default'` |
123
+ | `size` | `'small' \| 'medium' \| 'large' \| 'xlarge'` | `'medium'` |
124
+ | `interactive` | `boolean` | `false` |
125
+
126
+ Outputs: ninguno.
127
+ <!-- api:fin -->
128
+
129
+ Slots: `[sui-card-header]`, cuerpo (`<ng-content>`), `[sui-card-media]`, `[sui-card-footer]`.
130
+
131
+ ## Trampas
132
+
133
+ - **El `gap` del host separa slots, no hijos.** El cuerpo va dentro de `.sui-card__body` (flex en
134
+ columna, sin gap). Poner `gap` en una clase del `sui-card` no separa nada de lo que proyectas: se
135
+ necesita un wrapper propio (`<div class="x__card-body">` con flex y gap).
136
+ - Sin header ni footer el host queda con `gap: 0` (`:has(> .sui-card__body:only-child)`).
137
+ - **`interactive` no trae output, pero sí teclado** (desde 03-10-2026): pone `role="button"`,
138
+ `tabindex="0"`, hover y foco, y **Enter / Espacio hacen click en la card**, así que tu `(click)`
139
+ (o el `routerLink` de un `<a>` que la envuelve) también responde al teclado. No agregues
140
+ `(keydown.enter)` además: se dispararía dos veces. Una tecla dentro de un campo o botón
141
+ proyectado es de ese control, no de la card.
142
+ - Los slots son **atributos** (`sui-card-header`), no `slot="…"`.
143
+ - El host tiene `overflow: hidden` y radio 16: lo que sobresalga (un badge colgado de la esquina)
144
+ se corta.
145
+ - `sui-card-media` rompe el padding con margen negativo leído de `--sui-card-padding-x`; si le
146
+ cambias el padding a la card desde afuera, la media queda corrida.
147
+ - En modo oscuro `elevated` usa `--sui-card-elevated-border` para el borde (la sombra no se ve).
148
+
149
+ ## Ejemplo
150
+
151
+ ```html
152
+ <!-- Sección con título, dos bloques y una acción -->
153
+ <sui-card [size]="bp.isMobile() ? 'small' : 'medium'">
154
+ <div sui-card-header class="ganancias__head">
155
+ <h3>Tus días del mes</h3>
156
+ <sui-link-button variant="primary" size="small" (click)="verTodo()">Ver todo</sui-link-button>
157
+ </div>
158
+ <div class="ganancias__card-body"> <!-- display:flex; flex-direction:column; gap:12px -->
159
+ <span>Martes 3 · 6 entregas · S/ 42.00</span>
160
+ <span>Miércoles 4 · 4 entregas · S/ 28.50</span>
161
+ </div>
162
+ </sui-card>
163
+
164
+ <!-- Fila tocable -->
165
+ <sui-card size="small" [interactive]="true" (click)="abrirDirecciones()">
166
+ …
167
+ </sui-card>
168
+ ```
@@ -0,0 +1,140 @@
1
+ ---
2
+ name: sui-chart-legend
3
+ selector: sui-chart-legend
4
+ resumen: Leyenda de un gráfico — punto de color, nombre de la serie y su valor — dibujada fuera del gráfico
5
+ alternativas: [sui-chart-legend-dot (el punto suelto, en una fila o tabla), la leyenda propia de ECharts (cuando hay que poder apagar series tocándolas), sui-badge (una etiqueta, no una serie)]
6
+ ---
7
+
8
+ # sui-chart-legend
9
+
10
+ Story: [Molecules/Chart/Chart Legend](https://sui-design-system.web.app/?path=/docs/molecules-chart-chart-legend--docs)
11
+
12
+ ## Cuándo usarlo / cuándo no
13
+
14
+ **Úsalo** debajo o al lado de un gráfico para decir **qué es cada color**, y cuánto suma cada
15
+ serie si el número importa («Yape 42 · Efectivo 31 · Plin 9»). Es texto de la página, así que se lee
16
+ igual en el celular, sin tocar nada.
17
+
18
+ **No lo uses** para:
19
+
20
+ - Una leyenda que tiene que **apagar series** al tocarlas: eso lo hace la leyenda de ECharts
21
+ (`legend: {…}`), que es interactiva. Esta no tiene clic.
22
+ - Un estado o una categoría que no viene de un gráfico: `sui-badge` o `sui-status-badge`.
23
+ - Esconder los números en un tooltip: en el celular no hay hover (así lo hizo bien
24
+ `pages/super-admin/master-drivers/master-drivers.html:226`).
25
+
26
+ ## Qué variante usar
27
+
28
+ > La guía del DS no tiene página para este componente: sale del Figma del DS (set «Chart Legends»).
29
+ > Todo lo de abajo es **propuesta**, salvo lo marcado «según el componente» o «canon».
30
+ >
31
+ > Uso medido el 03-10-2026 en `master-pedidos/src/app` (sin prototipos ni vitrinas): **1 uso**, más
32
+ > **5 leyendas hechas a mano** y **9 gráficos con la leyenda de ECharts**.
33
+
34
+ ### `items` — cada serie
35
+
36
+ | campo | valor | cuándo | fuente |
37
+ |---|---|---|---|
38
+ | `label` | nombre corto | El nombre de la serie, tal como se dice en la app: «Entregados», «Yape». | propuesta |
39
+ | `color` | sin pasar | **Lo normal** en categorías sin bien ni mal (canales, métodos de pago, distritos): el componente reparte azul, naranja, rojo, verde… en orden. | según el componente (orden) · cuándo: propuesta |
40
+ | `color` | el del estado | Cuando la serie **es un estado**: entregados `green`, cancelados `red`, pendientes `orange`. Mismo significado que en `sui-badge`. | canon (colores con significado del badge) |
41
+ | `customColor` | el color que ya usa el gráfico | Solo cuando el gráfico tiene su propia paleta y el punto tiene que coincidir. Va el mismo valor en los dos lados. | propuesta |
42
+ | `value` | número o texto | Cuando el número importa para leer el gráfico: «42», «S/ 1,200», «38 %». | propuesta |
43
+ | `disabled` | `true` | Una serie sin datos en el período: se ve, apagada, para que no parezca que falta. | propuesta |
44
+
45
+ Los 12 valores de `color`, uno por uno y con su regla, están en el README de `sui-chart-legend-dot`.
46
+
47
+ Para que el gráfico y la leyenda pinten **el mismo color**, ECharts recibe la paleta desde
48
+ `SUI_CHART_LEGEND_HEX` (exportado por el paquete): `color: [SUI_CHART_LEGEND_HEX.blue, …]`.
49
+
50
+ ### `orientation`
51
+
52
+ | orientation | cuándo | fuente |
53
+ |---|---|---|
54
+ | `horizontal` (default) | Debajo de un gráfico de barras o de líneas. Si no entra, baja a la línea siguiente. | propuesta |
55
+ | `vertical` | Al lado de una dona o un pie, con el `value` de cada serie. En mobile, debajo de la dona. | propuesta |
56
+
57
+ ### Usos de hoy que romperían la regla
58
+
59
+ - **5 leyendas hechas a mano** (punto con `[style.background]` + nombre + valor) → `sui-chart-legend`
60
+ con `customColor` o la paleta del DS: `components/marketing-channels/marketing-channels.html:10`,
61
+ `components/customer-segments/customer-segments.html:26`,
62
+ `pages/overview/components/overview-retention/overview-retention.html:12`,
63
+ `pages/reports/reports.html:59` y `:80`.
64
+ - **A discutir — 9 gráficos con la leyenda de ECharts**: `pages/super-admin/master-semanas/master-semanas.ts:187`
65
+ (y `:248`, `:288`, `:335`), `pages/super-admin/master-overview/master-overview.ts:264` y `:401`,
66
+ `pages/reports/reports.ts:338` y `:381`, `core/utils/chart-barras-repartidores.ts:166`. Si nadie
67
+ apaga series tocándolas, pasarían a `sui-chart-legend` (fuente, tamaño y color del DS en vez de
68
+ `#525252` y 12 px puestos a mano). `pages/reports/` tiene además la leyenda a mano: hay dos
69
+ leyendas para el mismo gráfico.
70
+
71
+ ## Tamaño en mobile y en web
72
+
73
+ **No tiene `size`**: punto de 16 px y texto de 12 en las dos. No se toca, así que no tiene mínimo
74
+ para el dedo; lo que cambia por plataforma es la orientación.
75
+
76
+ | uso | mobile | web | fuente |
77
+ |---|---|---|---|
78
+ | bajo barras o líneas | `horizontal` (envuelve) | `horizontal` | propuesta |
79
+ | junto a una dona | `vertical`, **debajo** de la dona | `vertical`, a la derecha | propuesta |
80
+
81
+ ```html
82
+ <sui-chart-legend [orientation]="bp.isMobile() ? 'horizontal' : 'vertical'" [items]="metodos()" />
83
+ ```
84
+
85
+ El texto de 12 px queda chico en mobile y el componente no tiene un tamaño mayor: no se cambia aquí.
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
+ | `disabled` | ningún gráfico muestra series vacías | una serie sin datos en el período elegido |
92
+ | `customColor` con un hex propio | la paleta del DS ya cubre las series | un gráfico con colores de marca de terceros (Yape morado, Plin celeste) |
93
+
94
+ ## API
95
+
96
+ <!-- api:inicio -->
97
+ <!-- generada: no editar a mano — `npm run docs` -->
98
+
99
+ | input | tipo | default |
100
+ |---|---|---|
101
+ | `items` | `readonly SuiChartLegendItem[]` | — (requerido) |
102
+ | `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` |
103
+
104
+ Outputs: ninguno.
105
+ <!-- api:fin -->
106
+
107
+ ```ts
108
+ interface SuiChartLegendItem {
109
+ label: string;
110
+ color?: SuiChartLegendColor; // 'gray' | 'light-gray' | 'blue' | 'orange' | 'red' | 'green' | 'yellow' | 'purple' | 'sky' | 'pink' | 'teal' | 'disabled'
111
+ customColor?: string; // cualquier color CSS; gana sobre `color`
112
+ value?: string | number;
113
+ disabled?: boolean; // gana sobre los dos colores
114
+ }
115
+ ```
116
+
117
+ ## Trampas
118
+
119
+ - **Sin `color`, los colores salen en orden fijo** (azul, naranja, rojo, verde, amarillo…), no los
120
+ del gráfico: si ECharts usa otra paleta, el punto y la barra no coinciden. Usa
121
+ `SUI_CHART_LEGEND_HEX` en el gráfico o pasa el color.
122
+ - El orden automático empieza en **azul**, no en el naranja de la marca.
123
+ - `value` sale a 4 px del nombre, en negro (el nombre va en gris): el formato («S/ 1,200», «38 %») lo arma quien la usa.
124
+ - Host con `role="list"` y cada item `role="listitem"`; el punto es decorativo.
125
+ - `items` es obligatorio.
126
+
127
+ ## Ejemplo
128
+
129
+ ```html
130
+ <sui-chart-legend orientation="vertical" [items]="[
131
+ { label: 'Yape', value: 42 },
132
+ { label: 'Efectivo', value: 31 },
133
+ { label: 'Plin', value: 9 },
134
+ ]" />
135
+
136
+ <sui-chart-legend [items]="[
137
+ { label: 'Entregados', color: 'green', value: '86 %' },
138
+ { label: 'Cancelados', color: 'red', value: '14 %' },
139
+ ]" />
140
+ ```
@@ -0,0 +1,118 @@
1
+ ---
2
+ name: sui-chart-legend-dot
3
+ selector: sui-chart-legend-dot
4
+ resumen: Punto de color de una serie de gráfico, para atar un número de una fila o una tabla con su color en el gráfico
5
+ alternativas: [sui-chart-legend (la leyenda completa, que ya trae sus puntos), sui-color-dot (elegir un color, no nombrar una serie), sui-badge with-dot (un estado vivo)]
6
+ ---
7
+
8
+ # sui-chart-legend-dot
9
+
10
+ Story: [Molecules/Chart/Chart Legend Dot](https://sui-design-system.web.app/?path=/docs/molecules-chart-chart-legend-dot--docs)
11
+
12
+ ## Cuándo usarlo / cuándo no
13
+
14
+ **Úsalo** suelto cuando una fila o una tabla **habla de una serie del gráfico** y el color la ata:
15
+ «● Delivery 64 %» en el resumen bajo una dona, la columna de una tabla que repite las barras.
16
+
17
+ **No lo uses** para:
18
+
19
+ - La leyenda de un gráfico: `sui-chart-legend` ya trae sus puntos.
20
+ - Elegir un color (variantes de un producto): `sui-color-dot`.
21
+ - Marcar un estado vivo («Abierto», «En línea»): `sui-badge` con `type="with-dot"`.
22
+ - La línea de tiempo de una actividad: `sui-activity-feed`.
23
+
24
+ ## Qué variante usar
25
+
26
+ > La guía del DS no tiene página para este componente: sale del Figma del DS (set «Chart Legend
27
+ > Dots»). Todo lo de abajo es **propuesta**, salvo lo marcado «según el componente» o «canon».
28
+ >
29
+ > Uso medido el 03-10-2026 en `master-pedidos/src/app`: **0 usos sueltos** (sí dentro de la única
30
+ > `sui-chart-legend`), y **3 puntos de serie hechos a mano** fuera de una leyenda.
31
+
32
+ ### `color`
33
+
34
+ Cada color apunta al mismo estado de la paleta que en `sui-badge`. En un gráfico manda una regla:
35
+ **el mismo color que la serie en el gráfico**.
36
+
37
+ | color | estado de la paleta | cuándo | fuente |
38
+ |---|---|---|---|
39
+ | `blue` | information | Primera serie de categorías sin carga (el orden automático arranca aquí). | según el componente (orden) |
40
+ | `orange` | warning | Pendiente; o segunda serie de categorías. | canon (significado del badge) · como serie de categorías: propuesta |
41
+ | `red` | error | Cancelado, rechazado, fallido. | canon (significado del badge) |
42
+ | `green` | success | Entregado, pagado, aprobado. | canon (significado del badge) |
43
+ | `yellow` | away | En pausa; o una serie más de categorías. | canon (significado del badge) · como serie de categorías: propuesta |
44
+ | `purple` | feature | Lo nuevo; o una serie más de categorías. | canon (significado del badge) · como serie de categorías: propuesta |
45
+ | `sky` · `pink` · `teal` | verified · highlighted · stable | Series de categorías a partir de la séptima. | propuesta |
46
+ | `gray` (default) | faded | «Otros» o «Sin categoría»: lo que no se reparte. | propuesta |
47
+ | `light-gray` | — | No usar: es el mismo gris del apagado. **Cuándo sí:** el resto de una barra de progreso partida («lo que falta»). | propuesta |
48
+ | `disabled` | — | Una serie sin datos o apagada. Dentro de `sui-chart-legend` va por `disabled: true`, no por color. | según el componente |
49
+ | `customColor` | el color que ya usa el gráfico | Solo si el gráfico tiene paleta propia; gana sobre `color`. | propuesta |
50
+
51
+ ### `size`
52
+
53
+ | size | cuándo | fuente |
54
+ |---|---|---|
55
+ | `small` (16 px) | Junto a texto de 12 (como en la leyenda, que lo usa siempre). | según el componente |
56
+ | `medium` (20 px, default) | Junto a texto de 14: filas y tablas. | propuesta |
57
+
58
+ El círculo de color mide 12 px en los dos tamaños: lo que cambia es el aire alrededor.
59
+
60
+ ### Usos de hoy que romperían la regla
61
+
62
+ - **3 puntos de serie hechos a mano** (`<span>` con `[style.background]`) → `sui-chart-legend-dot`:
63
+ `components/customer-retention/customer-retention.html:17`,
64
+ `components/order-fulfillment/order-fulfillment.html:17`,
65
+ `components/cancellation-rate/cancellation-rate.html:33`.
66
+ - Las 5 leyendas hechas a mano están contadas en `sui-chart-legend`.
67
+
68
+ ## Tamaño en mobile y en web
69
+
70
+ Es decorativo y no se toca: no tiene mínimo para el dedo.
71
+
72
+ | uso | mobile | web | fuente |
73
+ |---|---|---|---|
74
+ | fila de resumen o tabla | `medium` (20) | `medium` (20) | propuesta |
75
+ | junto a texto de 12 | `small` (16) | `small` (16) | según el componente |
76
+
77
+ No cambia por plataforma: va con el tamaño del texto que acompaña, no con la pantalla.
78
+
79
+ ## «No usar»: por qué no hoy y cuándo sí
80
+
81
+ | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
82
+ |---|---|---|
83
+ | `light-gray` | es el gris del apagado | el resto de una barra partida |
84
+ | `sky`, `pink`, `teal` | ningún gráfico pasa de 6 series | un gráfico por distrito o por local con 7 series o más |
85
+
86
+ ## API
87
+
88
+ <!-- api:inicio -->
89
+ <!-- generada: no editar a mano — `npm run docs` -->
90
+
91
+ | input | tipo | default |
92
+ |---|---|---|
93
+ | `color` | `'gray' \| 'light-gray' \| 'blue' \| 'orange' \| 'red' \| 'green' \| 'yellow' \| 'purple' \| 'sky' \| 'pink' \| 'teal' \| 'disabled'` | `'gray'` |
94
+ | `size` | `'medium' \| 'small'` | `'medium'` |
95
+ | `customColor` | `string \| null` | `null` |
96
+
97
+ Outputs: ninguno.
98
+ <!-- api:fin -->
99
+
100
+ Constantes exportadas: `SUI_CHART_LEGEND_COLORS` (los 11 colores en el orden del Figma),
101
+ `SUI_CHART_SERIES_COLORS` (el orden automático: azul, naranja, rojo, verde…) y
102
+ `SUI_CHART_LEGEND_HEX` (color → hex, para darle la misma paleta a ECharts).
103
+
104
+ ## Trampas
105
+
106
+ - **El default es `gray`**, no un color de serie: sin `color` todos los puntos salen grises.
107
+ - `size` arranca en `medium` aquí, pero la leyenda usa siempre `small`.
108
+ - El punto lleva un anillo blanco y una sombra para separarse del gráfico: sobre un fondo blanco
109
+ se ve un poco más chico que un círculo plano del mismo tamaño.
110
+ - `SUI_CHART_LEGEND_HEX` tiene los hex del modo claro: en modo oscuro no se invierten.
111
+ - Es decorativo (`aria-hidden`): el significado lo dice el texto de al lado.
112
+
113
+ ## Ejemplo
114
+
115
+ ```html
116
+ <span class="fila"><sui-chart-legend-dot color="green" /> Entregados <b>86 %</b></span>
117
+ <span class="fila"><sui-chart-legend-dot color="red" /> Cancelados <b>14 %</b></span>
118
+ ```
@@ -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
+ ```