diff --git a/package.json b/package.json index 2c157137b..6a0bcd114 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,7 @@ "@phosphor-icons/react": "^2.1.10", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.16", + "@radix-ui/react-menu": "2.1.16", "@radix-ui/react-tooltip": "^1.2.8", "@react-three/drei": "^10.7.7", "@react-three/fiber": "^9.5.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index be1b01d31..05a6011b9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -100,6 +100,9 @@ importers: '@radix-ui/react-dropdown-menu': specifier: ^2.1.16 version: 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-menu': + specifier: 2.1.16 + version: 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@radix-ui/react-tooltip': specifier: ^1.2.8 version: 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) diff --git a/src/components/BrandContextMenu.tsx b/src/components/BrandContextMenu.tsx index 2f7bbbf2c..2a58540ca 100644 --- a/src/components/BrandContextMenu.tsx +++ b/src/components/BrandContextMenu.tsx @@ -2,34 +2,31 @@ import * as React from 'react' import { useToast } from '~/components/ToastProvider' import { useNavigate } from '@tanstack/react-router' import { twMerge } from 'tailwind-merge' -import { - Dropdown, - DropdownTrigger, - DropdownContent, - DropdownItem, - DropdownSeparator, -} from './Dropdown' +import * as Menu from '@radix-ui/react-menu' import { copyTextToClipboard } from '~/utils/browser-effects' interface BrandContextMenuProps extends React.HTMLAttributes { children: React.ReactNode + showTrigger?: boolean } -export function BrandContextMenu({ children, ...rest }: BrandContextMenuProps) { +export function BrandContextMenu({ + children, + showTrigger = false, + ...rest +}: BrandContextMenuProps) { const navigate = useNavigate() const { notify } = useToast() const [open, setOpen] = React.useState(false) - const [coords, setCoords] = React.useState<{ x: number; y: number }>({ - x: 0, - y: 0, - }) - const virtualTriggerRef = React.useRef(null) - - const onContextMenu = (e: React.MouseEvent) => { - e.preventDefault() - setCoords({ x: e.clientX, y: e.clientY }) - setOpen(true) - } + const [point, setPoint] = React.useState({ x: 0, y: 0 }) + const anchorRef = React.useMemo( + () => ({ + current: { + getBoundingClientRect: () => new DOMRect(point.x, point.y, 0, 0), + }, + }), + [point], + ) const copyText = async (text: string) => { try { @@ -58,25 +55,64 @@ export function BrandContextMenu({ children, ...rest }: BrandContextMenuProps) { } return ( -
- {children} - - - + +
{ + rest.onContextMenu?.(event) + if (event.defaultPrevented) return + event.preventDefault() + event.stopPropagation() + setPoint({ x: event.clientX, y: event.clientY }) + setOpen(true) + }} + onKeyDown={(event) => { + rest.onKeyDown?.(event) + if ( + event.defaultPrevented || + !( + event.key === 'ContextMenu' || + (event.shiftKey && event.key === 'F10') + ) + ) + return + event.preventDefault() + event.stopPropagation() + const target = + event.target instanceof HTMLElement + ? event.target + : event.currentTarget + const rect = target.getBoundingClientRect() + setPoint({ x: rect.left, y: rect.bottom }) + setOpen(true) + }} + > + {children} + {showTrigger && ( + + )} +
+ + {[ { @@ -107,9 +143,9 @@ export function BrandContextMenu({ children, ...rest }: BrandContextMenuProps) { darkBg: true, }, ].map(({ label, url, darkBg }) => ( - { try { const res = await fetch(url) @@ -131,14 +167,17 @@ export function BrandContextMenu({ children, ...rest }: BrandContextMenuProps) { > {label}
- + ))} - - navigate({ to: '/ds/logos' })}> + + navigate({ to: '/ds/logos' })} + > All Logo Assets - - - - + + + + ) } diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index e20f2913b..b910df7de 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -654,6 +654,7 @@ export function Navbar({ children }: { children: React.ReactNode }) { />
diff --git a/src/routes/login.tsx b/src/routes/login.tsx index 392df8213..5b8f54bff 100644 --- a/src/routes/login.tsx +++ b/src/routes/login.tsx @@ -57,7 +57,7 @@ function SplashImage() { return (
- + diff --git a/src/routes/oauth/authorize.tsx b/src/routes/oauth/authorize.tsx index 1a4182489..a52781cd0 100644 --- a/src/routes/oauth/authorize.tsx +++ b/src/routes/oauth/authorize.tsx @@ -170,7 +170,7 @@ function SplashImage() { return (
- +