import type { SearchResult } from "@/services/FlexSearchService"; import type { JSX, Accessor, Setter } from "solid-js"; // import React, { // useId, // createSignal, // createEffect, // createContext, // useContext, // Fragment, // } from "react"; import { createUniqueId, createContext, useContext, For, createEffect, createSignal, } from "solid-js"; import { Dialog, DialogPanel } from "terracotta"; import { useDebounce } from "@/hooks/useDebounce"; // import Highlighter from "react-highlight-words"; // import { navigation } from "@/lib/navigation"; import { navigate } from "vike/client/router"; import { onSearch } from "./Search.telefunc"; import clsx from "clsx"; const SearchContext = createContext<{ query: Accessor; close: () => void; results: Accessor; isLoading: Accessor; isOpened: Accessor; setQuery: (query: string) => void; setIsOpened: (isOpened: boolean) => void; setIsLoading: (isLoading: boolean) => void; setResults: (results: SearchResult[]) => void; }>({ query: () => "", close: () => {}, results: () => [], isLoading: () => false, isOpened: () => false, setQuery: () => {}, setIsOpened: () => {}, setIsLoading: () => {}, setResults: () => {}, }); function SearchIcon(props: JSX.IntrinsicElements["svg"]) { return ( ); } function LoadingIcon(props: JSX.IntrinsicElements["svg"]) { const id = createUniqueId(); return ( ); } function SearchInput() { const { close, setQuery, query, isLoading } = useContext(SearchContext); return (
{ if (event.key === "Escape") { // In Safari, closing the dialog with the escape key can sometimes cause the scroll position to jump to the // bottom of the page. This is a workaround for that until we can figure out a proper fix in Headless UI. if (document.activeElement instanceof HTMLElement) { document.activeElement.blur(); } close(); } }} value={query()} onChange={(event) => setQuery(event.currentTarget.value)} /> {isLoading() && (
)}
); } function HighlightQuery({ text, query }: { text: string; query: string }) { return {text}; // return ( // // ); } function SearchResultItem(props: { result: SearchResult; query: string }) { const { close } = useContext(SearchContext); const id = createUniqueId(); // const sectionTitle = navigation.find((section) => // section.links.find((link) => link.href === result.url.split("#")[0]), // )?.title; // const hierarchy = [sectionTitle, result.pageTitle].filter( // (x): x is string => typeof x === "string", // ); return (
  • { if (event.key === "Enter") { navigate(props.result.url); close(); } }} onClick={() => { navigate(props.result.url); close(); }} > {/* {props.result.length > 0 && ( )} */}
  • ); } function SearchResults() { const { results, query } = useContext(SearchContext); if (results.length === 0) { return (

    Aucun résultat pour “ {query()}

    ); } return (
      {(result) => (
    • )}
    ); } function SearchDialog(props: { class?: string }) { const { close, isOpened, setIsOpened, results } = useContext(SearchContext); createEffect(() => { if (isOpened()) return; function onKeyDown(event: KeyboardEvent) { if (event.key === "k" && (event.metaKey || event.ctrlKey)) { event.preventDefault(); setIsOpened(true); } } window.addEventListener("keydown", onKeyDown); return () => { window.removeEventListener("keydown", onKeyDown); }; }, [isOpened, setIsOpened]); return ( <>
    event.preventDefault()}>
    {results.length > 0 && }
    ); } export function Search() { const [results, setResults] = createSignal([]); const [debouncedQuery, setDebouncedQuery] = useDebounce(""); const [modifierKey, setModifierKey] = createSignal(); const [isLoading, setIsLoading] = createSignal(false); const [isOpened, setIsOpened] = createSignal(false); const [query, setQuery] = createSignal(""); createEffect(() => { const platform = navigator.userAgentData?.platform || navigator.platform; setModifierKey(/(Mac|iPhone|iPod|iPad)/i.test(platform) ? "⌘" : "Ctrl "); }, []); createEffect(() => { setDebouncedQuery(query()); }, [query()]); createEffect(() => { if (debouncedQuery.length === 0) { setIsLoading(false); setResults([]); return; } setIsLoading(true); onSearch(debouncedQuery()) .then(setResults) .finally(() => { setIsLoading(false); }); }, [debouncedQuery()]); return ( setIsOpened(false), results, isLoading, isOpened, setQuery, setIsOpened, setIsLoading, setResults, }} > ); }