saleor-dashboard/src/components/CardMenu/CardMenu.tsx
Dominik Żegleń f8254fd11b
Bump macaw to 0.3 (#1807)
* Update to new design theme (#1631)

* Update macaw to 0.3.0 (#1623)

* Update macaw to 0.3

* Use proper pagination component

* Fix type errors

* Remove leftover import

* Remove variant and color from confirm button

* Remove alias

* Update macaw

* Fix button type

* Random fixes (#1633)

* Improve layout components

* Use colored svgs

* Minor fixes

* Fix autocomplete loaders

* Fix padding

* Fix button variant

* Remove codegen file

* Fixes after bumping macaw to 0.3 part 2 (#1638)

* Fix various visual bugs

* Fix type errors

* Bump macaw

* Random fixes part 3 (#1647)

* wip

* Fix mismatched paddings

* Fix actions container padding

* Put story in the right directory

* Fix shipping zone picker

* Fix minor visual bugs

* Remove unused imports

* Move styles to separate file

* Random fixes part 4 (#1641)

* Fix various visual bugs

* Fix type errors

* Fix last table item padding

* Add outline on hover

* Fix spaces

* Fix spaces

* Remove dead code

* Fix elevation

* Remove dead code

* Fix shadows

* Add outline to expand button

* Fix spacing

* Fix spacings

* Fix selectable tables hover

* Use proper delete icon

* Fix ConfirmButtonTransitionState imports

* Update src/apps/components/CustomApps/CustomApps.tsx

Co-authored-by: Wojciech Mista <wojciech.mista@saleor.io>

Co-authored-by: Wojciech Mista <wojciech.mista@saleor.io>

* Rework error page (#1670)

* Remake error page

* Fix types

* Update error id styles

* Fix types

* Login page rework (#1703)

* Rework login page

* Remove outline

* Fix logo and footer placement

* Sort imports

* Random fixes part 5 (#1669)

* Fix text color in dark mode

* Update password reset pages (#1714)

* Update password reset pages

* Update src/auth/components/ResetPasswordPage/ResetPasswordPage.tsx

Co-authored-by: Jakub Majorek <majorek.jakub@gmail.com>

Co-authored-by: Jakub Majorek <majorek.jakub@gmail.com>

* Fix collection page

* Update dark mode logo

* Bring back "create app" button

* Fix spacings

* Fix selects

* Fix login e2e test

* Fix not found page displaying

* Update selector

* Add missing package

* Let dropdown overflow through card

* Fix scroll

* Fix scroll

* Fix overflow on grid element

* Fix e2e tests

* Fix data-test-id

* Update snapshots

* Update messages

* Update macaw

* Update snapshots

* Use stable macaw version

Co-authored-by: Wojciech Mista <wojciech.mista@saleor.io>
Co-authored-by: Jakub Majorek <majorek.jakub@gmail.com>

* Update to new design theme (#1631)

* Update macaw to 0.3.0 (#1623)

* Update macaw to 0.3

* Use proper pagination component

* Fix type errors

* Remove leftover import

* Remove variant and color from confirm button

* Remove alias

* Update macaw

* Fix button type

* Random fixes (#1633)

* Improve layout components

* Use colored svgs

* Minor fixes

* Fix autocomplete loaders

* Fix padding

* Fix button variant

* Remove codegen file

* Fixes after bumping macaw to 0.3 part 2 (#1638)

* Fix various visual bugs

* Fix type errors

* Bump macaw

* Random fixes part 3 (#1647)

* wip

* Fix mismatched paddings

* Fix actions container padding

* Put story in the right directory

* Fix shipping zone picker

* Fix minor visual bugs

* Remove unused imports

* Move styles to separate file

* Random fixes part 4 (#1641)

* Fix various visual bugs

* Fix type errors

* Fix last table item padding

* Add outline on hover

* Fix spaces

* Fix spaces

* Remove dead code

* Fix elevation

* Remove dead code

* Fix shadows

* Add outline to expand button

* Fix spacing

* Fix spacings

* Fix selectable tables hover

* Use proper delete icon

* Fix ConfirmButtonTransitionState imports

* Update src/apps/components/CustomApps/CustomApps.tsx

Co-authored-by: Wojciech Mista <wojciech.mista@saleor.io>

Co-authored-by: Wojciech Mista <wojciech.mista@saleor.io>

* Rework error page (#1670)

* Remake error page

* Fix types

* Update error id styles

* Fix types

* Login page rework (#1703)

* Rework login page

* Remove outline

* Fix logo and footer placement

* Sort imports

* Random fixes part 5 (#1669)

* Fix text color in dark mode

* Update password reset pages (#1714)

* Update password reset pages

* Update src/auth/components/ResetPasswordPage/ResetPasswordPage.tsx

Co-authored-by: Jakub Majorek <majorek.jakub@gmail.com>

Co-authored-by: Jakub Majorek <majorek.jakub@gmail.com>

* Fix collection page

* Update dark mode logo

* Bring back "create app" button

* Fix spacings

* Fix selects

* Fix login e2e test

* Fix not found page displaying

* Update selector

* Add missing package

* Let dropdown overflow through card

* Fix scroll

* Fix scroll

* Fix overflow on grid element

* Fix e2e tests

* Fix data-test-id

* Update snapshots

* Update messages

* Update macaw

* Update snapshots

* Use stable macaw version

Co-authored-by: Wojciech Mista <wojciech.mista@saleor.io>
Co-authored-by: Jakub Majorek <majorek.jakub@gmail.com>

* Fix visual bugs and artifacts

* Fix dropdown menus being clipped (#1762)

* wip

* Fix clipped select menus

* Remove unused import

* Fix spacing

* Fix tests

* Fix select content appearing under dialogs (#1777)

* Fix type errors

* Fix bulk delete button placement

* Fix filter arrow buttons

* Fix messages

* Remove backling from pages list

* Move status above events

* Update messages and snapshots

Co-authored-by: Wojciech Mista <wojciech.mista@saleor.io>
Co-authored-by: Jakub Majorek <majorek.jakub@gmail.com>
2022-01-28 13:34:20 +01:00

198 lines
5.2 KiB
TypeScript

import {
CircularProgress,
ClickAwayListener,
Grow,
MenuItem,
MenuList,
Paper,
Popper,
Typography
} from "@material-ui/core";
import { IconButton, makeStyles, MoreIcon } from "@saleor/macaw-ui";
import classNames from "classnames";
import React, { useEffect, useRef, useState } from "react";
import { FormattedMessage } from "react-intl";
import { cardMenuMessages as messages } from "./messages";
const ITEM_HEIGHT = 48;
export interface CardMenuItem {
disabled?: boolean;
label: string;
testId?: string;
onSelect: () => void;
loading?: boolean;
withLoading?: boolean;
hasError?: boolean;
}
export interface CardMenuProps {
className?: string;
disabled?: boolean;
menuItems: CardMenuItem[];
outlined?: boolean;
}
const useStyles = makeStyles(
theme => ({
container: {
zIndex: 1
},
iconButton: {
background: theme.palette.background.paper,
borderRadius: "100%",
height: 32,
padding: 0,
width: 32
},
paper: {
marginTop: theme.spacing(2),
maxHeight: ITEM_HEIGHT * 4.5,
overflowY: "scroll"
},
loadingContent: {
width: "100%",
display: "grid",
gridTemplateColumns: "1fr 24px",
gap: theme.spacing(2),
alignItems: "center",
justifyContent: "flex-end"
}
}),
{ name: "CardMenu" }
);
const CardMenu: React.FC<CardMenuProps> = props => {
const { className, disabled, menuItems, outlined, ...rest } = props;
const classes = useStyles(props);
const anchorRef = useRef<HTMLButtonElement | null>(null);
const [open, setOpen] = useState(false);
const handleToggle = () => setOpen(prevOpen => !prevOpen);
const handleClose = (event: React.MouseEvent<EventTarget>) => {
if (
anchorRef.current &&
anchorRef.current.contains(event.target as HTMLElement)
) {
return;
}
setOpen(false);
};
const handleListKeyDown = (event: React.KeyboardEvent) => {
if (event.key === "Tab") {
event.preventDefault();
setOpen(false);
}
};
const prevOpen = useRef(open);
useEffect(() => {
if (prevOpen.current === true && open === false) {
anchorRef.current!.focus();
}
prevOpen.current = open;
}, [open]);
useEffect(() => {
const hasAnyItemsLoadingOrWithError = menuItems
?.filter(({ withLoading }) => withLoading)
?.some(({ loading, hasError }) => loading || hasError);
if (!hasAnyItemsLoadingOrWithError) {
setOpen(false);
}
}, [menuItems]);
const handleMenuClick = (index: number) => {
const selectedItem = menuItems[index];
selectedItem.onSelect();
if (!selectedItem.withLoading) {
setOpen(false);
}
};
const isWithLoading = menuItems.some(({ withLoading }) => withLoading);
return (
<div className={className} {...rest}>
<IconButton
data-test-id="showMoreButton"
aria-label="More"
aria-owns={open ? "long-menu" : null}
aria-haspopup="true"
color="primary"
disabled={disabled}
ref={anchorRef}
onClick={handleToggle}
variant={outlined ? "primary" : "secondary"}
>
<MoreIcon />
</IconButton>
<Popper
placement="bottom-end"
className={classes.container}
open={open}
anchorEl={anchorRef.current}
transition
>
{({ TransitionProps, placement }) => (
<Grow
{...TransitionProps}
style={{
transformOrigin:
placement === "bottom" ? "right top" : "right bottom",
overflowY: "auto"
}}
>
<Paper className={classes.paper} elevation={8}>
<ClickAwayListener onClickAway={handleClose}>
<MenuList
autoFocusItem={open}
id="menu-list-grow"
onKeyDown={handleListKeyDown}
>
{menuItems.map((menuItem, menuItemIndex) => (
<MenuItem
data-test-id={menuItem.testId}
disabled={menuItem.loading || menuItem.disabled}
onClick={() => handleMenuClick(menuItemIndex)}
key={menuItem.label}
data-test={menuItem.testId}
>
<div
className={classNames(className, {
[classes.loadingContent]: isWithLoading
})}
>
{menuItem.loading ? (
<>
<Typography variant="subtitle1">
<FormattedMessage
{...messages.cardMenuItemLoading}
/>
</Typography>
<CircularProgress size={24} />
</>
) : (
<Typography>{menuItem.label}</Typography>
)}
</div>
</MenuItem>
))}
</MenuList>
</ClickAwayListener>
</Paper>
</Grow>
)}
</Popper>
</div>
);
};
CardMenu.displayName = "CardMenu";
export default CardMenu;