Skip to content

Commit

Permalink
Merge pull request #1252 from VEuPathDB/orthogroup-tree-table__protei…
Browse files Browse the repository at this point in the history
…n-filter

Orthogroup tree table  protein filter
  • Loading branch information
bobular authored Oct 31, 2024
2 parents 8b024bc + 2520735 commit 07a9a6d
Show file tree
Hide file tree
Showing 2 changed files with 324 additions and 161 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { ReactNode, useState, useEffect, useMemo } from 'react';
import {
ReactNode,
useState,
useEffect,
useMemo,
forwardRef,
useImperativeHandle,
} from 'react';
import { Popover } from '@material-ui/core';
import SwissArmyButton from '../SwissArmyButton';
import { gray } from '../../../definitions/colors';
Expand Down Expand Up @@ -66,6 +73,11 @@ const defaultStyle: ButtonStyleSpec = {
},
};

export interface PopoverButtonHandle {
/** Closes the popover */
close: () => void;
}

export interface PopoverButtonProps {
/** Contents of the menu when opened */
children: ReactNode;
Expand All @@ -87,86 +99,96 @@ export interface PopoverButtonProps {
/**
* Renders a button that display `children` in a popover widget.
*/
export default function PopoverButton(props: PopoverButtonProps) {
const {
children,
buttonDisplayContent,
onClose,
setIsPopoverOpen,
isDisabled = false,
styleOverrides = {},
} = props;
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);

const finalStyle = useMemo(
() => merge({}, defaultStyle, styleOverrides),
[styleOverrides]
);

const onCloseHandler = () => {
setAnchorEl(null);
onClose && onClose();
};

useEffect(() => {
if (!setIsPopoverOpen) return;
if (anchorEl) {
setIsPopoverOpen(true);
} else {
setIsPopoverOpen(false);
}
}, [anchorEl, setIsPopoverOpen]);

const menu = (
<Popover
id="dropdown"
aria-expanded={!!anchorEl}
open={Boolean(anchorEl)}
onClose={onCloseHandler}
anchorEl={anchorEl}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
keepMounted
>
{children}
</Popover>
);

const button = (
<SwissArmyButton
text={buttonDisplayContent}
textTransform="none"
onPress={(event) => setAnchorEl(event.currentTarget)}
disabled={isDisabled}
styleSpec={finalStyle}
icon={ArrowDown}
iconPosition="right"
additionalAriaProperties={{
'aria-controls': 'dropdown',
'aria-haspopup': 'true',
}}
/>
);

return (
<div
style={{
width: 'fit-content',
...(isDisabled ? { cursor: 'not-allowed' } : {}),
}}
onClick={(event) => {
// prevent click event from propagating to ancestor nodes
event.stopPropagation();
}}
>
{button}
{menu}
</div>
);
}

const PopoverButton = forwardRef<PopoverButtonHandle, PopoverButtonProps>(
function PopoverButton(props, ref) {
const {
children,
buttonDisplayContent,
onClose,
setIsPopoverOpen,
isDisabled = false,
styleOverrides = {},
} = props;
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);

const finalStyle = useMemo(
() => merge({}, defaultStyle, styleOverrides),
[styleOverrides]
);

const onCloseHandler = () => {
setAnchorEl(null);
onClose && onClose();
};

// Expose the `close()` method to external components via ref
useImperativeHandle(ref, () => ({
close: onCloseHandler,
}));

useEffect(() => {
if (!setIsPopoverOpen) return;
if (anchorEl) {
setIsPopoverOpen(true);
} else {
setIsPopoverOpen(false);
}
}, [anchorEl, setIsPopoverOpen]);

const menu = (
<Popover
id="dropdown"
aria-expanded={!!anchorEl}
open={Boolean(anchorEl)}
onClose={onCloseHandler}
anchorEl={anchorEl}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
keepMounted
>
{children}
</Popover>
);

const button = (
<SwissArmyButton
text={buttonDisplayContent}
textTransform="none"
onPress={(event) => setAnchorEl(event.currentTarget)}
disabled={isDisabled}
styleSpec={finalStyle}
icon={ArrowDown}
iconPosition="right"
additionalAriaProperties={{
'aria-controls': 'dropdown',
'aria-haspopup': 'true',
}}
/>
);

return (
<div
style={{
width: 'fit-content',
...(isDisabled ? { cursor: 'not-allowed' } : {}),
}}
onClick={(event) => {
// prevent click event from propagating to ancestor nodes
event.stopPropagation();
}}
>
{button}
{menu}
</div>
);
}
);

export default PopoverButton;
Loading

0 comments on commit 07a9a6d

Please sign in to comment.