LN

Issue Context Menu

Component 21

About

Here is ContextMenu by indevui

Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds Issue Context Menu to your project and fits it to your theme.

Code

How Issue Context Menu is used: the demo's code. The component's own source comes with a free account.

Usage.tsx

// demo.tsx
'use client';

import * as React from 'react';
import { toast } from 'sonner';
import {
   AlertCircle,
   BarChartHorizontal,
   SignalHigh,
   SignalLow,
   SignalMedium,
   LucideIcon,
} from 'lucide-react';
import IssueContextMenu, {
   ToDoIcon,
   InProgressIcon,
   CompletedIcon,
   BacklogIcon,
   PausedIcon,
} from '@/components/ui/issue-context-menu';
import type { Status, Priority, User, Label } from '@/components/ui/issue-context-menu';
import { ContextMenu, ContextMenuTrigger } from '@/components/ui/context-menu';

const statusList: Status[] = [
   { id: 'backlog', name: 'Backlog', icon: BacklogIcon, color: '#a1a1aa' },
   { id: 'todo', name: 'To-Do', icon: ToDoIcon, color: '#f97316' },
   { id: 'in-progress', name: 'In Progress', icon: InProgressIcon, color: '#facc15' },
   { id: 'paused', name: 'Paused', icon: PausedIcon, color: '#0ea5e9' },
   { id: 'completed', name: 'Completed', icon: CompletedIcon, color: '#8b5cf6' },
];

const priorityList: Priority[] = [
   { id: 'no-priority', name: 'No Priority', icon: BarChartHorizontal },
   { id: 'low', name: 'Low', icon: SignalLow },
   { id: 'medium', name: 'Medium', icon: SignalMedium },
   { id: 'high', name: 'High', icon: SignalHigh },
   { id: 'urgent', name: 'Urgent', icon: AlertCircle },
];

const userList: User[] = [
   { id: 'usr_1', name: 'Alice', avatarUrl: 'https://cdn.21st.dev/assets/mirror/a4/a4dd47498f54944edb9cd8095fb751847193faac01d922bae494e68d0cf90f4f.jpg' },
   { id: 'usr_2', name: 'Bob', avatarUrl: 'https://cdn.21st.dev/assets/mirror/6e/6ee15b9d102aaf9e45b91b5f40cf3b3374a0cd2733f239b5440d49190a96c57c.jpg' },
   { id: 'usr_3', name: 'Charlie', avatarUrl: 'https://cdn.21st.dev/assets/mirror/c9/c9038553755a8c1c3753ccd0a14af4854745b83bd3a97609f81d2c0d48f35517.jpg' },
];

const labelList: Label[] = [
   { id: 'lbl_1', name: 'Bug', color: '#d73a4a' },
   { id: 'lbl_2', name: 'Feature', color: '#0e8a16' },
   { id: 'lbl_3', name: 'Design', color: '#d876e3' },
];

const IssueContextMenuDemo = () => {
   const [isSubscribed, setIsSubscribed] = React.useState(false);
   const [isFavorite, setIsFavorite] = React.useState(false);

   const handleAction = (action: string, value?: any) => {
      switch (action) {
         case 'status':
            toast.success(`Status changed to ${statusList.find((s) => s.id === value)?.name}`);
            break;
         case 'assignee':
            const name = value ? userList.find((u) => u.id === value)?.name : 'Unassigned';
            toast.success(`Assigned to ${name}`);
            break;
         case 'priority':
            toast.success(`Priority set to ${priorityList.find((p) => p.id === value)?.name}`);
            break;
         case 'label':
            toast.info(`Toggled label: ${labelList.find((l) => l.id === value)?.name}`);
            break;
         case 'subscribe':
            setIsSubscribed((prev) => !prev);
            toast.success(isSubscribed ? 'Unsubscribed from issue' : 'Subscribed to issue');
            break;
         case 'favorite':
            setIsFavorite((prev) => !prev);
            toast.success(isFavorite ? 'Removed from favorites' : 'Added to favorites');
            break;
         case 'copyId':
            navigator.clipboard.writeText('ISSUE-123');
            toast.success('Issue ID copied to clipboard');
            break;
         case 'delete':
            toast.error('Issue has been deleted');
            break;
         default:
            toast('Action triggered', { description: `${action} ${value || ''}` });
      }
   };

   return (
      <div className="flex w-full items-center justify-center p-8">
         <ContextMenu>
            <ContextMenuTrigger>
               <div className="flex w-full max-w-sm cursor-context-menu flex-col items-center justify-center rounded-lg border-2 border-dashed border-border p-12 text-center">
                  <h3 className="font-medium">Right-Click Me</h3>
                  <p className="text-sm text-muted-foreground">
                     An issue context menu will appear.
                  </p>
               </div>
            </ContextMenuTrigger>
            <IssueContextMenu
               statusList={statusList}
               priorityList={priorityList}
               userList={userList}
               labelList={labelList}
               isSubscribed={isSubscribed}
               isFavorite={isFavorite}
               onAction={handleAction}
            />
         </ContextMenu>
      </div>
   );
};

export { IssueContextMenuDemo as DemoOne };

Dependencies

More by LN

View all
  • Pricing Interaction

    Pricing Interaction

    1.4K
  • Dorpdown Navigation

    Dorpdown Navigation

    1.2K
  • Visualize Booking

    Visualize Booking

    618
  • Assisted Password Confirmation

    Assisted Password Confirmation

    585
  • Tags Selector

    Tags Selector

    531
  • Mega Menu

    Mega Menu

    386
  • Feedback Slider

    Feedback Slider

    326
  • FlipButton

    FlipButton

    288