@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
@@ -43,7 +43,7 @@ más oscuro) y con texto (lupa naranja, X para limpiar).
43
43
  |---|---|---|
44
44
  | `placeholder` | **Siempre**, en español y diciendo qué se busca: «Busca pedidos, locales o repartidores…». El default genérico es `'Buscar o ir a…'`. | canon (CANON-SUI §5: copy en español, elipsis `…`) |
45
45
  | `shortcut` | `true` solo en web; en mobile `false` (no hay teclado físico). | canon (README de `sui-kbd`) |
46
- | `button` | Déjalo en `true`: la X de limpiar ahorra borrar a mano. El ícono de info del estado vacío no hace nada. | propuesta |
46
+ | `button` | La X de limpiar **solo en la computadora** (`true`): ahorra borrar a mano. En el celular y en la tablet táctil, `false` hasta que el DS tenga un size de 44 (la X mide 20): se toca, así que la tablet va con el celular (D16). El ícono de info del estado vacío no hace nada. | canon (aprobado por el dueño, 05-10-2026, bloque B13) |
47
47
 
48
48
  ## Tamaño en mobile y en web
49
49
 
@@ -51,13 +51,26 @@ No tiene tamaños: 48 px de alto (14 + 20 + 13 + 1 de borde), texto 14/20, hasta
51
51
 
52
52
  | uso | mobile | web | fuente |
53
53
  |---|---|---|---|
54
- | buscador del command menu | igual, sin chip ⌘K | igual, con chip ⌘K | canon para el chip (README de `sui-kbd`); el resto, propuesta |
54
+ | buscador del command menu | igual, sin chip ⌘K ni X | igual, con chip ⌘K y X | canon para el chip (README de `sui-kbd`) y la X (B13 + D16: la tablet táctil va sin X); el resto, propuesta |
55
55
 
56
56
  ```html
57
57
  <sui-command-menu-search [(value)]="q" placeholder="Busca pedidos, locales o repartidores…"
58
- [shortcut]="!bp.isMobile()" /> <!-- bp = BreakpointsService -->
58
+ [shortcut]="!bp.isMobile()" [button]="!bp.tactil()" /> <!-- bp = BreakpointsService -->
59
59
  ```
60
60
 
61
+ ### Por dispositivo (D16)
62
+
63
+ No aplica: no tiene input `size` (48 px de alto y texto 14 en todos los dispositivos), así que D16 no
64
+ lo mueve. Por dispositivo solo cambian dos cosas, y no con la misma señal:
65
+
66
+ - **La X de limpiar se toca** (`sui-compact-button` `medium`, 20 px): va apagada en el celular **y en
67
+ la tablet táctil**, porque D16 pone la tablet con el celular en lo que se toca (Apple pide 44
68
+ también en iPad). `bp.tactil()`, no `bp.isMobile()`: `isMobile()` solo mira el ancho (≤ 767 px) y
69
+ en un iPad la dejaría prendida.
70
+ - **El chip ⌘K no se toca**: sigue la regla de `sui-kbd`, apagado en el celular (`!bp.isMobile()`).
71
+
72
+ En master-pedidos: `[shortcut]="!bp.isMobile()" [button]="!bp.tactil()"`, sin `[size]`.
73
+
61
74
  ## API
62
75
 
63
76
  <!-- api:inicio -->
@@ -94,6 +107,47 @@ No tiene tamaños: 48 px de alto (14 + 20 + 13 + 1 de borde), texto 14/20, hasta
94
107
  - No tiene `disabled`.
95
108
  - El ícono de info del estado vacío es decorativo: no abre ayuda ni tiene `aria-label`.
96
109
 
110
+ ## Bien y mal
111
+
112
+ Devolver el texto al campo
113
+
114
+ ```html
115
+ <!-- ❌ mal: sin [(value)] el componente no sabe que hay texto; la X nunca aparece -->
116
+ <sui-command-menu-search placeholder="Busca pedidos, locales o repartidores…"
117
+ (valueChange)="buscar($event)" />
118
+ ```
119
+
120
+ ```html
121
+ <!-- ✅ bien: el filtro sale de q (un computed), no del evento -->
122
+ <sui-command-menu-search [(value)]="q" placeholder="Busca pedidos, locales o repartidores…" />
123
+ ```
124
+
125
+ Chip ⌘K y X en el celular
126
+
127
+ ```html
128
+ <!-- ❌ mal (en el celular y en la tablet táctil): ⌘K sin teclado físico y una X de 20 px para el dedo -->
129
+ <sui-command-menu-search [(value)]="q" placeholder="Busca pedidos, locales o repartidores…"
130
+ [shortcut]="true" [button]="true" />
131
+ ```
132
+
133
+ ```html
134
+ <!-- ✅ bien: la X se toca, así que también se apaga en la tablet táctil (bp.tactil()) -->
135
+ <sui-command-menu-search [(value)]="q" placeholder="Busca pedidos, locales o repartidores…"
136
+ [shortcut]="!bp.isMobile()" [button]="!bp.tactil()" />
137
+ ```
138
+
139
+ Buscar dentro de una pantalla
140
+
141
+ ```html
142
+ <!-- ❌ mal: suelto, sin caja, parece texto; y no lleva la lupa en el teclado -->
143
+ <sui-command-menu-search [(value)]="q" placeholder="Buscar pedido…" />
144
+ ```
145
+
146
+ ```html
147
+ <!-- ✅ bien: el buscador de una pantalla es sui-input search -->
148
+ <sui-input type="search" [size]="bp.sizeControl()" placeholder="Buscar pedido…" [(value)]="q" />
149
+ ```
150
+
97
151
  ## Ejemplo
98
152
 
99
153
  ```html
@@ -101,5 +155,6 @@ No tiene tamaños: 48 px de alto (14 + 20 + 13 + 1 de borde), texto 14/20, hasta
101
155
  [(value)]="q"
102
156
  placeholder="Busca pedidos, locales o repartidores…"
103
157
  [shortcut]="!bp.isMobile()"
158
+ [button]="!bp.tactil()"
104
159
  (cleared)="resultados.set([])" />
105
160
  ```
@@ -22,8 +22,8 @@ de lista. Es una píldora blanca con los avatares casi pegados y el «+N» como
22
22
  ## Qué variante usar
23
23
 
24
24
  > **La guía del DS dice qué es, sus tamaños y sus dos estilos, no cuándo usar cada uno.** Lo
25
- > marcado «según la guía del DS» sale de su texto o de su código; el resto es **propuesta,
26
- > falta aprobación**.
25
+ > marcado «según la guía del DS» sale de su texto o de su código. Lo marcado canon está
26
+ > aprobado; lo que sigue en **propuesta, falta aprobación** espera decisión.
27
27
  >
28
28
  > Uso medido el 03-10-2026 en `master-pedidos/src/app`: **0 usos directos**. En el DS no lo
29
29
  > monta ningún componente: `sui-table` solo lo nombra como contenido que se proyecta en una celda.
@@ -38,22 +38,25 @@ de lista. Es una píldora blanca con los avatares casi pegados y el «+N» como
38
38
 
39
39
  | input | valor | cuándo | fuente |
40
40
  |---|---|---|---|
41
- | `size` | `'24'` | Celda de tabla. | propuesta |
42
- | `size` | `'32'` (default SUI) | Fila de una lista. | propuesta |
43
- | `size` | `'40'` (default de la guía) | Dentro de una card. | propuesta |
44
- | `appearance` | `default` | Sobre un fondo gris o de color: la sombra lo separa. | propuesta |
45
- | `appearance` | `stroke` | Sobre blanco, donde la sombra sola no alcanza a marcar el borde. | propuesta |
46
- | `max` | `3` (default) | Tres avatares visibles. | propuesta |
47
- | `count` | — | Solo si el total no está en `items` (vienen 3 caras pero son 12 personas): `count="+9"`. Si no, se calcula solo. | propuesta |
41
+ | `size` | `'24'` | Celda de tabla. | canon (aprobado por el dueño, 05-10-2026, bloque B1) |
42
+ | `size` | `'32'` (default SUI) | Fila de una lista. | canon (aprobado por el dueño, 05-10-2026, bloque B1) |
43
+ | `size` | `'40'` (default de la guía) | Dentro de una card. | canon (aprobado por el dueño, 05-10-2026, bloque B1) |
44
+ | `appearance` | `default` | Sobre un fondo gris o de color: la sombra lo separa. | canon (aprobado por el dueño, 05-10-2026, bloque B2) |
45
+ | `appearance` | `stroke` | Sobre blanco, donde la sombra sola no alcanza a marcar el borde. | canon (aprobado por el dueño, 05-10-2026, bloque B2) |
46
+ | `max` | `3` (default) | Tres avatares visibles. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
47
+ | `count` | — | Solo si el total no está en `items` (vienen 3 caras pero son 12 personas): `count="+9"`. Si no, se calcula solo. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
48
48
 
49
49
  Usos de hoy que rompen la regla: **0** (no hay usos).
50
50
 
51
51
  ## Tamaño en mobile y en web
52
52
 
53
- En mobile se lee y se toca con el dedo, así que va más grande; en web, más chico. En las
53
+ En mobile va más grande por legibilidad (el grupo no se toca: el área la da la fila); en web, más chico. En las
54
54
  pantallas que se usan en los dos (panel del local, super admin) se elige con el servicio de
55
55
  breakpoints de la app (`bp`, en `services/breakpoints.service.ts`); en las que solo existen en
56
- el celular (cliente, repartidor) va directo el valor de mobile. Todo es **propuesta**.
56
+ el celular (cliente, repartidor) también va `bp.celular()`, porque el celular chico (< 380 px) toma
57
+ el valor de web (D16, dueño 05-10-2026). No se toca, así que la tablet va con el valor de web.
58
+ Es **canon (dueño, 05-10-2026, P1 b)**: un paso más grande en el celular que en computadora, y
59
+ se migra todo ahora, no solo al tocar cada pantalla.
57
60
 
58
61
  | uso | mobile | web |
59
62
  |---|---|---|
@@ -61,9 +64,26 @@ el celular (cliente, repartidor) va directo el valor de mobile. Todo es **propue
61
64
  | dentro de una card | `'40'` | `'32'` |
62
65
 
63
66
  ```html
64
- <sui-compact-avatar-group [size]="bp.isMobile() ? '32' : '24'" [items]="repartidores" />
67
+ <sui-compact-avatar-group [size]="bp.celular() ? '32' : '24'" [items]="repartidores" />
65
68
  ```
66
69
 
70
+ ### Por dispositivo (D16)
71
+
72
+ No se toca: sube un paso solo en el celular de 380 px o más; el resto va con el valor de web.
73
+
74
+ | dispositivo | size | nota |
75
+ |---|---|---|
76
+ | celular chico (< 380) | valor web: `'24'` fila · `'32'` card | lo que no se toca va como en la computadora (D16) |
77
+ | celular (380–767) | valor mobile: `'32'` fila · `'40'` card | P1 b: un paso más que en la computadora |
78
+ | tablet táctil (`pointer: coarse`) | valor web: `'24'` fila · `'32'` card | no se toca: el puntero no lo mueve |
79
+ | computadora (`pointer: fine`) | valor web: `'24'` fila · `'32'` card | |
80
+
81
+ Ultrawide: igual que la computadora; el espacio extra no agranda el grupo.
82
+
83
+ En master-pedidos: `[size]="bp.celular() ? '32' : '24'"` en una fila y `[size]="bp.celular() ? '40' : '32'"`
84
+ en una card (no hay helper: `bp.sizeAvatar()` usa la escala de `sui-avatar`, no `'24'`/`'32'`/`'40'`).
85
+ `bp.isMobile()` no sirve: incluye al celular chico.
86
+
67
87
  ## «No usar»: por qué no hoy y cuándo sí
68
88
 
69
89
  | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
@@ -97,8 +117,48 @@ Outputs: ninguno.
97
117
  - Las reglas de foto y color de cada persona son las de `sui-avatar`: el `color` por rol va
98
118
  explícito en cada item (canon, aprobado por el dueño, 03-10-2026); sin él cae a `slate`.
99
119
 
120
+ ## Bien y mal
121
+
122
+ El size es un string
123
+
124
+ ```html
125
+ <!-- ❌ mal: con números no compila; el tipo es '24' | '32' | '40' -->
126
+ <sui-compact-avatar-group [size]="bp.celular() ? 32 : 24" [items]="repartidores" />
127
+ ```
128
+
129
+ ```html
130
+ <!-- ✅ bien: los valores van entre comillas (fila: '32' en el celular, '24' en el resto) -->
131
+ <sui-compact-avatar-group [size]="bp.celular() ? '32' : '24'" [items]="repartidores" />
132
+ ```
133
+
134
+ Tamaño en el celular chico
135
+
136
+ ```html
137
+ <!-- ❌ mal: isMobile() también sube el celular chico, que va con el valor de web (D16) -->
138
+ <sui-compact-avatar-group [size]="bp.isMobile() ? '32' : '24'" [items]="repartidores" />
139
+ ```
140
+
141
+ ```html
142
+ <!-- ✅ bien -->
143
+ <sui-compact-avatar-group [size]="bp.celular() ? '32' : '24'" [items]="repartidores" />
144
+ ```
145
+
146
+ El «+N» a mano
147
+
148
+ ```html
149
+ <!-- ❌ mal: items ya trae a todos; count fijo gana al cálculo y miente cuando cambia la lista -->
150
+ <sui-compact-avatar-group [size]="bp.celular() ? '32' : '24'" appearance="stroke" [items]="repartidores"
151
+ count="+3" />
152
+ ```
153
+
154
+ ```html
155
+ <!-- ✅ bien: count solo si items trae menos personas que el total -->
156
+ <sui-compact-avatar-group [size]="bp.celular() ? '32' : '24'" appearance="stroke" [items]="repartidores" />
157
+ ```
158
+
100
159
  ## Ejemplo
101
160
 
102
161
  ```html
103
- <sui-compact-avatar-group size="24" appearance="stroke" [items]="repartidoresDelLocal" />
162
+ <!-- celda de la tabla de locales: '32' en el celular de 380 px o más, '24' en el resto (D16) -->
163
+ <sui-compact-avatar-group [size]="bp.celular() ? '32' : '24'" appearance="stroke" [items]="repartidoresDelLocal" />
104
164
  ```
@@ -27,11 +27,15 @@ carrusel o un mapa.
27
27
  > dos tamaños, el radio completo y el deshabilitado, sin do/don't. Las reglas de abajo son
28
28
  > **canon (aprobado por el dueño, 03-10-2026)** salvo donde dice otra fuente.
29
29
  >
30
- > Uso medido el 04-10-2026 en `master-pedidos/src/app`: 11 compact-buttons en 7 archivos, sin
30
+ > Uso medido el 06-10-2026 en `master-pedidos/src/app`: 12 compact-buttons en 8 archivos, sin
31
31
  > contar prototipos ni vitrinas (`master-preview`, `master-prototipos`, `mockup-sheets-*`,
32
- > `dx/*`, `master-rutina`, `master-medico`, `dev-index`). Estilos: 6 `ghost`, 3 `stroke` (uno
33
- > por error, ver abajo), 2 `white`, 0 `modifiable`. Tamaños: 3 `large`, 2 `medium`, 2 `xlarge` y
34
- > 4 por `bp` (`2xlarge`/`large` y `3xlarge`/`medium`). 4 con `fullRadius`, 1 con `disabled`.
32
+ > `dx/*`, `master-rutina`, `master-medico`, `dev-index`). Estilos: 7 `ghost`, 3 `stroke` (uno
33
+ > por error, ver abajo), 2 `white`, 0 `modifiable`. Tamaños: 7 por `bp` (6 `5xlarge`/`large` y 1
34
+ > `5xlarge`/`medium`, los 7 con `bp.isMobile()`), 2 `large` fijo, 1 `medium` fijo y 2 `xlarge`
35
+ > fijo. 4 con `fullRadius`, 1 con `disabled`.
36
+ >
37
+ > Las líneas citadas en este README son las de **apertura del elemento** (`<sui-compact-button`),
38
+ > aunque el `[size]` o el `(click)` estén unas líneas más abajo.
35
39
 
36
40
  ### Lo que sí dice la guía del DS
37
41
 
@@ -53,14 +57,16 @@ carrusel o un mapa.
53
57
 
54
58
  **Usos de hoy que rompen la regla:**
55
59
 
56
- - **1 bug: `variant="ghost"` en vez de `variantStyle`.** `pages/super-admin/master-settings/master-settings.html:658`
57
- («Quitar este nivel»). `variant` no es un input del compact-button: el atributo se ignora y el
58
- botón sale `stroke`. Pasar a `variantStyle="ghost"`.
60
+ - **Sin estilo explícito.** `pages/super-admin/master-settings/master-settings.html:649` («Quitar este
61
+ nivel»). Antes llevaba `variant="ghost"` (que el compact-button ignora); medido el 06-10-2026, ya
62
+ no lleva `variant`, pero tampoco `variantStyle`, así que sigue saliendo `stroke`. Pasar a
63
+ `variantStyle="ghost"` (además tiene `size="medium"` fijo y `(click)`: ver «Bien y mal»).
59
64
  - **Resuelto — `ghost` en acciones de fila** (canon, dueño 04-10-2026): se permite, igual que en
60
- `sui-button`. Los 5 usos de hoy quedan bien: `components/option-sections-manager/option-sections-manager.html:38`
61
- y `:148`, `components/add-product-modal/add-product-modal.html:315`,
62
- `pages/super-admin/master-settings/master-settings.html:113` y `:658` (este último sigue con el
63
- bug de `variant` en vez de `variantStyle`).
65
+ `sui-button`. En estos usos el **`ghost` queda bien**:
66
+ `components/option-sections-manager/option-sections-manager.html:38` y `:148`,
67
+ `components/add-product-modal/add-product-modal.html:317` y
68
+ `pages/super-admin/master-categorias/master-categorias.html:91` y `:98`. El **tamaño** no: los
69
+ cinco rompen D16 (ver «Usos de hoy que rompen la regla» en `size`).
64
70
 
65
71
  ### `size`
66
72
 
@@ -74,38 +80,57 @@ carrusel o un mapa.
74
80
  | `4xlarge` | 40 (24) | Flotantes sobre el mapa (volver, centrar). | ídem: canon; publicado desde 0.20.0 |
75
81
  | `5xlarge` | 44 (24) | **El del teléfono** cuando el botón se toca solo: cerrar un modal o sheet, flotantes sobre el mapa. El ícono se queda en 24 como `4xlarge`: crece el área, no el dibujo. | canon (dueño, 04-10-2026): piso táctil 44 en el teléfono |
76
82
 
77
- **Migración a tamaños de mobile: hecha** (medido el 04-10-2026). Los 4 casos del cliente ya usan
78
- `bp`: `components/product-detail-view/product-detail-view.html:169` y `:173` y
79
- `pages/customer/order-history/order-history.html:382` con `2xlarge`/`large`, y
80
- `components/store-ratings-modal/store-ratings-modal.html:33` con `3xlarge` en mobile.
83
+ **Migración a tamaños de mobile: a medias** (medido el 06-10-2026). 7 usos ya llevan `bp` con
84
+ `5xlarge` en el celular, pero los 7 con `bp.isMobile()`, que mira solo el ancho: en la tablet quedan
85
+ con el tamaño de web (24 o 20). Hay que pasarlos a `bp.tactil()` (D16):
86
+
87
+ - `components/product-detail-view/product-detail-view.html:169` y `:173` (− / +)
88
+ - `pages/customer/order-history/order-history.html:382` (ver detalle)
89
+ - `components/store-ratings-modal/store-ratings-modal.html:33` (cerrar)
90
+ - `components/add-product-modal/add-product-modal.html:317` (quitar opción)
91
+ - `components/option-sections-manager/option-sections-manager.html:38` (más) y `:148` (quitar opción)
92
+
93
+ **Usos de hoy que rompen la regla** (además de los 7 de arriba):
81
94
 
82
- **Uso de hoy que rompe la regla:** `store-ratings-modal.html:33` cierra en web con `medium` (20);
83
- la tabla de abajo pide `xlarge` (28).
95
+ - `store-ratings-modal.html:33` cierra en web con `medium` (20); la tabla de abajo pide `xlarge` (28).
96
+ - `pages/super-admin/master-settings/master-settings.html:649` («Quitar este nivel»): `size="medium"`
97
+ fijo, así que mide 20 en el celular y la tablet. Va `[size]="bp.tactil() ? '5xlarge' : 'large'"`.
98
+ - `pages/super-admin/master-categorias/master-categorias.html:91` (fijar) y `:98` (editar):
99
+ `size="large"` fijo, 24 en el celular y la tablet. Va `[size]="bp.tactil() ? '5xlarge' : 'large'"`.
100
+
101
+ Las flechas de `arrastre-carrusel.ts:102` y `:104` llevan `xlarge` fijo y están bien: solo aparecen
102
+ con mouse.
84
103
 
85
104
  ### `fullRadius`
86
105
 
87
106
  | fullRadius | cuándo | fuente |
88
107
  |---|---|---|
89
- | `false` (default, radio 6) | Lo normal: filas, cards, cabeceras. | default según la guía del DS · cuándo: propuesta |
108
+ | `false` (default, radio 6) | Lo normal: filas, cards, cabeceras. | default según la guía del DS · cuándo: canon (aprobado por el dueño, 05-10-2026, bloque B2) |
90
109
  | `true` (círculo) | Flotante (`white`) sobre mapa o foto. | canon (aprobado por el dueño, 03-10-2026) |
91
- | `true` (círculo) | El − / + de una cantidad, para que se lea como un stepper. | propuesta (es lo que ya hace `product-detail-view`) |
110
+ | `true` (círculo) | El − / + de una cantidad, para que se lea como un stepper. | canon (aprobado por el dueño, 05-10-2026, bloque B2) (es lo que ya hace `product-detail-view`) |
92
111
 
93
112
  ### `disabled`, `href`, `ariaLabel`
94
113
 
95
114
  | prop | cuándo | fuente |
96
115
  |---|---|---|
97
- | `disabled` | Se llegó al límite: no hay más stock para sumar, no se puede quitar el último. | cómo se ve: según la guía del DS · cuándo: propuesta |
98
- | `href` | Solo si el botón navega sin otra acción (volver a una ruta). Pinta un `<a>`; `rel` ya viene en `'noopener noreferrer'`. | propuesta |
99
- | `ariaLabel` (requerido) | Lo que hace, no lo que muestra: «Cerrar», «Quitar opción», «Agregar uno»; nunca «X» ni «Ícono». | propuesta (el input es obligatorio) |
100
- | `type="submit"` | Solo dentro de un `<form>`. | propuesta |
116
+ | `disabled` | Se llegó al límite: no hay más stock para sumar, no se puede quitar el último. | cómo se ve: según la guía del DS · cuándo: canon (aprobado por el dueño, 05-10-2026, bloque B8) |
117
+ | `href` | Solo si el botón navega sin otra acción (volver a una ruta). Pinta un `<a>`; `rel` ya viene en `'noopener noreferrer'`. | canon (aprobado por el dueño, 05-10-2026, bloque B10) |
118
+ | `ariaLabel` (requerido) | Lo que hace, no lo que muestra: «Cerrar», «Quitar opción», «Agregar uno»; nunca «X» ni «Ícono». | canon (aprobado por el dueño, 05-10-2026, bloque B5) (el input es obligatorio) |
119
+ | `type="submit"` | Solo dentro de un `<form>`. | canon (aprobado por el dueño, 05-10-2026, bloque B10) |
101
120
 
102
121
  ## Tamaño en mobile y en web
103
122
 
104
- En mobile se toca con el dedo: el área táctil tiene que medir **44 px o más**. En web, con mouse,
105
- va un tamaño más chico. La app ya lo resuelve con `BreakpointsService`
106
- (`src/app/services/breakpoints.service.ts`, mobile = hasta 767 px):
107
- `[size]="bp.isMobile() ? 'large' : 'small'"`. Medido el 04-10-2026 en `master-pedidos`: 166 `[size]`
108
- con `bp` (142 `large`/`medium`, 22 `large`/`small`, 2 `medium`/`xsmall`). Regla del dueño, 03-10-2026.
123
+ En mobile se toca con el dedo: el área táctil tiene que medir **44 px o más**. En la tablet
124
+ (`pointer: coarse`) va igual que en el celular, porque también se toca; en la computadora
125
+ (`pointer: fine`), el tamaño de web de la tabla de abajo. El compact-button no tiene un área tocable
126
+ más grande que lo que se ve, así que en el celular chico (< 380 px) también va el de 44.
127
+ Nada en `small` ni `xsmall` (canon, dueño, 05-10-2026, D16; reemplaza al «tamaño por plataforma» del
128
+ 03-10-2026, que bajaba la web a `small`). La app lo resuelve con `BreakpointsService`
129
+ (`src/app/services/breakpoints.service.ts`): `bp.tactil()` es verdadero en todo celular (hasta 767 px)
130
+ y en toda pantalla táctil (`pointer: coarse`), así que cubre la tablet; `bp.isMobile()` solo mira el
131
+ ancho y deja la tablet con el tamaño de web.
132
+ `sui-compact-button` tiene su propia escala (de `medium` 20 a `5xlarge` 44) y no tiene `small`: D16 no
133
+ lo mueve por el nombre; la tabla de abajo sigue igual.
109
134
 
110
135
  | uso | mobile | web | fuente |
111
136
  |---|---|---|---|
@@ -115,7 +140,7 @@ con `bp` (142 `large`/`medium`, 22 `large`/`small`, 2 `medium`/`xsmall`). Regla
115
140
 
116
141
  ```html
117
142
  <sui-compact-button icon="close-line" variantStyle="ghost" ariaLabel="Cerrar"
118
- [size]="bp.isMobile() ? '5xlarge' : 'xlarge'" (clicked)="cerrar()" />
143
+ [size]="bp.tactil() ? '5xlarge' : 'xlarge'" (clicked)="cerrar()" />
119
144
  ```
120
145
 
121
146
  `2xlarge`, `3xlarge` y `4xlarge` están publicados desde la 0.20.0 (la app usa la 0.22.0); `5xlarge`
@@ -124,6 +149,26 @@ entrar un botón de 44, `2xlarge` (32) con aire alrededor (gap o padding) es la
124
149
  dedo no toque el vecino. `medium` y `large` no
125
150
  van en mobile.
126
151
 
152
+ ### Por dispositivo (D16)
153
+
154
+ Fila propia en la tabla de D16 (dueño, 05-10-2026): el compact-button tiene **escala propia** y no
155
+ tiene `small`, así que D16 no lo mueve por el nombre; lo que manda es llegar a 44 donde se toca.
156
+
157
+ | dispositivo | size | nota |
158
+ |---|---|---|
159
+ | celular chico (< 380 px) | `5xlarge` (44) | escala propia: el área tocable es el botón mismo (no hay un `medium` con área de 44), así que va el mismo que en el celular |
160
+ | celular (380–767 px) | `5xlarge` (44) | `2xlarge` (32) con aire solo si la fila no lo deja entrar (propuesta, falta aprobación) |
161
+ | tablet táctil (`pointer: coarse`) | `5xlarge` (44) | igual que el celular: también se toca |
162
+ | computadora (`pointer: fine`) | `large` (24) en filas y cards · `xlarge` (28) en el cerrar y los flotantes | `medium` (20) solo en tablas densas |
163
+
164
+ Ultrawide (≥ 1920 px): igual que la computadora; el espacio extra va a columnas, no a botones más grandes.
165
+ Una flecha que **solo aparece con mouse** (las del carrusel, `arrastre-carrusel.ts:102`) no necesita
166
+ `bp`: va `xlarge` fijo.
167
+
168
+ En master-pedidos: `[size]="bp.tactil() ? '5xlarge' : 'large'"` (filas y cards) o
169
+ `[size]="bp.tactil() ? '5xlarge' : 'xlarge'"` (cerrar y flotantes). No hay helper `size*` propio:
170
+ `bp.sizeControl()` devuelve `large`/`medium`, que aquí miden 24/20.
171
+
127
172
  ## «No usar»: por qué no hoy y cuándo sí
128
173
 
129
174
  Ningún valor del compact-button está en «no usar»: los cuatro estilos y los siete tamaños tienen
@@ -158,10 +203,10 @@ El clic se escucha con `(clicked)`. `icon` recibe el nombre RemixIcon, sin el pr
158
203
  ## Trampas
159
204
 
160
205
  - **El estilo se llama `variantStyle`**, no `variant`. `variant="ghost"` no da error de
161
- compilación: se ignora y sale `stroke` (pasa hoy en `master-settings.html:658`).
206
+ compilación: se ignora y sale `stroke` (pasó en `master-settings.html:649`).
162
207
  - **`icon` y `ariaLabel` son obligatorios**: sin `ariaLabel` no compila.
163
208
  - **El output es `(clicked)`**. `(click)` sobre el host también llega porque el clic burbujea; hoy 6
164
- usos lo escuchan así (`product-detail-view.html:169` y `:173`, `master-settings.html:658`,
209
+ usos lo escuchan así (`product-detail-view.html:169` y `:173`, `master-settings.html:649`,
165
210
  `arrastre-carrusel.ts:102` y `:104`, `order-history.html:382`). Usa `(clicked)`, que ya respeta
166
211
  `disabled`.
167
212
  - En `medium` el ícono mide 16, no los 18 de la guía.
@@ -171,11 +216,55 @@ El clic se escucha con `(clicked)`. `icon` recibe el nombre RemixIcon, sin el pr
171
216
  blanco: es el estado activo del Figma, no un error.
172
217
  - Ya trae el arreglo de iOS para el `:active` pegado: no lo agregues.
173
218
 
219
+ ## Bien y mal
220
+
221
+ **Una acción de fila con size fijo**
222
+
223
+ ```html
224
+ <!-- ❌ mal: size fijo; en el celular y la tablet mide 20 o 24 (master-settings.html:649, master-categorias.html:98) -->
225
+ <sui-compact-button icon="pencil-line" variantStyle="ghost" size="large"
226
+ [ariaLabel]="'Editar ' + f.nombre" (clicked)="abrir(f.id)" />
227
+ ```
228
+
229
+ ```html
230
+ <!-- ✅ bien -->
231
+ <sui-compact-button icon="pencil-line" variantStyle="ghost" [size]="bp.tactil() ? '5xlarge' : 'large'"
232
+ [ariaLabel]="'Editar ' + f.nombre" (clicked)="abrir(f.id)" />
233
+ ```
234
+
235
+ **El cerrar de un modal**
236
+
237
+ ```html
238
+ <!-- ❌ mal: en web cierra en medium (20) y la tablet queda con el de web (store-ratings-modal.html:33) -->
239
+ <sui-compact-button icon="close-line" variantStyle="ghost" ariaLabel="Cerrar"
240
+ [size]="bp.isMobile() ? '5xlarge' : 'medium'" (clicked)="onClosed()" />
241
+ ```
242
+
243
+ ```html
244
+ <!-- ✅ bien -->
245
+ <sui-compact-button icon="close-line" variantStyle="ghost" ariaLabel="Cerrar"
246
+ [size]="bp.tactil() ? '5xlarge' : 'xlarge'" (clicked)="onClosed()" />
247
+ ```
248
+
249
+ **El − / + de una cantidad**
250
+
251
+ ```html
252
+ <!-- ❌ mal: (click) escucha al host; (clicked) es el que respeta disabled (product-detail-view.html:173) -->
253
+ <sui-compact-button icon="add-line" [fullRadius]="true" [size]="bp.tactil() ? '5xlarge' : 'large'"
254
+ [disabled]="sinStock" ariaLabel="Agregar uno" (click)="sumar()" />
255
+ ```
256
+
257
+ ```html
258
+ <!-- ✅ bien -->
259
+ <sui-compact-button icon="add-line" [fullRadius]="true" [size]="bp.tactil() ? '5xlarge' : 'large'"
260
+ [disabled]="sinStock" ariaLabel="Agregar uno" (clicked)="sumar()" />
261
+ ```
262
+
174
263
  ## Ejemplo
175
264
 
176
265
  ```html
177
- <!-- Cerrar en la cabecera de un sheet: 5xlarge (44) en mobile, xlarge en web -->
178
- <sui-compact-button icon="close-line" variantStyle="ghost" [size]="bp.isMobile() ? '5xlarge' : 'xlarge'"
266
+ <!-- Cerrar en la cabecera de un sheet: 5xlarge (44) donde se toca, xlarge en la computadora -->
267
+ <sui-compact-button icon="close-line" variantStyle="ghost" [size]="bp.tactil() ? '5xlarge' : 'xlarge'"
179
268
  ariaLabel="Cerrar" (clicked)="cerrar()" />
180
269
 
181
270
  <!-- Acción de una fila en desktop -->
@@ -183,5 +272,5 @@ El clic se escucha con `(clicked)`. `icon` recibe el nombre RemixIcon, sin el pr
183
272
 
184
273
  <!-- Flotante sobre el mapa -->
185
274
  <sui-compact-button icon="arrow-left-line" variantStyle="white" [fullRadius]="true"
186
- [size]="bp.isMobile() ? '5xlarge' : 'xlarge'" ariaLabel="Volver" (clicked)="volver()" />
275
+ [size]="bp.tactil() ? '5xlarge' : 'xlarge'" ariaLabel="Volver" (clicked)="volver()" />
187
276
  ```
@@ -42,7 +42,7 @@ Regla corta: **filtro suelto en una barra, ancho al texto → compact · campo c
42
42
  | `selected` / `selectedChange` | La opción elegida (objeto entero). O `formControlName`, nunca los dos. | API |
43
43
  | `placeholder` | El filtro sin elegir: «Todos». Corto. | propuesta, falta aprobación |
44
44
  | `value` / `icon` | Lo que muestra el campo cuando no hay `items` (modo «solo campo», el menú lo arma la pantalla). | API |
45
- | `error` | No usar hoy: un filtro no tiene error. | propuesta, falta aprobación |
45
+ | `error` | No usar hoy: un filtro no tiene error. | canon (aprobado por el dueño, 05-10-2026, bloque B6) |
46
46
  | `disabled` | Mientras carga la lista. | según la guía del DS |
47
47
  | `clicked` | Solo si la pantalla arma su propio menú (sin `items`). | API |
48
48
 
@@ -66,19 +66,35 @@ Las opciones del menú siguen al `size` como en `sui-select`: 36 hasta `medium`,
66
66
  |---|---|---|---|
67
67
  | `large` | 48 | 44 · 44 | canon (aprobado por el dueño, 03-10-2026), extensión SUI |
68
68
  | `medium` (default) | 40 | 36 · 44 | según la guía del DS; 44 en mobile: canon (aprobado por el dueño, 03-10-2026) |
69
- | `small` | 36 | 36 · 44 | ídem |
70
- | `xsmall` | 32 | 36 · 44 | ídem |
69
+ | `small` | 36 | 36 · 44 | ídem · no se usa: D16, dueño 05-10-2026 |
70
+ | `xsmall` | 32 | 36 · 44 | ídem · no se usa: D16, dueño 05-10-2026 (tampoco en la paginación) |
71
71
 
72
72
  | uso | mobile | web | fuente |
73
73
  |---|---|---|---|
74
- | filtro de una barra del panel | `large` (48), junto a botones `large` | `small` (36) | propuesta, falta aprobación |
75
- | paginación al pie de una tabla | no aplica | `xsmall` (32) | según la guía del DS (ejemplo de paginación); el tamaño es propuesta |
74
+ | filtro de una barra del panel | `large` (48), junto a botones `large` | `medium` (40) | mobile `large`: canon (decisión del dueño 04-10-2026, piso táctil 44: es el único size de 44 o más; texto 16 en large, DS 0.22.0) · web `medium`: canon (dueño, 05-10-2026, D16) |
75
+ | paginación al pie de una tabla | no aplica | `medium` (40) | canon (dueño, 05-10-2026, D16) (la guía del DS lo muestra en `xsmall`) |
76
76
 
77
77
  ```html
78
- <sui-compact-select [size]="bp.isMobile() ? 'large' : 'small'" placeholder="Todos los roles"
78
+ <sui-compact-select [size]="bp.sizeControl()" placeholder="Todos los roles"
79
79
  [items]="roles" [(selected)]="rolElegido" /> <!-- bp = BreakpointsService -->
80
80
  ```
81
81
 
82
+ ### Por dispositivo (D16)
83
+
84
+ Comparte fila con `input` y `select` en la tabla de D16 (dueño, 05-10-2026): se toca, así que va
85
+ grande en el celular y en la tablet, y `medium` en la computadora.
86
+
87
+ | dispositivo | size | nota |
88
+ |---|---|---|
89
+ | celular chico (< 380 px) | `large` (48) | interino: D16 pide `medium` con área tocable de 44, pero el DS todavía no la estira en `medium` (40); hasta que lo haga, el mismo que el celular |
90
+ | celular (380–767 px) | `large` (48) | junto a botones `large` de la misma barra |
91
+ | tablet táctil (`pointer: coarse`) | `large` (48) | también se toca. Ojo: las opciones del menú de un `medium` solo suben a 44 hasta 767 px, por eso la tablet no se queda en `medium` |
92
+ | computadora (`pointer: fine`) | `medium` (40) | filtros del panel y paginación; `small` y `xsmall` no se usan |
93
+
94
+ Ultrawide (≥ 1920 px): igual que la computadora.
95
+
96
+ En master-pedidos: `[size]="bp.sizeControl()"` (`large` donde se toca, `medium` en la computadora).
97
+
82
98
  ## «No usar»: por qué no hoy y cuándo sí
83
99
 
84
100
  | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
@@ -126,9 +142,47 @@ Implementa `ControlValueAccessor` (el valor es el `value` de la opción).
126
142
  - El menú mide al menos 200 px aunque el campo sea más angosto.
127
143
  - Las opciones miden 36 px en web hasta `medium`; 44 en `large` y en mobile (ver «Tamaño»).
128
144
 
145
+ ## Bien y mal
146
+
147
+ **El tamaño de un filtro del panel**
148
+
149
+ ```html
150
+ <!-- ❌ mal: small fijo; D16 no usa small y en el celular mide 36 (vitrina: master-preview/_guia-moleculas/campos.ts:214) -->
151
+ <sui-compact-select size="small" placeholder="Todos los roles" [items]="roles" [(selected)]="rolElegido" />
152
+ ```
153
+
154
+ ```html
155
+ <!-- ✅ bien -->
156
+ <sui-compact-select [size]="bp.sizeControl()" placeholder="Todos los roles" [items]="roles" [(selected)]="rolElegido" />
157
+ ```
158
+
159
+ **Solo ícono**
160
+
161
+ ```html
162
+ <!-- ❌ mal: type="icon" no muestra texto; sin ariaLabel el lector de pantalla no sabe qué elige (vitrina: campos.ts:218) -->
163
+ <sui-compact-select type="icon" [size]="bp.sizeControl()" [items]="vistas" [(selected)]="vista" />
164
+ ```
165
+
166
+ ```html
167
+ <!-- ✅ bien -->
168
+ <sui-compact-select type="icon" [size]="bp.sizeControl()" ariaLabel="Ver como" [items]="vistas" [(selected)]="vista" />
169
+ ```
170
+
171
+ **Dentro de un formulario reactivo**
172
+
173
+ ```html
174
+ <!-- ❌ mal: dos fuentes de verdad; el formulario no se entera de lo que escribe selected -->
175
+ <sui-compact-select [size]="bp.sizeControl()" [items]="roles" formControlName="rol" [(selected)]="rolElegido" />
176
+ ```
177
+
178
+ ```html
179
+ <!-- ✅ bien -->
180
+ <sui-compact-select [size]="bp.sizeControl()" [items]="roles" formControlName="rol" />
181
+ ```
182
+
129
183
  ## Ejemplo
130
184
 
131
185
  ```html
132
- <sui-compact-select size="small" placeholder="Todos los roles" [items]="roles"
186
+ <sui-compact-select [size]="bp.sizeControl()" placeholder="Todos los roles" [items]="roles"
133
187
  [(selected)]="rolElegido" />
134
188
  ```