diff --git a/src/App.tsx b/src/App.tsx
index 2087680..ff85361 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -2,7 +2,12 @@ import { MantineProvider } from "@mantine/core";
import "@mantine/core/styles.css";
import "@mantine/spotlight/styles.css";
+import { SpotlightTestDemo } from "./SpotlightTestDemo";
export default function App() {
- return ;
+ return (
+
+
+
+ );
}
diff --git a/src/SpotlightTestDemo.tsx b/src/SpotlightTestDemo.tsx
new file mode 100644
index 0000000..64598f0
--- /dev/null
+++ b/src/SpotlightTestDemo.tsx
@@ -0,0 +1,132 @@
+import { useEffect, useMemo, useState } from "react";
+import { Button } from "@mantine/core";
+import { Spotlight, spotlight } from "@mantine/spotlight";
+import type {
+ SpotlightActionData,
+ SpotlightActionGroupData,
+ SpotlightFilterFunction,
+} from "@mantine/spotlight";
+import Fuse from "fuse.js";
+
+interface Product {
+ id: number;
+ title: string;
+ description: string;
+ price: number;
+ category: string;
+ brand: string;
+}
+
+function generate5kMockProducts(): Product[] {
+ const categories = [
+ "Electronics",
+ "Fashion",
+ "Home & Living",
+ "Beauty & Care",
+ "Sports & Outdoors",
+ "Automotive",
+ ];
+ const brands = ["Sony", "Samsung", "Apple", "Nike", "Adidas", "IKEA"];
+
+ return Array.from({ length: 5000 }, (_, index) => {
+ const id = index + 1;
+ const category = categories[index % categories.length];
+ const brand = brands[index % brands.length];
+
+ return {
+ id,
+ title: `${brand} High-End Item #${id}`,
+ description: `Premium ${category.toLowerCase()} product manufactured by ${brand}. High availability in stock.`,
+ price: Math.floor(Math.random() * 900) + 10,
+ category,
+ brand,
+ };
+ });
+}
+
+function groupActionsByCategory(
+ actions: SpotlightActionData[],
+): SpotlightActionGroupData[] {
+ const groupsMap = actions.reduce>(
+ (acc, action) => {
+ const groupName = (action as any)._category || "OTHER";
+ if (!acc[groupName]) {
+ acc[groupName] = [];
+ }
+ acc[groupName].push(action);
+ return acc;
+ },
+ {},
+ );
+
+ return Object.entries(groupsMap).map(([group, groupActions]) => ({
+ group: group.toUpperCase(),
+ actions: groupActions,
+ }));
+}
+
+export function SpotlightTestDemo() {
+ const [query, setQuery] = useState("");
+ const [flatActions, setFlatActions] = useState([]);
+
+ useEffect(() => {
+ setTimeout(() => {
+ const products = generate5kMockProducts();
+
+ const actions: SpotlightActionData[] = products.map((product) => ({
+ id: `prod-${product.id}`,
+ label: product.title,
+ description: `${product.brand} | $${product.price} - ${product.description}`,
+ _category: product.category,
+ }));
+
+ setFlatActions(actions);
+ }, 50);
+ }, []);
+
+ const fuseIndex = useMemo(() => {
+ if (flatActions.length === 0) return null;
+
+ return new Fuse(flatActions, {
+ keys: ["label", "description", "_category"],
+ threshold: 0.5,
+ distance: 100,
+ minMatchCharLength: 1,
+ ignoreLocation: true,
+ useExtendedSearch: false,
+ });
+ }, [flatActions]);
+
+ const customFuzzyFilter: SpotlightFilterFunction = (searchQuery) => {
+ const trimmed = searchQuery.trim();
+
+ if (!trimmed) {
+ return groupActionsByCategory(flatActions.slice(0, 20));
+ }
+
+ if (!fuseIndex) return [];
+
+ const results = fuseIndex.search(trimmed);
+ const matchedItems = results.slice(0, 50).map((r) => r.item);
+
+ return groupActionsByCategory(matchedItems);
+ };
+
+ return (
+ <>
+
+
+ >
+ );
+}