Add settings dropdown

This commit is contained in:
bkellam 2024-08-27 21:00:59 -07:00
parent 30ac9165e1
commit a83eef57e2
6 changed files with 128 additions and 46 deletions

View file

@ -19,6 +19,7 @@
"@radix-ui/react-separator": "^1.1.0", "@radix-ui/react-separator": "^1.1.0",
"@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-slot": "^1.1.0",
"@replit/codemirror-vim": "^6.2.1", "@replit/codemirror-vim": "^6.2.1",
"@uidotdev/usehooks": "^2.4.1",
"@uiw/react-codemirror": "^4.23.0", "@uiw/react-codemirror": "^4.23.0",
"class-variance-authority": "^0.7.0", "class-variance-authority": "^0.7.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",

View file

@ -7,7 +7,7 @@ import {
} from "@/components/ui/resizable"; } from "@/components/ui/resizable";
import { Separator } from "@/components/ui/separator"; import { Separator } from "@/components/ui/separator";
import { useNonEmptyQueryParam } from "@/hooks/useNonEmptyQueryParam"; import { useNonEmptyQueryParam } from "@/hooks/useNonEmptyQueryParam";
import { GetSourceResponse, pathQueryParamName, repoQueryParamName, ZoektFileMatch } from "@/lib/types"; import { GetSourceResponse, KeymapType, pathQueryParamName, repoQueryParamName, ZoektFileMatch } from "@/lib/types";
import { createPathWithQueryParams } from "@/lib/utils"; import { createPathWithQueryParams } from "@/lib/utils";
import { SymbolIcon } from "@radix-ui/react-icons"; import { SymbolIcon } from "@radix-ui/react-icons";
import Image from "next/image"; import Image from "next/image";
@ -18,7 +18,8 @@ import logoLight from "../../public/sb_logo_light.png";
import { CodePreview } from "./codePreview"; import { CodePreview } from "./codePreview";
import { SearchBar } from "./searchBar"; import { SearchBar } from "./searchBar";
import { SearchResults } from "./searchResults"; import { SearchResults } from "./searchResults";
import { ThemeSelectorButton } from "./themeSelectorButton"; import { SettingsDropdown } from "./settingsDropdown";
import { useLocalStorage } from "@uidotdev/usehooks";
export default function Home() { export default function Home() {
const router = useRouter(); const router = useRouter();
@ -36,6 +37,8 @@ export default function Home() {
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [searchDurationMs, setSearchDurationMs] = useState(0); const [searchDurationMs, setSearchDurationMs] = useState(0);
const [keymapType, saveKeymapType] = useLocalStorage<KeymapType>("keymapType", "default");
// @todo: We need to be able to handle the case when the user navigates backwards / forwards. // @todo: We need to be able to handle the case when the user navigates backwards / forwards.
// Currently we do not re-query. // Currently we do not re-query.
@ -73,7 +76,10 @@ export default function Home() {
<SymbolIcon className="h-4 w-4 animate-spin" /> <SymbolIcon className="h-4 w-4 animate-spin" />
)} )}
</div> </div>
<ThemeSelectorButton /> <SettingsDropdown
keymapType={keymapType}
onKeymapTypeChange={saveKeymapType}
/>
</div> </div>
<Separator /> <Separator />
<div className="bg-accent p-2"> <div className="bg-accent p-2">
@ -115,7 +121,7 @@ export default function Home() {
code={code} code={code}
filepath={filepath} filepath={filepath}
onClose={() => setIsCodePanelOpen(false)} onClose={() => setIsCodePanelOpen(false)}
keymapType="default" keymapType={keymapType}
/> />
</ResizablePanel> </ResizablePanel>
</ResizablePanelGroup> </ResizablePanelGroup>

View file

@ -0,0 +1,109 @@
import {
CodeIcon,
Laptop,
Moon,
Settings,
Sun
} from "lucide-react"
import { Button } from "@/components/ui/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuLabel,
DropdownMenuPortal,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuSeparator,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { useTheme } from "next-themes"
import { useMemo } from "react"
import { KeymapType } from "@/lib/types"
interface SettingsDropdownProps {
keymapType: KeymapType;
onKeymapTypeChange: (keymapType: KeymapType) => void;
}
export const SettingsDropdown = ({
keymapType,
onKeymapTypeChange,
}: SettingsDropdownProps) => {
const { theme: _theme, setTheme } = useTheme();
const theme = useMemo(() => {
return _theme ?? "light";
}, [_theme]);
const ThemeIcon = useMemo(() => {
switch (theme) {
case "light":
return <Sun className="h-4 w-4 mr-2" />;
case "dark":
return <Moon className="h-4 w-4 mr-2" />;
case "system":
return <Laptop className="h-4 w-4 mr-2" />;
default:
return <Laptop className="h-4 w-4 mr-2" />;
}
}, [theme]);
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="icon">
<Settings className="h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56">
<DropdownMenuLabel>Settings</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuSub>
<DropdownMenuSubTrigger>
{ThemeIcon}
<span>Theme</span>
</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuRadioGroup value={theme} onValueChange={setTheme}>
<DropdownMenuRadioItem value="light">
Light
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="dark">
Dark
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="system">
System
</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
<DropdownMenuSub>
<DropdownMenuSubTrigger>
<CodeIcon className="h-4 w-4 mr-2" />
<span>Code navigation</span>
</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuRadioGroup value={keymapType} onValueChange={(value) => onKeymapTypeChange(value as KeymapType)}>
<DropdownMenuRadioItem value="default">
Default
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="vim">
Vim
</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
)
}

View file

@ -1,41 +0,0 @@
"use client"
import * as React from "react"
import { Moon, Sun } from "lucide-react"
import { useTheme } from "next-themes"
import { Button } from "@/components/ui/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
export const ThemeSelectorButton = () => {
const { setTheme } = useTheme()
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="icon">
<Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only">Toggle theme</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => setTheme("light")}>
Light
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("dark")}>
Dark
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("system")}>
System
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
)
}

View file

@ -38,3 +38,5 @@ export interface ZoektResult {
export interface ZoektSearchResponse { export interface ZoektSearchResponse {
result: ZoektResult, result: ZoektResult,
} }
export type KeymapType = "default" | "vim";

View file

@ -677,6 +677,11 @@
"@typescript-eslint/types" "7.2.0" "@typescript-eslint/types" "7.2.0"
eslint-visitor-keys "^3.4.1" eslint-visitor-keys "^3.4.1"
"@uidotdev/usehooks@^2.4.1":
version "2.4.1"
resolved "https://registry.yarnpkg.com/@uidotdev/usehooks/-/usehooks-2.4.1.tgz#4b733eaeae09a7be143c6c9ca158b56cc1ea75bf"
integrity sha512-1I+RwWyS+kdv3Mv0Vmc+p0dPYH0DTRAo04HLyXReYBL9AeseDWUJyi4THuksBJcu9F0Pih69Ak150VDnqbVnXg==
"@uiw/codemirror-extensions-basic-setup@4.23.0": "@uiw/codemirror-extensions-basic-setup@4.23.0":
version "4.23.0" version "4.23.0"
resolved "https://registry.yarnpkg.com/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.23.0.tgz#c3c181153335c208a25d59b8ecbc7fc87fe85356" resolved "https://registry.yarnpkg.com/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.23.0.tgz#c3c181153335c208a25d59b8ecbc7fc87fe85356"