diff --git a/react/ActionMenu/Readme.md b/react/ActionMenu/Readme.md index 7134425ad2..fe902651e8 100644 --- a/react/ActionMenu/Readme.md +++ b/react/ActionMenu/Readme.md @@ -74,3 +74,37 @@ const hideMenu = () => setState({ menuDisplayed: false }); } ``` + +### Placement + +The `placement` and `anchorElRef` prop can be used to control the placement of the menu on desktop. `anchorElRef` should be a ref to a DOM element and not a react component. + +``` +import ActionMenu, { ActionMenuItem } from 'cozy-ui/transpiled/react/ActionMenu'; +import Icon from 'cozy-ui/transpiled/react/Icon'; + +const testRef = React.createRef(); + +initialState = { menuDisplayed: isTesting() }; + +const showMenu = () => setState({ menuDisplayed: true }); +const hideMenu = () => setState({ menuDisplayed: false }); + +const anchorRef = React.createRef(); + +
+ + {state.menuDisplayed && + + }>Item 1 + } +
+``` + +### preventOverflow + +Set `preventOverflow` to `true` to keep the ActionMenu visible on desktop, even if `anchorElRef` is outside the viewport. diff --git a/react/ActionMenu/index.jsx b/react/ActionMenu/index.jsx index 33a26c869e..e7dba02499 100644 --- a/react/ActionMenu/index.jsx +++ b/react/ActionMenu/index.jsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useCallback } from 'react' import PropTypes from 'prop-types' import cx from 'classnames' import ClickAwayListener from '@material-ui/core/ClickAwayListener' @@ -6,29 +6,58 @@ import styles from './styles.styl' import { Media, Bd, Img } from '../Media' import BottomDrawer from '../BottomDrawer' import withBreakpoints from '../helpers/withBreakpoints' +import Popper from '@material-ui/core/Popper' -const ActionMenuWrapper = ({ inline, onClose, children }) => - inline ? ( - {children} +const ActionMenuWrapper = ({ + inline, + onClose, + anchorElRef, + placement, + preventOverflow, + children +}) => { + const getAnchorElement = useCallback(() => { + return anchorElRef.current + }, [anchorElRef]) + const normalOverflowModifiers = { + preventOverflow: { enabled: false }, + hide: { enabled: false } + } + + return inline ? ( + + {children} + ) : ( {children} ) +} const ActionMenu = ({ children, className, onClose, + placement, + preventOverflow, + anchorElRef, breakpoints: { isDesktop } }) => { const shouldDisplayInline = isDesktop + const containerRef = React.createRef() return ( -
- +
+
{ diff --git a/react/ActionMenu/styles.styl b/react/ActionMenu/styles.styl index ff10660612..37a263c627 100644 --- a/react/ActionMenu/styles.styl +++ b/react/ActionMenu/styles.styl @@ -6,9 +6,6 @@ .c-actionmenu--inline @extends $actionmenu--inline -.c-actionmenu-container - @extends $actionmenu-container - .c-actionmenu-header @extends $actionmenu-header diff --git a/react/BottomDrawer/styles.styl b/react/BottomDrawer/styles.styl index ebef19fb3f..dc9016446b 100644 --- a/react/BottomDrawer/styles.styl +++ b/react/BottomDrawer/styles.styl @@ -1,16 +1,17 @@ @require 'tools/mixins' @require 'settings/spaces' +@require 'settings/z-index' .with-transition transition transform .1s ease-out .BottomDrawer-content - z-index $file-action-menu + z-index $drawer-index position fixed bottom rem(9) bottom env(safe-area-inset-bottom) // @stylint ignore left 0 - width 'calc(100% - %s)' % rem(16) + width 'calc(100% - %s)' % (spacing_values.m * 2) margin 0 spacing_values.m padding-bottom rem(5) box-sizing border-box diff --git a/react/Menu/Readme.md b/react/Menu/Readme.md index 7a06da3278..071916a097 100644 --- a/react/Menu/Readme.md +++ b/react/Menu/Readme.md @@ -94,3 +94,12 @@ const showItem = item => { }
``` + +#### `position` and `popover` + +`ActionMenu` relies on the Material-UI (Popover)[https://v3.material-ui.com/utils/popper/] component to handle both `position` and `popover`. + +- `position='left'` is now `placement='bottom-start'`, and is still the default behavior. +- `position='right'` is now `placement='bottom-end'`. +- All other Popover.js placement options are also supported +- The Menu `popover` prop is now called `preventOverflow` diff --git a/react/__snapshots__/examples.spec.jsx.snap b/react/__snapshots__/examples.spec.jsx.snap index 680741141c..2aa8fa9c52 100644 --- a/react/__snapshots__/examples.spec.jsx.snap +++ b/react/__snapshots__/examples.spec.jsx.snap @@ -3,7 +3,7 @@ exports[`ActionMenu should render examples: ActionMenu 1`] = ` "
-
+
@@ -32,7 +32,7 @@ exports[`ActionMenu should render examples: ActionMenu 1`] = ` exports[`ActionMenu should render examples: ActionMenu 2`] = ` "
-
+
@@ -61,7 +61,24 @@ exports[`ActionMenu should render examples: ActionMenu 2`] = ` exports[`ActionMenu should render examples: ActionMenu 3`] = ` "
-
+
+
+
+
+ +
+
Item 1
+
+
+
+
+
" +`; + +exports[`ActionMenu should render examples: ActionMenu 4`] = ` +"
+
+
diff --git a/react/examples.spec.jsx b/react/examples.spec.jsx index f2ec5179ec..0291d8894a 100644 --- a/react/examples.spec.jsx +++ b/react/examples.spec.jsx @@ -1,6 +1,11 @@ import testFromStyleguidist from '../test/testFromStyleguidist' import path from 'path' +// Popper does not work well inside of jest as it heavily relies on DOM APIs (see https://github.com/popperjs/popper-core/issues/478). +jest.mock('@material-ui/core/Popper', () => { + return ({ children }) => children +}) + const makeRequire = subpath => m => { if (m.indexOf('.') === 0) { return require('./' + path.join(subpath, m)) diff --git a/stylus/components/action-menu.styl b/stylus/components/action-menu.styl index 1c3c338c7d..94ef7d5a24 100644 --- a/stylus/components/action-menu.styl +++ b/stylus/components/action-menu.styl @@ -1,9 +1,6 @@ @require './popover.styl' @require '../tools/mixins' -$actionmenu-container - position relative - $actionmenu @extend $popover @@ -11,9 +8,6 @@ $actionmenu margin-top 0 $actionmenu--inline - position absolute - bottom auto - left auto width auto min-width rem(220) diff --git a/stylus/settings/z-index.styl b/stylus/settings/z-index.styl index 3bffc6ee64..78e87d1bec 100644 --- a/stylus/settings/z-index.styl +++ b/stylus/settings/z-index.styl @@ -42,6 +42,7 @@ $bar-index = $nav-index + 1 // Not actually used, just as reference $selection-index = 30 $popover-index = 40 $overlay-index = 50 -$file-action-menu = 60 +$file-action-menu = 60 // replaced by $drawer-index +$drawer-index = 60 $modal-index = 70 $alert-index = 80