Skip to content

Commit

Permalink
feat(menu): allow to further customize className and styles of submenu
Browse files Browse the repository at this point in the history
Also increase the non popover popup z-index
  • Loading branch information
clementprevot committed Mar 14, 2024
1 parent 5987712 commit 3db8fbe
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 21 deletions.
41 changes: 31 additions & 10 deletions packages/fractal/src/components/Menu/Menu.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,16 +122,6 @@ export interface SubMenuProps
* `MenuItemSeparator` or `SubMenu`.
*/
children: ReactNode
/**
* Options to tweak the sub-menu content.
*
* You can on top of that add the `className` and `style` properties to
* customize the style of the sub-menu content.
*/
content?: {
className?: string
style?: CSSProperties
}
/** Indicates if the sub-menu should be opened by default. */
defaultOpen?: boolean
/** Indicates if the sub-menu is disabled. */
Expand Down Expand Up @@ -175,6 +165,37 @@ export interface SubMenuProps
* positioning" trick to display the sub-menu.
*/
popover?: boolean
/**
* Options to tweak the sub-menu popup, trigger and content.
*
* You can use the `className` and `style` properties to customize the style
* of the sub-menu popup, trigger (element and wrapper) and content (element,
* wrapper and positionner (in non popover mode)).
*/
popup?: {
className?: string
content?: {
className?: string
positionner?: {
className?: string
style?: CSSProperties
}
style?: CSSProperties
wrapper?: {
className?: string
style?: CSSProperties
}
}
style?: CSSProperties
trigger?: {
className?: string
style?: CSSProperties
wrapper: {
className?: string
style?: CSSProperties
}
}
}
/**
* The preferred side of the trigger (label) to render the popover.
*
Expand Down
45 changes: 34 additions & 11 deletions packages/fractal/src/components/Menu/SubMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ export const SubMenu = forwardRef<SubMenuCombinedRefs, SubMenuProps>(
active = false,
align = 'start',
children,
content,
defaultOpen = false,
disabled = false,
elevation = DEFAULT_SUB_MENU_ELEVATION,
Expand All @@ -55,6 +54,7 @@ export const SubMenu = forwardRef<SubMenuCombinedRefs, SubMenuProps>(
onSubMenuOpenChange,
open,
popover = true,
popup,
side,
triggerOnHover = true,
withIndicator = true,
Expand Down Expand Up @@ -184,7 +184,7 @@ export const SubMenu = forwardRef<SubMenuCombinedRefs, SubMenuProps>(
isDisabled
? `${PREFIX}-${GROUP_NAME}__sub-menu__trigger--disabled pointer-events-none cursor-not-allowed !bg-transparent text-disabled`
: 'cursor-pointer text-dark',
props.className,
popup?.trigger?.className,
)}
data-highlighted={active || isOpen || undefined}
element="div"
Expand All @@ -197,6 +197,7 @@ export const SubMenu = forwardRef<SubMenuCombinedRefs, SubMenuProps>(
: triggerOnHover
? { onMouseEnter: handleMouseEnter }
: {})}
style={popup?.trigger?.style}
onKeyDown={handleKeyDown}
>
{icon && (
Expand All @@ -212,6 +213,7 @@ export const SubMenu = forwardRef<SubMenuCombinedRefs, SubMenuProps>(
<Typography className="flex-1" element="label">
{label}
</Typography>

{withIndicator && (
<div
className={cj(
Expand Down Expand Up @@ -254,9 +256,9 @@ export const SubMenu = forwardRef<SubMenuCombinedRefs, SubMenuProps>(
!hasChildren
? `${PREFIX}-${GROUP_NAME}__sub-menu__content--empty invisible`
: '',
content?.className,
popup?.content?.className,
)}
{...omit(['className'], content)}
style={popup?.content?.style}
>
{withScroll ? (
<RxScrollArea.Root
Expand Down Expand Up @@ -308,34 +310,49 @@ export const SubMenu = forwardRef<SubMenuCombinedRefs, SubMenuProps>(
return !popover ? (
<div
ref={nonPopoverRef}
className={cj(
className={cn(
`${PREFIX}-${GROUP_NAME}__sub-menu__popup`,
`${PREFIX}-${GROUP_NAME}__sub-menu__popup--non-popover`,
'alternatee',
'relative rounded-sm outline-none transition-background-color duration-300 ease-out',
props.className,
popup?.className,
)}
style={{
...(props.style ?? {}),
...(popup?.style ?? {}),
}}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
{...omit(['className', 'style'], props)}
>
<div
className={`${PREFIX}-${GROUP_NAME}__sub-menu__popup__trigger-wrapper`}
className={cn(
`${PREFIX}-${GROUP_NAME}__sub-menu__popup__trigger-wrapper`,
popup?.trigger?.wrapper?.className,
)}
style={popup?.trigger?.wrapper?.style}
>
{trigger}
</div>

<div
className={cj(
className={cn(
`${PREFIX}-${GROUP_NAME}__sub-menu__popup__content-positionner`,
'absolute left-full top-0 z-50 pl-2',
'absolute left-full top-0 z-[5000] pl-2',
isOpen ? '' : 'hidden',
popup?.content?.positionner?.className,
)}
style={popup?.content?.positionner?.style}
>
<Paper
className={cj(
className={cn(
`${PREFIX}-${GROUP_NAME}__sub-menu__popup__content-wrapper`,
'p-0',
popup?.content?.wrapper?.className,
)}
elevation={elevation}
style={popup?.content?.wrapper?.style}
>
<div className={subMenuClassName}>{wrappedElement}</div>
</Paper>
Expand All @@ -344,17 +361,19 @@ export const SubMenu = forwardRef<SubMenuCombinedRefs, SubMenuProps>(
) : (
<Popover
align={align}
className={cj(
className={cn(
`${PREFIX}-${GROUP_NAME}__sub-menu__popup`,
`${PREFIX}-${GROUP_NAME}__sub-menu__popup--popover`,
'alternatee',
'rounded-sm',
props.className,
)}
disabled={disabled}
elevation={elevation}
fullWidth
popover={{
className: subMenuClassName,
style: popup?.style,
}}
side={
// eslint-disable-next-line no-nested-ternary
Expand All @@ -364,6 +383,10 @@ export const SubMenu = forwardRef<SubMenuCombinedRefs, SubMenuProps>(
? 'right'
: 'bottom'
}
style={{
...(props.style ?? {}),
...(popup?.style ?? {}),
}}
trigger={trigger}
withArrow={false}
withCloseButton={false}
Expand All @@ -374,8 +397,8 @@ export const SubMenu = forwardRef<SubMenuCombinedRefs, SubMenuProps>(
onOpenChange={handleOpenChange}
{...(defaultOpen ? { defaultOpen: true } : {})}
{...(disabled ? { open: false } : { open: isOpen })}
{...omit(['className'], props)}
onMouseLeave={handleMouseLeave}
{...omit(['className', 'style'], props)}
>
{wrappedElement}
</Popover>
Expand Down

0 comments on commit 3db8fbe

Please sign in to comment.