123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- import {Component} from 'react';
- import DropdownAutoCompleteMenu from 'sentry/components/dropdownAutoComplete/menu';
- import {Item} from 'sentry/components/dropdownAutoComplete/types';
- import Crumb from 'sentry/views/settings/components/settingsBreadcrumb/crumb';
- import Divider from 'sentry/views/settings/components/settingsBreadcrumb/divider';
- import {RouteWithName} from './types';
- const EXIT_DELAY = 0;
- interface AdditionalDropdownProps
- extends Pick<
- React.ComponentProps<typeof DropdownAutoCompleteMenu>,
- 'onChange' | 'busyItemsStillVisible'
- > {}
- export interface BreadcrumbDropdownProps extends AdditionalDropdownProps {
- items: Item[];
- name: React.ReactNode;
- onSelect: (item: Item) => void;
- route: RouteWithName;
- enterDelay?: number;
- hasMenu?: boolean;
- isLast?: boolean;
- }
- type State = {
- isOpen: boolean;
- };
- class BreadcrumbDropdown extends Component<BreadcrumbDropdownProps, State> {
- state: State = {
- isOpen: false,
- };
- componentWillUnmount() {
- window.clearTimeout(this.enteringTimeout);
- window.clearTimeout(this.leavingTimeout);
- }
- enteringTimeout: number | undefined = undefined;
- leavingTimeout: number | undefined = undefined;
- open = () => {
- this.setState({isOpen: true});
- };
- close = () => {
- this.setState({isOpen: false});
- };
- handleStateChange = () => {};
- // Adds a delay when mouse hovers on actor (in this case the breadcrumb)
- handleMouseEnterActor = () => {
- window.clearTimeout(this.leavingTimeout);
- window.clearTimeout(this.enteringTimeout);
- this.enteringTimeout = window.setTimeout(
- () => this.open(),
- this.props.enterDelay ?? 0
- );
- };
- // handles mouseEnter event on actor and menu, should clear the leaving timeout and keep menu open
- handleMouseEnter = () => {
- window.clearTimeout(this.leavingTimeout);
- window.clearTimeout(this.enteringTimeout);
- this.open();
- };
- // handles mouseLeave event on actor and menu, adds a timeout before updating state to account for
- // mouseLeave into
- handleMouseLeave = () => {
- window.clearTimeout(this.enteringTimeout);
- this.leavingTimeout = window.setTimeout(() => this.close(), EXIT_DELAY);
- };
- // Close immediately when actor is clicked clicked
- handleClickActor = () => {
- this.close();
- };
- // Close immediately when clicked outside
- handleClose = () => {
- this.close();
- };
- render() {
- const {hasMenu, route, isLast, name, items, onSelect, ...dropdownProps} = this.props;
- return (
- <DropdownAutoCompleteMenu
- blendCorner={false}
- onOpen={this.handleMouseEnter}
- onClose={this.close}
- isOpen={this.state.isOpen}
- menuProps={{
- onMouseEnter: this.handleMouseEnter,
- onMouseLeave: this.handleMouseLeave,
- }}
- items={items}
- onSelect={onSelect}
- virtualizedHeight={41}
- {...dropdownProps}
- >
- {({getActorProps, actions, isOpen}) => (
- <Crumb
- {...getActorProps({
- onClick: this.handleClickActor.bind(this, actions),
- onMouseEnter: this.handleMouseEnterActor.bind(this, actions),
- onMouseLeave: this.handleMouseLeave.bind(this, actions),
- })}
- >
- <span>{name || route.name} </span>
- <Divider isHover={hasMenu && isOpen} isLast={isLast} />
- </Crumb>
- )}
- </DropdownAutoCompleteMenu>
- );
- }
- }
- export default BreadcrumbDropdown;
|