From 23ab70f8ef0ba86fdfb1519547bfdfccd437f2e8 Mon Sep 17 00:00:00 2001 From: OrcDev Date: Fri, 16 May 2025 12:05:41 +0200 Subject: [PATCH 1/2] feat(registry) add context menu component --- app/docs/components/context-menu/page.tsx | 92 +++++++ components/ui/8bit/context-menu.tsx | 288 ++++++++++++++++++++++ config/nav-items.ts | 5 + package.json | 1 + pnpm-lock.yaml | 30 +++ public/r/8bit-context-menu.json | 16 ++ registry.json | 14 ++ 7 files changed, 446 insertions(+) create mode 100644 app/docs/components/context-menu/page.tsx create mode 100644 components/ui/8bit/context-menu.tsx create mode 100644 public/r/8bit-context-menu.json diff --git a/app/docs/components/context-menu/page.tsx b/app/docs/components/context-menu/page.tsx new file mode 100644 index 00000000..82df35f2 --- /dev/null +++ b/app/docs/components/context-menu/page.tsx @@ -0,0 +1,92 @@ +import { Metadata } from "next" + +import { buttonMetaData } from "@/lib/metadata" +import { + ContextMenu, + ContextMenuCheckboxItem, + ContextMenuContent, + ContextMenuItem, + ContextMenuTrigger, +} from "@/components/ui/8bit/context-menu" +import { Separator } from "@/components/ui/separator" + +import CodeSnippet from "../code-snippet" +import CopyCommandButton from "../copy-command-button" +import InstallationCommands from "../installation-commands" +import { OpenInV0Button } from "../open-in-v0-button" + +export const metadata: Metadata = { + title: "8-bit Context Menu", + description: "Displays an 8-bit context menu component.", + openGraph: { + images: buttonMetaData, + }, +} + +export default function ButtonPage() { + return ( +
+
+

Context Menu

+ +
+ +

+ Displays an 8-bit context menu component. +

+ +
+
+

+ 8-bit context menu component +

+ +
+ +
+
+
+ + Right click + + Profile + Billing + Team + Subscription + + Item + + + +
+
+ +

Installation

+ + + + + +

Usage

+ + + + {`import { ContextMenu } from "@/components/ui/8bit/context-menu"`} + + {` + Right click + + Profile + Billing + Team + Subscription + +`} +
+ ) +} diff --git a/components/ui/8bit/context-menu.tsx b/components/ui/8bit/context-menu.tsx new file mode 100644 index 00000000..47c39651 --- /dev/null +++ b/components/ui/8bit/context-menu.tsx @@ -0,0 +1,288 @@ +"use client" + +import * as React from "react" +import { Press_Start_2P } from "next/font/google" +import * as ContextMenuPrimitive from "@radix-ui/react-context-menu" +import { ChevronRight, Circle } from "lucide-react" + +import { cn } from "@/lib/utils" + +const pressStart = Press_Start_2P({ + weight: ["400"], + subsets: ["latin"], +}) + +const ContextMenu = ContextMenuPrimitive.Root + +const ContextMenuTrigger = ContextMenuPrimitive.Trigger + +const ContextMenuGroup = ContextMenuPrimitive.Group + +const ContextMenuPortal = ContextMenuPrimitive.Portal + +const ContextMenuSub = ContextMenuPrimitive.Sub + +const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup + +const ContextMenuSubTrigger = React.forwardRef< + React.ComponentRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, children, ...props }, ref) => ( + + {children} + + +)) +ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName + +const ContextMenuSubContent = React.forwardRef< + React.ComponentRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName + +const ContextMenuContent = React.forwardRef< + React.ComponentRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +
+ + + +)) +ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName + +const ContextMenuItem = React.forwardRef< + React.ComponentRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName + +const ContextMenuCheckboxItem = React.forwardRef< + React.ComponentRef, + React.ComponentPropsWithoutRef +>(({ className, children, checked, ...props }, ref) => ( + + + + + + + + + + + + + + + + {children} + +)) +ContextMenuCheckboxItem.displayName = + ContextMenuPrimitive.CheckboxItem.displayName + +const ContextMenuRadioItem = React.forwardRef< + React.ComponentRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + {children} + +)) +ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName + +const ContextMenuLabel = React.forwardRef< + React.ComponentRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName + +const ContextMenuSeparator = React.forwardRef< + React.ComponentRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName + +const ContextMenuShortcut = ({ + className, + ...props +}: React.HTMLAttributes) => { + return ( + + ) +} +ContextMenuShortcut.displayName = "ContextMenuShortcut" + +export { + ContextMenu, + ContextMenuTrigger, + ContextMenuContent, + ContextMenuItem, + ContextMenuCheckboxItem, + ContextMenuRadioItem, + ContextMenuLabel, + ContextMenuSeparator, + ContextMenuShortcut, + ContextMenuGroup, + ContextMenuPortal, + ContextMenuSub, + ContextMenuSubContent, + ContextMenuSubTrigger, + ContextMenuRadioGroup, +} diff --git a/config/nav-items.ts b/config/nav-items.ts index 5364e7e7..589ac24c 100644 --- a/config/nav-items.ts +++ b/config/nav-items.ts @@ -75,6 +75,11 @@ export const navItems = { title: "Command", url: "/docs/components/command", }, + { + title: "Context Menu", + url: "/docs/components/context-menu", + new: true, + }, { title: "Collapsible", url: "/docs/components/collapsible", diff --git a/package.json b/package.json index 66534cb7..52fca727 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "@radix-ui/react-avatar": "^1.1.9", "@radix-ui/react-checkbox": "^1.3.1", "@radix-ui/react-collapsible": "^1.1.10", + "@radix-ui/react-context-menu": "^2.2.14", "@radix-ui/react-dialog": "^1.1.13", "@radix-ui/react-dropdown-menu": "^2.1.14", "@radix-ui/react-hover-card": "^1.1.13", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 995b606d..1e25d716 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ importers: '@radix-ui/react-collapsible': specifier: ^1.1.10 version: 1.1.10(@types/react-dom@19.1.5(@types/react@19.1.4))(@types/react@19.1.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-context-menu': + specifier: ^2.2.14 + version: 2.2.14(@types/react-dom@19.1.5(@types/react@19.1.4))(@types/react@19.1.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@radix-ui/react-dialog': specifier: ^1.1.13 version: 1.1.13(@types/react-dom@19.1.5(@types/react@19.1.4))(@types/react@19.1.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -770,6 +773,19 @@ packages: '@types/react': optional: true + '@radix-ui/react-context-menu@2.2.14': + resolution: {integrity: sha512-RUHvrJE2qKAd9pQ50HZZsePio4SMWEh8v6FWQwg/4t6K1fuxfb4Ec40VEVvni6V7nFxmj9srU4UZc7aYp8x0LQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-context@1.1.2': resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} peerDependencies: @@ -4392,6 +4408,20 @@ snapshots: optionalDependencies: '@types/react': 19.1.4 + '@radix-ui/react-context-menu@2.2.14(@types/react-dom@19.1.5(@types/react@19.1.4))(@types/react@19.1.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-context': 1.1.2(@types/react@19.1.4)(react@19.1.0) + '@radix-ui/react-menu': 2.1.14(@types/react-dom@19.1.5(@types/react@19.1.4))(@types/react@19.1.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.2(@types/react-dom@19.1.5(@types/react@19.1.4))(@types/react@19.1.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.4)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.4)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.4 + '@types/react-dom': 19.1.5(@types/react@19.1.4) + '@radix-ui/react-context@1.1.2(@types/react@19.1.4)(react@19.1.0)': dependencies: react: 19.1.0 diff --git a/public/r/8bit-context-menu.json b/public/r/8bit-context-menu.json new file mode 100644 index 00000000..55cf3843 --- /dev/null +++ b/public/r/8bit-context-menu.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "8bit-context-menu", + "type": "registry:component", + "title": "8-bit Context Menu", + "description": "A simple 8-bit context menu component", + "registryDependencies": [], + "files": [ + { + "path": "components/ui/8bit/context-menu.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Press_Start_2P } from \"next/font/google\"\nimport * as ContextMenuPrimitive from \"@radix-ui/react-context-menu\"\nimport { ChevronRight, Circle } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst pressStart = Press_Start_2P({\n weight: [\"400\"],\n subsets: [\"latin\"],\n})\n\nconst ContextMenu = ContextMenuPrimitive.Root\n\nconst ContextMenuTrigger = ContextMenuPrimitive.Trigger\n\nconst ContextMenuGroup = ContextMenuPrimitive.Group\n\nconst ContextMenuPortal = ContextMenuPrimitive.Portal\n\nconst ContextMenuSub = ContextMenuPrimitive.Sub\n\nconst ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup\n\nconst ContextMenuSubTrigger = React.forwardRef<\n React.ComponentRef,\n React.ComponentPropsWithoutRef & {\n inset?: boolean\n }\n>(({ className, inset, children, ...props }, ref) => (\n \n {children}\n \n \n))\nContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName\n\nconst ContextMenuSubContent = React.forwardRef<\n React.ComponentRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\nContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName\n\nconst ContextMenuContent = React.forwardRef<\n React.ComponentRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n
\n \n \n
\n
\n))\nContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName\n\nconst ContextMenuItem = React.forwardRef<\n React.ComponentRef,\n React.ComponentPropsWithoutRef & {\n inset?: boolean\n }\n>(({ className, inset, ...props }, ref) => (\n \n))\nContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName\n\nconst ContextMenuCheckboxItem = React.forwardRef<\n React.ComponentRef,\n React.ComponentPropsWithoutRef\n>(({ className, children, checked, ...props }, ref) => (\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {children}\n \n))\nContextMenuCheckboxItem.displayName =\n ContextMenuPrimitive.CheckboxItem.displayName\n\nconst ContextMenuRadioItem = React.forwardRef<\n React.ComponentRef,\n React.ComponentPropsWithoutRef\n>(({ className, children, ...props }, ref) => (\n \n \n \n \n \n \n {children}\n \n))\nContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName\n\nconst ContextMenuLabel = React.forwardRef<\n React.ComponentRef,\n React.ComponentPropsWithoutRef & {\n inset?: boolean\n }\n>(({ className, inset, ...props }, ref) => (\n \n))\nContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName\n\nconst ContextMenuSeparator = React.forwardRef<\n React.ComponentRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\nContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName\n\nconst ContextMenuShortcut = ({\n className,\n ...props\n}: React.HTMLAttributes) => {\n return (\n \n )\n}\nContextMenuShortcut.displayName = \"ContextMenuShortcut\"\n\nexport {\n ContextMenu,\n ContextMenuTrigger,\n ContextMenuContent,\n ContextMenuItem,\n ContextMenuCheckboxItem,\n ContextMenuRadioItem,\n ContextMenuLabel,\n ContextMenuSeparator,\n ContextMenuShortcut,\n ContextMenuGroup,\n ContextMenuPortal,\n ContextMenuSub,\n ContextMenuSubContent,\n ContextMenuSubTrigger,\n ContextMenuRadioGroup,\n}\n", + "type": "registry:component", + "target": "components/ui/8bit/context-menu.tsx" + } + ] +} \ No newline at end of file diff --git a/registry.json b/registry.json index 16a723ed..14f43b35 100644 --- a/registry.json +++ b/registry.json @@ -409,6 +409,20 @@ } ] }, + { + "name": "8bit-context-menu", + "type": "registry:component", + "title": "8-bit Context Menu", + "description": "A simple 8-bit context menu component", + "registryDependencies": [], + "files": [ + { + "path": "components/ui/8bit/context-menu.tsx", + "type": "registry:component", + "target": "components/ui/8bit/context-menu.tsx" + } + ] + }, { "name": "8bit-toggle", "type": "registry:component", From 4d765d429227ca27623450c3dcc5fb512a2a5e86 Mon Sep 17 00:00:00 2001 From: OrcDev Date: Fri, 16 May 2025 12:08:22 +0200 Subject: [PATCH 2/2] feat(context-menu) add metadata --- app/docs/components/context-menu/page.tsx | 13 ++++++------- lib/metadata.ts | 1 + public/assets/8bitcn-context-menu-light.png | Bin 0 -> 32849 bytes 3 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 public/assets/8bitcn-context-menu-light.png diff --git a/app/docs/components/context-menu/page.tsx b/app/docs/components/context-menu/page.tsx index 82df35f2..18313984 100644 --- a/app/docs/components/context-menu/page.tsx +++ b/app/docs/components/context-menu/page.tsx @@ -1,9 +1,9 @@ import { Metadata } from "next" -import { buttonMetaData } from "@/lib/metadata" +import { contextMenuMetaData } from "@/lib/metadata" +import { Button } from "@/components/ui/8bit/button" import { ContextMenu, - ContextMenuCheckboxItem, ContextMenuContent, ContextMenuItem, ContextMenuTrigger, @@ -19,7 +19,7 @@ export const metadata: Metadata = { title: "8-bit Context Menu", description: "Displays an 8-bit context menu component.", openGraph: { - images: buttonMetaData, + images: contextMenuMetaData, }, } @@ -50,15 +50,14 @@ export default function ButtonPage() {
- Right click + + + Profile Billing Team Subscription - - Item -
diff --git a/lib/metadata.ts b/lib/metadata.ts index 7e66c815..f5106a52 100644 --- a/lib/metadata.ts +++ b/lib/metadata.ts @@ -49,3 +49,4 @@ export const toggleGroupMetaData = "/assets/8bitcn-toggle-group-light.png" export const accordionMetaData = "/assets/8bitcn-accordion-light.png" export const sliderMetaData = "/assets/8bitcn-slider-light.png" export const datePickerMetaData = "/assets/8bitcn-date-picker-light.png" +export const contextMenuMetaData = "/assets/8bitcn-context-menu-light.png" diff --git a/public/assets/8bitcn-context-menu-light.png b/public/assets/8bitcn-context-menu-light.png new file mode 100644 index 0000000000000000000000000000000000000000..ab7c5b4add0a04c69b39b5520e2402c8b0a25c0e GIT binary patch literal 32849 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 E2V#2E$N&HU literal 0 HcmV?d00001