@ajuarezso/sui-design-system 0.25.0 → 0.25.2

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 +83 -9
  2. package/docs/sui-activity-feed/README.md +55 -1
  3. package/docs/sui-activity-filter/README.md +50 -1
  4. package/docs/sui-alert/README.md +54 -0
  5. package/docs/sui-app-store-badge/README.md +57 -3
  6. package/docs/sui-avatar/README.md +66 -6
  7. package/docs/sui-avatar-group/README.md +64 -2
  8. package/docs/sui-badge/README.md +79 -11
  9. package/docs/sui-banner/README.md +70 -5
  10. package/docs/sui-brand-logo/README.md +77 -14
  11. package/docs/sui-breadcrumb-item/README.md +51 -0
  12. package/docs/sui-breadcrumbs/README.md +48 -0
  13. package/docs/sui-button/README.md +68 -6
  14. package/docs/sui-button-group/README.md +70 -5
  15. package/docs/sui-button-group-item/README.md +68 -4
  16. package/docs/sui-card/README.md +97 -10
  17. package/docs/sui-chart-legend/README.md +53 -0
  18. package/docs/sui-chart-legend-dot/README.md +49 -0
  19. package/docs/sui-checkbox/README.md +106 -26
  20. package/docs/sui-checkbox-card/README.md +58 -2
  21. package/docs/sui-checkbox-label/README.md +89 -23
  22. package/docs/sui-circular-progress-bar/README.md +63 -5
  23. package/docs/sui-color-dot/README.md +61 -5
  24. package/docs/sui-color-picker/README.md +62 -4
  25. package/docs/sui-command-menu-footer/README.md +49 -0
  26. package/docs/sui-command-menu-item/README.md +63 -4
  27. package/docs/sui-command-menu-search/README.md +58 -4
  28. package/docs/sui-compact-avatar-group/README.md +61 -4
  29. package/docs/sui-compact-button/README.md +112 -28
  30. package/docs/sui-compact-select/README.md +58 -4
  31. package/docs/sui-compact-select-for-input/README.md +69 -5
  32. package/docs/sui-content-card/README.md +63 -2
  33. package/docs/sui-content-divider/README.md +49 -1
  34. package/docs/sui-content-label/README.md +83 -4
  35. package/docs/sui-counter-input/README.md +91 -7
  36. package/docs/sui-date-selector/README.md +61 -3
  37. package/docs/sui-datepicker/README.md +72 -5
  38. package/docs/sui-day-cell/README.md +60 -3
  39. package/docs/sui-day-label/README.md +52 -3
  40. package/docs/sui-divider/README.md +57 -5
  41. package/docs/sui-drawer-footer/README.md +63 -2
  42. package/docs/sui-drawer-header/README.md +60 -3
  43. package/docs/sui-dropdown-caption/README.md +53 -1
  44. package/docs/sui-dropdown-item/README.md +72 -6
  45. package/docs/sui-dropdown-menu/README.md +74 -5
  46. package/docs/sui-dropdown-search/README.md +57 -1
  47. package/docs/sui-emoji/README.md +82 -18
  48. package/docs/sui-empty-state/README.md +68 -4
  49. package/docs/sui-fancy-button/README.md +59 -1
  50. package/docs/sui-file-icon/README.md +56 -1
  51. package/docs/sui-file-upload/README.md +69 -9
  52. package/docs/sui-file-upload-card/README.md +53 -2
  53. package/docs/sui-filter/README.md +74 -5
  54. package/docs/sui-flag/README.md +62 -1
  55. package/docs/sui-form-hint/README.md +54 -5
  56. package/docs/sui-form-label/README.md +53 -1
  57. package/docs/sui-href/README.md +47 -0
  58. package/docs/sui-icon/README.md +69 -4
  59. package/docs/sui-image-upload/README.md +70 -3
  60. package/docs/sui-image-upload-profile/README.md +58 -0
  61. package/docs/sui-img-retry/README.md +49 -0
  62. package/docs/sui-inline-input/README.md +61 -3
  63. package/docs/sui-inline-select/README.md +60 -0
  64. package/docs/sui-input/README.md +77 -14
  65. package/docs/sui-integration-switch/README.md +69 -2
  66. package/docs/sui-kbd/README.md +71 -7
  67. package/docs/sui-key-icon/README.md +65 -6
  68. package/docs/sui-link-button/README.md +79 -13
  69. package/docs/sui-logo/README.md +74 -4
  70. package/docs/sui-modal/README.md +61 -2
  71. package/docs/sui-modal-footer/README.md +83 -9
  72. package/docs/sui-modal-header/README.md +56 -0
  73. package/docs/sui-modal-sheet/README.md +72 -10
  74. package/docs/sui-notification/README.md +71 -1
  75. package/docs/sui-notification-footer/README.md +51 -1
  76. package/docs/sui-notification-tab-menu/README.md +57 -1
  77. package/docs/sui-otp-input/README.md +67 -6
  78. package/docs/sui-page-header/README.md +83 -15
  79. package/docs/sui-pagination/README.md +60 -0
  80. package/docs/sui-password-strength/README.md +50 -1
  81. package/docs/sui-payment-icon/README.md +66 -7
  82. package/docs/sui-period-range/README.md +65 -6
  83. package/docs/sui-popover/README.md +73 -7
  84. package/docs/sui-product-card/README.md +76 -8
  85. package/docs/sui-progress-bar/README.md +72 -8
  86. package/docs/sui-progress-bar-label/README.md +69 -12
  87. package/docs/sui-radio/README.md +83 -6
  88. package/docs/sui-radio-card/README.md +58 -4
  89. package/docs/sui-radio-label/README.md +86 -19
  90. package/docs/sui-rating/README.md +81 -14
  91. package/docs/sui-rich-editor/README.md +45 -0
  92. package/docs/sui-segmented-control/README.md +83 -14
  93. package/docs/sui-select/README.md +72 -3
  94. package/docs/sui-sidebar/README.md +64 -9
  95. package/docs/sui-slider/README.md +68 -1
  96. package/docs/sui-social-button/README.md +63 -3
  97. package/docs/sui-status-badge/README.md +64 -6
  98. package/docs/sui-stepper/README.md +57 -0
  99. package/docs/sui-store-card/README.md +71 -8
  100. package/docs/sui-switch/README.md +80 -9
  101. package/docs/sui-switch-card/README.md +70 -6
  102. package/docs/sui-switch-label/README.md +90 -13
  103. package/docs/sui-tab-chips/README.md +79 -9
  104. package/docs/sui-tab-menu-horizontal/README.md +62 -1
  105. package/docs/sui-tab-menu-vertical/README.md +56 -3
  106. package/docs/sui-table/README.md +68 -7
  107. package/docs/sui-tag/README.md +75 -4
  108. package/docs/sui-tag-input/README.md +71 -7
  109. package/docs/sui-textarea/README.md +78 -11
  110. package/docs/sui-time-picker/README.md +70 -7
  111. package/docs/sui-toast/README.md +65 -5
  112. package/docs/sui-tooltip/README.md +61 -4
  113. package/docs/sui-topbar/README.md +57 -3
  114. package/docs/sui-topbar-button/README.md +57 -3
  115. package/docs/sui-topbar-item/README.md +61 -0
  116. package/docs/sui-topbar-user/README.md +56 -0
  117. package/fesm2022/ajuarezso-sui-design-system.mjs +216 -227
  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 +68 -45
@@ -47,8 +47,9 @@ Regla corta: **código corto que llega por otro canal → otp · cupón o clave
47
47
 
48
48
  Tiene `size` (extensión SUI) para la celda. `large` es el de la guía y el default: **80 × 64** con 8
49
49
  px entre celdas (6 celdas = 520 px). Para el teléfono, **`medium` (52 × 56)**: 6 celdas miden 352
50
- px y entran en los 358 útiles de una pantalla de 390. `small` (44 × 48, dígito de 20) queda para
51
- 360 px o un código dentro de una tarjeta.
50
+ px y entran en los 358 útiles de una pantalla de 390. `small` (44 × 48, dígito de 20) **no se usa**:
51
+ en 360 px el `medium` se achica solo a unos 48 × 56 y sigue por encima de 44 (D16, dueño
52
+ 05-10-2026: nada en `small`; reemplaza el «`small` para 360 px» del 03-10-2026).
52
53
 
53
54
  Además, **el componente nunca es más ancho que su contenedor**: si las celdas no entran, se achican
54
55
  parejo en vez de salirse de la pantalla (un `large` de 6 en 390 queda en celdas de 53 × 64). Es la red
@@ -58,25 +59,45 @@ de seguridad, no el tamaño a elegir: se ve angosto y alto.
58
59
  |---|---|---|---|
59
60
  | `large` (default) | 80 × 64 · dígito 24 | 520 px | según la guía del DS |
60
61
  | `medium` | 52 × 56 · dígito 24 | 352 px | canon (aprobado por el dueño, 03-10-2026), extensión SUI |
61
- | `small` | 44 × 48 · dígito 20 | 304 px | canon (aprobado por el dueño, 03-10-2026), extensión SUI |
62
+ | `small` | 44 × 48 · dígito 20 | 304 px | canon (aprobado por el dueño, 03-10-2026), extensión SUI · no se usa: D16, dueño 05-10-2026 |
62
63
 
63
64
  | uso | mobile (390) | web | fuente |
64
65
  |---|---|---|---|
65
- | código de 6 dígitos | `medium` | `large` | canon (aprobado por el dueño, 05-10-2026, bloque B1) |
66
- | código de 4 dígitos | `large` (344 px, entra) | `large` | canon (aprobado por el dueño, 05-10-2026, bloque B1) |
66
+ | código de 6 dígitos | `medium` | `large` | canon (aprobado por el dueño, 05-10-2026, bloque B1) · la mitad web queda pendiente frente a D16 (ver «Por dispositivo») |
67
+ | código de 4 dígitos | `large` (344 px, entra) | `large` | canon (aprobado por el dueño, 05-10-2026, bloque B1) · la mitad web queda pendiente frente a D16 (ver «Por dispositivo») |
67
68
 
68
69
  ```html
69
70
  <sui-otp-input [length]="6" [size]="bp.isMobile() ? 'medium' : 'large'" [(value)]="codigo" />
70
71
  <!-- bp = BreakpointsService -->
71
72
  ```
72
73
 
74
+ ### Por dispositivo (D16)
75
+
76
+ Las celdas se tocan, pero aquí el `size` lo elige **el ancho** (que las celdas entren), no el
77
+ puntero: las tres miden 48 o más de alto, así que cualquiera se toca bien. Fuente: D16, dueño
78
+ 05-10-2026, y el bloque B1 (05-10-2026).
79
+
80
+ | dispositivo | size | nota |
81
+ |---|---|---|
82
+ | celular chico (< 380) | `medium` (6 dígitos) · `large` (4) | 6 `medium` no entran en los 328 útiles de 360: se achican solos a unos 48 × 56 y siguen tocables. Nada en `small` |
83
+ | celular (380–767) | `medium` (6 dígitos) · `large` (4) | 6 `medium` miden 352 y entran en los 358 útiles de 390; 4 `large` miden 344 |
84
+ | tablet táctil (`pointer: coarse`) | `large` desde 768 px · por debajo (iPad mini vertical, 744), como el celular: `medium` con 6 dígitos | aquí manda el ancho, no el puntero: es lo que da `bp.isMobile()` (hasta 767). Las dos celdas pasan los 44 |
85
+ | computadora (`pointer: fine`) | **pendiente** (`large` por ahora) | el bloque B1 (aprobado el 05-10-2026) dio `large` en web; la regla general de D16 (la misma tarde) da `medium` en lo que se toca. Pero el `medium` del otp es la celda angosta para que 6 entren en el teléfono (52 × 56), no un tamaño de escritorio. Falta que el dueño diga si D16 pisa a B1 aquí; mientras tanto se queda el `large` de B1, que es el default (interino) |
86
+
87
+ En el ultrawide, igual que en la computadora: el espacio extra no agranda las celdas.
88
+
89
+ En master-pedidos: `[size]="bp.isMobile() ? 'medium' : 'large'"` con 6 dígitos; con 4, sin `size`
90
+ (`large` es el default). El `'large'` de la computadora es el interino de B1 mientras la fila sigue
91
+ pendiente. No hay helper: `bp.sizeControl()` da `large` en el celular, y 6 celdas
92
+ `large` no entran.
93
+
73
94
  ## «No usar»: por qué no hoy y cuándo sí
74
95
 
75
96
  | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
76
97
  |---|---|---|
77
98
  | el componente entero (0 usos) | no hay verificación por código | verificar el teléfono del cliente por SMS, o un código de entrega de 4 dígitos que el cliente le dicta al repartidor |
78
99
  | `type="text"` | los códigos que llegan son numéricos | un código alfanumérico corto de una campaña |
79
- | `size="small"` | `medium` ya entra en 390 | pantallas de 360 px o un código dentro de una tarjeta |
100
+ | `size="small"` | `medium` ya entra en 390 | ninguno: en 360 px el `medium` se achica solo a 48 × 56 (D16, dueño 05-10-2026: nada en `small`) |
80
101
 
81
102
  ## API
82
103
 
@@ -108,6 +129,46 @@ de seguridad, no el tamaño a elegir: se ve angosto y alto.
108
129
  - `disabled` es un `model`: si el formulario lo deshabilita, el componente lo escribe de vuelta.
109
130
  - No hay grupos (3-3): si se necesitan, son dos componentes.
110
131
 
132
+ ## Bien y mal
133
+
134
+ Código de 6 dígitos en el teléfono
135
+
136
+ ```html
137
+ <!-- ❌ mal: sin size va large; 6 celdas de 80 no entran en 390 y se aplastan a 53 × 64. No hay usos en la app: la vitrina aún lo muestra así, marcado como propuesta y con la nota «falta una celda angosta en el DS», que ya existe (medium) (pages/super-admin/master-preview/_guia-moleculas/campos.ts:322) -->
138
+ <sui-otp-input [length]="6" ariaLabel="Código que te llegó por SMS" [(value)]="codigo" />
139
+ ```
140
+
141
+ ```html
142
+ <!-- ✅ bien -->
143
+ <sui-otp-input [length]="6" ariaLabel="Código que te llegó por SMS"
144
+ [size]="bp.isMobile() ? 'medium' : 'large'" [(value)]="codigo" />
145
+ ```
146
+
147
+ Código que no coincide
148
+
149
+ ```html
150
+ <!-- ❌ mal: error solo pinta las celdas; nadie dice qué pasó -->
151
+ <sui-otp-input [length]="4" ariaLabel="Código de entrega" [error]="codigoMalo()" [(value)]="codigo" />
152
+ ```
153
+
154
+ ```html
155
+ <!-- ✅ bien -->
156
+ <sui-otp-input [length]="4" ariaLabel="Código de entrega" [error]="codigoMalo()" [(value)]="codigo" />
157
+ @if (codigoMalo()) { <sui-form-hint variant="error" message="El código no coincide" /> }
158
+ ```
159
+
160
+ Un cupón con letras
161
+
162
+ ```html
163
+ <!-- ❌ mal: más de 6 caracteres y con letras no es un otp -->
164
+ <sui-otp-input [length]="8" type="text" ariaLabel="Cupón" [(value)]="cupon" />
165
+ ```
166
+
167
+ ```html
168
+ <!-- ✅ bien -->
169
+ <sui-input label="Cupón" [size]="bp.sizeControl()" [(value)]="cupon" />
170
+ ```
171
+
111
172
  ## Ejemplo
112
173
 
113
174
  ```html
@@ -30,10 +30,12 @@ toda la pantalla («Agregar», «Exportar»).
30
30
  > panel de empresa y no tiene Figma. Lo marcado **canon** sale de `master-pedidos/docs/CANON-SUI.md` o de la aprobación del dueño (05-10-2026);
31
31
  > lo marcado «componente» describe lo que el código ya hace. No queda nada en propuesta.
32
32
  >
33
- > Uso medido el 03-10-2026 en `master-pedidos/src/app`: 64 page headers, sin contar prototipos ni
34
- > vitrinas (`master-preview`, `master-prototipos`, `mockup-sheets-*`, `dx/*`, `master-rutina`,
35
- > `master-medico`, `dev-index`) ni las copias de `components/sui/`. 50 llevan `subtitle` fijo, 14
36
- > calculado; 17 tienen acciones; 0 usan `sticky`.
33
+ > Uso medido el 06-10-2026 en `master-pedidos/src/app`: 70 page headers en total y **66** sin contar
34
+ > prototipos ni vitrinas (1 en cada uno: `master-preview`, `master-prototipos`, `master-rutina` y
35
+ > `master-medico`; `mockup-sheets-*`, `dx/*`, `dev-index` y las copias de `components/sui/` no
36
+ > tienen). Un `grep` da 72 porque cuenta 2 comentarios (`master-preview.scss:1`, `envios.ts:923`).
37
+ > De los 66: 51 llevan `subtitle` fijo y 15 calculado; 17 tienen algo en
38
+ > `slot="actions"` (15 botones y 2 solo badges: `master-drivers`, `master-approvals`); 0 usan `sticky`.
37
39
 
38
40
  ### Lo que sí dice la guía del DS
39
41
 
@@ -46,10 +48,16 @@ escala del DS** (CANON-SUI §7): si se homologa, sería `title-h5`.
46
48
  |---|---|---|---|
47
49
  | `title` | El nombre de la pantalla, el mismo que en el menú. Sentence case, sin punto. Nunca un ID. | `pages/discounts/discounts.html:2` | canon (CANON-SUI, copy) |
48
50
  | `subtitle` | Una línea que dice **qué se hace aquí**, no que repite el título. | `pages/super-admin/master-orders/master-orders.html:1` | canon (aprobado por el dueño, 05-10-2026, bloque B4) |
49
- | acciones | Las que valen para toda la pantalla: una `filled` como máximo (la principal) y el resto `stroke`. Hoy: 9 `filled`, 7 `stroke`. | `pages/drivers/drivers.html:2` | canon (CANON-SUI §6.2: una sola primaria por pantalla; CLAUDE.md «Botones — composición y orden», 27-07-2026: uno solo `filled`, el secundario `stroke` `neutral`) |
51
+ | acciones | Las que valen para toda la pantalla: una `filled` como máximo (la principal) y el resto `stroke`. Hoy, de los 16 botones que se dibujan: 10 `filled` (uno por default, sin `variant`: `master-gastos.html:8`) y 6 `stroke`. | `pages/drivers/drivers.html:2` | canon (CANON-SUI §6.2: una sola primaria por pantalla; CLAUDE.md «Botones — composición y orden», 27-07-2026: uno solo `filled`, el secundario `stroke` `neutral`) |
50
52
 
51
- **Usos de hoy que rompen el copy canon** (sentence case en botones): `pages/drivers/drivers.html:8`
52
- («Nuevo Repartidor»).
53
+ **Usos de hoy que rompen** (medido el 06-10-2026):
54
+
55
+ - `pages/orders/orders.html:14`: el botón «Actualizar» va sin `slot="actions"`, así que no se
56
+ proyecta y no se dibuja en ningún ancho (ver «Bien y mal»).
57
+
58
+ Los cuatro botones en Title Case que había (`drivers.html:8`, `discounts.html:7`,
59
+ `employees.html:7`, `locations.html:7`) ya van en sentence case desde el commit `8b34d8ed`
60
+ (06-10-2026) de master-pedidos.
53
61
 
54
62
  ### `sticky`
55
63
 
@@ -70,17 +78,35 @@ El page header **no tiene `size`**. Cambia solo en 767 px:
70
78
  | padding lateral | ninguno: lo pone el contenedor del layout | igual | componente |
71
79
  | botones de las acciones | `large` (48) | `medium` (40) | mobile `large`: canon (decisión del dueño 04-10-2026, piso táctil 44) · web `medium`: canon (dueño, 05-10-2026, D16), reemplaza el `small` del bloque B1 |
72
80
 
73
- Los botones de las acciones hoy: 10 `small` fijos, 2 `bp.isMobile() ? 'large' : 'small'`, 2
74
- `bp.controlSize()` (`large`/`xlarge`), 2 `large`, 1 `medium`. En mobile, `large` es canon (piso táctil
75
- 44, 04-10-2026: `small` y `medium` no llegan); en la computadora va `medium` y la tablet va como el celular (canon, dueño,
76
- 05-10-2026, D16; reemplaza el `small` del bloque B1): en mobile las acciones bajan a su fila y tienen
77
- sitio para 48 px; en desktop van al lado del título de 28. Los 10 `small` fijos y los 2 pares con
78
- `small` se migran.
81
+ En mobile, `large` es canon (piso táctil 44, 04-10-2026: `small` y `medium` no llegan); en la
82
+ computadora va `medium` y la tablet va como el celular (canon, dueño, 05-10-2026, D16; reemplaza el
83
+ `small` del bloque B1): en mobile las acciones bajan a su fila y tienen sitio para 48 px; en desktop
84
+ van al lado del título de 28. Medido el 06-10-2026: 66 page headers (sin vitrinas ni prototipos),
85
+ 16 botones en las acciones, los 16 con `bp.sizeControl()` (ya no queda ningún `small`). Hay un
86
+ botón 17 dentro de un page header, también con `bp.sizeControl()`, pero va sin `slot="actions"` y no
87
+ se dibuja (`pages/orders/orders.html:14`).
79
88
 
80
89
  ```html
81
- <sui-button [size]="bp.isMobile() ? 'large' : 'medium'" slot="actions">Agregar</sui-button>
90
+ <sui-button [size]="bp.sizeControl()" slot="actions">Agregar</sui-button>
82
91
  ```
83
92
 
93
+ ### Por dispositivo (D16)
94
+
95
+ El header no tiene `size`: lo que cambia por dispositivo son **los botones de las acciones**, que
96
+ se tocan. Fuente: D16, dueño 05-10-2026 (fila `page-header (acciones)`).
97
+
98
+ | dispositivo | size | nota |
99
+ |---|---|---|
100
+ | celular chico (< 380) | `large` por ahora | D16 pide `medium` con área tocable de 44; el DS todavía no la estira, así que se queda el grande (interino) |
101
+ | celular (380–767) | `large` | las acciones bajan a su propia fila |
102
+ | tablet táctil (`pointer: coarse`) | `large` | Apple pide 44 también en el iPad; a 767 px o más las acciones ya van al lado del título |
103
+ | computadora (`pointer: fine`) | `medium` | al lado del título de 28 |
104
+
105
+ En el ultrawide, igual que en la computadora: el espacio extra no agranda los botones.
106
+
107
+ En master-pedidos: `[size]="bp.sizeControl()"` en cada `sui-button` de las acciones. No uses
108
+ `bp.isMobile() ? 'large' : 'medium'`: en el iPad `isMobile` es falso y el botón queda en 40.
109
+
84
110
  ## API
85
111
 
86
112
  <!-- api:inicio -->
@@ -113,12 +139,54 @@ Slot: `slot="actions"`, a la derecha (desktop) o debajo (mobile), gap 8. No hay
113
139
  - `title` es requerido: sin él, Angular falla al compilar la plantilla.
114
140
  - El host borra el atributo `title` nativo (sin tooltip gris del navegador).
115
141
 
142
+ ## Bien y mal
143
+
144
+ Botón de la pantalla
145
+
146
+ ```html
147
+ <!-- ❌ mal: sin slot="actions" el botón no se dibuja en ningún ancho (pages/orders/orders.html:14) -->
148
+ <sui-page-header title="Pedidos" subtitle="Lo que está en curso y todo lo que pasó por tu local.">
149
+ <sui-button variant="stroke" color="neutral" [size]="bp.sizeControl()" (click)="refresh()">Actualizar</sui-button>
150
+ </sui-page-header>
151
+ ```
152
+
153
+ ```html
154
+ <!-- ✅ bien -->
155
+ <sui-page-header title="Pedidos" subtitle="Lo que está en curso y todo lo que pasó por tu local.">
156
+ <sui-button slot="actions" variant="stroke" color="neutral" [size]="bp.sizeControl()" (click)="refresh()">Actualizar</sui-button>
157
+ </sui-page-header>
158
+ ```
159
+
160
+ Texto de la acción
161
+
162
+ ```html
163
+ <!-- ❌ mal: Title Case; los botones van en sentence case (así estaba pages/locations/locations.html:7 hasta el 06-10-2026) -->
164
+ <sui-button slot="actions" variant="filled" color="primary" [size]="bp.sizeControl()">Agregar Sucursal</sui-button>
165
+ ```
166
+
167
+ ```html
168
+ <!-- ✅ bien -->
169
+ <sui-button slot="actions" variant="filled" color="primary" [size]="bp.sizeControl()">Agregar sucursal</sui-button>
170
+ ```
171
+
172
+ Tamaño de la acción
173
+
174
+ ```html
175
+ <!-- ❌ mal: isMobile no mira el puntero; en el iPad el botón queda en medium (40) -->
176
+ <sui-button slot="actions" variant="filled" [size]="bp.isMobile() ? 'large' : 'medium'">Crear descuento</sui-button>
177
+ ```
178
+
179
+ ```html
180
+ <!-- ✅ bien -->
181
+ <sui-button slot="actions" variant="filled" [size]="bp.sizeControl()">Crear descuento</sui-button>
182
+ ```
183
+
116
184
  ## Ejemplo
117
185
 
118
186
  ```html
119
187
  <sui-page-header title="Descuentos" subtitle="Promociones y campañas activas de tu negocio.">
120
188
  <sui-button slot="actions" variant="filled"
121
- [size]="bp.isMobile() ? 'large' : 'medium'" (click)="crear()">
189
+ [size]="bp.sizeControl()" (click)="crear()">
122
190
  Crear descuento
123
191
  </sui-button>
124
192
  </sui-page-header>
@@ -89,6 +89,26 @@ mobile no se usa.
89
89
  }
90
90
  ```
91
91
 
92
+ ### Por dispositivo (D16)
93
+
94
+ Las celdas se tocan, pero ningún `size` llega a 44 (el más grande mide 32). Fuente: D16, dueño
95
+ 05-10-2026 (fila `pagination`).
96
+
97
+ | dispositivo | size | nota |
98
+ |---|---|---|
99
+ | celular chico (< 380) | no se usa | scroll infinito |
100
+ | celular (380–767) | no se usa | scroll infinito |
101
+ | tablet táctil (`pointer: coarse`) | **pendiente** | con 32 px tiene el mismo problema que en el celular: celdas por debajo de 44 para el dedo. Falta que el dueño decida qué va en la tablet |
102
+ | computadora (`pointer: fine`) | `medium` | también en un modal o panel angosto. `small` no se usa |
103
+
104
+ En el ultrawide, igual que en la computadora: el espacio extra va a más columnas de la tabla, no a
105
+ celdas más grandes.
106
+
107
+ En master-pedidos no hay helper: `size` no se pasa (`medium` es el default) y el componente va
108
+ dentro de `@if (!bp.isMobile())`. Ojo: con esa condición el iPad (768 px o más) **sí** lo muestra,
109
+ en 32 px; es justo el caso pendiente, y no se resuelve cambiando a `bp.tactil()` hasta que el dueño
110
+ decida.
111
+
92
112
  ## «No usar»: por qué no hoy y cuándo sí
93
113
 
94
114
  | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
@@ -142,6 +162,46 @@ type SuiPaginationInfoFormat = 'items' | 'pages';
142
162
  - **Con `total` en 0 no dibuja el texto**, pero sí los botones (una sola página «1»). Ocúltalo tú.
143
163
  - Las flechas son `<i class="ri-…">`: necesitan la fuente de Remix Icon cargada.
144
164
 
165
+ ## Bien y mal
166
+
167
+ Lista en el celular
168
+
169
+ ```html
170
+ <!-- ❌ mal: en el celular no se usa; las celdas de 32 no llegan a 44 -->
171
+ <sui-pagination [total]="filas().length" [(currentPage)]="pagina" [pageSize]="25" />
172
+ ```
173
+
174
+ ```html
175
+ <!-- ✅ bien -->
176
+ @if (!bp.isMobile()) {
177
+ <sui-pagination [total]="filas().length" [(currentPage)]="pagina" [pageSize]="25" />
178
+ }
179
+ ```
180
+
181
+ Tabla en un panel angosto
182
+
183
+ ```html
184
+ <!-- ❌ mal: small (28) no se usa; la vitrina aún lo marca como propuesta (pages/super-admin/master-preview/_guia-moleculas/navegacion.ts:169) -->
185
+ <sui-pagination [total]="134" [(currentPage)]="pagina" size="small" [showInfo]="false" />
186
+ ```
187
+
188
+ ```html
189
+ <!-- ✅ bien -->
190
+ <sui-pagination [total]="134" [(currentPage)]="pagina" [showInfo]="false" />
191
+ ```
192
+
193
+ Qué va en `total`
194
+
195
+ ```html
196
+ <!-- ❌ mal: total es la cantidad de ítems, no de páginas: con 6 páginas de 25 dibuja una sola -->
197
+ <sui-pagination [total]="paginas()" [(currentPage)]="pagina" [pageSize]="25" />
198
+ ```
199
+
200
+ ```html
201
+ <!-- ✅ bien -->
202
+ <sui-pagination [total]="filas().length" [(currentPage)]="pagina" [pageSize]="25" />
203
+ ```
204
+
145
205
  ## Ejemplo
146
206
 
147
207
  ```html
@@ -18,7 +18,7 @@ la barra se llena (rojo, naranja, verde) y cada condición se marca a medida que
18
18
 
19
19
  - El login: la contraseña ya existe, no se evalúa.
20
20
  - Una sola regla («Mínimo 6 caracteres»): alcanza el `hint` del `sui-input`, como hoy en
21
- `pages/auth/register/register.html:124`.
21
+ `pages/auth/register/register.html:132`.
22
22
 
23
23
  Regla corta: **contraseña nueva con 2+ reglas → este · una regla → hint.**
24
24
 
@@ -43,6 +43,12 @@ Regla corta: **contraseña nueva con 2+ reglas → este · una regla → hint.**
43
43
 
44
44
  No se toca: es texto (12 px) y una barra de 4 px a todo el ancho. **No necesita `bp`.**
45
45
 
46
+ ### Por dispositivo (D16)
47
+
48
+ No aplica: no tiene `size` y no se toca; mide lo mismo en el celular chico, el celular, la tablet,
49
+ la computadora y el ultrawide. Lo que sí cambia por dispositivo es el campo de arriba:
50
+ `sui-input` con `[size]="bp.sizeControl()"` (D16, dueño 05-10-2026).
51
+
46
52
  ## «No usar»: por qué no hoy y cuándo sí
47
53
 
48
54
  | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
@@ -89,6 +95,49 @@ interface SuiPasswordStrengthCondition {
89
95
  - `strengthChange` no emite el nivel inicial.
90
96
  - No incluye el campo: va debajo de un `sui-input type="password-toggle"`.
91
97
 
98
+ ## Bien y mal
99
+
100
+ Reglas de la contraseña
101
+
102
+ ```html
103
+ <!-- ❌ mal: sin conditions usa las default (8, mayúscula, número) y marca «débil» lo que el registro acepta. No hay usos en la app: la vitrina lo muestra a propósito como fila de «mal» (pages/super-admin/master-preview/_guia-moleculas/campos.ts:339) -->
104
+ <sui-password-strength [value]="clave()" />
105
+ ```
106
+
107
+ ```html
108
+ <!-- ✅ bien -->
109
+ <sui-password-strength [value]="clave()" [conditions]="reglas" />
110
+ ```
111
+
112
+ Una sola regla
113
+
114
+ ```html
115
+ <!-- ❌ mal: una barra de tres niveles para una sola condición -->
116
+ <sui-input label="Contraseña" type="password-toggle" [size]="bp.sizeControl()" [(value)]="clave" />
117
+ <sui-password-strength [value]="clave()" [conditions]="soloSeisCaracteres" />
118
+ ```
119
+
120
+ ```html
121
+ <!-- ✅ bien -->
122
+ <sui-input label="Contraseña" type="password-toggle" [size]="bp.sizeControl()"
123
+ hint="Mínimo 6 caracteres" [(value)]="clave" />
124
+ ```
125
+
126
+ En el login
127
+
128
+ ```html
129
+ <!-- ❌ mal: la contraseña ya existe; no hay nada que evaluar -->
130
+ <sui-input label="Contraseña" type="password-toggle" autocomplete="current-password"
131
+ [size]="bp.sizeControl()" [(value)]="clave" />
132
+ <sui-password-strength [value]="clave()" [conditions]="reglas" />
133
+ ```
134
+
135
+ ```html
136
+ <!-- ✅ bien -->
137
+ <sui-input label="Contraseña" type="password-toggle" autocomplete="current-password"
138
+ [size]="bp.sizeControl()" [(value)]="clave" />
139
+ ```
140
+
92
141
  ## Ejemplo
93
142
 
94
143
  ```html
@@ -52,11 +52,11 @@ Usos de hoy que rompen la regla: **0**.
52
52
 
53
53
  ## Tamaño en mobile y en web
54
54
 
55
- En mobile se lee y se toca con el dedo, así que va más grande; en web, más chico. En las
56
- pantallas que se usan en los dos (panel del local, super admin) se elige con el servicio de
57
- breakpoints de la app (`bp`, en `services/breakpoints.service.ts`); en las que solo existen en
58
- el celular (cliente, repartidor) va directo el valor de mobile. No se toca, así que la tablet va
59
- con el valor de web, y el celular chico (< 380 px) también (D16).
55
+ No se toca: es un ícono que se lee. Va un paso más grande en el celular de 380 px o más (`40`)
56
+ y más chico en la computadora (`32`); la tablet y el celular chico (< 380 px) van con el valor de
57
+ web (D16). Se elige siempre con el servicio de breakpoints de la app (`bp`, en
58
+ `services/breakpoints.service.ts`), **también en las pantallas que solo existen en el celular**
59
+ (cliente, repartidor): un `40` fijo ahí deja el celular chico con el valor de mobile.
60
60
  Es **canon (dueño, 05-10-2026, P1 b)**: un paso más grande en el celular que en computadora, y
61
61
  se migra todo ahora, no solo al tocar cada pantalla.
62
62
 
@@ -65,9 +65,28 @@ se migra todo ahora, no solo al tocar cada pantalla.
65
65
  | fila de una lista | `40` | `32` |
66
66
 
67
67
  ```html
68
- <sui-payment-icon type="electricity" [size]="bp.isMobile() ? 40 : 32" />
68
+ <sui-payment-icon type="electricity" [size]="bp.celular() ? 40 : 32" />
69
69
  ```
70
70
 
71
+ ### Por dispositivo (D16)
72
+
73
+ Fila `payment-icon` de la tabla D16 (dueño, 05-10-2026, P1 b): no se toca, así que sube un paso
74
+ **solo en el celular de 380 px o más**.
75
+
76
+ | dispositivo | size | nota |
77
+ |---|---|---|
78
+ | celular chico (< 380 px) | `32` | valor «web»: no se toca, no sube aunque sea un celular |
79
+ | celular (380–767 px) | `40` | valor «mobile», un paso más que en la computadora |
80
+ | tablet táctil (`pointer: coarse`) | `32` | valor «web»: el puntero no cambia lo que no se toca |
81
+ | computadora (`pointer: fine`) | `32` | |
82
+
83
+ Ultrawide (≥ 1920 px): igual que la computadora, `32`; el espacio extra va a más columnas, no a
84
+ íconos más grandes.
85
+
86
+ En master-pedidos: `[size]="bp.celular() ? 40 : 32"` (no hay helper propio: `bp.sizeAvatar` y
87
+ `bp.sizeBadge` devuelven los nombres de otra escala). No uses `bp.isMobile()`: incluye el celular
88
+ chico, que va con el valor de web.
89
+
71
90
  ## «No usar»: por qué no hoy y cuándo sí
72
91
 
73
92
  | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
@@ -94,8 +113,48 @@ Outputs: ninguno.
94
113
  - **`type` decide el ícono y el color**: no se pueden cambiar. Si necesitas otro, usa `sui-key-icon`.
95
114
  - **`size` es un número**: `[size]="48"`.
96
115
 
97
- ## Ejemplo
116
+ ## Bien y mal
117
+
118
+ Ícono en una fila de pagos
119
+
120
+ ```html
121
+ <!-- ❌ mal: isMobile incluye el celular chico, que va con el valor de web (D16) -->
122
+ <sui-payment-icon type="water" [size]="bp.isMobile() ? 40 : 32" />
123
+ ```
124
+
125
+ ```html
126
+ <!-- ✅ bien -->
127
+ <sui-payment-icon type="water" [size]="bp.celular() ? 40 : 32" />
128
+ ```
129
+
130
+ Servicio ya escrito al lado
98
131
 
99
132
  ```html
133
+ <!-- ❌ mal: el lector dice «Pago de luz» y después «Luz»; el texto ya lo nombra -->
134
+ <sui-payment-icon type="electricity" ariaLabel="Pago de luz" />
135
+ <span>Luz</span>
136
+ ```
137
+
138
+ ```html
139
+ <!-- ✅ bien -->
100
140
  <sui-payment-icon type="electricity" />
141
+ <span>Luz</span>
142
+ ```
143
+
144
+ Tamaño fijo
145
+
146
+ ```html
147
+ <!-- ❌ mal: size es un número; "48" llega como texto y no es ninguno de 32/40/48/56/64 -->
148
+ <sui-payment-icon type="rent" size="48" />
149
+ ```
150
+
151
+ ```html
152
+ <!-- ✅ bien -->
153
+ <sui-payment-icon type="rent" [size]="48" />
154
+ ```
155
+
156
+ ## Ejemplo
157
+
158
+ ```html
159
+ <sui-payment-icon type="electricity" [size]="bp.celular() ? 40 : 32" />
101
160
  ```
@@ -21,7 +21,7 @@ costado del calendario.
21
21
  - **Cambiar de período en un resumen** («Hoy · 7 días · 30 días»): `sui-segmented-control` si son 2
22
22
  a 4 opciones, `sui-tab-chips` si son 5 o más o se deslizan (canon, dueño 04-10-2026). Hoy la app
23
23
  los tiene en `sui-tab-chips` (super admin `master-overview.html:13`, ganancias del repartidor) y
24
- en `sui-select` (resumen del local, `overview.html:44`): con 3 opciones pasan a segmented.
24
+ en `sui-segmented-control` (resumen del local, `overview.html:43`, medido el 06-10-2026).
25
25
 
26
26
  ## Qué variante usar
27
27
 
@@ -47,17 +47,34 @@ se desplaza de costado.
47
47
 
48
48
  | size | alto | texto | uso | fuente |
49
49
  |---|---|---|---|---|
50
- | `large` | **44** (10 + 24 + 10) | 16/24 | mobile | canon (dueño, 04-10-2026): piso táctil 44 en el teléfono |
51
- | `medium` (default) | 36 | 14/20 | web, columna de presets | medido (Figma 443:341) |
50
+ | `large` | **44** (10 + 24 + 10) | 16/24 | celular y tablet táctil | canon (dueño, 04-10-2026): piso táctil 44 en el teléfono · la tablet: D16, dueño 05-10-2026 |
51
+ | `medium` (default) | 36 | 14/20 | computadora, columna de presets | medido (Figma 443:341) |
52
52
 
53
53
  ```html
54
- <sui-period-range [size]="bp.isMobile() ? 'large' : 'medium'" label="Últimos 7 días"
54
+ <sui-period-range [size]="bp.tactil() ? 'large' : 'medium'" label="Últimos 7 días"
55
55
  [active]="preset() === '7d'" (clicked)="aplicar('7d')" />
56
56
  ```
57
57
 
58
58
  Fuera del datepicker, en el celular los períodos fijos de 2 a 4 opciones van en
59
59
  `sui-segmented-control` y los de más opciones en `sui-tab-chips` (canon del dueño, 04-10-2026).
60
60
 
61
+ ### Por dispositivo (D16)
62
+
63
+ No está en la tabla por componente de D16; se toca (es un ítem clickeable), así que va como «lo
64
+ que se toca» (D16, dueño 05-10-2026).
65
+
66
+ | dispositivo | size | nota |
67
+ |---|---|---|
68
+ | celular chico (< 380 px) | `large` (44) | D16 pide `medium` con área tocable de 44; `medium` mide 36 y el DS no estira su área, así que va `large` (interino) |
69
+ | celular (380–767 px) | `large` (44) | |
70
+ | tablet táctil (`pointer: coarse`) | `large` (44) | se toca con el dedo: Apple pide 44 pt también en el iPad |
71
+ | computadora (`pointer: fine`) | `medium` (36) | la columna de presets al costado del calendario |
72
+
73
+ Ultrawide (≥ 1920 px): igual que la computadora, `medium`.
74
+
75
+ En master-pedidos: `[size]="bp.tactil() ? 'large' : 'medium'"` (no hay helper propio; es la misma
76
+ cuenta que `bp.sizeControl()`). No uses `bp.isMobile()`: deja la tablet táctil en `medium` (36).
77
+
61
78
  ## «No usar»: por qué no hoy y cuándo sí
62
79
 
63
80
  | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
@@ -89,9 +106,51 @@ Fuera del datepicker, en el celular los períodos fijos de 2 a 4 opciones van en
89
106
  - Ancho fijo de 168 px.
90
107
  - `active` no se apaga solo: lo maneja quien lo usa.
91
108
 
109
+ ## Bien y mal
110
+
111
+ Períodos de un resumen
112
+
113
+ ```html
114
+ <!-- ❌ mal: un resumen con períodos fijos no es la columna de un calendario -->
115
+ <sui-period-range label="Hoy" [active]="periodo() === 'hoy'" (clicked)="periodo.set('hoy')" />
116
+ <sui-period-range label="7 días" [active]="periodo() === '7d'" (clicked)="periodo.set('7d')" />
117
+ <sui-period-range label="30 días" [active]="periodo() === '30d'" (clicked)="periodo.set('30d')" />
118
+ ```
119
+
120
+ ```html
121
+ <!-- ✅ bien: de 2 a 4 períodos fijos, segmented-control -->
122
+ <sui-segmented-control [size]="bp.tactil() ? '2xlarge' : 'medium'"
123
+ [tabs]="periodOptions" [(active)]="periodo" />
124
+ ```
125
+
126
+ Texto del preset
127
+
128
+ ```html
129
+ <!-- ❌ mal: las fechas las muestra el calendario de al lado; el preset dice el período en palabras -->
130
+ <sui-period-range label="29/09 – 05/10" (clicked)="aplicar('7d')" />
131
+ ```
132
+
133
+ ```html
134
+ <!-- ✅ bien -->
135
+ <sui-period-range label="Últimos 7 días" (clicked)="aplicar('7d')" />
136
+ ```
137
+
138
+ Tamaño en la tablet
139
+
140
+ ```html
141
+ <!-- ❌ mal: isMobile deja la tablet táctil en medium (36), bajo el piso de 44 -->
142
+ <sui-period-range [size]="bp.isMobile() ? 'large' : 'medium'" label="Hoy" />
143
+ ```
144
+
145
+ ```html
146
+ <!-- ✅ bien -->
147
+ <sui-period-range [size]="bp.tactil() ? 'large' : 'medium'" label="Hoy" />
148
+ ```
149
+
92
150
  ## Ejemplo
93
151
 
94
152
  ```html
95
- <sui-period-range label="Hoy" [active]="true" />
96
- <sui-period-range label="Últimos 30 días" (clicked)="aplicar('30d')" />
153
+ <sui-period-range [size]="bp.tactil() ? 'large' : 'medium'" label="Hoy" [active]="true" />
154
+ <sui-period-range [size]="bp.tactil() ? 'large' : 'medium'" label="Últimos 30 días"
155
+ (clicked)="aplicar('30d')" />
97
156
  ```