@ajuarezso/sui-design-system 0.19.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.
Files changed (97) hide show
  1. package/docs/INDEX.md +136 -0
  2. package/docs/sui-alert/README.md +229 -0
  3. package/docs/sui-app-store-badge/README.md +137 -0
  4. package/docs/sui-avatar/README.md +263 -0
  5. package/docs/sui-avatar-group/README.md +115 -0
  6. package/docs/sui-badge/README.md +229 -0
  7. package/docs/sui-banner/README.md +190 -0
  8. package/docs/sui-brand-logo/README.md +143 -0
  9. package/docs/sui-breadcrumb-item/README.md +96 -0
  10. package/docs/sui-breadcrumbs/README.md +122 -0
  11. package/docs/sui-button/README.md +209 -0
  12. package/docs/sui-button-group/README.md +178 -0
  13. package/docs/sui-button-group-item/README.md +102 -0
  14. package/docs/sui-card/README.md +168 -0
  15. package/docs/sui-chart-legend/README.md +140 -0
  16. package/docs/sui-chart-legend-dot/README.md +118 -0
  17. package/docs/sui-checkbox/README.md +147 -0
  18. package/docs/sui-checkbox-card/README.md +150 -0
  19. package/docs/sui-checkbox-label/README.md +143 -0
  20. package/docs/sui-circular-progress-bar/README.md +131 -0
  21. package/docs/sui-color-dot/README.md +112 -0
  22. package/docs/sui-color-picker/README.md +124 -0
  23. package/docs/sui-compact-avatar-group/README.md +103 -0
  24. package/docs/sui-compact-button/README.md +190 -0
  25. package/docs/sui-compact-select/README.md +127 -0
  26. package/docs/sui-compact-select-for-input/README.md +117 -0
  27. package/docs/sui-content-card/README.md +147 -0
  28. package/docs/sui-content-divider/README.md +124 -0
  29. package/docs/sui-content-label/README.md +148 -0
  30. package/docs/sui-counter-input/README.md +145 -0
  31. package/docs/sui-date-selector/README.md +98 -0
  32. package/docs/sui-datepicker/README.md +193 -0
  33. package/docs/sui-day-cell/README.md +118 -0
  34. package/docs/sui-day-label/README.md +81 -0
  35. package/docs/sui-divider/README.md +102 -0
  36. package/docs/sui-drawer-footer/README.md +127 -0
  37. package/docs/sui-drawer-header/README.md +140 -0
  38. package/docs/sui-emoji/README.md +138 -0
  39. package/docs/sui-empty-state/README.md +145 -0
  40. package/docs/sui-fancy-button/README.md +148 -0
  41. package/docs/sui-file-icon/README.md +103 -0
  42. package/docs/sui-file-upload/README.md +154 -0
  43. package/docs/sui-file-upload-card/README.md +129 -0
  44. package/docs/sui-flag/README.md +99 -0
  45. package/docs/sui-form-hint/README.md +124 -0
  46. package/docs/sui-form-label/README.md +148 -0
  47. package/docs/sui-icon/README.md +135 -0
  48. package/docs/sui-image-upload/README.md +200 -0
  49. package/docs/sui-image-upload-profile/README.md +145 -0
  50. package/docs/sui-inline-input/README.md +104 -0
  51. package/docs/sui-inline-select/README.md +101 -0
  52. package/docs/sui-input/README.md +244 -0
  53. package/docs/sui-integration-switch/README.md +142 -0
  54. package/docs/sui-kbd/README.md +97 -0
  55. package/docs/sui-key-icon/README.md +125 -0
  56. package/docs/sui-link-button/README.md +221 -0
  57. package/docs/sui-logo/README.md +152 -0
  58. package/docs/sui-notification/README.md +179 -0
  59. package/docs/sui-notification-footer/README.md +98 -0
  60. package/docs/sui-notification-tab-menu/README.md +112 -0
  61. package/docs/sui-otp-input/README.md +116 -0
  62. package/docs/sui-pagination/README.md +146 -0
  63. package/docs/sui-password-strength/README.md +99 -0
  64. package/docs/sui-payment-icon/README.md +98 -0
  65. package/docs/sui-period-range/README.md +93 -0
  66. package/docs/sui-popover/README.md +178 -0
  67. package/docs/sui-product-card/README.md +173 -0
  68. package/docs/sui-progress-bar/README.md +132 -0
  69. package/docs/sui-progress-bar-label/README.md +143 -0
  70. package/docs/sui-radio/README.md +134 -0
  71. package/docs/sui-radio-card/README.md +160 -0
  72. package/docs/sui-radio-label/README.md +137 -0
  73. package/docs/sui-rating/README.md +199 -0
  74. package/docs/sui-rich-editor/README.md +114 -0
  75. package/docs/sui-segmented-control/README.md +144 -0
  76. package/docs/sui-select/README.md +180 -0
  77. package/docs/sui-slider/README.md +143 -0
  78. package/docs/sui-social-button/README.md +158 -0
  79. package/docs/sui-status-badge/README.md +164 -0
  80. package/docs/sui-stepper/README.md +166 -0
  81. package/docs/sui-store-card/README.md +147 -0
  82. package/docs/sui-switch/README.md +146 -0
  83. package/docs/sui-switch-card/README.md +149 -0
  84. package/docs/sui-switch-label/README.md +139 -0
  85. package/docs/sui-tab-chips/README.md +185 -0
  86. package/docs/sui-tab-menu-horizontal/README.md +142 -0
  87. package/docs/sui-tab-menu-vertical/README.md +136 -0
  88. package/docs/sui-tag/README.md +145 -0
  89. package/docs/sui-tag-input/README.md +120 -0
  90. package/docs/sui-textarea/README.md +157 -0
  91. package/docs/sui-time-picker/README.md +237 -0
  92. package/docs/sui-toast/README.md +190 -0
  93. package/docs/sui-tooltip/README.md +201 -0
  94. package/fesm2022/ajuarezso-sui-design-system.mjs +466 -279
  95. package/fesm2022/ajuarezso-sui-design-system.mjs.map +1 -1
  96. package/package.json +1 -1
  97. package/types/ajuarezso-sui-design-system.d.ts +367 -72
@@ -0,0 +1,190 @@
1
+ ---
2
+ name: sui-compact-button
3
+ selector: sui-compact-button
4
+ resumen: Botón de solo ícono, chico, para cuando falta espacio
5
+ alternativas: [sui-button (acción con texto, o de ícono con onlyIcon en tamaños de 28 a 52), sui-link-button (acción que se lee como texto), sui-topbar-button (ícono de la barra superior)]
6
+ ---
7
+
8
+ # sui-compact-button
9
+
10
+ Story: [Atoms/Button/Compact Button](https://sui-design-system.web.app/?path=/docs/atoms-button-compact-button--docs)
11
+
12
+ ## Cuándo usarlo / cuándo no
13
+
14
+ **Úsalo** para una acción de un solo ícono donde no entra un botón: cerrar en la cabecera de un
15
+ modal o sheet, «más» o «quitar» en una fila, el − / + de una cantidad, las flechas flotantes de un
16
+ carrusel o un mapa.
17
+
18
+ **No lo uses** para:
19
+
20
+ - **Una acción con texto**: `sui-button` o `sui-link-button`.
21
+ - **El ícono de la barra superior**: `sui-topbar-button`.
22
+ - **Un ícono decorativo** que no hace nada: `sui-icon`.
23
+
24
+ ## Qué variante usar
25
+
26
+ > **La guía del DS no dice cuándo usar cada estilo.** Su página muestra los cuatro estilos, los
27
+ > dos tamaños, el radio completo y el deshabilitado, sin do/don't. Las reglas de abajo son
28
+ > **canon (aprobado por el dueño, 03-10-2026)** salvo donde dice otra fuente.
29
+ >
30
+ > Uso medido el 03-10-2026 en `master-pedidos/src/app`: 11 compact-buttons en 7 archivos, sin
31
+ > contar prototipos ni vitrinas (`master-preview`, `master-prototipos`, `mockup-sheets-*`,
32
+ > `dx/*`, `master-rutina`, `master-medico`, `dev-index`). Estilos: 6 `ghost`, 3 `stroke` (uno
33
+ > por error, ver abajo), 2 `white`, 0 `modifiable`. Tamaños: 6 `large`, 3 `medium`, 2 `xlarge`.
34
+ > 4 con `fullRadius`, 1 con `disabled`.
35
+
36
+ ### Lo que sí dice la guía del DS
37
+
38
+ - **Para qué es**: botones para cuando el espacio es limitado.
39
+ - **Defaults**: `stroke` + `large` + sin `fullRadius`. Igual que SUI.
40
+ - **Tamaños**: solo `large` (24 px, ícono 20) y `medium` (20 px, ícono 18; en SUI, 16). `xlarge`
41
+ y los tres más grandes son extensión de SUI.
42
+ - **`modifiable` no tiene color, fondo ni hover propios**: hereda el color del contenedor.
43
+ - **Deshabilitado**: sin borde, sin fondo y sin sombra; el ícono en `text-disabled-300`.
44
+
45
+ ### `variantStyle`
46
+
47
+ | variantStyle | cuándo | ejemplo real de la app | fuente |
48
+ |---|---|---|---|
49
+ | `stroke` (default) | Acciones de una fila o una card: «más», «editar», el − / + de una cantidad. | `components/product-detail-view/product-detail-view.html:169` (− / +) | canon (aprobado por el dueño, 03-10-2026) |
50
+ | `ghost` | Cerrar en la cabecera de un modal o un sheet. | `components/store-ratings-modal/store-ratings-modal.html:33` («Cerrar») | canon (aprobado por el dueño, 03-10-2026) |
51
+ | `white` | Flotante sobre un mapa o una foto, siempre con `fullRadius`. | `pages/customer/store-browser/arrastre-carrusel.ts:102` (flechas del carrusel) | canon (aprobado por el dueño, 03-10-2026) |
52
+ | `modifiable` | Hereda el color del contenedor: el cerrar del alert (ya lo trae `sui-alert` adentro). | (sin uso directo; vive dentro de `sui-alert`) | hereda el color: según la guía del DS · dónde va: canon (aprobado por el dueño, 03-10-2026) |
53
+
54
+ **Usos de hoy que rompen la regla:**
55
+
56
+ - **1 bug: `variant="ghost"` en vez de `variantStyle`.** `pages/super-admin/master-settings/master-settings.html:647`
57
+ («Quitar este nivel»). `variant` no es un input del compact-button: el atributo se ignora y el
58
+ botón sale `stroke`. Pasar a `variantStyle="ghost"`.
59
+ - **A discutir — 5 `ghost` para acciones de fila** (quitar, más):
60
+ `components/option-sections-manager/option-sections-manager.html:39` y `:146`,
61
+ `components/add-product-modal/add-product-modal.html:306`,
62
+ `pages/super-admin/master-settings/master-settings.html:111` y `:647`. Este canon dice `stroke`
63
+ para filas y `ghost` solo para cerrar; el canon de `sui-button` permite `ghost` para editar y
64
+ borrar en filas. Los dos canon se contradicen: hay que elegir uno.
65
+
66
+ ### `size`
67
+
68
+ | size | px (ícono) | cuándo | fuente |
69
+ |---|---|---|---|
70
+ | `medium` | 20 (16) | Solo desktop, filas muy densas (tablas). | escala: según la guía del DS · cuándo: canon (aprobado por el dueño, 03-10-2026) |
71
+ | `large` (default) | 24 (20) | Desktop, dentro de cards. | default según la guía del DS · cuándo: canon (aprobado por el dueño, 03-10-2026) |
72
+ | `xlarge` | 28 (24) | Cabeceras de modal en desktop; flechas de carrusel que solo se ven con mouse. | extensión de SUI · canon (aprobado por el dueño, 03-10-2026) |
73
+ | `2xlarge` | 32 (20) | **El mínimo en mobile**: filas y cards que se tocan con el dedo. | extensión de SUI · canon (aprobado por el dueño, 03-10-2026). **En el repo del DS, todavía no en el paquete publicado 0.19.0** |
74
+ | `3xlarge` | 36 (20) | Cerrar en modales y sheets en mobile. | ídem: canon; en el repo, no en 0.19.0 |
75
+ | `4xlarge` | 40 (24) | Flotantes sobre el mapa (volver, centrar). | ídem: canon; en el repo, no en 0.19.0 |
76
+
77
+ **Usos de hoy que rompen la regla** (pantallas del cliente, que se usan en el teléfono, con
78
+ botones de 20 o 24 px):
79
+
80
+ - **4 casos**: `components/product-detail-view/product-detail-view.html:169` y `:173` (− / + en
81
+ `large` → `2xlarge`), `components/store-ratings-modal/store-ratings-modal.html:33` (cerrar en
82
+ `medium` → `3xlarge`), `pages/customer/order-history/order-history.html:383` (flecha de la fila
83
+ en `large` → `2xlarge`).
84
+ - **La migración está bloqueada** hasta que se publique la versión del DS con `2xlarge`,
85
+ `3xlarge` y `4xlarge`.
86
+
87
+ ### `fullRadius`
88
+
89
+ | fullRadius | cuándo | fuente |
90
+ |---|---|---|
91
+ | `false` (default, radio 6) | Lo normal: filas, cards, cabeceras. | default según la guía del DS · cuándo: propuesta |
92
+ | `true` (círculo) | Flotante (`white`) sobre mapa o foto. | canon (aprobado por el dueño, 03-10-2026) |
93
+ | `true` (círculo) | El − / + de una cantidad, para que se lea como un stepper. | propuesta (es lo que ya hace `product-detail-view`) |
94
+
95
+ ### `disabled`, `href`, `ariaLabel`
96
+
97
+ | prop | cuándo | fuente |
98
+ |---|---|---|
99
+ | `disabled` | Se llegó al límite: no hay más stock para sumar, no se puede quitar el último. | cómo se ve: según la guía del DS · cuándo: propuesta |
100
+ | `href` | Solo si el botón navega sin otra acción (volver a una ruta). Pinta un `<a>`; `rel` ya viene en `'noopener noreferrer'`. | propuesta |
101
+ | `ariaLabel` (requerido) | Lo que hace, no lo que muestra: «Cerrar», «Quitar opción», «Agregar uno»; nunca «X» ni «Ícono». | propuesta (el input es obligatorio) |
102
+ | `type="submit"` | Solo dentro de un `<form>`. | propuesta |
103
+
104
+ ## Tamaño en mobile y en web
105
+
106
+ En mobile se toca con el dedo: el área táctil tiene que medir **44 px o más**. En web, con mouse,
107
+ va un tamaño más chico. La app ya lo resuelve con `BreakpointsService`
108
+ (`src/app/services/breakpoints.service.ts`, mobile = hasta 767 px):
109
+ `[size]="bp.isMobile() ? 'large' : 'small'"`, 27 usos hoy en `master-pedidos` (16 `large`/`small`,
110
+ 9 `large`/`medium`, 2 `medium`/`xsmall`). Regla del dueño, 03-10-2026.
111
+
112
+ | uso | mobile | web | fuente |
113
+ |---|---|---|---|
114
+ | acciones de fila o card (más, quitar, − / +) | `2xlarge` (32) | `large` (24); `medium` (20) en tablas densas | canon (aprobado por el dueño, 03-10-2026) |
115
+ | cerrar en la cabecera de un modal o sheet | `3xlarge` (36) | `xlarge` (28) | canon (aprobado por el dueño, 03-10-2026) |
116
+ | flotante sobre el mapa o una foto | `4xlarge` (40) | `xlarge` (28) | canon (aprobado por el dueño, 03-10-2026) |
117
+
118
+ ```html
119
+ <sui-compact-button icon="close-line" variantStyle="ghost" ariaLabel="Cerrar"
120
+ [size]="bp.isMobile() ? '3xlarge' : 'xlarge'" (clicked)="cerrar()" />
121
+ ```
122
+
123
+ **`2xlarge`, `3xlarge` y `4xlarge` están en el repo del DS y todavía no en el paquete publicado
124
+ (0.19.0).** Hasta publicarlos, el patrón de arriba no compila. Aun en `4xlarge` (40) el botón queda
125
+ por debajo de 44: deja 4 px de aire alrededor (gap o padding del contenedor) para que el dedo no
126
+ toque el vecino. `medium` y `large` no van en mobile: hoy hay 4 en pantallas del cliente (ver
127
+ «`size`» arriba).
128
+
129
+ ## «No usar»: por qué no hoy y cuándo sí
130
+
131
+ Ningún valor del compact-button está en «no usar»: los cuatro estilos y los seis tamaños tienen
132
+ un caso. `modifiable` no tiene un uso directo hoy porque el único lugar donde va (el cerrar del
133
+ alert) ya lo trae `sui-alert` adentro.
134
+
135
+ ## API
136
+
137
+ <!-- api:inicio -->
138
+ <!-- generada: no editar a mano — `npm run docs` -->
139
+
140
+ | input | tipo | default |
141
+ |---|---|---|
142
+ | `icon` | `string` | — (requerido) |
143
+ | `variantStyle` | `'stroke' \| 'ghost' \| 'modifiable' \| 'white'` | `'stroke'` |
144
+ | `size` | `'medium' \| 'large' \| 'xlarge' \| '2xlarge' \| '3xlarge' \| '4xlarge'` | `'large'` |
145
+ | `fullRadius` | `boolean` | `false` |
146
+ | `disabled` | `boolean` | `false` |
147
+ | `href` | `string \| null` | `null` |
148
+ | `target` | `string \| null` | `null` |
149
+ | `rel` | `string \| null` | `'noopener noreferrer'` |
150
+ | `type` | `'button' \| 'submit' \| 'reset'` | `'button'` |
151
+ | `ariaLabel` | `string` | — (requerido) |
152
+
153
+ | output | payload |
154
+ |---|---|
155
+ | `clicked` | `MouseEvent` |
156
+ <!-- api:fin -->
157
+
158
+ El clic se escucha con `(clicked)`. `icon` recibe el nombre RemixIcon, sin el prefijo `ri-`.
159
+
160
+ ## Trampas
161
+
162
+ - **El estilo se llama `variantStyle`**, no `variant`. `variant="ghost"` no da error de
163
+ compilación: se ignora y sale `stroke` (pasó en `master-settings.html:647`).
164
+ - **`icon` y `ariaLabel` son obligatorios**: sin `ariaLabel` no compila.
165
+ - **El output es `(clicked)`**. `(click)` sobre el host también llega porque el clic burbujea; hoy 6
166
+ usos lo escuchan así (`product-detail-view.html:169` y `:173`, `master-settings.html:647`,
167
+ `arrastre-carrusel.ts:102` y `:104`, `order-history.html:383`). Usa `(clicked)`, que ya respeta
168
+ `disabled`.
169
+ - **El paquete publicado (0.19.0) solo trae `medium`, `large` y `xlarge`.** Pasar `2xlarge` con un
170
+ cast compila, pero el botón sale sin tamaño y con ícono de 16: no lo hagas hasta que se publique.
171
+ - En `medium` el ícono mide 16, no los 18 de la guía.
172
+ - `modifiable` en hover pinta blanco al 16 %: pensado para fondos oscuros o de color. Sobre blanco
173
+ casi no se nota. Se ajusta con `--sui-compact-button-hover-bg` y `--sui-compact-button-active-bg`.
174
+ - Al presionar, `stroke`, `ghost` y `white` se ponen oscuros (`bg-surface-800`) con el ícono
175
+ blanco: es el estado activo del Figma, no un error.
176
+ - Ya trae el arreglo de iOS para el `:active` pegado: no lo agregues.
177
+
178
+ ## Ejemplo
179
+
180
+ ```html
181
+ <!-- Cerrar en la cabecera de un sheet, en mobile -->
182
+ <sui-compact-button icon="close-line" variantStyle="ghost" size="xlarge" ariaLabel="Cerrar" (clicked)="cerrar()" />
183
+
184
+ <!-- Acción de una fila en desktop -->
185
+ <sui-compact-button icon="more-2-line" ariaLabel="Opciones de la sección" (clicked)="abrirMenu()" />
186
+
187
+ <!-- Flotante sobre el mapa -->
188
+ <sui-compact-button icon="arrow-left-line" variantStyle="white" [fullRadius]="true" size="xlarge"
189
+ ariaLabel="Volver" (clicked)="volver()" />
190
+ ```
@@ -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
+ ```