123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- import {css, useTheme} from '@emotion/react';
- import classNames from 'classnames';
- import DeprecatedDropdownMenu from 'sentry/components/deprecatedDropdownMenu';
- import {IconChevron} from 'sentry/icons';
- import {Theme} from 'sentry/utils/theme';
- const getRootCss = (theme: Theme) => css`
- .dropdown-menu {
- & > li > a {
- color: ${theme.textColor};
- &:hover,
- &:focus {
- color: inherit;
- background-color: ${theme.hover};
- }
- }
- & .disabled {
- cursor: not-allowed;
- &:hover {
- background: inherit;
- color: inherit;
- }
- }
- }
- .dropdown-submenu:hover > span {
- color: ${theme.textColor};
- background: ${theme.hover};
- }
- `;
- // .dropdown-actor-title = flexbox to fix vertical alignment on firefox Need
- // the extra container because dropdown-menu alignment is off if
- // `dropdown-actor` is a flexbox
- type Props = Omit<
- Omit<DeprecatedDropdownMenu['props'], 'children'>,
- keyof typeof DeprecatedDropdownMenu.defaultProps
- > &
- Partial<typeof DeprecatedDropdownMenu.defaultProps> & {
- children: React.ReactNode;
- /**
- * Always render children of dropdown menu, this is included to support menu
- * items that open a confirm modal. Otherwise when dropdown menu hides, the
- * modal also gets unmounted
- */
- alwaysRenderMenu?: boolean;
- anchorMiddle?: boolean;
- /**
- * Anchors menu to the right
- */
- anchorRight?: boolean;
- /**
- * display dropdown caret
- */
- caret?: boolean;
- className?: string;
- customTitle?: React.ReactNode;
- disabled?: boolean;
- menuClasses?: string;
- title?: React.ReactNode;
- topLevelClasses?: string;
- };
- function DropdownLink({
- anchorMiddle,
- title,
- customTitle,
- children,
- menuClasses,
- className,
- topLevelClasses,
- anchorRight = false,
- disabled = false,
- caret = true,
- alwaysRenderMenu = true,
- ...otherProps
- }: Props) {
- const theme = useTheme();
- return (
- <DeprecatedDropdownMenu alwaysRenderMenu={alwaysRenderMenu} {...otherProps}>
- {({isOpen, getRootProps, getActorProps, getMenuProps}) => {
- const shouldRenderMenu = alwaysRenderMenu || isOpen;
- const cx = classNames('dropdown-actor', className, {
- 'dropdown-menu-right': anchorRight,
- 'dropdown-toggle': true,
- hover: isOpen,
- disabled,
- });
- const topLevelCx = classNames('dropdown', topLevelClasses, {
- 'pull-right': anchorRight,
- 'anchor-right': anchorRight,
- 'anchor-middle': anchorMiddle,
- open: isOpen,
- });
- const {onClick: onClickActor, ...actorProps} = getActorProps({
- className: cx,
- });
- return (
- <span
- css={getRootCss(theme)}
- {...getRootProps({
- className: topLevelCx,
- })}
- data-test-id="dropdown-link"
- >
- <a onClick={disabled ? undefined : onClickActor} {...actorProps}>
- {customTitle || (
- <div className="dropdown-actor-title">
- {title}
- {caret && <IconChevron direction={isOpen ? 'up' : 'down'} size="xs" />}
- </div>
- )}
- </a>
- {shouldRenderMenu && (
- <ul
- {...getMenuProps({
- className: classNames(menuClasses, 'dropdown-menu'),
- })}
- >
- {children}
- </ul>
- )}
- </span>
- );
- }}
- </DeprecatedDropdownMenu>
- );
- }
- export default DropdownLink;
|