diff --git a/www/apps/api-reference/providers/search.tsx b/www/apps/api-reference/providers/search.tsx index f9406ceb98..a642be45a5 100644 --- a/www/apps/api-reference/providers/search.tsx +++ b/www/apps/api-reference/providers/search.tsx @@ -1,10 +1,6 @@ "use client" -import { - usePageLoading, - SearchProvider as UiSearchProvider, - searchFilters, -} from "docs-ui" +import { usePageLoading, SearchProvider as UiSearchProvider } from "docs-ui" import { config } from "../config" import basePathUrl from "../utils/base-path-url" @@ -20,17 +16,18 @@ const SearchProvider = ({ children }: SearchProviderProps) => { appId: process.env.NEXT_PUBLIC_ALGOLIA_APP_ID || "temp", apiKey: process.env.NEXT_PUBLIC_ALGOLIA_API_KEY || "temp", mainIndexName: process.env.NEXT_PUBLIC_API_ALGOLIA_INDEX_NAME || "temp", - indices: [ - { - name: process.env.NEXT_PUBLIC_API_ALGOLIA_INDEX_NAME || "temp", - title: "Store & Admin API", - }, - { - name: process.env.NEXT_PUBLIC_DOCS_ALGOLIA_INDEX_NAME || "temp", - title: "Docs", - }, - ], }} + indices={[ + { + value: process.env.NEXT_PUBLIC_DOCS_ALGOLIA_INDEX_NAME || "temp", + title: "Docs", + }, + { + value: process.env.NEXT_PUBLIC_API_ALGOLIA_INDEX_NAME || "temp", + title: "Store & Admin API", + }, + ]} + defaultIndex={process.env.NEXT_PUBLIC_API_ALGOLIA_INDEX_NAME || "temp"} searchProps={{ isLoading, suggestions: [ @@ -55,7 +52,6 @@ const SearchProvider = ({ children }: SearchProviderProps) => { checkInternalPattern: new RegExp( `^${config.baseUrl}${basePathUrl(`/(admin|store)`)}` ), - filterOptions: searchFilters, }} > {children} diff --git a/www/apps/book/providers/search.tsx b/www/apps/book/providers/search.tsx index e83792b688..d8e0344258 100644 --- a/www/apps/book/providers/search.tsx +++ b/www/apps/book/providers/search.tsx @@ -1,6 +1,6 @@ "use client" -import { SearchProvider as UiSearchProvider, searchFilters } from "docs-ui" +import { SearchProvider as UiSearchProvider } from "docs-ui" import { config } from "../config" type SearchProviderProps = { @@ -15,17 +15,18 @@ const SearchProvider = ({ children }: SearchProviderProps) => { apiKey: process.env.NEXT_PUBLIC_ALGOLIA_API_KEY || "temp", mainIndexName: process.env.NEXT_PUBLIC_DOCS_ALGOLIA_INDEX_NAME || "temp", - indices: [ - { - name: process.env.NEXT_PUBLIC_DOCS_ALGOLIA_INDEX_NAME || "temp", - title: "Docs", - }, - { - name: process.env.NEXT_PUBLIC_API_ALGOLIA_INDEX_NAME || "temp", - title: "Store & Admin API", - }, - ], }} + indices={[ + { + value: process.env.NEXT_PUBLIC_DOCS_ALGOLIA_INDEX_NAME || "temp", + title: "Docs", + }, + { + value: process.env.NEXT_PUBLIC_API_ALGOLIA_INDEX_NAME || "temp", + title: "Store & Admin API", + }, + ]} + defaultIndex={process.env.NEXT_PUBLIC_DOCS_ALGOLIA_INDEX_NAME || "temp"} searchProps={{ isLoading: false, suggestions: [ @@ -51,7 +52,6 @@ const SearchProvider = ({ children }: SearchProviderProps) => { checkInternalPattern: new RegExp( `^${config.baseUrl}/([^(resources)])*` ), - filterOptions: searchFilters, }} > {children} diff --git a/www/apps/resources/providers/search.tsx b/www/apps/resources/providers/search.tsx index a21006cfb8..78a1bec85f 100644 --- a/www/apps/resources/providers/search.tsx +++ b/www/apps/resources/providers/search.tsx @@ -1,6 +1,6 @@ "use client" -import { SearchProvider as UiSearchProvider, searchFilters } from "docs-ui" +import { SearchProvider as UiSearchProvider } from "docs-ui" import { config } from "../config" type SearchProviderProps = { @@ -15,17 +15,18 @@ const SearchProvider = ({ children }: SearchProviderProps) => { apiKey: process.env.NEXT_PUBLIC_ALGOLIA_API_KEY || "temp", mainIndexName: process.env.NEXT_PUBLIC_DOCS_ALGOLIA_INDEX_NAME || "temp", - indices: [ - { - name: process.env.NEXT_PUBLIC_DOCS_ALGOLIA_INDEX_NAME || "temp", - title: "Docs", - }, - { - name: process.env.NEXT_PUBLIC_API_ALGOLIA_INDEX_NAME || "temp", - title: "Store & Admin API", - }, - ], }} + indices={[ + { + value: process.env.NEXT_PUBLIC_DOCS_ALGOLIA_INDEX_NAME || "temp", + title: "Docs", + }, + { + value: process.env.NEXT_PUBLIC_API_ALGOLIA_INDEX_NAME || "temp", + title: "Store & Admin API", + }, + ]} + defaultIndex={process.env.NEXT_PUBLIC_DOCS_ALGOLIA_INDEX_NAME || "temp"} searchProps={{ isLoading: false, suggestions: [ @@ -40,7 +41,6 @@ const SearchProvider = ({ children }: SearchProviderProps) => { }, ], checkInternalPattern: new RegExp(`^${config.baseUrl}/resources/.*`), - filterOptions: searchFilters, }} > {children} diff --git a/www/apps/ui/src/providers/search.tsx b/www/apps/ui/src/providers/search.tsx index aa4a4be4a1..89cde5161d 100644 --- a/www/apps/ui/src/providers/search.tsx +++ b/www/apps/ui/src/providers/search.tsx @@ -1,6 +1,6 @@ "use client" -import { SearchProvider as UiSearchProvider, searchFilters } from "docs-ui" +import { SearchProvider as UiSearchProvider } from "docs-ui" import { absoluteUrl } from "../lib/absolute-url" type SearchProviderProps = { @@ -15,17 +15,18 @@ const SearchProvider = ({ children }: SearchProviderProps) => { apiKey: process.env.NEXT_PUBLIC_ALGOLIA_API_KEY || "temp", mainIndexName: process.env.NEXT_PUBLIC_DOCS_ALGOLIA_INDEX_NAME || "temp", - indices: [ - { - name: process.env.NEXT_PUBLIC_DOCS_ALGOLIA_INDEX_NAME || "temp", - title: "Docs", - }, - { - name: process.env.NEXT_PUBLIC_API_ALGOLIA_INDEX_NAME || "temp", - title: "Store & Admin API", - }, - ], }} + indices={[ + { + value: process.env.NEXT_PUBLIC_DOCS_ALGOLIA_INDEX_NAME || "temp", + title: "Docs", + }, + { + value: process.env.NEXT_PUBLIC_API_ALGOLIA_INDEX_NAME || "temp", + title: "Store & Admin API", + }, + ]} + defaultIndex={process.env.NEXT_PUBLIC_DOCS_ALGOLIA_INDEX_NAME || "temp"} searchProps={{ isLoading: false, suggestions: [ @@ -35,7 +36,6 @@ const SearchProvider = ({ children }: SearchProviderProps) => { }, ], checkInternalPattern: new RegExp(`^${absoluteUrl()}/ui`), - filterOptions: searchFilters, }} > {children} diff --git a/www/apps/user-guide/providers/search.tsx b/www/apps/user-guide/providers/search.tsx index c0b5d30284..66edcf1422 100644 --- a/www/apps/user-guide/providers/search.tsx +++ b/www/apps/user-guide/providers/search.tsx @@ -1,6 +1,6 @@ "use client" -import { SearchProvider as UiSearchProvider, searchFilters } from "docs-ui" +import { SearchProvider as UiSearchProvider } from "docs-ui" import { config } from "../config" type SearchProviderProps = { @@ -15,17 +15,18 @@ const SearchProvider = ({ children }: SearchProviderProps) => { apiKey: process.env.NEXT_PUBLIC_ALGOLIA_API_KEY || "temp", mainIndexName: process.env.NEXT_PUBLIC_DOCS_ALGOLIA_INDEX_NAME || "temp", - indices: [ - { - name: process.env.NEXT_PUBLIC_DOCS_ALGOLIA_INDEX_NAME || "temp", - title: "Docs", - }, - { - name: process.env.NEXT_PUBLIC_API_ALGOLIA_INDEX_NAME || "temp", - title: "Store & Admin API", - }, - ], }} + indices={[ + { + value: process.env.NEXT_PUBLIC_DOCS_ALGOLIA_INDEX_NAME || "temp", + title: "Docs", + }, + { + value: process.env.NEXT_PUBLIC_API_ALGOLIA_INDEX_NAME || "temp", + title: "Store & Admin API", + }, + ]} + defaultIndex={process.env.NEXT_PUBLIC_DOCS_ALGOLIA_INDEX_NAME || "temp"} searchProps={{ isLoading: false, suggestions: [ @@ -43,7 +44,6 @@ const SearchProvider = ({ children }: SearchProviderProps) => { }, ], checkInternalPattern: new RegExp(`^${config.baseUrl}/user-guide`), - filterOptions: searchFilters, }} > {children} diff --git a/www/packages/docs-ui/src/components/Search/Filters/index.tsx b/www/packages/docs-ui/src/components/Search/Filters/index.tsx new file mode 100644 index 0000000000..031573e9d8 --- /dev/null +++ b/www/packages/docs-ui/src/components/Search/Filters/index.tsx @@ -0,0 +1,31 @@ +"use client" + +import clsx from "clsx" +import React from "react" +import { useSearch } from "../../../providers" + +export const SearchFilters = () => { + const { indices, selectedIndex, setSelectedIndex } = useSearch() + return ( +
+
+ {indices.map((index) => ( + + ))} +
+
+ ) +} diff --git a/www/packages/docs-ui/src/components/Search/Footer/index.tsx b/www/packages/docs-ui/src/components/Search/Footer/index.tsx index 114b58c854..c3912c1563 100644 --- a/www/packages/docs-ui/src/components/Search/Footer/index.tsx +++ b/www/packages/docs-ui/src/components/Search/Footer/index.tsx @@ -8,13 +8,16 @@ export const SearchFooter = () => { className={clsx( "py-docs_0.75 hidden md:flex items-center justify-end px-docs_1", "border-medusa-border-base border-t", - "bg-medusa-bg-field" + "bg-medusa-bg-field z-10" )} >
Navigation @@ -40,7 +43,10 @@ export const SearchFooter = () => {
Open Result diff --git a/www/packages/docs-ui/src/components/Search/Hits/index.tsx b/www/packages/docs-ui/src/components/Search/Hits/index.tsx index 4162d37286..e3ab3765f9 100644 --- a/www/packages/docs-ui/src/components/Search/Hits/index.tsx +++ b/www/packages/docs-ui/src/components/Search/Hits/index.tsx @@ -1,6 +1,6 @@ "use client" -import React, { Fragment, useEffect, useMemo, useState } from "react" +import React, { useEffect, useMemo, useState } from "react" import clsx from "clsx" import { Configure, @@ -11,7 +11,7 @@ import { useInstantSearch, } from "react-instantsearch" import { SearchNoResult } from "../NoResults" -import { AlgoliaIndex, useSearch } from "@/providers" +import { useSearch } from "@/providers" import { Link, SearchHitGroupName } from "@/components" export type Hierarchy = "lvl0" | "lvl1" | "lvl2" | "lvl3" | "lvl4" | "lvl5" @@ -42,7 +42,6 @@ export type GroupedHitType = { export type SearchHitWrapperProps = { configureProps: ConfigureProps - indices: AlgoliaIndex[] } & Omit export type IndexResults = { @@ -51,41 +50,46 @@ export type IndexResults = { export const SearchHitsWrapper = ({ configureProps, - indices, ...rest }: SearchHitWrapperProps) => { const { status } = useInstantSearch() - const [hasNoResults, setHashNoResults] = useState({ - [indices[0].name]: false, - [indices[1].name]: false, + const { selectedIndex, indices } = useSearch() + const [hasNoResults, setHasNoResults] = useState({ + [indices[0].value]: false, + [indices[1].value]: false, }) - const showNoResults = useMemo(() => { - return Object.values(hasNoResults).every((value) => value === true) - }, [hasNoResults]) - const setNoResults = (index: string, value: boolean) => { - setHashNoResults((prev: IndexResults) => ({ + setHasNoResults((prev) => ({ ...prev, [index]: value, })) } + const showNoResults = useMemo(() => { + return Object.values(hasNoResults).every((val) => val) + }, [hasNoResults]) return ( -
+
{status !== "loading" && showNoResults && } - {indices.map((index, key) => ( - // @ts-expect-error React v19 doesn't see this type as a React element - - {!hasNoResults[index.name] && ( - - )} - - - + {indices.map((index) => ( +
+ {/* @ts-expect-error React v19 doesn't see this type as a React element */} + + {!hasNoResults[index.value] && ( + + )} + + + +
))}
) diff --git a/www/packages/docs-ui/src/components/Search/index.tsx b/www/packages/docs-ui/src/components/Search/index.tsx index 8dd684ffe0..53752be6cf 100644 --- a/www/packages/docs-ui/src/components/Search/index.tsx +++ b/www/packages/docs-ui/src/components/Search/index.tsx @@ -1,16 +1,16 @@ "use client" -import React, { useEffect, useMemo, useRef, useState } from "react" +import React, { useEffect, useRef } from "react" import { InstantSearch, SearchBox } from "react-instantsearch" import clsx from "clsx" import { SearchEmptyQueryBoundary } from "./EmptyQueryBoundary" import { SearchSuggestions, type SearchSuggestionType } from "./Suggestions" import { AlgoliaProps, useSearch } from "@/providers" -import { checkArraySameElms } from "@/utils" import { SearchHitsWrapper } from "./Hits" -import { SelectBadge, SpinnerLoading } from "@/components" +import { SpinnerLoading } from "@/components" import { useSearchNavigation, type OptionType } from "@/hooks" import { SearchFooter } from "./Footer" +import { SearchFilters } from "./Filters" export type SearchProps = { algolia: AlgoliaProps @@ -25,21 +25,13 @@ export const Search = ({ suggestions, isLoading = false, checkInternalPattern, - filterOptions = [], }: SearchProps) => { - const { isOpen, defaultFilters, searchClient, modalRef } = useSearch() - const [filters, setFilters] = useState(defaultFilters) + const { isOpen, searchClient, modalRef } = useSearch() const searchBoxRef = useRef(null) const focusSearchInput = () => searchBoxRef.current?.querySelector("input")?.focus() - useEffect(() => { - if (!checkArraySameElms(defaultFilters, filters)) { - setFilters(defaultFilters) - } - }, [defaultFilters]) - useEffect(() => { if (isOpen && searchBoxRef.current) { focusSearchInput() @@ -57,14 +49,6 @@ export const Search = ({ } }, [isOpen]) - const facetFilters = useMemo(() => { - const filtersToUse = - !filters.length || filters[0] === "all" - ? filterOptions.map((option) => option.value) - : filters - return filtersToUse.map((filter) => "_tags:" + filter) - }, [filters, defaultFilters]) - useSearchNavigation({ getInputElm: () => searchBoxRef.current?.querySelector("input") as HTMLInputElement, @@ -76,30 +60,6 @@ export const Search = ({ return (
- {filterOptions.length > 0 && ( - - setFilters(Array.isArray(value) ? [...value] : [value]) - } - addSelected={(value) => setFilters((prev) => [...prev, value])} - removeSelected={(value) => - setFilters((prev) => prev.filter((v) => v !== value)) - } - showClearButton={false} - placeholder="Filters" - handleAddAll={(isAllSelected: boolean) => { - if (isAllSelected) { - setFilters(defaultFilters) - } else { - setFilters(filterOptions.map((option) => option.value)) - } - }} - className="px-docs_1 pt-docs_1 bg-medusa-bg-base z-10" - /> - )} {/* @ts-expect-error React v19 doesn't see this type as a React element */}
0 && - "h-[calc(100%-95px)] lg:max-h-[calc(100%-140px)] lg:min-h-[calc(100%-140px)]", - filterOptions.length === 0 && - "h-[calc(100%-75px)] lg:max-h-[calc(100%-100px)] lg:min-h-[calc(100%-100px)]" + "md:flex-initial flex flex-col", + "h-[calc(100%-75px)] lg:max-h-[calc(100%-100px)] lg:min-h-[calc(100%-100px)]" )} > + } > diff --git a/www/packages/docs-ui/src/components/VerticalCodeTabs/index.tsx b/www/packages/docs-ui/src/components/VerticalCodeTabs/index.tsx index 564207e763..d3b3bef092 100644 --- a/www/packages/docs-ui/src/components/VerticalCodeTabs/index.tsx +++ b/www/packages/docs-ui/src/components/VerticalCodeTabs/index.tsx @@ -82,6 +82,7 @@ export const VerticalCodeTabs = ({ {...tabs[selectedTabIndex].code} noCopy={true} noReport={true} + noAskAi={true} forceNoTitle={true} wrapperClassName="h-full !rounded-docs_DEFAULT" className={clsx( diff --git a/www/packages/docs-ui/src/constants.tsx b/www/packages/docs-ui/src/constants.tsx index b05264aa17..ac894f104f 100644 --- a/www/packages/docs-ui/src/constants.tsx +++ b/www/packages/docs-ui/src/constants.tsx @@ -1,4 +1,3 @@ -import { OptionType } from "@/hooks" import { NavigationItem } from "types" export const GITHUB_ISSUES_LINK = @@ -356,31 +355,3 @@ export const navDropdownItems: NavigationItem[] = [ link: "/user-guide", }, ] - -export const searchFilters: OptionType[] = [ - { - value: "concepts-guides", - label: "Concepts & Guides", - hitsPerPage: 8, - }, - { - value: "references", - label: "References", - }, - { - value: "admin-v2", - label: "Admin API", - }, - { - value: "store-v2", - label: "Store API", - }, - { - value: "user-guide", - label: "User Guide", - }, - { - value: "troubleshooting", - label: "Troubleshooting", - }, -] diff --git a/www/packages/docs-ui/src/hooks/use-search-navigation/index.ts b/www/packages/docs-ui/src/hooks/use-search-navigation/index.ts index 1a3cfa5561..469322356c 100644 --- a/www/packages/docs-ui/src/hooks/use-search-navigation/index.ts +++ b/www/packages/docs-ui/src/hooks/use-search-navigation/index.ts @@ -87,7 +87,7 @@ export const useSearchNavigation = ({ if (isInput) { // go to the first data-hit item const nextItem = modalRef.current?.querySelector( - "[data-hit]" + "[data-index]:not(.hidden) [data-hit]" ) as HTMLElement nextItem?.focus() } else { diff --git a/www/packages/docs-ui/src/providers/Search/index.tsx b/www/packages/docs-ui/src/providers/Search/index.tsx index 03f8c1a3d3..4a7c40b47c 100644 --- a/www/packages/docs-ui/src/providers/Search/index.tsx +++ b/www/packages/docs-ui/src/providers/Search/index.tsx @@ -9,7 +9,6 @@ import React, { useRef, } from "react" import { BadgeProps, Modal, Search, SearchProps } from "@/components" -import { checkArraySameElms } from "../../utils" import { liteClient as algoliasearch, LiteClient as SearchClient, @@ -30,20 +29,21 @@ export type SearchCommand = { export type SearchContextType = { isOpen: boolean setIsOpen: React.Dispatch> - defaultFilters: string[] - setDefaultFilters: (value: string[]) => void searchClient: SearchClient commands: SearchCommand[] command: SearchCommand | null setCommand: React.Dispatch> setCommands: React.Dispatch> - modalRef: React.MutableRefObject + modalRef: React.RefObject + indices: AlgoliaIndex[] + selectedIndex: string + setSelectedIndex: (value: string) => void } const SearchContext = createContext(null) export type AlgoliaIndex = { - name: string + value: string title: string } @@ -51,12 +51,12 @@ export type AlgoliaProps = { appId: string apiKey: string mainIndexName: string - indices: AlgoliaIndex[] } export type SearchProviderProps = { children: React.ReactNode - initialDefaultFilters?: string[] + indices: AlgoliaIndex[] + defaultIndex: string algolia: AlgoliaProps searchProps: Omit commands?: SearchCommand[] @@ -65,16 +65,16 @@ export type SearchProviderProps = { export const SearchProvider = ({ children, - initialDefaultFilters = [], + defaultIndex: initialDefaultIndex, searchProps, algolia, commands: initialCommands = [], modalClassName, + indices, }: SearchProviderProps) => { const [isOpen, setIsOpen] = useState(false) - const [defaultFilters, setDefaultFilters] = useState( - initialDefaultFilters - ) + const [selectedIndex, setSelectedIndex] = + useState(initialDefaultIndex) const [commands, setCommands] = useState(initialCommands) const [command, setCommand] = useState(null) @@ -88,13 +88,10 @@ export const SearchProvider = ({ }, [algolia.appId, algolia.apiKey]) useEffect(() => { - if ( - initialDefaultFilters.length && - !checkArraySameElms(defaultFilters, initialDefaultFilters) - ) { - setDefaultFilters(initialDefaultFilters) + if (initialDefaultIndex !== selectedIndex) { + setSelectedIndex(initialDefaultIndex) } - }, [initialDefaultFilters]) + }, [initialDefaultIndex]) const componentWrapperRef = useRef(null) @@ -107,14 +104,15 @@ export const SearchProvider = ({ value={{ isOpen, setIsOpen, - defaultFilters, - setDefaultFilters, searchClient, commands, command, setCommand, modalRef, setCommands, + indices, + selectedIndex, + setSelectedIndex, }} > {children}