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: Setter; setIsOpened: Setter; setIsLoading: Setter; setResults: Setter; }>({ 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()} onInput={(event) => { const { value } = event.currentTarget; setQuery(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]); const handleClickOutside = (event: MouseEvent) => { const { target, currentTarget } = event; if (target instanceof Node && currentTarget instanceof Node) { if (target === currentTarget) close(); } }; return ( <>
    { if (event.key === "Escape") close(); }} >
    event.preventDefault()}>
    {results().length > 0 && }
    ); } export function Search() { const [results, setResults] = createSignal([]); const [modifierKey, setModifierKey] = createSignal(); const [isLoading, setIsLoading] = createSignal(false); const [isOpened, setIsOpened] = createSignal(false); const [query, setQuery] = createSignal(""); const debouncedQuery = useDebounce(query, 300); createEffect(() => { const platform = navigator.userAgentData?.platform || navigator.platform; setModifierKey(/(Mac|iPhone|iPod|iPad)/i.test(platform) ? "⌘" : "Ctrl "); }, []); createEffect(() => { const query = debouncedQuery(); if (query.length === 0) { setIsLoading(false); setResults([]); return; } setIsLoading(true); onSearch(query) .then(setResults) .finally(() => { setIsLoading(false); }); }); return ( setIsOpened(false), results, isLoading, isOpened, setQuery, setIsOpened, setIsLoading, setResults, }} > ); }