#How to use useEffect with Spotlight
19 messages · Page 1 of 1 (latest)
const spotlight = useSpotlight();
useEffect(() => {
console.log(`Searching for: ${spotlight.query}`);
// Perform the search here, for example by making an API request
// with the searchTerm as a parameter
spotlight.registerActions([
{
id: "secret-action-1",
title: "Secret action",
onTrigger: () => console.log("Secret"),
},
]);
}, [spotlight.query, spotlight]);
I've tried something like this which does not work since query also return an empty value
any ideas on how to do that
Use onQueryChange prop to subscribe to query changes
awesome, will try that. Thanks for the fast response
is there a wait to await a few seconds, before calling it? So I dont to a request for each letter the user types in
I think you would use the debounced hooks to resolve that https://mantine.dev/hooks/use-debounced-value/
If you get it working, would you mind posting a codesandbox of your solution? I was thinking of doing something similar
Sure will update the thread here if i get it working
import { MantineProvider } from "@mantine/core";
import { NotificationsProvider } from "@mantine/notifications";
import { SpotlightProvider } from "@mantine/spotlight";
import { createBrowserSupabaseClient } from "@supabase/auth-helpers-nextjs";
import { SessionContextProvider } from "@supabase/auth-helpers-react";
import { IconSearch } from "@tabler/icons";
import { AppProps } from "next/app";
import Head from "next/head";
import { useEffect, useState } from "react";
import { useDebouncedValue } from "@mantine/hooks";
import { useSpotlight } from "@mantine/spotlight";
import type { NextPage } from "next";
import type { ReactElement, ReactNode } from "react";
export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
getLayout?: (page: ReactElement) => ReactNode;
};
type AppPropsWithLayout = AppProps & {
Component: NextPageWithLayout;
};
export default function App({ Component, pageProps }: AppPropsWithLayout) {
const [supabase] = useState(() => createBrowserSupabaseClient());
const [searchValue, setSearchValue] = useState("");
const [debounced] = useDebouncedValue(searchValue, 1000);
const getLayout = Component.getLayout ?? ((page) => page);
const spotlight = useSpotlight();
useEffect(() => {
spotlight.registerActions([
{
id: "secret-action-1",
title: "Secret action",
description: "It was registered with a button click",
onTrigger: () => console.log("Secret"),
},
]);
console.log(`Searching for: ${debounced}`);
}, [debounced, spotlight]);
return getLayout(
<>
<Head>
<title>Page title</title>
<meta
name="viewport"
content="minimum-scale=1, initial-scale=1, width=device-width"
/>
</Head>
<MantineProvider
withGlobalStyles
withNormalizeCSS
theme={{
/** Put your mantine theme override here */
colorScheme: "light",
}}
>
<SpotlightProvider
actions={[]}
shortcut="mod + k"
searchIcon={<IconSearch size={18} />}
searchPlaceholder="Search anything"
nothingFoundMessage="No result found"
onQueryChange={(value) => setSearchValue(value)}
>
<NotificationsProvider position="top-right" zIndex={2077}>
<SessionContextProvider
supabaseClient={supabase}
initialSession={pageProps.initialSession}
>
<Component {...pageProps} />
</SessionContextProvider>
</NotificationsProvider>
</SpotlightProvider>
</MantineProvider>
</>
);
}
This is the current stand which results into Error: [@mantine/spotlight] SpotlightProvider was not found in tree
any Ideas on how to fix that? since i guess I want to register actions in the useffect method
this is all in the /pages/_app.tsx within nextjs13
I guess its tricky because its handled within _app.tsx
not sure if thats the right way to go
import { MantineProvider } from "@mantine/core";
import { NotificationsProvider } from "@mantine/notifications";
import { SpotlightProvider } from "@mantine/spotlight";
import { createBrowserSupabaseClient } from "@supabase/auth-helpers-nextjs";
import { SessionContextProvider } from "@supabase/auth-helpers-react";
import { IconSearch } from "@tabler/icons";
import { AppProps } from "next/app";
import Head from "next/head";
import { useEffect, useState } from "react";
import { useDebouncedValue } from "@mantine/hooks";
import { useSpotlight, registerSpotlightActions } from "@mantine/spotlight";
import type { NextPage } from "next";
import type { ReactElement, ReactNode } from "react";
export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
getLayout?: (page: ReactElement) => ReactNode;
};
type AppPropsWithLayout = AppProps & {
Component: NextPageWithLayout;
};
export default function App({ Component, pageProps }: AppPropsWithLayout) {
const [supabase] = useState(() => createBrowserSupabaseClient());
const [searchValue, setSearchValue] = useState("");
const [debounced] = useDebouncedValue(searchValue, 1000);
const getLayout = Component.getLayout ?? ((page) => page);
useEffect(() => {
registerSpotlightActions([
{
id: "secret-action-1",
title: "Secret action",
description: "It was registered with a button click",
onTrigger: () => console.log("Secret"),
},
]);
console.log(`Searching for: ${debounced}`);
}, [debounced]);
return getLayout(
<>
<Head>
<title>Page title</title>
<meta
name="viewport"
content="minimum-scale=1, initial-scale=1, width=device-width"
/>
</Head>
<MantineProvider
withGlobalStyles
withNormalizeCSS
theme={{
/** Put your mantine theme override here */
colorScheme: "light",
}}
>
<SpotlightProvider
actions={[]}
shortcut="mod + k"
searchIcon={<IconSearch size={18} />}
searchPlaceholder="Search anything"
nothingFoundMessage="No result found"
onQueryChange={(value) => setSearchValue(value)}
>
<NotificationsProvider position="top-right" zIndex={2077}>
<SessionContextProvider
supabaseClient={supabase}
initialSession={pageProps.initialSession}
>
<Component {...pageProps} />
</SessionContextProvider>
</NotificationsProvider>
</SpotlightProvider>
</MantineProvider>
</>
);
}