@studiolxd/brand 49.12.0 → 49.14.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 +36 -0
- package/dist/_shared/tokens.js +38 -0
- package/dist/_types/messages/BrandMessages.d.ts +3 -1
- package/dist/_types/messages/index.d.ts +1 -1
- package/dist/_types/molecules/SearchForm/SearchForm.d.ts +13 -0
- package/dist/_types/organisms/SiteSearch/SiteSearch.d.ts +171 -0
- package/dist/brand.css +78 -1
- package/dist/search-form.js +30 -24
- package/dist/site-search.css +1 -0
- package/dist/site-search.js +141 -0
- package/dist/tokens.css +81 -1
- package/package.json +6 -1
- package/src/tokens/index.css +1 -0
- package/src/tokens/molecules/site-search.css +57 -0
- package/src/tokens/molecules/site-search.ts +7 -0
- package/src/tokens/scss/_index.legacy.scss +1 -0
- package/src/tokens/scss/_index.scss +1 -0
- package/src/tokens/scss/molecules/_site-search.scss +41 -0
- package/src/tokens/surface-invert.css +7 -0
- package/src/tokens/surface-light.css +7 -0
- package/src/tokens/surface-public.css +8 -0
- package/src/tokens/tokens.json +38 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,42 @@ 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
|
+
## [49.14.0] — 2026-09-20
|
|
11
|
+
|
|
12
|
+
> **Minor.** El buscador, repasado con la página real delante. Seis cambios pedidos por
|
|
13
|
+
> quien lo iba a usar después de verlo en producción, que es cuando se ven las cosas.
|
|
14
|
+
|
|
15
|
+
### `SiteSearch` — lo que cambia
|
|
16
|
+
|
|
17
|
+
Ocupa el ancho de su contenedor y ya no se encoge dentro de una fila flexible o una
|
|
18
|
+
celda de retícula. Entre resultados hay aire de verdad, 32 píxeles, y dentro de cada
|
|
19
|
+
uno 8. **Fuera la línea separadora**: la separación la hace el espacio.
|
|
20
|
+
|
|
21
|
+
El título de cada resultado ya era un `h2`, pero leía al cuerpo de texto y no se
|
|
22
|
+
distinguía; ahora sube un peldaño y lleva interlineado de título. El rastro de
|
|
23
|
+
sección, el extracto y la dirección usan el cuerpo de las páginas públicas.
|
|
24
|
+
|
|
25
|
+
**El campo pasa a ser `SearchForm`**, el mismo del menú, no una copia de su CSS: la
|
|
26
|
+
flecha vive dentro del borde y no hay botón aparte. `SearchForm` gana `className`,
|
|
27
|
+
`describedBy` y `controls`, que no cambian su dibujo. Como consecuencia buscada, el
|
|
28
|
+
campo de la página y el del menú ya no pueden separarse.
|
|
29
|
+
|
|
30
|
+
## [49.13.0] — 2026-09-19
|
|
31
|
+
|
|
32
|
+
> **Minor.** El buscador del sitio. Existían el campo del menú y el autocompletar de la
|
|
33
|
+
> documentación; faltaba la página de resultados entera, que es lo que entra aquí.
|
|
34
|
+
|
|
35
|
+
### `SiteSearch` — campo, estado y resultados
|
|
36
|
+
|
|
37
|
+
Un organismo con los seis estados que de verdad tiene un buscador: en reposo, escribiendo,
|
|
38
|
+
buscando, con resultados, **sin resultados** y **con error**. Los dos últimos son dos estados
|
|
39
|
+
y no uno: hasta ahora la página de marketing se tragaba el fallo del índice y pintaba un
|
|
40
|
+
vacío, que es mentirle a quien busca — no es que no haya nada, es que no hemos podido mirar.
|
|
41
|
+
|
|
42
|
+
**No busca nada.** El estado se le pasa por prop, y la paginación y los filtros son ranuras
|
|
43
|
+
que rellena quien lo use. Teclado y lectores de pantalla desde el principio: foco visible,
|
|
44
|
+
recorrido con tabulador y el número de resultados anunciado.
|
|
45
|
+
|
|
10
46
|
## [49.12.0] — 2026-09-19
|
|
11
47
|
|
|
12
48
|
> **Minor.** Las seis piezas que pedían People, Projects y Finance al partir el ERP interno en
|
package/dist/_shared/tokens.js
CHANGED
|
@@ -3404,6 +3404,44 @@ var e = {
|
|
|
3404
3404
|
"--planning-grid-pending-opacity": "0.4",
|
|
3405
3405
|
"--public-page-shell-preferences-padding-block": "1.5rem",
|
|
3406
3406
|
"--public-page-shell-preferences-gap": "0.75rem",
|
|
3407
|
+
"--site-search-inline-size": "100%",
|
|
3408
|
+
"--site-search-gap": "1.5rem",
|
|
3409
|
+
"--site-search-block-gap": "0.75rem",
|
|
3410
|
+
"--site-search-status-font-size": "0.875rem",
|
|
3411
|
+
"--site-search-status-line-height": "1.5",
|
|
3412
|
+
"--site-search-status-color": "#4a4a4a",
|
|
3413
|
+
"--site-search-status-gap": "0.5rem",
|
|
3414
|
+
"--site-search-status-query-font-weight": "500",
|
|
3415
|
+
"--site-search-results-gap": "2rem",
|
|
3416
|
+
"--site-search-result-gap": "0.5rem",
|
|
3417
|
+
"--site-search-result-title-font-size": "1.25rem",
|
|
3418
|
+
"--site-search-result-title-line-height": "1.3",
|
|
3419
|
+
"--site-search-result-title-font-weight": "500",
|
|
3420
|
+
"--site-search-result-title-color": "#111e30",
|
|
3421
|
+
"--site-search-result-section-font-size": "1rem",
|
|
3422
|
+
"--site-search-result-section-line-height": "1.5",
|
|
3423
|
+
"--site-search-result-section-color": "#4a4a4a",
|
|
3424
|
+
"--site-search-result-excerpt-font-size": "1rem",
|
|
3425
|
+
"--site-search-result-excerpt-line-height": "1.5",
|
|
3426
|
+
"--site-search-result-excerpt-color": "#111e30",
|
|
3427
|
+
"--site-search-result-measure": "70ch",
|
|
3428
|
+
"--site-search-result-url-font-size": "1rem",
|
|
3429
|
+
"--site-search-result-url-line-height": "1.5",
|
|
3430
|
+
"--site-search-result-url-color": "#4a4a4a",
|
|
3431
|
+
"--site-search-result-link-hover-line-width": "1px",
|
|
3432
|
+
"--site-search-result-link-hover-line-offset": "0.25rem",
|
|
3433
|
+
"--site-search-result-focus-ring-color": "#111e30",
|
|
3434
|
+
"--site-search-result-focus-ring-width": "2px",
|
|
3435
|
+
"--site-search-result-focus-ring-offset": "1px",
|
|
3436
|
+
"--site-search-result-mark-bg": "#ffcd00",
|
|
3437
|
+
"--site-search-result-mark-color": "#111e30",
|
|
3438
|
+
"--site-search-suggestions-gap": "0.5rem",
|
|
3439
|
+
"--site-search-suggestions-label-font-size": "0.75rem",
|
|
3440
|
+
"--site-search-suggestions-label-color": "#4a4a4a",
|
|
3441
|
+
"--site-search-ghost-section-inline-size": "30%",
|
|
3442
|
+
"--site-search-ghost-title-inline-size": "70%",
|
|
3443
|
+
"--site-search-ghost-url-inline-size": "45%",
|
|
3444
|
+
"--site-search-skeleton-gap": "0.5rem",
|
|
3407
3445
|
"--steps-gap": "1.5rem",
|
|
3408
3446
|
"--steps-marker-gap": "1rem",
|
|
3409
3447
|
"--steps-body-gap": "0.5rem",
|
|
@@ -12,6 +12,7 @@ import type { AsyncSelectMessages } from '../atoms/AsyncSelect/AsyncSelect';
|
|
|
12
12
|
import type { AsyncMultiSelectMessages } from '../atoms/AsyncMultiSelect/AsyncMultiSelect';
|
|
13
13
|
import type { DocsSearchMessages } from '../molecules/DocsSearch/DocsSearch';
|
|
14
14
|
import type { SearchFormMessages } from '../molecules/SearchForm/SearchForm';
|
|
15
|
+
import type { SiteSearchMessages } from '../organisms/SiteSearch/SiteSearch';
|
|
15
16
|
import type { FilterBarMessages } from '../molecules/FilterBar/FilterBar';
|
|
16
17
|
import type { CalendarMessages } from '../molecules/Calendar/Calendar';
|
|
17
18
|
import type { DatePickerMessages } from '../molecules/DatePicker/DatePicker';
|
|
@@ -116,6 +117,7 @@ export interface BrandMessages {
|
|
|
116
117
|
asyncMultiSelect: AsyncMultiSelectMessages;
|
|
117
118
|
docsSearch: DocsSearchMessages;
|
|
118
119
|
searchForm: SearchFormMessages;
|
|
120
|
+
siteSearch: SiteSearchMessages;
|
|
119
121
|
filterBar: FilterBarMessages;
|
|
120
122
|
calendar: CalendarMessages;
|
|
121
123
|
datePicker: DatePickerMessages;
|
|
@@ -185,4 +187,4 @@ export interface BrandMessages {
|
|
|
185
187
|
connectorExternalSignIn: ConnectorExternalSignInMessages;
|
|
186
188
|
connectorRejection: ConnectorRejectionMessages;
|
|
187
189
|
}
|
|
188
|
-
export type { PaginationMessages, TableMessages, DataTableMessages, InputFieldMessages, PasswordFieldMessages, SelectMessages, MultiSelectMessages, NumberInputMessages, OtpInputMessages, InputPhoneMessages, AsyncSelectMessages, AsyncMultiSelectMessages, DocsSearchMessages, SearchFormMessages, FilterBarMessages, CalendarMessages, DatePickerMessages, TimeSelectMessages, FileUploadMessages, ImageCropDialogMessages, AvatarUploadMessages, ModalMessages, SheetMessages, ConfirmDialogMessages, AlertMessages, BannerMessages, ToasterMessages, ConsentMessages, CommandPaletteMessages, AppLauncherMessages, FloatingDockMessages, NotificationButtonMessages, NotificationPanelMessages, MenuButtonMessages, AppRootMessages, AppShellMessages, SidebarMessages, SidebarNavMessages, SiteNavMessages, SiteHeaderMessages, UserMenuMessages, OrgSwitcherMessages, BreadcrumbMessages, TableOfContentsMessages, PrevNextNavMessages, PublicPageShellMessages, OnboardingShellMessages, CopyMessages, CodeBlockMessages, DotsButtonMessages, ProgressBarMessages, SpinnerMessages, SliderMessages, TreeViewMessages, ClockWidgetMessages, HeatmapMessages, OrgChartMessages, PlanningGridMessages, RecurrenceFieldMessages, TimelineMessages, UptimeBarsMessages, ChartMessages, StepperMessages, CarouselMessages, LanguageSwitcherMessages, ProjectCardMessages, LegalFooterMessages, CalendarRosterMessages, CalendarPlannerMessages, NotificationListMessages, MessageComposerMessages, ConversationListMessages, ConversationThreadMessages, TypingIndicatorMessages, AnnotationThreadMessages, ChatShellMessages, UntrustedTextMessages, ConnectorRequestSummaryMessages, ConnectorConsentMessages, ConnectorSignInMessages, ConnectorExternalSignInMessages, ConnectorRejectionMessages, };
|
|
190
|
+
export type { PaginationMessages, TableMessages, DataTableMessages, InputFieldMessages, PasswordFieldMessages, SelectMessages, MultiSelectMessages, NumberInputMessages, OtpInputMessages, InputPhoneMessages, AsyncSelectMessages, AsyncMultiSelectMessages, DocsSearchMessages, SearchFormMessages, SiteSearchMessages, FilterBarMessages, CalendarMessages, DatePickerMessages, TimeSelectMessages, FileUploadMessages, ImageCropDialogMessages, AvatarUploadMessages, ModalMessages, SheetMessages, ConfirmDialogMessages, AlertMessages, BannerMessages, ToasterMessages, ConsentMessages, CommandPaletteMessages, AppLauncherMessages, FloatingDockMessages, NotificationButtonMessages, NotificationPanelMessages, MenuButtonMessages, AppRootMessages, AppShellMessages, SidebarMessages, SidebarNavMessages, SiteNavMessages, SiteHeaderMessages, UserMenuMessages, OrgSwitcherMessages, BreadcrumbMessages, TableOfContentsMessages, PrevNextNavMessages, PublicPageShellMessages, OnboardingShellMessages, CopyMessages, CodeBlockMessages, DotsButtonMessages, ProgressBarMessages, SpinnerMessages, SliderMessages, TreeViewMessages, ClockWidgetMessages, HeatmapMessages, OrgChartMessages, PlanningGridMessages, RecurrenceFieldMessages, TimelineMessages, UptimeBarsMessages, ChartMessages, StepperMessages, CarouselMessages, LanguageSwitcherMessages, ProjectCardMessages, LegalFooterMessages, CalendarRosterMessages, CalendarPlannerMessages, NotificationListMessages, MessageComposerMessages, ConversationListMessages, ConversationThreadMessages, TypingIndicatorMessages, AnnotationThreadMessages, ChatShellMessages, UntrustedTextMessages, ConnectorRequestSummaryMessages, ConnectorConsentMessages, ConnectorSignInMessages, ConnectorExternalSignInMessages, ConnectorRejectionMessages, };
|
|
@@ -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, InputFieldMessages, PasswordFieldMessages, SelectMessages, MultiSelectMessages, NumberInputMessages, OtpInputMessages, InputPhoneMessages, AsyncSelectMessages, AsyncMultiSelectMessages, DocsSearchMessages, SearchFormMessages, FilterBarMessages, CalendarMessages, DatePickerMessages, TimeSelectMessages, FileUploadMessages, ImageCropDialogMessages, AvatarUploadMessages, ModalMessages, SheetMessages, ConfirmDialogMessages, AlertMessages, BannerMessages, ToasterMessages, ConsentMessages, CommandPaletteMessages, AppLauncherMessages, FloatingDockMessages, NotificationButtonMessages, NotificationPanelMessages, MenuButtonMessages, AppRootMessages, AppShellMessages, SidebarMessages, SidebarNavMessages, SiteNavMessages, SiteHeaderMessages, UserMenuMessages, OrgSwitcherMessages, BreadcrumbMessages, TableOfContentsMessages, PrevNextNavMessages, PublicPageShellMessages, OnboardingShellMessages, CopyMessages, CodeBlockMessages, DotsButtonMessages, ProgressBarMessages, SpinnerMessages, SliderMessages, TreeViewMessages, ClockWidgetMessages, HeatmapMessages, OrgChartMessages, PlanningGridMessages, RecurrenceFieldMessages, TimelineMessages, UptimeBarsMessages, ChartMessages, StepperMessages, CarouselMessages, LanguageSwitcherMessages, ProjectCardMessages, LegalFooterMessages, CalendarRosterMessages, CalendarPlannerMessages, NotificationListMessages, MessageComposerMessages, ConversationListMessages, ConversationThreadMessages, TypingIndicatorMessages, AnnotationThreadMessages, ChatShellMessages, UntrustedTextMessages, ConnectorRequestSummaryMessages, ConnectorConsentMessages, ConnectorSignInMessages, ConnectorExternalSignInMessages, ConnectorRejectionMessages, } from './BrandMessages';
|
|
5
|
+
export type { BrandMessages, PaginationMessages, TableMessages, DataTableMessages, InputFieldMessages, PasswordFieldMessages, SelectMessages, MultiSelectMessages, NumberInputMessages, OtpInputMessages, InputPhoneMessages, AsyncSelectMessages, AsyncMultiSelectMessages, DocsSearchMessages, SearchFormMessages, SiteSearchMessages, FilterBarMessages, CalendarMessages, DatePickerMessages, TimeSelectMessages, FileUploadMessages, ImageCropDialogMessages, AvatarUploadMessages, ModalMessages, SheetMessages, ConfirmDialogMessages, AlertMessages, BannerMessages, ToasterMessages, ConsentMessages, CommandPaletteMessages, AppLauncherMessages, FloatingDockMessages, NotificationButtonMessages, NotificationPanelMessages, MenuButtonMessages, AppRootMessages, AppShellMessages, SidebarMessages, SidebarNavMessages, SiteNavMessages, SiteHeaderMessages, UserMenuMessages, OrgSwitcherMessages, BreadcrumbMessages, TableOfContentsMessages, PrevNextNavMessages, PublicPageShellMessages, OnboardingShellMessages, CopyMessages, CodeBlockMessages, DotsButtonMessages, ProgressBarMessages, SpinnerMessages, SliderMessages, TreeViewMessages, ClockWidgetMessages, HeatmapMessages, OrgChartMessages, PlanningGridMessages, RecurrenceFieldMessages, TimelineMessages, UptimeBarsMessages, ChartMessages, StepperMessages, CarouselMessages, LanguageSwitcherMessages, ProjectCardMessages, LegalFooterMessages, CalendarRosterMessages, CalendarPlannerMessages, NotificationListMessages, MessageComposerMessages, ConversationListMessages, ConversationThreadMessages, TypingIndicatorMessages, AnnotationThreadMessages, ChatShellMessages, UntrustedTextMessages, ConnectorRequestSummaryMessages, ConnectorConsentMessages, ConnectorSignInMessages, ConnectorExternalSignInMessages, ConnectorRejectionMessages, } from './BrandMessages';
|
|
@@ -15,6 +15,8 @@ export interface SearchFormMessages {
|
|
|
15
15
|
export interface SearchFormProps {
|
|
16
16
|
/** `id` del campo. Si no se pasa, el componente genera uno estable. */
|
|
17
17
|
id?: string;
|
|
18
|
+
/** Clase del `<form>`, para que quien lo monte lo coloque en su retícula. */
|
|
19
|
+
className?: string;
|
|
18
20
|
/**
|
|
19
21
|
* Nombre del parámetro con el que viaja la consulta en el envío sin JS.
|
|
20
22
|
* @default 'q'
|
|
@@ -67,6 +69,17 @@ export interface SearchFormProps {
|
|
|
67
69
|
size?: 'sm' | 'md' | 'lg' | 'xl';
|
|
68
70
|
/** Deshabilita el campo y el botón. */
|
|
69
71
|
disabled?: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* `id` de lo que describe al campo: el aviso vivo de una página de
|
|
74
|
+
* resultados («23 resultados para «factura»»). El campo lo referencia con
|
|
75
|
+
* `aria-describedby`.
|
|
76
|
+
*/
|
|
77
|
+
describedBy?: string;
|
|
78
|
+
/**
|
|
79
|
+
* `id` de la región que el campo gobierna: la lista de resultados que
|
|
80
|
+
* cambia al buscar. El campo lo referencia con `aria-controls`.
|
|
81
|
+
*/
|
|
82
|
+
controls?: string;
|
|
70
83
|
}
|
|
71
84
|
/**
|
|
72
85
|
* Buscador de sitio: un campo y un botón de envío que llevan a una página de
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { type ComponentPropsWithoutRef, type ReactNode } from 'react';
|
|
2
|
+
import type { HeadingLevel } from '../../atoms/Heading/Heading';
|
|
3
|
+
import './SiteSearch.css';
|
|
4
|
+
/**
|
|
5
|
+
* En qué punto está la búsqueda. **Lo decide quien busca**, no el componente:
|
|
6
|
+
* aquí no hay `fetch`, ni rebote, ni filtrado, así que nada de esto se puede
|
|
7
|
+
* deducir de las props.
|
|
8
|
+
*
|
|
9
|
+
* - `idle` — todavía no se ha preguntado nada. Es el estado de partida.
|
|
10
|
+
* - `typing` — hay algo escrito pero aún no se ha buscado: la consulta no
|
|
11
|
+
* llega a `minLength`, o el rebote está en marcha.
|
|
12
|
+
* - `loading` — la consulta está en vuelo.
|
|
13
|
+
* - `ready` — la respuesta llegó. Con `results` vacío, esto es el «sin
|
|
14
|
+
* resultados»: un buscador que respondió y no encontró nada.
|
|
15
|
+
* - `error` — la consulta falló. **No es lo mismo que no encontrar nada**, y
|
|
16
|
+
* por eso son dos estados: el vacío invita a reformular, el error a
|
|
17
|
+
* reintentar.
|
|
18
|
+
*/
|
|
19
|
+
export type SiteSearchStatus = 'idle' | 'typing' | 'loading' | 'ready' | 'error';
|
|
20
|
+
/** Un resultado. Lo que trae el índice, ya formateado por quien busca. */
|
|
21
|
+
export interface SiteSearchResult {
|
|
22
|
+
/** URL del documento. Es también la clave del resultado. */
|
|
23
|
+
href: string;
|
|
24
|
+
/** Título del documento, en texto plano. */
|
|
25
|
+
title: string;
|
|
26
|
+
/**
|
|
27
|
+
* El trozo del documento donde está la coincidencia. Es `ReactNode` para
|
|
28
|
+
* que quien busca pueda resaltarla con `<mark>`, que la hoja ya viste.
|
|
29
|
+
*/
|
|
30
|
+
excerpt?: ReactNode;
|
|
31
|
+
/** Dónde vive el documento («Documentación › Creator»). */
|
|
32
|
+
section?: string;
|
|
33
|
+
/** La dirección tal y como se le enseña a quien lee, sin protocolo. */
|
|
34
|
+
displayUrl?: string;
|
|
35
|
+
}
|
|
36
|
+
export type SiteSearchRenderLinkProps = ComponentPropsWithoutRef<'a'> & {
|
|
37
|
+
href: string;
|
|
38
|
+
className: string;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Los textos que el buscador emite por su cuenta. Todos son **cromo**: cómo se
|
|
42
|
+
* llama el campo, cómo se dice que está buscando y cómo se avisa de que no
|
|
43
|
+
* hay nada. Los resultados no están aquí — son datos que llegan por
|
|
44
|
+
* `results`.
|
|
45
|
+
*
|
|
46
|
+
* El campo es el `SearchForm` del menú del sitio, así que el buscador no
|
|
47
|
+
* emite ningún texto más: la flecha de envío se nombra con `submit`, y su
|
|
48
|
+
* rótulo ya no se ve — es el nombre accesible del adorno dentro del campo.
|
|
49
|
+
*/
|
|
50
|
+
export interface SiteSearchMessages {
|
|
51
|
+
/** Etiqueta del campo, que nombra también la región de búsqueda. */
|
|
52
|
+
label: string;
|
|
53
|
+
/** Pista dentro del campo. */
|
|
54
|
+
placeholder: string;
|
|
55
|
+
/** Nombre accesible de la flecha de envío, dentro del campo. */
|
|
56
|
+
submit: string;
|
|
57
|
+
/** Lo que se dice antes de la primera búsqueda. */
|
|
58
|
+
idle: string;
|
|
59
|
+
/** Cuántos caracteres hacen falta para buscar. Función del mínimo. */
|
|
60
|
+
minLength: (min: number) => string;
|
|
61
|
+
/** Lo que se dice con la consulta escrita y la búsqueda aún sin lanzar. */
|
|
62
|
+
pending: string;
|
|
63
|
+
/** Lo que se dice mientras se busca. */
|
|
64
|
+
loading: string;
|
|
65
|
+
/** El recuento: cuántos resultados hay para qué consulta. */
|
|
66
|
+
results: (count: number, query: string) => string;
|
|
67
|
+
/** Nombre accesible de la lista de resultados. */
|
|
68
|
+
resultsLabel: string;
|
|
69
|
+
/**
|
|
70
|
+
* Rótulo del vacío. **No lleva la consulta**: la consulta ya la dice el
|
|
71
|
+
* recuento de arriba («0 resultados para «x»»), y repetirla debajo es la
|
|
72
|
+
* misma frase dos veces.
|
|
73
|
+
*/
|
|
74
|
+
emptyTitle: string;
|
|
75
|
+
/** Qué hacer cuando no hay nada. */
|
|
76
|
+
emptyDescription: string;
|
|
77
|
+
/** Rótulo de las sugerencias de búsqueda. */
|
|
78
|
+
suggestionsLabel: string;
|
|
79
|
+
/** Rótulo del error. */
|
|
80
|
+
errorTitle: string;
|
|
81
|
+
/** Qué ha pasado y qué se puede hacer. */
|
|
82
|
+
errorDescription: string;
|
|
83
|
+
/** Rótulo del botón que vuelve a intentarlo. */
|
|
84
|
+
retry: string;
|
|
85
|
+
}
|
|
86
|
+
export interface SiteSearchProps extends Omit<ComponentPropsWithoutRef<'div'>, 'onSubmit' | 'onSelect' | 'results'> {
|
|
87
|
+
/** Lo escrito en el campo. El componente es controlado: no guarda estado. */
|
|
88
|
+
query: string;
|
|
89
|
+
/** Se llama en cada tecla. Quien lo recibe decide cuándo y cómo buscar. */
|
|
90
|
+
onQueryChange: (query: string) => void;
|
|
91
|
+
/**
|
|
92
|
+
* Se llama al enviar el formulario, con la consulta **recortada**. Con el
|
|
93
|
+
* campo vacío no se llama: un buscador sin consulta no tiene a dónde ir.
|
|
94
|
+
*/
|
|
95
|
+
onSubmit?: (query: string) => void;
|
|
96
|
+
/**
|
|
97
|
+
* Destino del envío sin JavaScript. Una búsqueda es una lectura, así que
|
|
98
|
+
* viaja por `get`. Solo se usa cuando no hay `onSubmit`.
|
|
99
|
+
*/
|
|
100
|
+
action?: string;
|
|
101
|
+
/**
|
|
102
|
+
* Nombre del parámetro con el que viaja la consulta en el envío sin JS.
|
|
103
|
+
* @default 'q'
|
|
104
|
+
*/
|
|
105
|
+
name?: string;
|
|
106
|
+
/** En qué punto está la búsqueda. @default 'idle' */
|
|
107
|
+
status?: SiteSearchStatus;
|
|
108
|
+
/** Los resultados de la página que se está viendo. */
|
|
109
|
+
results?: SiteSearchResult[];
|
|
110
|
+
/**
|
|
111
|
+
* Cuántos resultados hay **en total**, para el recuento. Sin él se cuenta
|
|
112
|
+
* lo que llega en `results`, que con paginación es solo la página actual.
|
|
113
|
+
*/
|
|
114
|
+
total?: number;
|
|
115
|
+
/**
|
|
116
|
+
* Cuántos caracteres hacen falta para buscar. Solo se usa para redactar la
|
|
117
|
+
* pista de `typing`: el componente no busca, así que tampoco corta nada.
|
|
118
|
+
* @default 2
|
|
119
|
+
*/
|
|
120
|
+
minLength?: number;
|
|
121
|
+
/** Búsquedas propuestas en reposo. Se pintan como botones. */
|
|
122
|
+
suggestions?: string[];
|
|
123
|
+
/** Se llama al pulsar una sugerencia. Sin él, la sugerencia no se pinta como acción. */
|
|
124
|
+
onSuggestionSelect?: (suggestion: string) => void;
|
|
125
|
+
/** Se llama al pulsar «Reintentar». Sin él, el error no ofrece el botón. */
|
|
126
|
+
onRetry?: () => void;
|
|
127
|
+
/** Lo que va entre el campo y los resultados: los filtros de la búsqueda. */
|
|
128
|
+
toolbar?: ReactNode;
|
|
129
|
+
/** Lo que va al pie de los resultados: la paginación. */
|
|
130
|
+
footer?: ReactNode;
|
|
131
|
+
/** Nivel del título de cada resultado. @default 2 */
|
|
132
|
+
headingLevel?: HeadingLevel;
|
|
133
|
+
/** Talla del campo y de su flecha. */
|
|
134
|
+
size?: 'sm' | 'md' | 'lg';
|
|
135
|
+
/** Cuántos resultados fantasma se pintan durante la carga. @default 3 */
|
|
136
|
+
loadingRows?: number;
|
|
137
|
+
/** Se llama al activar un resultado, además de seguir el enlace. */
|
|
138
|
+
onSelect?: (result: SiteSearchResult) => void;
|
|
139
|
+
/**
|
|
140
|
+
* Elemento sobre el que renderizar cada resultado: el `Link` del router del
|
|
141
|
+
* producto. Debe **propagar todas** las props que recibe.
|
|
142
|
+
*/
|
|
143
|
+
renderLink?: (props: SiteSearchRenderLinkProps) => ReactNode;
|
|
144
|
+
/** Etiqueta del campo. Sin ella, sale de `siteSearch.label`. */
|
|
145
|
+
label?: string;
|
|
146
|
+
/** Oculta la etiqueta a la vista; el lector la sigue leyendo. @default true */
|
|
147
|
+
labelHidden?: boolean;
|
|
148
|
+
/** Pista dentro del campo. Sin ella, sale de `siteSearch.placeholder`. */
|
|
149
|
+
placeholder?: string;
|
|
150
|
+
/** Nombre accesible de la flecha de envío. Sin él, sale de `siteSearch.submit`. */
|
|
151
|
+
submitLabel?: string;
|
|
152
|
+
/** Nombre accesible de la lista. Sin él, sale de `siteSearch.resultsLabel`. */
|
|
153
|
+
resultsLabel?: string;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* El buscador del sitio: el campo, lo que está pasando y los resultados.
|
|
157
|
+
*
|
|
158
|
+
* **No busca nada.** No hace `fetch`, no filtra, no rebota y no pagina:
|
|
159
|
+
* recibe `query`, `status` y `results`, y los pinta. El índice —Pagefind,
|
|
160
|
+
* Algolia, una ruta propia— es del producto, y con él la cancelación de
|
|
161
|
+
* respuestas tardías y el reparto en páginas (que se monta con `footer`).
|
|
162
|
+
*
|
|
163
|
+
* Los cinco estados son explícitos porque ninguno se puede deducir desde
|
|
164
|
+
* aquí, y **el vacío y el error son dos**: «no hay nada para esto» invita a
|
|
165
|
+
* reformular, «no se ha podido buscar» invita a reintentar, y un buscador que
|
|
166
|
+
* los confunde le dice a quien busca que su pregunta no tiene respuesta
|
|
167
|
+
* cuando lo que pasa es que el índice está caído.
|
|
168
|
+
*
|
|
169
|
+
* El `ref` va al `<input>`.
|
|
170
|
+
*/
|
|
171
|
+
export declare const SiteSearch: import("react").ForwardRefExoticComponent<SiteSearchProps & import("react").RefAttributes<HTMLInputElement>>;
|