@ajuarezso/sui-design-system 0.25.0 → 0.25.1

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 (118) hide show
  1. package/docs/sui-accordion/README.md +83 -9
  2. package/docs/sui-activity-feed/README.md +55 -1
  3. package/docs/sui-activity-filter/README.md +50 -1
  4. package/docs/sui-alert/README.md +54 -0
  5. package/docs/sui-app-store-badge/README.md +57 -3
  6. package/docs/sui-avatar/README.md +66 -6
  7. package/docs/sui-avatar-group/README.md +64 -2
  8. package/docs/sui-badge/README.md +79 -11
  9. package/docs/sui-banner/README.md +70 -5
  10. package/docs/sui-brand-logo/README.md +77 -14
  11. package/docs/sui-breadcrumb-item/README.md +51 -0
  12. package/docs/sui-breadcrumbs/README.md +48 -0
  13. package/docs/sui-button/README.md +68 -6
  14. package/docs/sui-button-group/README.md +70 -5
  15. package/docs/sui-button-group-item/README.md +68 -4
  16. package/docs/sui-card/README.md +97 -10
  17. package/docs/sui-chart-legend/README.md +53 -0
  18. package/docs/sui-chart-legend-dot/README.md +49 -0
  19. package/docs/sui-checkbox/README.md +106 -26
  20. package/docs/sui-checkbox-card/README.md +58 -2
  21. package/docs/sui-checkbox-label/README.md +89 -23
  22. package/docs/sui-circular-progress-bar/README.md +63 -5
  23. package/docs/sui-color-dot/README.md +61 -5
  24. package/docs/sui-color-picker/README.md +62 -4
  25. package/docs/sui-command-menu-footer/README.md +49 -0
  26. package/docs/sui-command-menu-item/README.md +63 -4
  27. package/docs/sui-command-menu-search/README.md +58 -4
  28. package/docs/sui-compact-avatar-group/README.md +61 -4
  29. package/docs/sui-compact-button/README.md +112 -28
  30. package/docs/sui-compact-select/README.md +58 -4
  31. package/docs/sui-compact-select-for-input/README.md +69 -5
  32. package/docs/sui-content-card/README.md +63 -2
  33. package/docs/sui-content-divider/README.md +49 -1
  34. package/docs/sui-content-label/README.md +83 -4
  35. package/docs/sui-counter-input/README.md +91 -7
  36. package/docs/sui-date-selector/README.md +61 -3
  37. package/docs/sui-datepicker/README.md +72 -5
  38. package/docs/sui-day-cell/README.md +60 -3
  39. package/docs/sui-day-label/README.md +52 -3
  40. package/docs/sui-divider/README.md +57 -5
  41. package/docs/sui-drawer-footer/README.md +63 -2
  42. package/docs/sui-drawer-header/README.md +60 -3
  43. package/docs/sui-dropdown-caption/README.md +53 -1
  44. package/docs/sui-dropdown-item/README.md +72 -6
  45. package/docs/sui-dropdown-menu/README.md +74 -5
  46. package/docs/sui-dropdown-search/README.md +57 -1
  47. package/docs/sui-emoji/README.md +82 -18
  48. package/docs/sui-empty-state/README.md +68 -4
  49. package/docs/sui-fancy-button/README.md +59 -1
  50. package/docs/sui-file-icon/README.md +56 -1
  51. package/docs/sui-file-upload/README.md +69 -9
  52. package/docs/sui-file-upload-card/README.md +53 -2
  53. package/docs/sui-filter/README.md +74 -5
  54. package/docs/sui-flag/README.md +62 -1
  55. package/docs/sui-form-hint/README.md +54 -5
  56. package/docs/sui-form-label/README.md +53 -1
  57. package/docs/sui-href/README.md +47 -0
  58. package/docs/sui-icon/README.md +69 -4
  59. package/docs/sui-image-upload/README.md +70 -3
  60. package/docs/sui-image-upload-profile/README.md +58 -0
  61. package/docs/sui-img-retry/README.md +49 -0
  62. package/docs/sui-inline-input/README.md +61 -3
  63. package/docs/sui-inline-select/README.md +60 -0
  64. package/docs/sui-input/README.md +77 -14
  65. package/docs/sui-integration-switch/README.md +69 -2
  66. package/docs/sui-kbd/README.md +71 -7
  67. package/docs/sui-key-icon/README.md +65 -6
  68. package/docs/sui-link-button/README.md +79 -13
  69. package/docs/sui-logo/README.md +74 -4
  70. package/docs/sui-modal/README.md +61 -2
  71. package/docs/sui-modal-footer/README.md +83 -9
  72. package/docs/sui-modal-header/README.md +56 -0
  73. package/docs/sui-modal-sheet/README.md +72 -10
  74. package/docs/sui-notification/README.md +71 -1
  75. package/docs/sui-notification-footer/README.md +51 -1
  76. package/docs/sui-notification-tab-menu/README.md +57 -1
  77. package/docs/sui-otp-input/README.md +67 -6
  78. package/docs/sui-page-header/README.md +83 -15
  79. package/docs/sui-pagination/README.md +60 -0
  80. package/docs/sui-password-strength/README.md +50 -1
  81. package/docs/sui-payment-icon/README.md +66 -7
  82. package/docs/sui-period-range/README.md +65 -6
  83. package/docs/sui-popover/README.md +73 -7
  84. package/docs/sui-product-card/README.md +76 -8
  85. package/docs/sui-progress-bar/README.md +72 -8
  86. package/docs/sui-progress-bar-label/README.md +69 -12
  87. package/docs/sui-radio/README.md +83 -6
  88. package/docs/sui-radio-card/README.md +58 -4
  89. package/docs/sui-radio-label/README.md +86 -19
  90. package/docs/sui-rating/README.md +81 -14
  91. package/docs/sui-rich-editor/README.md +45 -0
  92. package/docs/sui-segmented-control/README.md +83 -14
  93. package/docs/sui-select/README.md +72 -3
  94. package/docs/sui-sidebar/README.md +64 -9
  95. package/docs/sui-slider/README.md +68 -1
  96. package/docs/sui-social-button/README.md +63 -3
  97. package/docs/sui-status-badge/README.md +64 -6
  98. package/docs/sui-stepper/README.md +57 -0
  99. package/docs/sui-store-card/README.md +71 -8
  100. package/docs/sui-switch/README.md +80 -9
  101. package/docs/sui-switch-card/README.md +70 -6
  102. package/docs/sui-switch-label/README.md +90 -13
  103. package/docs/sui-tab-chips/README.md +79 -9
  104. package/docs/sui-tab-menu-horizontal/README.md +62 -1
  105. package/docs/sui-tab-menu-vertical/README.md +56 -3
  106. package/docs/sui-table/README.md +68 -7
  107. package/docs/sui-tag/README.md +75 -4
  108. package/docs/sui-tag-input/README.md +71 -7
  109. package/docs/sui-textarea/README.md +78 -11
  110. package/docs/sui-time-picker/README.md +70 -7
  111. package/docs/sui-toast/README.md +65 -5
  112. package/docs/sui-tooltip/README.md +61 -4
  113. package/docs/sui-topbar/README.md +57 -3
  114. package/docs/sui-topbar-button/README.md +57 -3
  115. package/docs/sui-topbar-item/README.md +61 -0
  116. package/docs/sui-topbar-user/README.md +56 -0
  117. package/package.json +1 -1
  118. package/types/ajuarezso-sui-design-system.d.ts +19 -19
@@ -83,9 +83,9 @@ En mobile se toca con el dedo: el área táctil tiene que medir **44 px o más**
83
83
  (`pointer: coarse`) va igual que en el celular, porque también se toca; en la computadora
84
84
  (`pointer: fine`), `medium`; en el celular chico (< 380 px), `medium` a la vista sin bajar el área de 44.
85
85
  Nada en `small` ni `xsmall` (canon, dueño, 05-10-2026, D16; reemplaza al «tamaño por plataforma» del
86
- 03-10-2026, que bajaba la web a `small`). Hoy la app lo resuelve con `BreakpointsService`
87
- (`src/app/services/breakpoints.service.ts`, mobile = hasta 767 px): `[size]="bp.isMobile() ? 'large' : 'medium'"`,
88
- que todavía deja la tablet en `medium` (el helper de D16 está propuesto en la hoja de decisiones). Medido el 04-10-2026 en `master-pedidos`: 166 `[size]`
86
+ 03-10-2026, que bajaba la web a `small`). La app lo resuelve con `BreakpointsService`
87
+ (`src/app/services/breakpoints.service.ts`): la señal `bp.tactil()` (celular por ancho o pantalla
88
+ táctil) ya incluye la tablet; ver «Por dispositivo (D16)» abajo. Medido el 04-10-2026 en `master-pedidos`: 166 `[size]`
89
89
  con `bp` (142 `large`/`medium`, 22 `large`/`small`, 2 `medium`/`xsmall`); los 24 que bajan de `medium` se migran.
90
90
 
91
91
  Desde el 03-10-2026 el grupo tiene `large` (48) y `medium` (40), la misma escala de `sui-button`,
@@ -100,7 +100,7 @@ así que el par es el de toda la app.
100
100
 
101
101
  ```html
102
102
  <sui-button-group [items]="dias" [multi]="true" [(value)]="diasAbiertos" ariaLabel="Días de atención"
103
- [size]="bp.isMobile() ? 'large' : 'medium'" />
103
+ [size]="bp.tactil() ? 'large' : 'medium'" />
104
104
  ```
105
105
 
106
106
  En mobile, cada opción va ancha (los 7 días repartidos en todo el ancho, no apretados a la
@@ -108,6 +108,24 @@ izquierda) — propuesta, falta aprobación. **El componente no lo hace solo**:
108
108
  `inline-flex` y no hay un input de ancho completo, así que hoy lo tendría que resolver quien lo usa
109
109
  con CSS. Si las opciones no entran ni en `medium`, va una lista de `sui-checkbox`.
110
110
 
111
+ ### Por dispositivo (D16)
112
+
113
+ Fila `button-group` (+ `-item`) de la tabla D16 (dueño, 05-10-2026). Se toca, así que va por tipo de
114
+ puntero además del ancho.
115
+
116
+ | dispositivo | size | nota |
117
+ |---|---|---|
118
+ | celular chico (< 380 px) | `large` (48) | D16 pide `medium` con área tocable de 44; mientras el DS no estire el área de los `medium`, va `large` (interino) |
119
+ | celular (380–767 px) | `large` (48) | `medium` (40) si los 7 días no entran: **pendiente (P18)**, falta decidir entre `[stretch]`, lista de `checkbox-label` o bajar el tope |
120
+ | tablet táctil (`pointer: coarse`) | `large` (48) | también se toca con el dedo: Apple pide 44 pt en el iPad |
121
+ | computadora (`pointer: fine`) | `medium` (40) | también en tablas y cards densas |
122
+
123
+ Ultrawide (≥ 1920 px): igual que la computadora, `medium`; el espacio extra va a ancho y columnas,
124
+ no a controles más grandes.
125
+
126
+ En master-pedidos: `[size]="bp.tactil() ? 'large' : 'medium'"` (no hay helper propio; da el mismo
127
+ par que `bp.sizeControl()`). `bp.isMobile()` solo no sirve: deja la tablet en `medium`.
128
+
111
129
  ## «No usar»: por qué no hoy y cuándo sí
112
130
 
113
131
  Nada se borra del DS. Lo marcado «no usar» no tiene caso en la app de hoy; si un flujo nuevo cae
@@ -165,11 +183,58 @@ interface SuiButtonGroupEntry {
165
183
  acompáñalo con un texto que diga cuántas hay elegidas.
166
184
  - Ya trae el arreglo de iOS para el `:active` pegado: no lo agregues.
167
185
 
186
+ ## Bien y mal
187
+
188
+ Hoy no hay usos en la app: los pares salen de «Cuándo no» y de «Trampas».
189
+
190
+ **Cambiar de vista**
191
+
192
+ ```html
193
+ <!-- ❌ mal: elegir una sola vista no es un button-group; con multi en false ni se puede apagar la prendida -->
194
+ <sui-button-group [items]="vistas" [(value)]="vista" ariaLabel="Vista" size="medium" />
195
+ ```
196
+
197
+ ```html
198
+ <!-- ✅ bien -->
199
+ <sui-segmented-control [tabs]="vistas" [(active)]="vista" ariaLabel="Vista"
200
+ [size]="bp.tactil() ? '2xlarge' : 'medium'" />
201
+ ```
202
+
203
+ **Opciones proyectadas en vez de `items`**
204
+
205
+ ```html
206
+ <!-- ❌ mal: el grupo no tiene ng-content (los ítems no se pintan) e items es obligatorio -->
207
+ <sui-button-group ariaLabel="Días de atención">
208
+ <sui-button-group-item label="L" />
209
+ <sui-button-group-item label="M" />
210
+ </sui-button-group>
211
+ ```
212
+
213
+ ```html
214
+ <!-- ✅ bien: las opciones van en items, con ariaLabel en los dos «M» -->
215
+ <sui-button-group [items]="dias" [multi]="true" [(value)]="diasAbiertos" ariaLabel="Días de atención"
216
+ [size]="bp.tactil() ? 'large' : 'medium'" />
217
+ ```
218
+
219
+ **Sin `size`**
220
+
221
+ ```html
222
+ <!-- ❌ mal: sin size queda en small (36): chico en la computadora y sin los 44 del dedo en el teléfono -->
223
+ <sui-button-group [items]="dias" [multi]="true" [(value)]="diasAbiertos" ariaLabel="Días de atención" />
224
+ ```
225
+
226
+ ```html
227
+ <!-- ✅ bien -->
228
+ <sui-button-group [items]="dias" [multi]="true" [(value)]="diasAbiertos" ariaLabel="Días de atención"
229
+ [size]="bp.tactil() ? 'large' : 'medium'" />
230
+ ```
231
+
168
232
  ## Ejemplo
169
233
 
170
234
  ```html
171
235
  <!-- Días de atención del local -->
172
- <sui-button-group [items]="dias" [multi]="true" [(value)]="diasAbiertos" ariaLabel="Días de atención" />
236
+ <sui-button-group [items]="dias" [multi]="true" [(value)]="diasAbiertos" ariaLabel="Días de atención"
237
+ [size]="bp.tactil() ? 'large' : 'medium'" />
173
238
  ```
174
239
 
175
240
  ```ts
@@ -39,9 +39,9 @@ En mobile se toca con el dedo: el área táctil tiene que medir **44 px o más**
39
39
  (`pointer: coarse`) va igual que en el celular, porque también se toca; en la computadora
40
40
  (`pointer: fine`), `medium`; en el celular chico (< 380 px), `medium` a la vista sin bajar el área de 44.
41
41
  Nada en `small` ni `xsmall` (canon, dueño, 05-10-2026, D16; reemplaza al «tamaño por plataforma» del
42
- 03-10-2026, que bajaba la web a `small`). Hoy la app lo resuelve con `BreakpointsService`
43
- (`src/app/services/breakpoints.service.ts`, mobile = hasta 767 px): `[size]="bp.isMobile() ? 'large' : 'medium'"`,
44
- que todavía deja la tablet en `medium` (el helper de D16 está propuesto en la hoja de decisiones). Medido el 04-10-2026 en `master-pedidos`: 166 `[size]`
42
+ 03-10-2026, que bajaba la web a `small`). La app lo resuelve con `BreakpointsService`
43
+ (`src/app/services/breakpoints.service.ts`): la señal `bp.tactil()` (celular por ancho o pantalla
44
+ táctil) ya incluye la tablet; ver «Por dispositivo (D16)» abajo. Medido el 04-10-2026 en `master-pedidos`: 166 `[size]`
45
45
  con `bp` (142 `large`/`medium`, 22 `large`/`small`, 2 `medium`/`xsmall`); los 24 que bajan de `medium` se migran.
46
46
 
47
47
  El tamaño lo pone el grupo: es el mismo `size` de `sui-button-group` (ver su README).
@@ -51,6 +51,24 @@ El tamaño lo pone el grupo: es el mismo `size` de `sui-button-group` (ver su RE
51
51
  | dentro de un grupo | `large` (48) · `medium` (40) si la fila no entra | `medium` (40) | mobile: canon (aprobado por el dueño, 03-10-2026) · web: canon (dueño, 05-10-2026, D16), antes `small` |
52
52
  | suelto (barra de herramientas) | no va en mobile | `medium` (40) | no va en mobile: canon (aprobado por el dueño, 05-10-2026, bloque B7) · web: canon (dueño, 05-10-2026, D16), antes `xsmall` o `2xsmall` |
53
53
 
54
+ ### Por dispositivo (D16)
55
+
56
+ Dentro del grupo el ítem no elige: recibe el `size` de `sui-button-group` (fila `button-group` de
57
+ la tabla D16, dueño 05-10-2026).
58
+
59
+ | dispositivo | size | nota |
60
+ |---|---|---|
61
+ | celular chico (< 380 px) | `large` (48) | D16 pide `medium` con área tocable de 44; mientras el DS no estire el área de los `medium`, va `large` (interino) |
62
+ | celular (380–767 px) | `large` (48) | `medium` (40) si los 7 días no entran: **pendiente (P18)**, falta decidir entre `[stretch]`, lista de `checkbox-label` o bajar el tope |
63
+ | tablet táctil (`pointer: coarse`) | `large` (48) | también se toca con el dedo: Apple pide 44 pt en el iPad |
64
+ | computadora (`pointer: fine`) | `medium` (40) | también suelto en una barra de herramientas |
65
+
66
+ Ultrawide (≥ 1920 px): igual que la computadora, `medium`; el espacio extra va a ancho y columnas,
67
+ no a controles más grandes.
68
+
69
+ En master-pedidos: `[size]="bp.tactil() ? 'large' : 'medium'"` en el grupo (no hay helper propio;
70
+ da el mismo par que `bp.sizeControl()`). Suelto: `size="medium"`.
71
+
54
72
  ## «No usar»: por qué no hoy y cuándo sí
55
73
 
56
74
  Nada se borra del DS. Lo marcado «no usar» no tiene caso en la app de hoy; si un flujo nuevo cae
@@ -93,11 +111,57 @@ en la columna de la derecha, se usa (aprobado por el dueño, 03-10-2026).
93
111
  - Es un `<button type="button">` con `aria-pressed`: el lector de pantalla lo anuncia como botón de
94
112
  alternar.
95
113
 
114
+ ## Bien y mal
115
+
116
+ Hoy no hay usos en la app (ni del ítem ni del grupo): los pares salen de «Trampas» y de «Cuándo no».
117
+
118
+ **Opciones armadas a mano en vez de `items`**
119
+
120
+ ```html
121
+ <!-- ❌ mal: sueltos no reciben las puntas redondeadas ni los bordes juntos; eso lo pone el grupo -->
122
+ <div class="horario__dias">
123
+ <sui-button-group-item label="L" size="medium" [active]="lunes()" (clicked)="lunes.set(!lunes())" />
124
+ <sui-button-group-item label="M" size="medium" [active]="martes()" (clicked)="martes.set(!martes())" />
125
+ </div>
126
+ ```
127
+
128
+ ```html
129
+ <!-- ✅ bien -->
130
+ <sui-button-group [items]="dias" [multi]="true" [(value)]="diasAbiertos" ariaLabel="Días de atención"
131
+ [size]="bp.tactil() ? 'large' : 'medium'" />
132
+ ```
133
+
134
+ **Botón de alternar suelto en una barra de desktop**
135
+
136
+ ```html
137
+ <!-- ❌ mal: 2xsmall (24) es chico (D16) y, sin label ni ariaLabel, el lector de pantalla no dice qué es -->
138
+ <sui-button-group-item leftIcon="bold" size="2xsmall" [active]="negrita()" (clicked)="negrita.set(!negrita())" />
139
+ ```
140
+
141
+ ```html
142
+ <!-- ✅ bien -->
143
+ <sui-button-group-item leftIcon="bold" ariaLabel="Negrita" size="medium"
144
+ [active]="negrita()" (clicked)="negrita.set(!negrita())" />
145
+ ```
146
+
147
+ **Esperar que se prenda solo al tocarlo**
148
+
149
+ ```html
150
+ <!-- ❌ mal: active no cambia solo; el ítem avisa con (clicked) y se queda apagado -->
151
+ <sui-button-group-item label="Negrita" size="medium" (clicked)="guardarFormato()" />
152
+ ```
153
+
154
+ ```html
155
+ <!-- ✅ bien: quien lo usa cambia active -->
156
+ <sui-button-group-item label="Negrita" size="medium" [active]="negrita()" (clicked)="negrita.set(!negrita())" />
157
+ ```
158
+
96
159
  ## Ejemplo
97
160
 
98
161
  ```html
99
162
  <!-- Lo normal: no se escribe a mano, lo arma el grupo -->
100
- <sui-button-group [items]="dias" [multi]="true" [(value)]="diasAbiertos" ariaLabel="Días de atención" />
163
+ <sui-button-group [items]="dias" [multi]="true" [(value)]="diasAbiertos" ariaLabel="Días de atención"
164
+ [size]="bp.tactil() ? 'large' : 'medium'" />
101
165
 
102
166
  <!-- Suelto, solo en el caso de «cuándo sí» -->
103
167
  <sui-button-group-item leftIcon="bold" ariaLabel="Negrita" size="medium"
@@ -74,16 +74,27 @@ selección.**
74
74
  | `[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. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
75
75
  | `[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) |
76
76
 
77
- **Usos de hoy que rompen las reglas** (revisado el 04-10-2026):
78
-
79
- - **Los 18 `gap` puestos en la clase del `sui-card`** (central-inicio, master-semanas,
80
- central-ingresos, invoices, driver-history, driver-wallet) ya van con un wrapper `…-body` propio
81
- desde el 03-10-2026 (commit `103f76fa` de la app). Quedan 0.
82
- - **3 cards tocables con `[interactive]` y además `(keydown.enter)`**: la card ya dispara el click
83
- con Enter, así que el handler corre **dos veces** (ver Trampas).
84
- `pages/super-admin/master-users/master-users.html:156`,
85
- `pages/super-admin/master-settings/master-settings.html:611` (con `routerLink`) y
86
- `pages/driver/driver-dashboard/driver-dashboard.html:990`. Se borra el `(keydown.enter)`.
77
+ **Usos de hoy que rompen las reglas** (revisado el 06-10-2026):
78
+
79
+ - **`gap` puesto en la clase del `sui-card` para separar lo del cuerpo.** Los 18 que se contaron el
80
+ 03-10-2026 (central-inicio, master-semanas, central-ingresos, invoices, driver-history,
81
+ driver-wallet) ya van con un wrapper `…-body` propio (commit `103f76fa` de la app). Ese conteo
82
+ dejó fuera 6 cards en 3 archivos, que siguen igual: su `gap` no separa nada porque todo va en el
83
+ cuerpo.
84
+ - `pages/super-admin/master-users/master-users.html:158` · `.mu__card { gap: 6px !important }`
85
+ (`master-users.scss:57`). Es el «mal» de «Separar las filas del cuerpo», abajo.
86
+ - `pages/super-admin/master-overview/master-overview.html:444`, `:450`, `:456`, `:462` ·
87
+ `.mo__quick-link { gap: 8px }` (`master-overview.scss:273`).
88
+ - `pages/central/central-gastos/central-gastos.html:35` · `.cg__kpi { gap: 4px }`
89
+ (`central-gastos.scss:37`).
90
+
91
+ No cuentan los `gap: 0 !important` (master-settings, master-users `.mu__table-wrap`,
92
+ master-earnings, master-approvals, master-overview `.mo__recent-list`): apagan el gap entre slots
93
+ a propósito, no intentan separar hijos.
94
+ - **Cards con `[interactive]` y además `(keydown.enter)`**: quedan 0. Las 3 que había
95
+ (master-users, master-settings y driver-dashboard) se corrigieron con el commit `00c3f17c` de la
96
+ app; hoy ningún `sui-card` lleva `(keydown.enter)`. El `(keydown.enter)` que sigue en
97
+ `master-users.html:117` es de una fila `<tr>` de la tabla, no de una card.
87
98
 
88
99
  ## Tamaño en mobile y en web
89
100
 
@@ -103,6 +114,13 @@ mobile es no perder ancho.
103
114
  `bp` es el `BreakpointsService` de la app. Va al ritmo de los gaps de página (12 / 16 / 20 por
104
115
  breakpoint). Si la card es tocable, el alto de la fila (≥ 44) lo da su contenido, no el `size`.
105
116
 
117
+ ### Por dispositivo (D16)
118
+
119
+ D16 no mueve la card: su `size` es padding y gap, no algo que se toca ni que se lee más grande, y
120
+ no está en la tabla por componente de D16. Lo que va adentro sigue su propio README (los botones,
121
+ `bp.sizeControl()`). El `small` en mobile de la tabla de arriba sigue **pendiente (P12)**: falta
122
+ decidir si va solo en pantallas nuevas, si se migran las de hoy o si queda `medium` en las dos.
123
+
106
124
  ## «No usar»: por qué no hoy y cuándo sí
107
125
 
108
126
  | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
@@ -144,6 +162,75 @@ Slots: `[sui-card-header]`, cuerpo (`<ng-content>`), `[sui-card-media]`, `[sui-c
144
162
  cambias el padding a la card desde afuera, la media queda corrida.
145
163
  - En modo oscuro `elevated` usa `--sui-card-elevated-border` para el borde (la sombra no se ve).
146
164
 
165
+ ## Bien y mal
166
+
167
+ **Separar las filas del cuerpo**
168
+
169
+ ```html
170
+ <!-- ❌ mal: el gap en la clase del card separa slots, no lo que proyectas (master-users.html:158, .mu__card { gap: 6px } en master-users.scss:57) -->
171
+ <sui-card size="small" class="mu__card">
172
+ <span class="mu__card-name">{{ u.name }}</span>
173
+ <span class="mu__card-email">{{ u.email }}</span>
174
+ </sui-card>
175
+ ```
176
+
177
+ ```html
178
+ <!-- ✅ bien: wrapper propio con display:flex; flex-direction:column; gap:6px -->
179
+ <sui-card size="small">
180
+ <div class="mu__card-body">
181
+ <span class="mu__card-name">{{ u.name }}</span>
182
+ <span class="mu__card-email">{{ u.email }}</span>
183
+ </div>
184
+ </sui-card>
185
+ ```
186
+
187
+ **Card tocable con botones adentro**
188
+
189
+ ```html
190
+ <!-- ❌ mal: interactive es para UNA acción; esta abre la ficha y además tiene dos botones
191
+ (pages/super-admin/master-users/master-users.html:158, resumido) -->
192
+ <sui-card size="small" [interactive]="true" (click)="abrirFicha(u)">
193
+ …nombre, correo, aparatos, fecha…
194
+ <div class="mu__card-actions" (click)="$event.stopPropagation()">
195
+ <sui-button variant="stroke" color="neutral" [size]="bp.sizeControl()" (click)="openBanModal(u)">{{ u.baneado ? 'Desbloquear cuenta' : 'Bloquear cuenta' }}</sui-button>
196
+ <sui-button variant="stroke" color="error" [size]="bp.sizeControl()" (click)="openDeleteUserModal(u)">Eliminar usuario</sui-button>
197
+ </div>
198
+ </sui-card>
199
+ ```
200
+
201
+ Son **tres** acciones: abrir la ficha, bloquear y eliminar. Sin `interactive`, abrir la ficha
202
+ pasa a ser una acción explícita, y no entra como tercer botón: el canon de `sui-modal-footer`
203
+ admite dos botones como máximo, y la tercera acción va como `sui-link-button` a la izquierda.
204
+ Ninguna se pierde.
205
+
206
+ ```html
207
+ <!-- ✅ bien: sin interactive; «Ver ficha» es el link de la izquierda y los dos botones quedan a la derecha
208
+ (.mu__card-actions: display:flex; align-items:center; gap:12px · .mu__card-ver: margin-right:auto) -->
209
+ <sui-card size="small"> <!-- nombre y correo en el cuerpo, con su wrapper como arriba -->
210
+ <div sui-card-footer class="mu__card-actions">
211
+ <sui-link-button class="mu__card-ver" variant="primary" [size]="bp.isMobile() ? 'large' : 'medium'" (click)="abrirFicha(u)">Ver ficha</sui-link-button>
212
+ <sui-button variant="stroke" color="neutral" [size]="bp.sizeControl()" (click)="openBanModal(u)">{{ u.baneado ? 'Desbloquear cuenta' : 'Bloquear cuenta' }}</sui-button>
213
+ <sui-button variant="stroke" color="error" [size]="bp.sizeControl()" (click)="openDeleteUserModal(u)">Eliminar usuario</sui-button>
214
+ </div>
215
+ </sui-card>
216
+ ```
217
+
218
+ El tamaño del link sigue su README (`large` en el teléfono está pendiente de P8); los botones van
219
+ con `bp.sizeControl()` (D16). Los dos son `stroke` como en la app: en una lista de cards un
220
+ `filled` rojo por fila pesa más que el dato.
221
+
222
+ **Enter además de `interactive`**
223
+
224
+ ```html
225
+ <!-- ❌ mal: la card ya hace click con Enter; el handler corre dos veces (pasaba en master-users.html, master-settings.html y driver-dashboard.html; corregido en el commit 00c3f17c de la app) -->
226
+ <sui-card size="small" [interactive]="true" (click)="abrirDirecciones()" (keydown.enter)="abrirDirecciones()">…</sui-card>
227
+ ```
228
+
229
+ ```html
230
+ <!-- ✅ bien -->
231
+ <sui-card size="small" [interactive]="true" (click)="abrirDirecciones()">…</sui-card>
232
+ ```
233
+
147
234
  ## Ejemplo
148
235
 
149
236
  ```html
@@ -85,6 +85,15 @@ para el dedo; lo que cambia por plataforma es la orientación.
85
85
 
86
86
  El texto de 12 px queda chico en mobile y el componente no tiene un tamaño mayor: no se cambia aquí.
87
87
 
88
+ ### Por dispositivo (D16)
89
+
90
+ No aplica: **no tiene `size`** (punto de 16 y texto de 12 en todos los dispositivos, del celular
91
+ chico al ultrawide). Es lo que no se toca, pero no hay un tamaño más grande al que subir en el
92
+ celular; lo único que cambia por dispositivo es dónde se pone (`orientation` y el layout, tabla de
93
+ arriba).
94
+
95
+ En master-pedidos: no hay helper ni `[size]`; solo `orientation` según el gráfico.
96
+
88
97
  ## «No usar»: por qué no hoy y cuándo sí
89
98
 
90
99
  | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
@@ -125,6 +134,50 @@ interface SuiChartLegendItem {
125
134
  - Host con `role="list"` y cada item `role="listitem"`; el punto es decorativo.
126
135
  - `items` es obligatorio.
127
136
 
137
+ ## Bien y mal
138
+
139
+ Leyenda bajo una dona
140
+
141
+ ```html
142
+ <!-- ❌ mal: leyenda hecha a mano con el punto en [style.background] (components/marketing-channels/marketing-channels.html:13) -->
143
+ <div class="payment-methods__legend-item">
144
+ <span class="payment-methods__legend-dot" [style.background]="item.color"></span>
145
+ <span class="payment-methods__legend-label">{{ item.name }}</span>
146
+ </div>
147
+ ```
148
+
149
+ ```html
150
+ <!-- ✅ bien: leyendaPagos() = { label: item.name, customColor: item.color, value: item.value } -->
151
+ <sui-chart-legend orientation="vertical" [items]="leyendaPagos()" />
152
+ ```
153
+
154
+ Color de cada método de pago
155
+
156
+ ```html
157
+ <!-- ❌ mal: hex suelto en un ternario, distinto de la paleta del gráfico (pages/reports/reports.html:86) -->
158
+ <span class="reports__legend-dot"
159
+ [style.background-color]="pm.method === 'yape' ? '#7e22ce' : '#6366f1'"></span>
160
+ ```
161
+
162
+ ```html
163
+ <!-- ✅ bien: el mismo customColor que recibe ECharts en series[].color -->
164
+ <sui-chart-legend orientation="vertical" [items]="[
165
+ { label: 'Yape', customColor: colorYape, value: 42 },
166
+ ]" />
167
+ ```
168
+
169
+ Series sin color con un gráfico de paleta propia
170
+
171
+ ```html
172
+ <!-- ❌ mal: sin color salen azul, naranja… y el gráfico pinta otros -->
173
+ <sui-chart-legend [items]="[{ label: 'Entregados' }, { label: 'Cancelados' }]" />
174
+ ```
175
+
176
+ ```html
177
+ <!-- ✅ bien: la serie es un estado, va su color -->
178
+ <sui-chart-legend [items]="[{ label: 'Entregados', color: 'green' }, { label: 'Cancelados', color: 'red' }]" />
179
+ ```
180
+
128
181
  ## Ejemplo
129
182
 
130
183
  ```html
@@ -76,6 +76,16 @@ Es decorativo y no se toca: no tiene mínimo para el dedo.
76
76
 
77
77
  No cambia por plataforma: va con el tamaño del texto que acompaña, no con la pantalla.
78
78
 
79
+ ### Por dispositivo (D16)
80
+
81
+ No aplica: el tamaño va con el texto de al lado (`medium` junto a 14, `small` junto a 12, como en la
82
+ leyenda), igual en celular chico, celular, tablet, computadora y ultrawide. Es lo que no se toca, y
83
+ `medium` ya es su size más grande: el paso extra del celular (P1 b) no tiene a dónde subir (D16,
84
+ dueño 05-10-2026).
85
+
86
+ En master-pedidos: no hay helper; el `size` va literal según el texto (`size="small"` junto a 12, o
87
+ nada para `medium`).
88
+
79
89
  ## «No usar»: por qué no hoy y cuándo sí
80
90
 
81
91
  | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
@@ -110,6 +120,45 @@ Constantes exportadas: `SUI_CHART_LEGEND_COLORS` (los 11 colores en el orden del
110
120
  - `SUI_CHART_LEGEND_HEX` tiene los hex del modo claro: en modo oscuro no se invierten.
111
121
  - Es decorativo (`aria-hidden`): el significado lo dice el texto de al lado.
112
122
 
123
+ ## Bien y mal
124
+
125
+ Punto de una serie fuera de la leyenda
126
+
127
+ ```html
128
+ <!-- ❌ mal: punto hecho a mano, sin anillo ni sombra (components/customer-retention/customer-retention.html:17) -->
129
+ <span class="customer-retention__stat-dot" [style.background]="seg.color"></span>
130
+ ```
131
+
132
+ ```html
133
+ <!-- ✅ bien -->
134
+ <sui-chart-legend-dot [customColor]="seg.color" />
135
+ ```
136
+
137
+ Punto sin `color`
138
+
139
+ ```html
140
+ <!-- ❌ mal: sin color sale el default gray, no el verde de la serie -->
141
+ <span class="fila"><sui-chart-legend-dot /> Entregados <b>86 %</b></span>
142
+ ```
143
+
144
+ ```html
145
+ <!-- ✅ bien -->
146
+ <span class="fila"><sui-chart-legend-dot color="green" /> Entregados <b>86 %</b></span>
147
+ ```
148
+
149
+ Varios puntos sueltos que hacen de leyenda
150
+
151
+ ```html
152
+ <!-- ❌ mal: es una leyenda armada a mano con puntos sueltos -->
153
+ <span><sui-chart-legend-dot color="blue" size="small" /> Yape</span>
154
+ <span><sui-chart-legend-dot color="orange" size="small" /> Efectivo</span>
155
+ ```
156
+
157
+ ```html
158
+ <!-- ✅ bien -->
159
+ <sui-chart-legend [items]="[{ label: 'Yape' }, { label: 'Efectivo' }]" />
160
+ ```
161
+
113
162
  ## Ejemplo
114
163
 
115
164
  ```html
@@ -34,11 +34,13 @@ Regla corta: **se suma y se confirma después → checkbox · se aplica ya → s
34
34
  > avanzado (sublabel, badge, descripción y link). Lo marcado «según la guía del DS» sale de ahí;
35
35
  > el resto es canon del dueño o propuesta.
36
36
  >
37
- > Uso medido el 03-10-2026 en `master-pedidos/src/app`, sin contar prototipos ni vitrinas
38
- > (`master-preview`, `master-prototipos`, `mockup-sheets-*`, `dx/*`, `_guia-*`, `master-rutina`,
39
- > `master-medico`, `dev-index`): **5 checkbox en 3 archivos**, todos con tamaño dinámico
40
- > (`bp.controlSize()` / `ctrlSize()` = `large` en desktop, `xlarge` en mobile, y uno con el
41
- > `size()` del padre). Más **1 `<input type="checkbox">` nativo** que debería ser este componente.
37
+ > Uso medido el 03-10-2026 y revisado el 06-10-2026 en `master-pedidos/src/app`, sin contar
38
+ > prototipos ni vitrinas (`master-preview`, `master-prototipos`, `mockup-sheets-*`, `dx/*`,
39
+ > `_guia-*`, `master-rutina`, `master-medico`, `dev-index`): **queda 1 `sui-checkbox`**, el de la
40
+ > fila de opciones del detalle de producto, con el `size()` que le pasa el padre (`bp.controlSize()`
41
+ > en la carta del cliente, `ctrlSize()` en la vista previa del modal de producto). Los otros 4 del
42
+ > 03-10 eran casillas con texto armadas a mano y ya pasaron a `sui-checkbox-label`. Quedan además
43
+ > **2 `<input type="checkbox">` nativos** que no deberían serlo (ver abajo).
42
44
 
43
45
  ### Lo que sí dice la guía del DS
44
46
 
@@ -59,25 +61,30 @@ Regla corta: **se suma y se confirma después → checkbox · se aplica ya → s
59
61
 
60
62
  | size | px | cuándo | fuente |
61
63
  |---|---|---|---|
62
- | `xlarge` | 28 | Mobile. Viene de `bp.controlSize()`. | canon (aprobado por el dueño, 28-09-2026: «componentes grandes») |
63
- | `large` | 24 | Desktop. Viene de `bp.controlSize()`. | canon (aprobado por el dueño, 28-09-2026) |
64
- | `medium` (default) | 20 | Solo dentro de un componente que ya fija su escala (la fila de opciones del detalle de producto recibe el `size` del padre). | canon (aprobado por el dueño, 05-10-2026, bloque B1) |
64
+ | `xlarge` | 28 | Celular y tablet táctil (D16). | canon (aprobado por el dueño, 28-09-2026: «componentes grandes») |
65
+ | `large` | 24 | Computadora (D16). | canon (aprobado por el dueño, 28-09-2026) |
66
+ | `medium` (default) | 20 | Solo dentro de un componente que ya fija su escala. Hoy no hay ninguno: la fila de opciones del detalle de producto recibe el `size` del padre, que es el de D16. | canon (aprobado por el dueño, 05-10-2026, bloque B1) |
65
67
  | `small` | 16 | No usar (ver abajo). | canon (aprobado por el dueño, 28-09-2026) |
66
68
 
67
- Regla: **`[size]="bp.controlSize()"`** en toda pantalla. Así ya están los 5 usos de hoy.
69
+ Regla: **`[size]="bp.tactil() ? 'xlarge' : 'large'"`** en toda pantalla (la expresión exacta de
70
+ D16, ver «Por dispositivo»). El único `sui-checkbox` de hoy no la lleva escrita: recibe el `size()`
71
+ del detalle de producto, y ese padre recibe `bp.controlSize()` o `ctrlSize()`.
68
72
 
69
- **Usos de hoy que rompen la regla de componente:**
73
+ **Usos de hoy frente a la regla de componente** (revisado 06-10-2026):
70
74
 
71
- - **4 `sui-checkbox` envueltos en un `<label>` hecho a mano con su texto → `sui-checkbox-label`.**
72
- `pages/settings/team/team.html:228` y `:301` (permisos: «Gestionar productos»…),
73
- `components/option-sections-manager/option-sections-manager.html:191` (categorías) y `:214`
74
- (productos). Además, tocar el texto no marca nada: un `<label>` solo activa controles nativos
75
- y `sui-checkbox` no lo es, así que hoy solo responde la casilla.
75
+ - **Los 4 `sui-checkbox` envueltos en un `<label>` a mano ya pasaron a `sui-checkbox-label`** con
76
+ su tamaño: `pages/settings/team/team.html:237` y `:309` (permisos, `[size]="bp.controlSize()"`),
77
+ `components/option-sections-manager/option-sections-manager.html:190` (categorías) y `:212`
78
+ (productos). Estos dos usan `ctrlSize()`, una copia local de `bp.controlSize()`
79
+ (`option-sections-manager.ts:62`): da lo mismo, pero conviene usar el helper del servicio.
80
+ Antes, tocar el texto no marcaba nada: un `<label>` solo activa controles nativos y
81
+ `sui-checkbox` no lo es, así que solo respondía la casilla. `sui-checkbox-label` hace que toda
82
+ la fila responda.
76
83
  - **1 checkbox nativo → `sui-checkbox-label`:** `pages/sales-channels/facebook/facebook.html:69`
77
- («Qué se sincroniza»).
78
- - **Al migrar, pásale el tamaño:** `sui-checkbox-label` tiene `size` (`medium` 20, `large` 24,
79
- `xlarge` 28) desde el 03-10-2026. Con `[size]="bp.controlSize()"` los 4 de arriba siguen en
80
- 24/28 px; sin él caen a 20.
84
+ («Qué se sincroniza»). **Al migrarlo, pásale el tamaño:** `sui-checkbox-label` arranca en
85
+ `medium` (casilla de 20); sin `[size]` queda chico en el celular.
86
+ - **1 checkbox nativo que en realidad es un interruptor → `sui-switch-label`:**
87
+ `components/settings-panel/settings-panel.html:99` (notificaciones push, se aplica al instante).
81
88
  - El de `components/product-detail-view/product-detail-view.html:204` está bien pelado: la fila
82
89
  es propia (foto, nombre, precio) y es la fila la que recibe el clic.
83
90
 
@@ -89,14 +96,38 @@ que lo contiene. En web va un escalón más chico.
89
96
  | uso | mobile | web |
90
97
  |---|---|---|
91
98
  | casilla en una lista, tabla o fila de formulario | `xlarge` (28 px) | `large` (24 px) |
92
- | dentro de un componente que fija su escala (fila de opciones del detalle de producto) | lo que pase el padre | lo que pase el padre |
99
+ | dentro de un componente que recibe su `size` del padre (fila de opciones del detalle de producto) | lo que pase el padre | lo que pase el padre |
93
100
 
94
101
  ```html
95
- <sui-checkbox [size]="bp.controlSize()" … /> <!-- controlSize() = isMobile() ? 'xlarge' : 'large' -->
102
+ <sui-checkbox [size]="bp.tactil() ? 'xlarge' : 'large'" … /> <!-- tactil() = isMobile() || pointer: coarse -->
96
103
  ```
97
104
 
98
- El más grande mide 28 px: ningún tamaño llega a 44 px por sí solo. La fila (o el `<label>` que
99
- envuelve) tiene que medir al menos 44 px de alto para que el toque sea cómodo.
105
+ El más grande mide 28 px: ningún tamaño llega a 44 px por sí solo. La fila que lo
106
+ contiene tiene que medir al menos 44 px de alto para que el toque sea cómodo.
107
+
108
+ ### Por dispositivo (D16)
109
+
110
+ Fila de `checkbox` en la tabla de D16 (dueño, 05-10-2026; computadora resuelta el 06-10-2026): se
111
+ toca, y en la computadora va **un paso menos que en el celular**, sin bajar a `medium`.
112
+
113
+ | dispositivo | size | nota |
114
+ |---|---|---|
115
+ | celular chico (< 380 px) | `xlarge` (28) | la fila que lo contiene da los 44 de alto |
116
+ | celular (380–767 px) | `xlarge` (28) | |
117
+ | tablet táctil (`pointer: coarse`) | `xlarge` (28) | Apple pide 44 pt también en iPad; la fila da el alto |
118
+ | computadora (`pointer: fine`) | `large` (24) | un paso menos que el celular (dueño, 06-10-2026) |
119
+
120
+ Ultrawide (≥ 1920 px): igual que la computadora, `large`. `small` no se usa en ningún dispositivo;
121
+ `medium` solo si un padre fija su propia escala (el detalle de producto hoy no lo hace: recibe el
122
+ tamaño de D16 de su padre).
123
+
124
+ En master-pedidos, la expresión que da esta tabla completa es
125
+ **`[size]="bp.tactil() ? 'xlarge' : 'large'"`** (`bp.tactil()` = celular por ancho o pantalla
126
+ táctil). La fila de D16 nombra `bp.controlSize()`, que es lo que llevan hoy los usos de la app: da
127
+ lo mismo en el celular y en la computadora, pero mira solo el ancho (≤ 767 px), así que en un iPad
128
+ de 768 o más devuelve `large` y no `xlarge`. Para que la tabla se cumpla en la tablet hay dos
129
+ caminos: escribir la expresión de arriba, o que `controlSize()` pase a mirar `tactil()` en el
130
+ servicio. Eso último cambia todos los usos de golpe y es decisión del dueño.
100
131
 
101
132
  ## «No usar»: por qué no hoy y cuándo sí
102
133
 
@@ -129,7 +160,10 @@ Implementa `ControlValueAccessor`: funciona con `[(ngModel)]` y `formControlName
129
160
  ## Trampas
130
161
 
131
162
  - **No tiene `label`.** Para el texto está `sui-checkbox-label`. Y el host lleva `role="checkbox"`
132
- sin `aria-label` propio: pelado, ponle `aria-label="…"` o un `<label>` que lo envuelva.
163
+ sin `aria-label` propio: pelado, ponle `aria-label="…"` (o `aria-labelledby` apuntando al texto
164
+ de la fila). **Un `<label>` que lo envuelva no sirve**: `<label>` solo activa y nombra controles
165
+ nativos, y `sui-checkbox` es un elemento propio con `role="checkbox"`. Tocar el texto no lo marca
166
+ y el lector de pantalla no lo asocia.
133
167
  - **`checked` es model; `indeterminate` es input.** Hay `[(checked)]` pero no `[(indeterminate)]`,
134
168
  y el componente **no limpia el guion solo** al tocarlo: mientras `indeterminate` siga en `true`
135
169
  se ve el guion aunque cambie `checked`.
@@ -141,12 +175,58 @@ Implementa `ControlValueAccessor`: funciona con `[(ngModel)]` y `formControlName
141
175
  - El tilde es un SVG dibujado a mano: no se cambia el ícono.
142
176
  - Ya trae el arreglo de iOS para el `:active` pegado: no lo agregues.
143
177
 
178
+ ## Bien y mal
179
+
180
+ Casilla con su texto
181
+
182
+ ```html
183
+ <!-- ❌ mal: nativo dentro de un <label> hecho a mano (pages/sales-channels/facebook/facebook.html:69) -->
184
+ <label class="fb-channel__sync-item">
185
+ <input type="checkbox" [checked]="item.checked" (change)="toggleSync(item.id)" />
186
+ <span>{{ item.label }}</span>
187
+ </label>
188
+ ```
189
+
190
+ ```html
191
+ <!-- ✅ bien -->
192
+ <sui-checkbox-label [size]="bp.tactil() ? 'xlarge' : 'large'" [label]="item.label"
193
+ [active]="item.checked" (activeChange)="toggleSync(item.id)" />
194
+ ```
195
+
196
+ Algo que se aplica al instante
197
+
198
+ ```html
199
+ <!-- ❌ mal: casilla nativa pintada de interruptor para las notificaciones (components/settings-panel/settings-panel.html:99) -->
200
+ <label class="sp__toggle">
201
+ <input type="checkbox" [checked]="pushEnabled()" (change)="togglePush(!pushEnabled())" />
202
+ </label>
203
+ ```
204
+
205
+ ```html
206
+ <!-- ✅ bien: se aplica ya → switch, no checkbox -->
207
+ <sui-switch-label [size]="bp.tactil() ? 'xlarge' : 'large'" label="Notificaciones push"
208
+ [active]="pushEnabled()" (activeChange)="togglePush($event)" />
209
+ ```
210
+
211
+ «Seleccionar todo» de una lista
212
+
213
+ ```html
214
+ <!-- ❌ mal: el guion fijo no se limpia al tocar la casilla, y pelada no tiene nombre -->
215
+ <sui-checkbox [size]="bp.tactil() ? 'xlarge' : 'large'" [indeterminate]="true" [(checked)]="todas" />
216
+ ```
217
+
218
+ ```html
219
+ <!-- ✅ bien -->
220
+ <sui-checkbox [size]="bp.tactil() ? 'xlarge' : 'large'" aria-label="Seleccionar todo"
221
+ [indeterminate]="algunas() && !todas()" [checked]="todas()" (checkedChange)="marcarTodas($event)" />
222
+ ```
223
+
144
224
  ## Ejemplo
145
225
 
146
226
  ```html
147
227
  <!-- Pelado, el texto vive en la fila (celda de tabla, fila propia) -->
148
- <sui-checkbox [size]="bp.controlSize()" [(checked)]="seleccionado" aria-label="Elegir pedido" />
228
+ <sui-checkbox [size]="bp.tactil() ? 'xlarge' : 'large'" [(checked)]="seleccionado" aria-label="Elegir pedido" />
149
229
 
150
230
  <!-- Con texto: usa sui-checkbox-label, no esto a mano -->
151
- <sui-checkbox-label label="Gestionar productos" [(active)]="puedeProductos" />
231
+ <sui-checkbox-label [size]="bp.tactil() ? 'xlarge' : 'large'" label="Gestionar productos" [(active)]="puedeProductos" />
152
232
  ```