feat: keyboard spotlight
This commit is contained in:
parent
463e91c3bd
commit
4428555762
6 changed files with 140 additions and 2 deletions
|
@ -37,6 +37,7 @@
|
||||||
"@mantine/next": "^6.0.0",
|
"@mantine/next": "^6.0.0",
|
||||||
"@mantine/notifications": "^6.0.0",
|
"@mantine/notifications": "^6.0.0",
|
||||||
"@mantine/prism": "^6.0.0",
|
"@mantine/prism": "^6.0.0",
|
||||||
|
"@mantine/spotlight": "^6.0.0",
|
||||||
"@prisma/client": "^4.10.1",
|
"@prisma/client": "^4.10.1",
|
||||||
"@prisma/internals": "^4.10.1",
|
"@prisma/internals": "^4.10.1",
|
||||||
"@prisma/migrate": "^4.10.1",
|
"@prisma/migrate": "^4.10.1",
|
||||||
|
|
|
@ -15,9 +15,14 @@ import qogir_dark from 'lib/themes/qogir_dark';
|
||||||
import { createEmotionCache, MantineProvider, MantineThemeOverride, Modal, ScrollArea } from '@mantine/core';
|
import { createEmotionCache, MantineProvider, MantineThemeOverride, Modal, ScrollArea } from '@mantine/core';
|
||||||
import { useColorScheme } from '@mantine/hooks';
|
import { useColorScheme } from '@mantine/hooks';
|
||||||
import { ModalsProvider } from '@mantine/modals';
|
import { ModalsProvider } from '@mantine/modals';
|
||||||
|
import { SpotlightProvider } from '@mantine/spotlight';
|
||||||
import { Notifications } from '@mantine/notifications';
|
import { Notifications } from '@mantine/notifications';
|
||||||
import { userSelector } from 'lib/recoil/user';
|
import { userSelector } from 'lib/recoil/user';
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
|
import { SearchIcon } from './icons';
|
||||||
|
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
|
import { createSpotlightActions } from 'lib/spotlight';
|
||||||
|
|
||||||
export const themes = {
|
export const themes = {
|
||||||
system: (colorScheme: 'dark' | 'light') => (colorScheme === 'dark' ? dark_blue : light_blue),
|
system: (colorScheme: 'dark' | 'light') => (colorScheme === 'dark' ? dark_blue : light_blue),
|
||||||
|
@ -52,6 +57,7 @@ const cache = createEmotionCache({ key: 'zipline' });
|
||||||
export default function ZiplineTheming({ Component, pageProps, ...props }) {
|
export default function ZiplineTheming({ Component, pageProps, ...props }) {
|
||||||
const user = useRecoilValue(userSelector);
|
const user = useRecoilValue(userSelector);
|
||||||
const colorScheme = useColorScheme();
|
const colorScheme = useColorScheme();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
let theme: MantineThemeOverride;
|
let theme: MantineThemeOverride;
|
||||||
|
|
||||||
|
@ -141,8 +147,14 @@ export default function ZiplineTheming({ Component, pageProps, ...props }) {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ModalsProvider>
|
<ModalsProvider>
|
||||||
<Notifications position='top-center' style={{ marginTop: -10 }} />
|
<SpotlightProvider
|
||||||
{props.children ? props.children : <Component {...pageProps} />}
|
searchIcon={<SearchIcon />}
|
||||||
|
shortcut={['mod + k', '/']}
|
||||||
|
actions={createSpotlightActions(router)}
|
||||||
|
>
|
||||||
|
<Notifications position='top-center' style={{ marginTop: -10 }} />
|
||||||
|
{props.children ? props.children : <Component {...pageProps} />}
|
||||||
|
</SpotlightProvider>
|
||||||
</ModalsProvider>
|
</ModalsProvider>
|
||||||
</MantineProvider>
|
</MantineProvider>
|
||||||
);
|
);
|
||||||
|
|
5
src/components/icons/SearchIcon.tsx
Normal file
5
src/components/icons/SearchIcon.tsx
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import { Search } from 'react-feather';
|
||||||
|
|
||||||
|
export default function SearchIcon({ ...props }) {
|
||||||
|
return <Search size={15} {...props} />;
|
||||||
|
}
|
|
@ -42,6 +42,7 @@ import GlobeIcon from './GlobeIcon';
|
||||||
import LockIcon from './LockIcon';
|
import LockIcon from './LockIcon';
|
||||||
import UnlockIcon from './UnlockIcon';
|
import UnlockIcon from './UnlockIcon';
|
||||||
import HardDriveIcon from './HardDriveIcon';
|
import HardDriveIcon from './HardDriveIcon';
|
||||||
|
import SearchIcon from './SearchIcon';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
ActivityIcon,
|
ActivityIcon,
|
||||||
|
@ -88,4 +89,5 @@ export {
|
||||||
LockIcon,
|
LockIcon,
|
||||||
UnlockIcon,
|
UnlockIcon,
|
||||||
HardDriveIcon,
|
HardDriveIcon,
|
||||||
|
SearchIcon,
|
||||||
};
|
};
|
||||||
|
|
103
src/lib/spotlight.tsx
Normal file
103
src/lib/spotlight.tsx
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
import { useClipboard } from '@mantine/hooks';
|
||||||
|
import { showNotification } from '@mantine/notifications';
|
||||||
|
import type { SpotlightAction } from '@mantine/spotlight';
|
||||||
|
import {
|
||||||
|
FileIcon,
|
||||||
|
FolderIcon,
|
||||||
|
HomeIcon,
|
||||||
|
ActivityIcon,
|
||||||
|
LinkIcon,
|
||||||
|
UserIcon,
|
||||||
|
LogoutIcon,
|
||||||
|
CopyIcon,
|
||||||
|
SearchIcon,
|
||||||
|
} from 'components/icons';
|
||||||
|
import { NextRouter } from 'next/router';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
import { userSelector } from './recoil/user';
|
||||||
|
|
||||||
|
export const createSpotlightActions = (router: NextRouter): SpotlightAction[] => {
|
||||||
|
const user = useRecoilValue(userSelector);
|
||||||
|
const clipboard = useClipboard();
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const linkTo = (url: string) => {
|
||||||
|
router.push(url);
|
||||||
|
};
|
||||||
|
|
||||||
|
const actionLink = (
|
||||||
|
group: string,
|
||||||
|
title: string,
|
||||||
|
description: string,
|
||||||
|
link: string,
|
||||||
|
icon: any
|
||||||
|
): SpotlightAction => {
|
||||||
|
return actionDo(group, title, description, icon, () => linkTo(link));
|
||||||
|
};
|
||||||
|
|
||||||
|
const actionDo = (
|
||||||
|
group: string,
|
||||||
|
title: string,
|
||||||
|
description: string,
|
||||||
|
icon: any,
|
||||||
|
action: () => void
|
||||||
|
): SpotlightAction => {
|
||||||
|
return {
|
||||||
|
group,
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
closeOnTrigger: true,
|
||||||
|
icon,
|
||||||
|
onTrigger: action,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return [
|
||||||
|
// Navigation
|
||||||
|
actionLink('Navigation', 'Home', 'Go to the home page', '/dashboard', <HomeIcon />),
|
||||||
|
actionLink('Navigation', 'Files', 'View your files', '/dashboard/files', <FileIcon />),
|
||||||
|
actionLink('Navigation', 'URLs', 'View your URLs', '/dashboard/urls', <LinkIcon />),
|
||||||
|
actionLink('Navigation', 'Folders', 'View your folders', '/dashboard/folders', <FolderIcon />),
|
||||||
|
actionLink('Navigation', 'Statistics', 'View your statistics', '/dashboard/stats', <ActivityIcon />),
|
||||||
|
actionLink(
|
||||||
|
'Navigation',
|
||||||
|
'Manage Account',
|
||||||
|
'Manage your account settings',
|
||||||
|
'/dashboard/manage',
|
||||||
|
<UserIcon />
|
||||||
|
),
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
actionLink('Actions', 'Logout', 'Logout of your account', '/auth/logout', <LogoutIcon />),
|
||||||
|
actionLink('Actions', 'Upload Files', 'Upload files of any kind', '/dashboard/upload/file', <FileIcon />),
|
||||||
|
actionLink(
|
||||||
|
'Actions',
|
||||||
|
'Upload Text',
|
||||||
|
'Upload code, or any other kind of text file',
|
||||||
|
'/dashboard/upload/text',
|
||||||
|
<FileIcon />
|
||||||
|
),
|
||||||
|
actionDo('Actions', 'Copy Token', 'Copy your API token to your clipboard', <CopyIcon />, () => {
|
||||||
|
clipboard.copy(user.token);
|
||||||
|
showNotification({
|
||||||
|
title: 'Copied to clipboard',
|
||||||
|
message: '',
|
||||||
|
color: 'green',
|
||||||
|
icon: <CopyIcon />,
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
|
||||||
|
actionLink(
|
||||||
|
'Help',
|
||||||
|
'Documentation',
|
||||||
|
'View the documentation',
|
||||||
|
'https://zipline.diced.tech',
|
||||||
|
<SearchIcon />
|
||||||
|
),
|
||||||
|
|
||||||
|
// the list of actions here is very incomplete, and will be expanded in the future
|
||||||
|
];
|
||||||
|
};
|
15
yarn.lock
15
yarn.lock
|
@ -1681,6 +1681,20 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@mantine/spotlight@npm:^6.0.0":
|
||||||
|
version: 6.0.0
|
||||||
|
resolution: "@mantine/spotlight@npm:6.0.0"
|
||||||
|
dependencies:
|
||||||
|
"@mantine/utils": 6.0.0
|
||||||
|
peerDependencies:
|
||||||
|
"@mantine/core": 6.0.0
|
||||||
|
"@mantine/hooks": 6.0.0
|
||||||
|
react: ">=16.8.0"
|
||||||
|
react-dom: ">=16.8.0"
|
||||||
|
checksum: d8312be7b422ed70074b39e7fb269827ea864c3eee0eb15c359c469684ea01904c3775b7bd23a2a6c99203c515c22f118e371c7d008a425dbe22d2746b136611
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@mantine/ssr@npm:6.0.0":
|
"@mantine/ssr@npm:6.0.0":
|
||||||
version: 6.0.0
|
version: 6.0.0
|
||||||
resolution: "@mantine/ssr@npm:6.0.0"
|
resolution: "@mantine/ssr@npm:6.0.0"
|
||||||
|
@ -11676,6 +11690,7 @@ __metadata:
|
||||||
"@mantine/next": ^6.0.0
|
"@mantine/next": ^6.0.0
|
||||||
"@mantine/notifications": ^6.0.0
|
"@mantine/notifications": ^6.0.0
|
||||||
"@mantine/prism": ^6.0.0
|
"@mantine/prism": ^6.0.0
|
||||||
|
"@mantine/spotlight": ^6.0.0
|
||||||
"@prisma/client": ^4.10.1
|
"@prisma/client": ^4.10.1
|
||||||
"@prisma/internals": ^4.10.1
|
"@prisma/internals": ^4.10.1
|
||||||
"@prisma/migrate": ^4.10.1
|
"@prisma/migrate": ^4.10.1
|
||||||
|
|
Loading…
Reference in a new issue