@studiolxd/brand 41.1.0 → 42.0.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.
- package/CHANGELOG.md +65 -0
- package/dist/_types/atoms/AsyncMultiSelect/AsyncMultiSelect.d.ts +28 -5
- package/dist/_types/atoms/AsyncSelect/AsyncSelect.d.ts +26 -6
- package/dist/_types/atoms/InputPhone/InputPhone.d.ts +15 -4
- package/dist/_types/atoms/MultiSelect/MultiSelect.d.ts +20 -1
- package/dist/_types/atoms/NumberInput/NumberInput.d.ts +14 -4
- package/dist/_types/atoms/OtpInput/OtpInput.d.ts +15 -4
- package/dist/_types/atoms/Select/Select.d.ts +18 -1
- package/dist/_types/messages/BrandMessages.d.ts +25 -1
- package/dist/_types/messages/index.d.ts +1 -1
- package/dist/_types/molecules/DocsSearch/DocsSearch.d.ts +31 -12
- package/dist/_types/molecules/FilterBar/FilterBar.d.ts +10 -1
- package/dist/_types/molecules/InputField/InputField.d.ts +16 -2
- package/dist/_types/molecules/MultiSelectField/MultiSelectField.d.ts +9 -1
- package/dist/_types/molecules/PasswordField/PasswordField.d.ts +22 -2
- package/dist/_types/molecules/SearchForm/SearchForm.d.ts +18 -6
- package/dist/_types/molecules/SelectField/SelectField.d.ts +5 -0
- package/dist/async-multi-select.js +50 -49
- package/dist/async-select.js +89 -88
- package/dist/docs-search.js +38 -37
- package/dist/filter-bar.css +1 -1
- package/dist/filter-bar.js +19 -17
- package/dist/input-field.js +66 -65
- package/dist/input-phone.js +39 -38
- package/dist/multi-select.js +109 -108
- package/dist/number-input.js +61 -60
- package/dist/otp-input.js +86 -85
- package/dist/password-field.js +46 -45
- package/dist/search-form.js +35 -34
- package/dist/select.js +75 -71
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,71 @@ El paquete sigue [semver](https://semver.org/lang/es/): **patch** para bug fixes
|
|
|
7
7
|
regeneración de `dist`, **minor** para componentes/props/variantes/tokens nuevos, **major**
|
|
8
8
|
para breaking changes.
|
|
9
9
|
|
|
10
|
+
## [42.0.0] — 2026-09-15
|
|
11
|
+
|
|
12
|
+
> **Major.** Tercera familia al proveedor de textos: los átomos y moléculas de formulario
|
|
13
|
+
> dejan de traer castellano puesto. Y la barra de filtros apila de verdad por debajo del
|
|
14
|
+
> punto de ruptura, no solo cuando la aritmética de la rejilla lo permitía.
|
|
15
|
+
|
|
16
|
+
### Los formularios leen del proveedor
|
|
17
|
+
|
|
18
|
+
Doce componentes, doce espacios nuevos en `BrandMessages`: `inputField`, `passwordField`,
|
|
19
|
+
`select`, `multiSelect`, `numberInput`, `otpInput`, `inputPhone`, `asyncSelect`,
|
|
20
|
+
`asyncMultiSelect`, `searchForm`, `docsSearch` y `filterBar`. Los `*Field` que los envuelven
|
|
21
|
+
son reenvío puro y no tienen espacio propio: pasan la prop al átomo, y el átomo lee del
|
|
22
|
+
catálogo. Mismo orden que en las dos olas anteriores —**prop → proveedor → error**— y
|
|
23
|
+
mismo carácter: incompatible **en tiempo de compilación**, que es lo que se busca.
|
|
24
|
+
|
|
25
|
+
Esta familia iba ahora, y no más tarde, por un reenvío: `DataTable` pasaba
|
|
26
|
+
`searchClearLabel` a un `InputField` que seguía con su «Borrar» cableado, así que las
|
|
27
|
+
tablas no quedaban limpias del todo en una aplicación francesa hasta que cayera el átomo.
|
|
28
|
+
Ese reenvío está cerrado. Y de paso se ha visto lo que tapaba: `removeLabel`,
|
|
29
|
+
`decrementLabel`, `incrementLabel`, `digitLabel`, `countryLabel` y `loadingLabel` **no se
|
|
30
|
+
pasaban en ningún sitio de la suite** — esos controles salían en castellano dentro de las
|
|
31
|
+
aplicaciones en francés, alemán, neerlandés y portugués, y nadie lo había parcheado porque
|
|
32
|
+
nadie lo veía. Con el proveedor se corrigen sin tocar un solo punto de uso.
|
|
33
|
+
|
|
34
|
+
### Lo que se queda como prop, y las dudosas
|
|
35
|
+
|
|
36
|
+
`label`, `helperText`, `errorMessage` y el `placeholder` que dice algo del campo son
|
|
37
|
+
**contenido de ese campo** y siguen siendo props; ninguno traía castellano que retirar. Las
|
|
38
|
+
que hubo que decidir mirando **el valor y no el nombre**: `Select.placeholder`
|
|
39
|
+
(«Seleccionar…») es cromo, y la prop gana cuando el marcador dice algo del campo;
|
|
40
|
+
`SearchForm.label` («Buscar») es cromo, porque el buscador de sitio se llama igual en toda
|
|
41
|
+
la suite; `AsyncSelect.emptyMessage` («Sin resultados») es cromo, con la prop intacta para
|
|
42
|
+
un vacío propio. `DocsSearch.clearLabel` no tiene clave: el aspa es la del `InputField` de
|
|
43
|
+
debajo, y darle clave obligaría a traducir «Borrar» dos veces y a que coincidieran.
|
|
44
|
+
`InputPhone.internationalLabel` conserva su «🌐»: un glifo no se traduce.
|
|
45
|
+
|
|
46
|
+
El sistema **no tiene marca de obligatorio ni de «opcional»** — ni `Label` ni ningún
|
|
47
|
+
`*Field` la emiten. No había nada que migrar ahí; si algún día se quiere, es una pieza
|
|
48
|
+
nueva.
|
|
49
|
+
|
|
50
|
+
### `FilterBar`: una columna por debajo de `md`, de verdad
|
|
51
|
+
|
|
52
|
+
Su documentación prometía una columna por debajo del punto de ruptura y sus acciones sí
|
|
53
|
+
conmutaban ahí, pero los filtros se dejaban a la aritmética de la rejilla
|
|
54
|
+
(`minmax(min(192px, 100%), 1fr)`), que solo apila por fuerza por debajo de unos 400px.
|
|
55
|
+
Medido en Chromium: a 320 y 390px, una columna; **a 430, 600, 700 y 760px, dos o tres
|
|
56
|
+
columnas y un selector a media línea**. Es justo lo que se veía en un teléfono apaisado.
|
|
57
|
+
Ahora la base es `1fr` y la rejilla `auto-fill` vive dentro del `@media (min-width: 768px)`
|
|
58
|
+
que ya existía.
|
|
59
|
+
|
|
60
|
+
El test que debía haberlo cogido medía la caja equivocada: comprobaba que la **celda**
|
|
61
|
+
llenaba la línea —y lo hacía siempre—, no el **control** de dentro, que era lo que se
|
|
62
|
+
quedaba corto, y solo en una franja que ningún preset de ventana de Storybook toca. El test
|
|
63
|
+
nuevo mide el control y mide a 600px.
|
|
64
|
+
|
|
65
|
+
`FilterBar` pasa a ser componente cliente: leer del contexto lo exige.
|
|
66
|
+
|
|
67
|
+
### Un solo fixture inglés para las historias
|
|
68
|
+
|
|
69
|
+
Las historias «Textos desde el proveedor (otro idioma)» de esta ola y de las dos anteriores
|
|
70
|
+
importan un único `.storybook/brandMessagesFixtureEn.ts`, hermano del castellano, en vez de
|
|
71
|
+
repetir el literal en cada una. El test que vigila que ningún fixture se publica ahora
|
|
72
|
+
enumera lo que hay en `.storybook/`, así que el de la próxima ola queda cubierto por
|
|
73
|
+
existir.
|
|
74
|
+
|
|
10
75
|
## [41.1.0] — 2026-09-15
|
|
11
76
|
|
|
12
77
|
> **Minor.** El interruptor de la barra de filtros se centra con el campo que tiene al
|
|
@@ -4,6 +4,21 @@ export interface AsyncMultiSelectOption {
|
|
|
4
4
|
value: string;
|
|
5
5
|
label: string;
|
|
6
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* Los textos que el control emite por su cuenta. Todos son cromo: dicen lo
|
|
9
|
+
* mismo en toda la suite y no hablan de lo que se busca. Lo que sí es de esta
|
|
10
|
+
* pantalla —las opciones que devuelve `onSearch`— no pasa por aquí.
|
|
11
|
+
*/
|
|
12
|
+
export interface AsyncMultiSelectMessages {
|
|
13
|
+
/** Pista dentro del campo de búsqueda. */
|
|
14
|
+
placeholder: string;
|
|
15
|
+
/** Aviso cuando la búsqueda no devuelve opciones. */
|
|
16
|
+
empty: string;
|
|
17
|
+
/** Nombre accesible del spinner mientras se busca. */
|
|
18
|
+
loading: string;
|
|
19
|
+
/** Nombre accesible del aspa de cada ficha, con la etiqueta de su opción. */
|
|
20
|
+
remove: (label: string) => string;
|
|
21
|
+
}
|
|
7
22
|
export interface AsyncMultiSelectProps {
|
|
8
23
|
onSearch: (query: string) => Promise<AsyncMultiSelectOption[]>;
|
|
9
24
|
value?: string[];
|
|
@@ -21,6 +36,10 @@ export interface AsyncMultiSelectProps {
|
|
|
21
36
|
* componente las recuerda—, solo para los valores de `defaultValue`.
|
|
22
37
|
*/
|
|
23
38
|
selectedOptions?: AsyncMultiSelectOption[];
|
|
39
|
+
/**
|
|
40
|
+
* Pista dentro del campo de búsqueda. **Sin default**: sale de la clave
|
|
41
|
+
* `placeholder` del espacio de este control.
|
|
42
|
+
*/
|
|
24
43
|
placeholder?: string;
|
|
25
44
|
disabled?: boolean;
|
|
26
45
|
readOnly?: boolean;
|
|
@@ -53,16 +72,20 @@ export interface AsyncMultiSelectProps {
|
|
|
53
72
|
*/
|
|
54
73
|
'aria-label'?: string;
|
|
55
74
|
'aria-describedby'?: string;
|
|
56
|
-
/**
|
|
75
|
+
/**
|
|
76
|
+
* aria-label del botón que quita un valor. **Sin default**: sale de
|
|
77
|
+
* `asyncMultiSelect.remove`.
|
|
78
|
+
*/
|
|
57
79
|
removeLabel?: (label: string) => string;
|
|
58
80
|
/**
|
|
59
|
-
* Texto mostrado cuando la búsqueda no devuelve opciones.
|
|
60
|
-
*
|
|
81
|
+
* Texto mostrado cuando la búsqueda no devuelve opciones. **Sin default**:
|
|
82
|
+
* sale de la clave `empty` del espacio de este control en el
|
|
83
|
+
* `BrandMessagesProvider`.
|
|
61
84
|
*/
|
|
62
85
|
emptyMessage?: string;
|
|
63
86
|
/**
|
|
64
|
-
* Etiqueta accesible del spinner mientras se busca.
|
|
65
|
-
*
|
|
87
|
+
* Etiqueta accesible del spinner mientras se busca. **Sin default**: sale de
|
|
88
|
+
* la clave `loading` del espacio de este control.
|
|
66
89
|
*/
|
|
67
90
|
loadingLabel?: string;
|
|
68
91
|
/**
|
|
@@ -4,12 +4,31 @@ export interface AsyncSelectOption {
|
|
|
4
4
|
value: string;
|
|
5
5
|
label: string;
|
|
6
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* Los textos que el control emite por su cuenta. Todos son cromo: dicen lo
|
|
9
|
+
* mismo en toda la suite y no hablan de lo que se busca. Lo que sí es de esta
|
|
10
|
+
* pantalla —las opciones que devuelve `onSearch`— no pasa por aquí.
|
|
11
|
+
*/
|
|
12
|
+
export interface AsyncSelectMessages {
|
|
13
|
+
/** Pista dentro del campo de búsqueda. */
|
|
14
|
+
placeholder: string;
|
|
15
|
+
/** Aviso cuando la búsqueda no devuelve opciones. */
|
|
16
|
+
empty: string;
|
|
17
|
+
/** Nombre accesible del spinner mientras se busca. */
|
|
18
|
+
loading: string;
|
|
19
|
+
/** Nombre accesible del botón que vacía la selección. */
|
|
20
|
+
clear: string;
|
|
21
|
+
}
|
|
7
22
|
export interface AsyncSelectProps {
|
|
8
23
|
onSearch: (query: string) => Promise<AsyncSelectOption[]>;
|
|
9
24
|
value?: string | null;
|
|
10
25
|
onValueChange?: (value: string | null, option: AsyncSelectOption | null) => void;
|
|
11
26
|
/** Label of the currently selected option — required when `value` is set so the component can display it */
|
|
12
27
|
selectedOption?: AsyncSelectOption | null;
|
|
28
|
+
/**
|
|
29
|
+
* Pista dentro del campo de búsqueda. **Sin default**: sale de la clave
|
|
30
|
+
* `placeholder` del espacio de este control.
|
|
31
|
+
*/
|
|
13
32
|
placeholder?: string;
|
|
14
33
|
disabled?: boolean;
|
|
15
34
|
readOnly?: boolean;
|
|
@@ -43,18 +62,19 @@ export interface AsyncSelectProps {
|
|
|
43
62
|
'aria-label'?: string;
|
|
44
63
|
'aria-describedby'?: string;
|
|
45
64
|
/**
|
|
46
|
-
* Texto mostrado cuando la búsqueda no devuelve opciones.
|
|
47
|
-
*
|
|
65
|
+
* Texto mostrado cuando la búsqueda no devuelve opciones. **Sin default**:
|
|
66
|
+
* sale de la clave `empty` del espacio de este control en el
|
|
67
|
+
* `BrandMessagesProvider`.
|
|
48
68
|
*/
|
|
49
69
|
emptyMessage?: string;
|
|
50
70
|
/**
|
|
51
|
-
* Etiqueta accesible del spinner mientras se busca.
|
|
52
|
-
*
|
|
71
|
+
* Etiqueta accesible del spinner mientras se busca. **Sin default**: sale de
|
|
72
|
+
* la clave `loading` del espacio de este control.
|
|
53
73
|
*/
|
|
54
74
|
loadingLabel?: string;
|
|
55
75
|
/**
|
|
56
|
-
* aria-label del botón de limpiar selección.
|
|
57
|
-
*
|
|
76
|
+
* aria-label del botón de limpiar selección. **Sin default**: sale de
|
|
77
|
+
* `asyncSelect.clear`.
|
|
58
78
|
*/
|
|
59
79
|
clearLabel?: string;
|
|
60
80
|
/**
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { Select as BaseSelect } from '@base-ui/react/select';
|
|
2
2
|
import type { Country } from 'react-phone-number-input';
|
|
3
3
|
import './InputPhone.css';
|
|
4
|
+
/**
|
|
5
|
+
* El único texto que el campo emite por su cuenta: el nombre accesible del
|
|
6
|
+
* selector de país. Los **nombres de los países** no están aquí: los resuelve
|
|
7
|
+
* `Intl` desde el `locale`, como los meses y las fechas.
|
|
8
|
+
*/
|
|
9
|
+
export interface InputPhoneMessages {
|
|
10
|
+
/** Nombre accesible del selector de prefijo/país. */
|
|
11
|
+
country: string;
|
|
12
|
+
}
|
|
4
13
|
export interface InputPhoneProps {
|
|
5
14
|
value?: string;
|
|
6
15
|
defaultCountry?: Country;
|
|
@@ -24,14 +33,16 @@ export interface InputPhoneProps {
|
|
|
24
33
|
onBlur?: React.FocusEventHandler<HTMLInputElement>;
|
|
25
34
|
onFocus?: React.FocusEventHandler<HTMLInputElement>;
|
|
26
35
|
/**
|
|
27
|
-
* aria-label del selector de país.
|
|
28
|
-
*
|
|
36
|
+
* aria-label del selector de país. **Sin default**: sale de
|
|
37
|
+
* `inputPhone.country` del `BrandMessagesProvider`.
|
|
29
38
|
*/
|
|
30
39
|
countryLabel?: string;
|
|
31
40
|
/**
|
|
32
41
|
* Lo que enseña el selector cuando no hay país elegido (número en formato
|
|
33
|
-
* internacional). Default: "🌐".
|
|
34
|
-
*
|
|
42
|
+
* internacional). Default: "🌐". **No pasa por el catálogo de textos a
|
|
43
|
+
* propósito**: un glifo no se traduce, dice lo mismo en los seis idiomas y
|
|
44
|
+
* meterlo en el catálogo obligaría a repetirlo seis veces. Una app que no
|
|
45
|
+
* quiera el emoji pasa aquí su propio texto o glifo.
|
|
35
46
|
*/
|
|
36
47
|
internationalLabel?: string;
|
|
37
48
|
/**
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import { Popover as BasePopover } from '@base-ui/react/popover';
|
|
2
2
|
import './MultiSelect.css';
|
|
3
|
+
/**
|
|
4
|
+
* Los dos textos que el control emite por su cuenta: el marcador de sitio sin
|
|
5
|
+
* nada elegido y el nombre del aspa de cada ficha. Los dos son cromo — dicen
|
|
6
|
+
* lo mismo en toda la suite, y el segundo solo interpola la etiqueta de la
|
|
7
|
+
* opción, que es un dato.
|
|
8
|
+
*/
|
|
9
|
+
export interface MultiSelectMessages {
|
|
10
|
+
/** Marcador de sitio de la caja sin valores elegidos. */
|
|
11
|
+
placeholder: string;
|
|
12
|
+
/** Nombre accesible del aspa de una ficha, con la etiqueta de su opción. */
|
|
13
|
+
remove: (label: string) => string;
|
|
14
|
+
}
|
|
3
15
|
export interface MultiSelectOption {
|
|
4
16
|
value: string;
|
|
5
17
|
label: string;
|
|
@@ -9,6 +21,10 @@ export interface MultiSelectProps {
|
|
|
9
21
|
options: MultiSelectOption[];
|
|
10
22
|
value?: string[];
|
|
11
23
|
defaultValue?: string[];
|
|
24
|
+
/**
|
|
25
|
+
* Marcador de sitio sin valores elegidos. **Sin default**: sale de
|
|
26
|
+
* `multiSelect.placeholder` del `BrandMessagesProvider`.
|
|
27
|
+
*/
|
|
12
28
|
placeholder?: string;
|
|
13
29
|
disabled?: boolean;
|
|
14
30
|
readOnly?: boolean;
|
|
@@ -32,7 +48,10 @@ export interface MultiSelectProps {
|
|
|
32
48
|
'aria-labelledby'?: string;
|
|
33
49
|
/** Ids de ayuda/error que describen el control (lo pone el campo). */
|
|
34
50
|
'aria-describedby'?: string;
|
|
35
|
-
/**
|
|
51
|
+
/**
|
|
52
|
+
* aria-label del botón que quita un valor. **Sin default**: sale de
|
|
53
|
+
* `multiSelect.remove` del `BrandMessagesProvider`.
|
|
54
|
+
*/
|
|
36
55
|
removeLabel?: (label: string) => string;
|
|
37
56
|
/**
|
|
38
57
|
* Nodo DOM donde montar el portal del dropdown (reenviado a Base UI
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { type ComponentPropsWithoutRef } from 'react';
|
|
2
2
|
import './NumberInput.css';
|
|
3
|
+
/**
|
|
4
|
+
* Los dos textos que el control emite por su cuenta: los nombres accesibles de
|
|
5
|
+
* sus dos botones. Cromo puro — no dicen nada de qué se cuenta.
|
|
6
|
+
*/
|
|
7
|
+
export interface NumberInputMessages {
|
|
8
|
+
/** Nombre accesible del botón que resta un paso. */
|
|
9
|
+
decrement: string;
|
|
10
|
+
/** Nombre accesible del botón que suma un paso. */
|
|
11
|
+
increment: string;
|
|
12
|
+
}
|
|
3
13
|
export interface NumberInputProps extends Omit<ComponentPropsWithoutRef<'input'>, 'size' | 'type' | 'value' | 'defaultValue' | 'onChange'> {
|
|
4
14
|
value?: number;
|
|
5
15
|
defaultValue?: number;
|
|
@@ -20,13 +30,13 @@ export interface NumberInputProps extends Omit<ComponentPropsWithoutRef<'input'>
|
|
|
20
30
|
/** Se añade DESPUÉS de las clases propias del componente (el consumidor añade, no sustituye). */
|
|
21
31
|
className?: string;
|
|
22
32
|
/**
|
|
23
|
-
* aria-label del botón de decremento.
|
|
24
|
-
*
|
|
33
|
+
* aria-label del botón de decremento. **Sin default**: sale de
|
|
34
|
+
* `numberInput.decrement` del `BrandMessagesProvider`.
|
|
25
35
|
*/
|
|
26
36
|
decrementLabel?: string;
|
|
27
37
|
/**
|
|
28
|
-
* aria-label del botón de incremento.
|
|
29
|
-
*
|
|
38
|
+
* aria-label del botón de incremento. **Sin default**: sale de
|
|
39
|
+
* `numberInput.increment` del `BrandMessagesProvider`.
|
|
30
40
|
*/
|
|
31
41
|
incrementLabel?: string;
|
|
32
42
|
onChange?: (value: number) => void;
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
import './OtpInput.css';
|
|
2
|
+
/**
|
|
3
|
+
* Los textos que el control emite por su cuenta: el nombre del grupo cuando va
|
|
4
|
+
* suelto y el de cada celda. Cromo — el segundo solo interpola la posición de
|
|
5
|
+
* la celda, que es una cifra.
|
|
6
|
+
*/
|
|
7
|
+
export interface OtpInputMessages {
|
|
8
|
+
/** Nombre accesible del grupo de celdas cuando el control va suelto. */
|
|
9
|
+
group: string;
|
|
10
|
+
/** Nombre accesible de una celda, con su posición y el total. */
|
|
11
|
+
digit: (index: number, length: number) => string;
|
|
12
|
+
}
|
|
2
13
|
export interface OtpInputProps {
|
|
3
14
|
/** Número de celdas a renderizar. Requerido. */
|
|
4
15
|
length: number;
|
|
@@ -22,8 +33,8 @@ export interface OtpInputProps {
|
|
|
22
33
|
'aria-labelledby'?: string;
|
|
23
34
|
/**
|
|
24
35
|
* Nombre accesible del grupo cuando no se pasa `aria-label` ni
|
|
25
|
-
* `aria-labelledby` — el caso del control suelto.
|
|
26
|
-
*
|
|
36
|
+
* `aria-labelledby` — el caso del control suelto. **Sin default**: sale de
|
|
37
|
+
* `otpInput.group` del `BrandMessagesProvider`.
|
|
27
38
|
*/
|
|
28
39
|
groupLabel?: string;
|
|
29
40
|
id?: string;
|
|
@@ -39,8 +50,8 @@ export interface OtpInputProps {
|
|
|
39
50
|
/** Se añade DESPUÉS de las clases propias del componente. */
|
|
40
51
|
className?: string;
|
|
41
52
|
/**
|
|
42
|
-
* Etiqueta accesible de cada celda.
|
|
43
|
-
*
|
|
53
|
+
* Etiqueta accesible de cada celda. **Sin default**: sale de
|
|
54
|
+
* `otpInput.digit` del `BrandMessagesProvider`.
|
|
44
55
|
*/
|
|
45
56
|
digitLabel?: (index: number, length: number) => string;
|
|
46
57
|
}
|
|
@@ -2,6 +2,18 @@ import type { ReactNode } from 'react';
|
|
|
2
2
|
import { Select as BaseSelect } from '@base-ui/react/select';
|
|
3
3
|
import type { SeparatorProps as BaseSeparatorProps } from '@base-ui/react/separator';
|
|
4
4
|
import './Select.css';
|
|
5
|
+
/**
|
|
6
|
+
* El único texto que el desplegable emite por su cuenta: el marcador de sitio
|
|
7
|
+
* genérico del disparador, el que dice «aquí no has elegido nada todavía».
|
|
8
|
+
*
|
|
9
|
+
* Es cromo, no contenido: cuando el marcador dice algo de ESTE campo («Elige
|
|
10
|
+
* un país») lo escribe quien monta el campo y viaja por la prop `placeholder`,
|
|
11
|
+
* que sigue ganando. Las **opciones** tampoco están aquí: son datos.
|
|
12
|
+
*/
|
|
13
|
+
export interface SelectMessages {
|
|
14
|
+
/** Marcador de sitio del disparador sin valor elegido. */
|
|
15
|
+
placeholder: string;
|
|
16
|
+
}
|
|
5
17
|
export interface SelectOption {
|
|
6
18
|
value: string;
|
|
7
19
|
label: string;
|
|
@@ -34,7 +46,12 @@ export interface SelectProps {
|
|
|
34
46
|
options: SelectOptionOrGroup[];
|
|
35
47
|
value?: string;
|
|
36
48
|
defaultValue?: string;
|
|
37
|
-
/**
|
|
49
|
+
/**
|
|
50
|
+
* Placeholder del trigger. **Sin default**: sale de `select.placeholder` del
|
|
51
|
+
* `BrandMessagesProvider`, y esta prop es la anulación puntual cuando el
|
|
52
|
+
* marcador dice algo de este campo concreto. En la API compuesta lo pone cada
|
|
53
|
+
* consumidor vía `Select.Value`.
|
|
54
|
+
*/
|
|
38
55
|
placeholder?: string;
|
|
39
56
|
disabled?: boolean;
|
|
40
57
|
readOnly?: boolean;
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
import type { PaginationMessages } from '../molecules/Pagination/Pagination';
|
|
2
2
|
import type { TableMessages } from '../molecules/Table/Table';
|
|
3
3
|
import type { DataTableMessages } from '../organisms/DataTable/DataTable';
|
|
4
|
+
import type { InputFieldMessages } from '../molecules/InputField/InputField';
|
|
5
|
+
import type { PasswordFieldMessages } from '../molecules/PasswordField/PasswordField';
|
|
6
|
+
import type { SelectMessages } from '../atoms/Select/Select';
|
|
7
|
+
import type { MultiSelectMessages } from '../atoms/MultiSelect/MultiSelect';
|
|
8
|
+
import type { NumberInputMessages } from '../atoms/NumberInput/NumberInput';
|
|
9
|
+
import type { OtpInputMessages } from '../atoms/OtpInput/OtpInput';
|
|
10
|
+
import type { InputPhoneMessages } from '../atoms/InputPhone/InputPhone';
|
|
11
|
+
import type { AsyncSelectMessages } from '../atoms/AsyncSelect/AsyncSelect';
|
|
12
|
+
import type { AsyncMultiSelectMessages } from '../atoms/AsyncMultiSelect/AsyncMultiSelect';
|
|
13
|
+
import type { DocsSearchMessages } from '../molecules/DocsSearch/DocsSearch';
|
|
14
|
+
import type { SearchFormMessages } from '../molecules/SearchForm/SearchForm';
|
|
15
|
+
import type { FilterBarMessages } from '../molecules/FilterBar/FilterBar';
|
|
4
16
|
/**
|
|
5
17
|
* El contrato de textos de la librería: un espacio por componente, y dentro
|
|
6
18
|
* de cada espacio **todas las claves obligatorias**.
|
|
@@ -26,5 +38,17 @@ export interface BrandMessages {
|
|
|
26
38
|
pagination: PaginationMessages;
|
|
27
39
|
table: TableMessages;
|
|
28
40
|
dataTable: DataTableMessages;
|
|
41
|
+
inputField: InputFieldMessages;
|
|
42
|
+
passwordField: PasswordFieldMessages;
|
|
43
|
+
select: SelectMessages;
|
|
44
|
+
multiSelect: MultiSelectMessages;
|
|
45
|
+
numberInput: NumberInputMessages;
|
|
46
|
+
otpInput: OtpInputMessages;
|
|
47
|
+
inputPhone: InputPhoneMessages;
|
|
48
|
+
asyncSelect: AsyncSelectMessages;
|
|
49
|
+
asyncMultiSelect: AsyncMultiSelectMessages;
|
|
50
|
+
docsSearch: DocsSearchMessages;
|
|
51
|
+
searchForm: SearchFormMessages;
|
|
52
|
+
filterBar: FilterBarMessages;
|
|
29
53
|
}
|
|
30
|
-
export type { PaginationMessages, TableMessages, DataTableMessages };
|
|
54
|
+
export type { PaginationMessages, TableMessages, DataTableMessages, InputFieldMessages, PasswordFieldMessages, SelectMessages, MultiSelectMessages, NumberInputMessages, OtpInputMessages, InputPhoneMessages, AsyncSelectMessages, AsyncMultiSelectMessages, DocsSearchMessages, SearchFormMessages, FilterBarMessages, };
|
|
@@ -2,4 +2,4 @@ export { BrandMessagesProvider } from './BrandMessagesProvider';
|
|
|
2
2
|
export type { BrandMessagesProviderProps } from './BrandMessagesProvider';
|
|
3
3
|
export { useBrandMessages } from './BrandMessagesContext';
|
|
4
4
|
export type { BrandMessagesReader } from './BrandMessagesContext';
|
|
5
|
-
export type { BrandMessages, PaginationMessages, TableMessages, DataTableMessages, } from './BrandMessages';
|
|
5
|
+
export type { BrandMessages, PaginationMessages, TableMessages, DataTableMessages, InputFieldMessages, PasswordFieldMessages, SelectMessages, MultiSelectMessages, NumberInputMessages, OtpInputMessages, InputPhoneMessages, AsyncSelectMessages, AsyncMultiSelectMessages, DocsSearchMessages, SearchFormMessages, FilterBarMessages, } from './BrandMessages';
|
|
@@ -17,6 +17,27 @@ export type DocsSearchRenderLinkProps = React.AnchorHTMLAttributes<HTMLAnchorEle
|
|
|
17
17
|
href: string;
|
|
18
18
|
className: string;
|
|
19
19
|
};
|
|
20
|
+
/**
|
|
21
|
+
* Los textos que el buscador emite por su cuenta. Los seis son cromo: en toda
|
|
22
|
+
* la suite el buscador de la documentación se llama igual y avisa igual. Los
|
|
23
|
+
* **resultados** no están aquí — son datos que llegan por `results`.
|
|
24
|
+
*
|
|
25
|
+
* El nombre del aspa tampoco: el aspa es la del `InputField` que hay debajo y
|
|
26
|
+
* sale de `inputField.clear`. Es la misma palabra y el mismo botón; darle una
|
|
27
|
+
* clave propia solo obligaría a traducir «Borrar» dos veces.
|
|
28
|
+
*/
|
|
29
|
+
export interface DocsSearchMessages {
|
|
30
|
+
/** Etiqueta del campo, que nombra también el punto de referencia. */
|
|
31
|
+
label: string;
|
|
32
|
+
/** Pista dentro del campo. */
|
|
33
|
+
placeholder: string;
|
|
34
|
+
/** Nombre accesible de la lista de resultados. */
|
|
35
|
+
results: string;
|
|
36
|
+
/** Aviso cuando la búsqueda no encuentra nada. */
|
|
37
|
+
empty: string;
|
|
38
|
+
/** Aviso mientras se busca. */
|
|
39
|
+
loading: string;
|
|
40
|
+
}
|
|
20
41
|
export interface DocsSearchProps {
|
|
21
42
|
/** `id` del campo. Ata la etiqueta con el campo y el campo con la lista. */
|
|
22
43
|
id?: string;
|
|
@@ -29,15 +50,14 @@ export interface DocsSearchProps {
|
|
|
29
50
|
/** Hay una búsqueda en curso: el aviso de estado lo dice. */
|
|
30
51
|
loading?: boolean;
|
|
31
52
|
/**
|
|
32
|
-
* Etiqueta del campo.
|
|
33
|
-
*
|
|
53
|
+
* Etiqueta del campo. **Sin default**: sale de `docsSearch.label` del
|
|
54
|
+
* `BrandMessagesProvider`.
|
|
34
55
|
*/
|
|
35
56
|
label?: string;
|
|
36
57
|
/** Oculta la etiqueta a la vista; el lector de pantalla la sigue leyendo. */
|
|
37
58
|
labelHidden?: boolean;
|
|
38
59
|
/**
|
|
39
|
-
* Pista dentro del campo.
|
|
40
|
-
* @default 'Buscar…'
|
|
60
|
+
* Pista dentro del campo. **Sin default**: sale de `docsSearch.placeholder`.
|
|
41
61
|
*/
|
|
42
62
|
placeholder?: string;
|
|
43
63
|
/**
|
|
@@ -47,23 +67,22 @@ export interface DocsSearchProps {
|
|
|
47
67
|
*/
|
|
48
68
|
clearable?: boolean;
|
|
49
69
|
/**
|
|
50
|
-
* Nombre accesible del botón de borrado.
|
|
51
|
-
*
|
|
70
|
+
* Nombre accesible del botón de borrado. Reenvío puro al `InputField`: sin
|
|
71
|
+
* él, el texto sale de `inputField.clear` del `BrandMessagesProvider`.
|
|
52
72
|
*/
|
|
53
73
|
clearLabel?: string;
|
|
54
74
|
/**
|
|
55
|
-
* Nombre accesible de la lista de resultados.
|
|
56
|
-
*
|
|
75
|
+
* Nombre accesible de la lista de resultados. **Sin default**: sale de
|
|
76
|
+
* `docsSearch.results`.
|
|
57
77
|
*/
|
|
58
78
|
resultsLabel?: string;
|
|
59
79
|
/**
|
|
60
|
-
* Aviso cuando la búsqueda no encuentra nada.
|
|
61
|
-
*
|
|
80
|
+
* Aviso cuando la búsqueda no encuentra nada. **Sin default**: sale de
|
|
81
|
+
* `docsSearch.empty`.
|
|
62
82
|
*/
|
|
63
83
|
emptyLabel?: string;
|
|
64
84
|
/**
|
|
65
|
-
* Aviso mientras se busca.
|
|
66
|
-
* @default 'Buscando…'
|
|
85
|
+
* Aviso mientras se busca. **Sin default**: sale de `docsSearch.loading`.
|
|
67
86
|
*/
|
|
68
87
|
loadingLabel?: string;
|
|
69
88
|
/** Talla del campo. */
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { type ComponentPropsWithoutRef, type ReactNode } from 'react';
|
|
2
2
|
import './FilterBar.css';
|
|
3
|
+
/**
|
|
4
|
+
* El único texto que la barra emite por su cuenta: su nombre accesible como
|
|
5
|
+
* punto de referencia de búsqueda. Los rótulos de los filtros no están aquí —
|
|
6
|
+
* los escribe cada campo, y dicen qué filtran.
|
|
7
|
+
*/
|
|
8
|
+
export interface FilterBarMessages {
|
|
9
|
+
/** Nombre accesible del punto de referencia `search` que es la barra. */
|
|
10
|
+
label: string;
|
|
11
|
+
}
|
|
3
12
|
export interface FilterBarProps extends Omit<ComponentPropsWithoutRef<'div'>, 'children'> {
|
|
4
13
|
/**
|
|
5
14
|
* El buscador: el campo de búsqueda del sistema —un `InputField kind="search"`,
|
|
@@ -22,7 +31,7 @@ export interface FilterBarProps extends Omit<ComponentPropsWithoutRef<'div'>, 'c
|
|
|
22
31
|
actions?: ReactNode;
|
|
23
32
|
/**
|
|
24
33
|
* Nombre accesible del punto de referencia `search` que es la barra.
|
|
25
|
-
*
|
|
34
|
+
* **Sin default**: sale de `filterBar.label` del `BrandMessagesProvider`.
|
|
26
35
|
*/
|
|
27
36
|
ariaLabel?: string;
|
|
28
37
|
/** Se añade DESPUÉS de las clases propias. */
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import { type ComponentPropsWithoutRef } from 'react';
|
|
2
2
|
import './InputField.css';
|
|
3
|
+
/**
|
|
4
|
+
* El único texto que el campo emite por su cuenta: el nombre accesible del
|
|
5
|
+
* aspa de borrado. Es cromo —dice la misma cosa en toda la suite—, así que
|
|
6
|
+
* sale del catálogo común y no de quien monta el campo.
|
|
7
|
+
*
|
|
8
|
+
* El `label`, el `placeholder`, el `helperText` y el `errorMessage` NO están
|
|
9
|
+
* aquí: son el contenido de ESTE campo, y ningún catálogo común puede saber
|
|
10
|
+
* qué dicen.
|
|
11
|
+
*/
|
|
12
|
+
export interface InputFieldMessages {
|
|
13
|
+
/** Nombre accesible del botón que vacía un campo de búsqueda. */
|
|
14
|
+
clear: string;
|
|
15
|
+
}
|
|
3
16
|
export interface InputFieldProps extends Omit<ComponentPropsWithoutRef<'input'>, 'size' | 'type' | 'value' | 'defaultValue'> {
|
|
4
17
|
id: string;
|
|
5
18
|
label: string;
|
|
@@ -33,8 +46,9 @@ export interface InputFieldProps extends Omit<ComponentPropsWithoutRef<'input'>,
|
|
|
33
46
|
*/
|
|
34
47
|
clearable?: boolean;
|
|
35
48
|
/**
|
|
36
|
-
* Nombre accesible del botón de borrado.
|
|
37
|
-
*
|
|
49
|
+
* Nombre accesible del botón de borrado. **Sin default**: sale de
|
|
50
|
+
* `inputField.clear` del `BrandMessagesProvider`, y esta prop es la
|
|
51
|
+
* anulación puntual de un uso concreto.
|
|
38
52
|
*/
|
|
39
53
|
clearLabel?: string;
|
|
40
54
|
/** Se llama tras vaciar el campo desde el aspa, ya con el foco devuelto. */
|
|
@@ -15,6 +15,11 @@ export interface MultiSelectFieldProps {
|
|
|
15
15
|
options: MultiSelectOption[];
|
|
16
16
|
value?: string[];
|
|
17
17
|
defaultValue?: string[];
|
|
18
|
+
/**
|
|
19
|
+
* Marcador de sitio del control sin valor elegido. Reenvío puro al `MultiSelect`:
|
|
20
|
+
* sin él, el texto sale de `multiSelect.placeholder` del `BrandMessagesProvider`.
|
|
21
|
+
* Se pasa solo cuando el marcador dice algo de ESTE campo.
|
|
22
|
+
*/
|
|
18
23
|
placeholder?: string;
|
|
19
24
|
/** Nombre del campo en el formulario: se monta un input oculto por valor elegido. */
|
|
20
25
|
name?: string;
|
|
@@ -29,7 +34,10 @@ export interface MultiSelectFieldProps {
|
|
|
29
34
|
size?: 'sm' | 'md' | 'lg';
|
|
30
35
|
/** Se añade DESPUÉS de las clases propias (el consumidor añade, no sustituye). */
|
|
31
36
|
className?: string;
|
|
32
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* aria-label del botón que quita un valor. Reenvío puro al `MultiSelect`:
|
|
39
|
+
* sin él, el texto sale de `multiSelect.remove` del `BrandMessagesProvider`.
|
|
40
|
+
*/
|
|
33
41
|
removeLabel?: (label: string) => string;
|
|
34
42
|
onValueChange?: (value: string[]) => void;
|
|
35
43
|
onBlur?: React.FocusEventHandler<HTMLDivElement>;
|
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
import './PasswordField.css';
|
|
2
|
+
/**
|
|
3
|
+
* Los dos textos que el campo emite por su cuenta: las dos caras del
|
|
4
|
+
* interruptor de mostrar/ocultar. Son cromo —dicen lo mismo en toda la
|
|
5
|
+
* suite—, y por eso salen del catálogo común.
|
|
6
|
+
*
|
|
7
|
+
* El `label`, el `placeholder`, el `helperText` y el `errorMessage` no están
|
|
8
|
+
* aquí: son el contenido de ESTE campo.
|
|
9
|
+
*/
|
|
10
|
+
export interface PasswordFieldMessages {
|
|
11
|
+
/** Nombre accesible del interruptor con la contraseña oculta. */
|
|
12
|
+
show: string;
|
|
13
|
+
/** Nombre accesible del interruptor con la contraseña a la vista. */
|
|
14
|
+
hide: string;
|
|
15
|
+
}
|
|
2
16
|
export interface PasswordFieldProps extends Omit<React.ComponentPropsWithoutRef<'input'>, 'size' | 'type'> {
|
|
3
17
|
/**
|
|
4
18
|
* Etiqueta del campo. **Opcional**: si se omite, el componente renderiza solo
|
|
@@ -18,9 +32,15 @@ export interface PasswordFieldProps extends Omit<React.ComponentPropsWithoutRef<
|
|
|
18
32
|
action?: React.ReactNode;
|
|
19
33
|
/** Tamaño del campo. */
|
|
20
34
|
size?: 'sm' | 'md' | 'lg';
|
|
21
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* aria-label del toggle cuando la contraseña está oculta. **Sin default**:
|
|
37
|
+
* sale de `passwordField.show` del `BrandMessagesProvider`.
|
|
38
|
+
*/
|
|
22
39
|
showPasswordLabel?: string;
|
|
23
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* aria-label del toggle cuando la contraseña es visible. **Sin default**:
|
|
42
|
+
* sale de `passwordField.hide` del `BrandMessagesProvider`.
|
|
43
|
+
*/
|
|
24
44
|
hidePasswordLabel?: string;
|
|
25
45
|
/**
|
|
26
46
|
* Se añade DESPUÉS de las clases propias, sobre el wrapper raíz `.password-field`.
|