Skip to content

Commit d354273

Browse files
committed
refactor: rewrite CommandMenu component with useListbox
1 parent d1935ca commit d354273

48 files changed

Lines changed: 1868 additions & 1259 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/showcase/__store__/index.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,10 @@ export const Store: Record<string, Record<string, Record<string, { component: Re
517517
'component': React.lazy(() => import('demo/styled/commandmenu/controlled-demo')),
518518
'filePath': 'demo/styled/commandmenu/controlled-demo.tsx',
519519
},
520+
'custom-demo': {
521+
'component': React.lazy(() => import('demo/styled/commandmenu/custom-demo')),
522+
'filePath': 'demo/styled/commandmenu/custom-demo.tsx',
523+
},
520524
'filter-demo': {
521525
'component': React.lazy(() => import('demo/styled/commandmenu/filter-demo')),
522526
'filePath': 'demo/styled/commandmenu/filter-demo.tsx',
@@ -525,6 +529,10 @@ export const Store: Record<string, Record<string, Record<string, { component: Re
525529
'component': React.lazy(() => import('demo/styled/commandmenu/with-dialog-demo')),
526530
'filePath': 'demo/styled/commandmenu/with-dialog-demo.tsx',
527531
},
532+
'with-scrollarea-demo': {
533+
'component': React.lazy(() => import('demo/styled/commandmenu/with-scrollarea-demo')),
534+
'filePath': 'demo/styled/commandmenu/with-scrollarea-demo.tsx',
535+
},
528536
},
529537
'compare': {
530538
'basic-demo': {
Lines changed: 126 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,55 @@
11
'use client';
2+
import { ArrowDown, ArrowUp } from '@primeicons/react';
3+
import type { CommandMenuListInstance } from '@primereact/types/shared/commandmenu';
24
import { CommandMenu } from '@primereact/ui/commandmenu';
3-
import * as React from 'react';
4-
import { cmds } from './cmds';
55

6-
export default function BasicDemo() {
7-
const [search, setSearch] = React.useState('');
86

7+
export default function BasicDemo() {
98
return (
10-
<CommandMenu.Root>
11-
<div className="border-b border-surface-200 dark:border-surface-700/50 px-4 py-2">
12-
<CommandMenu.Input value={search} onValueChange={(val: string) => setSearch(val)} placeholder="Search for commands..." />
13-
</div>
9+
<CommandMenu.Root
10+
options={commands}
11+
optionLabel="label"
12+
optionValue="value"
13+
optionGroupLabel="group"
14+
optionGroupChildren="items"
15+
optionKeywords="keywords"
16+
className="mx-auto"
17+
>
18+
<CommandMenu.Header>
19+
<CommandMenu.Input placeholder="Search for commands..." />
20+
</CommandMenu.Header>
21+
<CommandMenu.Empty>No results found</CommandMenu.Empty>
1422
<CommandMenu.List>
15-
<CommandMenu.Empty>
16-
No results found for <span className="text-surface-900 dark:text-surface-0">&quot;{search}&quot;</span>
17-
</CommandMenu.Empty>
18-
{commands.map((group) => (
19-
<CommandMenu.Group key={group.group} value={group.group}>
20-
<CommandMenu.GroupHeading>{group.group}</CommandMenu.GroupHeading>
21-
{group.items.map((item, index) => (
22-
<CommandMenu.Item key={index} value={item.value}>
23-
<div className={`w-5 h-5 rounded-md ${item.color} flex items-center justify-center text-white`}>
24-
<i className={`pi ${item.icon} text-xs font-bold`} />
25-
</div>
26-
<span>{item.label}</span>
27-
<span className="opacity-50 ml-auto">{item.category}</span>
28-
</CommandMenu.Item>
29-
))}
30-
</CommandMenu.Group>
31-
))}
32-
<CommandMenu.Item value="test">Test</CommandMenu.Item>
23+
{({ commandmenu }: CommandMenuListInstance) =>
24+
((commandmenu?.filteredOptions ?? []) as typeof commands).map((group, gi) => (
25+
<CommandMenu.Group key={gi}>
26+
<CommandMenu.GroupHeader>{group.group}</CommandMenu.GroupHeader>
27+
{group.items.map((item, ii) => (
28+
<CommandMenu.Item key={ii} option={item}>
29+
{item.label}
30+
</CommandMenu.Item>
31+
))}
32+
</CommandMenu.Group>
33+
))
34+
}
3335
</CommandMenu.List>
36+
<CommandMenu.Footer className="justify-end">
37+
<span className="flex items-center gap-1 text-surface-500 text-xs">
38+
<kbd className="bg-surface-100 dark:bg-surface-800 size-5 inline-flex items-center justify-center rounded border border-surface-200 dark:border-surface-700">
39+
<ArrowUp />
40+
</kbd>
41+
<kbd className="bg-surface-100 dark:bg-surface-800 size-5 inline-flex items-center justify-center rounded border border-surface-200 dark:border-surface-700">
42+
<ArrowDown />
43+
</kbd>
44+
Navigate
45+
</span>
46+
<span className="flex items-center gap-1 text-surface-500 text-xs">
47+
<kbd className="bg-surface-100 dark:bg-surface-800 size-5 inline-flex items-center justify-center rounded border border-surface-200 dark:border-surface-700">
48+
49+
</kbd>
50+
Select
51+
</span>
52+
</CommandMenu.Footer>
3453
</CommandMenu.Root>
3554
);
3655
}
@@ -39,51 +58,87 @@ const commands = [
3958
{
4059
group: 'recents',
4160
items: [
42-
{
43-
icon: 'pi-refresh',
44-
label: 'Check For Updates',
45-
category: 'Command',
46-
color: 'bg-[linear-gradient(rgb(245,83,84),rgb(235,70,70))]',
47-
value: 'check for updates',
48-
keywords: ['check', 'updates']
49-
},
50-
{
51-
icon: 'pi-cog',
52-
label: 'Open Settings',
53-
category: 'Command',
54-
color: 'bg-[linear-gradient(rgb(96,165,250),rgb(59,130,246))]',
55-
value: 'open settings'
56-
},
57-
{
58-
icon: 'pi-search',
59-
label: 'Search Files',
60-
category: 'Command',
61-
color: 'bg-[linear-gradient(rgb(167,139,250),rgb(139,92,246))]',
62-
value: 'search files'
63-
},
64-
{
65-
icon: 'pi-terminal',
66-
label: 'Open Terminal',
67-
category: 'View',
68-
color: 'bg-[linear-gradient(rgb(148,163,184),rgb(100,116,139))]',
69-
value: 'open terminal'
70-
},
71-
{
72-
icon: 'pi-history',
73-
label: 'View History',
74-
category: 'View',
75-
color: 'bg-[linear-gradient(rgb(192,132,252),rgb(168,85,247))]',
76-
value: 'view history',
77-
keywords: ['history', 'recent']
78-
},
79-
{
80-
icon: 'pi-comments',
81-
label: 'Open Chat',
82-
category: 'Communication',
83-
color: 'bg-[linear-gradient(rgb(34,211,238),rgb(6,182,212))]',
84-
value: 'open chat'
85-
}
61+
{ label: 'Check For Updates', value: 'check for updates', keywords: ['check', 'updates'] },
62+
{ label: 'Open Settings', value: 'open settings' },
63+
{ label: 'Search Files', value: 'search files' },
64+
{ label: 'Open Terminal', value: 'open terminal' },
65+
{ label: 'View History', value: 'view history', keywords: ['history', 'recent'] },
66+
{ label: 'Open Chat', value: 'open chat' }
8667
]
8768
},
88-
...cmds
69+
{
70+
group: 'files',
71+
items: [
72+
{ label: 'New File', value: 'new file' },
73+
{ label: 'New Folder', value: 'new folder' },
74+
{ label: 'Save All', value: 'save-all' },
75+
{ label: 'Change Theme', value: 'change theme' },
76+
{ label: 'Run Task', value: 'run-task' },
77+
{ label: 'Stop Task', value: 'stop task' },
78+
{ label: 'Export Project', value: 'export project' },
79+
{ label: 'Import Project', value: 'import project' },
80+
{ label: 'Delete File', value: 'delete file' },
81+
{ label: 'Duplicate File', value: 'duplicate file' }
82+
]
83+
},
84+
{
85+
group: 'source',
86+
items: [
87+
{ label: 'Git: Commit', value: 'git commit' },
88+
{ label: 'Git: Push', value: 'git push' },
89+
{ label: 'Git: Pull', value: 'git pull' },
90+
{ label: 'Switch Account', value: 'switch account' },
91+
{ label: 'Open Documentation', value: 'open documentation' },
92+
{ label: 'Git: Sync', value: 'git sync' },
93+
{ label: 'Git: Create Branch', value: 'git create branch' },
94+
{ label: 'Git: Create Tag', value: 'git create tag' }
95+
]
96+
},
97+
{
98+
group: 'editor',
99+
items: [
100+
{ label: 'Align Left', value: 'align left' },
101+
{ label: 'Align Center', value: 'align center' },
102+
{ label: 'Align Right', value: 'align right' },
103+
{ label: 'Toggle Bold', value: 'toggle bold' },
104+
{ label: 'Toggle Italic', value: 'toggle italic' },
105+
{ label: 'Insert Link', value: 'insert link' },
106+
{ label: 'Insert Image', value: 'insert image' },
107+
{ label: 'Insert List', value: 'insert list' }
108+
]
109+
},
110+
{
111+
group: 'navigation',
112+
items: [
113+
{ label: 'Go to Home', value: 'go to home' },
114+
{ label: 'Go Back', value: 'go back' },
115+
{ label: 'Go Forward', value: 'go forward' },
116+
{ label: 'Open Explorer', value: 'open explorer' },
117+
{ label: 'View Bookmarks', value: 'view bookmarks' },
118+
{ label: 'Open Minimap', value: 'open minimap' }
119+
]
120+
},
121+
{
122+
group: 'view',
123+
items: [
124+
{ label: 'Toggle Preview', value: 'toggle preview' },
125+
{ label: 'Maximize Window', value: 'maximize window' },
126+
{ label: 'Minimize Window', value: 'minimize window' },
127+
{ label: 'Grid View', value: 'grid view' },
128+
{ label: 'List View', value: 'list view' },
129+
{ label: 'Light Mode', value: 'light mode' },
130+
{ label: 'Dark Mode', value: 'dark mode' }
131+
]
132+
},
133+
{
134+
group: 'tools',
135+
items: [
136+
{ label: 'Open Calculator', value: 'open calculator' },
137+
{ label: 'Open Calendar', value: 'open calendar' },
138+
{ label: 'Open Timer', value: 'open timer' },
139+
{ label: 'View Analytics', value: 'view analytics' },
140+
{ label: 'View Trends', value: 'view trends' },
141+
{ label: 'Open Database', value: 'open database' }
142+
]
143+
}
89144
];

0 commit comments

Comments
 (0)