@docsearch/react 5.0.5 → 5.1.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/dist/esm/{DocSearch-2gNxdJcC.d.ts → DocSearch-BFLV-F2L.d.ts} +3 -2
- package/dist/esm/{DocSearchAI-DKtAqje2.d.ts → DocSearchAI-f-C2lV8l.d.ts} +2 -2
- package/dist/esm/{DocSearchAskAiModal-BzQZxvTY.js → DocSearchAskAiModal-CZm9AVU0.js} +3 -3
- package/dist/esm/{DocSearchAskAiModal-BzQZxvTY.js.map → DocSearchAskAiModal-CZm9AVU0.js.map} +1 -1
- package/dist/esm/{DocSearchModal-Cgdi4eHY.js → DocSearchModal-CLcbYBea.js} +2 -2
- package/dist/esm/{DocSearchModal-Cgdi4eHY.js.map → DocSearchModal-CLcbYBea.js.map} +1 -1
- package/dist/esm/askaiModal.d.ts +1 -1
- package/dist/esm/askaiModal.js +1 -1
- package/dist/esm/docsearch.d.ts +1 -1
- package/dist/esm/docsearch.js +1 -1
- package/dist/esm/docsearchAi.d.ts +1 -1
- package/dist/esm/docsearchAi.js +1 -1
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +2 -2
- package/dist/esm/modal.d.ts +1 -1
- package/dist/esm/modal.js +1 -1
- package/dist/esm/{normalizeDocSearchIndexes-CFHzf-sx.js → normalizeDocSearchIndexes-B_bI_ytC.js} +170 -52
- package/dist/esm/normalizeDocSearchIndexes-B_bI_ytC.js.map +1 -0
- package/dist/esm/sidepanel.d.ts +3 -3
- package/dist/esm/sidepanel.js +1 -1
- package/dist/esm/{useSuggestedQuestions-DitQZbae.js → useSuggestedQuestions-DkGTPSdx.js} +3 -3
- package/dist/esm/useSuggestedQuestions-DkGTPSdx.js.map +1 -0
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/umd/index.js +45 -45
- package/dist/umd/index.js.map +1 -1
- package/package.json +6 -6
- package/dist/esm/normalizeDocSearchIndexes-CFHzf-sx.js.map +0 -1
- package/dist/esm/useSuggestedQuestions-DitQZbae.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocSearchModal-Cgdi4eHY.js","names":[],"sources":["../../src/components/KeywordSearchBox.tsx","../../src/components/KeywordStartScreen.tsx","../../src/ScreenState.tsx","../../src/DocSearchModal.tsx"],"sourcesContent":["import type {\n AutocompleteApi,\n AutocompleteState,\n} from '@algolia/autocomplete-core';\nimport React, { type JSX, type RefObject } from 'react';\n\nimport type { InternalDocSearchHit } from '../types';\n\nimport { SearchBoxForm } from './ui/SearchBoxForm';\n\nexport type KeywordSearchBoxTranslations = Partial<{\n clearButtonTitle: string;\n clearButtonAriaLabel: string;\n closeButtonText: string;\n closeButtonAriaLabel: string;\n placeholderText: string;\n enterKeyHint: string;\n searchInputLabel: string;\n}>;\n\ninterface KeywordSearchBoxProps extends AutocompleteApi<\n InternalDocSearchHit,\n React.FormEvent,\n React.MouseEvent,\n React.KeyboardEvent\n> {\n state: AutocompleteState<InternalDocSearchHit>;\n autoFocus: boolean;\n inputRef: RefObject<HTMLInputElement | null>;\n onClose: () => void;\n placeholder: string;\n isFromSelection: boolean;\n translations?: KeywordSearchBoxTranslations;\n}\n\nexport function KeywordSearchBox({\n translations = {},\n ...props\n}: KeywordSearchBoxProps): JSX.Element {\n const {\n clearButtonTitle = 'Clear',\n clearButtonAriaLabel = 'Clear the query',\n closeButtonText = 'Close',\n closeButtonAriaLabel = 'Close',\n searchInputLabel = 'Search',\n } = translations;\n\n const actionsBeforeClose = (\n <>\n <button\n className=\"DocSearch-Clear\"\n type=\"reset\"\n aria-label={clearButtonAriaLabel}\n hidden={!props.state.query}\n tabIndex={props.state.query ? 0 : -1}\n aria-hidden={!props.state.query ? 'true' : 'false'}\n >\n {clearButtonTitle}\n </button>\n\n {props.state.query && <div className=\"DocSearch-Divider\" />}\n </>\n );\n\n return (\n <SearchBoxForm\n {...props}\n clearButtonTitle={clearButtonTitle}\n clearButtonAriaLabel={clearButtonAriaLabel}\n closeButtonText={closeButtonText}\n closeButtonAriaLabel={closeButtonAriaLabel}\n searchInputLabel={searchInputLabel}\n inputProps={{\n enterKeyHint: 'search',\n }}\n actionsBeforeClose={actionsBeforeClose}\n />\n );\n}\n","import React, { type JSX } from 'react';\n\nimport type { ScreenStateProps } from '../ScreenState';\nimport type { InternalDocSearchHit } from '../types';\n\nimport type { StoredSearchesSectionsTranslations } from './ui/StoredSearchesSections';\nimport { StoredSearchesSections } from './ui/StoredSearchesSections';\n\nexport type KeywordStartScreenTranslations = StoredSearchesSectionsTranslations;\n\ntype KeywordStartScreenProps = Omit<\n ScreenStateProps<InternalDocSearchHit>,\n 'translations'\n> & {\n hasCollections: boolean;\n translations?: KeywordStartScreenTranslations;\n};\n\nexport function KeywordStartScreen({\n translations = {},\n ...props\n}: KeywordStartScreenProps): JSX.Element | null {\n return (\n <div className=\"DocSearch-Dropdown-Container\">\n <StoredSearchesSections {...props} translations={translations} />\n </div>\n );\n}\n","import type {\n AutocompleteApi,\n AutocompleteState,\n BaseItem,\n} from '@algolia/autocomplete-core';\nimport React from 'react';\n\nimport type { KeywordStartScreenTranslations } from './components/KeywordStartScreen';\nimport { KeywordStartScreen } from './components/KeywordStartScreen';\nimport type { DocSearchProps } from './DocSearch';\nimport type { ErrorScreenTranslations } from './ErrorScreen';\nimport { ErrorScreen } from './ErrorScreen';\nimport type { NoResultsScreenTranslations } from './NoResultsScreen';\nimport { NoResultsScreen } from './NoResultsScreen';\nimport type { ResultsScreenTranslations } from './ResultsScreen';\nimport { ResultsScreen } from './ResultsScreen';\nimport type { StoredSearchPlugin } from './stored-searches';\nimport type { InternalDocSearchHit, StoredDocSearchHit } from './types';\nimport { isQueryEmpty } from './utils';\n\nexport type ScreenStateTranslations = Partial<{\n errorScreen: ErrorScreenTranslations;\n startScreen: KeywordStartScreenTranslations;\n noResultsScreen: NoResultsScreenTranslations;\n resultsScreen: ResultsScreenTranslations;\n}>;\n\nexport interface ScreenStateProps<\n TItem extends BaseItem,\n> extends AutocompleteApi<\n TItem,\n React.FormEvent,\n React.MouseEvent,\n React.KeyboardEvent\n> {\n state: AutocompleteState<TItem>;\n recentSearches: StoredSearchPlugin<StoredDocSearchHit>;\n favoriteSearches: StoredSearchPlugin<StoredDocSearchHit>;\n onItemClick: (\n item: InternalDocSearchHit,\n event: KeyboardEvent | MouseEvent\n ) => void;\n inputRef: React.MutableRefObject<HTMLInputElement | null>;\n hitComponent: DocSearchProps['hitComponent'];\n indexName: string;\n disableUserPersonalization: boolean;\n resultsFooterComponent: DocSearchProps['resultsFooterComponent'];\n translations: ScreenStateTranslations;\n getMissingResultsUrl?: DocSearchProps['getMissingResultsUrl'];\n hasCollections: boolean;\n resultBadgeKey?: string;\n}\n\nexport const ScreenState = React.memo(\n ({ translations = {}, ...props }: ScreenStateProps<InternalDocSearchHit>) => {\n if (props.state?.status === 'error') {\n return <ErrorScreen translations={translations?.errorScreen} />;\n }\n\n if (isQueryEmpty(props.state.query)) {\n return (\n <KeywordStartScreen\n {...props}\n hasCollections={props.hasCollections}\n translations={translations?.startScreen}\n />\n );\n }\n\n if (!props.hasCollections) {\n return (\n <NoResultsScreen\n {...props}\n translations={translations?.noResultsScreen}\n />\n );\n }\n\n return (\n <ResultsScreen {...props} translations={translations?.resultsScreen} />\n );\n },\n function areEqual(prevProps, nextProps) {\n const isLoading =\n nextProps.state.status === 'loading' ||\n nextProps.state.status === 'stalled';\n\n const isWaitingForCollections =\n nextProps.state.status === 'idle' &&\n !isQueryEmpty(nextProps.state.query) &&\n prevProps.state.query !== nextProps.state.query &&\n prevProps.state.collections === nextProps.state.collections;\n\n return isLoading || isWaitingForCollections;\n }\n);\n","import { createAutocomplete } from '@algolia/autocomplete-core';\nimport React, { type JSX } from 'react';\n\nimport type { FacetBarTranslations } from './components/FacetBar';\nimport { FacetBar } from './components/FacetBar';\nimport type { KeywordSearchBoxTranslations } from './components/KeywordSearchBox';\nimport { KeywordSearchBox } from './components/KeywordSearchBox';\nimport { ModalShell } from './components/ui/ModalShell';\nimport type { DocSearchProps } from './DocSearch';\nimport type { FooterTranslations } from './Footer';\nimport { Footer } from './Footer';\nimport { Hit } from './Hit';\nimport { useDocSearchFacets } from './hooks/useDocSearchFacets';\nimport { useSendItemClickEvent } from './hooks/useDocSearchInsights';\nimport { useInitialModalQuery } from './hooks/useInitialModalQuery';\nimport { useModalEnvironment } from './hooks/useModalEnvironment';\nimport { useModalRefs } from './hooks/useModalRefs';\nimport { useRefreshOnInitialQuery } from './hooks/useRefreshOnInitialQuery';\nimport { useSaveRecentSearch } from './hooks/useSaveRecentSearch';\nimport { useStoredDocSearches } from './hooks/useStoredDocSearches';\nimport type { ScreenStateTranslations } from './ScreenState';\nimport { ScreenState } from './ScreenState';\nimport type { DocSearchState, InternalDocSearchHit } from './types';\nimport { useSearchClient } from './useSearchClient';\nimport {\n identity,\n isModifierEvent,\n isQueryEmpty,\n noop,\n scrollTo as scrollToUtils,\n} from './utils';\nimport {\n buildNoQuerySources,\n buildQuerySources,\n type BuildQuerySourcesState,\n} from './utils/createDocSearchSources';\nimport { normalizeDocSearchIndexes } from './utils/normalizeDocSearchIndexes';\n\nexport type ModalTranslations = Partial<{\n searchBox: KeywordSearchBoxTranslations;\n footer: FooterTranslations;\n facets: FacetBarTranslations;\n}> &\n ScreenStateTranslations;\n\nexport type DocSearchModalProps = DocSearchProps & {\n initialScrollY: number;\n onClose?: () => void;\n translations?: ModalTranslations;\n};\n\nexport function DocSearchModal({\n appId,\n apiKey,\n maxResultsPerGroup,\n theme,\n onClose = noop,\n transformItems = identity,\n hitComponent = Hit,\n resultsFooterComponent = (): JSX.Element | null => null,\n navigator,\n initialScrollY = 0,\n transformSearchClient = identity,\n disableUserPersonalization = false,\n initialQuery: initialQueryFromProp = '',\n translations = {},\n getMissingResultsUrl,\n insights = false,\n recentSearchesLimit = 7,\n recentSearchesWithFavoritesLimit = 4,\n indices,\n facets,\n footerAction,\n ...props\n}: DocSearchModalProps): JSX.Element {\n const {\n footer: footerTranslations,\n searchBox: searchBoxTranslations,\n facets: facetBarTranslations,\n ...screenStateTranslations\n } = translations;\n const [state, setState] = React.useState<\n DocSearchState<InternalDocSearchHit>\n >({\n query: '',\n collections: [],\n completion: null,\n context: {},\n isOpen: false,\n activeItemId: null,\n status: 'idle',\n });\n\n const placeholder =\n translations?.searchBox?.placeholderText ||\n props.placeholder ||\n 'Search docs';\n\n const { containerRef, modalRef, formElementRef, dropdownRef, inputRef } =\n useModalRefs();\n const { initialQuery, initialQueryFromSelection } =\n useInitialModalQuery(initialQueryFromProp);\n\n const searchClient = useSearchClient(appId, apiKey, transformSearchClient);\n\n const indexes = React.useMemo(\n () =>\n normalizeDocSearchIndexes({\n indices,\n }),\n [indices]\n );\n const defaultIndexName = indexes[0].name;\n\n const autocompleteRef =\n React.useRef<\n ReturnType<\n typeof createAutocomplete<\n InternalDocSearchHit,\n React.FormEvent<HTMLFormElement>,\n React.MouseEvent,\n React.KeyboardEvent\n >\n >\n >(undefined);\n\n const {\n visibleFacets,\n facetSelections,\n facetSelectionsRef,\n handleFacetSelectionChange,\n clearFacetSelections,\n } = useDocSearchFacets({\n facets,\n indexes,\n searchClient,\n onSelectionsChange: () => autocompleteRef.current?.refresh(),\n });\n\n const { favoriteSearches, recentSearches } = useStoredDocSearches({\n defaultIndexName,\n recentSearchesLimit,\n recentSearchesWithFavoritesLimit,\n });\n const saveRecentSearch = useSaveRecentSearch({\n favoriteSearches,\n recentSearches,\n disableUserPersonalization,\n });\n const sendItemClickEvent = useSendItemClickEvent(state);\n\n if (!autocompleteRef.current) {\n autocompleteRef.current = createAutocomplete({\n id: 'docsearch',\n defaultActiveItemId: 0,\n openOnFocus: true,\n initialState: {\n query: initialQuery,\n context: {\n searchSuggestions: [],\n },\n },\n insights: Boolean(insights),\n navigator,\n onStateChange(changes) {\n setState(changes.state);\n },\n getSources({ query, state: sourcesState, setContext, setStatus }) {\n if (isQueryEmpty(query)) {\n const noQuerySources = buildNoQuerySources({\n recentSearches,\n favoriteSearches,\n saveRecentSearch,\n onClose,\n disableUserPersonalization,\n });\n return noQuerySources;\n }\n\n const querySourcesState: BuildQuerySourcesState = {\n context: sourcesState.context,\n };\n\n const algoliaSourcesPromise = buildQuerySources({\n query,\n state: querySourcesState,\n setContext,\n setStatus,\n searchClient,\n indexes,\n insights: Boolean(insights),\n appId,\n apiKey,\n maxResultsPerGroup,\n transformItems,\n saveRecentSearch,\n onClose,\n facetSelections: facetSelectionsRef,\n });\n\n return algoliaSourcesPromise;\n },\n });\n }\n\n const autocomplete = autocompleteRef.current;\n\n const { getEnvironmentProps, getRootProps, refresh } = autocomplete;\n\n useModalEnvironment({\n getEnvironmentProps,\n containerRef,\n dropdownRef,\n formElementRef,\n inputRef,\n initialScrollY,\n modalRef,\n theme,\n });\n\n React.useEffect(() => {\n if (dropdownRef.current) {\n scrollToUtils(dropdownRef.current);\n }\n }, [state.query, dropdownRef]);\n\n useRefreshOnInitialQuery({ initialQuery, inputRef, refresh });\n\n // hide the dropdown on idle and no collections\n let showDocsearchDropdown = true;\n const hasCollections = state.collections.some(\n (collection) => collection.items.length > 0\n );\n if (\n state.status === 'idle' &&\n hasCollections === false &&\n isQueryEmpty(state.query)\n ) {\n showDocsearchDropdown = false;\n }\n\n return (\n <ModalShell\n state={state}\n containerRef={containerRef}\n modalRef={modalRef}\n formElementRef={formElementRef}\n dropdownRef={dropdownRef}\n getRootProps={getRootProps}\n showDropdown={showDocsearchDropdown}\n searchBox={\n <KeywordSearchBox\n {...autocomplete}\n state={state}\n placeholder={placeholder || 'Search docs'}\n autoFocus={isQueryEmpty(initialQuery)}\n inputRef={inputRef}\n isFromSelection={\n Boolean(initialQuery) && initialQuery === initialQueryFromSelection\n }\n translations={searchBoxTranslations}\n onClose={onClose}\n />\n }\n filterBar={\n !isQueryEmpty(state.query) ? (\n <FacetBar\n facets={visibleFacets}\n selections={facetSelections}\n translations={facetBarTranslations}\n clearSelections={clearFacetSelections}\n onSelectionChange={handleFacetSelectionChange}\n />\n ) : null\n }\n screenState={\n <ScreenState\n {...autocomplete}\n indexName={defaultIndexName}\n state={state}\n hitComponent={hitComponent}\n resultsFooterComponent={resultsFooterComponent}\n disableUserPersonalization={disableUserPersonalization}\n recentSearches={recentSearches}\n favoriteSearches={favoriteSearches}\n inputRef={inputRef}\n translations={screenStateTranslations}\n getMissingResultsUrl={getMissingResultsUrl}\n hasCollections={hasCollections}\n resultBadgeKey={props.resultBadgeKey}\n onItemClick={(item, event) => {\n sendItemClickEvent(item);\n saveRecentSearch(item);\n if (!isModifierEvent(event)) {\n onClose();\n }\n }}\n />\n }\n footer={\n <Footer translations={footerTranslations} footerAction={footerAction} />\n }\n onClose={onClose}\n />\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DocSearchModal-CLcbYBea.js","names":[],"sources":["../../src/components/KeywordSearchBox.tsx","../../src/components/KeywordStartScreen.tsx","../../src/ScreenState.tsx","../../src/DocSearchModal.tsx"],"sourcesContent":["import type {\n AutocompleteApi,\n AutocompleteState,\n} from '@algolia/autocomplete-core';\nimport React, { type JSX, type RefObject } from 'react';\n\nimport type { InternalDocSearchHit } from '../types';\n\nimport { SearchBoxForm } from './ui/SearchBoxForm';\n\nexport type KeywordSearchBoxTranslations = Partial<{\n clearButtonTitle: string;\n clearButtonAriaLabel: string;\n closeButtonText: string;\n closeButtonAriaLabel: string;\n placeholderText: string;\n enterKeyHint: string;\n searchInputLabel: string;\n}>;\n\ninterface KeywordSearchBoxProps extends AutocompleteApi<\n InternalDocSearchHit,\n React.FormEvent,\n React.MouseEvent,\n React.KeyboardEvent\n> {\n state: AutocompleteState<InternalDocSearchHit>;\n autoFocus: boolean;\n inputRef: RefObject<HTMLInputElement | null>;\n onClose: () => void;\n placeholder: string;\n isFromSelection: boolean;\n translations?: KeywordSearchBoxTranslations;\n}\n\nexport function KeywordSearchBox({\n translations = {},\n ...props\n}: KeywordSearchBoxProps): JSX.Element {\n const {\n clearButtonTitle = 'Clear',\n clearButtonAriaLabel = 'Clear the query',\n closeButtonText = 'Close',\n closeButtonAriaLabel = 'Close',\n searchInputLabel = 'Search',\n } = translations;\n\n const actionsBeforeClose = (\n <>\n <button\n className=\"DocSearch-Clear\"\n type=\"reset\"\n aria-label={clearButtonAriaLabel}\n hidden={!props.state.query}\n tabIndex={props.state.query ? 0 : -1}\n aria-hidden={!props.state.query ? 'true' : 'false'}\n >\n {clearButtonTitle}\n </button>\n\n {props.state.query && <div className=\"DocSearch-Divider\" />}\n </>\n );\n\n return (\n <SearchBoxForm\n {...props}\n clearButtonTitle={clearButtonTitle}\n clearButtonAriaLabel={clearButtonAriaLabel}\n closeButtonText={closeButtonText}\n closeButtonAriaLabel={closeButtonAriaLabel}\n searchInputLabel={searchInputLabel}\n inputProps={{\n enterKeyHint: 'search',\n }}\n actionsBeforeClose={actionsBeforeClose}\n />\n );\n}\n","import React, { type JSX } from 'react';\n\nimport type { ScreenStateProps } from '../ScreenState';\nimport type { InternalDocSearchHit } from '../types';\n\nimport type { StoredSearchesSectionsTranslations } from './ui/StoredSearchesSections';\nimport { StoredSearchesSections } from './ui/StoredSearchesSections';\n\nexport type KeywordStartScreenTranslations = StoredSearchesSectionsTranslations;\n\ntype KeywordStartScreenProps = Omit<\n ScreenStateProps<InternalDocSearchHit>,\n 'translations'\n> & {\n hasCollections: boolean;\n translations?: KeywordStartScreenTranslations;\n};\n\nexport function KeywordStartScreen({\n translations = {},\n ...props\n}: KeywordStartScreenProps): JSX.Element | null {\n return (\n <div className=\"DocSearch-Dropdown-Container\">\n <StoredSearchesSections {...props} translations={translations} />\n </div>\n );\n}\n","import type {\n AutocompleteApi,\n AutocompleteState,\n BaseItem,\n} from '@algolia/autocomplete-core';\nimport React from 'react';\n\nimport type { KeywordStartScreenTranslations } from './components/KeywordStartScreen';\nimport { KeywordStartScreen } from './components/KeywordStartScreen';\nimport type { DocSearchProps } from './DocSearch';\nimport type { ErrorScreenTranslations } from './ErrorScreen';\nimport { ErrorScreen } from './ErrorScreen';\nimport type { NoResultsScreenTranslations } from './NoResultsScreen';\nimport { NoResultsScreen } from './NoResultsScreen';\nimport type { ResultsScreenTranslations } from './ResultsScreen';\nimport { ResultsScreen } from './ResultsScreen';\nimport type { StoredSearchPlugin } from './stored-searches';\nimport type { InternalDocSearchHit, StoredDocSearchHit } from './types';\nimport { isQueryEmpty } from './utils';\n\nexport type ScreenStateTranslations = Partial<{\n errorScreen: ErrorScreenTranslations;\n startScreen: KeywordStartScreenTranslations;\n noResultsScreen: NoResultsScreenTranslations;\n resultsScreen: ResultsScreenTranslations;\n}>;\n\nexport interface ScreenStateProps<\n TItem extends BaseItem,\n> extends AutocompleteApi<\n TItem,\n React.FormEvent,\n React.MouseEvent,\n React.KeyboardEvent\n> {\n state: AutocompleteState<TItem>;\n recentSearches: StoredSearchPlugin<StoredDocSearchHit>;\n favoriteSearches: StoredSearchPlugin<StoredDocSearchHit>;\n onItemClick: (\n item: InternalDocSearchHit,\n event: KeyboardEvent | MouseEvent\n ) => void;\n inputRef: React.MutableRefObject<HTMLInputElement | null>;\n hitComponent: DocSearchProps['hitComponent'];\n indexName: string;\n disableUserPersonalization: boolean;\n resultsFooterComponent: DocSearchProps['resultsFooterComponent'];\n translations: ScreenStateTranslations;\n getMissingResultsUrl?: DocSearchProps['getMissingResultsUrl'];\n hasCollections: boolean;\n resultBadgeKey?: string;\n}\n\nexport const ScreenState = React.memo(\n ({ translations = {}, ...props }: ScreenStateProps<InternalDocSearchHit>) => {\n if (props.state?.status === 'error') {\n return <ErrorScreen translations={translations?.errorScreen} />;\n }\n\n if (isQueryEmpty(props.state.query)) {\n return (\n <KeywordStartScreen\n {...props}\n hasCollections={props.hasCollections}\n translations={translations?.startScreen}\n />\n );\n }\n\n if (!props.hasCollections) {\n return (\n <NoResultsScreen\n {...props}\n translations={translations?.noResultsScreen}\n />\n );\n }\n\n return (\n <ResultsScreen {...props} translations={translations?.resultsScreen} />\n );\n },\n function areEqual(prevProps, nextProps) {\n const isLoading =\n nextProps.state.status === 'loading' ||\n nextProps.state.status === 'stalled';\n\n const isWaitingForCollections =\n nextProps.state.status === 'idle' &&\n !isQueryEmpty(nextProps.state.query) &&\n prevProps.state.query !== nextProps.state.query &&\n prevProps.state.collections === nextProps.state.collections;\n\n return isLoading || isWaitingForCollections;\n }\n);\n","import { createAutocomplete } from '@algolia/autocomplete-core';\nimport React, { type JSX } from 'react';\n\nimport type { FacetBarTranslations } from './components/FacetBar';\nimport { FacetBar } from './components/FacetBar';\nimport type { KeywordSearchBoxTranslations } from './components/KeywordSearchBox';\nimport { KeywordSearchBox } from './components/KeywordSearchBox';\nimport { ModalShell } from './components/ui/ModalShell';\nimport type { DocSearchProps } from './DocSearch';\nimport type { FooterTranslations } from './Footer';\nimport { Footer } from './Footer';\nimport { Hit } from './Hit';\nimport { useDocSearchFacets } from './hooks/useDocSearchFacets';\nimport { useSendItemClickEvent } from './hooks/useDocSearchInsights';\nimport { useInitialModalQuery } from './hooks/useInitialModalQuery';\nimport { useModalEnvironment } from './hooks/useModalEnvironment';\nimport { useModalRefs } from './hooks/useModalRefs';\nimport { useRefreshOnInitialQuery } from './hooks/useRefreshOnInitialQuery';\nimport { useSaveRecentSearch } from './hooks/useSaveRecentSearch';\nimport { useStoredDocSearches } from './hooks/useStoredDocSearches';\nimport type { ScreenStateTranslations } from './ScreenState';\nimport { ScreenState } from './ScreenState';\nimport type { DocSearchState, InternalDocSearchHit } from './types';\nimport { useSearchClient } from './useSearchClient';\nimport {\n identity,\n isModifierEvent,\n isQueryEmpty,\n noop,\n scrollTo as scrollToUtils,\n} from './utils';\nimport {\n buildNoQuerySources,\n buildQuerySources,\n type BuildQuerySourcesState,\n} from './utils/createDocSearchSources';\nimport { normalizeDocSearchIndexes } from './utils/normalizeDocSearchIndexes';\n\nexport type ModalTranslations = Partial<{\n searchBox: KeywordSearchBoxTranslations;\n footer: FooterTranslations;\n facets: FacetBarTranslations;\n}> &\n ScreenStateTranslations;\n\nexport type DocSearchModalProps = DocSearchProps & {\n initialScrollY: number;\n onClose?: () => void;\n translations?: ModalTranslations;\n};\n\nexport function DocSearchModal({\n appId,\n apiKey,\n maxResultsPerGroup,\n theme,\n onClose = noop,\n transformItems = identity,\n hitComponent = Hit,\n resultsFooterComponent = (): JSX.Element | null => null,\n navigator,\n initialScrollY = 0,\n transformSearchClient = identity,\n disableUserPersonalization = false,\n initialQuery: initialQueryFromProp = '',\n translations = {},\n getMissingResultsUrl,\n insights = false,\n recentSearchesLimit = 7,\n recentSearchesWithFavoritesLimit = 4,\n indices,\n facets,\n footerAction,\n ...props\n}: DocSearchModalProps): JSX.Element {\n const {\n footer: footerTranslations,\n searchBox: searchBoxTranslations,\n facets: facetBarTranslations,\n ...screenStateTranslations\n } = translations;\n const [state, setState] = React.useState<\n DocSearchState<InternalDocSearchHit>\n >({\n query: '',\n collections: [],\n completion: null,\n context: {},\n isOpen: false,\n activeItemId: null,\n status: 'idle',\n });\n\n const placeholder =\n translations?.searchBox?.placeholderText ||\n props.placeholder ||\n 'Search docs';\n\n const { containerRef, modalRef, formElementRef, dropdownRef, inputRef } =\n useModalRefs();\n const { initialQuery, initialQueryFromSelection } =\n useInitialModalQuery(initialQueryFromProp);\n\n const searchClient = useSearchClient(appId, apiKey, transformSearchClient);\n\n const indexes = React.useMemo(\n () =>\n normalizeDocSearchIndexes({\n indices,\n }),\n [indices]\n );\n const defaultIndexName = indexes[0].name;\n\n const autocompleteRef =\n React.useRef<\n ReturnType<\n typeof createAutocomplete<\n InternalDocSearchHit,\n React.FormEvent<HTMLFormElement>,\n React.MouseEvent,\n React.KeyboardEvent\n >\n >\n >(undefined);\n\n const {\n visibleFacets,\n facetSelections,\n facetSelectionsRef,\n handleFacetSelectionChange,\n clearFacetSelections,\n } = useDocSearchFacets({\n facets,\n indexes,\n searchClient,\n onSelectionsChange: () => autocompleteRef.current?.refresh(),\n });\n\n const { favoriteSearches, recentSearches } = useStoredDocSearches({\n defaultIndexName,\n recentSearchesLimit,\n recentSearchesWithFavoritesLimit,\n });\n const saveRecentSearch = useSaveRecentSearch({\n favoriteSearches,\n recentSearches,\n disableUserPersonalization,\n });\n const sendItemClickEvent = useSendItemClickEvent(state);\n\n if (!autocompleteRef.current) {\n autocompleteRef.current = createAutocomplete({\n id: 'docsearch',\n defaultActiveItemId: 0,\n openOnFocus: true,\n initialState: {\n query: initialQuery,\n context: {\n searchSuggestions: [],\n },\n },\n insights: Boolean(insights),\n navigator,\n onStateChange(changes) {\n setState(changes.state);\n },\n getSources({ query, state: sourcesState, setContext, setStatus }) {\n if (isQueryEmpty(query)) {\n const noQuerySources = buildNoQuerySources({\n recentSearches,\n favoriteSearches,\n saveRecentSearch,\n onClose,\n disableUserPersonalization,\n });\n return noQuerySources;\n }\n\n const querySourcesState: BuildQuerySourcesState = {\n context: sourcesState.context,\n };\n\n const algoliaSourcesPromise = buildQuerySources({\n query,\n state: querySourcesState,\n setContext,\n setStatus,\n searchClient,\n indexes,\n insights: Boolean(insights),\n appId,\n apiKey,\n maxResultsPerGroup,\n transformItems,\n saveRecentSearch,\n onClose,\n facetSelections: facetSelectionsRef,\n });\n\n return algoliaSourcesPromise;\n },\n });\n }\n\n const autocomplete = autocompleteRef.current;\n\n const { getEnvironmentProps, getRootProps, refresh } = autocomplete;\n\n useModalEnvironment({\n getEnvironmentProps,\n containerRef,\n dropdownRef,\n formElementRef,\n inputRef,\n initialScrollY,\n modalRef,\n theme,\n });\n\n React.useEffect(() => {\n if (dropdownRef.current) {\n scrollToUtils(dropdownRef.current);\n }\n }, [state.query, dropdownRef]);\n\n useRefreshOnInitialQuery({ initialQuery, inputRef, refresh });\n\n // hide the dropdown on idle and no collections\n let showDocsearchDropdown = true;\n const hasCollections = state.collections.some(\n (collection) => collection.items.length > 0\n );\n if (\n state.status === 'idle' &&\n hasCollections === false &&\n isQueryEmpty(state.query)\n ) {\n showDocsearchDropdown = false;\n }\n\n return (\n <ModalShell\n state={state}\n containerRef={containerRef}\n modalRef={modalRef}\n formElementRef={formElementRef}\n dropdownRef={dropdownRef}\n getRootProps={getRootProps}\n showDropdown={showDocsearchDropdown}\n searchBox={\n <KeywordSearchBox\n {...autocomplete}\n state={state}\n placeholder={placeholder || 'Search docs'}\n autoFocus={isQueryEmpty(initialQuery)}\n inputRef={inputRef}\n isFromSelection={\n Boolean(initialQuery) && initialQuery === initialQueryFromSelection\n }\n translations={searchBoxTranslations}\n onClose={onClose}\n />\n }\n filterBar={\n !isQueryEmpty(state.query) ? (\n <FacetBar\n facets={visibleFacets}\n selections={facetSelections}\n translations={facetBarTranslations}\n clearSelections={clearFacetSelections}\n onSelectionChange={handleFacetSelectionChange}\n />\n ) : null\n }\n screenState={\n <ScreenState\n {...autocomplete}\n indexName={defaultIndexName}\n state={state}\n hitComponent={hitComponent}\n resultsFooterComponent={resultsFooterComponent}\n disableUserPersonalization={disableUserPersonalization}\n recentSearches={recentSearches}\n favoriteSearches={favoriteSearches}\n inputRef={inputRef}\n translations={screenStateTranslations}\n getMissingResultsUrl={getMissingResultsUrl}\n hasCollections={hasCollections}\n resultBadgeKey={props.resultBadgeKey}\n onItemClick={(item, event) => {\n sendItemClickEvent(item);\n saveRecentSearch(item);\n if (!isModifierEvent(event)) {\n onClose();\n }\n }}\n />\n }\n footer={\n <Footer translations={footerTranslations} footerAction={footerAction} />\n }\n onClose={onClose}\n />\n );\n}\n"],"mappings":"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"}
|
package/dist/esm/askaiModal.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { d as DocSearchAskAiModalProps, f as DocSearchAskAiModalTranslations, u as DocSearchAskAiModal } from "./DocSearchAI-
|
|
1
|
+
import { d as DocSearchAskAiModalProps, f as DocSearchAskAiModalTranslations, u as DocSearchAskAiModal } from "./DocSearchAI-f-C2lV8l.js";
|
|
2
2
|
export { DocSearchAskAiModal, DocSearchAskAiModalProps, DocSearchAskAiModalTranslations };
|
package/dist/esm/askaiModal.js
CHANGED
package/dist/esm/docsearch.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as DocSearchProps, c as DocSearchTranslations, i as DocSearchInner, l as HitComponentProps, n as DocSearchFacet, o as DocSearchRef, r as DocSearchIndex, s as DocSearchTransformClient, t as DocSearch, u as ResultsFooterComponentProps } from "./DocSearch-
|
|
1
|
+
import { a as DocSearchProps, c as DocSearchTranslations, i as DocSearchInner, l as HitComponentProps, n as DocSearchFacet, o as DocSearchRef, r as DocSearchIndex, s as DocSearchTransformClient, t as DocSearch, u as ResultsFooterComponentProps } from "./DocSearch-BFLV-F2L.js";
|
|
2
2
|
export { DocSearch, DocSearchFacet, DocSearchIndex, DocSearchInner, DocSearchProps, type DocSearchRef, DocSearchTransformClient, DocSearchTranslations, HitComponentProps, ResultsFooterComponentProps };
|
package/dist/esm/docsearch.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as _objectSpread2 } from "./objectSpread2-BNmiQYyW.js";
|
|
2
2
|
import { t as DocSearchButton } from "./DocSearchButton-CaxxOzQU.js";
|
|
3
3
|
import { t as _objectWithoutProperties } from "./objectWithoutProperties-phqYxDS0.js";
|
|
4
|
-
import { t as DocSearchModal } from "./DocSearchModal-
|
|
4
|
+
import { t as DocSearchModal } from "./DocSearchModal-CLcbYBea.js";
|
|
5
5
|
import { DocSearch as DocSearch$1, useDocSearch } from "@docsearch/core";
|
|
6
6
|
import React from "react";
|
|
7
7
|
import { createPortal } from "react-dom";
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { o as ToolCalls } from "./index-BijiN4hK.js";
|
|
2
|
-
import { a as DocSearchAIProps, c as Memory, i as DocSearchAIInner, l as PromptSuggestions, n as AskAiSearchParameters, o as DocSearchAITranslations, r as DocSearchAI, s as DocSearchAskAi, t as AgentStudioSearchParameters } from "./DocSearchAI-
|
|
2
|
+
import { a as DocSearchAIProps, c as Memory, i as DocSearchAIInner, l as PromptSuggestions, n as AskAiSearchParameters, o as DocSearchAITranslations, r as DocSearchAI, s as DocSearchAskAi, t as AgentStudioSearchParameters } from "./DocSearchAI-f-C2lV8l.js";
|
|
3
3
|
export { AgentStudioSearchParameters, AskAiSearchParameters, DocSearchAI, DocSearchAIInner, DocSearchAIProps, DocSearchAITranslations, DocSearchAskAi, Memory, PromptSuggestions, type ToolCalls };
|
package/dist/esm/docsearchAi.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as _objectSpread2 } from "./objectSpread2-BNmiQYyW.js";
|
|
2
2
|
import { t as DocSearchButton } from "./DocSearchButton-CaxxOzQU.js";
|
|
3
3
|
import { t as _objectWithoutProperties } from "./objectWithoutProperties-phqYxDS0.js";
|
|
4
|
-
import { t as DocSearchAskAiModal } from "./DocSearchAskAiModal-
|
|
4
|
+
import { t as DocSearchAskAiModal } from "./DocSearchAskAiModal-CZm9AVU0.js";
|
|
5
5
|
import { DocSearch, useDocSearch } from "@docsearch/core";
|
|
6
6
|
import React from "react";
|
|
7
7
|
import { createPortal } from "react-dom";
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { a as StoredDocSearchHit, c as AskAiFeedbackReason, d as DocSearchHit, i as StoredAskAiState, l as OnAskAiFeedback, n as SuggestedQuestionHit, o as ToolCalls, r as StoredAskAiMessage, s as AskAiFeedbackPayload, t as SuggestedQuestion, u as DocSearchState } from "./index-BijiN4hK.js";
|
|
2
2
|
import { t as DocSearchTheme } from "./DocSearchTheme-DvL4mf0D.js";
|
|
3
|
-
import { a as DocSearchProps, b as InternalDocSearchHit, c as DocSearchTranslations, d as DocSearchModal, f as DocSearchModalProps, i as DocSearchInner, l as HitComponentProps, n as DocSearchFacet, o as DocSearchRef, p as ModalTranslations, r as DocSearchIndex, s as DocSearchTransformClient, t as DocSearch, u as ResultsFooterComponentProps } from "./DocSearch-
|
|
3
|
+
import { a as DocSearchProps, b as InternalDocSearchHit, c as DocSearchTranslations, d as DocSearchModal, f as DocSearchModalProps, i as DocSearchInner, l as HitComponentProps, n as DocSearchFacet, o as DocSearchRef, p as ModalTranslations, r as DocSearchIndex, s as DocSearchTransformClient, t as DocSearch, u as ResultsFooterComponentProps } from "./DocSearch-BFLV-F2L.js";
|
|
4
4
|
import { n as useDocSearchKeyboardEvents, r as KeyboardShortcuts, t as UseDocSearchKeyboardEventsProps } from "./useDocSearchKeyboardEvents-B7PKBkuX.js";
|
|
5
5
|
import { n as DocSearchButton, r as DocSearchButtonProps, t as ButtonTranslations } from "./DocSearchButton-DyJd_QGM.js";
|
|
6
|
-
import { a as DocSearchAIProps, c as Memory, d as DocSearchAskAiModalProps, f as DocSearchAskAiModalTranslations, i as DocSearchAIInner, l as PromptSuggestions, n as AskAiSearchParameters, o as DocSearchAITranslations, r as DocSearchAI, s as DocSearchAskAi, t as AgentStudioSearchParameters, u as DocSearchAskAiModal } from "./DocSearchAI-
|
|
6
|
+
import { a as DocSearchAIProps, c as Memory, d as DocSearchAskAiModalProps, f as DocSearchAskAiModalTranslations, i as DocSearchAIInner, l as PromptSuggestions, n as AskAiSearchParameters, o as DocSearchAITranslations, r as DocSearchAI, s as DocSearchAskAi, t as AgentStudioSearchParameters, u as DocSearchAskAiModal } from "./DocSearchAI-f-C2lV8l.js";
|
|
7
7
|
import { version } from "./version.js";
|
|
8
8
|
export { AgentStudioSearchParameters, AskAiFeedbackPayload, AskAiFeedbackReason, AskAiSearchParameters, ButtonTranslations, DocSearch, DocSearchAI, DocSearchAIInner, DocSearchAIProps, DocSearchAITranslations, DocSearchAskAi, DocSearchAskAiModal, DocSearchAskAiModalProps, DocSearchAskAiModalTranslations, DocSearchButton, DocSearchButtonProps, DocSearchFacet, DocSearchHit, DocSearchIndex, DocSearchInner, DocSearchModal, DocSearchModalProps, DocSearchProps, type DocSearchRef, DocSearchState, DocSearchTheme, DocSearchTransformClient, DocSearchTranslations, HitComponentProps, InternalDocSearchHit, KeyboardShortcuts, Memory, ModalTranslations, OnAskAiFeedback, PromptSuggestions, ResultsFooterComponentProps, StoredAskAiMessage, StoredAskAiState, StoredDocSearchHit, SuggestedQuestion, SuggestedQuestionHit, type ToolCalls, UseDocSearchKeyboardEventsProps, useDocSearchKeyboardEvents, version };
|
package/dist/esm/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as DocSearchButton } from "./DocSearchButton-CaxxOzQU.js";
|
|
2
|
-
import { t as DocSearchAskAiModal } from "./DocSearchAskAiModal-
|
|
3
|
-
import { t as DocSearchModal } from "./DocSearchModal-
|
|
2
|
+
import { t as DocSearchAskAiModal } from "./DocSearchAskAiModal-CZm9AVU0.js";
|
|
3
|
+
import { t as DocSearchModal } from "./DocSearchModal-CLcbYBea.js";
|
|
4
4
|
import { version } from "./version.js";
|
|
5
5
|
import { DocSearch, DocSearchInner } from "./docsearch.js";
|
|
6
6
|
import { DocSearchAI, DocSearchAIInner } from "./docsearchAi.js";
|
package/dist/esm/modal.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { d as DocSearchModal, f as DocSearchModalProps, p as ModalTranslations } from "./DocSearch-
|
|
1
|
+
import { d as DocSearchModal, f as DocSearchModalProps, p as ModalTranslations } from "./DocSearch-BFLV-F2L.js";
|
|
2
2
|
export { DocSearchModal, DocSearchModalProps, ModalTranslations };
|
package/dist/esm/modal.js
CHANGED
package/dist/esm/{normalizeDocSearchIndexes-CFHzf-sx.js → normalizeDocSearchIndexes-B_bI_ytC.js}
RENAMED
|
@@ -239,18 +239,58 @@ function getFacetLabel(facet) {
|
|
|
239
239
|
if (facet.label) return facet.label;
|
|
240
240
|
return facet.key.replace(/[._-]+/g, " ").replace(/\b\w/g, (letter) => letter.toUpperCase());
|
|
241
241
|
}
|
|
242
|
+
/**
|
|
243
|
+
* Extracts the facet key from an Algolia `facetFilters` string entry such as
|
|
244
|
+
* `language:en`. Returns `null` when the entry doesn't have a `key:value`
|
|
245
|
+
* shape.
|
|
246
|
+
*/
|
|
247
|
+
function getFacetFilterKey(facetFilter) {
|
|
248
|
+
const separatorIndex = facetFilter.indexOf(":");
|
|
249
|
+
return separatorIndex <= 0 ? null : facetFilter.slice(0, separatorIndex);
|
|
250
|
+
}
|
|
251
|
+
function parseFacetFilter(facetFilter) {
|
|
252
|
+
const key = getFacetFilterKey(facetFilter);
|
|
253
|
+
if (key === null) return null;
|
|
254
|
+
const value = facetFilter.slice(key.length + 1);
|
|
255
|
+
return value ? {
|
|
256
|
+
key,
|
|
257
|
+
value
|
|
258
|
+
} : null;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Reads the initial facet selections from the configured `facetFilters` of each
|
|
262
|
+
* index. Later indices override earlier ones for the same facet key.
|
|
263
|
+
*
|
|
264
|
+
* - A `key:value` string selects a single value.
|
|
265
|
+
* - A nested OR group whose entries all share the same key (for example
|
|
266
|
+
* `['docusaurus_tag:default', 'docusaurus_tag:docs-default-current']`)
|
|
267
|
+
* selects every value in the group.
|
|
268
|
+
* - OR groups that mix facet keys can't map to a single facet and are ignored.
|
|
269
|
+
*/
|
|
242
270
|
function deriveDefaultSelectedFacetsFromIndex(indices) {
|
|
243
271
|
const defaultFacets = {};
|
|
244
272
|
for (const index of indices) {
|
|
245
273
|
var _index$searchParamete;
|
|
246
274
|
const facetFilters = (_index$searchParamete = index.searchParameters) === null || _index$searchParamete === void 0 ? void 0 : _index$searchParamete.facetFilters;
|
|
247
275
|
for (const facetFilter of Array.isArray(facetFilters) ? facetFilters : [facetFilters]) {
|
|
248
|
-
if (typeof facetFilter
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
if (
|
|
276
|
+
if (typeof facetFilter === "string") {
|
|
277
|
+
const parsed = parseFacetFilter(facetFilter);
|
|
278
|
+
if (parsed) defaultFacets[parsed.key] = [parsed.value];
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
if (!Array.isArray(facetFilter) || facetFilter.length === 0) continue;
|
|
282
|
+
let groupKey = null;
|
|
283
|
+
const groupValues = [];
|
|
284
|
+
for (const entry of facetFilter) {
|
|
285
|
+
const parsed = typeof entry === "string" ? parseFacetFilter(entry) : null;
|
|
286
|
+
if (!parsed || groupKey !== null && parsed.key !== groupKey) {
|
|
287
|
+
groupKey = null;
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
groupKey = parsed.key;
|
|
291
|
+
groupValues.push(parsed.value);
|
|
292
|
+
}
|
|
293
|
+
if (groupKey !== null) defaultFacets[groupKey] = groupValues;
|
|
254
294
|
}
|
|
255
295
|
}
|
|
256
296
|
return defaultFacets;
|
|
@@ -284,8 +324,10 @@ const _excluded2 = [
|
|
|
284
324
|
"collisionBoundary",
|
|
285
325
|
"container"
|
|
286
326
|
];
|
|
287
|
-
const _excluded3 = ["className"
|
|
288
|
-
const _excluded4 = ["className"];
|
|
327
|
+
const _excluded3 = ["className"];
|
|
328
|
+
const _excluded4 = ["className", "children"];
|
|
329
|
+
const _excluded5 = ["className", "children"];
|
|
330
|
+
const _excluded6 = ["className"];
|
|
289
331
|
function Menu$1(_ref) {
|
|
290
332
|
let props = _extends({}, (_objectDestructuringEmpty(_ref), _ref));
|
|
291
333
|
return /* @__PURE__ */ React.createElement(Menu.Root, props);
|
|
@@ -310,13 +352,19 @@ function MenuPopup(_ref3) {
|
|
|
310
352
|
}, /* @__PURE__ */ React.createElement(Menu.Popup, _objectSpread2({ className: "DocSearch-Menu-Popup" }, props))));
|
|
311
353
|
}
|
|
312
354
|
Menu$1.Popup = MenuPopup;
|
|
313
|
-
function
|
|
314
|
-
let
|
|
355
|
+
function MenuItem(_ref4) {
|
|
356
|
+
let { className } = _ref4, props = _objectWithoutProperties(_ref4, _excluded3);
|
|
357
|
+
const cn = `DocSearch-Menu-Item${className ? ` ${className}` : ""}`;
|
|
358
|
+
return /* @__PURE__ */ React.createElement(Menu.Item, _objectSpread2({ className: cn }, props));
|
|
359
|
+
}
|
|
360
|
+
Menu$1.Item = MenuItem;
|
|
361
|
+
function MenuRadioGroup(_ref5) {
|
|
362
|
+
let props = _extends({}, (_objectDestructuringEmpty(_ref5), _ref5));
|
|
315
363
|
return /* @__PURE__ */ React.createElement(Menu.RadioGroup, props);
|
|
316
364
|
}
|
|
317
365
|
Menu$1.RadioGroup = MenuRadioGroup;
|
|
318
|
-
function MenuRadioItem(
|
|
319
|
-
let { className, children } =
|
|
366
|
+
function MenuRadioItem(_ref6) {
|
|
367
|
+
let { className, children } = _ref6, props = _objectWithoutProperties(_ref6, _excluded4);
|
|
320
368
|
const cn = `DocSearch-Menu-Item DocSearch-Menu-RadioItem${className ? ` ${className}` : ""}`;
|
|
321
369
|
return /* @__PURE__ */ React.createElement(Menu.RadioItem, _objectSpread2({
|
|
322
370
|
className: cn,
|
|
@@ -324,8 +372,14 @@ function MenuRadioItem(_ref5) {
|
|
|
324
372
|
}, props), /* @__PURE__ */ React.createElement("span", { className: "DocSearch-Menu-RadioItem-Indicator" }, /* @__PURE__ */ React.createElement(Menu.RadioItemIndicator, null, /* @__PURE__ */ React.createElement(CheckIcon, null))), children);
|
|
325
373
|
}
|
|
326
374
|
Menu$1.RadioItem = MenuRadioItem;
|
|
327
|
-
function
|
|
328
|
-
let { className } =
|
|
375
|
+
function MenuCheckboxItem(_ref7) {
|
|
376
|
+
let { className, children } = _ref7, props = _objectWithoutProperties(_ref7, _excluded5);
|
|
377
|
+
const cn = `DocSearch-Menu-Item DocSearch-Menu-CheckboxItem${className ? ` ${className}` : ""}`;
|
|
378
|
+
return /* @__PURE__ */ React.createElement(Menu.CheckboxItem, _objectSpread2({ className: cn }, props), /* @__PURE__ */ React.createElement("span", { className: "DocSearch-Menu-CheckboxItem-Indicator" }, /* @__PURE__ */ React.createElement(Menu.CheckboxItemIndicator, null, /* @__PURE__ */ React.createElement(CheckIcon, null))), children);
|
|
379
|
+
}
|
|
380
|
+
Menu$1.CheckboxItem = MenuCheckboxItem;
|
|
381
|
+
function MenuGroupLabel(_ref8) {
|
|
382
|
+
let { className } = _ref8, props = _objectWithoutProperties(_ref8, _excluded6);
|
|
329
383
|
const cn = `DocSearch-Menu-GroupLabel${className ? ` ${className}` : ""}`;
|
|
330
384
|
return /* @__PURE__ */ React.createElement(Menu.GroupLabel, _objectSpread2({ className: cn }, props));
|
|
331
385
|
}
|
|
@@ -333,34 +387,64 @@ Menu$1.GroupLabel = MenuGroupLabel;
|
|
|
333
387
|
|
|
334
388
|
//#endregion
|
|
335
389
|
//#region src/components/FacetBar.tsx
|
|
336
|
-
const
|
|
390
|
+
const EMPTY_SELECTION$1 = [];
|
|
391
|
+
const FacetValueItem = React.memo(function FacetValueItem({ facetKey, value, checked, onToggle }) {
|
|
392
|
+
const handleCheckedChange = React.useCallback(() => {
|
|
393
|
+
onToggle(facetKey, value);
|
|
394
|
+
}, [
|
|
395
|
+
facetKey,
|
|
396
|
+
onToggle,
|
|
397
|
+
value
|
|
398
|
+
]);
|
|
399
|
+
return /* @__PURE__ */ React.createElement(Menu$1.CheckboxItem, {
|
|
400
|
+
checked,
|
|
401
|
+
label: value,
|
|
402
|
+
onCheckedChange: handleCheckedChange
|
|
403
|
+
}, capitalize(value));
|
|
404
|
+
});
|
|
405
|
+
function toggleValue(value) {
|
|
406
|
+
return (currentValues) => currentValues.includes(value) ? currentValues.filter((selected) => selected !== value) : [...currentValues, value];
|
|
407
|
+
}
|
|
408
|
+
function removeValue(value) {
|
|
409
|
+
return (currentValues) => currentValues.filter((selected) => selected !== value);
|
|
410
|
+
}
|
|
411
|
+
const FacetMenu = React.memo(function FacetMenu({ facet, selectedValues, defaultValueLabel, onSelectionChange, registerTrigger, menuTriggerSelectedAriaLabel }) {
|
|
337
412
|
const label = getFacetLabel(facet);
|
|
338
|
-
const
|
|
339
|
-
|
|
413
|
+
const hasSelection = selectedValues.length > 0;
|
|
414
|
+
const selectedSet = React.useMemo(() => new Set(selectedValues), [selectedValues]);
|
|
415
|
+
const handleToggleValue = React.useCallback((facetKey, value) => {
|
|
416
|
+
onSelectionChange(facetKey, toggleValue(value));
|
|
417
|
+
}, [onSelectionChange]);
|
|
418
|
+
const handleSelectAll = React.useCallback(() => {
|
|
419
|
+
onSelectionChange(facet.key, EMPTY_SELECTION$1);
|
|
340
420
|
}, [facet.key, onSelectionChange]);
|
|
341
421
|
const triggerRef = React.useCallback((el) => {
|
|
342
422
|
registerTrigger(facet.key, el);
|
|
343
423
|
}, [facet.key, registerTrigger]);
|
|
344
424
|
return /* @__PURE__ */ React.createElement(Menu$1, null, /* @__PURE__ */ React.createElement(Menu$1.Trigger, {
|
|
345
425
|
ref: triggerRef,
|
|
346
|
-
"data-has-selection":
|
|
347
|
-
"aria-label":
|
|
348
|
-
}, /* @__PURE__ */ React.createElement("span", null, capitalize(label)), /* @__PURE__ */ React.createElement(ChevronIcon, null)), /* @__PURE__ */ React.createElement(Menu$1.Popup, null, /* @__PURE__ */ React.createElement(Menu$1.
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
label: `${defaultValueLabel} ${label}`
|
|
354
|
-
}, defaultValueLabel), facet.values.map((value) => /* @__PURE__ */ React.createElement(Menu$1.RadioItem, {
|
|
426
|
+
"data-has-selection": hasSelection,
|
|
427
|
+
"aria-label": hasSelection ? `${label}, ${selectedValues.join(", ")} ${menuTriggerSelectedAriaLabel}` : label
|
|
428
|
+
}, /* @__PURE__ */ React.createElement("span", null, capitalize(label)), /* @__PURE__ */ React.createElement(ChevronIcon, null)), /* @__PURE__ */ React.createElement(Menu$1.Popup, null, /* @__PURE__ */ React.createElement(Menu$1.Item, {
|
|
429
|
+
className: "DocSearch-Menu-ResetItem",
|
|
430
|
+
label: `${defaultValueLabel} ${label}`,
|
|
431
|
+
onClick: handleSelectAll
|
|
432
|
+
}, defaultValueLabel), facet.values.map((value) => /* @__PURE__ */ React.createElement(FacetValueItem, {
|
|
355
433
|
key: value,
|
|
434
|
+
facetKey: facet.key,
|
|
356
435
|
value,
|
|
357
|
-
|
|
358
|
-
|
|
436
|
+
checked: selectedSet.has(value),
|
|
437
|
+
onToggle: handleToggleValue
|
|
438
|
+
}))));
|
|
359
439
|
});
|
|
360
440
|
const SelectedFacetChip = React.memo(function SelectedFacetChip({ facetKey, facetLabel, value, dismissAriaLabel, onDismiss }) {
|
|
361
441
|
const handleDismissFacet = React.useCallback((e) => {
|
|
362
|
-
onDismiss(facetKey, e);
|
|
363
|
-
}, [
|
|
442
|
+
onDismiss(facetKey, value, e);
|
|
443
|
+
}, [
|
|
444
|
+
facetKey,
|
|
445
|
+
onDismiss,
|
|
446
|
+
value
|
|
447
|
+
]);
|
|
364
448
|
return /* @__PURE__ */ React.createElement(Chip, null, capitalize(value), /* @__PURE__ */ React.createElement(Chip.Dismiss, {
|
|
365
449
|
"aria-label": `${dismissAriaLabel} ${capitalize(value)} (${facetLabel})`,
|
|
366
450
|
onClick: handleDismissFacet
|
|
@@ -370,14 +454,19 @@ const FacetBar = React.memo(function FacetBar({ facets, selections, onSelectionC
|
|
|
370
454
|
const { defaultValueLabel = "All", facetMenuTriggerAriaLabel = "selected", clearAllLabel = "Clear all", facetsAriaLabel = "Search filters", selectedFacetsAriaLabel = "Selected search filters", clearFacetAriaLabel = "Clear filter:" } = translations;
|
|
371
455
|
const visibleFacetKeys = React.useMemo(() => new Set(facets.map((f) => f.key)), [facets]);
|
|
372
456
|
const selectionsToDisplay = React.useMemo(() => {
|
|
373
|
-
|
|
457
|
+
const entries = [];
|
|
458
|
+
for (const [key, values] of Object.entries(selections)) {
|
|
459
|
+
if (!visibleFacetKeys.has(key)) continue;
|
|
460
|
+
for (const value of values) entries.push([key, value]);
|
|
461
|
+
}
|
|
462
|
+
return entries;
|
|
374
463
|
}, [selections, visibleFacetKeys]);
|
|
375
464
|
const triggerRefs = React.useRef(/* @__PURE__ */ new Map());
|
|
376
465
|
const registerTrigger = React.useCallback((facetKey, el) => {
|
|
377
466
|
if (el) triggerRefs.current.set(facetKey, el);
|
|
378
467
|
else triggerRefs.current.delete(facetKey);
|
|
379
468
|
}, []);
|
|
380
|
-
const handleDismissFacet = React.useCallback((facetKey, ev) => {
|
|
469
|
+
const handleDismissFacet = React.useCallback((facetKey, value, ev) => {
|
|
381
470
|
const dismissButton = ev.currentTarget;
|
|
382
471
|
const selectionBar = dismissButton.closest(".DocSearch-FacetSelectionBar");
|
|
383
472
|
if (selectionBar) {
|
|
@@ -387,7 +476,7 @@ const FacetBar = React.memo(function FacetBar({ facets, selections, onSelectionC
|
|
|
387
476
|
const target = (_ref = (_dismissButtons = dismissButtons[index + 1]) !== null && _dismissButtons !== void 0 ? _dismissButtons : dismissButtons[index - 1]) !== null && _ref !== void 0 ? _ref : triggerRefs.current.get(facetKey);
|
|
388
477
|
target === null || target === void 0 || target.focus();
|
|
389
478
|
}
|
|
390
|
-
onSelectionChange(facetKey,
|
|
479
|
+
onSelectionChange(facetKey, removeValue(value));
|
|
391
480
|
}, [onSelectionChange]);
|
|
392
481
|
const handleClearAll = React.useCallback(() => {
|
|
393
482
|
var _triggerRefs$current$;
|
|
@@ -402,11 +491,10 @@ const FacetBar = React.memo(function FacetBar({ facets, selections, onSelectionC
|
|
|
402
491
|
"aria-label": facetsAriaLabel
|
|
403
492
|
}, facets.map((facet) => {
|
|
404
493
|
var _selections$facet$key;
|
|
405
|
-
const selectedValue = (_selections$facet$key = selections[facet.key]) !== null && _selections$facet$key !== void 0 ? _selections$facet$key : "";
|
|
406
494
|
return /* @__PURE__ */ React.createElement(FacetMenu, {
|
|
407
495
|
key: facet.key,
|
|
408
496
|
facet,
|
|
409
|
-
|
|
497
|
+
selectedValues: (_selections$facet$key = selections[facet.key]) !== null && _selections$facet$key !== void 0 ? _selections$facet$key : EMPTY_SELECTION$1,
|
|
410
498
|
defaultValueLabel,
|
|
411
499
|
registerTrigger,
|
|
412
500
|
menuTriggerSelectedAriaLabel: facetMenuTriggerAriaLabel,
|
|
@@ -419,7 +507,7 @@ const FacetBar = React.memo(function FacetBar({ facets, selections, onSelectionC
|
|
|
419
507
|
}, selectionsToDisplay.map(([key, value]) => {
|
|
420
508
|
var _facetLabels$get;
|
|
421
509
|
return /* @__PURE__ */ React.createElement(SelectedFacetChip, {
|
|
422
|
-
key
|
|
510
|
+
key: `${key}:${value}`,
|
|
423
511
|
facetKey: key,
|
|
424
512
|
facetLabel: (_facetLabels$get = facetLabels.get(key)) !== null && _facetLabels$get !== void 0 ? _facetLabels$get : key,
|
|
425
513
|
value,
|
|
@@ -598,6 +686,19 @@ function useFacetValues({ facets, indexes, searchClient }) {
|
|
|
598
686
|
|
|
599
687
|
//#endregion
|
|
600
688
|
//#region src/hooks/useDocSearchFacets.ts
|
|
689
|
+
const EMPTY_SELECTION = [];
|
|
690
|
+
/**
|
|
691
|
+
* Compares two selections for a facet. A missing entry and an empty array are
|
|
692
|
+
* both "nothing selected" so clearing an untouched facet doesn't trigger a
|
|
693
|
+
* refresh.
|
|
694
|
+
*/
|
|
695
|
+
function areSelectionsEqual(a, b) {
|
|
696
|
+
const left = a !== null && a !== void 0 ? a : EMPTY_SELECTION;
|
|
697
|
+
const right = b !== null && b !== void 0 ? b : EMPTY_SELECTION;
|
|
698
|
+
if (left === right) return true;
|
|
699
|
+
if (left.length !== right.length) return false;
|
|
700
|
+
return left.every((value, index) => value === right[index]);
|
|
701
|
+
}
|
|
601
702
|
function useDocSearchFacets({ facets, indexes, searchClient, onSelectionsChange }) {
|
|
602
703
|
const normalizedFacets = React.useMemo(() => normalizeFacets(facets), [facets]);
|
|
603
704
|
const normalizedFacetsRef = React.useRef(normalizedFacets);
|
|
@@ -627,16 +728,23 @@ function useDocSearchFacets({ facets, indexes, searchClient, onSelectionsChange
|
|
|
627
728
|
visibleFacets,
|
|
628
729
|
facetSelections,
|
|
629
730
|
facetSelectionsRef,
|
|
630
|
-
handleFacetSelectionChange: React.useCallback((facet,
|
|
631
|
-
|
|
632
|
-
const
|
|
633
|
-
|
|
634
|
-
applySelections(
|
|
731
|
+
handleFacetSelectionChange: React.useCallback((facet, update) => {
|
|
732
|
+
const existing = facetSelectionsRef.current[facet];
|
|
733
|
+
const values = typeof update === "function" ? update(existing !== null && existing !== void 0 ? existing : EMPTY_SELECTION) : update;
|
|
734
|
+
if (areSelectionsEqual(existing, values)) return;
|
|
735
|
+
applySelections(_objectSpread2(_objectSpread2({}, facetSelectionsRef.current), {}, { [facet]: values }));
|
|
635
736
|
}, [applySelections]),
|
|
636
737
|
clearFacetSelections: React.useCallback(() => {
|
|
637
|
-
|
|
738
|
+
const current = facetSelectionsRef.current;
|
|
638
739
|
const next = {};
|
|
639
|
-
|
|
740
|
+
let hasSelectedValues = false;
|
|
741
|
+
for (const facet of normalizedFacetsRef.current) {
|
|
742
|
+
const values = current[facet.key];
|
|
743
|
+
if (values === void 0) continue;
|
|
744
|
+
if (values.length > 0) hasSelectedValues = true;
|
|
745
|
+
next[facet.key] = EMPTY_SELECTION;
|
|
746
|
+
}
|
|
747
|
+
if (!hasSelectedValues) return;
|
|
640
748
|
applySelections(next);
|
|
641
749
|
}, [applySelections])
|
|
642
750
|
};
|
|
@@ -1130,21 +1238,31 @@ function ResultsScreen(_ref) {
|
|
|
1130
1238
|
|
|
1131
1239
|
//#endregion
|
|
1132
1240
|
//#region src/utils/createDocSearchSources.ts
|
|
1241
|
+
function isFacetFilterOverridden(facetFilter, selectedFacets) {
|
|
1242
|
+
if (typeof facetFilter === "string") {
|
|
1243
|
+
const key = getFacetFilterKey(facetFilter);
|
|
1244
|
+
return key !== null && selectedFacets.has(key);
|
|
1245
|
+
}
|
|
1246
|
+
return facetFilter.length > 0 && facetFilter.every((entry) => isFacetFilterOverridden(entry, selectedFacets));
|
|
1247
|
+
}
|
|
1248
|
+
/**
|
|
1249
|
+
* Merges configured `facetFilters` with the user's facet selections.
|
|
1250
|
+
*
|
|
1251
|
+
* Multiple values selected for the same facet are combined into an OR group
|
|
1252
|
+
* (nested array). Different facets are combined with AND (top-level entries),
|
|
1253
|
+
* following Algolia `facetFilters` semantics.
|
|
1254
|
+
*/
|
|
1133
1255
|
function createFacetFilters(searchParametersFacetFilters, facetSelections) {
|
|
1134
1256
|
const selections = Object.entries(facetSelections);
|
|
1257
|
+
if (selections.length === 0) return searchParametersFacetFilters;
|
|
1135
1258
|
const selectedFacets = new Set(selections.map(([facet]) => facet));
|
|
1136
1259
|
const dynamicFacetFilters = [];
|
|
1137
|
-
for (const [facet,
|
|
1138
|
-
if (
|
|
1260
|
+
for (const [facet, values] of selections) if (values.length === 1) dynamicFacetFilters.push(`${facet}:${values[0]}`);
|
|
1261
|
+
else if (values.length > 1) dynamicFacetFilters.push(values.map((value) => `${facet}:${value}`));
|
|
1139
1262
|
let configuredFacetFilters = [];
|
|
1140
1263
|
if (searchParametersFacetFilters && Array.isArray(searchParametersFacetFilters)) configuredFacetFilters = searchParametersFacetFilters;
|
|
1141
1264
|
else if (searchParametersFacetFilters) configuredFacetFilters = [searchParametersFacetFilters];
|
|
1142
|
-
return [...configuredFacetFilters.filter((facetFilter) =>
|
|
1143
|
-
if (typeof facetFilter !== "string") return true;
|
|
1144
|
-
const separatorIndex = facetFilter.indexOf(":");
|
|
1145
|
-
const facet = facetFilter.slice(0, separatorIndex);
|
|
1146
|
-
return separatorIndex <= 0 || !selectedFacets.has(facet);
|
|
1147
|
-
}), ...dynamicFacetFilters];
|
|
1265
|
+
return [...configuredFacetFilters.filter((facetFilter) => !isFacetFilterOverridden(facetFilter, selectedFacets)), ...dynamicFacetFilters];
|
|
1148
1266
|
}
|
|
1149
1267
|
function buildNoQuerySources({ recentSearches, favoriteSearches, saveRecentSearch, onClose, disableUserPersonalization }) {
|
|
1150
1268
|
if (disableUserPersonalization) return [];
|
|
@@ -1268,4 +1386,4 @@ function normalizeDocSearchIndexes({ indices }) {
|
|
|
1268
1386
|
|
|
1269
1387
|
//#endregion
|
|
1270
1388
|
export { noop as C, SOURCE_IDS as D, identity as E, getCollection as O, scrollTo as S, isModifierEvent as T, Hit as _, NoResultsScreen as a, SearchBoxForm as b, Results as c, useRefreshOnInitialQuery as d, useModalRefs as f, useDocSearchFacets as g, useSendItemClickEvent as h, ResultsScreen as i, useStoredDocSearches as l, useInitialModalQuery as m, buildNoQuerySources as n, ErrorScreen as o, useModalEnvironment as p, buildQuerySources as r, StoredSearchesSections as s, normalizeDocSearchIndexes as t, useSaveRecentSearch as u, Footer as v, isQueryEmpty as w, FacetBar as x, ModalShell as y };
|
|
1271
|
-
//# sourceMappingURL=normalizeDocSearchIndexes-
|
|
1389
|
+
//# sourceMappingURL=normalizeDocSearchIndexes-B_bI_ytC.js.map
|