Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
6c300f0
feat: Menu phase I
tugcekucukoglu Nov 18, 2025
e6c3222
fix: Menu type and expose updates
tugcekucukoglu Nov 19, 2025
7f6c91d
chore: fix aria-activedescendant usage
tugcekucukoglu Nov 19, 2025
c3ff529
chore: remove comment
tugcekucukoglu Nov 19, 2025
657fc32
feat: Menu demos added I
tugcekucukoglu Nov 19, 2025
2a64f61
feat: composite mode added
tugcekucukoglu Nov 20, 2025
d04200a
feat: Composite Menu phase I
tugcekucukoglu Nov 20, 2025
550ec12
feat: Composite portal menu updates
tugcekucukoglu Nov 20, 2025
e300b72
feat: Menu.Icon added
tugcekucukoglu Nov 24, 2025
6178fde
feat: responsiveness
tugcekucukoglu Nov 24, 2025
607b296
chore: style and type updates
tugcekucukoglu Nov 24, 2025
6a5eb85
feat: Menu.Icon demo updates
tugcekucukoglu Nov 24, 2025
1cc7203
chore: Menu.Item keyboard support updates
tugcekucukoglu Nov 24, 2025
bb9bb8e
chore: Composite and router demos added
tugcekucukoglu Nov 24, 2025
0428484
fix: submenu. opening blink fixed
tugcekucukoglu Nov 24, 2025
4df921a
chore: remove comments
tugcekucukoglu Nov 24, 2025
47da469
feat: ContextMenu phase i
tugcekucukoglu Nov 25, 2025
19b7fe1
chore: Menu.Item updates
tugcekucukoglu Nov 25, 2025
f23ae3c
feat: Add Menu.Label
tugcekucukoglu Nov 25, 2025
3e32081
chore: Menu demo updates
tugcekucukoglu Nov 25, 2025
a3af4b7
feat: Menu checkbox and radio select implementation
tugcekucukoglu Nov 26, 2025
686569f
feat: ContextMenu phase II
tugcekucukoglu Nov 26, 2025
3b8d4ac
feat: Dot icon added
tugcekucukoglu Nov 26, 2025
913cc20
chore: Menu demo updates
tugcekucukoglu Nov 26, 2025
6ebdfb1
chore: ContextMenu demo phase I
tugcekucukoglu Nov 26, 2025
4b9de6f
chore: ContextMenu demo added
tugcekucukoglu Nov 26, 2025
2381ff3
fix: refactor
tugcekucukoglu Nov 26, 2025
8cd729e
chore: Menu type updates
tugcekucukoglu Nov 26, 2025
37e62c9
chore: ContextMenu demos added
tugcekucukoglu Nov 26, 2025
f8881a7
chore: Menu documentation updates
tugcekucukoglu Nov 26, 2025
41b88bf
chore: remove ContextMenu styles
tugcekucukoglu Nov 27, 2025
be88d93
fix: checked state updates
tugcekucukoglu Nov 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions apps/showcase/demo/contextmenu/basic-demo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { ContextMenu } from 'primereact/contextmenu';

export default function BasicDemo() {
return (
<div className="card flex justify-center">
<ContextMenu className="w-64">
<ContextMenu.Trigger className="flex justify-center items-center border-2 border-dashed border-surface-200 dark:border-surface-700 w-120 h-64">
Right Click Here
</ContextMenu.Trigger>
<ContextMenu.Portal>
<ContextMenu.List>
<ContextMenu.Item>
<i className="pi pi-home" />
Dashboard
</ContextMenu.Item>

<ContextMenu.Separator />

<ContextMenu.Label>Workspace</ContextMenu.Label>

<ContextMenu.Item>
<i className="pi pi-chart-line" />
Analytics
</ContextMenu.Item>

<ContextMenu.Sub>
<ContextMenu.Trigger>
<i className="pi pi-folder" />
Projects
<ContextMenu.Icon />
</ContextMenu.Trigger>
<ContextMenu.List>
<ContextMenu.Item>
<i className="pi pi-briefcase" />
Active Projects
</ContextMenu.Item>
<ContextMenu.Item>
<i className="pi pi-clock" />
Recent
</ContextMenu.Item>

<ContextMenu.Sub>
<ContextMenu.Trigger>
<i className="pi pi-star" />
Favorites
<ContextMenu.Icon />
</ContextMenu.Trigger>
<ContextMenu.List>
<ContextMenu.Item>
<i className="pi pi-code" />
Website Redesign
</ContextMenu.Item>
<ContextMenu.Item>
<i className="pi pi-mobile" />
Mobile App
</ContextMenu.Item>
<ContextMenu.Item>
<i className="pi pi-database" />
API Development
</ContextMenu.Item>
</ContextMenu.List>
</ContextMenu.Sub>

<ContextMenu.Item>
<i className="pi pi-check-circle" />
Completed
</ContextMenu.Item>
</ContextMenu.List>
</ContextMenu.Sub>

<ContextMenu.Sub>
<ContextMenu.Trigger>
<i className="pi pi-users" />
Team
<ContextMenu.Icon />
</ContextMenu.Trigger>
<ContextMenu.List>
<ContextMenu.Item>
<i className="pi pi-user-plus" />
Add Member
</ContextMenu.Item>
<ContextMenu.Item>
<i className="pi pi-sitemap" />
Organization
</ContextMenu.Item>

<ContextMenu.Sub>
<ContextMenu.Trigger>
<i className="pi pi-cog" />
Settings
<ContextMenu.Icon />
</ContextMenu.Trigger>
<ContextMenu.List>
<ContextMenu.Item>
<i className="pi pi-shield" />
Permissions
</ContextMenu.Item>
<ContextMenu.Item>
<i className="pi pi-bell" />
Notifications
</ContextMenu.Item>
<ContextMenu.Item>
<i className="pi pi-lock" />
Privacy
</ContextMenu.Item>
</ContextMenu.List>
</ContextMenu.Sub>
</ContextMenu.List>
</ContextMenu.Sub>

<ContextMenu.Separator />

<ContextMenu.Item>
<i className="pi pi-question-circle" />
Help & Support
</ContextMenu.Item>
</ContextMenu.List>
</ContextMenu.Portal>
</ContextMenu>
</div>
);
}
62 changes: 62 additions & 0 deletions apps/showcase/demo/contextmenu/contextmenu-pt.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
'use client';

import { ContextMenuCheckboxItemCheckedChangeEvent, ContextMenuRadioGroupValueChangeEvent } from '@primereact/types/shared/contextmenu';
import { ContextMenu } from 'primereact/contextmenu';
import * as React from 'react';

export default function ContextMenuPTDemo() {
const [notificationsEnabled, setNotificationsEnabled] = React.useState(true);
const [soundEnabled, setSoundEnabled] = React.useState(false);
const [theme, setTheme] = React.useState('light');

return (
<ContextMenu className="w-64">
<ContextMenu.List>
<ContextMenu.Item>Overview</ContextMenu.Item>

<ContextMenu.Separator />

<ContextMenu.Label>Preferences</ContextMenu.Label>

<ContextMenu.CheckboxItem
checked={notificationsEnabled}
onCheckedChange={(e: ContextMenuCheckboxItemCheckedChangeEvent) => setNotificationsEnabled(e.value)}
>
<ContextMenu.CheckboxIcon />
Enable Notifications
</ContextMenu.CheckboxItem>

<ContextMenu.CheckboxItem
checked={soundEnabled}
onCheckedChange={(e: ContextMenuCheckboxItemCheckedChangeEvent) => setSoundEnabled(e.value)}
>
<ContextMenu.CheckboxIcon />
Enable Sound
</ContextMenu.CheckboxItem>

<ContextMenu.Separator />

<ContextMenu.Label>Appearance</ContextMenu.Label>

<ContextMenu.RadioGroup value={theme} onValueChange={(e: ContextMenuRadioGroupValueChangeEvent) => setTheme(e.value as string)}>
<ContextMenu.RadioItem value="light">
<ContextMenu.RadioIcon />
Light Mode
</ContextMenu.RadioItem>
<ContextMenu.RadioItem value="dark">
<ContextMenu.RadioIcon />
Dark Mode
</ContextMenu.RadioItem>
<ContextMenu.RadioItem value="system">
<ContextMenu.RadioIcon />
System Default
</ContextMenu.RadioItem>
</ContextMenu.RadioGroup>

<ContextMenu.Separator />

<ContextMenu.Item>Settings</ContextMenu.Item>
</ContextMenu.List>
</ContextMenu>
);
}
72 changes: 72 additions & 0 deletions apps/showcase/demo/contextmenu/radio-checkbox-demo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
'use client';

import { ContextMenuCheckboxItemCheckedChangeEvent, ContextMenuRadioGroupValueChangeEvent } from '@primereact/types/shared/contextmenu';
import { ContextMenu } from 'primereact/contextmenu';
import * as React from 'react';

export default function RadioCheckboxDemo() {
const [notificationsEnabled, setNotificationsEnabled] = React.useState(true);
const [soundEnabled, setSoundEnabled] = React.useState(false);
const [theme, setTheme] = React.useState('light');

return (
<div className="card flex justify-center">
<ContextMenu className="w-64">
<ContextMenu.Trigger className="flex justify-center items-center border-2 border-dashed border-surface-200 dark:border-surface-700 w-120 h-64">
Right Click Here
</ContextMenu.Trigger>
<ContextMenu.Portal>
<ContextMenu.List>
<ContextMenu.Item>Overview</ContextMenu.Item>

<ContextMenu.Separator />

<ContextMenu.Label>Preferences</ContextMenu.Label>

<ContextMenu.CheckboxItem
checked={notificationsEnabled}
onCheckedChange={(e: ContextMenuCheckboxItemCheckedChangeEvent) => setNotificationsEnabled(e.value)}
>
<ContextMenu.CheckboxIcon />
Enable Notifications
</ContextMenu.CheckboxItem>

<ContextMenu.CheckboxItem
checked={soundEnabled}
onCheckedChange={(e: ContextMenuCheckboxItemCheckedChangeEvent) => setSoundEnabled(e.value)}
>
<ContextMenu.CheckboxIcon />
Enable Sound
</ContextMenu.CheckboxItem>

<ContextMenu.Separator />

<ContextMenu.Label>Appearance</ContextMenu.Label>

<ContextMenu.RadioGroup
value={theme}
onValueChange={(e: ContextMenuRadioGroupValueChangeEvent) => setTheme(e.value as string)}
>
<ContextMenu.RadioItem value="light">
<ContextMenu.RadioIcon />
Light Mode
</ContextMenu.RadioItem>
<ContextMenu.RadioItem value="dark">
<ContextMenu.RadioIcon />
Dark Mode
</ContextMenu.RadioItem>
<ContextMenu.RadioItem value="system">
<ContextMenu.RadioIcon />
System Default
</ContextMenu.RadioItem>
</ContextMenu.RadioGroup>

<ContextMenu.Separator />

<ContextMenu.Item>Settings</ContextMenu.Item>
</ContextMenu.List>
</ContextMenu.Portal>
</ContextMenu>
</div>
);
}
40 changes: 40 additions & 0 deletions apps/showcase/demo/menu/apps-demo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Menu } from 'primereact/menu';

const apps = [
{ label: 'Search', icon: 'pi-search', gradient: 'from-sky-400 to-cyan-500' },
{ label: 'Maps', icon: 'pi-map-marker', gradient: 'from-emerald-500 to-green-600' },
{ label: 'Mail', icon: 'pi-envelope', gradient: 'from-orange-400 to-red-500' },
{ label: 'Drive', icon: 'pi-cloud', gradient: 'from-blue-500 to-indigo-600' },
{ label: 'Calendar', icon: 'pi-calendar', gradient: 'from-violet-500 to-purple-600' },
{ label: 'Photos', icon: 'pi-image', gradient: 'from-fuchsia-500 to-pink-600' },
{ label: 'Videos', icon: 'pi-video', gradient: 'from-red-500 to-rose-600' },
{ label: 'Analytics', icon: 'pi-chart-line', gradient: 'from-cyan-500 to-blue-600' },
{ label: 'Settings', icon: 'pi-cog', gradient: 'from-slate-500 to-zinc-700' }
];

export default function AppsDemo() {
return (
<div className="card flex justify-center">
<Menu className="w-116">
<Menu.Trigger rounded iconOnly>
<i className="pi pi-bars" />
</Menu.Trigger>

<Menu.Portal>
<Menu.List className="grid grid-cols-3 gap-1 p-2">
{apps.map((app) => (
<Menu.Item key={app.label} className="flex-col items-center justify-center h-28 gap-3">
<div
className={`w-14 h-14 rounded-2xl bg-linear-to-br ${app.gradient} flex items-center justify-center transition-transform`}
>
<i className={`pi ${app.icon} text-2xl text-white`} />
</div>
<span className="text-sm font-medium">{app.label}</span>
</Menu.Item>
))}
</Menu.List>
</Menu.Portal>
</Menu>
</div>
);
}
88 changes: 88 additions & 0 deletions apps/showcase/demo/menu/composite-demo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { Menu } from 'primereact/menu';

export default function CompositeDemo() {
return (
<div className="card flex justify-center">
<Menu className="w-56" composite>
<Menu.List>
<Menu.Item>
<i className="pi pi-file" />
New
</Menu.Item>
<Menu.Item>
<i className="pi pi-folder-open" />
Open
</Menu.Item>

<Menu.Separator />

<Menu.Sub>
<Menu.Trigger>
<i className="pi pi-download" />
Import
<Menu.Icon />
</Menu.Trigger>
<Menu.List>
<Menu.Item>
<i className="pi pi-file" />
From File
</Menu.Item>

<Menu.Sub>
<Menu.Trigger>
<i className="pi pi-cloud" />
From Cloud
<Menu.Icon />
</Menu.Trigger>
<Menu.List>
<Menu.Item>Google Drive</Menu.Item>
<Menu.Item>Dropbox</Menu.Item>
<Menu.Item>OneDrive</Menu.Item>
</Menu.List>
</Menu.Sub>

<Menu.Item>
<i className="pi pi-globe" />
From URL
</Menu.Item>
</Menu.List>
</Menu.Sub>

<Menu.Sub>
<Menu.Trigger>
<i className="pi pi-share-alt" />
Share
<Menu.Icon />
</Menu.Trigger>
<Menu.List>
<Menu.Item>
<i className="pi pi-send" />
Send via Email
</Menu.Item>
<Menu.Item>
<i className="pi pi-link" />
Copy Link
</Menu.Item>
<Menu.Item>
<i className="pi pi-users" />
Share with Team
</Menu.Item>
</Menu.List>
</Menu.Sub>

<Menu.Item>
<i className="pi pi-save" />
Save
</Menu.Item>

<Menu.Separator />

<Menu.Item>
<i className="pi pi-sign-out" />
Exit
</Menu.Item>
</Menu.List>
</Menu>
</div>
);
}
Loading
Loading