@ajuarezso/sui-design-system 0.19.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/docs/INDEX.md +136 -0
  2. package/docs/sui-alert/README.md +229 -0
  3. package/docs/sui-app-store-badge/README.md +137 -0
  4. package/docs/sui-avatar/README.md +263 -0
  5. package/docs/sui-avatar-group/README.md +115 -0
  6. package/docs/sui-badge/README.md +229 -0
  7. package/docs/sui-banner/README.md +190 -0
  8. package/docs/sui-brand-logo/README.md +143 -0
  9. package/docs/sui-breadcrumb-item/README.md +96 -0
  10. package/docs/sui-breadcrumbs/README.md +122 -0
  11. package/docs/sui-button/README.md +209 -0
  12. package/docs/sui-button-group/README.md +178 -0
  13. package/docs/sui-button-group-item/README.md +102 -0
  14. package/docs/sui-card/README.md +168 -0
  15. package/docs/sui-chart-legend/README.md +140 -0
  16. package/docs/sui-chart-legend-dot/README.md +118 -0
  17. package/docs/sui-checkbox/README.md +147 -0
  18. package/docs/sui-checkbox-card/README.md +150 -0
  19. package/docs/sui-checkbox-label/README.md +143 -0
  20. package/docs/sui-circular-progress-bar/README.md +131 -0
  21. package/docs/sui-color-dot/README.md +112 -0
  22. package/docs/sui-color-picker/README.md +124 -0
  23. package/docs/sui-compact-avatar-group/README.md +103 -0
  24. package/docs/sui-compact-button/README.md +190 -0
  25. package/docs/sui-compact-select/README.md +127 -0
  26. package/docs/sui-compact-select-for-input/README.md +117 -0
  27. package/docs/sui-content-card/README.md +147 -0
  28. package/docs/sui-content-divider/README.md +124 -0
  29. package/docs/sui-content-label/README.md +148 -0
  30. package/docs/sui-counter-input/README.md +145 -0
  31. package/docs/sui-date-selector/README.md +98 -0
  32. package/docs/sui-datepicker/README.md +193 -0
  33. package/docs/sui-day-cell/README.md +118 -0
  34. package/docs/sui-day-label/README.md +81 -0
  35. package/docs/sui-divider/README.md +102 -0
  36. package/docs/sui-drawer-footer/README.md +127 -0
  37. package/docs/sui-drawer-header/README.md +140 -0
  38. package/docs/sui-emoji/README.md +138 -0
  39. package/docs/sui-empty-state/README.md +145 -0
  40. package/docs/sui-fancy-button/README.md +148 -0
  41. package/docs/sui-file-icon/README.md +103 -0
  42. package/docs/sui-file-upload/README.md +154 -0
  43. package/docs/sui-file-upload-card/README.md +129 -0
  44. package/docs/sui-flag/README.md +99 -0
  45. package/docs/sui-form-hint/README.md +124 -0
  46. package/docs/sui-form-label/README.md +148 -0
  47. package/docs/sui-icon/README.md +135 -0
  48. package/docs/sui-image-upload/README.md +200 -0
  49. package/docs/sui-image-upload-profile/README.md +145 -0
  50. package/docs/sui-inline-input/README.md +104 -0
  51. package/docs/sui-inline-select/README.md +101 -0
  52. package/docs/sui-input/README.md +244 -0
  53. package/docs/sui-integration-switch/README.md +142 -0
  54. package/docs/sui-kbd/README.md +97 -0
  55. package/docs/sui-key-icon/README.md +125 -0
  56. package/docs/sui-link-button/README.md +221 -0
  57. package/docs/sui-logo/README.md +152 -0
  58. package/docs/sui-notification/README.md +179 -0
  59. package/docs/sui-notification-footer/README.md +98 -0
  60. package/docs/sui-notification-tab-menu/README.md +112 -0
  61. package/docs/sui-otp-input/README.md +116 -0
  62. package/docs/sui-pagination/README.md +146 -0
  63. package/docs/sui-password-strength/README.md +99 -0
  64. package/docs/sui-payment-icon/README.md +98 -0
  65. package/docs/sui-period-range/README.md +93 -0
  66. package/docs/sui-popover/README.md +178 -0
  67. package/docs/sui-product-card/README.md +173 -0
  68. package/docs/sui-progress-bar/README.md +132 -0
  69. package/docs/sui-progress-bar-label/README.md +143 -0
  70. package/docs/sui-radio/README.md +134 -0
  71. package/docs/sui-radio-card/README.md +160 -0
  72. package/docs/sui-radio-label/README.md +137 -0
  73. package/docs/sui-rating/README.md +199 -0
  74. package/docs/sui-rich-editor/README.md +114 -0
  75. package/docs/sui-segmented-control/README.md +144 -0
  76. package/docs/sui-select/README.md +180 -0
  77. package/docs/sui-slider/README.md +143 -0
  78. package/docs/sui-social-button/README.md +158 -0
  79. package/docs/sui-status-badge/README.md +164 -0
  80. package/docs/sui-stepper/README.md +166 -0
  81. package/docs/sui-store-card/README.md +147 -0
  82. package/docs/sui-switch/README.md +146 -0
  83. package/docs/sui-switch-card/README.md +149 -0
  84. package/docs/sui-switch-label/README.md +139 -0
  85. package/docs/sui-tab-chips/README.md +185 -0
  86. package/docs/sui-tab-menu-horizontal/README.md +142 -0
  87. package/docs/sui-tab-menu-vertical/README.md +136 -0
  88. package/docs/sui-tag/README.md +145 -0
  89. package/docs/sui-tag-input/README.md +120 -0
  90. package/docs/sui-textarea/README.md +157 -0
  91. package/docs/sui-time-picker/README.md +237 -0
  92. package/docs/sui-toast/README.md +190 -0
  93. package/docs/sui-tooltip/README.md +201 -0
  94. package/fesm2022/ajuarezso-sui-design-system.mjs +466 -279
  95. package/fesm2022/ajuarezso-sui-design-system.mjs.map +1 -1
  96. package/package.json +1 -1
  97. package/types/ajuarezso-sui-design-system.d.ts +367 -72
@@ -0,0 +1,124 @@
1
+ ---
2
+ name: sui-content-divider
3
+ selector: sui-content-divider
4
+ resumen: Línea con algo encima: el «o» entre dos opciones, la cabecera de un grupo o un botón entre bloques
5
+ alternativas: [sui-divider (la línea sola, horizontal o vertical)]
6
+ ---
7
+
8
+ # sui-content-divider
9
+
10
+ Story: [Atoms/Divider/Content Divider](https://sui-design-system.web.app/?path=/docs/atoms-divider-content-divider--docs)
11
+
12
+ ## Cuándo usarlo / cuándo no
13
+
14
+ **Úsalo** cuando la separación **dice algo**:
15
+
16
+ - El «o» entre dos formas de hacer lo mismo (entrar con Google **o** con el correo).
17
+ - La cabecera de un grupo dentro de una lista o un modal («Con pocos pedidos», «Ayer»).
18
+ - Un botón entre dos bloques (agregar algo ahí, ver el resto).
19
+
20
+ **No lo uses** para una línea sola: eso es `sui-divider`, que pesa menos y tiene vertical.
21
+
22
+ ## Qué variante usar
23
+
24
+ > **En la guía del DS este componente se llama «Divider»** y trae: línea (default), línea con
25
+ > espacio, línea con texto («OR»), solo texto, texto con fondo («a menudo va en modales») y
26
+ > contenido al centro. Los cuatro tipos con botones vienen del Figma del DS, no de la guía. Lo
27
+ > marcado «según la guía del DS» sale de su texto o de sus ejemplos; el resto es **propuesta,
28
+ > falta aprobación**.
29
+ >
30
+ > Uso medido el 03-10-2026 en `master-pedidos/src/app`: **1 content-divider**
31
+ > (`pages/super-admin/master-drivers/master-drivers.html:190`, `solid-text` «Con pocos
32
+ > pedidos»), sin contar prototipos ni vitrinas (`master-preview`, `master-prototipos`,
33
+ > `mockup-sheets-*`, `dx/*`, `_guia-*`, `master-rutina`, `master-medico`, `master-ejercicios`,
34
+ > `dev-index`).
35
+
36
+ | type | cuándo | ejemplo | fuente |
37
+ |---|---|---|---|
38
+ | `text-line` | El «o» entre dos formas de hacer lo mismo. | `text="o"` entre «Continuar con Google» y el formulario de correo | según la guía del DS («OR») |
39
+ | `solid-text` | Cabecera de un grupo dentro de una lista o un modal, con fondo. | «Con pocos pedidos» (`master-drivers.html:190`) | según la guía del DS («a menudo en modales») |
40
+ | `text` | Cabecera de grupo sin fondo, en una lista partida por fecha o por tipo. | «Ayer», «Esta semana» | según la guía del DS (existe) · propuesta (cuándo) |
41
+ | `line` (default) | **No usar** (ver abajo). | — | según la guía del DS (default) |
42
+ | `line-spacing` | **No usar** (ver abajo). | — | según la guía del DS |
43
+ | `icon-button` | **No usar** hoy (ver abajo). | `icon="add-line"` | propuesta, falta aprobación |
44
+ | `text-button` | **No usar** hoy (ver abajo). | «Ver 12 más» | propuesta, falta aprobación |
45
+ | `icon-button-group` | **No usar** hoy (ver abajo). | Subir · agregar · bajar | propuesta, falta aprobación |
46
+ | `text-button-group` | **No usar** hoy (ver abajo). | «Producto» · «Sección» | propuesta, falta aprobación |
47
+
48
+ | propiedad | regla | fuente |
49
+ |---|---|---|
50
+ | `text` | Se escribe en sentence case («o», «Con pocos pedidos»): el componente lo pasa a MAYÚSCULAS. | propuesta, falta aprobación |
51
+ | `icon` | Solo en `icon-button`. Nombre Remix sin `ri-`. | propuesta, falta aprobación |
52
+ | `ariaLabel` | **Obligatorio en `icon-button`**: sin él el lector dice «Acción». | propuesta, falta aprobación |
53
+ | `items` | Solo en los `-group`: de 2 a 3, cada uno con `ariaLabel` si es ícono. | propuesta, falta aprobación |
54
+ | `disabled` | El botón existe pero hoy no aplica (lista ya completa). | propuesta, falta aprobación |
55
+
56
+ **Corregido el 03-10-2026:** los 2 «o» que estaban hechos a mano (login y registro) ya son `type="text-line"`.
57
+
58
+ ## No usar: por qué no hoy y cuándo sí
59
+
60
+ | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
61
+ |---|---|---|
62
+ | `line` y `line-spacing` | `sui-divider` hace lo mismo, pesa menos y tiene vertical; el espacio lo pone el `gap`. | Ninguno. |
63
+ | `icon-button` | No hay editores donde se inserte algo entre dos bloques. | «Agregar opción aquí» entre dos opciones en el editor de opciones del producto. |
64
+ | `text-button` | Ninguna pantalla de hoy corta una lista con un botón para ver el resto. | «Ver 12 más» al final de una lista cortada (reseñas, historial). |
65
+ | `icon-button-group` / `text-button-group` | No hay editores con bloques que se mueven o se insertan. | Mover, agregar o elegir qué insertar entre secciones de la carta. |
66
+
67
+ ## Tamaño en mobile y en web
68
+
69
+ Criterio de la app: **en mobile se lee y se toca con el dedo, así que va más grande; en web
70
+ (desktop), más chico.** Mobile es `≤ 767 px`, el mismo corte de `BreakpointsService.isMobile()`
71
+ en master-pedidos. Fuente: canon del dueño (03-10-2026), el mismo patrón que ya usan 27 controles
72
+ de la app.
73
+
74
+ | uso | mobile | web | fuente |
75
+ |---|---|---|---|
76
+ | Cualquiera | tamaño único | tamaño único | lo que hay en el DS |
77
+
78
+ **No tiene tamaños**: el texto mide 11–12 px y los botones 32 px en las dos plataformas. En mobile
79
+ los botones (`icon-button`, `text-button`, grupos) quedan debajo de los 44 px del dedo; es otra
80
+ razón para no usarlos hoy. Si un flujo nuevo los necesita en mobile, se pide al DS un tamaño grande.
81
+
82
+ ## API
83
+
84
+ <!-- api:inicio -->
85
+ <!-- generada: no editar a mano — `npm run docs` -->
86
+
87
+ | input | tipo | default |
88
+ |---|---|---|
89
+ | `type` | `'line' \| 'line-spacing' \| 'text-line' \| 'text' \| 'solid-text' \| 'icon-button' \| 'icon-button-group' \| 'text-button' \| 'text-button-group'` | `'line'` |
90
+ | `text` | `string` | `''` |
91
+ | `icon` | `string \| null` | `null` |
92
+ | `ariaLabel` | `string \| null` | `null` |
93
+ | `disabled` | `boolean` | `false` |
94
+ | `items` | `readonly SuiContentDividerItem[]` | `[]` |
95
+
96
+ | output | payload |
97
+ |---|---|
98
+ | `buttonClick` | `MouseEvent` |
99
+ | `itemClick` | `{ item: SuiContentDividerItem; index: number; event: MouseEvent }` |
100
+ <!-- api:fin -->
101
+
102
+ Outputs: `(buttonClick)` en `icon-button` y `text-button`; `(itemClick)` con
103
+ `{ item, index, event }` en los `-group`.
104
+
105
+ ## Trampas
106
+
107
+ - **Todo el texto sale en MAYÚSCULAS** por CSS: escribirlo normal.
108
+ - **`text` y `solid-text` alinean a la izquierda**, no al centro (así está en el Figma).
109
+ - `text-line` usa 11 px; `text` y `solid-text`, 12 px.
110
+ - Sin `ariaLabel`, el `icon-button` se anuncia como «Acción» y los ítems de grupo como
111
+ «Acción 0», «Acción 1».
112
+ - `line` y `line-spacing` existen, pero la línea sola es `sui-divider`.
113
+
114
+ ## Ejemplo
115
+
116
+ ```html
117
+ <!-- Login: Google o correo -->
118
+ <sui-social-button brand="google" label="Continuar con Google" />
119
+ <sui-content-divider type="text-line" text="o" />
120
+ <form>…</form>
121
+
122
+ <!-- Cabecera de grupo en una lista -->
123
+ <sui-content-divider type="solid-text" text="Con pocos pedidos" />
124
+ ```
@@ -0,0 +1,148 @@
1
+ ---
2
+ name: sui-content-label
3
+ selector: sui-content-label
4
+ resumen: Fila sin caja con ícono, foto o logo a la izquierda, título, descripción y un badge opcional
5
+ alternativas: [sui-content-card (la misma fila dentro de su propia cajita, con X), sui-switch-label (un ajuste que se prende o apaga), sui-alert (un aviso con color), sui-card (para agrupar las filas)]
6
+ ---
7
+
8
+ # sui-content-label
9
+
10
+ Story: [Molecules/Card/Content Label](https://sui-design-system.web.app/?path=/docs/molecules-card-content-label--docs)
11
+
12
+ ## Cuándo usarlo / cuándo no
13
+
14
+ **Úsalo** para una fila de lectura dentro de una superficie que ya pone el borde (una card, un
15
+ sheet): los consejos del perfil del repartidor y de mi-negocio, el resumen «dato → estado» al
16
+ terminar un registro, un negocio en una lista, «Contactar soporte».
17
+
18
+ **No lo uses** para:
19
+
20
+ - Una fila que necesita su propia caja o una X para quitarla: `sui-content-card`.
21
+ - Un ajuste que se prende o se apaga: `sui-switch-label` con `flip` (no el `toggle` de este).
22
+ - Un aviso que tiene que llamar la atención: `sui-alert`.
23
+ - Una opción que se elige: las cards de selección.
24
+
25
+ Regla corta: **fila de lectura dentro de una card → content-label · fila suelta con caja →
26
+ content-card · ajuste → switch-label.**
27
+
28
+ ## Qué variante usar
29
+
30
+ > **La guía del DS no tiene página del content label.** Lo que sigue es práctica de la app
31
+ > («propuesta») salvo lo que ya está aprobado («canon»).
32
+ >
33
+ > Uso medido el 03-10-2026 en `master-pedidos/src/app` (misma exclusión que `sui-card`): **18
34
+ > content-labels en 4 archivos**. Tipos: 14 `left-icon`, 3 `basic`, 1 `avatar`. Tamaños: 13
35
+ > `large` (los consejos), 1 `medium` explícito, 4 sin `size`. 4 con `badge` (3 a la derecha, 1 en
36
+ > el título). 0 con `toggle`, `sublabel` o `disabled`.
37
+
38
+ ### `type` (el leading)
39
+
40
+ | type | cuándo | fuente |
41
+ |---|---|---|
42
+ | `left-icon` (`icon`) | El ícono dice de qué va la fila: los consejos («Revisa tu zona de cobertura»), «Contactar soporte». Sale en un círculo con borde (`sui-key-icon` stroke). | propuesta (14 de 18) |
43
+ | `basic` | Fila de dato sin cara, casi siempre con badge: «Datos personales → Completados». | propuesta |
44
+ | `avatar` (`avatar`) | Una persona o un local. El color de las iniciales va por rol: local `orange`, repartidor `green`, cliente `blue`. | canon (avatar por rol) |
45
+ | `company` (`avatar` + `companyLogoSrc`) | Ver «No usar». | propuesta |
46
+ | `brand` (`brand`) | Ver «No usar». | propuesta |
47
+
48
+ ### `size`
49
+
50
+ | size | cuándo | fuente |
51
+ |---|---|---|
52
+ | `large` (leading 48, título 16) | Consejos y pasos que se leen, con descripción larga (los 13 de hoy). | propuesta |
53
+ | `medium` (leading 40, título 14, default) | Filas de dato en una lista: el negocio del repartidor, el resumen del registro. | propuesta |
54
+
55
+ ### Las piezas
56
+
57
+ | prop | cuándo | fuente |
58
+ |---|---|---|
59
+ | `label` | Siempre. En los consejos, una instrucción («Ponle foto a tus productos»); en los datos, el nombre del dato. | propuesta |
60
+ | `description` | La explicación o el detalle. En los consejos, el porqué. | propuesta |
61
+ | `badge` trailing (default) | El estado del dato a la derecha. Pasa el objeto con el color del badge: con string sale naranja. | propuesta |
62
+ | `badgePlacement="title"` | El badge pegado al nombre, cuando la derecha queda libre o es angosta («Sabores Andinos · Propio»). | propuesta |
63
+ | `sublabel` | Ver «No usar». | propuesta |
64
+ | `toggle` / `toggleChecked` | Ver «No usar». | propuesta |
65
+ | `disabled` | Ver «No usar». | propuesta |
66
+
67
+ **Usos de hoy que rompen las reglas:** 0. A mirar: los 3 badges de
68
+ `pages/driver-onboarding/step-complete/step-complete.html:48`–`:58` dicen estados de ciclo
69
+ («Completados», «Esperando vinculación»); el README de `sui-badge` deja esos en
70
+ `sui-status-badge`, pero el content-label solo recibe la config del badge.
71
+
72
+ ## Tamaño en mobile y en web
73
+
74
+ No se toca, así que no tiene que llegar a 44. El `size` es de lectura, no de dedo.
75
+
76
+ | uso | mobile | web |
77
+ |---|---|---|
78
+ | consejos y pasos | `large` | `large` |
79
+ | filas de dato | `medium` | `medium` |
80
+ | fila que se toca (soporte) | `large`, o dale a la fila un alto mínimo de 44 | `medium` |
81
+
82
+ ```html
83
+ <sui-content-label [size]="bp.isMobile() ? 'large' : 'medium'" … /> <!-- solo si la fila se toca -->
84
+ ```
85
+
86
+ ## «No usar»: por qué no hoy y cuándo sí
87
+
88
+ | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
89
+ |---|---|---|
90
+ | `toggle` (0 usos) | el switch es `medium` fijo (32 × 20) y la fila no se toca entera | nunca para un ajuste (es `sui-switch-label` con `flip`); un resumen de solo lectura en web |
91
+ | `sublabel` (0 usos) | ninguna fila lo pide | una precisión corta junto al nombre: «(opcional)», «(9 a. m. a 9 p. m.)» |
92
+ | `disabled` (0 usos) | ninguna fila está apagada | un paso del onboarding que todavía no aplica |
93
+ | `type="company"` (0 usos) | no se muestran empleados con su local | la fila de un empleado con el logo de su local |
94
+ | `type="brand"` (0 usos) | no hay servicios externos | un canal de contacto externo con su logo (WhatsApp) |
95
+
96
+ ## API
97
+
98
+ <!-- api:inicio -->
99
+ <!-- generada: no editar a mano — `npm run docs` -->
100
+
101
+ | input | tipo | default |
102
+ |---|---|---|
103
+ | `type` | `'basic' \| 'left-icon' \| 'avatar' \| 'brand' \| 'company'` | `'basic'` |
104
+ | `size` | `'medium' \| 'large'` | `'medium'` |
105
+ | `label` | `string` | `''` |
106
+ | `sublabel` | `string` | `''` |
107
+ | `description` | `string` | `''` |
108
+ | `icon` | `string \| null` | `null` |
109
+ | `avatar` | `SuiAvatarConfig \| string \| null` | `null` |
110
+ | `companyLogoSrc` | `string \| null` | `null` |
111
+ | `brand` | `SuiBrandLogoCompany \| null` | `null` |
112
+ | `badge` | `SuiBadgeConfig \| string \| null` | `null` |
113
+ | `badgePlacement` | `'trailing' \| 'title'` | `'trailing'` |
114
+ | `toggle` | `boolean` | `false` |
115
+ | `toggleChecked` | `boolean` | `false` |
116
+ | `disabled` | `boolean` | `false` |
117
+
118
+ | output | payload |
119
+ |---|---|
120
+ | `toggleCheckedChange` | `boolean` |
121
+ <!-- api:fin -->
122
+
123
+ ## Trampas
124
+
125
+ - **Aquí se llama `label` / `description`**; en `sui-content-card` la misma fila se llama
126
+ `title` / `subtitle`.
127
+ - **`badge` con string sale naranja `lighter` `medium`** (sin mayúsculas). En la content-card el
128
+ mismo string sale `small` (en MAYÚSCULAS).
129
+ - `avatar` acepta string (es el `src`) o `{ src, initials, color }`; sin `color` las iniciales
130
+ salen `slate`, no el color del rol.
131
+ - `left-icon` sin `icon` no dibuja nada a la izquierda.
132
+ - El `toggle` es un `sui-switch` `medium` fijo y solo el interruptor se toca, no la fila.
133
+ - El host lleva `role="group"` y `aria-label` = `label`.
134
+
135
+ ## Ejemplo
136
+
137
+ ```html
138
+ <!-- Consejo -->
139
+ <sui-content-label
140
+ type="left-icon"
141
+ size="large"
142
+ icon="camera-line"
143
+ label="Ponle foto a tus productos"
144
+ description="Desde dos productos con foto tu negocio sube en la lista. Las cargas en Productos." />
145
+
146
+ <!-- Dato con estado -->
147
+ <sui-content-label label="Datos personales" [badge]="{ label: 'Completados', color: 'green', variant: 'lighter' }" />
148
+ ```
@@ -0,0 +1,145 @@
1
+ ---
2
+ name: sui-counter-input
3
+ selector: sui-counter-input
4
+ resumen: Cantidad con − y + a los lados, con mínimo y máximo (unidades en el carrito, pasajeros)
5
+ alternativas: [sui-input type="number" (un número que se tipea, sin pasos de a uno), sui-slider (un valor de un rango continuo), sui-select (elegir una cantidad de una lista corta)]
6
+ ---
7
+
8
+ # sui-counter-input
9
+
10
+ Story: [Molecules/Input/Counter Input](https://sui-design-system.web.app/?path=/docs/molecules-input-counter-input--docs)
11
+
12
+ ## Cuándo usarlo / cuándo no
13
+
14
+ **Úsalo** para una cantidad chica que se ajusta de a uno y tiene tope: unidades de un producto
15
+ (carrito, detalle del producto), pasajeros de un viaje. Los botones se apagan solos al llegar al
16
+ mínimo o al máximo.
17
+
18
+ **No lo uses** para:
19
+
20
+ - Un número que se tipea entero (minutos, kilómetros, un monto): `sui-input` (`number` o `amount`).
21
+ - Una cantidad que arranca en cero y aparece al tocar «+» (los extras de un producto): hoy es un
22
+ armado propio con dos `sui-compact-button` en `components/product-detail-view/product-detail-view.html:169`,
23
+ y está bien así; el contador del DS siempre muestra los dos botones y el número.
24
+ - Quitar el producto: el contador baja hasta `min` y para. Borrar es otro botón (el tacho).
25
+
26
+ Regla corta: **se ajusta de a uno y tiene tope → counter · se tipea → input.**
27
+
28
+ ## Qué variante usar
29
+
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.
33
+ >
34
+ > Uso medido el 03-10-2026 en `master-pedidos/src/app` (misma exclusión que `sui-badge`, más
35
+ > `master-ejercicios`): **4 usos en 4 archivos**, todos con `min=1`. Tamaños: 2 `large`, 2 `medium`.
36
+ > 1 con `label`, 2 con `ariaLabel`, 2 sin ninguno de los dos.
37
+
38
+ | prop | cuándo | fuente |
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:82`) |
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:480`) |
42
+ | `step` | `1`. Otro paso no tiene caso hoy. | propuesta, falta aprobación |
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 |
48
+ | `error` + `errorMessage` | No usar hoy: el contador no deja salir del rango. | — |
49
+ | `required` · `sublabel` · `tooltip` | No usar hoy: una cantidad siempre tiene valor. | — |
50
+
51
+ **Usos de hoy que rompen la regla:**
52
+
53
+ - **2 sin `label` ni `ariaLabel`** (el lector de pantalla dice solo «grupo»):
54
+ `pages/customer/cart/cart.html:82`, `pages/customer/restaurant-menu/restaurant-menu.html:480`.
55
+ - **2 en `medium` en pantallas del teléfono** → `large`: `pages/customer/cart/cart.html:82`,
56
+ `pages/customer/viaje/viaje.html:190`.
57
+
58
+ ## Tamaño en mobile y en web
59
+
60
+ El campo llega a la escala completa del botón (2xsmall 28 · xsmall 32 · small 36 · medium 40 ·
61
+ large 48 · xlarge 52; la guía solo tiene 40, 36 y 32). **Los botones − y + crecen con el campo en
62
+ los tamaños de mobile**: 24 × 24 de `2xsmall` a `medium` (como la guía, el default no cambia), **40
63
+ × 40 en `large`** y **44 × 44 en `xlarge`**, ocupando todo el alto útil del campo (3 px de aire
64
+ dentro de la píldora). El ícono es de 20 hasta `large` y de 24 en `xlarge`.
65
+
66
+ | size | campo | botón − / + | fuente |
67
+ |---|---|---|---|
68
+ | `xlarge` | 52 | 44 | canon (aprobado por el dueño, 03-10-2026), extensión SUI |
69
+ | `large` | 48 | 40 | canon (aprobado por el dueño, 03-10-2026), extensión SUI |
70
+ | `medium` (default) · `small` · `xsmall` | 40 · 36 · 32 | 24 | según la guía del DS |
71
+ | `2xsmall` | 28 | 24 | extensión SUI |
72
+
73
+ | uso | mobile | web | fuente |
74
+ |---|---|---|---|
75
+ | cantidad junto al CTA (detalle del producto) | `large` (48), igual que el botón | `large` | propuesta (ya es práctica en `restaurant-menu.html:480`) |
76
+ | cantidad en una fila (carrito, pasajeros) | `large` (48) | `medium` (40) | propuesta, falta aprobación |
77
+
78
+ ```html
79
+ <sui-counter-input [size]="bp.isMobile() ? 'large' : 'medium'" … /> <!-- bp = BreakpointsService -->
80
+ ```
81
+
82
+ ## «No usar»: por qué no hoy y cuándo sí
83
+
84
+ | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
85
+ |---|---|---|
86
+ | `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 |
87
+ | `size="xlarge"` | el CTA de al lado es `large` | si el CTA del detalle pasa a `xlarge` |
88
+ | `step` distinto de 1 | no hay productos que se vendan de a varios | huevos por media docena, gaseosas por pack de 6 |
89
+ | `error` | el contador no deja salir del rango | el stock bajó con el carrito abierto y la cantidad ya no alcanza |
90
+ | `tooltip` · `sublabel` · `required` | una cantidad siempre tiene valor | — |
91
+
92
+ ## API
93
+
94
+ <!-- api:inicio -->
95
+ <!-- generada: no editar a mano — `npm run docs` -->
96
+
97
+ | input | tipo | default |
98
+ |---|---|---|
99
+ | `size` | `'2xsmall' \| 'xsmall' \| 'small' \| 'medium' \| 'large' \| 'xlarge'` | `'medium'` |
100
+ | `label` | `string \| null` | `null` |
101
+ | `sublabel` | `string \| null` | `null` |
102
+ | `required` | `boolean` | `false` |
103
+ | `tooltip` | `string \| null` | `null` |
104
+ | `hint` | `string \| null` | `null` |
105
+ | `error` | `boolean` | `false` |
106
+ | `errorMessage` | `string \| null` | `null` |
107
+ | `value` | `number` | `0` |
108
+ | `min` | `number` | `Number.NEGATIVE_INFINITY` |
109
+ | `max` | `number` | `Number.POSITIVE_INFINITY` |
110
+ | `step` | `number` | `1` |
111
+ | `disabled` | `boolean` | `false` |
112
+ | `ariaLabel` | `string \| null` | `null` |
113
+ | `decrementLabel` | `string` | `'Disminuir'` |
114
+ | `incrementLabel` | `string` | `'Aumentar'` |
115
+
116
+ | output | payload |
117
+ |---|---|
118
+ | `valueChange` | `number` |
119
+ <!-- api:fin -->
120
+
121
+ `value` es un `input` y `valueChange` un `output`: `[(value)]` funciona. Implementa
122
+ `ControlValueAccessor`.
123
+
124
+ ## Trampas
125
+
126
+ - **Es controlado**: al tocar − o + no cambia su número; emite `valueChange` con el valor nuevo
127
+ (ya recortado a `min`/`max`) y el padre lo aplica. Con solo `[value]` y sin `(valueChange)` el
128
+ número no se mueve.
129
+ - `min` y `max` arrancan en −∞ y +∞: sin pasarlos, el contador baja a negativos.
130
+ - Los botones de 24 px de `medium` para abajo no llegan a los 40 de un dedo: en mobile, `large`
131
+ o `xlarge` (ver «Tamaño en mobile y en web»).
132
+ - Sin `label` ni `ariaLabel` el grupo no tiene nombre para el lector de pantalla.
133
+ - El campo es una píldora (radio completo), decisión de SUI; el Figma de origen usa 10/8 px.
134
+
135
+ ## Ejemplo
136
+
137
+ ```html
138
+ <!-- En el detalle del producto, al lado del CTA -->
139
+ <sui-counter-input size="large" [min]="1" [max]="pdv.topeCantidad()"
140
+ ariaLabel="Cantidad" [value]="pdv.qty()" (valueChange)="pdv.setQty($event)" />
141
+
142
+ <!-- Campo de formulario -->
143
+ <sui-counter-input label="Pasajeros" hint="Hasta 4 pasajeros" [min]="1" [max]="4"
144
+ [size]="bp.isMobile() ? 'large' : 'medium'" [(value)]="pasajeros" />
145
+ ```
@@ -0,0 +1,98 @@
1
+ ---
2
+ name: sui-date-selector
3
+ selector: sui-date-selector
4
+ resumen: La cabecera de un calendario con el mes y las flechas de anterior y siguiente
5
+ alternativas: [sui-datepicker (el calendario completo, que ya la trae), sui-tab-chips (elegir entre pocos días: hoy, mañana, sábado)]
6
+ ---
7
+
8
+ # sui-date-selector
9
+
10
+ Story: [Molecules/Date & Time/Date Selector](https://sui-design-system.web.app/?path=/docs/molecules-date-time-date-selector--docs)
11
+
12
+ ## Cuándo usarlo / cuándo no
13
+
14
+ **Úsalo** como cabecera de un **calendario armado a mano** o de una vista que se recorre por
15
+ mes o por semana: «Octubre 2026» con flechas para ir al mes anterior o al siguiente (los gastos
16
+ del mes, las ganancias del repartidor por mes).
17
+
18
+ **No lo uses** para:
19
+
20
+ - Un calendario completo: `sui-datepicker` ya lo trae adentro.
21
+ - Elegir entre pocos días: `sui-tab-chips` (como la hoja de pedido programado).
22
+ - Cambiar entre períodos fijos («Hoy», «Esta semana», «Este mes»): `sui-tab-chips`, como el super admin.
23
+
24
+ ## Qué variante usar
25
+
26
+ > **La guía del DS no tiene página para este componente** (vive dentro del datepicker). Todo es
27
+ > **propuesta, falta aprobación**.
28
+ >
29
+ > Uso medido el 03-10-2026 en `master-pedidos/src/app`: **0 usos directos**. Lo usa por dentro
30
+ > `sui-datepicker`.
31
+
32
+ | input | valor | cuándo | fuente |
33
+ |---|---|---|---|
34
+ | `label` | texto | El período visible, con mayúscula inicial y sin abreviar: «Octubre 2026», «Semana del 6 al 12 de octubre». | propuesta |
35
+ | `leftIcon` + `rightIcon` | `true` / `true` (default) | Lo normal: se puede ir atrás y adelante. | propuesta |
36
+ | `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 |
37
+ | `leftIcon` | `false` | Ya se está en el primer período con datos (el mes en que se abrió el local). | propuesta |
38
+ | los dos en `false` | — | No usar: sin flechas es un título; va un texto. | no usar |
39
+ | `disabled` | `true` | Mientras carga el período nuevo, para que no se encadenen toques. | propuesta |
40
+
41
+ Usos de hoy que rompen la regla: **0**.
42
+
43
+ ## Tamaño en mobile y en web
44
+
45
+ **No tiene `size`.** Mide 288 × 36 y las flechas son `sui-compact-button` `large` de **24 px**:
46
+ en mobile **no llegan** a los 44 px.
47
+
48
+ | uso | mobile | web | fuente |
49
+ |---|---|---|---|
50
+ | cabecera de un período | — **no hay tamaño** | 288 × 36, flechas de 24 | medido |
51
+
52
+ ```html
53
+ <!-- Web -->
54
+ <sui-date-selector label="Octubre 2026" [rightIcon]="!esMesActual()" (prev)="mesAnterior()" (next)="mesSiguiente()" />
55
+ ```
56
+
57
+ **Sin tamaño suficiente para mobile.** En el celular, hasta que el DS le sume un `size`, se arma
58
+ con `sui-compact-button` `xlarge` (o `sui-button` `onlyIcon` `large`) a los lados de un título.
59
+
60
+ ## «No usar»: por qué no hoy y cuándo sí
61
+
62
+ | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
63
+ |---|---|---|
64
+ | todo el componente suelto (0 usos) | no hay vistas que se recorran mes a mes | ganancias del repartidor o gastos del super admin «por mes», en web |
65
+ | los dos íconos apagados | sin flechas es un título | ninguno |
66
+
67
+ ## API
68
+
69
+ <!-- api:inicio -->
70
+ <!-- generada: no editar a mano — `npm run docs` -->
71
+
72
+ | input | tipo | default |
73
+ |---|---|---|
74
+ | `label` | `string` | — (requerido) |
75
+ | `leftIcon` | `boolean` | `true` |
76
+ | `rightIcon` | `boolean` | `true` |
77
+ | `disabled` | `boolean` | `false` |
78
+
79
+ | output | payload |
80
+ |---|---|
81
+ | `prev` | `void` |
82
+ | `next` | `void` |
83
+ <!-- api:fin -->
84
+
85
+ ## Trampas
86
+
87
+ - **`leftIcon` y `rightIcon` son booleanos**, no nombres de ícono: prenden o apagan las flechas.
88
+ - **Ancho fijo de 288 px** (`max-width` incluido): no se estira con el contenedor.
89
+ - Con una flecha apagada queda un hueco de 24 px para que el texto siga centrado.
90
+ - El componente **no sabe de fechas**: el texto lo arma quien lo usa y las flechas solo emiten.
91
+ - Los `aria-label` de las flechas dicen «Mes anterior» y «Mes siguiente» aunque el período sea
92
+ una semana.
93
+
94
+ ## Ejemplo
95
+
96
+ ```html
97
+ <sui-date-selector label="Octubre 2026" [rightIcon]="false" (prev)="mesAnterior()" />
98
+ ```