import type { IndexWidget } from '../widgets'; import type { RecommendResponse } from './algoliasearch'; import type { InstantSearch } from './instantsearch'; import type { IndexRenderState, WidgetRenderState } from './render-state'; import type { IndexUiState, UiState } from './ui-state'; import type { Expand, RequiredKeys } from './utils'; import type { AlgoliaSearchHelper as Helper, SearchParameters, SearchResults, RecommendParameters } from 'algoliasearch-helper'; export type ScopedResult = { indexId: string; results: SearchResults | null; helper: Helper; }; type SharedRenderOptions = { instantSearchInstance: InstantSearch; parent: IndexWidget; templatesConfig: Record; scopedResults: ScopedResult[]; state: SearchParameters; renderState: IndexRenderState; helper: Helper; /** @deprecated use `status` instead */ searchMetadata: { /** @deprecated use `status === "stalled"` instead */ isSearchStalled: boolean; }; status: InstantSearch['status']; error: InstantSearch['error']; createURL: (nextState: SearchParameters | ((state: IndexUiState) => IndexUiState)) => string; }; export type InitOptions = SharedRenderOptions & { uiState: UiState; results?: undefined; }; export type ShouldRenderOptions = { instantSearchInstance: InstantSearch; }; export type RenderOptions = SharedRenderOptions & { results: SearchResults | null; }; export type DisposeOptions = { helper: Helper; state: SearchParameters; recommendState: RecommendParameters; parent: IndexWidget; }; export type BuiltinTypes = 'ais.analytics' | 'ais.answers' | 'ais.autocomplete' | 'ais.breadcrumb' | 'ais.clearRefinements' | 'ais.chat' | 'ais.configure' | 'ais.configureRelatedItems' | 'ais.currentRefinements' | 'ais.dynamicWidgets' | 'ais.frequentlyBoughtTogether' | 'ais.geoSearch' | 'ais.hierarchicalMenu' | 'ais.hits' | 'ais.hitsPerPage' | 'ais.index' | 'ais.infiniteHits' | 'ais.lookingSimilar' | 'ais.menu' | 'ais.numericMenu' | 'ais.pagination' | 'ais.places' | 'ais.poweredBy' | 'ais.queryRules' | 'ais.range' | 'ais.rangeSlider' | 'ais.rangeInput' | 'ais.ratingMenu' | 'ais.refinementList' | 'ais.relatedProducts' | 'ais.searchBox' | 'ais.relevantSort' | 'ais.sortBy' | 'ais.stats' | 'ais.toggleRefinement' | 'ais.trendingFacets' | 'ais.trendingItems' | 'ais.voiceSearch'; export type BuiltinWidgetTypes = 'ais.analytics' | 'ais.answers' | 'ais.autocomplete' | 'ais.breadcrumb' | 'ais.chat' | 'ais.clearRefinements' | 'ais.configure' | 'ais.configureRelatedItems' | 'ais.currentRefinements' | 'ais.dynamicWidgets' | 'ais.frequentlyBoughtTogether' | 'ais.geoSearch' | 'ais.hierarchicalMenu' | 'ais.hits' | 'ais.hitsPerPage' | 'ais.index' | 'ais.infiniteHits' | 'ais.lookingSimilar' | 'ais.menu' | 'ais.menuSelect' | 'ais.numericMenu' | 'ais.pagination' | 'ais.places' | 'ais.poweredBy' | 'ais.queryRuleCustomData' | 'ais.queryRuleContext' | 'ais.rangeInput' | 'ais.rangeSlider' | 'ais.ratingMenu' | 'ais.refinementList' | 'ais.relatedProducts' | 'ais.searchBox' | 'ais.relevantSort' | 'ais.sortBy' | 'ais.stats' | 'ais.toggleRefinement' | 'ais.trendingFacets' | 'ais.trendingItems' | 'ais.voiceSearch'; export type UnknownWidgetParams = NonNullable; export type WidgetParams = { widgetParams?: UnknownWidgetParams; }; export type WidgetDescription = { $$type: string; $$widgetType?: string; renderState?: Record; indexRenderState?: Record; indexUiState?: Record; }; type SearchWidget = { dependsOn?: 'search'; getWidgetParameters?: (state: SearchParameters, widgetParametersOptions: { uiState: Expand>; }) => SearchParameters; }; type RecommendRenderOptions = SharedRenderOptions & { results: RecommendResponse; }; type RecommendWidget = { dependsOn: 'recommend'; $$id?: number; getWidgetParameters: (state: RecommendParameters, widgetParametersOptions: { uiState: Expand>; }) => RecommendParameters; getRenderState: (renderState: Expand>, renderOptions: InitOptions | RecommendRenderOptions) => IndexRenderState & TWidgetDescription['indexRenderState']; getWidgetRenderState: (renderOptions: InitOptions | RecommendRenderOptions) => Expand>; }; type Parent = { /** * This gets dynamically added by the `index` widget. * If the widget has gone through `addWidget`, it will have a parent. */ parent?: IndexWidget; }; type RequiredWidgetLifeCycle = { /** * Identifier for connectors and widgets. */ $$type: TWidgetDescription['$$type']; /** * Called once before the first search. */ init?: (options: InitOptions) => void; /** * Whether `render` should be called */ shouldRender?: (options: ShouldRenderOptions) => boolean; /** * Called after each search response has been received. */ render?: (options: RenderOptions) => void; /** * Called when this widget is unmounted. Used to remove refinements set by * during this widget's initialization and life time. */ dispose?: (options: DisposeOptions) => SearchParameters | RecommendParameters | void; }; type RequiredWidgetType = { /** * Identifier for widgets. */ $$widgetType: TWidgetDescription['$$widgetType']; }; type WidgetType = TWidgetDescription extends RequiredKeys ? RequiredWidgetType : { /** * Identifier for widgets. */ $$widgetType?: string; }; type RequiredUiStateLifeCycle = { /** * This function is required for a widget to be taken in account for routing. * It will derive a uiState for this widget based on the existing uiState and * the search parameters applied. * * @param uiState - Current state. * @param widgetStateOptions - Extra information to calculate uiState. */ getWidgetUiState: (uiState: Expand>, widgetUiStateOptions: { searchParameters: SearchParameters; helper: Helper; }) => Partial; /** * This function is required for a widget to be taken in account for routing. * It will derive a uiState for this widget based on the existing uiState and * the search parameters applied. * * @deprecated Use `getWidgetUiState` instead. * @param uiState - Current state. * @param widgetStateOptions - Extra information to calculate uiState. */ getWidgetState?: RequiredUiStateLifeCycle['getWidgetUiState']; /** * This function is required for a widget to behave correctly when a URL is * loaded via e.g. Routing. It receives the current UiState and applied search * parameters, and is expected to return a new search parameters. * * @param state - Applied search parameters. * @param widgetSearchParametersOptions - Extra information to calculate next searchParameters. */ getWidgetSearchParameters: (state: SearchParameters, widgetSearchParametersOptions: { uiState: Expand>; }) => SearchParameters; }; type UiStateLifeCycle = TWidgetDescription extends RequiredKeys ? RequiredUiStateLifeCycle : Partial>; type RequiredRenderStateLifeCycle = { /** * Returns the render state of the current widget to pass to the render function. */ getWidgetRenderState: (renderOptions: InitOptions | RenderOptions) => Expand>; /** * Returns IndexRenderState of the current index component tree * to build the render state of the whole app. */ getRenderState: (renderState: Expand>, renderOptions: InitOptions | RenderOptions) => IndexRenderState & TWidgetDescription['indexRenderState']; }; type RenderStateLifeCycle = TWidgetDescription extends RequiredKeys & WidgetParams ? RequiredRenderStateLifeCycle : Partial>; export type Widget = Expand & WidgetType & UiStateLifeCycle & RenderStateLifeCycle> & (SearchWidget | RecommendWidget); export type { IndexWidget } from '../widgets'; export type TransformItemsMetadata = { results: SearchResults | undefined | null; }; /** * Transforms the given items. */ export type TransformItems = (items: TItem[], metadata: TMetadata) => TItem[]; type SortByDirection = TCriterion | `${TCriterion}:asc` | `${TCriterion}:desc`; /** * Transforms the given items. */ export type SortBy = ((a: TItem, b: TItem) => number) | Array>; /** * Creates the URL for the given value. */ export type CreateURL = (value: TValue) => string;