Skip to content

Commit

Permalink
refactor(Search): simplify components and implement language switching
Browse files Browse the repository at this point in the history
  • Loading branch information
TinsFox committed Nov 2, 2024
1 parent da08e8c commit 81c33c7
Showing 1 changed file with 56 additions and 38 deletions.
94 changes: 56 additions & 38 deletions src/components/layout/search.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import type { DialogProps } from "@radix-ui/react-dialog"
import { LaptopIcon, MoonIcon, SunIcon } from "@radix-ui/react-icons"
import { SearchIcon } from "lucide-react"
import * as React from "react"
import { useTranslation } from "react-i18next"
import { useNavigate } from "react-router-dom"

import type { ButtonProps } from "@/components/ui/button"
import { Button } from "@/components/ui/button"
import { languages } from "@/i18n"
import { cn } from "@/lib/utils"
import type { MenuItem } from "@/models/menu"

import { Icons } from "../icons"
import { useTheme } from "../theme/theme-provider"
import {
CommandDialog,
Expand All @@ -18,14 +21,18 @@ import {
CommandList,
CommandSeparator,
} from "../ui/command"
import { Separator } from "../ui/separator"
import { menus } from "./sidebar/data"

export function Search({ ...props }: ButtonProps & DialogProps) {
const navigate = useNavigate()
const [open, setOpen] = React.useState(false)
const { setTheme } = useTheme()

const { i18n, t } = useTranslation("common")

const changeLanguage = (lng: string) => {
i18n.changeLanguage(lng)
}

React.useEffect(() => {
const down = (e: KeyboardEvent) => {
if ((e.key === "k" && (e.metaKey || e.ctrlKey)) || e.key === "/") {
Expand Down Expand Up @@ -57,13 +64,17 @@ export function Search({ ...props }: ButtonProps & DialogProps) {
<Button
variant="outline"
className={cn(
"relative h-8 w-full justify-start rounded-[0.5rem] bg-muted/50 text-sm font-normal text-muted-foreground shadow-none sm:pr-12 md:w-40 lg:w-64",
"relative h-8 w-full justify-start rounded-[0.5rem] bg-muted/50 text-sm font-normal text-muted-foreground shadow-none sm:w-64 md:w-80 lg:w-96",
"transition-all duration-200",
"hover:bg-muted/80",
)}
onClick={() => setOpen(true)}
{...props}
>
<span className="hidden lg:inline-flex">Search documentation...</span>
<span className="inline-flex lg:hidden">Search...</span>
<span className="inline-flex items-center gap-2 capitalize">
<SearchIcon className="size-4" />
<span className="sm:inline-flex">{t("search")}...</span>
</span>
<kbd className="pointer-events-none absolute right-[0.3rem] top-[0.3rem] hidden h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium opacity-100 sm:flex">
<span className="text-xs"></span>K
</kbd>
Expand All @@ -73,51 +84,58 @@ export function Search({ ...props }: ButtonProps & DialogProps) {
<CommandList>
<CommandEmpty>No results found.</CommandEmpty>
<CommandGroup heading="Links">
{menus.map((navItem, index) => {
if ("type" in navItem && navItem.type === "separator") {
// eslint-disable-next-line @eslint-react/no-array-index-key
return <Separator key={`separator-${index}`} />
}
const menuItem = navItem as MenuItem
return (
<CommandItem
key={`${menuItem.title}-${menuItem.to}`}
value={menuItem.title}
onSelect={() => {
runCommand(() => navigate(menuItem.to!))
}}
>
<menuItem.icon className="mr-2 size-4" />
{menuItem.title}
{menuItem.label && (
<span
className={cn(
"ml-auto",
"data-[active=true]:text-white data-[active=true]:dark:text-white",
)}
>
{menuItem.label}
</span>
)}
</CommandItem>
)
})}
<CommandItem
value={pkg.repository.url}
onSelect={() => {
runCommand(() =>
navigate(pkg.repository.url),
)
}}
>
<Icons.gitHub className="mr-2 size-4" />
GitHub
</CommandItem>
<CommandItem
value="https://shadcnui-boilerplate.pages.dev/"
onSelect={() => {
runCommand(() =>
navigate("https://shadcnui-boilerplate.pages.dev/"),
)
}}
>
<Icons.document />
Document
</CommandItem>
</CommandGroup>
<CommandSeparator />
<CommandGroup heading="Theme">
<CommandItem onSelect={() => runCommand(() => setTheme("light"))}>
<SunIcon className="mr-2 size-4" />
Light
{t("themes.light")}
</CommandItem>
<CommandItem onSelect={() => runCommand(() => setTheme("dark"))}>
<MoonIcon className="mr-2 size-4" />
Dark
{t("themes.dark")}
</CommandItem>
<CommandItem onSelect={() => runCommand(() => setTheme("system"))}>
<LaptopIcon className="mr-2 size-4" />
System
{t("themes.system")}
</CommandItem>
</CommandGroup>
<CommandGroup heading="Language">
{languages.map((language) => (
<CommandItem
key={language.value}
value={language.value}
onSelect={() => runCommand(() => changeLanguage(language.value))}
>
{language.icon}
{" "}
{language.label}
</CommandItem>
))}

</CommandGroup>
</CommandList>
</CommandDialog>
</>
Expand Down

0 comments on commit 81c33c7

Please sign in to comment.