@ajuarezso/sui-design-system 0.24.1 → 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 (120) hide show
  1. package/docs/sui-accordion/README.md +85 -11
  2. package/docs/sui-activity-feed/README.md +65 -11
  3. package/docs/sui-activity-filter/README.md +54 -5
  4. package/docs/sui-alert/README.md +54 -0
  5. package/docs/sui-app-store-badge/README.md +64 -10
  6. package/docs/sui-avatar/README.md +92 -29
  7. package/docs/sui-avatar-group/README.md +75 -9
  8. package/docs/sui-badge/README.md +85 -17
  9. package/docs/sui-banner/README.md +85 -20
  10. package/docs/sui-brand-logo/README.md +95 -31
  11. package/docs/sui-breadcrumb-item/README.md +54 -3
  12. package/docs/sui-breadcrumbs/README.md +54 -6
  13. package/docs/sui-button/README.md +76 -12
  14. package/docs/sui-button-group/README.md +91 -23
  15. package/docs/sui-button-group-item/README.md +81 -14
  16. package/docs/sui-card/README.md +105 -18
  17. package/docs/sui-chart-legend/README.md +63 -10
  18. package/docs/sui-chart-legend-dot/README.md +59 -10
  19. package/docs/sui-checkbox/README.md +109 -29
  20. package/docs/sui-checkbox-card/README.md +70 -14
  21. package/docs/sui-checkbox-label/README.md +92 -26
  22. package/docs/sui-circular-progress-bar/README.md +80 -19
  23. package/docs/sui-color-dot/README.md +72 -12
  24. package/docs/sui-color-picker/README.md +71 -13
  25. package/docs/sui-command-menu-footer/README.md +50 -1
  26. package/docs/sui-command-menu-item/README.md +74 -14
  27. package/docs/sui-command-menu-search/README.md +58 -3
  28. package/docs/sui-compact-avatar-group/README.md +73 -13
  29. package/docs/sui-compact-button/README.md +123 -34
  30. package/docs/sui-compact-select/README.md +61 -7
  31. package/docs/sui-compact-select-for-input/README.md +70 -6
  32. package/docs/sui-content-card/README.md +75 -14
  33. package/docs/sui-content-divider/README.md +67 -16
  34. package/docs/sui-content-label/README.md +99 -20
  35. package/docs/sui-counter-input/README.md +102 -18
  36. package/docs/sui-date-selector/README.md +69 -11
  37. package/docs/sui-datepicker/README.md +85 -18
  38. package/docs/sui-day-cell/README.md +75 -17
  39. package/docs/sui-day-label/README.md +56 -7
  40. package/docs/sui-divider/README.md +64 -9
  41. package/docs/sui-drawer-footer/README.md +63 -2
  42. package/docs/sui-drawer-header/README.md +69 -12
  43. package/docs/sui-dropdown-caption/README.md +58 -6
  44. package/docs/sui-dropdown-item/README.md +75 -9
  45. package/docs/sui-dropdown-menu/README.md +83 -14
  46. package/docs/sui-dropdown-search/README.md +60 -4
  47. package/docs/sui-emoji/README.md +94 -30
  48. package/docs/sui-empty-state/README.md +71 -7
  49. package/docs/sui-fancy-button/README.md +74 -14
  50. package/docs/sui-file-icon/README.md +70 -12
  51. package/docs/sui-file-upload/README.md +77 -17
  52. package/docs/sui-file-upload-card/README.md +64 -12
  53. package/docs/sui-filter/README.md +83 -14
  54. package/docs/sui-flag/README.md +73 -8
  55. package/docs/sui-form-hint/README.md +56 -7
  56. package/docs/sui-form-label/README.md +57 -5
  57. package/docs/sui-href/README.md +47 -0
  58. package/docs/sui-icon/README.md +86 -18
  59. package/docs/sui-image-upload/README.md +90 -22
  60. package/docs/sui-image-upload-profile/README.md +70 -11
  61. package/docs/sui-img-retry/README.md +50 -1
  62. package/docs/sui-inline-input/README.md +67 -9
  63. package/docs/sui-inline-select/README.md +62 -2
  64. package/docs/sui-input/README.md +90 -27
  65. package/docs/sui-integration-switch/README.md +84 -17
  66. package/docs/sui-kbd/README.md +73 -9
  67. package/docs/sui-key-icon/README.md +85 -23
  68. package/docs/sui-link-button/README.md +96 -27
  69. package/docs/sui-logo/README.md +93 -22
  70. package/docs/sui-modal/README.md +72 -13
  71. package/docs/sui-modal-footer/README.md +86 -12
  72. package/docs/sui-modal-header/README.md +57 -1
  73. package/docs/sui-modal-sheet/README.md +74 -12
  74. package/docs/sui-notification/README.md +81 -11
  75. package/docs/sui-notification-footer/README.md +55 -5
  76. package/docs/sui-notification-tab-menu/README.md +61 -5
  77. package/docs/sui-otp-input/README.md +70 -9
  78. package/docs/sui-page-header/README.md +89 -19
  79. package/docs/sui-pagination/README.md +73 -13
  80. package/docs/sui-password-strength/README.md +50 -1
  81. package/docs/sui-payment-icon/README.md +80 -18
  82. package/docs/sui-period-range/README.md +70 -11
  83. package/docs/sui-popover/README.md +81 -15
  84. package/docs/sui-product-card/README.md +89 -21
  85. package/docs/sui-progress-bar/README.md +82 -15
  86. package/docs/sui-progress-bar-label/README.md +79 -18
  87. package/docs/sui-radio/README.md +84 -7
  88. package/docs/sui-radio-card/README.md +70 -16
  89. package/docs/sui-radio-label/README.md +89 -22
  90. package/docs/sui-rating/README.md +101 -31
  91. package/docs/sui-rich-editor/README.md +47 -2
  92. package/docs/sui-segmented-control/README.md +90 -21
  93. package/docs/sui-select/README.md +80 -11
  94. package/docs/sui-sidebar/README.md +71 -16
  95. package/docs/sui-slider/README.md +75 -8
  96. package/docs/sui-social-button/README.md +71 -11
  97. package/docs/sui-status-badge/README.md +75 -14
  98. package/docs/sui-stepper/README.md +75 -18
  99. package/docs/sui-store-card/README.md +85 -22
  100. package/docs/sui-switch/README.md +82 -11
  101. package/docs/sui-switch-card/README.md +80 -16
  102. package/docs/sui-switch-label/README.md +91 -14
  103. package/docs/sui-tab-chips/README.md +93 -21
  104. package/docs/sui-tab-menu-horizontal/README.md +68 -7
  105. package/docs/sui-tab-menu-vertical/README.md +64 -11
  106. package/docs/sui-table/README.md +77 -16
  107. package/docs/sui-tag/README.md +86 -12
  108. package/docs/sui-tag-input/README.md +77 -13
  109. package/docs/sui-textarea/README.md +84 -17
  110. package/docs/sui-time-picker/README.md +96 -33
  111. package/docs/sui-toast/README.md +81 -20
  112. package/docs/sui-tooltip/README.md +80 -22
  113. package/docs/sui-topbar/README.md +64 -10
  114. package/docs/sui-topbar-button/README.md +61 -7
  115. package/docs/sui-topbar-item/README.md +68 -7
  116. package/docs/sui-topbar-user/README.md +61 -5
  117. package/fesm2022/ajuarezso-sui-design-system.mjs +15 -10
  118. package/fesm2022/ajuarezso-sui-design-system.mjs.map +1 -1
  119. package/package.json +1 -1
  120. package/types/ajuarezso-sui-design-system.d.ts +7 -3
@@ -28,8 +28,8 @@ Regla corta: **se ajusta de a uno y tiene tope → counter · se tipea → input
28
28
  ## Qué variante usar
29
29
 
30
30
  > **La guía del DS lo muestra como un ejemplo de su página del input** (un campo «Counter Input*»
31
- > con − y + a los lados) y no dice cuándo usarlo. Todo lo de abajo es **propuesta, falta
32
- > aprobación**, salvo lo que se indica.
31
+ > con − y + a los lados) y no dice cuándo usarlo. Las reglas marcadas canon
32
+ > están aprobadas; lo que sigue en propuesta espera decisión.
33
33
  >
34
34
  > Uso medido el 04-10-2026 en `master-pedidos/src/app` (misma exclusión que `sui-badge`, más
35
35
  > `master-ejercicios`): **4 usos en 4 archivos**, todos con `min=1`. Tamaños: 2 `large`, 2
@@ -37,19 +37,27 @@ Regla corta: **se ajusta de a uno y tiene tope → counter · se tipea → input
37
37
 
38
38
  | prop | cuándo | fuente |
39
39
  |---|---|---|
40
- | `min` | `1` en cantidades de compra: en 1 el − se apaga y quitar queda en el tacho (evita borrar por error). | propuesta (ya es práctica en los 4 usos: `pages/customer/cart/cart.html:80`) |
41
- | `max` | Siempre el tope real: stock, tope por pedido, cupo del viaje. Sin dato, 99. | propuesta (ya es práctica: `pages/customer/restaurant-menu/restaurant-menu.html:479`) |
42
- | `step` | `1`. Otro paso no tiene caso hoy. | propuesta, falta aprobación |
40
+ | `min` | `1` en cantidades de compra: en 1 el − se apaga y quitar queda en el tacho (evita borrar por error). | canon (aprobado por el dueño, 05-10-2026, bloque B9; ya es práctica en los 4 usos: `pages/customer/cart/cart.html:80`) |
41
+ | `max` | Siempre el tope real: stock, tope por pedido, cupo del viaje. Sin dato, 99. | canon (aprobado por el dueño, 05-10-2026, bloque B9; ya es práctica: `pages/customer/restaurant-menu/restaurant-menu.html:479`) |
42
+ | `step` | `1`. Otro paso no tiene caso hoy. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
43
43
  | `label` | Cuando es un campo de un formulario («Pasajeros»). | según la guía del DS (su ejemplo lleva label) |
44
- | `hint` | El tope dicho en palabras: «Hasta 4 pasajeros». | propuesta (ya es práctica: `components/cambiar-pasajeros/cambiar-pasajeros.html:7`) |
45
- | `ariaLabel` | **Obligatorio si no hay `label`**: en el carrito o en una fila donde el texto está al lado. «Cantidad de Pollo a la brasa 1/4». | propuesta, falta aprobación |
46
- | `decrementLabel` / `incrementLabel` | Los defaults («Disminuir», «Aumentar») sirven. Cambiarlos solo si el contexto pide otro verbo («Quitar un pasajero»). | propuesta, falta aprobación |
47
- | `disabled` | El producto se agotó mientras estaba en el carrito. | propuesta, falta aprobación |
44
+ | `hint` | El tope dicho en palabras: «Hasta 4 pasajeros». | canon (aprobado por el dueño, 05-10-2026, bloque B4; ya es práctica: `components/cambiar-pasajeros/cambiar-pasajeros.html:7`) |
45
+ | `ariaLabel` | **Obligatorio si no hay `label`**: en el carrito o en una fila donde el texto está al lado. «Cantidad de Pollo a la brasa 1/4». | canon (aprobado por el dueño, 05-10-2026, bloque B5) |
46
+ | `decrementLabel` / `incrementLabel` | Los defaults («Disminuir», «Aumentar») sirven. Cambiarlos solo si el contexto pide otro verbo («Quitar un pasajero»). | default: canon (CANON-SUI §5.7: `Aumentar`/`Disminuir` se usan tal cual) · cambiarlos: propuesta, falta aprobación |
47
+ | `disabled` | El producto se agotó mientras estaba en el carrito. | canon (aprobado por el dueño, 05-10-2026, bloque B8) |
48
48
  | `error` + `errorMessage` | No usar hoy: el contador no deja salir del rango. | — |
49
49
  | `required` · `sublabel` · `tooltip` | No usar hoy: una cantidad siempre tiene valor. | — |
50
50
 
51
- **Usos de hoy que rompen la regla:** ninguno (medido el 04-10-2026). Los 2 sin nombre para el
52
- lector y los 2 en `medium` fijo en el teléfono se corrigieron en la app el 03-10-2026 (`f96cf735`).
51
+ **Usos de hoy que rompen la regla:** los 4, por el `size` (medido el 06-10-2026, D16): en el
52
+ teléfono van en `large`, con botones de 40, por debajo del piso de 44.
53
+ `pages/customer/restaurant-menu/restaurant-menu.html:479` y
54
+ `components/cambiar-pasajeros/cambiar-pasajeros.html:8` llevan `size="large"` fijo, pero no les
55
+ toca lo mismo: el de restaurant-menu va junto al CTA (`bp.tactil() ? 'xlarge' : 'large'`) y el de
56
+ cambiar-pasajeros es un campo de formulario dentro de un modal, con `label` y `hint`, que va como
57
+ una fila (`bp.tactil() ? 'xlarge' : 'medium'`). `pages/customer/cart/cart.html:77` y
58
+ `pages/customer/viaje/viaje.html:182` llevan `bp.isMobile() ? 'large' : 'medium'` (además la tablet
59
+ queda en `medium`); les toca `bp.tactil() ? 'xlarge' : 'medium'`. Los 2 sin nombre para el
60
+ lector y los 2 en `medium` fijo en el teléfono ya se habían corregido el 03-10-2026 (`f96cf735`).
53
61
 
54
62
  ## Tamaño en mobile y en web
55
63
 
@@ -74,19 +82,38 @@ en 40, por debajo del piso; no hace falta un size nuevo porque `xlarge` ya llega
74
82
 
75
83
  | uso | mobile | web | fuente |
76
84
  |---|---|---|---|
77
- | cantidad junto al CTA (detalle del producto) | `xlarge` (52, botones de 44) | `large` | mobile: canon (dueño, 04-10-2026): piso táctil 44 en el teléfono · web: propuesta |
78
- | cantidad en una fila (carrito, pasajeros) | `xlarge` (52, botones de 44) | `medium` (40) | mobile: canon (dueño, 04-10-2026): piso táctil 44 en el teléfono · web: propuesta, falta aprobación |
85
+ | cantidad junto al CTA (detalle del producto) | `xlarge` (52, botones de 44) | `large` | mobile: canon (dueño, 04-10-2026): piso táctil 44 en el teléfono · web: canon (aprobado por el dueño, 05-10-2026, bloque B1) |
86
+ | cantidad en una fila o campo de un formulario (carrito, pasajeros) | `xlarge` (52, botones de 44) | `medium` (40) | mobile: canon (dueño, 04-10-2026): piso táctil 44 en el teléfono · web: canon (aprobado por el dueño, 05-10-2026, bloque B1) |
79
87
 
80
88
  ```html
81
- <sui-counter-input [size]="bp.isMobile() ? 'xlarge' : 'medium'" … /> <!-- bp = BreakpointsService -->
89
+ <sui-counter-input [size]="bp.tactil() ? 'xlarge' : 'medium'" … /> <!-- en una fila · bp = BreakpointsService -->
90
+ <sui-counter-input [size]="bp.tactil() ? 'xlarge' : 'large'" … /> <!-- junto al CTA -->
82
91
  ```
83
92
 
93
+ ### Por dispositivo (D16)
94
+
95
+ Fila de D16 para `counter-input` (dueño, 05-10-2026). Se toca: donde hay dedo va `xlarge`, el
96
+ único size con botones de 44.
97
+
98
+ | dispositivo | size | nota |
99
+ |---|---|---|
100
+ | celular chico (< 380) | `xlarge` | no hay un `medium` con botones de 44, así que no baja como el resto de lo que se toca |
101
+ | celular (380–767) | `xlarge` | campo de 52, botones de 44 |
102
+ | tablet táctil (`pointer: coarse`) | `xlarge` | Apple pide 44 pt también en iPad |
103
+ | computadora (`pointer: fine`) | `large` junto al CTA · `medium` en una fila o en un formulario | con mouse no hace falta llegar a 44 |
104
+
105
+ Ultrawide: igual que la computadora.
106
+
107
+ En master-pedidos: no hay helper (`bp.sizeControl()` da `large`/`medium` y no llega a `xlarge`).
108
+ En una fila o en un formulario `[size]="bp.tactil() ? 'xlarge' : 'medium'"`; junto al CTA
109
+ `[size]="bp.tactil() ? 'xlarge' : 'large'"`.
110
+
84
111
  ## «No usar»: por qué no hoy y cuándo sí
85
112
 
86
113
  | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
87
114
  |---|---|---|
88
- | `size` `2xsmall`, `xsmall`, `small` | en la app la cantidad se toca con el dedo | una tabla del panel donde se ajusta el stock de varios productos |
89
- | `size="xlarge"` | el CTA de al lado es `large` | si el CTA del detalle pasa a `xlarge` |
115
+ | `size` `2xsmall`, `xsmall`, `small` | en la app la cantidad se toca con el dedo, y son chicos (D16, 05-10-2026) | nunca: una tabla del panel donde se ajusta el stock también va `medium` |
116
+ | `size="xlarge"` en la computadora | con mouse no hace falta llegar a 44: junto al CTA va `large` y en una fila `medium` (D16, dueño 05-10-2026). En celular y tablet sí va `xlarge` | — |
90
117
  | `step` distinto de 1 | no hay productos que se vendan de a varios | huevos por media docena, gaseosas por pack de 6 |
91
118
  | `error` | el contador no deja salir del rango | el stock bajó con el carrito abierto y la cantidad ya no alcanza |
92
119
  | `tooltip` · `sublabel` · `required` | una cantidad siempre tiene valor | — |
@@ -136,14 +163,71 @@ en 40, por debajo del piso; no hace falta un size nuevo porque `xlarge` ya llega
136
163
  mínimo/máximo, si están definidos) desde el 04-10-2026; antes solo se operaba con − y +.
137
164
  - El campo es una píldora (radio completo), decisión de SUI; el Figma de origen usa 10/8 px.
138
165
 
166
+ ## Bien y mal
167
+
168
+ **Cantidad junto al CTA del detalle**
169
+
170
+ ```html
171
+ <!-- ❌ mal: `large` fijo deja los botones en 40 en el teléfono (restaurant-menu.html:479) -->
172
+ <sui-counter-input size="large" ariaLabel="Cantidad" [min]="1" [max]="pdv.topeCantidad()"
173
+ [value]="pdv.qty()" (valueChange)="pdv.setQty($event)" />
174
+ ```
175
+
176
+ ```html
177
+ <!-- ✅ bien -->
178
+ <sui-counter-input [size]="bp.tactil() ? 'xlarge' : 'large'" ariaLabel="Cantidad" [min]="1"
179
+ [max]="pdv.topeCantidad()" [value]="pdv.qty()" (valueChange)="pdv.setQty($event)" />
180
+ ```
181
+
182
+ **Cantidad en una fila del carrito**
183
+
184
+ ```html
185
+ <!-- ❌ mal: `large` en el teléfono (botones de 40) y `medium` en la tablet (cart.html:77, viaje.html:182) -->
186
+ <sui-counter-input [size]="bp.isMobile() ? 'large' : 'medium'" [ariaLabel]="'Cantidad de ' + item.name"
187
+ [value]="item.quantity" [min]="1" [max]="99" (valueChange)="setQuantity(item.lineKey, $event)" />
188
+ ```
189
+
190
+ ```html
191
+ <!-- ✅ bien -->
192
+ <sui-counter-input [size]="bp.tactil() ? 'xlarge' : 'medium'" [ariaLabel]="'Cantidad de ' + item.name"
193
+ [value]="item.quantity" [min]="1" [max]="99" (valueChange)="setQuantity(item.lineKey, $event)" />
194
+ ```
195
+
196
+ **Campo de formulario con `large` fijo**
197
+
198
+ ```html
199
+ <!-- ❌ mal: `large` fijo deja los botones en 40 en el teléfono, y en la computadora no va junto a un CTA (cambiar-pasajeros.html:8) -->
200
+ <sui-counter-input size="large" label="Pasajeros" [hint]="cupoTexto()" [min]="1" [max]="cupo()"
201
+ [value]="pasajeros()" (valueChange)="pasajeros.set($event)" />
202
+ ```
203
+
204
+ ```html
205
+ <!-- ✅ bien: es un campo, va como una fila -->
206
+ <sui-counter-input [size]="bp.tactil() ? 'xlarge' : 'medium'" label="Pasajeros" [hint]="cupoTexto()"
207
+ [min]="1" [max]="cupo()" [value]="pasajeros()" (valueChange)="pasajeros.set($event)" />
208
+ ```
209
+
210
+ **Sin tope y sin `valueChange`**
211
+
212
+ ```html
213
+ <!-- ❌ mal: es controlado, el número no se mueve; y sin `min` baja a negativos (Trampas) -->
214
+ <sui-counter-input ariaLabel="Cantidad" [value]="cantidad()" />
215
+ ```
216
+
217
+ ```html
218
+ <!-- ✅ bien -->
219
+ <sui-counter-input ariaLabel="Cantidad" [min]="1" [max]="99"
220
+ [value]="cantidad()" (valueChange)="cantidad.set($event)" />
221
+ ```
222
+
139
223
  ## Ejemplo
140
224
 
141
225
  ```html
142
226
  <!-- En el detalle del producto, al lado del CTA -->
143
- <sui-counter-input size="large" [min]="1" [max]="pdv.topeCantidad()"
227
+ <sui-counter-input [size]="bp.tactil() ? 'xlarge' : 'large'" [min]="1" [max]="pdv.topeCantidad()"
144
228
  ariaLabel="Cantidad" [value]="pdv.qty()" (valueChange)="pdv.setQty($event)" />
145
229
 
146
230
  <!-- Campo de formulario -->
147
231
  <sui-counter-input label="Pasajeros" hint="Hasta 4 pasajeros" [min]="1" [max]="4"
148
- [size]="bp.isMobile() ? 'large' : 'medium'" [(value)]="pasajeros" />
232
+ [size]="bp.tactil() ? 'xlarge' : 'medium'" [(value)]="pasajeros" />
149
233
  ```
@@ -24,20 +24,20 @@ del mes, las ganancias del repartidor por mes).
24
24
 
25
25
  ## Qué variante usar
26
26
 
27
- > **La guía del DS no tiene página para este componente** (vive dentro del datepicker). Todo es
28
- > **propuesta, falta aprobación**.
27
+ > **La guía del DS no tiene página para este componente** (vive dentro del datepicker). Las
28
+ > reglas de uso quedaron aprobadas por el dueño (canon, 05-10-2026).
29
29
  >
30
30
  > Uso medido el 03-10-2026 en `master-pedidos/src/app`: **0 usos directos**. Lo usa por dentro
31
31
  > `sui-datepicker`.
32
32
 
33
33
  | input | valor | cuándo | fuente |
34
34
  |---|---|---|---|
35
- | `label` | texto | El período visible, con mayúscula inicial y sin abreviar: «Octubre 2026», «Semana del 6 al 12 de octubre». | propuesta |
36
- | `leftIcon` + `rightIcon` | `true` / `true` (default) | Lo normal: se puede ir atrás y adelante. | propuesta |
37
- | `rightIcon` | `false` | Ya se está en el período actual y no hay futuro que mirar (ganancias, gastos). Mejor que dejar la flecha y que no haga nada. | propuesta |
38
- | `leftIcon` | `false` | Ya se está en el primer período con datos (el mes en que se abrió el local). | propuesta |
39
- | los dos en `false` | — | No usar: sin flechas es un título; va un texto. | propuesta |
40
- | `disabled` | `true` | Mientras carga el período nuevo, para que no se encadenen toques. | propuesta |
35
+ | `label` | texto | El período visible, con mayúscula inicial y sin abreviar: «Octubre 2026», «Semana del 6 al 12 de octubre». | mayúscula inicial: canon (CANON-SUI §5.1, sentence case) · sin abreviar: canon (aprobado por el dueño, 05-10-2026, bloque B4) |
36
+ | `leftIcon` + `rightIcon` | `true` / `true` (default) | Lo normal: se puede ir atrás y adelante. | canon (aprobado por el dueño, 05-10-2026, bloque B8) |
37
+ | `rightIcon` | `false` | Ya se está en el período actual y no hay futuro que mirar (ganancias, gastos). Mejor que dejar la flecha y que no haga nada. | canon (aprobado por el dueño, 05-10-2026, bloque B8) |
38
+ | `leftIcon` | `false` | Ya se está en el primer período con datos (el mes en que se abrió el local). | canon (aprobado por el dueño, 05-10-2026, bloque B8) |
39
+ | los dos en `false` | — | No usar: sin flechas es un título; va un texto. | canon (aprobado por el dueño, 05-10-2026, bloque B8) |
40
+ | `disabled` | `true` | Mientras carga el período nuevo, para que no se encadenen toques. | canon (aprobado por el dueño, 05-10-2026, bloque B8) |
41
41
 
42
42
  Usos de hoy que rompen la regla: **0**.
43
43
 
@@ -53,13 +53,30 @@ Tiene `size`: **`medium`** (default, 288 × 36, flechas `sui-compact-button` de
53
53
  | `medium` (default) | 36 | 24 × 24 | 14/20 | web | medido (Figma 442:192) |
54
54
 
55
55
  ```html
56
- <sui-date-selector [size]="bp.isMobile() ? 'large' : 'medium'" label="Octubre 2026"
56
+ <sui-date-selector [size]="bp.tactil() ? 'large' : 'medium'" label="Octubre 2026"
57
57
  [rightIcon]="!esMesActual()" (prev)="mesAnterior()" (next)="mesSiguiente()" />
58
58
  ```
59
59
 
60
60
  Dentro del `sui-datepicker` `large` (y en mobile con `small`–`large`) el datepicker agranda las
61
61
  flechas a 40 por su cuenta; con `xlarge` usa este `size="large"` (44).
62
62
 
63
+ ### Por dispositivo (D16)
64
+
65
+ No está en la tabla por componente de D16; las flechas se tocan, así que va como **lo que se
66
+ toca** (dueño, 05-10-2026). `large` es el único size con flechas de 44.
67
+
68
+ | dispositivo | size | nota |
69
+ |---|---|---|
70
+ | celular chico (< 380) | `medium` + área 44 | interino: hoy `large`, porque el DS todavía no estira a 44 el área de las flechas de 24 del `medium` |
71
+ | celular (380–767) | `large` | barra de 52, flechas de 44 |
72
+ | tablet táctil (`pointer: coarse`) | `large` | Apple pide 44 pt también en iPad |
73
+ | computadora (`pointer: fine`) | `medium` | barra de 36, flechas de 24 |
74
+
75
+ Ultrawide: igual que la computadora; el ancho sigue fijo en 288.
76
+
77
+ En master-pedidos: `[size]="bp.tactil() ? 'large' : 'medium'"` (son los mismos literales que
78
+ devuelve `bp.sizeControl()`, que también sirve).
79
+
63
80
  ## «No usar»: por qué no hoy y cuándo sí
64
81
 
65
82
  | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
@@ -90,13 +107,54 @@ flechas a 40 por su cuenta; con `xlarge` usa este `size="large"` (44).
90
107
 
91
108
  - **`leftIcon` y `rightIcon` son booleanos**, no nombres de ícono: prenden o apagan las flechas.
92
109
  - **Ancho fijo de 288 px** (`max-width` incluido): no se estira con el contenedor.
93
- - Con una flecha apagada queda un hueco de 24 px para que el texto siga centrado.
110
+ - Con una flecha apagada queda un hueco del ancho de la flecha (24 px en `medium`, 44 en `large`)
111
+ para que el texto siga centrado.
94
112
  - El componente **no sabe de fechas**: el texto lo arma quien lo usa y las flechas solo emiten.
95
113
  - Los `aria-label` de las flechas dicen «Mes anterior» y «Mes siguiente» aunque el período sea
96
114
  una semana.
97
115
 
98
- ## Ejemplo
116
+ ## Bien y mal
117
+
118
+ **Las flechas en el teléfono**
119
+
120
+ ```html
121
+ <!-- ❌ mal: `medium` deja las flechas en 24 en el celular y la tablet -->
122
+ <sui-date-selector label="Octubre 2026" (prev)="mesAnterior()" (next)="mesSiguiente()" />
123
+ ```
124
+
125
+ ```html
126
+ <!-- ✅ bien -->
127
+ <sui-date-selector [size]="bp.tactil() ? 'large' : 'medium'" label="Octubre 2026"
128
+ (prev)="mesAnterior()" (next)="mesSiguiente()" />
129
+ ```
130
+
131
+ **Ya se está en el mes actual**
99
132
 
100
133
  ```html
134
+ <!-- ❌ mal: los dos en `false` es un título con fondo; y abrevia el mes («Qué variante usar») -->
135
+ <sui-date-selector label="Oct. 2026" [leftIcon]="false" [rightIcon]="false" />
136
+ ```
137
+
138
+ ```html
139
+ <!-- ✅ bien: se apaga solo la flecha que no lleva a nada -->
101
140
  <sui-date-selector label="Octubre 2026" [rightIcon]="false" (prev)="mesAnterior()" />
102
141
  ```
142
+
143
+ **Períodos fijos**
144
+
145
+ ```html
146
+ <!-- ❌ mal: «Hoy», «Esta semana», «Este mes» no se recorren con flechas («Cuándo no») -->
147
+ <sui-date-selector [label]="periodo()" (prev)="periodoAnterior()" (next)="periodoSiguiente()" />
148
+ ```
149
+
150
+ ```html
151
+ <!-- ✅ bien -->
152
+ <sui-segmented-control [tabs]="periodos" [(active)]="periodo" ariaLabel="Período" />
153
+ ```
154
+
155
+ ## Ejemplo
156
+
157
+ ```html
158
+ <sui-date-selector [size]="bp.tactil() ? 'large' : 'medium'" label="Octubre 2026"
159
+ [rightIcon]="false" (prev)="mesAnterior()" />
160
+ ```
@@ -35,7 +35,7 @@ type="date"` · día + franja de entrega → la hoja del checkout.**
35
35
  > **Lo que dice la guía del DS** (página del datepicker): sirve para elegir **una fecha o un rango
36
36
  > de fechas**, y trae tres ejemplos: **Popover** (se aplica al tocar el día), **Approval** (con
37
37
  > Cancelar/Aplicar: la fecha queda en espera hasta confirmar) y **Range** (rango con un solo mes a
38
- > la vista). No dice cuándo usar cada uno. El resto es **propuesta, falta aprobación**.
38
+ > la vista). No dice cuándo usar cada uno. Las reglas marcadas canon están aprobadas; lo que sigue en propuesta espera decisión.
39
39
  >
40
40
  > Uso medido el 03-10-2026 en `master-pedidos/src/app` (sin prototipos ni vitrinas): **0 usos**.
41
41
  > Las fechas de la app van con `sui-input type="date"` (7) y `type="datetime-local"` (1).
@@ -45,28 +45,28 @@ type="date"` · día + franja de entrega → la hoja del checkout.**
45
45
  | valor | cuándo | fuente |
46
46
  |---|---|---|
47
47
  | `date` (default) | Una fecha cuando el calendario tiene que verse (en línea, con días marcados). Si es un campo de formulario, va `sui-input type="date"`. | guía (una fecha) · el «cuándo» es propuesta |
48
- | `range` | Un período libre desde–hasta: reportes, filtros de ventas o de gastos con «Personalizado». | guía (rango) · el «cuándo» es propuesta |
48
+ | `range` | Un período libre desde–hasta: reportes, filtros de ventas o de gastos con «Personalizado». | guía (rango) · el «cuándo»: canon (aprobado por el dueño, 05-10-2026, bloque B2) |
49
49
 
50
50
  ### `inline`, `showFooter`, `calendars`
51
51
 
52
52
  | input | valor | cuándo | fuente |
53
53
  |---|---|---|---|
54
54
  | `inline` | `false` (default) | El campo abre el calendario en un popover. Solo en web. | guía (ejemplo Popover) |
55
- | `inline` | `true` | El calendario es el contenido: un panel de disponibilidad o el calendario de pedidos del día. También dentro de un `sui-modal` en mobile, para no depender del popover. | propuesta |
55
+ | `inline` | `true` | El calendario es el contenido: un panel de disponibilidad o el calendario de pedidos del día. También dentro de un `sui-modal` en mobile, para no depender del popover. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
56
56
  | `showFooter` | `true` (default) | Cancelar/Aplicar: la elección no se guarda hasta confirmar. Úsalo cuando cambiar la fecha recalcula algo caro (un reporte). | guía (ejemplo Approval) |
57
57
  | `showFooter` | `false` | Se aplica al tocar el día. Fecha única y nada que recalcular. En `range` no tiene efecto: el rango siempre trae footer. | guía (ejemplo Popover) |
58
- | `calendars` | `2` (default) | Rango en web: dos meses lado a lado (936 px). | propuesta |
59
- | `calendars` | `1` | Rango en un espacio angosto (columna, modal `medium`). En mobile se fuerza a 1 solo. | guía (Range con un mes) |
58
+ | `calendars` | `2` (default) | Rango en web: dos meses lado a lado (936 px). | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
59
+ | `calendars` | `1` | Rango en un espacio angosto (columna, modal `medium`, tablet en vertical: los 936 px necesitan ≥ 968 de ancho). En mobile (≤ 767) se fuerza a 1 solo; en tablet hay que pasarlo. | guía (Range con un mes) |
60
60
 
61
61
  ### `min`, `max`, `markedDates`, `presets`, `placeholder`, `disabled`
62
62
 
63
63
  | input | cuándo | fuente |
64
64
  |---|---|---|
65
- | `min` / `max` | Siempre que haya un límite real: un cupón no vence en el pasado (`min` = hoy), un reporte no pasa de hoy (`max` = hoy). Los presets se recortan al límite. | propuesta |
66
- | `markedDates` | Días con algo: pedidos programados, gastos cargados. El punto es chico: dice «hay algo», no cuánto. | propuesta |
67
- | `presets` | Los 8 de fábrica están en español (Hoy, Últimos 7 días… Todo el tiempo). Recortarlos a los que la pantalla usa: un reporte del local no necesita «Últimos 12 meses» si no hay datos de hace un año. | propuesta |
68
- | `placeholder` | El default «Seleccionar fecha» ya está en español y se usa tal cual. Cambiarlo por lo que se elige («Elige el período», «Desde cuándo») es propuesta: hoy choca con esa regla. | default: canon (CANON-SUI §5.7) · cambiarlo: propuesta, falta aprobación |
69
- | `disabled` | Mientras carga lo que depende de la fecha. | propuesta |
65
+ | `min` / `max` | Siempre que haya un límite real: un cupón no vence en el pasado (`min` = hoy), un reporte no pasa de hoy (`max` = hoy). Los presets se recortan al límite. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
66
+ | `markedDates` | Días con algo: pedidos programados, gastos cargados. El punto es chico: dice «hay algo», no cuánto. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
67
+ | `presets` | Los 8 de fábrica están en español (Hoy, Últimos 7 días… Todo el tiempo). Recortarlos a los que la pantalla usa: un reporte del local no necesita «Últimos 12 meses» si no hay datos de hace un año. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
68
+ | `placeholder` | Sin pasarlo, el campo dice «Elige una fecha» (`mode="date"`) o «Elige el período» (`mode="range"`), en imperativo con tuteo. Cambiarlo solo para decir qué se elige, también en imperativo («Elige desde cuándo»). | canon (dueño, 05-10-2026, P4 a); el default cambió en la 0.25.0 (antes «Seleccionar fecha» en los dos modos). CANON-SUI §5.7 (infinitivo) necesita esta excepción en master-pedidos |
69
+ | `disabled` | Mientras carga lo que depende de la fecha. | canon (aprobado por el dueño, 05-10-2026, bloque B8) |
70
70
 
71
71
  Usos de hoy que rompen la regla: **0** (no hay datepickers). Los 8 campos de fecha son fechas
72
72
  sueltas en formularios y ya usan `sui-input` (líneas del `type`, medidas el 04-10-2026):
@@ -86,14 +86,14 @@ sueltas en formularios y ya usan `sui-input` (líneas del `type`, medidas el 04-
86
86
 
87
87
  En mobile se toca con el dedo: lo que se toca mide **44 px o más** (canon del dueño, 04-10-2026).
88
88
  Para eso está **`xlarge`**: con los otros sizes las celdas de día (40) y los presets (36) no llegan.
89
- En web, con mouse, puede ir más chico. En pantallas de los dos se elige con el servicio de breakpoints
90
- de la app (`bp`, en `services/breakpoints.service.ts`).
89
+ En la computadora va `medium`, nunca `small`; la tablet va como el celular (canon, dueño, 05-10-2026, D16). En pantallas de los
90
+ dos se elige con el servicio de breakpoints de la app (`bp`, en `services/breakpoints.service.ts`).
91
91
 
92
92
  Tiene `size` para el campo: `small` (36), `medium` (40, default, el de siempre), **`large` (48)**,
93
93
  el mismo alto que `sui-input` y `sui-select` `large`, y **`xlarge` (52)**, el de `sui-input` `xlarge`.
94
94
  Con `large` **y siempre en mobile (≤ 767 px)** el panel también crece: **flechas de mes de 40** y
95
95
  **Cancelar / Aplicar en `large` (48)**. Con **`xlarge`** todo lo que se toca llega a 44: **días de
96
- 44 × 44** (`sui-day-cell` `large`, gap 4: 7 × 44 + 6 × 4 = 332, entra en 390), **flechas de mes de
96
+ 44 × 44** (`sui-day-cell` `large`, gap 4: grilla de 7 × 44 + 6 × 4 = 332, panel de 358 con padding y borde: entra en una pantalla de 390, y dentro de un modal fullscreen solo con `[fullBody]`, ver «Por dispositivo»), **flechas de mes de
97
97
  44** (`sui-date-selector` `large`, barra de 52) y **rangos predefinidos de 44** (`sui-period-range`
98
98
  `large`). En el teléfono el footer del rango pone el resumen «Rango: …» arriba y los dos botones
99
99
  abajo, 50/50.
@@ -112,18 +112,42 @@ campo (y su placeholder) va en 16/24. Con `large` el calendario no cambia (días
112
112
  `large`). El resumen del rango sigue en 14.
113
113
 
114
114
  ```html
115
- <!-- Web: popover. Mobile: en línea dentro de un sui-modal fullscreen. -->
115
+ <!-- Web: popover. Mobile: en línea dentro de un sui-modal fullscreen con [fullBody]="true"
116
+ (sin él el body deja ancho − 56 y el panel de 358 no entra; ver «Por dispositivo»). -->
116
117
  @if (bp.isMobile()) {
117
118
  <sui-datepicker mode="range" size="xlarge" [inline]="true" [calendars]="1" [(value)]="rango" />
118
119
  } @else {
119
- <sui-datepicker mode="range" placeholder="Elige el período" [(value)]="rango" />
120
+ <sui-datepicker mode="range" [size]="bp.tactil() ? 'xlarge' : 'medium'"
121
+ [calendars]="bp.isTablet() ? 1 : 2"
122
+ placeholder="Elige el período" [(value)]="rango" />
120
123
  }
121
124
  ```
122
125
 
123
126
  | uso | mobile | web | fuente |
124
127
  |---|---|---|---|
125
- | fecha en un formulario | `xlarge` (días de 44) | `medium` | canon (dueño, 04-10-2026): piso táctil 44 en el teléfono (el «web medium» es propuesta) |
126
- | filtro de período de un reporte | `xlarge`, en línea dentro de un modal | `medium`, popover | canon (dueño, 04-10-2026): piso táctil 44 en el teléfono (el «web medium» es propuesta) |
128
+ | fecha en un formulario | `xlarge` (días de 44) | `medium` | mobile: canon (dueño, 04-10-2026): piso táctil 44 en el teléfono · web: canon (aprobado por el dueño, 05-10-2026, bloque B1) |
129
+ | filtro de período de un reporte | `xlarge`, en línea dentro de un modal con `[fullBody]` | `medium`, popover | mobile: canon (dueño, 04-10-2026): piso táctil 44 en el teléfono · web: canon (aprobado por el dueño, 05-10-2026, bloque B1) |
130
+
131
+ ### Por dispositivo (D16)
132
+
133
+ El datepicker tiene fila propia en D16: los días solo llegan a 44 en `xlarge`, así que todo
134
+ dispositivo táctil va en `xlarge`, también el celular chico.
135
+
136
+ | dispositivo | size | nota |
137
+ |---|---|---|
138
+ | celular chico (< 380) | `xlarge` | **no entra en 360 hoy** (en 375 solo `mode="date"` con `[fullBody]`, por 1 px). La grilla de días mide 332 (7 × 44 + 6 × 4), pero el panel mide **358** (332 + 2 × 12 de padding + borde). Dentro de un `sui-modal` fullscreen el body deja `ancho − 56` (8 de inset y 20 de padding por lado): 304 en 360. Con `[fullBody]="true"` deja `ancho − 16`: 344 en 360, 359 en 375. En `range` además el panel se fija en `ancho − 32` (328 en 360, 343 en 375) y recorta el domingo. Pendiente: que quepa en 360 es código del DS (gap o padding del calendario), no del README |
139
+ | celular (380–767) | `xlarge` | en línea dentro de un `sui-modal` fullscreen **con `[fullBody]="true"`**: sin él el body deja 334 en 390 y el panel de 358 se sale. Con él quedan 374 en 390. Se fuerza a 1 calendario |
140
+ | tablet táctil (`pointer: coarse`) | `xlarge` | popover. En `mode="date"` el panel mide 368 y entra desde 768. En `range` con 2 calendarios mide 936 (200 + 2 × 368) y necesita ≥ 968 de ancho: un iPad en vertical (820–834) lo recorta, así que va con `[calendars]="1"` (200 + 368 = 568). Los días, flechas y rangos llegan a 44 por el `size`, no por el ancho |
141
+ | computadora (`pointer: fine`) | `medium` | popover. Ojo: con `medium` el componente pinta Cancelar / Aplicar en `small` (36) por dentro (`footerButtonSize()`); D16 no deja nada en `small`, pero cambiarlo es código del DS, no del README |
142
+
143
+ Ultrawide: igual que la computadora; el rango ya ocupa sus dos meses (936 px) y el espacio extra no
144
+ agranda nada. Fuente: D16, dueño 05-10-2026.
145
+
146
+ En master-pedidos: `[size]="bp.tactil() ? 'xlarge' : 'medium'"` (no hay helper que dé
147
+ `xlarge`/`medium`). `bp.isMobile()` decide solo si va en línea o en popover, que es cuestión de
148
+ ancho, no de puntero. En `range` fuera del celular, `[calendars]="bp.isTablet() ? 1 : 2"`: el
149
+ componente solo baja a 1 calendario por su cuenta hasta 767. `isTablet()` es hasta 1024, un poco
150
+ conservador (en 1024 los dos meses sí entran), pero es la señal que tiene el servicio.
127
151
 
128
152
  ## «No usar»: por qué no hoy y cuándo sí
129
153
 
@@ -149,7 +173,7 @@ en la columna de la derecha, se usa (aprobado por el dueño, 03-10-2026).
149
173
  | `calendars` | `1 \| 2` | `2` |
150
174
  | `inline` | `boolean` | `false` |
151
175
  | `size` | `'small' \| 'medium' \| 'large' \| 'xlarge'` | `'medium'` |
152
- | `placeholder` | `string` | `'Seleccionar fecha'` |
176
+ | `placeholder` | `string \| null` | `null` |
153
177
  | `showFooter` | `boolean` | `true` |
154
178
  | `disabled` | `boolean` | `false` |
155
179
  | `min` | `Date \| null` | `null` |
@@ -198,6 +222,49 @@ interface DatepickerPreset { id: DatepickerPresetId; label: string; resolve: (ho
198
222
  - Las piezas internas son `sui-date-selector`, `sui-day-label`, `sui-day-cell` y
199
223
  `sui-period-range`: no se arman a mano.
200
224
 
225
+ ## Bien y mal
226
+
227
+ Una fecha suelta en un formulario
228
+
229
+ ```html
230
+ <!-- ❌ mal: un popover de 368 px para un campo «Válido hasta» (Cuándo no) -->
231
+ <sui-form-label label="Válido hasta" />
232
+ <sui-datepicker [min]="hoy" [(value)]="venceEl" />
233
+ ```
234
+
235
+ ```html
236
+ <!-- ✅ bien -->
237
+ <sui-input type="date" label="Válido hasta" [size]="bp.sizeControl()" [(value)]="venceEl" />
238
+ ```
239
+
240
+ Período en el celular
241
+
242
+ ```html
243
+ <!-- ❌ mal: en el celular el popover no es hoja (Trampas), y en medium los días miden 40
244
+ (Tamaño en mobile y en web) -->
245
+ <sui-datepicker mode="range" [(value)]="rango" />
246
+ ```
247
+
248
+ ```html
249
+ <!-- ✅ bien: [fullBody] porque el panel xlarge mide 358 y el body con padding deja 334 en 390.
250
+ En < 380 todavía no entra (pendiente del DS, ver «Por dispositivo») -->
251
+ <sui-modal [(open)]="eligiendo" [fullscreen]="true" [fullBody]="true" title="Elige el período">
252
+ <sui-datepicker mode="range" size="xlarge" [inline]="true" [calendars]="1" [(value)]="rango" />
253
+ </sui-modal>
254
+ ```
255
+
256
+ Rango que se aplica al tocar
257
+
258
+ ```html
259
+ <!-- ❌ mal: en range el footer sale igual; showFooter no tiene efecto (Trampas) -->
260
+ <sui-datepicker mode="range" [showFooter]="false" [(value)]="rango" />
261
+ ```
262
+
263
+ ```html
264
+ <!-- ✅ bien: el rango siempre confirma con Aplicar; [showFooter]="false" es solo para mode="date" -->
265
+ <sui-datepicker mode="range" [max]="hoy" [(value)]="rango" />
266
+ ```
267
+
201
268
  ## Ejemplo
202
269
 
203
270
  ```html
@@ -22,8 +22,9 @@ de la semana con los días de turno del repartidor, o un mes con los días que e
22
22
 
23
23
  ## Qué variante usar
24
24
 
25
- > **La guía del DS no tiene página para este componente** (vive dentro del datepicker). Todo es
26
- > **propuesta, falta aprobación**.
25
+ > **La guía del DS no tiene página para este componente** (vive dentro del datepicker). Las
26
+ > filas que describen lo que el componente ya hace van «según el código»; las reglas marcadas canon
27
+ > están aprobadas.
27
28
  >
28
29
  > Uso medido el 03-10-2026 en `master-pedidos/src/app`: **0 usos directos**. Lo usa por dentro
29
30
  > `sui-datepicker`.
@@ -32,23 +33,23 @@ de la semana con los días de turno del repartidor, o un mes con los días que e
32
33
 
33
34
  | valor | cuándo | fuente |
34
35
  |---|---|---|
35
- | `type="basic"` (default) | Calendario de una fecha. | propuesta |
36
- | `type="range"` | Calendario de rango. Va con `rangePosition`. | propuesta |
37
- | `rangePosition="start"` | Primer día del rango (fondo naranja, esquina izquierda). | propuesta |
38
- | `rangePosition="end"` | Último día (fondo naranja, esquina derecha). | propuesta |
39
- | `rangePosition="in"` | Días del medio (texto naranja, sin fondo propio: la banda la pinta la fila). | propuesta |
40
- | `rangePosition=null` | Fuera del rango. | propuesta |
36
+ | `type="basic"` (default) | Calendario de una fecha. | según el código |
37
+ | `type="range"` | Calendario de rango. Va con `rangePosition`. | según el código |
38
+ | `rangePosition="start"` | Primer día del rango (fondo naranja, esquina izquierda). | según el código |
39
+ | `rangePosition="end"` | Último día (fondo naranja, esquina derecha). | según el código |
40
+ | `rangePosition="in"` | Días del medio (texto naranja, sin fondo propio: la banda la pinta la fila). | según el código |
41
+ | `rangePosition=null` | Fuera del rango. | según el código |
41
42
 
42
43
  ### Estados
43
44
 
44
45
  | input | cuándo | fuente |
45
46
  |---|---|---|
46
- | `selected` | El día elegido (fondo naranja). Uno solo en `basic`. | propuesta |
47
- | `today` | Hoy: un punto debajo del número. Siempre, para que la persona se ubique. | propuesta |
48
- | `marked` | El día tiene algo (pedidos, un turno). Si además es hoy, gana el punto de hoy. | propuesta |
49
- | `disabled` | Fuera de `min`/`max` o no se puede elegir (local cerrado ese día). | propuesta |
50
- | `outOfMonth` | Días del mes anterior o siguiente que completan la grilla: se ven apagados. | propuesta |
51
- | `ariaLabel` | Siempre que el número solo no alcance: «Martes 7 de octubre, con pedidos». El default dice «Día 7». | propuesta |
47
+ | `selected` | El día elegido (fondo naranja). Uno solo en `basic`. | según el código |
48
+ | `today` | Hoy: un punto debajo del número. Siempre, para que la persona se ubique. | según el código |
49
+ | `marked` | El día tiene algo (pedidos, un turno). Si además es hoy, gana el punto de hoy. | según el código |
50
+ | `disabled` | Fuera de `min`/`max` o no se puede elegir (local cerrado ese día). | según el código |
51
+ | `outOfMonth` | Días del mes anterior o siguiente que completan la grilla: se ven apagados. | según el código |
52
+ | `ariaLabel` | Siempre que el número solo no alcance: «Martes 7 de octubre, con pedidos». El default dice «Día 7». | canon (aprobado por el dueño, 05-10-2026, bloque B5) |
52
53
 
53
54
  Usos de hoy que rompen la regla: **0**.
54
55
 
@@ -60,8 +61,8 @@ de 44 px en mobile (gap 4) y 48 en web (gap 8) con `medium`, y 48 (gap 4) con `l
60
61
 
61
62
  | size | celda | texto | uso | fuente |
62
63
  |---|---|---|---|---|
63
- | `large` | **44 × 44** | 16/24 | mobile: lo que se toca llega a 44 (en 390 entran 7 × 44 con gap 4 = 332) | canon (dueño, 04-10-2026): piso táctil 44 en el teléfono |
64
- | `medium` (default) | 40 × 40 | 14/20 | web | medido (Figma 437:174) |
64
+ | `large` | **44 × 44** | 16/24 | celular y tablet táctil: lo que se toca llega a 44 (en 390 entran 7 × 44 con gap 4 = 332) | canon (dueño, 04-10-2026): piso táctil 44 en el teléfono · tablet: D16, dueño 05-10-2026 |
65
+ | `medium` (default) | 40 × 40 | 14/20 | computadora | medido (Figma 437:174) |
65
66
 
66
67
  Los puntos de hoy y de marcado no cambian con el size.
67
68
 
@@ -69,12 +70,31 @@ Los puntos de hoy y de marcado no cambian con el size.
69
70
  <!-- La grilla da el paso: gap 4 -->
70
71
  <div class="semana" [style.gap.px]="4">
71
72
  @for (d of dias(); track d.fecha) {
72
- <sui-day-cell [size]="bp.isMobile() ? 'large' : 'medium'" [day]="d.numero" [today]="d.esHoy"
73
+ <sui-day-cell [size]="bp.tactil() ? 'large' : 'medium'" [day]="d.numero" [today]="d.esHoy"
73
74
  [marked]="d.conTurno" (clicked)="elegir(d)" />
74
75
  }
75
76
  </div>
76
77
  ```
77
78
 
79
+ ### Por dispositivo (D16)
80
+
81
+ La celda se toca: sigue «lo que se toca» de D16. Su size grande es `large` (44), el único que llega
82
+ al piso del dedo.
83
+
84
+ | dispositivo | size | nota |
85
+ |---|---|---|
86
+ | celular chico (< 380) | `large` | interino: D16 pide `medium` con área de 44, pero el DS todavía no la estira; 7 × 44 + 6 × 4 = 332 entra en 360 |
87
+ | celular (380–767) | `large` | gap 4 en la grilla |
88
+ | tablet táctil (`pointer: coarse`) | `large` | Apple pide 44 también en iPad |
89
+ | computadora (`pointer: fine`) | `medium` | 40 × 40, el de Figma |
90
+
91
+ Ultrawide: igual que la computadora. Fuente: D16, dueño 05-10-2026.
92
+
93
+ En master-pedidos: `[size]="bp.tactil() ? 'large' : 'medium'"`. `bp.sizeControl()` devuelve lo
94
+ mismo (`'large' | 'medium'`), pero está documentado para botón y campo; la expresión deja claro de
95
+ dónde sale. Si la grilla va con `sui-day-label`, la cabecera también tiene que medir 44 en `large`
96
+ (ver su README).
97
+
78
98
  ## «No usar»: por qué no hoy y cuándo sí
79
99
 
80
100
  | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
@@ -118,6 +138,44 @@ Los puntos de hoy y de marcado no cambian con el size.
118
138
  completa. Hoy lleva `aria-current="date"` y, en `type="range"`, `start`/`end` salen
119
139
  `aria-selected` (04-10-2026).
120
140
 
141
+ ## Bien y mal
142
+
143
+ El día de la grilla
144
+
145
+ ```html
146
+ <!-- ❌ mal: day es el número, no una fecha; la celda no sabe qué día es (Trampas) -->
147
+ <sui-day-cell [day]="d.fecha" [today]="true" />
148
+ ```
149
+
150
+ ```html
151
+ <!-- ✅ bien -->
152
+ <sui-day-cell [day]="d.fecha.getDate()" [today]="d.esHoy" [size]="bp.tactil() ? 'large' : 'medium'" />
153
+ ```
154
+
155
+ Días del mes vecino que no se eligen
156
+
157
+ ```html
158
+ <!-- ❌ mal: outOfMonth solo los apaga; se pueden tocar igual (Trampas) -->
159
+ <sui-day-cell [day]="d.numero" [outOfMonth]="true" (clicked)="elegir(d)" />
160
+ ```
161
+
162
+ ```html
163
+ <!-- ✅ bien -->
164
+ <sui-day-cell [day]="d.numero" [outOfMonth]="true" [disabled]="true" (clicked)="elegir(d)" />
165
+ ```
166
+
167
+ Un día con algo
168
+
169
+ ```html
170
+ <!-- ❌ mal: el lector de pantalla dice «Día 12», sin mes ni qué tiene (canon B5) -->
171
+ <sui-day-cell day="12" [marked]="true" />
172
+ ```
173
+
174
+ ```html
175
+ <!-- ✅ bien -->
176
+ <sui-day-cell day="12" [marked]="true" ariaLabel="Domingo 12 de octubre, con pedidos" />
177
+ ```
178
+
121
179
  ## Ejemplo
122
180
 
123
181
  ```html