Spaces:
Running
Running
| 'use client' | |
| import React, { useRef, useEffect } from 'react' | |
| import { motion, AnimatePresence } from 'framer-motion' | |
| import { | |
| Image, | |
| PaintBrush, | |
| Upload, | |
| Palette, | |
| Desktop as DesktopIcon, | |
| Gradient | |
| } from '@phosphor-icons/react' | |
| interface DesktopContextMenuProps { | |
| isOpen: boolean | |
| position: { x: number; y: number } | |
| onClose: () => void | |
| onChangeBackground: (type: 'upload' | 'preset') => void | |
| } | |
| const presetBackgrounds = [ | |
| { name: 'Ubuntu Purple', value: 'gradient-purple' }, | |
| { name: 'Ocean Blue', value: 'gradient-blue' }, | |
| { name: 'Forest Green', value: 'gradient-green' }, | |
| { name: 'Sunset Orange', value: 'gradient-orange' }, | |
| { name: 'Dark Mode', value: 'gradient-dark' }, | |
| ] | |
| export function DesktopContextMenu({ | |
| isOpen, | |
| position, | |
| onClose, | |
| onChangeBackground | |
| }: DesktopContextMenuProps) { | |
| const menuRef = useRef<HTMLDivElement>(null) | |
| useEffect(() => { | |
| const handleClickOutside = (event: MouseEvent) => { | |
| if (menuRef.current && !menuRef.current.contains(event.target as Node)) { | |
| onClose() | |
| } | |
| } | |
| const handleEscape = (event: KeyboardEvent) => { | |
| if (event.key === 'Escape') { | |
| onClose() | |
| } | |
| } | |
| if (isOpen) { | |
| document.addEventListener('mousedown', handleClickOutside) | |
| document.addEventListener('keydown', handleEscape) | |
| } | |
| return () => { | |
| document.removeEventListener('mousedown', handleClickOutside) | |
| document.removeEventListener('keydown', handleEscape) | |
| } | |
| }, [isOpen, onClose]) | |
| return ( | |
| <AnimatePresence> | |
| {isOpen && ( | |
| <motion.div | |
| ref={menuRef} | |
| initial={{ opacity: 0, scale: 0.95 }} | |
| animate={{ opacity: 1, scale: 1 }} | |
| exit={{ opacity: 0, scale: 0.95 }} | |
| transition={{ duration: 0.1 }} | |
| className="fixed z-50 bg-[#2C2C2C]/95 backdrop-blur-md rounded-lg shadow-2xl border border-white/10 py-2 min-w-[240px]" | |
| style={{ | |
| left: `${position.x}px`, | |
| top: `${position.y}px`, | |
| maxHeight: 'calc(100vh - 20px)', | |
| overflowY: 'auto' | |
| }} | |
| > | |
| {/* Change Background Section */} | |
| <button | |
| onClick={() => onChangeBackground('preset')} | |
| className="w-full px-3 py-2 flex items-center gap-3 hover:bg-white/10 transition-colors text-left" | |
| > | |
| <Image size={18} className="text-blue-400" /> | |
| <span className="text-sm text-gray-200">Change Wallpaper</span> | |
| </button> | |
| </motion.div> | |
| )} | |
| </AnimatePresence> | |
| ) | |
| } |