@@ -5,16 +5,20 @@ import {
55 Item ,
66 ItemIndicator ,
77 Label ,
8+ Portal ,
89 RadioGroup ,
910 RadioItem ,
1011 Root ,
1112 Separator ,
13+ Sub ,
14+ SubContent ,
15+ SubTrigger ,
1216 Trigger ,
13- TriggerItem ,
1417} from '@radix-ui/react-dropdown-menu'
1518import React , { ComponentProps , ElementRef , forwardRef } from 'react'
1619import type { CSSProps } from '../../stitches.config'
1720import { styled } from '../../stitches.config'
21+ import { ConditionalWrapper } from '../../utils'
1822import {
1923 checkboxItemStyles ,
2024 contentStyles ,
@@ -25,7 +29,7 @@ import {
2529 labelStyles ,
2630 separatorStyles ,
2731 StyledCheckIndicator ,
28- StyledTriggerItemIndicator ,
32+ StyledSubTriggerIndicator ,
2933 triggerItemStyles ,
3034} from '../../utils/menuStyles'
3135import { Button } from '../Button'
@@ -55,32 +59,27 @@ const StyledContent = styled(Content, paperStyles, contentStyles)
5559const StyledItemIndicator = styled ( ItemIndicator , itemIndicatorStyles )
5660const StyledCheckboxItem = styled ( CheckboxItem , itemStyles , checkboxItemStyles )
5761const StyledRadioItem = styled ( RadioItem , itemStyles , checkboxItemStyles )
58- const StyledTriggerItem = styled ( TriggerItem , itemStyles , triggerItemStyles )
5962
60- type MenuTriggerItemProps = ComponentProps < typeof TriggerItem > & CSSProps
61-
62- export const MenuTriggerItem = forwardRef <
63- ElementRef < typeof StyledTriggerItem > ,
64- MenuTriggerItemProps
65- > ( ( { children, ...props } , forwardedRef ) => {
66- return (
67- < StyledTriggerItem { ...props } ref = { forwardedRef } >
68- { children }
69- < StyledTriggerItemIndicator />
70- </ StyledTriggerItem >
71- )
72- } )
73- MenuTriggerItem . toString = ( ) => `.${ StyledTriggerItem . className } `
74-
75- type MenuContentProps = ComponentProps < typeof Content > & CSSProps
63+ type MenuContentProps = ComponentProps < typeof Content > &
64+ CSSProps & {
65+ /** By default, portals your content parts into the body, set false to add at dom location. */
66+ portalled ?: boolean
67+ /** Specify a container element to portal the content into. */
68+ container ?: ComponentProps < typeof Portal > [ 'container' ]
69+ }
7670
7771export const MenuContent = forwardRef <
7872 ElementRef < typeof StyledContent > ,
7973 MenuContentProps
80- > ( ( { children, ...props } , forwardedRef ) => (
81- < StyledContent alignOffset = { 8 } { ...props } ref = { forwardedRef } >
82- { children }
83- </ StyledContent >
74+ > ( ( { portalled = true , container, children, ...props } , forwardedRef ) => (
75+ < ConditionalWrapper
76+ condition = { portalled }
77+ wrapper = { ( child ) => < Portal container = { container } > { child } </ Portal > }
78+ >
79+ < StyledContent alignOffset = { 8 } { ...props } ref = { forwardedRef } >
80+ { children }
81+ </ StyledContent >
82+ </ ConditionalWrapper >
8483) )
8584MenuContent . toString = ( ) => `.${ StyledContent . className } `
8685
@@ -164,3 +163,47 @@ export const MenuRadioItem = forwardRef<
164163 </ StyledRadioItem >
165164) )
166165MenuRadioItem . toString = ( ) => `.${ StyledRadioItem . className } `
166+
167+ // Sub menu
168+
169+ export const MenuSub = Sub
170+ const StyledSubTrigger = styled ( SubTrigger , itemStyles , triggerItemStyles )
171+ const StyledSubContent = styled ( SubContent , paperStyles , contentStyles )
172+
173+ type MenuSubTriggerProps = ComponentProps < typeof StyledSubTrigger > & CSSProps
174+
175+ export const MenuSubTrigger = forwardRef <
176+ ElementRef < typeof StyledSubTrigger > ,
177+ MenuSubTriggerProps
178+ > ( ( { children, ...props } , forwardedRef ) => {
179+ return (
180+ < StyledSubTrigger { ...props } ref = { forwardedRef } >
181+ { children }
182+ < StyledSubTriggerIndicator />
183+ </ StyledSubTrigger >
184+ )
185+ } )
186+ MenuSubTrigger . toString = ( ) => `.${ StyledSubTrigger . className } `
187+
188+ type MenuSubContentProps = ComponentProps < typeof StyledSubContent > &
189+ CSSProps & {
190+ /** By default, portals your content parts into the body, set false to add at dom location. */
191+ portalled ?: boolean
192+ /** Specify a container element to portal the content into. */
193+ container ?: ComponentProps < typeof Portal > [ 'container' ]
194+ }
195+
196+ export const MenuSubContent = forwardRef <
197+ ElementRef < typeof StyledSubContent > ,
198+ MenuSubContentProps
199+ > ( ( { container, portalled = true , children, ...props } , forwardedRef ) => (
200+ < ConditionalWrapper
201+ condition = { portalled }
202+ wrapper = { ( child ) => < Portal container = { container } > { child } </ Portal > }
203+ >
204+ < StyledSubContent { ...props } ref = { forwardedRef } >
205+ { children }
206+ </ StyledSubContent >
207+ </ ConditionalWrapper >
208+ ) )
209+ MenuSubContent . toString = ( ) => `.${ StyledSubContent . className } `
0 commit comments