@ajuarezso/sui-design-system 0.21.0 → 0.23.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 (114) hide show
  1. package/docs/INDEX.md +30 -35
  2. package/docs/sui-accordion/README.md +171 -0
  3. package/docs/sui-activity-feed/README.md +154 -0
  4. package/docs/sui-activity-filter/README.md +100 -0
  5. package/docs/sui-alert/README.md +28 -19
  6. package/docs/sui-app-store-badge/README.md +5 -4
  7. package/docs/sui-avatar/README.md +16 -16
  8. package/docs/sui-avatar-group/README.md +4 -4
  9. package/docs/sui-badge/README.md +27 -9
  10. package/docs/sui-banner/README.md +10 -9
  11. package/docs/sui-brand-logo/README.md +3 -3
  12. package/docs/sui-breadcrumbs/README.md +1 -1
  13. package/docs/sui-button/README.md +64 -21
  14. package/docs/sui-button-group/README.md +6 -4
  15. package/docs/sui-button-group-item/README.md +3 -3
  16. package/docs/sui-card/README.md +17 -19
  17. package/docs/sui-chart-legend/README.md +8 -7
  18. package/docs/sui-checkbox/README.md +11 -6
  19. package/docs/sui-checkbox-card/README.md +24 -19
  20. package/docs/sui-checkbox-label/README.md +32 -10
  21. package/docs/sui-circular-progress-bar/README.md +2 -0
  22. package/docs/sui-color-dot/README.md +1 -1
  23. package/docs/sui-color-picker/README.md +22 -7
  24. package/docs/sui-command-menu-footer/README.md +100 -0
  25. package/docs/sui-command-menu-item/README.md +140 -0
  26. package/docs/sui-command-menu-search/README.md +105 -0
  27. package/docs/sui-compact-avatar-group/README.md +4 -3
  28. package/docs/sui-compact-button/README.md +41 -44
  29. package/docs/sui-compact-select/README.md +12 -5
  30. package/docs/sui-compact-select-for-input/README.md +5 -2
  31. package/docs/sui-content-card/README.md +6 -5
  32. package/docs/sui-content-divider/README.md +4 -4
  33. package/docs/sui-content-label/README.md +11 -6
  34. package/docs/sui-counter-input/README.md +21 -17
  35. package/docs/sui-date-selector/README.md +16 -12
  36. package/docs/sui-datepicker/README.md +46 -28
  37. package/docs/sui-day-cell/README.md +17 -8
  38. package/docs/sui-day-label/README.md +2 -2
  39. package/docs/sui-divider/README.md +5 -5
  40. package/docs/sui-drawer-footer/README.md +19 -5
  41. package/docs/sui-dropdown-caption/README.md +92 -0
  42. package/docs/sui-dropdown-item/README.md +163 -0
  43. package/docs/sui-dropdown-menu/README.md +196 -0
  44. package/docs/sui-dropdown-search/README.md +113 -0
  45. package/docs/sui-emoji/README.md +6 -6
  46. package/docs/sui-empty-state/README.md +13 -23
  47. package/docs/sui-fancy-button/README.md +24 -18
  48. package/docs/sui-file-icon/README.md +1 -1
  49. package/docs/sui-file-upload/README.md +3 -0
  50. package/docs/sui-file-upload-card/README.md +8 -7
  51. package/docs/sui-filter/README.md +181 -0
  52. package/docs/sui-flag/README.md +3 -2
  53. package/docs/sui-form-hint/README.md +12 -8
  54. package/docs/sui-form-label/README.md +11 -16
  55. package/docs/sui-href/README.md +85 -0
  56. package/docs/sui-icon/README.md +4 -3
  57. package/docs/sui-image-upload/README.md +28 -16
  58. package/docs/sui-img-retry/README.md +107 -0
  59. package/docs/sui-inline-input/README.md +7 -6
  60. package/docs/sui-inline-select/README.md +8 -5
  61. package/docs/sui-input/README.md +27 -33
  62. package/docs/sui-integration-switch/README.md +14 -7
  63. package/docs/sui-kbd/README.md +4 -4
  64. package/docs/sui-key-icon/README.md +6 -2
  65. package/docs/sui-link-button/README.md +21 -17
  66. package/docs/sui-modal/README.md +238 -0
  67. package/docs/sui-modal-footer/README.md +178 -0
  68. package/docs/sui-modal-header/README.md +115 -0
  69. package/docs/sui-modal-sheet/README.md +170 -0
  70. package/docs/sui-notification/README.md +8 -6
  71. package/docs/sui-notification-footer/README.md +2 -2
  72. package/docs/sui-notification-tab-menu/README.md +5 -3
  73. package/docs/sui-page-header/README.md +123 -0
  74. package/docs/sui-pagination/README.md +8 -5
  75. package/docs/sui-password-strength/README.md +1 -1
  76. package/docs/sui-period-range/README.md +18 -14
  77. package/docs/sui-popover/README.md +13 -7
  78. package/docs/sui-product-card/README.md +14 -10
  79. package/docs/sui-progress-bar/README.md +4 -2
  80. package/docs/sui-progress-bar-label/README.md +2 -0
  81. package/docs/sui-radio/README.md +14 -7
  82. package/docs/sui-radio-card/README.md +12 -12
  83. package/docs/sui-radio-label/README.md +36 -11
  84. package/docs/sui-rating/README.md +28 -9
  85. package/docs/sui-rich-editor/README.md +3 -3
  86. package/docs/sui-segmented-control/README.md +33 -19
  87. package/docs/sui-select/README.md +40 -33
  88. package/docs/sui-sidebar/README.md +216 -0
  89. package/docs/sui-slider/README.md +7 -0
  90. package/docs/sui-social-button/README.md +24 -11
  91. package/docs/sui-status-badge/README.md +7 -3
  92. package/docs/sui-stepper/README.md +30 -17
  93. package/docs/sui-store-card/README.md +9 -4
  94. package/docs/sui-switch/README.md +16 -11
  95. package/docs/sui-switch-card/README.md +18 -16
  96. package/docs/sui-switch-label/README.md +25 -11
  97. package/docs/sui-tab-chips/README.md +56 -39
  98. package/docs/sui-tab-menu-horizontal/README.md +19 -11
  99. package/docs/sui-tab-menu-vertical/README.md +10 -5
  100. package/docs/sui-table/README.md +264 -0
  101. package/docs/sui-tag/README.md +25 -11
  102. package/docs/sui-tag-input/README.md +25 -12
  103. package/docs/sui-textarea/README.md +23 -20
  104. package/docs/sui-time-picker/README.md +39 -30
  105. package/docs/sui-toast/README.md +27 -22
  106. package/docs/sui-tooltip/README.md +14 -17
  107. package/docs/sui-topbar/README.md +153 -0
  108. package/docs/sui-topbar-button/README.md +95 -0
  109. package/docs/sui-topbar-item/README.md +97 -0
  110. package/docs/sui-topbar-user/README.md +83 -0
  111. package/fesm2022/ajuarezso-sui-design-system.mjs +1076 -242
  112. package/fesm2022/ajuarezso-sui-design-system.mjs.map +1 -1
  113. package/package.json +1 -1
  114. package/types/ajuarezso-sui-design-system.d.ts +616 -280
@@ -96,7 +96,7 @@ readonly bp = inject(BreakpointsService); // master-pedidos: src/app/services/br
96
96
  ```
97
97
 
98
98
  ```html
99
- <sui-progress-bar [value]="progreso()" [size]="bp.isMobile() ? 'medium' : 'small'" ariaLabel="Subiendo la foto" />
99
+ <sui-progress-bar [value]="progreso()" [size]="bp.isMobile() ? 'large' : 'medium'" ariaLabel="Subiendo la foto" />
100
100
  ```
101
101
 
102
102
  ## API
@@ -110,6 +110,7 @@ readonly bp = inject(BreakpointsService); // master-pedidos: src/app/services/br
110
110
  | `color` | `'blue' \| 'green' \| 'orange' \| 'red' \| 'purple'` | `'blue'` |
111
111
  | `size` | `'small' \| 'medium' \| 'large' \| 'xlarge'` | `'medium'` |
112
112
  | `ariaLabel` | `string \| null` | `null` |
113
+ | `ariaLabelledby` | `string \| null` | `null` |
113
114
 
114
115
  Outputs: ninguno.
115
116
  <!-- api:fin -->
@@ -122,7 +123,8 @@ Outputs: ninguno.
122
123
  este proyecto es naranja).
123
124
  - El ancho es el 100 % del padre: dentro de un flex, dale `flex: 1` o un ancho.
124
125
  - Lleva `role="progressbar"` con `aria-valuenow`; la animación se apaga con
125
- `prefers-reduced-motion`.
126
+ `prefers-reduced-motion`. Nombre: `ariaLabel`, o `ariaLabelledby` (id de un texto visible), y si
127
+ no hay ninguno se llama «Progreso» (04-10-2026: antes quedaba sin nombre).
126
128
 
127
129
  ## Ejemplo
128
130
 
@@ -123,6 +123,8 @@ Output: `(linkClick)`. Con `link` de texto el `<a>` no navega y solo emite; con
123
123
  - El link se pinta en el azul de información, no en el naranja de la marca.
124
124
  - Si no hay `title` y `percentage` es `false`, no se dibuja la fila de arriba.
125
125
  - Tiene el strip del `title` nativo: no aparece el tooltip gris del navegador.
126
+ - El `title` visible nombra la barra (`aria-labelledby`, 04-10-2026); sin título (`on-right`) y sin
127
+ `ariaLabel` se anuncia «Progreso».
126
128
 
127
129
  ## Ejemplo
128
130
 
@@ -19,8 +19,8 @@ Va dentro de un `sui-radio-group`, que es el que hace que elegir una desmarque l
19
19
 
20
20
  - Un círculo con su texto en una lista densa (franjas horarias): `sui-radio-label`.
21
21
  - Opciones con peso (ícono, descripción, borde) o que se tocan en el teléfono: `sui-radio-card`
22
- (método de pago, tipo de entrega, motivos de cancelación). Crece con `bp.controlSize()`; el
23
- radio-label no tiene `size`.
22
+ (método de pago, tipo de entrega, motivos de cancelación). La tarjeta entera es el área táctil
23
+ (54 px o más); un radio-label sin descripción mide lo que su círculo.
24
24
  - Más de ~6 opciones: `sui-select`.
25
25
  - 2-4 modos de la misma vista que se aplican al instante: `sui-segmented-control`.
26
26
  - Varias a la vez: `sui-checkbox`.
@@ -57,10 +57,10 @@ Regla corta: **lista densa de texto → radio-label · con peso o en el teléfon
57
57
  **Usos de hoy que rompen la regla:**
58
58
 
59
59
  - **1 radio nativo → `sui-radio-card type="basic"`:**
60
- `pages/driver/driver-order-detail/driver-order-detail.html:812` (motivos de cancelación del
60
+ `pages/driver/driver-order-detail/driver-order-detail.html:844` (motivos de cancelación del
61
61
  repartidor, el mismo caso del ejemplo de la guía). La pantalla hermana del local ya lo resolvió
62
- así: `pages/orders/orders.html:566`.
63
- - **1 suelto que se puede desincronizar:** `pages/super-admin/master-settings/master-settings.html:105`
62
+ así: `pages/orders/orders.html:567`.
63
+ - **1 suelto que se puede desincronizar:** `pages/super-admin/master-settings/master-settings.html:107`
64
64
  (categoría por defecto). Usa `[standaloneChecked]` + `$event && …`: al tocar el que ya está
65
65
  elegido, el círculo se apaga por dentro pero el padre sigue diciendo que es el elegido. Va en
66
66
  un `sui-radio-group` con `[ngModel]`.
@@ -96,6 +96,7 @@ El más grande mide 28 px: el área táctil de 44 px la tiene que dar la fila.
96
96
  | `size` | `'medium' \| 'large' \| 'xlarge'` | `'medium'` |
97
97
  | `value` | `SuiRadioValue` | `null` |
98
98
  | `disabled` | `boolean` | `false` |
99
+ | `focusable` | `boolean` | `true` |
99
100
  | `standaloneChecked` · model, `[(standaloneChecked)]` | `boolean` | `false` |
100
101
 
101
102
  Outputs: ninguno.
@@ -117,8 +118,14 @@ y proyecta los radios (`sui-radio`, `sui-radio-label`, `sui-radio-card`).
117
118
  - **`sui-radio-group` no tiene `value`**: se maneja con `[(ngModel)]` o un form control.
118
119
  - **`sui-radio-group` es `inline-flex` en fila con gap 16.** Para lista vertical hay que darle
119
120
  `flex-direction: column; align-items: flex-start` desde afuera.
120
- - **Deshabilitar el control del grupo no deshabilita los radios** (`setDisabledState` no hace
121
- nada): pasa `[disabled]` a cada uno.
121
+ - **Teclado en `sui-radio-group`** (revisión 04-10-2026): un solo tab stop —la opción marcada, o la
122
+ primera habilitada— y las flechas ↑ ↓ ← → mueven el foco y eligen la vecina, saltando las
123
+ deshabilitadas y dando la vuelta. Vale igual con `sui-radio-label` y `sui-radio-card` adentro.
124
+ Antes cada radio era una parada de Tab y no había flechas.
125
+ - **Deshabilitar el control del grupo deshabilita todas las opciones** (`setDisabledState`;
126
+ hasta el 04-10-2026 no hacía nada y había que pasar `[disabled]` a cada una).
127
+ - **`[focusable]="false"`** saca al radio del Tab y del grupo de flechas: es para cuando un padre
128
+ ya es el radio enfocable (`sui-radio-label`).
122
129
  - No hay `small`: el más chico es `medium` (20 px).
123
130
  - Sin marcar, en foco, el círculo se pinta del color de marca: viene del Figma, no es un error.
124
131
  - No dibuja texto ni `aria-label`: pelado, pon el texto en un `<label>` o usa `sui-radio-label`.
@@ -31,10 +31,11 @@ checkbox-card.**
31
31
  > adentro: **«para elegir una sola opción de una lista corta»**. El resto es práctica de la app
32
32
  > («propuesta») o regla ya aprobada («canon»).
33
33
  >
34
- > Uso medido el 03-10-2026 en `master-pedidos/src/app` (misma exclusión que `sui-card`): **31
34
+ > Uso medido el 04-10-2026 en `master-pedidos/src/app` (misma exclusión que `sui-card`): **31
35
35
  > radio-cards en 14 archivos**. Tipos: 23 `left-icon` (3 de ellos con emoji animado por
36
- > `iconSrc`), 6 `basic`, 1 `avatar`, 1 `company`. Tamaños: 24 `bp.controlSize()`, 4 `medium`, 1
37
- > `xlarge` fijo, 1 dinámico, 1 sin `size`. 6 con `sublabel`, 3 con `disabled`, 1 con `badge`.
36
+ > `iconSrc`), 6 `basic`, 1 `avatar`, 1 `company`. Tamaños: 30 `bp.controlSize()` y 1 con el
37
+ > `size()` del padre (`components/address-picker-modal/address-picker-modal.html:41`). 6 con
38
+ > `sublabel`, 6 con `disabled`, 1 con `badge`.
38
39
 
39
40
  ### `type` (el leading)
40
41
 
@@ -68,13 +69,10 @@ checkbox-card.**
68
69
  | `large` (24) | Desktop, vía `bp.controlSize()`. | canon (aprobado por el dueño, 28-09-2026) |
69
70
  | `medium` (20, default) | No usar en pantallas nuevas. | canon (aprobado por el dueño, 28-09-2026) |
70
71
 
71
- **Usos de hoy que rompen las reglas:**
72
+ **Usos de hoy que rompen las reglas: 0.** Los 5 que iban sin el size del breakpoint y el
73
+ `xlarge` fijo de `pages/customer/mandadito/mandadito.html:30` pasaron a `bp.controlSize()` el
74
+ 03-10-2026.
72
75
 
73
- - **5 sin el size del breakpoint**: `components/por-cobrar-card/por-cobrar-card.html:38` y `:48`,
74
- `pages/driver/driver-dashboard/driver-dashboard.html:581`,
75
- `pages/super-admin/master-orders/master-orders.html:720` (los cuatro en `medium`) y
76
- `pages/mi-negocio/mi-negocio.html:22` (sin `size`). Además `pages/customer/mandadito/mandadito.html:30`
77
- va en `xlarge` fijo (en web debería ser `large`).
78
76
  - **A revisar:** `pages/super-admin/master-orders/master-orders.html:720` lista a los repartidores
79
77
  candidatos, una lista que crece con la flota (con muchos, `sui-select` o una lista con búsqueda).
80
78
  `pages/role-selector/role-selector.html:24` usa la radio como botón: elegir ya avanza, sin
@@ -82,8 +80,9 @@ checkbox-card.**
82
80
 
83
81
  ## Tamaño en mobile y en web
84
82
 
85
- La card entera es el área táctil (≥ 72 de alto con descripción, 16 de padding): llega al piso de
86
- 44 sola. El `size` cambia solo el radio.
83
+ La card entera es el área táctil: 74 px con descripción (16 + 40 + 16 de padding y contenido,
84
+ más 2 de borde) y 54 px la más chica (`basic`, sin descripción, `medium`). Llega al piso de 44
85
+ sola. El `size` cambia solo el radio.
87
86
 
88
87
  | uso | mobile | web |
89
88
  |---|---|---|
@@ -141,7 +140,8 @@ Implementa `ControlValueAccessor` (el valor del form es el `value` elegido). Den
141
140
  `imageUrl` si la marca no está en el catálogo). No hay slot para proyectar el leading (a
142
141
  diferencia de `sui-checkbox-card`).
143
142
  - Suelta (sin grupo), elegirla la marca pero **no desmarca a las otras**: el padre tiene que
144
- bindear `[checked]` de todas a la misma señal.
143
+ bindear `[checked]` de todas a la misma señal. Suelta, además, **cada card es una parada de Tab
144
+ y no hay flechas**; dentro de `sui-radio-group` sí hay un solo tab stop y flechas (revisión 04-10-2026).
145
145
  - `badge` con string sale **azul `light` `small`** (en `sui-content-label` sale naranja).
146
146
  - `size` cambia solo el radio, no el padding ni el alto de la card.
147
147
 
@@ -21,7 +21,8 @@ franjas horarias del checkout, tipo de documento. Toda la fila se toca. Va dentr
21
21
  usa la app para método de pago, tipo de entrega y modo de asignación.
22
22
  - **Una lista de motivos que se toca en el teléfono**: la app ya resolvió ese caso con
23
23
  `sui-radio-card type="basic"` y `bp.controlSize()` (motivos de cancelación del local,
24
- `pages/orders/orders.html:566`). El radio-label no tiene `size` y en mobile queda chico.
24
+ `pages/orders/orders.html:567`). La tarjeta da el área táctil; un radio-label sin descripción
25
+ mide 28 px de alto aun en `xlarge`.
25
26
  - Más de ~6 opciones: `sui-select`.
26
27
  - Varias a la vez: `sui-checkbox-label`.
27
28
  - Prender algo al instante: `sui-switch-label`.
@@ -51,16 +52,17 @@ o con peso → radio-card · muchas → select.**
51
52
  | `link` | «Ver detalle» que no elige la opción. Solo se ve con `description`. | según la guía del DS |
52
53
  | `flip` | Círculo a la derecha en listas de opciones tipo hoja (sheet) y de ajustes, donde el texto es lo que se lee y el círculo es el indicador, como las franjas del checkout. En formularios, a la izquierda. | canon (aprobado por el dueño, 03-10-2026) |
53
54
  | `disabled` | La opción existe pero no aplica (franja ya llena). | según la guía del DS |
54
- | `size` | `medium` (default, Figma): círculo 20, label 14/20. `large`: círculo 24, label 16/24. `xlarge`: círculo 28, label 16/24. En large y xlarge el sublabel y la descripción pasan a 14/20, el badge sin `size` propio sube a `medium` / `large` y el link a `medium`. Se usa con `[size]="bp.controlSize()"`. | `medium`: según la guía del DS · `large` / `xlarge`: canon (aprobado por el dueño, 03-10-2026), extensión SUI |
55
+ | `size` | `medium` (default, Figma): círculo 20, label 14/20. `large`: círculo 24, label 16/24. `xlarge`: círculo 28, label 16/24. En large y xlarge el sublabel y la descripción se quedan en 12/16 (canon, dueño 04-10-2026); el badge sin `size` propio sube a `medium` / `large` y el link a `medium`. Se usa con `[size]="bp.controlSize()"`. | `medium`: según la guía del DS · `large` / `xlarge`: canon (aprobado por el dueño, 03-10-2026), extensión SUI |
55
56
 
56
57
  **Usos de hoy:**
57
58
 
58
- - **1 radio nativo de motivos:** `pages/driver/driver-order-detail/driver-order-detail.html:812`
59
+ - **1 radio nativo de motivos:** `pages/driver/driver-order-detail/driver-order-detail.html:844`
59
60
  (motivos de cancelación del repartidor). Por la pantalla hermana va a `sui-radio-card
60
- type="basic"` como `pages/orders/orders.html:566`, no a este componente.
61
- - El único uso actual, `pages/customer/checkout/checkout.html:480`, controla la selección con
61
+ type="basic"` como `pages/orders/orders.html:567`, no a este componente.
62
+ - El único uso actual, `pages/customer/checkout/checkout.html:473`, controla la selección con
62
63
  `[checked]` + `(selected)` por fila, sin `sui-radio-group`. Funciona porque el padre fija el
63
- estado, pero no se enchufa a un formulario.
64
+ estado, pero no se enchufa a un formulario. **Va sin `size`** (`medium`, círculo de 20 px) en
65
+ una hoja del checkout del cliente, que se usa en el teléfono: rompe la tabla de abajo.
64
66
 
65
67
  ## Tamaño en mobile y en web
66
68
 
@@ -72,17 +74,36 @@ dueño, 28-09-2026).
72
74
 
73
75
  | uso | mobile | web | fuente |
74
76
  |---|---|---|---|
75
- | opciones de un formulario o una hoja (franjas horarias, método de entrega) | `xlarge` (círculo 28, label 16/24) | `large` (círculo 24, label 16/24) | canon (aprobado por el dueño, 03-10-2026) |
77
+ | opciones de un formulario o una hoja (franjas horarias, método de entrega) | `2xlarge` (fila de 44 como mínimo, círculo 28, label 16/24) | `large` (círculo 24, label 16/24) | canon (dueño, 04-10-2026): piso táctil 44 en el teléfono; web: canon (aprobado por el dueño, 03-10-2026) |
76
78
  | lista densa de desktop | — | `medium` (círculo 20, label 14/20) | propuesta, falta aprobación |
77
79
  | opciones con mucho contexto cada una | `sui-radio-card` con `bp.controlSize()` | `sui-radio-card` con `bp.controlSize()` | propuesta |
78
80
 
79
81
  ```html
80
- <sui-radio-label value="recojo" [size]="bp.controlSize()" label="Recojo en tienda" />
82
+ <sui-radio-label value="recojo" [size]="bp.isMobile() ? '2xlarge' : 'large'" label="Recojo en tienda" />
81
83
  ```
82
84
 
85
+ | size | círculo | label | sublabel / descripción | alto de la fila sin descripción |
86
+ |---|---|---|---|---|
87
+ | `medium` (default, Figma) | 20 | 14/20 | 12/16 | 20 |
88
+ | `large` | 24 | 16/24 | 12/16 | 24 |
89
+ | `xlarge` | 28 | 16/24 | 12/16 | 28 |
90
+ | `2xlarge` | 28 | 16/24 | 12/16 | **44** (`min-height`) |
91
+
92
+ `2xlarge` (canon (dueño, 04-10-2026): piso táctil 44 en el teléfono) es la fila del teléfono: mismo círculo de 28 y mismo label que `xlarge`,
93
+ pero la fila mide 44 como mínimo con todo centrado en vertical, y el texto secundario se queda en 12
94
+ (regla del 03-10). Con descripción la fila ya pasa de 44 y vuelve a alinearse arriba.
95
+
83
96
  Toda la fila se toca (el host recibe el click). Con `xlarge` el contenido baja 2 px para que la
84
97
  línea del label (24) quede centrada con el círculo (28).
85
98
 
99
+ Sin descripción, la fila en `xlarge` mide 28 px (lo que mide el círculo): en el teléfono va
100
+ `2xlarge`, que la lleva a 44. Con descripción llega sola: 2 + 24 (label) + 4 + 16 (descripción) = 46 px
101
+ en `xlarge` y en `2xlarge`.
102
+
103
+ **Regla de tamaños aplicada (canon, dueño 04-10-2026):** en `large` y `xlarge` el label sube a
104
+ 16/24 y el sublabel y la descripción se quedan en 12/16, igual que `sui-switch-label`. Antes subían
105
+ a 14/20. El badge y el link siguen creciendo con el size.
106
+
86
107
  ## «No usar»: por qué no hoy y cuándo sí
87
108
 
88
109
  | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
@@ -103,7 +124,7 @@ línea del label (24) quede centrada con el círculo (28).
103
124
  | `description` | `string \| null` | `null` |
104
125
  | `badge` | `SuiBadgeConfig \| string \| null` | `null` |
105
126
  | `link` | `SuiLinkConfig \| string \| null` | `null` |
106
- | `size` | `'medium' \| 'large' \| 'xlarge'` | `'medium'` |
127
+ | `size` | `'medium' \| 'large' \| 'xlarge' \| '2xlarge'` | `'medium'` |
107
128
  | `flip` | `boolean` | `false` |
108
129
  | `disabled` | `boolean` | `false` |
109
130
  | `checked` · model, `[(checked)]` | `boolean` | `false` |
@@ -118,11 +139,15 @@ línea del label (24) quede centrada con el círculo (28).
118
139
 
119
140
  - **No implementa `ControlValueAccessor`.** El formulario se engancha al `sui-radio-group`, no a
120
141
  cada opción. Sin grupo, se maneja con `[(checked)]`.
121
- - **No tiene `size`**: el círculo mide 20 px siempre. Choca con la regla de controles grandes
122
- (dueño, 28-09-2026) en mobile; si hace falta grande, `sui-radio-card`.
142
+ - **`size` arranca en `medium`** (círculo de 20 px): sin `[size]="bp.controlSize()"` choca con la
143
+ regla de controles grandes (dueño, 28-09-2026) en mobile.
123
144
  - **Tocar una opción ya elegida no la desmarca** (bien, es un radio). Tocar el link tampoco la elige.
124
145
  - **`link` solo se dibuja con `description`.**
125
146
  - El `sui-radio` de adentro no recibe clics (`pointer-events: none`): no le pongas handlers.
147
+ Tampoco foco ni lector: va con `[focusable]="false"` y `aria-hidden`, y el radio es el host,
148
+ con nombre = `label` y descripción = `description`. Hasta el 04-10-2026 cada opción eran dos
149
+ paradas de Tab y dos radios anidados.
150
+ - En `sui-radio-group`, un solo tab stop y flechas ↑ ↓ ← → (revisión 04-10-2026).
126
151
  - El badge con string sale naranja; en `sui-radio-card` el default es azul.
127
152
  - `flip` usa CSS `order`: el orden para lector de pantalla no cambia.
128
153
 
@@ -50,8 +50,8 @@ lista cargada, que viene con tope. La fórmula depende de `n`: otro denominador
50
50
  | appearance | cuándo | ejemplo real | fuente |
51
51
  |---|---|---|---|
52
52
  | `inline` (default), `readonly` | **Mostrar** una nota: la fila de estrellas pelada. | `components/ratings-detail/ratings-detail.html:31` (la nota del local) | según la guía del DS (ejemplo «Rating Review») |
53
- | `inline`, interactivo | **A discutir.** Pedir la nota en grande (`xlarge`). Cada estrella mide 28 px, por debajo de los 44 que pide un dedo. | `pages/customer/rate-order/rate-order.html:93` y `:166` | propuesta, falta aprobación |
54
- | `bar` | **Pedir** una nota en el celular: celdas de 64 × 36 fáciles de tocar. | `components/rate-entity-card/rate-entity-card.html:40` | según la guía del DS (ejemplo «Rating Bar») |
53
+ | `inline`, interactivo | Pedir la nota en grande: en el teléfono con `size="2xlarge"` (estrellas de 32 en botones de 44 × 44); `xlarge` (28 tocables) queda para web. | `pages/customer/rate-order/rate-order.html:93` y `:167` (hoy en `xlarge`) | tamaño: canon (dueño, 04-10-2026): piso táctil 44 en el teléfono; el «cuándo inline vs bar» sigue como propuesta |
54
+ | `bar` | **Pedir** una nota en el celular: con `size="2xlarge"` las celdas miden 64 × 44 (36 en los demás sizes). | `components/rate-entity-card/rate-entity-card.html:40` | según la guía del DS (ejemplo «Rating Bar») |
55
55
  | `cell` | **No usar** hoy (ver abajo). | — | según la guía del DS (ejemplo «Rating Cell») |
56
56
  | `bar-area` | **No usar** hoy (ver abajo). | — | según la guía del DS (ejemplo «Rating Bar With Textarea») |
57
57
 
@@ -99,7 +99,7 @@ lista cargada, que viene con tope. La fórmula depende de `n`: otro denominador
99
99
  - **1 rating usado como ícono** (`type="heart"` con `max=1` para los favoritos):
100
100
  `components/ratings-detail/ratings-detail.html:45`. Va `sui-icon name="heart-3-fill"`.
101
101
  - **A discutir, 2 `inline` interactivos de 28 px** como input:
102
- `pages/customer/rate-order/rate-order.html:93` y `:166`. Alternativa: `appearance="bar"`.
102
+ `pages/customer/rate-order/rate-order.html:93` y `:167`. Alternativa: `appearance="bar"`.
103
103
 
104
104
  ## No usar: por qué no hoy y cuándo sí
105
105
 
@@ -125,7 +125,7 @@ de la app.
125
125
  | Mostrar en una fila o lista | `medium` (20) | `small` (16) | propuesta, falta aprobación |
126
126
  | Mostrar en perfil o ficha | `large` (24) | `medium` (20) | propuesta, falta aprobación |
127
127
  | La nota grande de un resumen | `xlarge` (28) | `large` (24) | propuesta, falta aprobación |
128
- | Pedir una nota | `appearance="bar"` (celdas de 64 × 36) | `bar`, o `inline` `large` con mouse | propuesta, falta aprobación |
128
+ | Pedir una nota | `2xlarge`: `inline` (estrellas de 32 en botones de 44 × 44) o `bar` (celdas de 64 × 44) | `bar` (64 × 36), o `inline` `large` con mouse | canon (dueño, 04-10-2026): piso táctil 44 en el teléfono; web: propuesta |
129
129
 
130
130
  ```ts
131
131
  readonly bp = inject(BreakpointsService); // master-pedidos: src/app/services/breakpoints.service.ts
@@ -136,8 +136,23 @@ readonly bp = inject(BreakpointsService); // master-pedidos: src/app/services/br
136
136
  [size]="bp.isMobile() ? 'medium' : 'small'" ariaLabel="Nota del local" />
137
137
  ```
138
138
 
139
- En `bar` el `size` no cuenta (íconos fijos de 20) y en `cell` tampoco (32): el tamaño por
140
- plataforma solo se elige en `inline`.
139
+ En `bar` el `size` no cuenta salvo `2xlarge` (celda de 44 de alto en vez de 36; íconos fijos de 20
140
+ y número en 16), y en `cell` tampoco (32): el resto del tamaño por plataforma se elige en `inline`.
141
+
142
+ | size | `inline`: glyph · lo que se toca | `bar`: alto de celda |
143
+ |---|---|---|
144
+ | `small` | 16 · 16 | 36 |
145
+ | `medium` (default) | 20 · 20 | 36 |
146
+ | `large` | 24 · 24 | 36 |
147
+ | `xlarge` | 28 · 28 | 36 |
148
+ | `2xlarge` | 32 · **44 × 44** (padding 6, sin gap entre estrellas) | **44** |
149
+
150
+ `2xlarge` (canon (dueño, 04-10-2026): piso táctil 44 en el teléfono) es para **pedir** la nota en el teléfono. Para mostrar una
151
+ nota de solo lectura sigue `medium`/`large`.
152
+
153
+ Área táctil de cada forma de **pedir** la nota, medida en el `.scss`: `inline` `xlarge` 28 px
154
+ (el botón es el ícono, sin padding) y `2xlarge` 44 px (32 + 6 + 6); `bar` 36 px (8 + 20 + 8 de cada
155
+ celda) y en `2xlarge` 44 (12 + 20 + 12); `cell` 58 px (12 + 32 + 12 de padding y 2 de borde).
141
156
 
142
157
  ## API
143
158
 
@@ -150,7 +165,7 @@ plataforma solo se elige en `inline`.
150
165
  | `type` | `'star' \| 'heart' \| 'emoji' \| 'number'` | `'star'` |
151
166
  | `value` · model, `[(value)]` | `number` | `0` |
152
167
  | `max` | `number` | `5` |
153
- | `size` | `'small' \| 'medium' \| 'large' \| 'xlarge'` | `'medium'` |
168
+ | `size` | `'small' \| 'medium' \| 'large' \| 'xlarge' \| '2xlarge'` | `'medium'` |
154
169
  | `readonly` | `boolean` | `false` |
155
170
  | `halfStep` | `boolean` | `false` |
156
171
  | `showValue` | `boolean` | `false` |
@@ -184,8 +199,12 @@ Implementa `ControlValueAccessor` sobre `value` (sirve con `formControlName`). `
184
199
  estrellas que se llena.
185
200
  - `emoji` y `number` **solo se dibujan en `bar`**.
186
201
  - `(valueChange)` emite de 1 a `max`, nunca 0; volver a tocar la misma no la quita.
187
- - El host lleva `role="radiogroup"` y `aria-label`: si la pantalla ya escribe la nota al lado,
188
- ponle `aria-hidden="true"` para que no se lea dos veces.
202
+ - **Roles (04-10-2026):** con `readonly` es una nota, no una pregunta: el host es `role="img"` con
203
+ «Calificación: 4,5 de 5» (más «, 120 calificaciones» si hay `reviewCount`), sin radios adentro; con
204
+ `reviewLink` pasa a `role="group"` para que el link siga alcanzable. Interactivo es
205
+ `role="radiogroup"` con un solo tab stop: → ↓ suben la nota, ← ↑ la bajan (como un radio
206
+ nativo), Home/End van a 1 y al máximo, sin vuelta. Cada flecha elige y emite `valueChange`. Si
207
+ la pantalla ya escribe la nota al lado, ponle `aria-hidden="true"` para que no se lea dos veces.
189
208
 
190
209
  ## Ejemplo
191
210
 
@@ -39,7 +39,7 @@ Regla corta: **hoy, siempre `sui-textarea`.**
39
39
  | `editable` | `true` para tener el área donde se escribe; `false` deja solo la barra. | API |
40
40
  | `placeholder` | «Escribe algo…» (default) o algo del contexto. | API |
41
41
  | `value` | El contenido, **en HTML**. | API |
42
- | `headingLabel` · `fontSizeLabel` | Lo que dicen los botones de título y tamaño («Header», «14px» por default). | API |
42
+ | `headingLabel` · `fontSizeLabel` | Lo que dicen los botones de título y tamaño («Título», «14px» por default). | API |
43
43
  | `(action)` | Cada botón de la barra: la pantalla tiene que resolver título, tamaño, enlace, comentario y mención. | API |
44
44
 
45
45
  ## Tamaño en mobile y en web
@@ -68,7 +68,7 @@ mobile**. Si alguna vez se usa, que sea en el panel web.
68
68
  | `editable` | `boolean` | `false` |
69
69
  | `placeholder` | `string` | `'Escribe algo…'` |
70
70
  | `value` · model, `[(value)]` | `string` | `''` |
71
- | `headingLabel` | `string` | `'Header'` |
71
+ | `headingLabel` | `string` | `'Título'` |
72
72
  | `fontSizeLabel` | `string` | `'14px'` |
73
73
 
74
74
  | output | payload |
@@ -104,7 +104,7 @@ Sub-componente: `sui-rich-editor-item` (cada botón de la barra).
104
104
  Título, tamaño, enlace, comentario y mención solo emiten `(action)`: la pantalla tiene que hacer
105
105
  el resto.
106
106
  - Por default muestra solo la barra: sin `[editable]="true"` no hay dónde escribir.
107
- - Labels por default en inglés o técnicos («Header», «14px»).
107
+ - El label de tamaño por default es técnico («14px»); el de título ya está en español («Título», 04-10-2026).
108
108
 
109
109
  ## Ejemplo
110
110
 
@@ -17,12 +17,14 @@ cuadrícula o lista en el catálogo, el local cuyo horario estás viendo, el rol
17
17
  **No lo uses** para:
18
18
 
19
19
  - Navegar entre secciones de contenido distinto: `sui-tab-menu-horizontal`.
20
- - Una fila de filtros con muchas opciones o que scrollea: `sui-tab-chips`.
20
+ - Una fila de filtros con 5 o más opciones o que scrollea: `sui-tab-chips`. **Período o filtro con 2 a 4 opciones excluyentes → `sui-segmented-control`; con 5 o más, o si no caben y tienen que deslizarse → `sui-tab-chips`** (canon, dueño 04-10-2026).
21
21
  - Elegir un valor que se guarda después con un botón: `sui-radio-card` (no se enchufa a un formulario).
22
22
  - Varias opciones a la vez: `sui-button-group`.
23
23
  - 5 o más opciones: los segmentos se reparten el ancho y los textos se cortan.
24
24
 
25
- Regla corta: **2-4 modos de la misma vista, efecto inmediato → segmented · secciones → tab menu · filtros → tab-chips.**
25
+ Regla corta (canon, dueño 04-10-2026): **2-4 opciones excluyentes de efecto inmediato (modos de la
26
+ vista, períodos o filtros fijos como «Hoy · 7 días · 30 días») → segmented · 5+ o que deslizan →
27
+ tab-chips · secciones → tab menu.**
26
28
 
27
29
  ## Qué variante usar
28
30
 
@@ -55,40 +57,46 @@ Regla corta: **2-4 modos de la misma vista, efecto inmediato → segmented · se
55
57
  **Usos de hoy que rompen las reglas:**
56
58
 
57
59
  - **2 dentro de un borrador que se guarda después (a discutir):**
58
- `pages/super-admin/master-settings/master-settings.html:296` (modo de envío: «Por distancia» /
59
- «Precio único») y `:329` («Por calle» / «En línea recta»). La guía dice que se aplica de
60
+ `pages/super-admin/master-settings/master-settings.html:303` (modo de envío: «Por distancia» /
61
+ «Precio único») y `:336` («Por calle» / «En línea recta»). La guía dice que se aplica de
60
62
  inmediato; aquí la elección espera al «Guardar». Es trabajo de `sui-radio-card`.
61
63
  - **1 con textos largos, a verificar en mobile:** `pages/super-admin/master-roles/master-roles.html:47`
62
64
  («Administrador de ciudad» / «Jefe de operaciones»). Por ancho de texto quedan apretados cerca
63
65
  del borde a 390 px; no se midió en la pantalla real.
64
- - **2 en `small` con texto** (la propuesta deja `small` solo para íconos): `master-settings.html:296`
65
- y `:329`. El tercero en `small`, `pages/products/products.html:80`, está bien: solo íconos.
66
+ - **2 en `small` con texto** (la propuesta deja `small` solo para íconos): `master-settings.html:303`
67
+ y `:336`. El tercero en `small`, `pages/products/products.html:81`, está bien: solo íconos.
66
68
  - **5 sin tamaño por plataforma** (todos fijos): ninguno cambia a `xlarge` en mobile. Ejemplo:
67
- `pages/driver/driver-schedule/driver-schedule.html:32` (`size="medium"` en una pantalla del
69
+ `pages/driver/driver-schedule/driver-schedule.html:30` (`size="medium"` en una pantalla del
68
70
  repartidor, que se usa en el teléfono).
69
71
 
70
72
  ## Tamaño en mobile y en web
71
73
 
72
- Alto de cada segmento: `small` 28 px, `medium` 28 px, `large` 32 px, `xlarge` 40 px (el control
73
- suma 8 px de borde interno).
74
+ Alto de cada segmento con texto: `small` 28 px, `medium` 28 px, `large` 32 px, `xlarge` 40 px
75
+ (8 + 24 + 8), `2xlarge` 44 px (10 + 24 + 10). Con `iconOnly` el `xlarge` mide 36 (8 + 20 + 8) y el
76
+ `2xlarge` 44 (12 + 20 + 12): el ícono queda en 20 y no hay línea de texto. El riel suma 8 px más (4
77
+ de relleno arriba y 4 abajo), pero ese relleno no responde al toque: el área táctil es el segmento.
74
78
 
75
- | uso | mobile | web |
76
- |---|---|---|
77
- | modos con texto (local del horario, rol) | `xlarge` (segmento de 40 px) | `medium` |
78
- | solo íconos en una barra (cuadrícula / lista) | `xlarge` | `small` |
79
+ En large, xlarge y 2xlarge el texto sube a 16 px (regla del 03-10-2026): Label/Medium 16/24. En
80
+ `large` el padding del segmento con texto bajó de 6 a 4 para que siga midiendo 32.
81
+
82
+ **`2xlarge` es el size del teléfono**: 44 px por segmento, con texto o solo ícono (canon (dueño,
83
+ 04-10-2026): piso táctil 44 en el teléfono). `xlarge` (40) no cambia y queda para las pantallas que
84
+ ya lo usan.
85
+
86
+ | uso | mobile | web | fuente |
87
+ |---|---|---|---|
88
+ | modos con texto (local del horario, rol) | `2xlarge` (segmento de 44 px) | `medium` | canon (dueño, 04-10-2026): piso táctil 44 en el teléfono |
89
+ | solo íconos en una barra (cuadrícula / lista) | `2xlarge` (44) | `small` | canon (dueño, 04-10-2026): piso táctil 44 en el teléfono |
79
90
 
80
91
  ```html
81
- <sui-segmented-control [size]="bp.isMobile() ? 'xlarge' : 'medium'" … />
92
+ <sui-segmented-control [size]="bp.isMobile() ? '2xlarge' : 'medium'" … />
82
93
  ```
83
94
 
84
- El más grande llega a 40 px por segmento: queda 4 px corto de los 44 px de área táctil. Es el
85
- mejor disponible para mobile.
86
-
87
95
  ## «No usar»: por qué no hoy y cuándo sí
88
96
 
89
97
  | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
90
98
  |---|---|---|
91
- | `large` | 32 px: no llega al dedo en mobile y sobra en web | un control dentro de un sheet de mobile muy apretado donde `xlarge` no entra |
99
+ | `large` | 32 px: no llega al dedo en mobile y sobra en web | un control dentro de un sheet de mobile muy apretado donde `2xlarge` no entra |
92
100
  | `disabled` por ítem | ningún modo está bloqueado | un modo que depende del plan («Reportes completos» en plan básico) |
93
101
  | 5+ ítems | se cortan los textos | nunca: pasa a `sui-tab-chips` |
94
102
 
@@ -101,7 +109,8 @@ mejor disponible para mobile.
101
109
  |---|---|---|
102
110
  | `tabs` | `SuiSegmentedControlItem<T>[]` | — (requerido) |
103
111
  | `active` · model, `[(active)]` | `T` | `undefined` |
104
- | `size` | `'small' \| 'medium' \| 'large' \| 'xlarge'` | `'medium'` |
112
+ | `size` | `'small' \| 'medium' \| 'large' \| 'xlarge' \| '2xlarge'` | `'medium'` |
113
+ | `ariaLabel` | `string \| null` | `null` |
105
114
 
106
115
  | output | payload |
107
116
  |---|---|
@@ -128,6 +137,11 @@ interface SuiSegmentedControlItem<T = string> {
128
137
  - El indicador se mide con el DOM: si arranca oculto queda en ancho 0 hasta que algo cambie de tamaño.
129
138
  - `iconOnly` sin `icon` no dibuja nada. El ícono mide 20 px en todos los tamaños.
130
139
  - `disabled` es por ítem; no hay `disabled` del control entero.
140
+ - **Es un `radiogroup`, no pestañas** (04-10-2026): elige un valor, así que cada ítem es
141
+ `role="radio"` con `aria-checked`. Un solo tab stop (el elegido); ← → ↑ ↓ mueven **y eligen**
142
+ (patrón de radio, con vuelta al inicio y saltando los deshabilitados), Home/End van a los
143
+ extremos. Cada flecha emite `tabChange`: con 2-4 opciones está bien, pero si elegir dispara una
144
+ carga pesada, pensarlo. Pásale `ariaLabel` («Tipo de entrega») para que el grupo tenga nombre.
131
145
  - Los tamaños son extensión de SUI: la guía tiene uno solo. Su versión redondeada (`Rounded`)
132
146
  no existe en SUI.
133
147
 
@@ -18,7 +18,8 @@ distrito, repartidor, categoría, plan) o que tiene **más de 6 opciones fijas**
18
18
 
19
19
  - 2 a 6 opciones fijas dentro de un formulario: se ven todas de una con `sui-radio-label` (web) o
20
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`.
21
+ - 2 a 4 modos, períodos o filtros fijos que se aplican al tocar (Hoy · Semana · Mes): `sui-segmented-control`.
22
+ Con 5 o más que se aplican al tocar: `sui-tab-chips`. **Período o filtro con 2 a 4 opciones excluyentes → `sui-segmented-control`; con 5 o más, o si no caben y tienen que deslizarse → `sui-tab-chips`** (canon, dueño 04-10-2026).
22
23
  - **Buscar** dentro de la lista: `sui-select` **no tiene buscador**. Con 40 distritos se scrollea.
23
24
  - Elegir **varias**: no es múltiple. Varias opciones fijas → casillas; valores libres → `sui-tag-input`.
24
25
  - Una lista con foto o bandera por opción: las opciones solo muestran texto (ver «Trampas»).
@@ -32,70 +33,73 @@ Regla corta: **sale de datos o son más de 6 → select · 2–6 fijas → radio
32
33
  > variantes que en SUI son componentes aparte: `compact` (`sui-compact-select`), `inline`
33
34
  > (`sui-inline-select`) y `compactForInput` (`sui-compact-select-for-input`). No dice cuándo va cada una.
34
35
  >
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`.
36
+ > Uso medido el 04-10-2026 en `master-pedidos/src/app` (misma exclusión que `sui-badge`, más
37
+ > `master-ejercicios`): **54 usos en 26 archivos**. Todos `type="basic"` y sin ícono. Tamaños:
38
+ > 23 `bp.isMobile() ? 'large' : 'medium'`, 13 sin `size` (`medium`), 11 `large`,
39
+ > 3 `bp.isMobile() ? 'large' : 'small'`, 2 `medium`, 1 `small`, 1 `bp.controlSize()`. Los 54 pasan
40
+ > `placeholder` (46 «Elige…»; los 8 restantes son filtros sin label: «Filtrar», «Rol», «Estado»…).
39
41
 
40
42
  ### Qué elegir según las opciones
41
43
 
42
44
  | caso | componente | fuente |
43
45
  |---|---|---|
44
46
  | 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) |
47
+ | Más de ~6 opciones fijas | `sui-select` | derivado del README de `sui-radio` («más de ~6 → select»), falta confirmación |
46
48
  | 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) |
49
+ | 2 a 4 modos que se aplican al instante | `sui-segmented-control` | según la guía del DS («aplicarla de inmediato», ver README de `sui-segmented-control`); el tope de 4 es propuesta |
48
50
  | 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
51
 
50
52
  **Candidatos de hoy** (no rompen nada; se verían mejor con radios o segmented):
51
53
 
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`.
54
+ - **5 selects con 2 opciones fijas**: `components/add-product-modal/add-product-modal.html:255`,
55
+ `pages/drivers/drivers.html:376` y `pages/drivers/add-driver/add-driver.html:111` («Tipo de pago»),
56
+ `pages/super-admin/master-gastos/master-gastos.html:186` («Estado») y `:203` («Moneda»).
57
+ - **Unos 15 con 3 a 6 opciones fijas en un formulario** (cifra aproximada, no recontada el 04-10): `components/address-form-modal/address-form-modal.html:11`
58
+ («Etiqueta»), `pages/customer/profile/profile.html:252` («Género»), `pages/drivers/drivers.html:360`
59
+ («Tipo de vehículo»), `pages/discounts/discounts.html:142`,
60
+ `pages/super-admin/master-sonidos-push/master-sonidos-push.html:85` (6 opciones).
61
+ - **2 filtros de período de 3 opciones** → `sui-segmented-control`: `pages/overview/overview.html:44`,
62
+ `pages/discounts/discounts.html:49`. Decidido (canon, dueño 04-10-2026): período o filtro de 2 a 4
63
+ opciones excluyentes → segmented; 5 o más o que deslizan → tab-chips. Los README de tab-chips,
64
+ datepicker, period-range y date-selector ya dicen lo mismo.
61
65
 
62
66
  ### `type`, `leadingIcon`, `imageUrl`, `flag`, `badge`
63
67
 
64
68
  | prop | cuándo | fuente |
65
69
  |---|---|---|
66
70
  | `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 |
71
+ | `type="avatar"` + `imageUrl` | Elegir un **repartidor**: la foto de quien quedó elegido en el campo. Hoy `pages/orders/orders.html:257` muestra solo el nombre. | según la guía del DS (ejemplo «User»); el caso es propuesta |
68
72
  | `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
73
  | `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
74
  | `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. | — |
75
+ | `type="brand"` / `"company"` | No usar hoy. | propuesta, falta aprobación |
76
+ | `badge` | No usar hoy. | propuesta, falta aprobación |
73
77
 
74
78
  ### Las piezas
75
79
 
76
80
  | prop | cuándo | fuente |
77
81
  |---|---|---|
78
82
  | `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 |
83
+ | `placeholder` | **Siempre**, en imperativo con tuteo: «Elige…» o «Elige el distrito» cuando el sustantivo ayuda. El default genérico es «Elige…» (04-10-2026). | canon (CANON-SUI §5.7, decisión del dueño 03-10-2026) |
84
+ | `required` · `sublabel` · `tooltip` · `hint` | Igual que `sui-input`: asterisco, «(Opcional)» con paréntesis, aclaración, ayuda de una línea. | según la guía del DS |
81
85
  | `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`) |
86
+ | `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:97`) |
83
87
  | `options` | `SuiSelectOption<T>[]`: `{ value, label, disabled? }`. `disabled` en la opción para lo que existe pero hoy no se puede elegir. | API |
84
88
 
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».
89
+ **Usos de hoy que rompen la regla:** 0 sin `placeholder` y 0 «Seleccionar…» (medido el
90
+ 04-10-2026; el 03-10 eran 28 y 16, ya corregidos en la app). Los 8 que no dicen «Elige…» son
91
+ filtros sin label donde el placeholder hace de label («Rol», «Estado», «Período»).
91
92
 
92
93
  ## Tamaño en mobile y en web
93
94
 
94
95
  El campo sigue la escala del input y del botón (`large` 48 y `xlarge` 52 son extensión de SUI;
95
96
  la guía tiene `medium` 40, `small` 36 y `xsmall` 32). **La lista acompaña al campo**: las opciones
96
97
  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.
98
+ nunca bajan de 44**, sea cual sea el `size`. El texto de la opción es el mismo del valor del
99
+ campo: 14/20 hasta `medium` y 16/24 en `large` y `xlarge`.
100
+
101
+ En large y xlarge el texto sube a 16 px (regla del 03-10-2026). Vale para el valor, el placeholder
102
+ y las opciones de la lista; el alto no cambia (las opciones bajan 2 de padding para seguir en 44/48).
99
103
 
100
104
  | size del campo | opción en web | opción en mobile | fuente |
101
105
  |---|---|---|---|
@@ -106,7 +110,7 @@ valor del campo.
106
110
  | uso | mobile | web | fuente |
107
111
  |---|---|---|---|
108
112
  | 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`) |
113
+ | filtro de una barra | `large` (48) | `small` (36) | propuesta (ya es práctica en `pages/orders/orders.html:257`) |
110
114
  | dentro de una tabla densa | no aplica | `xsmall` (32) | según la guía del DS |
111
115
  | `xlarge` (52) | no usar | no usar | propuesta: queda más alto que el botón `large` del footer |
112
116
 
@@ -133,7 +137,7 @@ valor del campo.
133
137
  | input | tipo | default |
134
138
  |---|---|---|
135
139
  | `size` | `'xsmall' \| 'small' \| 'medium' \| 'large' \| 'xlarge'` | `'medium'` |
136
- | `placeholder` | `string` | `'Seleccionar...'` |
140
+ | `placeholder` | `string` | `'Elige…'` |
137
141
  | `options` | `SuiSelectOption<T>[]` | `[]` |
138
142
  | `disabled` | `boolean` | `false` |
139
143
  | `error` | `boolean` | `false` |
@@ -161,13 +165,16 @@ decoración propia del campo (gana sobre ícono, imagen y bandera).
161
165
  - **No busca y no es múltiple.** Con 40 opciones la lista se scrollea; con varias a elegir no sirve.
162
166
  - **Las opciones solo llevan texto**: `SuiSelectOption` no tiene ícono, foto ni bandera. El
163
167
  `type="avatar"` o `"country"` decora **el campo**, no la lista.
164
- - **El default del placeholder es «Seleccionar...»**: genérico y con `...`. Pásalo siempre.
168
+ - **El default del placeholder es «Elige…»** (genérico, desde el 04-10-2026): pásalo con el sustantivo cuando ayude («Elige el distrito»).
165
169
  - El `valueChange` puede traer `null`: los usos de hoy hacen `$event ?? ''`.
166
170
  - `T` arranca en `any`: tipa las opciones (`SuiSelectOption<string>[]`) para no arrastrar `any`
167
171
  a la pantalla.
168
172
  - Con 44 px por opción en mobile el panel muestra unas 4 opciones antes de scrollear (el alto
169
173
  máximo del panel no cambió).
170
174
  - El label también abre la lista al tocarlo.
175
+ - **Accesibilidad (04-10-2026)**: el combobox se nombra con el `label` (`aria-labelledby`; sin
176
+ label, con el placeholder), apunta al listbox abierto (`aria-controls`) y anuncia la opción
177
+ resaltada con las flechas (`aria-activedescendant`). Hint y error van en `aria-describedby`.
171
178
 
172
179
  ## Ejemplo
173
180