diff --git a/packages/docs/src/components/docsearch/doc-search-modal.tsx b/packages/docs/src/components/docsearch/doc-search-modal.tsx index 60393c1c101..8bcdf611360 100644 --- a/packages/docs/src/components/docsearch/doc-search-modal.tsx +++ b/packages/docs/src/components/docsearch/doc-search-modal.tsx @@ -33,6 +33,7 @@ export const DocSearchModal = component$( state, transformItems$ = identity, aiResultOpen, + isOpen, disableUserPersonalization = false, }: DocSearchModalProps) => { const containerRef = useSignal(); @@ -44,7 +45,7 @@ export const DocSearchModal = component$( const onSelectItem = noSerialize(({ item, event }: any) => { if (event) { if (!event.shiftKey && !event.ctrlKey && !event.metaKey) { - state.isOpen = false; + isOpen.value = false; } } }) as any; @@ -167,7 +168,8 @@ export const DocSearchModal = component$( tabIndex={0} onMouseDown$={(event) => { if (event.target === containerRef.value) { - state.isOpen = false; + isOpen.value = false; + //state.isOpen.value = false; } }} > @@ -178,7 +180,8 @@ export const DocSearchModal = component$( autoFocus={true} inputRef={inputRef as any} onClose$={() => { - state.isOpen = false; + //state.isOpen.value = false; + isOpen.value = false; }} /> diff --git a/packages/docs/src/components/docsearch/doc-search.tsx b/packages/docs/src/components/docsearch/doc-search.tsx index 4a809788590..be7874b6891 100644 --- a/packages/docs/src/components/docsearch/doc-search.tsx +++ b/packages/docs/src/components/docsearch/doc-search.tsx @@ -1,4 +1,5 @@ import type { SearchClient } from 'algoliasearch/lite'; +import { SearchIcon } from './icons/SearchIcon'; import { component$, useStore, @@ -9,7 +10,9 @@ import { type Signal, $, sync$, + useTask$, } from '@builder.io/qwik'; +import { Modal } from '@qwik-ui/headless'; import type { DocSearchHit, InternalDocSearchHit } from './types'; import { type ButtonTranslations, DocSearchButton } from './doc-search-button'; import { DocSearchModal, type ModalTranslations } from './doc-search-modal'; @@ -21,7 +24,6 @@ export type DocSearchTranslations = Partial<{ }>; export type DocSearchState = { - isOpen: boolean; query: string; collections: { items: InternalDocSearchHit[]; @@ -34,10 +36,10 @@ export type DocSearchState = { status: 'idle' | 'loading' | 'stalled' | 'error'; initialQuery?: string; }; - export interface DocSearchProps { appId: string; apiKey: string; + isOpen: Signal; indexName: string; transformItems$?: (items: DocSearchHit[]) => DocSearchHit[]; transformSearchClient?: (searchClient: SearchClient) => SearchClient; @@ -55,12 +57,12 @@ export const AiResultOpenContext = createContextId>('aiResultOpe export const DocSearch = component$((props: DocSearchProps) => { useStyles$(styles); + const aiResultOpen = useSignal(false); useContextProvider(AiResultOpenContext, aiResultOpen); const state = useStore({ - isOpen: false, initialQuery: '', query: '', collections: [], @@ -73,7 +75,6 @@ export const DocSearch = component$((props: DocSearchProps) => { }); const searchButtonRef = useSignal(); - return (
{ // We check that no other DocSearch modal is showing before opening // another one. if (!document.body.classList.contains('DocSearch--active')) { - state.isOpen = true; + props.isOpen.value = true; } } if ( - (event.key === 'Escape' && state.isOpen) || + (event.key === 'Escape' && props.isOpen.value) || // The `Cmd+K` shortcut both opens and closes the modal. (event.key === 'k' && (event.metaKey || event.ctrlKey)) || // The `/` shortcut opens but doesn't close the modal because it's // a character. - (!isEditingContent(event) && event.key === '/' && !state.isOpen) + (!isEditingContent(event) && event.key === '/' && !props.isOpen.value) ) { event.preventDefault(); - if (state.isOpen) { - state.isOpen = false; + if (props.isOpen.value) { + props.isOpen.value = false; } else if (!document.body.classList.contains('DocSearch--active')) { open(); } @@ -109,28 +110,27 @@ export const DocSearch = component$((props: DocSearchProps) => { if (searchButtonRef && searchButtonRef.value === document.activeElement) { if (/[a-zA-Z0-9]/.test(String.fromCharCode(event.keyCode))) { - state.isOpen = true; + props.isOpen.value = true; state.initialQuery = event.key; } } }), ]} > - { - state.isOpen = true; - }} - /> - {state.isOpen && ( - - )} + + + {props.isOpen.value && ( + + )} + +
); }); diff --git a/packages/docs/src/components/docsearch/search-box.tsx b/packages/docs/src/components/docsearch/search-box.tsx index 0f7b1e2ad6c..1dd34e0b1df 100644 --- a/packages/docs/src/components/docsearch/search-box.tsx +++ b/packages/docs/src/components/docsearch/search-box.tsx @@ -96,7 +96,7 @@ export const SearchBox = component$((props: SearchBoxProps) => { } } if (event.key === 'Escape') { - props.state.isOpen = false; + props.state.isOpen.value = false; } if (event.key === 'Enter') { if (props.state.activeItemId !== null) { diff --git a/packages/docs/src/components/header/header.tsx b/packages/docs/src/components/header/header.tsx index a9aa3a20816..dd4f4312dae 100644 --- a/packages/docs/src/components/header/header.tsx +++ b/packages/docs/src/components/header/header.tsx @@ -1,5 +1,5 @@ import { useLocation } from '@builder.io/qwik-city'; -import { component$, useStyles$, useContext, useVisibleTask$ } from '@builder.io/qwik'; +import { component$, useStyles$, useContext, useVisibleTask$, useSignal } from '@builder.io/qwik'; import { DocSearch } from '../docsearch/doc-search'; import { CloseIcon } from '../svgs/close-icon'; import { DiscordLogo } from '../svgs/discord-logo'; @@ -15,9 +15,28 @@ import { setPreference, ThemeToggle, } from '../theme-toggle/theme-toggle'; +import { SearchIcon } from '../docsearch/icons/SearchIcon'; + +export const SearchButton = component$((props: { onClick$: () => void; className?: string }) => { + return ( + + ); +}); export const Header = component$(() => { useStyles$(styles); + const shouldActivate = useSignal(false); const globalStore = useContext(GlobalStore); const pathname = useLocation().url.pathname; @@ -44,6 +63,14 @@ export const Header = component$(() => { +
+ { + shouldActivate.value = true; + }} + className=" absolute right-10 lg:hidden" + /> +