diff --git a/.prettierrc.mjs b/.prettierrc.mjs index ae53b38b..5532f83e 100644 --- a/.prettierrc.mjs +++ b/.prettierrc.mjs @@ -1,4 +1,4 @@ -import prettierConfig from "./prettierrc.precommit.mjs"; +import prettierConfig from "./.prettierrc.precommit.mjs"; export default { ...prettierConfig, diff --git a/apps/docs/package.json b/apps/docs/package.json index e2d49b07..dad6448f 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -25,6 +25,7 @@ "@iconify-json/mdi": "^1.1.64", "@iconify-json/ri": "^1.1.20", "@radix-ui/react-accordion": "^1.1.2", + "@radix-ui/react-alert-dialog": "^1.0.5", "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-navigation-menu": "^1.1.4", @@ -39,6 +40,7 @@ "balance-text": "^3.3.1", "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", + "cmdk": "^1.0.0", "date-fns": "^3.5.0", "framer-motion": "^11.0.14", "lucide-react": "^0.358.0", diff --git a/apps/docs/src/components/CommandMenu.tsx b/apps/docs/src/components/CommandMenu.tsx new file mode 100644 index 00000000..44e37194 --- /dev/null +++ b/apps/docs/src/components/CommandMenu.tsx @@ -0,0 +1,75 @@ +import type { DialogProps } from "@radix-ui/react-alert-dialog"; +import * as React from "react"; + +import { Button } from "@/components/ui/Button"; +import { + CommandDialog, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, +} from "@/components/ui/Command"; +import { cn } from "@/lib/utils"; + +type CommandMenuProps = DialogProps & { className?: string }; + +export const CommandMenu = ({ ...props }: CommandMenuProps) => { + const [isOpen, setIsOpen] = React.useState(false); + + React.useEffect(() => { + const down = (e: KeyboardEvent) => { + if ((e.key === "k" && (e.metaKey || e.ctrlKey)) || e.key === "/") { + if ( + (e.target instanceof HTMLElement && e.target.isContentEditable) || + e.target instanceof HTMLInputElement || + e.target instanceof HTMLTextAreaElement || + e.target instanceof HTMLSelectElement + ) { + return; + } + + e.preventDefault(); + setIsOpen((prevIsValue) => !prevIsValue); + } + }; + + document.addEventListener("keydown", down); + return () => document.removeEventListener("keydown", down); + }, []); + + // const runCommand = React.useCallback((command: () => unknown) => { + // setOpen(false); + // command(); + // }, []); + + return ( + <> + + + + + No results found. + + Calendar + Search Emoji + Calculator + + + + + ); +}; diff --git a/apps/docs/src/components/TableOfContents.tsx b/apps/docs/src/components/TableOfContents.tsx index 5794f190..d6ce3e9c 100644 --- a/apps/docs/src/components/TableOfContents.tsx +++ b/apps/docs/src/components/TableOfContents.tsx @@ -19,7 +19,6 @@ export const DashboardTableOfContents = ({ toc }: TocProps) => { if (!toc?.items) { return null; } - console.log("delete"); return (

On This Page

diff --git a/apps/docs/src/components/layout/Header.astro b/apps/docs/src/components/layout/Header.astro index c329e931..1943b4c7 100644 --- a/apps/docs/src/components/layout/Header.astro +++ b/apps/docs/src/components/layout/Header.astro @@ -32,15 +32,6 @@ const { className } = Astro.props;
- -
- - - -
- diff --git a/apps/docs/src/components/layout/SheetMobileNav.tsx b/apps/docs/src/components/layout/SheetMobileNav.tsx index 07140007..194297c4 100644 --- a/apps/docs/src/components/layout/SheetMobileNav.tsx +++ b/apps/docs/src/components/layout/SheetMobileNav.tsx @@ -3,9 +3,9 @@ import * as React from "react"; import { Button } from "@/components/ui/Button"; import { ScrollArea } from "@/components/ui/ScrollArea"; import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/Sheet"; -import { siteConfig } from "@/config/site"; import { Icons } from "@/icons"; import type { MainNavItem, SidebarNavItem } from "@/types"; +import { ThemeToggle } from "../ThemeToggle"; interface SheetMobileProps { mainNavItems?: MainNavItem[]; @@ -37,10 +37,6 @@ export const SheetMobileNav = ({ - - - {siteConfig.name} -
{mainNavItems?.length ? ( @@ -100,6 +96,7 @@ export const SheetMobileNav = ({ ) : null}
+
); diff --git a/apps/docs/src/components/ui/Command.tsx b/apps/docs/src/components/ui/Command.tsx new file mode 100644 index 00000000..68489d15 --- /dev/null +++ b/apps/docs/src/components/ui/Command.tsx @@ -0,0 +1,154 @@ +import { type DialogProps } from "@radix-ui/react-dialog"; +import { Command as CommandPrimitive } from "cmdk"; +import { Search } from "lucide-react"; +import * as React from "react"; + +import { Dialog, DialogContent } from "@/components/ui/Dialog"; +import { cn } from "@/lib/utils"; + +const Command = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +Command.displayName = CommandPrimitive.displayName; + +interface CommandDialogProps extends DialogProps {} + +const CommandDialog = ({ children, ...props }: CommandDialogProps) => { + return ( + + + + {children} + + + + ); +}; + +const CommandInput = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + // eslint-disable-next-line react/no-unknown-property +
+ + +
+)); + +CommandInput.displayName = CommandPrimitive.Input.displayName; + +const CommandList = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); + +CommandList.displayName = CommandPrimitive.List.displayName; + +const CommandEmpty = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>((props, ref) => ( + +)); + +CommandEmpty.displayName = CommandPrimitive.Empty.displayName; + +const CommandGroup = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); + +CommandGroup.displayName = CommandPrimitive.Group.displayName; + +const CommandSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +CommandSeparator.displayName = CommandPrimitive.Separator.displayName; + +const CommandItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); + +CommandItem.displayName = CommandPrimitive.Item.displayName; + +const CommandShortcut = ({ + className, + ...props +}: React.HTMLAttributes) => { + return ( + + ); +}; +CommandShortcut.displayName = "CommandShortcut"; + +export { + Command, + CommandDialog, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, + CommandSeparator, + CommandShortcut, +}; diff --git a/apps/docs/src/components/ui/Dialog.tsx b/apps/docs/src/components/ui/Dialog.tsx new file mode 100644 index 00000000..fe2fc03d --- /dev/null +++ b/apps/docs/src/components/ui/Dialog.tsx @@ -0,0 +1,120 @@ +import * as DialogPrimitive from "@radix-ui/react-dialog"; +import { X } from "lucide-react"; +import * as React from "react"; + +import { cn } from "@/lib/utils"; + +const Dialog = DialogPrimitive.Root; + +const DialogTrigger = DialogPrimitive.Trigger; + +const DialogPortal = DialogPrimitive.Portal; + +const DialogClose = DialogPrimitive.Close; + +const DialogOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DialogOverlay.displayName = DialogPrimitive.Overlay.displayName; + +const DialogContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + {children} + + + Close + + + +)); +DialogContent.displayName = DialogPrimitive.Content.displayName; + +const DialogHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+); +DialogHeader.displayName = "DialogHeader"; + +const DialogFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+); +DialogFooter.displayName = "DialogFooter"; + +const DialogTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DialogTitle.displayName = DialogPrimitive.Title.displayName; + +const DialogDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DialogDescription.displayName = DialogPrimitive.Description.displayName; + +export { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogOverlay, + DialogPortal, + DialogTitle, + DialogTrigger, +}; diff --git a/apps/docs/src/layouts/MainLayout.astro b/apps/docs/src/layouts/MainLayout.astro index 16dca611..c33c952e 100644 --- a/apps/docs/src/layouts/MainLayout.astro +++ b/apps/docs/src/layouts/MainLayout.astro @@ -4,6 +4,7 @@ import Header from "@/components/layout/Header.astro"; import { cn } from "@/lib/utils"; import BaseLayout from "./BaseLayout.astro"; import { SheetMobileNav } from "@/components/layout/SheetMobileNav"; +import { CommandMenu } from "@/components/CommandMenu"; import { ThemeToggle } from "@/components/ThemeToggle"; import { siteConfig } from "@/config/site"; import { Icon } from "astro-icon/components"; @@ -27,7 +28,11 @@ const { title, description, mainClass } = Astro.props; slot="mobile-nav-header" client:load /> -
+
+ -
+
diff --git a/lint-staged.config.js b/lint-staged.config.js index 4a274bce..71838bf5 100644 --- a/lint-staged.config.js +++ b/lint-staged.config.js @@ -3,6 +3,6 @@ module.exports = { [ (files) => `pnpm exec eslint ${files.join(" ")}`, (files) => - `pnpm exec prettier -c .prettierrc.precommit.mjs --write ${files.join(" ")}`, + `pnpm exec prettier --config .prettierrc.precommit.mjs --write ${files.join(" ")}`, ], }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c5519395..c2a693fc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -95,6 +95,9 @@ importers: '@radix-ui/react-accordion': specifier: ^1.1.2 version: 1.1.2(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-alert-dialog': + specifier: ^1.0.5 + version: 1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-dialog': specifier: ^1.0.5 version: 1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0) @@ -137,6 +140,9 @@ importers: clsx: specifier: ^2.1.0 version: 2.1.0 + cmdk: + specifier: ^1.0.0 + version: 1.0.0(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0) date-fns: specifier: ^3.5.0 version: 3.6.0 @@ -1898,6 +1904,32 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@radix-ui/react-alert-dialog@1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-OrVIOcZL0tl6xibeuGt5/+UxoT2N27KCFOPjFyfXMnchxSHZ/OW7cCX2nGlIYJrbHK/fczPcFzAwvNBB6XBNMA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.24.1 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.73)(react@18.2.0) + '@radix-ui/react-dialog': 1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.73)(react@18.2.0) + '@types/react': 18.2.73 + '@types/react-dom': 18.2.23 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@radix-ui/react-arrow@1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==} peerDependencies: @@ -3910,6 +3942,21 @@ packages: engines: {node: '>=6'} dev: false + /cmdk@1.0.0(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-gDzVf0a09TvoJ5jnuPvygTB77+XdOSwEmJ88L6XPFPlv7T3RxbP9jgenfylrAMD0+Le1aO0nVjQUzl2g+vjz5Q==} + peerDependencies: + react: ^18.0.0 + react-dom: ^18.0.0 + dependencies: + '@radix-ui/react-dialog': 1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + dev: false + /collapse-white-space@2.1.0: resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} dev: false