diff --git a/packages/decap-cms-core/src/components/Editor/__tests__/__snapshots__/EditorToolbar.spec.js.snap b/packages/decap-cms-core/src/components/Editor/__tests__/__snapshots__/EditorToolbar.spec.js.snap index 38f1aa359057..1c5888c4c395 100644 --- a/packages/decap-cms-core/src/components/Editor/__tests__/__snapshots__/EditorToolbar.spec.js.snap +++ b/packages/decap-cms-core/src/components/Editor/__tests__/__snapshots__/EditorToolbar.spec.js.snap @@ -106,6 +106,7 @@ exports[`EditorToolbar should render normal save button 1`] = ` -moz-user-select: none; -ms-user-select: none; user-select: none; + touch-action: manipulation; margin: 0 10px; } @@ -127,6 +128,7 @@ exports[`EditorToolbar should render normal save button 1`] = ` padding-left: 20px; padding-right: 40px; position: relative; + white-space: nowrap; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; @@ -245,15 +247,17 @@ exports[`EditorToolbar should render normal save button 1`] = `
- +
+ +
@@ -383,6 +387,7 @@ exports[`EditorToolbar should render normal save button 2`] = ` -moz-user-select: none; -ms-user-select: none; user-select: none; + touch-action: manipulation; margin: 0 10px; } @@ -404,6 +409,7 @@ exports[`EditorToolbar should render normal save button 2`] = ` padding-left: 20px; padding-right: 40px; position: relative; + white-space: nowrap; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; @@ -522,15 +528,17 @@ exports[`EditorToolbar should render normal save button 2`] = `
- +
+ +
@@ -927,6 +935,7 @@ exports[`EditorToolbar should render with status=draft,useOpenAuthoring=false 1` -moz-user-select: none; -ms-user-select: none; user-select: none; + touch-action: manipulation; margin: 0 10px; } @@ -948,6 +957,7 @@ exports[`EditorToolbar should render with status=draft,useOpenAuthoring=false 1` padding-left: 20px; padding-right: 40px; position: relative; + white-space: nowrap; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; @@ -1072,15 +1082,17 @@ exports[`EditorToolbar should render with status=draft,useOpenAuthoring=false 1`
- +
+ +
- +
+ +
+ * + * + * ); + */ +export function useDropDownCoords({ dropdownPosition = 'left', open } = {}) { + const [x, setX] = useState(0); + const [y, setY] = useState(0); + const viewport = useViewportRect(); + const source = useRef(/** @type {HTMLElement | null} */ (null)); + const dropdown = useRef(/** @type {HTMLElement | null} */ (null)); + + useLayoutEffect(() => { + if (!open || !viewport || !source.current || !dropdown.current) { + return; + } + + const { x, y } = getCoords({ + reference: source.current.getBoundingClientRect(), + target: dropdown.current.getBoundingClientRect(), + viewport, + dropdownPosition, + }); + + setX(x); + setY(y); + }, [dropdownPosition, source.current, dropdown.current, viewport, open]); + + return { refs: { source, dropdown }, coords: { x, y } }; +} diff --git a/packages/decap-cms-ui-default/src/Dropdown.js b/packages/decap-cms-ui-default/src/Dropdown.js index c64f4aad4d55..be3113b28819 100644 --- a/packages/decap-cms-ui-default/src/Dropdown.js +++ b/packages/decap-cms-ui-default/src/Dropdown.js @@ -1,9 +1,10 @@ -import React from 'react'; +import React, { useState } from 'react'; import PropTypes from 'prop-types'; import { css } from '@emotion/react'; import styled from '@emotion/styled'; import { Wrapper, Button as DropdownButton, Menu, MenuItem } from 'react-aria-menubutton'; +import { useDropDownCoords } from './DropDown/useDropDownCoords'; import { colors, buttons, components, zIndex } from './styles'; import Icon from './Icon'; @@ -11,6 +12,7 @@ const StyledWrapper = styled(Wrapper)` position: relative; font-size: 14px; user-select: none; + touch-action: manipulation; `; const StyledDropdownButton = styled(DropdownButton)` @@ -20,6 +22,7 @@ const StyledDropdownButton = styled(DropdownButton)` padding-left: 20px; padding-right: 40px; position: relative; + white-space: nowrap; &:after { ${components.caretDown}; @@ -44,8 +47,7 @@ const DropdownList = styled.ul` ${props => css` width: ${props.width}; top: ${props.top}; - left: ${props.position === 'left' ? 0 : 'auto'}; - right: ${props.position === 'right' ? 0 : 'auto'}; + left: ${props.left}; `}; `; @@ -91,15 +93,23 @@ function Dropdown({ className, children, }) { + const [open, setOpen] = useState(false); + const { coords, refs } = useDropDownCoords({ dropdownPosition, open }); return ( handler()} + onMenuToggle={({ isOpen }) => setOpen(isOpen)} className={className} > - {renderButton()} +
{renderButton()}
- + {children}