feat(spotlight): implement tab navigation via spotlight search

This commit is contained in:
2026-07-13 11:37:18 +03:30
parent 4f29fec854
commit 1247edb523
3 changed files with 106 additions and 29 deletions
+3 -1
View File
@@ -10,7 +10,9 @@
"preview": "vite preview"
},
"dependencies": {
"@mantine/core": "^9.3.1",
"@mantine/core": "^9.4.1",
"@mantine/hooks": "9.4.1",
"@mantine/spotlight": "9.4.1",
"react": "^19.2.6",
"react-dom": "^19.2.6",
"react-hotkeys-hook": "^5.3.2"
+41 -10
View File
@@ -9,8 +9,14 @@ importers:
.:
dependencies:
'@mantine/core':
specifier: ^9.3.1
version: 9.3.1(@mantine/hooks@9.3.1(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
specifier: ^9.4.1
version: 9.4.1(@mantine/hooks@9.4.1(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
'@mantine/hooks':
specifier: 9.4.1
version: 9.4.1(react@19.2.7)
'@mantine/spotlight':
specifier: 9.4.1
version: 9.4.1(@mantine/core@9.4.1(@mantine/hooks@9.4.1(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.4.1(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
react:
specifier: ^19.2.6
version: 19.2.7
@@ -232,15 +238,28 @@ packages:
'@jridgewell/trace-mapping@0.3.31':
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
'@mantine/core@9.3.1':
resolution: {integrity: sha512-4rBoHpggSohayE+Os7lKdbsHTw7m/uZRKYjk9DN6cKBhQIjdiULdcG+b4b5CMVZSqZDHPgT70uWGI7yqkn8Ufw==}
'@mantine/core@9.4.1':
resolution: {integrity: sha512-lZWEICrum4+vwKxzh/mk4RB1N6BqZ0Cshdl6lhm7OYLiQzmOaxKtOgyaWz+vr65G8mqTXjalZalB+wmMVBYK2Q==}
peerDependencies:
'@mantine/hooks': 9.3.1
'@mantine/hooks': 9.4.1
react: ^19.2.0
react-dom: ^19.2.0
'@mantine/hooks@9.3.1':
resolution: {integrity: sha512-zAOlxV59j5CDgAnExN+ypaR6dVW1vwMKDvKUxIlUVd/e52qxYnPyYRD+shJmyOLaZRuQmVF0R/7mJAjt2jw9cA==}
'@mantine/hooks@9.4.1':
resolution: {integrity: sha512-eTI8wmzPx3r98zgKIEuvukmoGTHBhmtI6+9E6o2DbTmEU2eM1bCdjE2vFdf0op2AlRO0KEYEcZhNQi4T/SJk0A==}
peerDependencies:
react: ^19.2.0
'@mantine/spotlight@9.4.1':
resolution: {integrity: sha512-gJ+7DdnGULeobtGXVGbVgvJSG3TeecxLXNxzpZo+ohl1OetPftCBGJOUrX2tYOOC6nJE1eHSIr/kpB31YIRjhQ==}
peerDependencies:
'@mantine/core': 9.4.1
'@mantine/hooks': 9.4.1
react: ^19.2.0
react-dom: ^19.2.0
'@mantine/store@9.4.1':
resolution: {integrity: sha512-/DCZq0aqqIdm03J0RJ7pbzoau2cwY8ndSOjskHOKHhTeWMnOBdCKXA3oMO5aIDldDqJ9T7Io4Boh4Pt461zNQw==}
peerDependencies:
react: ^19.2.0
@@ -1260,10 +1279,10 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.5
'@mantine/core@9.3.1(@mantine/hooks@9.3.1(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)':
'@mantine/core@9.4.1(@mantine/hooks@9.4.1(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)':
dependencies:
'@floating-ui/react': 0.27.19(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
'@mantine/hooks': 9.3.1(react@19.2.7)
'@mantine/hooks': 9.4.1(react@19.2.7)
clsx: 2.1.1
react: 19.2.7
react-dom: 19.2.7(react@19.2.7)
@@ -1273,7 +1292,19 @@ snapshots:
transitivePeerDependencies:
- '@types/react'
'@mantine/hooks@9.3.1(react@19.2.7)':
'@mantine/hooks@9.4.1(react@19.2.7)':
dependencies:
react: 19.2.7
'@mantine/spotlight@9.4.1(@mantine/core@9.4.1(@mantine/hooks@9.4.1(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.4.1(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)':
dependencies:
'@mantine/core': 9.4.1(@mantine/hooks@9.4.1(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
'@mantine/hooks': 9.4.1(react@19.2.7)
'@mantine/store': 9.4.1(react@19.2.7)
react: 19.2.7
react-dom: 19.2.7(react@19.2.7)
'@mantine/store@9.4.1(react@19.2.7)':
dependencies:
react: 19.2.7
+62 -18
View File
@@ -1,12 +1,14 @@
import { useState, useEffect } from "react";
import { MantineProvider, Tabs } from "@mantine/core";
import { MantineProvider, Tabs, Button } from "@mantine/core";
import {
HotkeysProvider,
useHotkeys,
useHotkeysContext,
} from "react-hotkeys-hook";
import "@mantine/core/styles.css";
import { Spotlight, spotlight } from "@mantine/spotlight";
import type { SpotlightActionData } from "@mantine/spotlight";
import "@mantine/spotlight/styles.css";
function TabContent({ title, scopeName }: any) {
const [text, setText] = useState(`${title} panel `);
const [used, setUsed] = useState(false);
@@ -30,6 +32,32 @@ function TabContent({ title, scopeName }: any) {
function TabsPage() {
const { enableScope, disableScope } = useHotkeysContext();
const [activeTab, setActiveTab] = useState("1");
const actions: SpotlightActionData[] = [
{
id: "first",
label: "First",
description: "First panel",
onClick: () => {
setActiveTab("1");
},
},
{
id: "second",
label: "Second",
description: "Second panel",
onClick: () => {
setActiveTab("2");
},
},
{
id: "third",
label: "Third",
description: "Third panel",
onClick: () => {
setActiveTab("3");
},
},
];
useEffect(() => {
const currentScope = `tab${activeTab}`;
@@ -45,25 +73,41 @@ function TabsPage() {
useHotkeys("ctrl+3", () => setActiveTab("3"), { preventDefault: true });
return (
<Tabs value={activeTab} onChange={(value) => value && setActiveTab(value)}>
<Tabs.List>
<Tabs.Tab value="1">First</Tabs.Tab>
<Tabs.Tab value="2">Second</Tabs.Tab>
<Tabs.Tab value="3">Third</Tabs.Tab>
</Tabs.List>
<>
<Button onClick={spotlight.open} variant="default">
Open spotlight
</Button>
<Spotlight
actions={actions}
nothingFound="Nothing found..."
highlightQuery
searchProps={{
placeholder: "Search...",
}}
/>
<Tabs
value={activeTab}
onChange={(value) => value && setActiveTab(value)}
>
<Tabs.List>
<Tabs.Tab value="1">First</Tabs.Tab>
<Tabs.Tab value="2">Second</Tabs.Tab>
<Tabs.Tab value="3">Third</Tabs.Tab>
</Tabs.List>
<Tabs.Panel value="1">
<TabContent title="First" scopeName="tab1" />
</Tabs.Panel>
<Tabs.Panel value="1">
<TabContent title="First" scopeName="tab1" />
</Tabs.Panel>
<Tabs.Panel value="2">
<TabContent title="Second" scopeName="tab2" />
</Tabs.Panel>
<Tabs.Panel value="2">
<TabContent title="Second" scopeName="tab2" />
</Tabs.Panel>
<Tabs.Panel value="3">
<TabContent title="Third" scopeName="tab3" />
</Tabs.Panel>
</Tabs>
<Tabs.Panel value="3">
<TabContent title="Third" scopeName="tab3" />
</Tabs.Panel>
</Tabs>
</>
);
}