Closed jayden-unho closed 4 weeks ago
Latest commit: 2dc6512a2b64dd2c25fb2c277b199e96e4520df3
Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.
Click here to learn what changesets are, and how to add one.
Click here if you're a maintainer who wants to add a changeset to this PR
@jayden-unho is attempting to deploy a commit to the Fuma Team on Vercel.
A member of the Team first needs to authorize it.
The dialog actually relies on the useSearchContext()
context provided by your Root Provider, this is required for shortcuts and lazy loading.
You can import the context hook from fumadocs-ui/provider
, and use it instead of a custom useState
which is not compatible with Root Provider and its search.hotKey
API.
The other option is to just call the props.onOpenChange
function in your CustomSearch
component with a useEffect
hook.
The following component, for example, works really well:
'use client';
import { useDocsSearch } from 'fumadocs-core/search/client';
import {type ReactNode, type ReactElement, useEffect, useState, useContext} from 'react';
import { useOnChange } from 'fumadocs-core/utils/use-on-change';
import {SearchDialog, type SharedProps, type TagItem, TagsList,} from 'fumadocs-ui/components/dialog/search';
import {SearchContext} from "@/context/search";
export interface CustomSearchDialogProps extends SharedProps {
defaultTag?: string;
tags?: TagItem[];
api?: string;
delayMs?: number;
footer?: ReactNode;
}
export default function CustomSearchDialog({defaultTag, tags, api, delayMs, ...props}: CustomSearchDialogProps): ReactElement {
const [tag, setTag] = useState(defaultTag);
const { search, setSearch, query } = useDocsSearch('', tag, api, delayMs);
// @ts-ignore
const {searchOpen, setSearchOpen} = useContext(SearchContext);
useEffect(() => {
if(props.open !== searchOpen) {
setSearchOpen(props.open);
}
}, [props.open]);
useEffect(() => {
if(props.open !== searchOpen) {
props.onOpenChange(searchOpen);
}
}, [searchOpen]);
useOnChange(defaultTag, (v) => {
setTag(v);
});
return (
<SearchDialog
search={search}
onSearchChange={setSearch}
isLoading={query.isLoading}
results={query.data ?? []}
{...props}
open={searchOpen}
footer={
tags ? (
<>
<TagsList tag={tag} onTagChange={setTag} items={tags} />
{props.footer}
</>
) : (
props.footer
)
}
/>
);
}
The key is that fumadocs will pass in the onOpenChange
function as part of the props. If you don't call that function when your button opens the search modal, then the key capture won't be registered. If you do call the function, everything works as expected.
I'm using contexts above to open and close the modal but useState
will work just as well.
Thanks for the explanation of @ShivanshVij, notice that you can use the useOnChange
hook to avoid useEffect.
closing this for now, I think it would be better to expose the props from root provider
Problem
I needed to customize the use of the button that opens the Search Dialog to place it where I wanted it to be
While looking for a way to do this, I found your docs (link)
However, clicking the ESC button or clicking a result in the Dialog list did not close the Search Dialog
https://github.com/user-attachments/assets/b3820143-2bfa-4461-8853-48b56c3e7ae7
Solution & Suggest
I solved the problem in the same way as this PR
I propose to apply this fix
Changes
onOpenChange
props in search componentonOpenChange
method when need to close the search dialog