Files
paint-ui/store/context-menu-store.ts
Sebastian Krüger 108dfb5cec feat(ui): implement right-click context menu system for layers
Added comprehensive context menu system with:

Context Menu Infrastructure:
- Context menu store using Zustand for state management
- Reusable ContextMenu component with positioning logic
- Automatic viewport boundary detection and adjustment
- Keyboard support (Escape to close)
- Click-outside detection

Layer Context Menu Features:
- Duplicate Layer (with icon)
- Move Up/Down (with disabled state when not possible)
- Show/Hide Layer (dynamic label based on state)
- Delete Layer (with confirmation, danger styling, disabled when only one layer)
- Visual separators between action groups

UX Enhancements:
- Smooth fade-in animation
- Proper z-indexing (9999) above all content
- Focus management with keyboard navigation
- Disabled state styling for unavailable actions
- Danger state (red text) for destructive actions
- Icon support for better visual identification

Accessibility:
- role="menu" and role="menuitem" attributes
- aria-label for screen readers
- aria-disabled for unavailable actions
- Keyboard navigation support

The context menu system is extensible and can be used for other
components beyond layers (canvas, tools, etc.).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 15:52:35 +01:00

41 lines
793 B
TypeScript

import { create } from 'zustand';
export interface ContextMenuItem {
label: string;
icon?: React.ReactNode;
onClick: () => void;
disabled?: boolean;
separator?: boolean;
danger?: boolean;
}
interface ContextMenuState {
isOpen: boolean;
position: { x: number; y: number } | null;
items: ContextMenuItem[];
showContextMenu: (x: number, y: number, items: ContextMenuItem[]) => void;
hideContextMenu: () => void;
}
export const useContextMenuStore = create<ContextMenuState>((set) => ({
isOpen: false,
position: null,
items: [],
showContextMenu: (x, y, items) => {
set({
isOpen: true,
position: { x, y },
items,
});
},
hideContextMenu: () => {
set({
isOpen: false,
position: null,
items: [],
});
},
}));