@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,180 @@
1
+ ---
2
+ name: sui-select
3
+ selector: sui-select
4
+ resumen: Campo que despliega una lista para elegir UNA opción (distrito, repartidor, categoría, motivo)
5
+ alternativas: [sui-radio-label / sui-radio-card (2 a 6 opciones fijas a la vista), sui-segmented-control (2 a 4 modos que se aplican al instante), sui-compact-select (filtro chico que se ajusta al texto), sui-compact-select-for-input (elegir moneda o país dentro de un campo), sui-tag-input (varios valores)]
6
+ ---
7
+
8
+ # sui-select
9
+
10
+ Story: [Molecules/Select/Select](https://sui-design-system.web.app/?path=/docs/molecules-select-select--docs)
11
+
12
+ ## Cuándo usarlo / cuándo no
13
+
14
+ **Úsalo** para elegir **una** opción de una lista que **sale de datos** (departamento, provincia,
15
+ distrito, repartidor, categoría, plan) o que tiene **más de 6 opciones fijas**.
16
+
17
+ **No lo uses** para:
18
+
19
+ - 2 a 6 opciones fijas dentro de un formulario: se ven todas de una con `sui-radio-label` (web) o
20
+ `sui-radio-card` (mobile). Abrir un menú para elegir entre «Casa» y «Trabajo» es un toque de más.
21
+ - 2 a 4 modos de la vista que se aplican al tocar (Hoy · Semana · Mes): `sui-segmented-control`.
22
+ - **Buscar** dentro de la lista: `sui-select` **no tiene buscador**. Con 40 distritos se scrollea.
23
+ - Elegir **varias**: no es múltiple. Varias opciones fijas → casillas; valores libres → `sui-tag-input`.
24
+ - Una lista con foto o bandera por opción: las opciones solo muestran texto (ver «Trampas»).
25
+
26
+ Regla corta: **sale de datos o son más de 6 → select · 2–6 fijas → radio · modos de la vista → segmented.**
27
+
28
+ ## Qué variante usar
29
+
30
+ > **La guía del DS lo define como el control para elegir una sola opción de un menú** y muestra
31
+ > label y hint, íconos, tamaños, país, método de pago, usuario y deshabilitado. Trae además tres
32
+ > variantes que en SUI son componentes aparte: `compact` (`sui-compact-select`), `inline`
33
+ > (`sui-inline-select`) y `compactForInput` (`sui-compact-select-for-input`). No dice cuándo va cada una.
34
+ >
35
+ > Uso medido el 03-10-2026 en `master-pedidos/src/app` (misma exclusión que `sui-badge`, más
36
+ > `master-ejercicios`): **57 usos en 26 archivos**. Todos `type="basic"` y sin ícono. Tamaños:
37
+ > 39 sin `size` (`medium`), 11 `large`, 3 `bp.isMobile() ? 'large' : 'small'`, 2 `medium`,
38
+ > 1 `small`, 1 `bp.controlSize()`. 29 pasan `placeholder`.
39
+
40
+ ### Qué elegir según las opciones
41
+
42
+ | caso | componente | fuente |
43
+ |---|---|---|
44
+ | La lista sale de datos (ubigeo, repartidores, categorías, planes) | `sui-select` | según la guía del DS (elegir una opción de un menú) |
45
+ | Más de ~6 opciones fijas | `sui-select` | canon (README de `sui-radio`, aprobado 03-10-2026) |
46
+ | 2 a 6 opciones fijas en un formulario | `sui-radio-label` / `sui-radio-card` | propuesta, falta aprobación (sale del umbral de `sui-radio`) |
47
+ | 2 a 4 modos que se aplican al instante | `sui-segmented-control` | canon (README de `sui-segmented-control`, aprobado 03-10-2026) |
48
+ | Filtro de una barra con 5 o más opciones | `sui-select` sin label (o `sui-compact-select` en web) | propuesta, falta aprobación |
49
+
50
+ **Candidatos de hoy** (no rompen nada; se verían mejor con radios o segmented):
51
+
52
+ - **6 selects con 2 opciones fijas**: `components/add-product-modal/add-product-modal.html:246`,
53
+ `pages/drivers/drivers.html:373` y `pages/drivers/add-driver/add-driver.html:111` («Tipo de pago»),
54
+ `pages/super-admin/master-gastos/master-gastos.html:185` y `:200`,
55
+ `pages/super-admin/master-sonidos-push/master-sonidos-push.html:85`.
56
+ - **15 con 3 a 6 opciones fijas en un formulario**: `components/address-form-modal/address-form-modal.html:11`
57
+ («Etiqueta»), `pages/customer/profile/profile.html:249` («Género»), `pages/drivers/drivers.html:359`
58
+ («Tipo de vehículo»), `pages/discounts/discounts.html:139`.
59
+ - **2 filtros de período de 3 opciones** → segmented: `pages/overview/overview.html:46`,
60
+ `pages/discounts/discounts.html:48`.
61
+
62
+ ### `type`, `leadingIcon`, `imageUrl`, `flag`, `badge`
63
+
64
+ | prop | cuándo | fuente |
65
+ |---|---|---|
66
+ | `type="basic"` (default) sin ícono | Todo select de la app hoy. | según la guía del DS |
67
+ | `type="avatar"` + `imageUrl` | Elegir un **repartidor**: la foto de quien quedó elegido en el campo. Hoy `pages/orders/orders.html:256` muestra solo el nombre. | según la guía del DS (ejemplo «User»); el caso es propuesta |
68
+ | `type="provider"` + `imageUrl` | Método de pago con logo (Yape, Plin). | según la guía del DS (ejemplo «Payment Method»); el caso es propuesta |
69
+ | `leadingIcon` (`true` o nombre RemixIcon) | Un ícono que ayuda a reconocer el campo en un formulario largo. Hoy sin caso. | según la guía del DS (ejemplo «Icons») |
70
+ | `type="country"` + `flag` | No usar hoy: todo es Perú. | según la guía del DS (ejemplo «Country») |
71
+ | `type="brand"` / `"company"` | No usar hoy. | — |
72
+ | `badge` | No usar hoy. | — |
73
+
74
+ ### Las piezas
75
+
76
+ | prop | cuándo | fuente |
77
+ |---|---|---|
78
+ | `label` | Siempre en formularios. Sin label solo en un filtro de barra donde el valor se explica solo («Todos los roles»). | según la guía del DS (ejemplo con label y hint) |
79
+ | `placeholder` | **Siempre**, en imperativo con tuteo: «Elige el motivo», «Elige tu distrito». El default es «Seleccionar...». | canon (CANON-SUI §5.3) |
80
+ | `required` · `sublabel` · `tooltip` · `hint` | Igual que `sui-input`: asterisco, «(Opcional)» con paréntesis, aclaración, ayuda de una línea. Hoy 1 sin paréntesis: `pages/customer/profile/profile.html:249`. | según la guía del DS |
81
+ | `error` + `errorMessage` | No eligió en un campo obligatorio: «Elige tu distrito». | según la guía del DS |
82
+ | `disabled` | Selects en cascada: provincia hasta elegir departamento, distrito hasta elegir provincia. | según la guía del DS (ejemplo deshabilitado); el caso ya es práctica (`components/address-form-modal/address-form-modal.html:87`) |
83
+ | `options` | `SuiSelectOption<T>[]`: `{ value, label, disabled? }`. `disabled` en la opción para lo que existe pero hoy no se puede elegir. | API |
84
+
85
+ **Usos de hoy que rompen la regla:**
86
+
87
+ - **28 sin `placeholder`** muestran «Seleccionar...» si arrancan vacíos.
88
+ - **16 placeholders «Seleccionar…» o «Selecciona…»** (y 4 que ya dicen «Elige…») → «Elige…»: «Seleccionar departamento»
89
+ (`components/address-form-modal/address-form-modal.html:77`), «Seleccionar tipo»,
90
+ «Selecciona una categoría».
91
+
92
+ ## Tamaño en mobile y en web
93
+
94
+ El campo sigue la escala del input y del botón (`large` 48 y `xlarge` 52 son extensión de SUI;
95
+ la guía tiene `medium` 40, `small` 36 y `xsmall` 32). **La lista acompaña al campo**: las opciones
96
+ miden 36 hasta `medium` (las de la guía), 44 en `large` y 48 en `xlarge`, y **en mobile (≤ 767 px)
97
+ nunca bajan de 44**, sea cual sea el `size`. El texto de la opción queda en 14/20, el mismo del
98
+ valor del campo.
99
+
100
+ | size del campo | opción en web | opción en mobile | fuente |
101
+ |---|---|---|---|
102
+ | `xsmall` · `small` · `medium` | 36 | 44 | 36: según la guía del DS · 44 en mobile: canon (aprobado por el dueño, 03-10-2026), extensión SUI |
103
+ | `large` | 44 | 44 | canon (aprobado por el dueño, 03-10-2026), extensión SUI |
104
+ | `xlarge` | 48 | 48 | canon (aprobado por el dueño, 03-10-2026), extensión SUI |
105
+
106
+ | uso | mobile | web | fuente |
107
+ |---|---|---|---|
108
+ | campo de formulario | `large` (48) | `medium` (40) | propuesta, falta aprobación (igual que `sui-input`) |
109
+ | filtro de una barra | `large` (48) | `small` (36) | propuesta (ya es práctica en `pages/orders/orders.html:256`) |
110
+ | dentro de una tabla densa | no aplica | `xsmall` (32) | según la guía del DS |
111
+ | `xlarge` (52) | no usar | no usar | propuesta: queda más alto que el botón `large` del footer |
112
+
113
+ ```html
114
+ <sui-select [size]="bp.isMobile() ? 'large' : 'medium'" label="Distrito" … /> <!-- bp = BreakpointsService -->
115
+ ```
116
+
117
+ ## «No usar»: por qué no hoy y cuándo sí
118
+
119
+ | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
120
+ |---|---|---|
121
+ | `type="country"` + `flag` | todo es Perú | si se abren repartidores o locales en otro país |
122
+ | `type="brand"` / `"company"` | no hay listas de marcas o empresas | elegir la marca de un producto envasado o la empresa de una flota |
123
+ | `leadingIcon` | ningún formulario lo necesita para reconocerse | un formulario largo del panel con varios selects seguidos |
124
+ | `badge` | no hay valores que marcar | marcar el plan elegido como «Recomendado» |
125
+ | `size="xsmall"` | no hay selects dentro de tablas | cambiar el estado de una fila sin abrir el detalle |
126
+ | `size="xlarge"` | queda más alto que el botón del footer | un select solo, como acción principal de la pantalla |
127
+
128
+ ## API
129
+
130
+ <!-- api:inicio -->
131
+ <!-- generada: no editar a mano — `npm run docs` -->
132
+
133
+ | input | tipo | default |
134
+ |---|---|---|
135
+ | `size` | `'xsmall' \| 'small' \| 'medium' \| 'large' \| 'xlarge'` | `'medium'` |
136
+ | `placeholder` | `string` | `'Seleccionar...'` |
137
+ | `options` | `SuiSelectOption<T>[]` | `[]` |
138
+ | `disabled` | `boolean` | `false` |
139
+ | `error` | `boolean` | `false` |
140
+ | `errorMessage` | `string \| null` | `null` |
141
+ | `label` | `string \| null` | `null` |
142
+ | `hint` | `string \| null` | `null` |
143
+ | `type` | `'basic' \| 'country' \| 'avatar' \| 'provider' \| 'brand' \| 'company'` | `'basic'` |
144
+ | `leadingIcon` | `string \| boolean` | `false` |
145
+ | `flag` | `SuiFlagName \| null` | `null` |
146
+ | `imageUrl` | `string \| null` | `null` |
147
+ | `badge` | `SuiBadgeConfig \| string \| null` | `null` |
148
+ | `sublabel` | `string \| null` | `null` |
149
+ | `required` | `boolean` | `false` |
150
+ | `tooltip` | `string \| null` | `null` |
151
+ | `value` · model, `[(value)]` | `T \| null` | `null` |
152
+
153
+ Outputs: ninguno.
154
+ <!-- api:fin -->
155
+
156
+ `value` es `model<T | null>`. Implementa `ControlValueAccessor`. Slot `[slot=leading]` para una
157
+ decoración propia del campo (gana sobre ícono, imagen y bandera).
158
+
159
+ ## Trampas
160
+
161
+ - **No busca y no es múltiple.** Con 40 opciones la lista se scrollea; con varias a elegir no sirve.
162
+ - **Las opciones solo llevan texto**: `SuiSelectOption` no tiene ícono, foto ni bandera. El
163
+ `type="avatar"` o `"country"` decora **el campo**, no la lista.
164
+ - **El default del placeholder es «Seleccionar...»**: genérico y con `...`. Pásalo siempre.
165
+ - El `valueChange` puede traer `null`: los usos de hoy hacen `$event ?? ''`.
166
+ - `T` arranca en `any`: tipa las opciones (`SuiSelectOption<string>[]`) para no arrastrar `any`
167
+ a la pantalla.
168
+ - Con 44 px por opción en mobile el panel muestra unas 4 opciones antes de scrollear (el alto
169
+ máximo del panel no cambió).
170
+ - El label también abre la lista al tocarlo.
171
+
172
+ ## Ejemplo
173
+
174
+ ```html
175
+ <sui-select label="Distrito" [required]="true" placeholder="Elige tu distrito"
176
+ [options]="distritos()" [disabled]="!provinciaId()"
177
+ [error]="intentado() && !distritoId()" errorMessage="Elige tu distrito"
178
+ [size]="bp.isMobile() ? 'large' : 'medium'"
179
+ [value]="distritoId()" (valueChange)="distritoId.set($event ?? '')" />
180
+ ```
@@ -0,0 +1,143 @@
1
+ ---
2
+ name: sui-slider
3
+ selector: sui-slider
4
+ resumen: Barra para elegir un valor, o un rango, dentro de una escala donde importa ver la posición
5
+ alternativas: [sui-counter-input (cantidad chica y exacta con − y +), sui-input type="number" (valor exacto o rango abierto), sui-progress-bar (avance de solo lectura)]
6
+ ---
7
+
8
+ # sui-slider
9
+
10
+ Story: [Atoms/Slider](https://sui-design-system.web.app/?path=/docs/atoms-slider--docs)
11
+
12
+ ## Cuándo usarlo / cuándo no
13
+
14
+ **Úsalo** cuando el valor vive en una escala con mínimo y máximo y **ver dónde cae** ayuda a
15
+ decidir: el radio de cobertura del repartidor en km, un rango de precios en un filtro, un
16
+ porcentaje.
17
+
18
+ **No lo uses** para:
19
+
20
+ - Una cantidad chica y exacta (unidades, comensales): `sui-counter-input`.
21
+ - Un valor exacto o sin tope (un monto, un DNI): `sui-input`.
22
+ - Mostrar avance sin que se pueda mover: `sui-progress-bar`.
23
+ - Dinero que se cobra: el arrastre no da precisión; va un `sui-input type="amount"`.
24
+
25
+ Regla corta: **escala con tope y la posición importa → slider · número exacto → input · cantidad chica → counter.**
26
+
27
+ ## Qué variante usar
28
+
29
+ > **La guía del DS lo define como selección «precisa de un valor dentro de un rango»** y muestra
30
+ > tres ejemplos: valor único, rango (dos manijas) y con tooltip. No dice cuándo va cada uno.
31
+ >
32
+ > Uso medido el 03-10-2026 en `master-pedidos/src/app` (misma exclusión que `sui-badge`):
33
+ > **1 uso**, `components/driver-coverage-modal/driver-coverage-modal.html:83` (radio de
34
+ > cobertura, 1–15 km, con `label`, `amount` y `tooltip`). Más **1 `<input type="range">` nativo**.
35
+
36
+ ### `type`
37
+
38
+ | type | cuándo | fuente |
39
+ |---|---|---|
40
+ | `single` (default) | Un valor: radio de cobertura, porcentaje. | según la guía del DS |
41
+ | `range` | Un mínimo y un máximo en la misma escala: rango de precios de un filtro. Una sola barra con dos manijas, nunca dos sliders. | según la guía del DS (existe); el «cuándo» es propuesta |
42
+
43
+ ### Las piezas
44
+
45
+ | prop | cuándo | fuente |
46
+ |---|---|---|
47
+ | `label` | Siempre que el slider no esté dentro de un campo que ya lo titula. Sin `label` desaparece toda la fila de arriba, `amount` incluido. | propuesta, falta aprobación |
48
+ | `amount` | El valor con su unidad, a la derecha del label: «12 km», «S/ 10 – S/ 40». Sin `amount` escribe el número pelado. | propuesta, falta aprobación |
49
+ | `sublabel` | Una precisión corta junto al label: «(máximo 15)». | propuesta, falta aprobación |
50
+ | `tooltip` | Solo **sin** `amount`: el número flota sobre la manija mientras se arrastra. Con `amount` repite el valor y sin unidad. | según la guía del DS (existe); el «cuándo» es propuesta |
51
+ | `tooltipAlways` | No usar (ver abajo). | propuesta, falta aprobación |
52
+ | `min` / `max` / `step` | La escala real del negocio (1–15 km, paso 1). | API |
53
+ | `disabled` | La escala existe pero hoy no se puede mover (falta un dato antes). | propuesta, falta aprobación |
54
+ | `size` | `medium` (default, Figma): manija 16, riel 6, label 12/16. `large`: manija 24, riel 8, punto interno 8, label 14/20 — para mobile. | `medium`: según la guía del DS · `large`: canon (aprobado por el dueño, 03-10-2026), extensión SUI |
55
+
56
+ **Usos de hoy que rompen la propuesta:**
57
+
58
+ - **1 con `amount` y `tooltip` a la vez:** `components/driver-coverage-modal/driver-coverage-modal.html:83`
59
+ muestra «12 km» arriba y «12» flotando al arrastrar.
60
+ - **1 nativo → `sui-slider`:** `components/image-cropper/image-cropper.html:57` (zoom del recorte).
61
+ A discutir: es un control de herramienta sin label, con botones − y + al lado.
62
+
63
+ ## Tamaño en mobile y en web
64
+
65
+ En mobile se toca con el dedo: el área táctil tiene que medir **44 px o más**. En web, con mouse,
66
+ va un tamaño más chico. La app ya lo resuelve con `BreakpointsService`
67
+ (`src/app/services/breakpoints.service.ts`, mobile = hasta 767 px). Regla del dueño, 03-10-2026.
68
+
69
+ | uso | mobile | web | fuente |
70
+ |---|---|---|---|
71
+ | slider con label (radio de cobertura, filtro de precio) | `large` (manija 24, riel 8) | `medium` (manija 16, riel 6) | canon (aprobado por el dueño, 03-10-2026) |
72
+
73
+ ```html
74
+ <sui-slider [size]="bp.isMobile() ? 'large' : 'medium'" label="Radio de cobertura" amount="12 km"
75
+ [min]="1" [max]="15" [(value)]="radioKm" />
76
+ ```
77
+
78
+ Toda la barra responde al toque (24 de alto en `large`), así que no hace falta acertarle a la
79
+ manija. Igual la barra mide menos de 44: el slider necesita aire arriba y abajo en la fila. La
80
+ manija en 0 o en 100 sobresale media manija (12 px en `large`) del borde de la barra: el
81
+ contenedor tiene que tener margen lateral.
82
+
83
+ ## «No usar»: por qué no hoy y cuándo sí
84
+
85
+ | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
86
+ |---|---|---|
87
+ | `type="range"` (0 usos) | ningún filtro de la app pide mínimo y máximo | un filtro de rango de precios o de distancia en la búsqueda del cliente |
88
+ | `tooltipAlways` | un número fijo encima de la manija tapa el contenido de arriba y repite el `amount` | un slider sin `label` dentro de una herramienta (zoom del recorte), donde el número es lo único que orienta |
89
+
90
+ ## API
91
+
92
+ <!-- api:inicio -->
93
+ <!-- generada: no editar a mano — `npm run docs` -->
94
+
95
+ | input | tipo | default |
96
+ |---|---|---|
97
+ | `type` | `'single' \| 'range'` | `'single'` |
98
+ | `size` | `'medium' \| 'large'` | `'medium'` |
99
+ | `min` | `number` | `0` |
100
+ | `max` | `number` | `100` |
101
+ | `step` | `number` | `1` |
102
+ | `label` | `string` | `''` |
103
+ | `sublabel` | `string` | `''` |
104
+ | `amount` | `string \| null` | `null` |
105
+ | `tooltip` | `boolean` | `false` |
106
+ | `tooltipAlways` | `boolean` | `false` |
107
+ | `disabled` | `boolean` | `false` |
108
+ | `value` | `number` | `0` |
109
+ | `minValue` | `number` | `0` |
110
+ | `maxValue` | `number` | `0` |
111
+
112
+ | output | payload |
113
+ |---|---|
114
+ | `valueChange` | `number` |
115
+ | `minValueChange` | `number` |
116
+ | `maxValueChange` | `number` |
117
+ <!-- api:fin -->
118
+
119
+ Implementa `ControlValueAccessor` **solo para `single`**.
120
+
121
+ ## Trampas
122
+
123
+ - **`label=""` borra toda la fila**, `amount` incluido. No hay forma de tener solo el valor.
124
+ - **El tooltip va 28 px arriba de la manija**: deja aire arriba o queda cortado.
125
+ - En `range`, `amount` vacío escribe «min–max» con guion largo; el formulario no lo cubre: usa
126
+ `[(minValue)]` y `[(maxValue)]`.
127
+ - Con `formControlName` ignora `[value]`. No mezcles las dos formas.
128
+ - `value` es input + output (`[(value)]` funciona), no un model.
129
+ - El punto de la manija queda **gris** cuando el valor está en el mínimo: es a propósito.
130
+ - Mide el ancho con el DOM: si arranca oculto (`display: none`, una pestaña cerrada) el arrastre
131
+ calcula mal hasta que se muestra.
132
+ - Las flechas, Inicio y Fin lo mueven con teclado.
133
+
134
+ ## Ejemplo
135
+
136
+ ```html
137
+ <sui-slider
138
+ label="Radio de cobertura"
139
+ [amount]="radioKm() + ' km'"
140
+ [min]="1" [max]="15" [step]="1"
141
+ [value]="radioKm()"
142
+ (valueChange)="radioKm.set($event)" />
143
+ ```
@@ -0,0 +1,158 @@
1
+ ---
2
+ name: sui-social-button
3
+ selector: sui-social-button
4
+ resumen: Botón para iniciar sesión o registrarse con una cuenta de Google o Apple
5
+ alternativas: [sui-button (cualquier otra acción, aunque mencione una marca), sui-app-store-badge (descargar la app de una tienda)]
6
+ ---
7
+
8
+ # sui-social-button
9
+
10
+ Story: [Atoms/Button/Social Button](https://sui-design-system.web.app/?path=/docs/atoms-button-social-button--docs)
11
+
12
+ ## Cuándo usarlo / cuándo no
13
+
14
+ **Úsalo** solo en las pantallas de iniciar sesión y registrarse, para entrar con una cuenta de
15
+ otra marca: hoy Google y Apple.
16
+
17
+ **No lo uses** para:
18
+
19
+ - **Abrir WhatsApp, el mapa u otra app**: `sui-button` `filled` `neutral` con su ícono.
20
+ - **Descargar la app**: `sui-app-store-badge`.
21
+ - **Una marca sin login implementado** «para que se vea completo»: un botón que no hace nada es
22
+ peor que no tenerlo.
23
+
24
+ ## Qué variante usar
25
+
26
+ > **La guía del DS no dice cuándo usar cada marca ni cada estilo.** Su página lo presenta como
27
+ > «simplificar el inicio de sesión y el registro» y muestra las siete marcas en lleno y en borde,
28
+ > sin do/don't. Las reglas de abajo son **canon (aprobado por el dueño, 03-10-2026)** salvo donde
29
+ > dice otra fuente.
30
+ >
31
+ > Uso medido el 03-10-2026 en `master-pedidos/src/app`: 5 social-buttons en 2 archivos, sin contar
32
+ > prototipos ni vitrinas. Marcas: 2 `google`, 1 `apple`, 1 `x-twitter`, 1 `linkedin`. Estilos:
33
+ > 4 `stroke`, 1 `filled`. 3 con `onlyIcon`, 3 con `loading`.
34
+
35
+ ### Lo que sí dice la guía del DS
36
+
37
+ - **Para qué es**: simplificar el inicio de sesión y el registro.
38
+ - **Defaults**: `apple` + `filled`. SUI también arranca en `filled`, pero `brand` es obligatorio.
39
+ - **Siete marcas**: Apple, X (en la guía, `twitter`), Google, Facebook, LinkedIn, GitHub y Dropbox,
40
+ cada una en lleno (`filled`, el color de la marca) y en borde (`stroke`, fondo blanco y logo a
41
+ color). La guía llama `mode` a lo que SUI llama `variantStyle`.
42
+ - **No trae `onlyIcon` ni `loading`**: el primero sale del Figma y el segundo es extensión de SUI.
43
+
44
+ ### `brand` + `variantStyle`
45
+
46
+ | brand + estilo | cuándo | ejemplo real de la app | fuente |
47
+ |---|---|---|---|
48
+ | `google` + `stroke` | Iniciar sesión o registrarse con Google: fondo blanco, logo a color. | `pages/auth/login/login.html:39` («Continuar con Google») | canon (aprobado por el dueño, 03-10-2026) |
49
+ | `apple` + `filled` | Iniciar sesión con Apple: negro lleno, como pide Apple. | `pages/auth/login/login.html:50` («Continuar con Apple») | canon (aprobado por el dueño, 03-10-2026) |
50
+ | `google` + `filled` (rojo) | No: el botón de Google va en blanco. Es lo que sale si se olvida `variantStyle`. | — | propuesta |
51
+ | `apple` + `stroke` | No: Apple va negro lleno en tema claro. | — | propuesta |
52
+ | `facebook`, `x-twitter`, `linkedin`, `github`, `dropbox` (cualquier estilo) | No hay login con esas cuentas. | — | no usar · canon (aprobado por el dueño, 03-10-2026) |
53
+
54
+ ### `onlyIcon`
55
+
56
+ | onlyIcon | cuándo | fuente |
57
+ |---|---|---|
58
+ | `false` (default) | Siempre en el login: logo + «Continuar con …». | canon (aprobado por el dueño, 03-10-2026) |
59
+ | `true` | No: Apple exige el texto en su botón de login. | no usar · canon (aprobado por el dueño, 03-10-2026) |
60
+
61
+ **Usos de hoy que rompen la regla:**
62
+
63
+ - **3 casos, todos en `pages/auth/register/register.html`**: `:86` (`x-twitter`), `:87` (`google`) y
64
+ `:94` (`linkedin`), los tres con `onlyIcon`. X y LinkedIn además están deshabilitados porque no
65
+ hay login con esas cuentas (el comentario del HTML lo dice: son decorativos). Pasar a lo mismo que
66
+ el login: `google` `stroke` con texto (y `apple` `filled` si el registro ofrece Apple), y quitar
67
+ X y LinkedIn.
68
+
69
+ ### `label`, `loading`, `disabled`, `href`
70
+
71
+ | prop | cuándo | fuente |
72
+ |---|---|---|
73
+ | `label` | Sin pasarlo sale «Continuar con Google» / «Continuar con Apple», que sirve igual para entrar y para registrarse. Pasarlo solo si el texto tiene que decir otra cosa. | propuesta |
74
+ | `loading` | Desde el toque hasta que vuelve la ventana de la marca: cambia el logo por un spinner y deshabilita el botón. | propuesta (ya es la práctica del login) |
75
+ | `disabled` | Mientras otro login está en curso, para que no se abran dos (en el login: `processingRedirect`). Nunca para una marca que no tiene login. | propuesta |
76
+ | `href` | Solo si el login se hace navegando a una URL (OAuth por redirect web). Pinta un `<a>`. | propuesta |
77
+ | `ariaLabel` | No hace falta: con texto se lee el texto; con `onlyIcon` el componente usa el label. | propuesta |
78
+
79
+ ## Tamaño en mobile y en web
80
+
81
+ En mobile se toca con el dedo: el área táctil tiene que medir **44 px o más**. En web, con mouse,
82
+ va un tamaño más chico. La app ya lo resuelve con `BreakpointsService`
83
+ (`src/app/services/breakpoints.service.ts`, mobile = hasta 767 px):
84
+ `[size]="bp.isMobile() ? 'large' : 'small'"`, 27 usos hoy en `master-pedidos` (16 `large`/`small`,
85
+ 9 `large`/`medium`, 2 `medium`/`xsmall`). Regla del dueño, 03-10-2026.
86
+
87
+ | uso | mobile | web | fuente |
88
+ |---|---|---|---|
89
+ | login con Google o Apple | 40 de alto, **ancho completo** (`width: 100%`) | 40 de alto, ancho del formulario | propuesta (es lo que ya hace `pages/auth/login/login.html` con `.auth-page__provider-btn`) |
90
+
91
+ **Ancho completo**: `width: 100%` en el host estira el botón (arreglado en el DS el 03-10-2026 con
92
+ `flex: 1 1 auto` en `.sui-social-button__el`; antes el host medía 360 y el botón 193). Sin
93
+ `width` sigue midiendo lo que su texto, como siempre. Con `onlyIcon` el cuadrado de 40 no se
94
+ estira nunca. El host sigue siendo `inline-flex`: para el ancho completo va `width: 100%`, no
95
+ `display: block`. El `::ng-deep .sui-social-button__el { width: 100% }` de
96
+ `pages/auth/auth-shared.scss` queda de más con la versión que trae el arreglo.
97
+
98
+ No tiene input `size`: mide siempre 40 de alto. En mobile no llega a 44; lo compensa el ancho
99
+ completo (el dedo no puede errarle) y 12 px de separación entre los dos botones. Si un día hace
100
+ falta más alto, se pide al DS un `size`, no se estira con CSS (el logo y el padding no escalan).
101
+
102
+ ## «No usar»: por qué no hoy y cuándo sí
103
+
104
+ Nada se borra del DS. Lo marcado «no usar» no tiene caso en la app de hoy; si un flujo nuevo cae
105
+ en la columna de la derecha, se usa (aprobado por el dueño, 03-10-2026).
106
+
107
+ | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
108
+ |---|---|---|
109
+ | `facebook`, `x-twitter`, `linkedin`, `github`, `dropbox` | no hay login con esas cuentas | si se agrega «Continuar con Facebook» (muy usado en Perú) o botones de compartir en redes |
110
+ | `onlyIcon` | Apple exige el texto en su botón de login | una fila de «compartir en» con íconos de redes, fuera del login |
111
+
112
+ ## API
113
+
114
+ <!-- api:inicio -->
115
+ <!-- generada: no editar a mano — `npm run docs` -->
116
+
117
+ | input | tipo | default |
118
+ |---|---|---|
119
+ | `brand` | `'apple' \| 'x-twitter' \| 'google' \| 'facebook' \| 'linkedin' \| 'github' \| 'dropbox'` | — (requerido) |
120
+ | `variantStyle` | `'filled' \| 'stroke'` | `'filled'` |
121
+ | `onlyIcon` | `boolean` | `false` |
122
+ | `label` | `string \| null` | `null` |
123
+ | `disabled` | `boolean` | `false` |
124
+ | `loading` | `boolean` | `false` |
125
+ | `href` | `string \| null` | `null` |
126
+ | `target` | `string \| null` | `null` |
127
+ | `rel` | `string \| null` | `'noopener noreferrer'` |
128
+ | `type` | `'button' \| 'submit' \| 'reset'` | `'button'` |
129
+ | `ariaLabel` | `string \| null` | `null` |
130
+
131
+ | output | payload |
132
+ |---|---|
133
+ | `clicked` | `MouseEvent` |
134
+ <!-- api:fin -->
135
+
136
+ ## Trampas
137
+
138
+ - **`brand` es obligatorio** y **`variantStyle` arranca en `filled`**: `<sui-social-button brand="google" />`
139
+ sale rojo lleno. Para el login de Google hay que pasar `variantStyle="stroke"`.
140
+ - **El estilo se llama `variantStyle`** (en la guía, `mode`) y **X se llama `x-twitter`** (en la
141
+ guía, `twitter`).
142
+ - **No tiene `size`**: mide 40 px de alto. Con `width: 100%` en el host el botón se estira al ancho completo (arreglado en el DS el 03-10-2026; antes no estiraba). El de solo ícono queda en 40 × 40.
143
+ - **`loading` también deshabilita**: no emite `(clicked)` mientras está en `true`.
144
+ - El logo es una imagen distinta por tema: en modo oscuro, Apple, X y GitHub en `stroke` usan el
145
+ logo blanco para no perderse. El componente lo resuelve solo leyendo `data-theme`.
146
+ - El radio es 10 px, no pill como `sui-button`.
147
+ - El output es `(clicked)`.
148
+ - Ya trae el arreglo de iOS para el `:active` pegado: no lo agregues.
149
+
150
+ ## Ejemplo
151
+
152
+ ```html
153
+ <!-- Login: Google en blanco, Apple negro lleno, los dos con texto -->
154
+ <sui-social-button brand="google" variantStyle="stroke" [loading]="cargandoGoogle()"
155
+ [disabled]="procesando()" (clicked)="entrarConGoogle()" />
156
+ <sui-social-button brand="apple" variantStyle="filled" [loading]="cargandoApple()"
157
+ [disabled]="procesando()" (clicked)="entrarConApple()" />
158
+ ```
@@ -0,0 +1,164 @@
1
+ ---
2
+ name: sui-status-badge
3
+ selector: sui-status-badge
4
+ resumen: El resultado de un ciclo (completado, pendiente, fallido, deshabilitado) con su color y su ícono ya resueltos
5
+ alternativas: [sui-badge (estado con muchos valores, categoría o distinción), sui-tag (chip neutro que se puede quitar), sui-alert (mensaje que hay que leer)]
6
+ ---
7
+
8
+ # sui-status-badge
9
+
10
+ Story: [Atoms/Badge/Status Badge](https://sui-design-system.web.app/?path=/docs/atoms-badge-status-badge--docs)
11
+
12
+ ## Cuándo usarlo / cuándo no
13
+
14
+ **Úsalo** cuando el valor es el **resultado de un ciclo** y cae en uno de estos: terminó bien
15
+ («Pagado», «Aprobada»), espera que alguien actúe («Pendiente», «En revisión»), terminó mal
16
+ («Rechazada», «Anulado») o está apagado («Desactivado», «Vencido»). El componente pone el color
17
+ y el ícono a partir del `status`: la pantalla no elige ninguno de los dos.
18
+
19
+ **No lo uses** para:
20
+
21
+ - **Un estado con más valores** que esos cuatro (los de un pedido: preparando, en camino,
22
+ entregado…): `sui-badge`. Es la misma frontera que fija el README del badge.
23
+ - **Una categoría o una distinción de marca** («Hamburguesas», «Local exclusivo»): no es un
24
+ estado. `sui-badge` gray, o el color cuyo significado le calce (pink destacado, sky verificado,
25
+ purple nuevo).
26
+ - Un chip que se quita: `sui-tag`.
27
+ - Un mensaje con explicación: `sui-alert`.
28
+
29
+ Regla corta: **¿es el final (o la espera) de un trámite? → status-badge · cualquier otra
30
+ etiqueta → badge.**
31
+
32
+ ## Qué variante usar
33
+
34
+ > **La guía del DS dice para qué es, no cuándo usar cada estilo.** Su página lo define como
35
+ > «resaltar estados o condiciones en poco espacio», trae cuatro estados (`completed`,
36
+ > `pending`, `failed`, `disabled`), dos estilos (`stroke`, `light`), ícono o punto, y un ícono
37
+ > por estado en sus ejemplos (los mismos que pone SUI). No trae do/don't. Lo marcado
38
+ > «según la guía del DS» sale de ahí; el resto es **propuesta, falta aprobación**.
39
+ >
40
+ > Uso medido el 03-10-2026 en `master-pedidos/src/app`: **0 status-badges** (eran 3), sin contar
41
+ > prototipos ni vitrinas (`master-preview`, `master-prototipos`, `mockup-sheets-*`, `dx/*`,
42
+ > `_guia-*`, `master-rutina`, `master-medico`, `master-ejercicios`, `dev-index`). Los 3 que había
43
+ > eran los distintivos del local y pasaron a `sui-badge` (ver abajo). Fuera de esa cuenta,
44
+ > `master-ejercicios` tiene 2 más (categorías de ejercicio con `withDot`).
45
+
46
+ ### `status` — mismo significado de color que `sui-badge`
47
+
48
+ | status | color (token de estado) | cuándo | copy de ejemplo | fuente |
49
+ |---|---|---|---|---|
50
+ | `completed` (default) | green (`success`) | Terminó bien. | «Pagado», «Aprobada», «Entregado» | según la guía del DS (estado y color) |
51
+ | `pending` | orange (`warning`) | Espera que alguien haga algo. | «Pendiente», «En revisión» | según la guía del DS (estado y color) |
52
+ | `failed` | red (`error`) | Terminó mal. | «Rechazada», «Fallido», «Anulado» | según la guía del DS (estado y color) |
53
+ | `disabled` | gray (`faded`) | Apagado o fuera de uso. | «Desactivado», «Vencido» | según la guía del DS (estado y color; es el default de la guía) |
54
+ | `information` | blue (`information`) | Extensión SUI: avanza solo y nadie tiene que actuar. | «En proceso» | propuesta, falta aprobación |
55
+
56
+ Es el mismo mapa que el badge aprobado (green bien, orange pendiente, red error, blue info,
57
+ gray neutro), porque los dos pintan con los mismos tokens `--sui-state-*`.
58
+
59
+ ### `appearance`, `withDot` e `icon`
60
+
61
+ | propiedad | valor | cuándo | fuente |
62
+ |---|---|---|---|
63
+ | `appearance` | `stroke` (default) | Tablas y listas: fondo blanco, texto gris, solo el ícono lleva color. Es el que menos ruido hace cuando hay muchos. | según la guía del DS (default) |
64
+ | `appearance` | `light` | El estado es **el** dato de la card o de la fila (fondo teñido, texto de color). | propuesta, falta aprobación |
65
+ | `withDot` | `false` (default) | Ícono del estado. Lo normal. | según la guía del DS |
66
+ | `withDot` | `true` con `stroke` | Tabla densa con la misma columna de estado en muchas filas, donde veinte íconos hacen ruido. | propuesta, falta aprobación |
67
+ | `withDot` | `true` con `light` | **No usar** (ver abajo). | propuesta, falta aprobación |
68
+ | `icon` | `''` (default) | Siempre el del estado: es la mitad de su significado. | según la guía del DS (ícono por estado en sus ejemplos) |
69
+ | `icon` | nombre Remix | **No usar** (ver abajo). | propuesta, falta aprobación |
70
+
71
+ ### `sui-status-badge` o `sui-badge`
72
+
73
+ | caso | componente | fuente |
74
+ |---|---|---|
75
+ | El estado cae en completado / pendiente / fallido / deshabilitado | `sui-status-badge` | canon (aprobado por el dueño, 03-10-2026, en el README de sui-badge) |
76
+ | Estado con más valores (pedido) o una categoría | `sui-badge` | canon (aprobado por el dueño, 03-10-2026, en el README de sui-badge) |
77
+
78
+ **Candidatos para pasar de badge a status-badge**: los **17 badges con un estado de ciclo escrito
79
+ a mano** que cuenta el README de `sui-badge` («Pendiente», «Aprobado», «Rechazado», «En
80
+ revisión», «Pagado», «Anulado»), por ejemplo
81
+ `pages/super-admin/master-drivers/master-drivers.html:781` y
82
+ `pages/driver/driver-profile/driver-profile.html:83`.
83
+
84
+ **Usos de hoy que rompen la regla: 0.** Los distintivos del local («Local exclusivo», «Mismo
85
+ precio que en el local») usaban el status-badge en `pending` y `completed`, que se leen como un
86
+ trámite que avanza. Desde el 03-10-2026 son `<sui-badge color="pink" type="left-icon">` y
87
+ `<sui-badge color="sky" type="left-icon">` (pink = destacado, sky = verificado, los dos con modo
88
+ oscuro por sus tokens `--sui-state-*`), en `core/distintivos-local.ts`. Canon (aprobado por el
89
+ dueño, 03-10-2026).
90
+
91
+ ## No usar: por qué no hoy y cuándo sí
92
+
93
+ | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
94
+ |---|---|---|
95
+ | `withDot` + `light` | El fondo teñido ya dice el color; el punto repite. | Ninguno a la vista. Si hace falta punto, va `stroke` + `withDot`. |
96
+ | `icon` propio | El ícono del estado es la mitad del significado: cambiarlo rompe la lectura. | Una espera **por hora** y no por alguien: «Programado 7:00 p. m.» con `pending` + `icon="time-fill"`. |
97
+ | Sin texto (solo ícono) | Sin texto no se sabe qué estado es. | Una columna muy angosta con el texto en `aria-label` y un tooltip. |
98
+
99
+ ## Tamaño en mobile y en web
100
+
101
+ Criterio de la app: **en mobile se lee y se toca con el dedo, así que va más grande; en web
102
+ (desktop), más chico.** Mobile es `≤ 767 px`, el mismo corte de `BreakpointsService.isMobile()`
103
+ en master-pedidos. Fuente: canon del dueño (03-10-2026), el mismo patrón que ya usan 27 controles
104
+ de la app.
105
+
106
+ | size | alto | texto | ícono (caja) | punto |
107
+ |---|---|---|---|---|
108
+ | `medium` (default) | 24 px | `label-xs` 12/16 | 12 (16) | 6 |
109
+ | `large` | 28 px | `label-sm` 14/20 | 16 (20) | 8 |
110
+ | `xlarge` | 32 px | `label-md` 16/24 | 20 (24) | 8 |
111
+
112
+ `medium` es el de Figma; `large` y `xlarge` son extensión SUI (03-10-2026). Siguen la escala del
113
+ `sui-button` (28 · 32) y no la del `sui-badge` (24 · 28), porque el status-badge ya parte de 24.
114
+
115
+ | uso | mobile | web | fuente |
116
+ |---|---|---|---|
117
+ | Estado en una fila, card o tabla | `large` (28) | `medium` (24) | propuesta: el tamaño es extensión SUI aprobada (03-10-2026); el «cuándo» falta aprobarlo |
118
+ | Estado principal de una pantalla de detalle (el pedido que se mira) | `xlarge` (32) | `medium` (24) | propuesta: el tamaño es extensión SUI aprobada (03-10-2026); el «cuándo» falta aprobarlo |
119
+
120
+ ```html
121
+ <sui-status-badge status="completed" appearance="light" [size]="bp.isMobile() ? 'large' : 'medium'">Entregado</sui-status-badge>
122
+ ```
123
+
124
+ No se agranda con CSS en la pantalla: se pasa `size`.
125
+
126
+ ## API
127
+
128
+ <!-- api:inicio -->
129
+ <!-- generada: no editar a mano — `npm run docs` -->
130
+
131
+ | input | tipo | default |
132
+ |---|---|---|
133
+ | `status` | `'completed' \| 'pending' \| 'failed' \| 'information' \| 'disabled'` | `'completed'` |
134
+ | `appearance` | `'stroke' \| 'light'` | `'stroke'` |
135
+ | `size` | `'medium' \| 'large' \| 'xlarge'` | `'medium'` |
136
+ | `withDot` | `boolean` | `false` |
137
+ | `icon` | `string` | `''` |
138
+
139
+ Outputs: ninguno.
140
+ <!-- api:fin -->
141
+
142
+ Slot: `<ng-content>` (el texto).
143
+
144
+ ## Trampas
145
+
146
+ - **El default es `completed`**; el de la guía es `disabled`. Un `<sui-status-badge>` sin
147
+ `status` sale verde con check.
148
+ - **El estilo se llama `appearance`**, no `variant` (badge) ni `tagStyle` (tag).
149
+ - En `stroke` el **texto es gris** siempre; solo el ícono o el punto llevan color.
150
+ - Tamaños: `medium` 24 (default, Figma), `large` 28 y `xlarge` 32 para mobile (extensión SUI, 03-10-2026). No hay uno más chico que 24.
151
+ - **No pasa a mayúsculas** (el `sui-badge` small sí).
152
+ - `icon` no hace nada con `withDot`.
153
+ - El punto mide 6 px; el del `sui-badge with-dot`, 4 px. Son distintos a propósito.
154
+ - El host lleva `role="status"`: el lector de pantalla anuncia los cambios.
155
+
156
+ ## Ejemplo
157
+
158
+ ```html
159
+ <!-- En una tabla de recargas: stroke (default) -->
160
+ <sui-status-badge status="pending">En revisión</sui-status-badge>
161
+
162
+ <!-- El estado es el dato principal de la card -->
163
+ <sui-status-badge status="failed" appearance="light">Rechazada</sui-status-badge>
164
+ ```