Skip to content

Commit 06e668f

Browse files
committed
Re-export of Menu
1 parent 98c3e83 commit 06e668f

File tree

13 files changed

+450
-83
lines changed

13 files changed

+450
-83
lines changed

docs/reference/generated/context-menu-root.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ContextMenuRoot",
3-
"description": "A component that creates a context menu activated by right clicking or long pressing.\nWraps the `Menu` component to provide context menu functionality.\nDoesn’t render its own HTML element.",
3+
"description": "A component that creates a context menu activated by right clicking or long pressing.\nDoesn’t render its own HTML element.",
44
"props": {},
55
"dataAttributes": {},
66
"cssVariables": {}
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import * as React from 'react';
22
import { ContextMenu } from '@base-ui-components/react/context-menu';
3-
import { Menu } from '@base-ui-components/react/menu';
43
import styles from './index.module.css';
54

65
export default function ExampleMenu() {
@@ -9,26 +8,28 @@ export default function ExampleMenu() {
98
<ContextMenu.Trigger className={styles.Trigger}>
109
Right click here
1110
</ContextMenu.Trigger>
12-
<Menu.Root>
13-
<Menu.Portal>
14-
<Menu.Positioner
15-
className={styles.Positioner}
16-
align="start"
17-
alignOffset={5}
18-
>
19-
<Menu.Popup className={styles.Popup}>
20-
<Menu.Item className={styles.Item}>Add to Library</Menu.Item>
21-
<Menu.Item className={styles.Item}>Add to Playlist</Menu.Item>
22-
<Menu.Separator className={styles.Separator} />
23-
<Menu.Item className={styles.Item}>Play Next</Menu.Item>
24-
<Menu.Item className={styles.Item}>Play Last</Menu.Item>
25-
<Menu.Separator className={styles.Separator} />
26-
<Menu.Item className={styles.Item}>Favorite</Menu.Item>
27-
<Menu.Item className={styles.Item}>Share</Menu.Item>
28-
</Menu.Popup>
29-
</Menu.Positioner>
30-
</Menu.Portal>
31-
</Menu.Root>
11+
<ContextMenu.Portal>
12+
<ContextMenu.Positioner
13+
className={styles.Positioner}
14+
align="start"
15+
alignOffset={5}
16+
>
17+
<ContextMenu.Popup className={styles.Popup}>
18+
<ContextMenu.Item className={styles.Item}>
19+
Add to Library
20+
</ContextMenu.Item>
21+
<ContextMenu.Item className={styles.Item}>
22+
Add to Playlist
23+
</ContextMenu.Item>
24+
<ContextMenu.Separator className={styles.Separator} />
25+
<ContextMenu.Item className={styles.Item}>Play Next</ContextMenu.Item>
26+
<ContextMenu.Item className={styles.Item}>Play Last</ContextMenu.Item>
27+
<ContextMenu.Separator className={styles.Separator} />
28+
<ContextMenu.Item className={styles.Item}>Favorite</ContextMenu.Item>
29+
<ContextMenu.Item className={styles.Item}>Share</ContextMenu.Item>
30+
</ContextMenu.Popup>
31+
</ContextMenu.Positioner>
32+
</ContextMenu.Portal>
3233
</ContextMenu.Root>
3334
);
3435
}
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,42 @@
11
import * as React from 'react';
2-
import { Menu } from '@base-ui-components/react/menu';
32
import { ContextMenu } from '@base-ui-components/react/context-menu';
43

54
export default function ExampleMenu() {
65
return (
76
<ContextMenu.Root>
8-
<Menu.Root>
9-
<ContextMenu.Trigger className="flex h-[12rem] w-[15rem] items-center justify-center rounded border border-gray-300 text-gray-900 select-none">
10-
Right click here
11-
</ContextMenu.Trigger>
12-
<Menu.Portal>
13-
<Menu.Positioner className="outline-none" align="start" alignOffset={5}>
14-
<Menu.Popup className="origin-[var(--transform-origin)] rounded-md bg-[canvas] py-1 text-gray-900 shadow-lg shadow-gray-200 outline outline-1 outline-gray-200 transition-[opacity] data-[ending-style]:opacity-0 dark:shadow-none dark:-outline-offset-1 dark:outline-gray-300">
15-
<Menu.Item className="flex cursor-default py-2 pr-8 pl-4 text-sm leading-4 outline-none select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-gray-50 data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:z-[-1] data-[highlighted]:before:rounded-sm data-[highlighted]:before:bg-gray-900">
16-
Add to Library
17-
</Menu.Item>
18-
<Menu.Item className="flex cursor-default py-2 pr-8 pl-4 text-sm leading-4 outline-none select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-gray-50 data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:z-[-1] data-[highlighted]:before:rounded-sm data-[highlighted]:before:bg-gray-900">
19-
Add to Playlist
20-
</Menu.Item>
21-
<Menu.Separator className="mx-4 my-1.5 h-px bg-gray-200" />
22-
<Menu.Item className="flex cursor-default py-2 pr-8 pl-4 text-sm leading-4 outline-none select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-gray-50 data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:z-[-1] data-[highlighted]:before:rounded-sm data-[highlighted]:before:bg-gray-900">
23-
Play Next
24-
</Menu.Item>
25-
<Menu.Item className="flex cursor-default py-2 pr-8 pl-4 text-sm leading-4 outline-none select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-gray-50 data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:z-[-1] data-[highlighted]:before:rounded-sm data-[highlighted]:before:bg-gray-900">
26-
Play Last
27-
</Menu.Item>
28-
<Menu.Separator className="mx-4 my-1.5 h-px bg-gray-200" />
29-
<Menu.Item className="flex cursor-default py-2 pr-8 pl-4 text-sm leading-4 outline-none select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-gray-50 data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:z-[-1] data-[highlighted]:before:rounded-sm data-[highlighted]:before:bg-gray-900">
30-
Favorite
31-
</Menu.Item>
32-
<Menu.Item className="flex cursor-default py-2 pr-8 pl-4 text-sm leading-4 outline-none select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-gray-50 data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:z-[-1] data-[highlighted]:before:rounded-sm data-[highlighted]:before:bg-gray-900">
33-
Share
34-
</Menu.Item>
35-
</Menu.Popup>
36-
</Menu.Positioner>
37-
</Menu.Portal>
38-
</Menu.Root>
7+
<ContextMenu.Trigger className="flex h-[12rem] w-[15rem] items-center justify-center rounded border border-gray-300 text-gray-900 select-none">
8+
Right click here
9+
</ContextMenu.Trigger>
10+
<ContextMenu.Portal>
11+
<ContextMenu.Positioner
12+
className="outline-none"
13+
align="start"
14+
alignOffset={5}
15+
>
16+
<ContextMenu.Popup className="origin-[var(--transform-origin)] rounded-md bg-[canvas] py-1 text-gray-900 shadow-lg shadow-gray-200 outline outline-1 outline-gray-200 transition-[opacity] data-[ending-style]:opacity-0 dark:shadow-none dark:-outline-offset-1 dark:outline-gray-300">
17+
<ContextMenu.Item className="flex cursor-default py-2 pr-8 pl-4 text-sm leading-4 outline-none select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-gray-50 data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:z-[-1] data-[highlighted]:before:rounded-sm data-[highlighted]:before:bg-gray-900">
18+
Add to Library
19+
</ContextMenu.Item>
20+
<ContextMenu.Item className="flex cursor-default py-2 pr-8 pl-4 text-sm leading-4 outline-none select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-gray-50 data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:z-[-1] data-[highlighted]:before:rounded-sm data-[highlighted]:before:bg-gray-900">
21+
Add to Playlist
22+
</ContextMenu.Item>
23+
<ContextMenu.Separator className="mx-4 my-1.5 h-px bg-gray-200" />
24+
<ContextMenu.Item className="flex cursor-default py-2 pr-8 pl-4 text-sm leading-4 outline-none select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-gray-50 data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:z-[-1] data-[highlighted]:before:rounded-sm data-[highlighted]:before:bg-gray-900">
25+
Play Next
26+
</ContextMenu.Item>
27+
<ContextMenu.Item className="flex cursor-default py-2 pr-8 pl-4 text-sm leading-4 outline-none select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-gray-50 data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:z-[-1] data-[highlighted]:before:rounded-sm data-[highlighted]:before:bg-gray-900">
28+
Play Last
29+
</ContextMenu.Item>
30+
<ContextMenu.Separator className="mx-4 my-1.5 h-px bg-gray-200" />
31+
<ContextMenu.Item className="flex cursor-default py-2 pr-8 pl-4 text-sm leading-4 outline-none select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-gray-50 data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:z-[-1] data-[highlighted]:before:rounded-sm data-[highlighted]:before:bg-gray-900">
32+
Favorite
33+
</ContextMenu.Item>
34+
<ContextMenu.Item className="flex cursor-default py-2 pr-8 pl-4 text-sm leading-4 outline-none select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-gray-50 data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:z-[-1] data-[highlighted]:before:rounded-sm data-[highlighted]:before:bg-gray-900">
35+
Share
36+
</ContextMenu.Item>
37+
</ContextMenu.Popup>
38+
</ContextMenu.Positioner>
39+
</ContextMenu.Portal>
3940
</ContextMenu.Root>
4041
);
4142
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
.Trigger {
2+
box-sizing: border-box;
3+
display: flex;
4+
align-items: center;
5+
justify-content: center;
6+
width: 15rem;
7+
height: 12rem;
8+
border: 1px solid var(--color-gray-300);
9+
color: var(--color-gray-900);
10+
border-radius: 0.375rem;
11+
-webkit-user-select: none;
12+
user-select: none;
13+
}
14+
15+
.Positioner {
16+
outline: 0;
17+
}
18+
19+
.Popup {
20+
box-sizing: border-box;
21+
padding-block: 0.25rem;
22+
border-radius: 0.375rem;
23+
background-color: canvas;
24+
color: var(--color-gray-900);
25+
transform-origin: var(--transform-origin);
26+
transition:
27+
transform 150ms,
28+
opacity 150ms;
29+
30+
&[data-ending-style] {
31+
opacity: 0;
32+
}
33+
34+
@media (prefers-color-scheme: light) {
35+
outline: 1px solid var(--color-gray-200);
36+
box-shadow:
37+
0 10px 15px -3px var(--color-gray-200),
38+
0 4px 6px -4px var(--color-gray-200);
39+
}
40+
41+
@media (prefers-color-scheme: dark) {
42+
outline: 1px solid var(--color-gray-300);
43+
outline-offset: -1px;
44+
}
45+
}
46+
47+
.Arrow {
48+
display: flex;
49+
50+
&[data-side='top'] {
51+
bottom: -8px;
52+
rotate: 180deg;
53+
}
54+
55+
&[data-side='bottom'] {
56+
top: -8px;
57+
rotate: 0deg;
58+
}
59+
60+
&[data-side='left'] {
61+
right: -13px;
62+
rotate: 90deg;
63+
}
64+
65+
&[data-side='right'] {
66+
left: -13px;
67+
rotate: -90deg;
68+
}
69+
}
70+
71+
.ArrowFill {
72+
fill: canvas;
73+
}
74+
75+
.ArrowOuterStroke {
76+
@media (prefers-color-scheme: light) {
77+
fill: var(--color-gray-200);
78+
}
79+
}
80+
81+
.ArrowInnerStroke {
82+
@media (prefers-color-scheme: dark) {
83+
fill: var(--color-gray-300);
84+
}
85+
}
86+
87+
.Item,
88+
.SubmenuTrigger {
89+
outline: 0;
90+
cursor: default;
91+
user-select: none;
92+
padding-block: 0.5rem;
93+
padding-left: 1rem;
94+
padding-right: 2rem;
95+
display: flex;
96+
font-size: 0.875rem;
97+
line-height: 1rem;
98+
99+
&[data-popup-open] {
100+
z-index: 0;
101+
position: relative;
102+
}
103+
104+
&[data-popup-open]::before {
105+
content: '';
106+
z-index: -1;
107+
position: absolute;
108+
inset-block: 0;
109+
inset-inline: 0.25rem;
110+
border-radius: 0.25rem;
111+
background-color: var(--color-gray-100);
112+
}
113+
114+
&[data-highlighted] {
115+
z-index: 0;
116+
position: relative;
117+
color: var(--color-gray-50);
118+
}
119+
120+
&[data-highlighted]::before {
121+
content: '';
122+
z-index: -1;
123+
position: absolute;
124+
inset-block: 0;
125+
inset-inline: 0.25rem;
126+
border-radius: 0.25rem;
127+
background-color: var(--color-gray-900);
128+
}
129+
}
130+
131+
.SubmenuTrigger {
132+
align-items: center;
133+
justify-content: space-between;
134+
gap: 1rem;
135+
padding-right: 1rem;
136+
}
137+
138+
.Separator {
139+
margin: 0.375rem 1rem;
140+
height: 1px;
141+
background-color: var(--color-gray-200);
142+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import * as React from 'react';
2+
import { ContextMenu } from '@base-ui-components/react/context-menu';
3+
import styles from './index.module.css';
4+
5+
export default function ExampleContextMenu() {
6+
return (
7+
<ContextMenu.Root>
8+
<ContextMenu.Trigger className={styles.Trigger}>
9+
Right click here
10+
</ContextMenu.Trigger>
11+
<ContextMenu.Portal>
12+
<ContextMenu.Positioner
13+
className={styles.Positioner}
14+
align="start"
15+
alignOffset={5}
16+
>
17+
<ContextMenu.Popup className={styles.Popup}>
18+
<ContextMenu.Item className={styles.Item}>
19+
Add to Library
20+
</ContextMenu.Item>
21+
22+
<ContextMenu.Root>
23+
<ContextMenu.SubmenuTrigger className={styles.SubmenuTrigger}>
24+
Add to Playlist
25+
<ChevronRightIcon />
26+
</ContextMenu.SubmenuTrigger>
27+
<ContextMenu.Portal>
28+
<ContextMenu.Positioner
29+
className={styles.Positioner}
30+
alignOffset={-4}
31+
sideOffset={-4}
32+
>
33+
<ContextMenu.Popup className={styles.Popup}>
34+
<ContextMenu.Item className={styles.Item}>
35+
Get Up!
36+
</ContextMenu.Item>
37+
<ContextMenu.Item className={styles.Item}>
38+
Inside Out
39+
</ContextMenu.Item>
40+
<ContextMenu.Item className={styles.Item}>
41+
Night Beats
42+
</ContextMenu.Item>
43+
<ContextMenu.Separator className={styles.Separator} />
44+
<ContextMenu.Item className={styles.Item}>
45+
New playlist…
46+
</ContextMenu.Item>
47+
</ContextMenu.Popup>
48+
</ContextMenu.Positioner>
49+
</ContextMenu.Portal>
50+
</ContextMenu.Root>
51+
52+
<ContextMenu.Separator className={styles.Separator} />
53+
<ContextMenu.Item className={styles.Item}>Play Next</ContextMenu.Item>
54+
<ContextMenu.Item className={styles.Item}>Play Last</ContextMenu.Item>
55+
<ContextMenu.Separator className={styles.Separator} />
56+
<ContextMenu.Item className={styles.Item}>Favorite</ContextMenu.Item>
57+
<ContextMenu.Item className={styles.Item}>Share</ContextMenu.Item>
58+
</ContextMenu.Popup>
59+
</ContextMenu.Positioner>
60+
</ContextMenu.Portal>
61+
</ContextMenu.Root>
62+
);
63+
}
64+
65+
function ChevronDownIcon(props: React.ComponentProps<'svg'>) {
66+
return (
67+
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" {...props}>
68+
<path d="M1 3.5L5 7.5L9 3.5" stroke="currentcolor" strokeWidth="1.5" />
69+
</svg>
70+
);
71+
}
72+
73+
function ChevronRightIcon(props: React.ComponentProps<'svg'>) {
74+
return (
75+
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" {...props}>
76+
<path d="M3.5 9L7.5 5L3.5 1" stroke="currentcolor" strokeWidth="1.5" />
77+
</svg>
78+
);
79+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
'use client';
2+
export { default as CssModules } from './css-modules';
3+
export { default as Tailwind } from './tailwind';

0 commit comments

Comments
 (0)