From 65a98b07ed791f935caeb4115f4d341bafcf7281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Chalifour?= Date: Thu, 14 May 2020 13:52:21 +0200 Subject: [PATCH] feat(docsearch): add `DocSearch` component --- src/DocSearch.tsx | 54 ++++++++++++++++++++++++++++++++++++++++++ src/DocSearchModal.tsx | 17 +++---------- src/index.ts | 3 ++- 3 files changed, 59 insertions(+), 15 deletions(-) create mode 100644 src/DocSearch.tsx diff --git a/src/DocSearch.tsx b/src/DocSearch.tsx new file mode 100644 index 000000000..e6cae310b --- /dev/null +++ b/src/DocSearch.tsx @@ -0,0 +1,54 @@ +import React from 'react'; +import { createPortal } from 'react-dom'; +import { PublicAutocompleteOptions } from '@francoischalifour/autocomplete-core'; + +import { DocSearchHit, InternalDocSearchHit } from './types'; +import { DocSearchButton } from './DocSearchButton'; +import { DocSearchModal } from './DocSearchModal'; +import { useDocSearchKeyboardEvents } from './useDocSearchKeyboardEvents'; + +export interface DocSearchProps + extends Pick, 'navigator'> { + appId?: string; + apiKey: string; + indexName: string; + placeholder?: string; + searchParameters?: any; + transformItems?(items: DocSearchHit[]): DocSearchHit[]; + hitComponent?(props: { + hit: DocSearchHit; + children: React.ReactNode; + }): JSX.Element; +} + +export function DocSearch(props: DocSearchProps) { + const [isOpen, setIsOpen] = React.useState(false); + + const onOpen = React.useCallback( + function onOpen() { + setIsOpen(true); + }, + [setIsOpen] + ); + + const onClose = React.useCallback( + function onClose() { + setIsOpen(false); + }, + [setIsOpen] + ); + + useDocSearchKeyboardEvents({ isOpen, onOpen, onClose }); + + return ( + <> + + + {isOpen && + createPortal( + , + document.body + )} + + ); +} diff --git a/src/DocSearchModal.tsx b/src/DocSearchModal.tsx index 85d6fb133..170068202 100644 --- a/src/DocSearchModal.tsx +++ b/src/DocSearchModal.tsx @@ -2,7 +2,6 @@ import React from 'react'; import { createAutocomplete, AutocompleteState, - PublicAutocompleteOptions, } from '@francoischalifour/autocomplete-core'; import { getAlgoliaHits } from '@francoischalifour/autocomplete-preset-algolia'; @@ -17,24 +16,14 @@ import { createStoredSearches } from './stored-searches'; import { useSearchClient } from './useSearchClient'; import { useTrapFocus } from './useTrapFocus'; import { useTouchEvents } from './useTouchEvents'; +import { DocSearchProps } from './DocSearch'; import { Hit } from './Hit'; import { SearchBox } from './SearchBox'; import { ScreenState } from './ScreenState'; import { Footer } from './Footer'; -interface DocSearchProps - extends Pick, 'navigator'> { - appId?: string; - apiKey: string; - indexName: string; - placeholder?: string; - searchParameters?: any; +interface DocSearchModalProps extends DocSearchProps { onClose?(): void; - transformItems?(items: DocSearchHit[]): DocSearchHit[]; - hitComponent?(props: { - hit: DocSearchHit; - children: React.ReactNode; - }): JSX.Element; } export function DocSearchModal({ @@ -47,7 +36,7 @@ export function DocSearchModal({ transformItems = (x) => x, hitComponent = Hit, navigator, -}: DocSearchProps) { +}: DocSearchModalProps) { const [state, setState] = React.useState< AutocompleteState >({ diff --git a/src/index.ts b/src/index.ts index ee6356a03..7097959d9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,4 @@ -export * from './DocSearchModal'; +export * from './DocSearch'; export * from './DocSearchButton'; +export * from './DocSearchModal'; export * from './useDocSearchKeyboardEvents';