@zendeskgarden/react-dropdowns
Version:
Components related to dropdowns in the Garden Design System
131 lines (128 loc) • 3.74 kB
JavaScript
/**
* Copyright Zendesk, Inc.
*
* Use of this source code is governed under the Apache License, Version 2.0
* found at http://www.apache.org/licenses/LICENSE-2.0.
*/
import React__default, { forwardRef, useRef, useContext, useMemo } from 'react';
import PropTypes from 'prop-types';
import { mergeRefs } from 'react-merge-refs';
import { ThemeContext } from 'styled-components';
import { useMenu } from '@zendeskgarden/container-menu';
import { DEFAULT_THEME, useWindow } from '@zendeskgarden/react-theming';
import { Button } from '@zendeskgarden/react-buttons';
import { PLACEMENT } from '../../types/index.js';
import { MenuContext } from '../../context/useMenuContext.js';
import { toItems } from './utils.js';
import { MenuList } from './MenuList.js';
import SvgChevronDownStroke from '../../node_modules/@zendeskgarden/svg-icons/src/16/chevron-down-stroke.svg.js';
const Menu = forwardRef((_ref2, ref) => {
let {
button,
buttonProps: _buttonProps = {},
children,
isCompact,
focusedValue: _focusedValue,
defaultFocusedValue,
defaultExpanded,
isExpanded: _isExpanded,
restoreFocus,
selectedItems,
onChange,
onMouseLeave,
...props
} = _ref2;
const triggerRef = useRef(null);
const menuRef = useRef(null);
const items = toItems(children);
const theme = useContext(ThemeContext) || DEFAULT_THEME;
const environment = useWindow(theme);
const {
isExpanded,
focusedValue,
getTriggerProps,
getMenuProps,
getItemProps,
getItemGroupProps,
getSeparatorProps
} = useMenu({
rtl: theme.rtl,
environment,
defaultFocusedValue,
focusedValue: _focusedValue,
defaultExpanded,
isExpanded: _isExpanded,
restoreFocus,
selectedItems,
items,
menuRef,
triggerRef,
onChange
});
const {
onClick,
onKeyDown,
disabled,
ref: _ref,
...buttonProps
} = _buttonProps;
const triggerProps = {
...(isCompact && {
size: 'small'
}),
...buttonProps,
...getTriggerProps({
type: 'button',
onClick,
onKeyDown,
disabled
}),
ref: mergeRefs([triggerRef, _ref])
};
const trigger = typeof button === 'function' ? button(triggerProps) : React__default.createElement(Button, triggerProps, button, React__default.createElement(Button.EndIcon, {
isRotated: isExpanded
}, React__default.createElement(SvgChevronDownStroke, null)));
const contextValue = useMemo(() => ({
isCompact,
focusedValue,
getItemProps,
getItemGroupProps,
getSeparatorProps
}), [isCompact, focusedValue, getItemProps, getItemGroupProps, getSeparatorProps]);
return React__default.createElement(MenuContext.Provider, {
value: contextValue
}, trigger, React__default.createElement(MenuList, Object.assign({}, props, getMenuProps({
onMouseLeave
}), {
ref: mergeRefs([menuRef, ref]),
isCompact: isCompact,
isExpanded: isExpanded,
triggerRef: triggerRef
}), children));
});
Menu.displayName = 'Menu';
Menu.propTypes = {
appendToNode: PropTypes.any,
button: PropTypes.any.isRequired,
buttonProps: PropTypes.object,
defaultExpanded: PropTypes.bool,
defaultFocusedValue: PropTypes.string,
fallbackPlacements: PropTypes.arrayOf(PropTypes.any),
focusedValue: PropTypes.string,
hasArrow: PropTypes.bool,
isCompact: PropTypes.bool,
isExpanded: PropTypes.bool,
maxHeight: PropTypes.string,
minHeight: PropTypes.string,
onChange: PropTypes.func,
placement: PropTypes.oneOf(PLACEMENT),
restoreFocus: PropTypes.bool,
selectedItems: PropTypes.arrayOf(PropTypes.any),
zIndex: PropTypes.number
};
Menu.defaultProps = {
maxHeight: '400px',
placement: 'bottom-start',
zIndex: 1000
};
export { Menu };