Web:Components: remove new-context-menu and menu-item from components
This commit is contained in:
parent
c3b901c64a
commit
fab58673ab
@ -1,37 +0,0 @@
|
||||
# DropDownItem
|
||||
|
||||
Is a item of DropDown or ContextMenu component
|
||||
|
||||
### Usage
|
||||
|
||||
```js
|
||||
import MenuItem from "@appserver/components/menu-item";
|
||||
```
|
||||
|
||||
```jsx
|
||||
<MenuItem
|
||||
isSeparator={false}
|
||||
isHeader={false}
|
||||
label="Button 1"
|
||||
icon="static/images/nav.logo.react.svg"
|
||||
onClick={() => console.log("Button 1 clicked")}
|
||||
/>
|
||||
```
|
||||
|
||||
An item can act as separator, header, line, line with arrow or container.
|
||||
|
||||
When used as container, it will retain all styling features and positioning. To disable hover effects in container mode, you can use _noHover_ property.`
|
||||
|
||||
### Properties
|
||||
|
||||
| Props | Type | Required | Values | Default | Description |
|
||||
| ------------- | :------------: | :------: | :----: | :-------------: | ---------------------------------------------------------- |
|
||||
| `className` | `string` | - | - | - | Accepts class |
|
||||
| `id` | `string` | - | - | - | Accepts id |
|
||||
| `icon` | `string` | - | - | - | Dropdown item icon |
|
||||
| `label` | `string` | - | - | `Dropdown item` | Dropdown item text |
|
||||
| `isHeader` | `bool` | - | - | `false` | Tells when the dropdown item should display like header |
|
||||
| `isSeparator` | `bool` | - | - | `false` | Tells when the dropdown item should display like separator |
|
||||
| `noHover` | `bool` | - | - | `false` | Disable default style hover effect |
|
||||
| `onClick` | `func` | - | - | - | What the dropdown item will trigger when clicked |
|
||||
| `style` | `obj`, `array` | - | - | - | Accepts css style |
|
@ -1,167 +0,0 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { ReactSVG } from "react-svg";
|
||||
|
||||
import DomHelpers from "../utils/domHelpers";
|
||||
|
||||
import { isMobile } from "react-device-detect";
|
||||
import {
|
||||
isTablet as isTabletUtils,
|
||||
isMobile as isMobileUtils,
|
||||
} from "../utils/device";
|
||||
|
||||
import { StyledMenuItem, StyledText, IconWrapper } from "./styled-menu-item";
|
||||
|
||||
import ArrowIcon from "./svg/folder-arrow.react.svg";
|
||||
import ArrowMobileIcon from "./svg/folder-arrow.mobile.react.svg";
|
||||
import NewContextMenu from "../new-context-menu";
|
||||
|
||||
//TODO: Add arrow type
|
||||
const MenuItem = (props) => {
|
||||
const [hover, setHover] = React.useState(false);
|
||||
const [positionContextMenu, setPositionContextMenu] = React.useState(null);
|
||||
const itemRef = React.useRef(null);
|
||||
const cmRef = React.useRef(null);
|
||||
//console.log("MenuItem render");
|
||||
const {
|
||||
isHeader,
|
||||
isSeparator,
|
||||
label,
|
||||
icon,
|
||||
options,
|
||||
children,
|
||||
onClick,
|
||||
hideMenu,
|
||||
className,
|
||||
} = props;
|
||||
|
||||
const onHover = () => {
|
||||
if (!cmRef.current) return;
|
||||
if (hover) {
|
||||
getPosition();
|
||||
cmRef.current.show(new Event("click"));
|
||||
} else {
|
||||
cmRef.current.hide(new Event("click"));
|
||||
}
|
||||
};
|
||||
|
||||
const getPosition = () => {
|
||||
if (!cmRef.current) return;
|
||||
if (!itemRef.current) return;
|
||||
const outerWidth = DomHelpers.getOuterWidth(itemRef.current);
|
||||
const offset = DomHelpers.getOffset(itemRef.current);
|
||||
|
||||
setPositionContextMenu({
|
||||
top: offset.top,
|
||||
left: offset.left + outerWidth + 10,
|
||||
width: outerWidth,
|
||||
});
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
onHover();
|
||||
}, [hover]);
|
||||
|
||||
const onClickAction = (e) => {
|
||||
onClick && onClick(e);
|
||||
hideMenu && hideMenu();
|
||||
};
|
||||
|
||||
return options ? (
|
||||
<StyledMenuItem
|
||||
{...props}
|
||||
className={className}
|
||||
onClick={onClickAction}
|
||||
ref={itemRef}
|
||||
onMouseEnter={() => setHover(true)}
|
||||
onMouseLeave={() => setHover(false)}
|
||||
>
|
||||
{icon && (
|
||||
<IconWrapper isHeader={isHeader}>
|
||||
<ReactSVG src={icon} className="drop-down-item_icon" />
|
||||
</IconWrapper>
|
||||
)}
|
||||
{isSeparator ? (
|
||||
<></>
|
||||
) : label ? (
|
||||
<>
|
||||
<StyledText isHeader={isHeader} truncate={true}>
|
||||
{label}
|
||||
</StyledText>
|
||||
{isMobile || isTabletUtils() || isMobileUtils() ? (
|
||||
<ArrowMobileIcon className="arrow-icon" />
|
||||
) : (
|
||||
<ArrowIcon className="arrow-icon" />
|
||||
)}
|
||||
<NewContextMenu
|
||||
ref={cmRef}
|
||||
model={options}
|
||||
withBackdrop={false}
|
||||
position={positionContextMenu}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
children && children
|
||||
)}
|
||||
</StyledMenuItem>
|
||||
) : (
|
||||
<StyledMenuItem {...props} className={className} onClick={onClickAction}>
|
||||
{icon && (
|
||||
<IconWrapper isHeader={isHeader}>
|
||||
<ReactSVG src={icon} className="drop-down-item_icon" />
|
||||
</IconWrapper>
|
||||
)}
|
||||
{isSeparator ? (
|
||||
<></>
|
||||
) : label ? (
|
||||
<>
|
||||
<StyledText isHeader={isHeader} truncate={true}>
|
||||
{label}
|
||||
</StyledText>
|
||||
</>
|
||||
) : (
|
||||
children && children
|
||||
)}
|
||||
</StyledMenuItem>
|
||||
);
|
||||
};
|
||||
|
||||
MenuItem.propTypes = {
|
||||
/** Tells when the menu item should display like separator */
|
||||
isSeparator: PropTypes.bool,
|
||||
/** Tells when the menu item should display like header */
|
||||
isHeader: PropTypes.bool,
|
||||
/** Accepts tab-index */
|
||||
tabIndex: PropTypes.number,
|
||||
/** Menu item text */
|
||||
label: PropTypes.string,
|
||||
/** Menu item icon */
|
||||
icon: PropTypes.string,
|
||||
/** Tells when the menu item should display like arrow and open context menu */
|
||||
options: PropTypes.array,
|
||||
/** Disable default style hover effect */
|
||||
noHover: PropTypes.bool,
|
||||
/** What the menu item will trigger when clicked */
|
||||
onClick: PropTypes.func,
|
||||
/** Children elements */
|
||||
children: PropTypes.any,
|
||||
/** Accepts class */
|
||||
className: PropTypes.string,
|
||||
/** Accepts id */
|
||||
id: PropTypes.string,
|
||||
/** Accepts css style */
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
/** Accepts css text-overflow */
|
||||
textOverflow: PropTypes.bool,
|
||||
};
|
||||
|
||||
MenuItem.defaultProps = {
|
||||
isSeparator: false,
|
||||
isHeader: false,
|
||||
noHover: false,
|
||||
textOverflow: false,
|
||||
tabIndex: -1,
|
||||
label: "",
|
||||
};
|
||||
|
||||
export default MenuItem;
|
@ -1,70 +0,0 @@
|
||||
import React from "react";
|
||||
import MenuItem from ".";
|
||||
|
||||
export default {
|
||||
title: "Components/MenuItem",
|
||||
component: MenuItem,
|
||||
|
||||
argTypes: {
|
||||
onClick: { action: "onClick" },
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component: `Is a item of DropDown or ContextMenu component
|
||||
|
||||
An item can act as separator, header, line, line with arrow or container.
|
||||
|
||||
When used as container, it will retain all styling features and positioning. To disable hover effects in container mode, you can use _noHover_ property.`,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const Template = () => {
|
||||
return (
|
||||
<div style={{ width: "250px", position: "relative" }}>
|
||||
<MenuItem
|
||||
icon={"static/images/nav.logo.react.svg"}
|
||||
label="Header(tablet or mobile)"
|
||||
isHeader={true}
|
||||
onClick={() => console.log("Header clicked")}
|
||||
noHover={true}
|
||||
/>
|
||||
<MenuItem
|
||||
icon={"static/images/nav.logo.react.svg"}
|
||||
label="First item"
|
||||
onClick={() => console.log("Button 1 clicked")}
|
||||
/>
|
||||
<MenuItem isSeparator={true} />
|
||||
<MenuItem
|
||||
icon={"static/images/nav.logo.react.svg"}
|
||||
label="Item after separator"
|
||||
onClick={() => console.log("Button 2 clicked")}
|
||||
/>
|
||||
<MenuItem onClick={() => console.log("Button 3 clicked")}>
|
||||
<div>some child without styles</div>
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon={"static/images/nav.logo.react.svg"}
|
||||
label="Item after separator"
|
||||
options={[
|
||||
{
|
||||
key: "key1",
|
||||
icon: "static/images/nav.logo.react.svg",
|
||||
label: "Item after separator",
|
||||
onClick: () => console.log("Button 1 clicked"),
|
||||
},
|
||||
{
|
||||
key: "key2",
|
||||
icon: "static/images/nav.logo.react.svg",
|
||||
label: "Item after separator",
|
||||
onClick: () => console.log("Button 2 clicked"),
|
||||
},
|
||||
]}
|
||||
onClick={() => console.log("Button 2 clicked")}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export const Default = Template.bind({});
|
@ -1,76 +0,0 @@
|
||||
import React from "react";
|
||||
import { mount, shallow } from "enzyme";
|
||||
import MenuItem from ".";
|
||||
|
||||
const baseProps = {
|
||||
isSeparator: false,
|
||||
isHeader: false,
|
||||
tabIndex: -1,
|
||||
label: "test",
|
||||
disabled: false,
|
||||
icon: "static/images/nav.logo.react.svg",
|
||||
noHover: false,
|
||||
onClick: jest.fn(),
|
||||
};
|
||||
|
||||
describe("<MenuItem />", () => {
|
||||
it("renders without error", () => {
|
||||
const wrapper = mount(<MenuItem {...baseProps} />);
|
||||
|
||||
expect(wrapper).toExist();
|
||||
});
|
||||
|
||||
it("check isSeparator props", () => {
|
||||
const wrapper = mount(<MenuItem {...baseProps} isSeparator={true} />);
|
||||
|
||||
expect(wrapper.prop("isSeparator")).toEqual(true);
|
||||
});
|
||||
|
||||
it("check isHeader props", () => {
|
||||
const wrapper = mount(<MenuItem {...baseProps} isHeader={true} />);
|
||||
|
||||
expect(wrapper.prop("isHeader")).toEqual(true);
|
||||
});
|
||||
|
||||
it("check noHover props", () => {
|
||||
const wrapper = mount(<MenuItem {...baseProps} noHover={true} />);
|
||||
|
||||
expect(wrapper.prop("noHover")).toEqual(true);
|
||||
});
|
||||
|
||||
it("causes function onClick()", () => {
|
||||
const onClick = jest.fn();
|
||||
|
||||
const wrapper = shallow(
|
||||
<MenuItem id="test" {...baseProps} onClick={onClick} />
|
||||
);
|
||||
|
||||
wrapper.find("#test").simulate("click");
|
||||
|
||||
expect(onClick).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("render without child", () => {
|
||||
const wrapper = shallow(<MenuItem>test</MenuItem>);
|
||||
|
||||
expect(wrapper.props.children).toEqual(undefined);
|
||||
});
|
||||
|
||||
it("accepts id", () => {
|
||||
const wrapper = mount(<MenuItem {...baseProps} id="testId" />);
|
||||
|
||||
expect(wrapper.prop("id")).toEqual("testId");
|
||||
});
|
||||
|
||||
it("accepts className", () => {
|
||||
const wrapper = mount(<MenuItem {...baseProps} className="test" />);
|
||||
|
||||
expect(wrapper.prop("className")).toEqual("test");
|
||||
});
|
||||
|
||||
it("accepts style", () => {
|
||||
const wrapper = mount(<MenuItem {...baseProps} style={{ color: "red" }} />);
|
||||
|
||||
expect(wrapper.getDOMNode().style).toHaveProperty("color", "red");
|
||||
});
|
||||
});
|
@ -1,168 +0,0 @@
|
||||
import styled, { css } from "styled-components";
|
||||
import Base from "../themes/base";
|
||||
|
||||
import Text from "../text/";
|
||||
|
||||
import { tablet } from "../utils/device";
|
||||
import { isMobile } from "react-device-detect";
|
||||
|
||||
const styledHeaderText = css`
|
||||
font-size: ${(props) => props.theme.menuItem.text.header.fontSize};
|
||||
line-height: ${(props) => props.theme.menuItem.text.header.lineHeight};
|
||||
`;
|
||||
|
||||
const styledMobileText = css`
|
||||
font-size: ${(props) => props.theme.menuItem.text.mobile.fontSize};
|
||||
line-height: ${(props) => props.theme.menuItem.text.mobile.lineHeight};
|
||||
`;
|
||||
|
||||
const StyledText = styled(Text)`
|
||||
width: 100%;
|
||||
font-weight: ${(props) => props.theme.menuItem.text.fontWeight};
|
||||
font-size: ${(props) => props.theme.menuItem.text.fontSize};
|
||||
line-height: ${(props) => props.theme.menuItem.text.lineHeight};
|
||||
margin: ${(props) => props.theme.menuItem.text.margin};
|
||||
color: ${(props) => props.theme.menuItem.text.color};
|
||||
text-align: left;
|
||||
text-transform: none;
|
||||
text-decoration: none;
|
||||
user-select: none;
|
||||
${isMobile
|
||||
? (props) => (props.isHeader ? styledHeaderText : styledMobileText)
|
||||
: null}
|
||||
|
||||
@media ${tablet} {
|
||||
${(props) => (props.isHeader ? styledHeaderText : styledMobileText)}
|
||||
}
|
||||
`;
|
||||
StyledText.defaultProps = { theme: Base };
|
||||
|
||||
const StyledMenuItem = styled.div`
|
||||
display: ${(props) =>
|
||||
props.isHeader && !isMobile
|
||||
? "none"
|
||||
: props.textOverflow
|
||||
? "block"
|
||||
: "flex"};
|
||||
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: ${(props) =>
|
||||
isMobile
|
||||
? props.isHeader
|
||||
? props.theme.menuItem.header.height
|
||||
: props.theme.menuItem.mobile.height
|
||||
: props.theme.menuItem.height};
|
||||
max-height: ${(props) =>
|
||||
isMobile
|
||||
? props.isHeader
|
||||
? props.theme.menuItem.header.height
|
||||
: props.theme.menuItem.mobile.height
|
||||
: props.theme.menuItem.height};
|
||||
border: none;
|
||||
border-bottom: ${(props) =>
|
||||
isMobile && props.isHeader
|
||||
? props.theme.menuItem.header.borderBottom
|
||||
: props.theme.menuItem.borderBottom};
|
||||
cursor: ${(props) => (isMobile && props.isHeader ? "default" : "pointer")};
|
||||
margin: 0;
|
||||
margin-bottom: ${(props) =>
|
||||
isMobile && props.isHeader
|
||||
? props.theme.menuItem.header.marginBottom
|
||||
: props.theme.menuItem.marginBottom};
|
||||
padding: ${(props) =>
|
||||
isMobile
|
||||
? props.theme.menuItem.mobile.padding
|
||||
: props.theme.menuItem.padding};
|
||||
box-sizing: border-box;
|
||||
background: none;
|
||||
outline: 0 !important;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
|
||||
@media ${tablet} {
|
||||
display: ${(props) => (props.textOverflow ? "block" : "flex")};
|
||||
height: ${(props) =>
|
||||
props.isHeader
|
||||
? props.theme.menuItem.header.height
|
||||
: props.theme.menuItem.mobile.height};
|
||||
max-height: ${(props) =>
|
||||
props.isHeader
|
||||
? props.theme.menuItem.header.height
|
||||
: props.theme.menuItem.mobile.height};
|
||||
padding: ${(props) => props.theme.menuItem.mobile.padding};
|
||||
border: none;
|
||||
border-bottom: ${(props) =>
|
||||
props.isHeader
|
||||
? props.theme.menuItem.header.borderBottom
|
||||
: props.theme.menuItem.borderBottom};
|
||||
margin-bottom: ${(props) =>
|
||||
props.isHeader
|
||||
? props.theme.menuItem.header.marginBottom
|
||||
: props.theme.menuItem.marginBottom};
|
||||
cursor: ${(props) => (props.isHeader ? "default" : "pointer")};
|
||||
}
|
||||
|
||||
.drop-down-item_icon {
|
||||
path {
|
||||
fill: ${(props) => !props.isHeader && props.theme.menuItem.svgFill};
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: ${(props) =>
|
||||
props.noHover || props.isHeader
|
||||
? props.theme.menuItem.background
|
||||
: props.theme.menuItem.hover};
|
||||
}
|
||||
${(props) =>
|
||||
props.isSeparator &&
|
||||
css`
|
||||
border-bottom: ${props.theme.menuItem.separator.borderBottom};
|
||||
cursor: default !important;
|
||||
margin: ${props.theme.menuItem.separator.margin};
|
||||
height: ${props.theme.menuItem.separator.height};
|
||||
width: ${props.theme.menuItem.separator.width};
|
||||
&:hover {
|
||||
cursor: default !important;
|
||||
}
|
||||
`}
|
||||
|
||||
.arrow-icon {
|
||||
margin: 0 0 0 8px;
|
||||
}
|
||||
`;
|
||||
StyledMenuItem.defaultProps = { theme: Base };
|
||||
|
||||
const IconWrapper = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: ${(props) =>
|
||||
props.isHeader && isMobile
|
||||
? props.theme.menuItem.iconWrapper.header.width
|
||||
: props.theme.menuItem.iconWrapper.width};
|
||||
height: ${(props) =>
|
||||
props.isHeader && isMobile
|
||||
? props.theme.menuItem.iconWrapper.header.height
|
||||
: props.theme.menuItem.iconWrapper.height};
|
||||
|
||||
@media ${tablet} {
|
||||
width: ${(props) =>
|
||||
props.isHeader
|
||||
? props.theme.menuItem.iconWrapper.header.width
|
||||
: props.theme.menuItem.iconWrapper.width};
|
||||
height: ${(props) =>
|
||||
props.isHeader
|
||||
? props.theme.menuItem.iconWrapper.header.height
|
||||
: props.theme.menuItem.iconWrapper.height};
|
||||
}
|
||||
|
||||
svg {
|
||||
&:not(:root) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
`;
|
||||
IconWrapper.defaultProps = { theme: Base };
|
||||
|
||||
export { StyledMenuItem, StyledText, IconWrapper };
|
@ -1,3 +0,0 @@
|
||||
<svg width="4" height="8" viewBox="0 0 4 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.5255 4L0.153211 1.10054C-0.0755111 0.820987 -0.0446084 0.400121 0.222235 0.160507C0.489078 -0.0791068 0.890813 -0.0467326 1.11954 0.232817L3.8468 3.56614C4.05107 3.8158 4.05107 4.1842 3.8468 4.43386L1.11954 7.76718C0.890813 8.04673 0.489078 8.07911 0.222235 7.83949C-0.0446084 7.59988 -0.0755111 7.17901 0.153211 6.89946L2.5255 4Z" fill="#333333"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 460 B |
@ -1,3 +0,0 @@
|
||||
<svg width="4" height="8" viewBox="0 0 4 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.146447 7.35355C-0.0488156 7.15829 -0.0488156 6.84171 0.146447 6.64645L2.79289 4L0.146446 1.35355C-0.0488158 1.15829 -0.0488158 0.841709 0.146446 0.646447C0.341708 0.451184 0.658291 0.451184 0.853553 0.646447L3.85355 3.64645C4.04882 3.84171 4.04882 4.15829 3.85355 4.35355L0.853553 7.35355C0.658291 7.54882 0.341709 7.54882 0.146447 7.35355Z" fill="#333333"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 510 B |
@ -1,35 +0,0 @@
|
||||
# ContextMenu
|
||||
|
||||
ContextMenu is used for a call context actions on a page.
|
||||
|
||||
> Implemented as part of RowContainer component.
|
||||
|
||||
### Usage
|
||||
|
||||
```js
|
||||
import NewContextMenu from "@appserver/components/new-context-menu";
|
||||
```
|
||||
|
||||
```jsx
|
||||
<NewContextMenu model={defaultModel} />
|
||||
```
|
||||
|
||||
For use within separate component it is necessary to determine active zone and events for calling and transferring options in menu.
|
||||
|
||||
In particular case, state is created containing options for particular Row element and passed to component when called.
|
||||
|
||||
ContextMenu contain MenuItem component and can take from the props model(all view)
|
||||
and header(show only tablet or mobile, when view changed).
|
||||
|
||||
### Properties
|
||||
|
||||
| Props | Type | Required | Values | Default | Description |
|
||||
| -------------- | :------------: | :------: | :----: | :-----------: | ------------------------ |
|
||||
| `className` | `string` | - | - | - | Accepts class |
|
||||
| `id` | `string` | - | - | `contextMenu` | Accepts id |
|
||||
| `model` | `array` | - | - | `[]` | Items collection |
|
||||
| `header` | `object` | - | - | `{}` | ContextMenu header |
|
||||
| `position` | `object` | - | - | `{}` | ContextMenu position |
|
||||
| `style` | `obj`, `array` | - | - | - | Accepts css style |
|
||||
| `targetAreaId` | `string` | - | - | - | Id of container apply to |
|
||||
| `withBackdrop` | `bool` | - | - | `true` | Used to display backdrop |
|
@ -1,494 +0,0 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import DomHelpers from "../utils/domHelpers";
|
||||
import { classNames } from "../utils/classNames";
|
||||
import { CSSTransition } from "react-transition-group";
|
||||
import { VariableSizeList } from "react-window";
|
||||
|
||||
import CustomScrollbarsVirtualList from "../scrollbar/custom-scrollbars-virtual-list";
|
||||
|
||||
import { isMobile, isMobileOnly } from "react-device-detect";
|
||||
import {
|
||||
isMobile as isMobileUtils,
|
||||
isTablet as isTabletUtils,
|
||||
} from "../utils/device";
|
||||
|
||||
import Portal from "../portal";
|
||||
import MenuItem from "../menu-item";
|
||||
import Backdrop from "../backdrop";
|
||||
|
||||
import StyledContextMenu from "./styled-new-context-menu";
|
||||
|
||||
// eslint-disable-next-line react/display-name, react/prop-types
|
||||
const Row = React.memo(({ data, index, style }) => {
|
||||
// eslint-disable-next-line react/prop-types
|
||||
if (!data.data[index]) return null;
|
||||
return (
|
||||
<MenuItem
|
||||
// eslint-disable-next-line react/prop-types
|
||||
key={data.data[index].key}
|
||||
// eslint-disable-next-line react/prop-types
|
||||
name={data.data[index].key}
|
||||
// eslint-disable-next-line react/prop-types
|
||||
icon={data.data[index].icon}
|
||||
// eslint-disable-next-line react/prop-types
|
||||
label={data.data[index].label}
|
||||
// eslint-disable-next-line react/prop-types
|
||||
isSeparator={data.data[index].isSeparator}
|
||||
// eslint-disable-next-line react/prop-types
|
||||
options={data.data[index].options}
|
||||
// eslint-disable-next-line react/prop-types
|
||||
onClick={data.data[index].onClick}
|
||||
// eslint-disable-next-line react/prop-types
|
||||
hideMenu={data.hideMenu}
|
||||
style={style}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
class NewContextMenu extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
visible: false,
|
||||
reshow: false,
|
||||
resetMenu: false,
|
||||
changeView: false,
|
||||
};
|
||||
|
||||
this.onMenuClick = this.onMenuClick.bind(this);
|
||||
this.onLeafClick = this.onLeafClick.bind(this);
|
||||
this.onMenuMouseEnter = this.onMenuMouseEnter.bind(this);
|
||||
this.onEnter = this.onEnter.bind(this);
|
||||
this.onEntered = this.onEntered.bind(this);
|
||||
this.onExit = this.onExit.bind(this);
|
||||
this.onExited = this.onExited.bind(this);
|
||||
|
||||
this.menuRef = React.createRef();
|
||||
}
|
||||
onMenuClick() {
|
||||
this.setState({
|
||||
resetMenu: false,
|
||||
});
|
||||
}
|
||||
|
||||
onMenuMouseEnter() {
|
||||
this.setState({
|
||||
resetMenu: false,
|
||||
});
|
||||
}
|
||||
|
||||
show(e) {
|
||||
if (!(e instanceof Event)) {
|
||||
e.persist();
|
||||
}
|
||||
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
this.currentEvent = e;
|
||||
|
||||
if (this.state.visible) {
|
||||
this.setState({ reshow: true });
|
||||
} else {
|
||||
this.setState({ visible: true }, () => {
|
||||
if (this.props.onShow) {
|
||||
this.props.onShow(this.currentEvent);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
if (this.state.visible && prevState.reshow !== this.state.reshow) {
|
||||
let event = this.currentEvent;
|
||||
this.setState(
|
||||
{
|
||||
visible: false,
|
||||
reshow: false,
|
||||
rePosition: false,
|
||||
changeView: false,
|
||||
resetMenu: true,
|
||||
},
|
||||
() => this.show(event)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
hide(e) {
|
||||
if (!(e instanceof Event)) {
|
||||
e.persist();
|
||||
}
|
||||
|
||||
this.currentEvent = e;
|
||||
this.setState({ visible: false, reshow: false, changeView: false }, () => {
|
||||
if (this.props.onHide) {
|
||||
this.props.onHide(this.currentEvent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
hideMenu() {
|
||||
this.setState({ visible: false, reshow: false, changeView: false }, () => {
|
||||
if (this.props.onHide) {
|
||||
this.props.onHide(this.currentEvent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onEnter() {
|
||||
if (this.props.autoZIndex) {
|
||||
this.menuRef.current.style.zIndex = String(
|
||||
this.props.baseZIndex + DomHelpers.generateZIndex()
|
||||
);
|
||||
}
|
||||
|
||||
this.position(this.currentEvent);
|
||||
}
|
||||
|
||||
onEntered() {
|
||||
this.bindDocumentListeners();
|
||||
}
|
||||
|
||||
onExit() {
|
||||
this.currentEvent = null;
|
||||
this.unbindDocumentListeners();
|
||||
}
|
||||
|
||||
onExited() {
|
||||
DomHelpers.revertZIndex();
|
||||
}
|
||||
|
||||
position(event) {
|
||||
if (this.props.position) {
|
||||
let width = this.menuRef.current.offsetParent
|
||||
? this.menuRef.current.offsetWidth
|
||||
: DomHelpers.getHiddenElementOuterWidth(this.menuRef.current);
|
||||
let viewport = DomHelpers.getViewport();
|
||||
if (
|
||||
this.props.position.left + width >
|
||||
viewport.width - DomHelpers.calculateScrollbarWidth()
|
||||
) {
|
||||
this.menuRef.current.style.right =
|
||||
// -1 * this.props.position.width + width + "px";
|
||||
0 + "px";
|
||||
} else {
|
||||
this.menuRef.current.style.left = this.props.position.left + "px";
|
||||
}
|
||||
|
||||
this.menuRef.current.style.top = this.props.position.top + "px";
|
||||
return;
|
||||
}
|
||||
if (event) {
|
||||
let left = event.pageX + 1;
|
||||
let top = event.pageY + 1;
|
||||
let width = this.menuRef.current.offsetParent
|
||||
? this.menuRef.current.offsetWidth
|
||||
: DomHelpers.getHiddenElementOuterWidth(this.menuRef.current);
|
||||
let height = this.menuRef.current.offsetParent
|
||||
? this.menuRef.current.offsetHeight
|
||||
: DomHelpers.getHiddenElementOuterHeight(this.menuRef.current);
|
||||
let viewport = DomHelpers.getViewport();
|
||||
|
||||
if ((isMobile || isTabletUtils()) && height > 483) {
|
||||
this.setState({ changeView: true });
|
||||
return;
|
||||
}
|
||||
|
||||
if ((isMobileOnly || isMobileUtils()) && height > 210) {
|
||||
this.setState({ changeView: true });
|
||||
return;
|
||||
}
|
||||
//flip
|
||||
if (left + width - document.body.scrollLeft > viewport.width) {
|
||||
left -= width;
|
||||
}
|
||||
|
||||
//flip
|
||||
if (top + height - document.body.scrollTop > viewport.height) {
|
||||
top -= height;
|
||||
}
|
||||
|
||||
//fit
|
||||
if (left < document.body.scrollLeft) {
|
||||
left = document.body.scrollLeft;
|
||||
}
|
||||
|
||||
//fit
|
||||
if (top < document.body.scrollTop) {
|
||||
top = document.body.scrollTop;
|
||||
}
|
||||
|
||||
this.menuRef.current.style.left = left + "px";
|
||||
this.menuRef.current.style.top = top + "px";
|
||||
}
|
||||
}
|
||||
|
||||
onLeafClick(e) {
|
||||
this.setState({
|
||||
resetMenu: true,
|
||||
});
|
||||
|
||||
this.hide(e);
|
||||
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
isOutsideClicked(e) {
|
||||
return (
|
||||
this.menuRef &&
|
||||
this.menuRef.current &&
|
||||
!(
|
||||
this.menuRef.current.isSameNode(e.target) ||
|
||||
this.menuRef.current.contains(e.target)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
bindDocumentListeners() {
|
||||
this.bindDocumentResizeListener();
|
||||
this.bindDocumentClickListener();
|
||||
}
|
||||
|
||||
unbindDocumentListeners() {
|
||||
this.unbindDocumentResizeListener();
|
||||
this.unbindDocumentClickListener();
|
||||
}
|
||||
|
||||
bindDocumentClickListener() {
|
||||
if (!this.documentClickListener) {
|
||||
this.documentClickListener = (e) => {
|
||||
if (this.isOutsideClicked(e)) {
|
||||
//TODO: (&& e.button !== 2) restore after global usage
|
||||
this.hide(e);
|
||||
|
||||
this.setState({
|
||||
resetMenu: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener("click", this.documentClickListener);
|
||||
document.addEventListener("mousedown", this.documentClickListener);
|
||||
}
|
||||
}
|
||||
|
||||
bindDocumentContextMenuListener() {
|
||||
if (!this.documentContextMenuListener) {
|
||||
this.documentContextMenuListener = (e) => {
|
||||
this.show(e);
|
||||
};
|
||||
|
||||
document.addEventListener(
|
||||
"contextmenu",
|
||||
this.documentContextMenuListener
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
bindDocumentResizeListener() {
|
||||
if (!this.documentResizeListener) {
|
||||
this.documentResizeListener = (e) => {
|
||||
if (this.state.visible) {
|
||||
this.hide(e);
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("resize", this.documentResizeListener);
|
||||
}
|
||||
}
|
||||
|
||||
unbindDocumentClickListener() {
|
||||
if (this.documentClickListener) {
|
||||
document.removeEventListener("click", this.documentClickListener);
|
||||
document.removeEventListener("mousedown", this.documentClickListener);
|
||||
this.documentClickListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
unbindDocumentContextMenuListener() {
|
||||
if (this.documentContextMenuListener) {
|
||||
document.removeEventListener(
|
||||
"contextmenu",
|
||||
this.documentContextMenuListener
|
||||
);
|
||||
this.documentContextMenuListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
unbindDocumentResizeListener() {
|
||||
if (this.documentResizeListener) {
|
||||
window.removeEventListener("resize", this.documentResizeListener);
|
||||
this.documentResizeListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.props.global) {
|
||||
this.bindDocumentContextMenuListener();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.unbindDocumentListeners();
|
||||
this.unbindDocumentContextMenuListener();
|
||||
|
||||
DomHelpers.revertZIndex();
|
||||
}
|
||||
|
||||
renderContextMenuItems() {
|
||||
if (!this.props.model) return null;
|
||||
if (this.state.changeView) {
|
||||
const model = this.props.model.filter((item) => !!item);
|
||||
|
||||
const rowHeights = model.map((item, index) => {
|
||||
if (!item) return 0;
|
||||
if (item.isSeparator) return 13;
|
||||
return 36;
|
||||
});
|
||||
|
||||
const getItemSize = (index) => rowHeights[index];
|
||||
|
||||
const height = rowHeights.reduce((a, b) => a + b);
|
||||
|
||||
const viewport = DomHelpers.getViewport();
|
||||
|
||||
const listHeight =
|
||||
height + 61 > viewport.height - 64 ? viewport.height - 125 : height;
|
||||
|
||||
return (
|
||||
<VariableSizeList
|
||||
height={listHeight}
|
||||
width={"auto"}
|
||||
itemCount={model.length}
|
||||
itemSize={getItemSize}
|
||||
itemData={{
|
||||
data: model,
|
||||
hideMenu: this.hideMenu.bind(this),
|
||||
}}
|
||||
outerElementType={CustomScrollbarsVirtualList}
|
||||
>
|
||||
{Row}
|
||||
</VariableSizeList>
|
||||
);
|
||||
} else {
|
||||
const items = this.props.model.map((item, index) => {
|
||||
if (!item) return;
|
||||
return (
|
||||
<MenuItem
|
||||
key={item.key}
|
||||
name={item.key}
|
||||
icon={item.icon}
|
||||
label={item.label}
|
||||
isSeparator={item.isSeparator}
|
||||
options={item.options}
|
||||
onClick={item.onClick}
|
||||
{...item}
|
||||
hideMenu={this.hideMenu.bind(this)}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
||||
renderContextMenu() {
|
||||
const className = classNames("p-contextmenu", this.props.className);
|
||||
|
||||
const items = this.renderContextMenuItems();
|
||||
return (
|
||||
<>
|
||||
{this.props.withBackdrop && (
|
||||
<Backdrop visible={this.state.visible} withBackground={true} />
|
||||
)}
|
||||
<StyledContextMenu changeView={this.state.changeView}>
|
||||
<CSSTransition
|
||||
nodeRef={this.menuRef}
|
||||
classNames="p-contextmenu"
|
||||
in={this.state.visible}
|
||||
timeout={{ enter: 250, exit: 0 }}
|
||||
unmountOnExit
|
||||
onEnter={this.onEnter}
|
||||
onEntered={this.onEntered}
|
||||
onExit={this.onExit}
|
||||
onExited={this.onExited}
|
||||
>
|
||||
<div
|
||||
ref={this.menuRef}
|
||||
id={this.props.id}
|
||||
className={className}
|
||||
style={this.props.style}
|
||||
onClick={this.onMenuClick}
|
||||
onMouseEnter={this.onMenuMouseEnter}
|
||||
>
|
||||
{this.state.changeView && (
|
||||
<MenuItem
|
||||
key={"header"}
|
||||
isHeader={true}
|
||||
icon={this.props.header.icon}
|
||||
label={this.props.header.title}
|
||||
/>
|
||||
)}
|
||||
{items}
|
||||
</div>
|
||||
</CSSTransition>
|
||||
</StyledContextMenu>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const element = this.renderContextMenu();
|
||||
|
||||
return <Portal element={element} appendTo={this.props.appendTo} />;
|
||||
}
|
||||
}
|
||||
|
||||
NewContextMenu.propTypes = {
|
||||
/** Unique identifier of the element */
|
||||
id: PropTypes.string,
|
||||
/** An array of objects */
|
||||
model: PropTypes.array,
|
||||
/** An object of header with icon and label */
|
||||
header: PropTypes.object,
|
||||
/** Position of context menu */
|
||||
position: PropTypes.object,
|
||||
/** Inline style of the component */
|
||||
style: PropTypes.object,
|
||||
/** Style class of the component */
|
||||
className: PropTypes.string,
|
||||
/** Attaches the menu to document instead of a particular item */
|
||||
global: PropTypes.bool,
|
||||
/** Tell when context menu was render with backdrop */
|
||||
withBackdrop: PropTypes.bool,
|
||||
/** Base zIndex value to use in layering */
|
||||
autoZIndex: PropTypes.bool,
|
||||
/** Whether to automatically manage layering */
|
||||
baseZIndex: PropTypes.number,
|
||||
/** DOM element instance where the menu should be mounted */
|
||||
appendTo: PropTypes.any,
|
||||
/** Callback to invoke when a popup menu is shown */
|
||||
onShow: PropTypes.func,
|
||||
/** Callback to invoke when a popup menu is hidden */
|
||||
onHide: PropTypes.func,
|
||||
};
|
||||
|
||||
NewContextMenu.defaultProps = {
|
||||
id: null,
|
||||
model: null,
|
||||
position: null,
|
||||
header: null,
|
||||
style: null,
|
||||
className: null,
|
||||
global: false,
|
||||
autoZIndex: true,
|
||||
baseZIndex: 0,
|
||||
appendTo: null,
|
||||
onShow: null,
|
||||
onHide: null,
|
||||
withBackdrop: true,
|
||||
};
|
||||
|
||||
export default NewContextMenu;
|
@ -1,179 +0,0 @@
|
||||
import React from "react";
|
||||
import NewContextMenu from ".";
|
||||
|
||||
export default {
|
||||
title: "Components/NewContextMenu",
|
||||
component: NewContextMenu,
|
||||
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component: `Is a ContextMenu component.
|
||||
ContextMenu contain MenuItem component and can take from the props model(all view)
|
||||
and header(show only tablet or mobile, when view changed).
|
||||
`,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const Template = (args) => {
|
||||
const cm = React.useRef(null);
|
||||
const defaultModel = [
|
||||
{
|
||||
disabled: false,
|
||||
icon: "/static/images/access.edit.react.svg",
|
||||
key: "edit",
|
||||
label: "Edit",
|
||||
onClick: () => console.log("item 1 clicked"),
|
||||
},
|
||||
{
|
||||
disabled: false,
|
||||
icon: "/static/images/eye.react.svg",
|
||||
key: "preview",
|
||||
label: "Preview",
|
||||
onClick: () => console.log("item 2 clicked"),
|
||||
},
|
||||
{ isSeparator: true, key: "separator0" },
|
||||
{
|
||||
disabled: false,
|
||||
icon: "/static/images/catalog.shared.react.svg",
|
||||
key: "sharing-settings",
|
||||
label: "Sharing settings",
|
||||
onClick: () => console.log("item 3 clicked"),
|
||||
},
|
||||
{
|
||||
disabled: false,
|
||||
icon: "/static/images/catalog.shared.react.svg",
|
||||
key: "sharing-settings1",
|
||||
label: "Sharing settings",
|
||||
onClick: () => console.log("item 3 clicked"),
|
||||
},
|
||||
{
|
||||
disabled: false,
|
||||
icon: "/static/images/catalog.shared.react.svg",
|
||||
key: "sharing-settings2",
|
||||
label: "Sharing settings",
|
||||
onClick: () => console.log("item 3 clicked"),
|
||||
},
|
||||
{
|
||||
disabled: false,
|
||||
icon: "/static/images/catalog.shared.react.svg",
|
||||
key: "sharing-settings3",
|
||||
label: "Sharing settings",
|
||||
onClick: () => console.log("item 3 clicked"),
|
||||
},
|
||||
{
|
||||
disabled: false,
|
||||
icon: "/static/images/catalog.shared.react.svg",
|
||||
key: "sharing-settings4",
|
||||
label: "Sharing settings",
|
||||
onClick: () => console.log("item 3 clicked"),
|
||||
},
|
||||
{
|
||||
disabled: false,
|
||||
icon: "/static/images/catalog.shared.react.svg",
|
||||
key: "sharing-settings5",
|
||||
label: "Sharing settings",
|
||||
onClick: () => console.log("item 3 clicked"),
|
||||
},
|
||||
{
|
||||
disabled: false,
|
||||
icon: "/static/images/catalog.shared.react.svg",
|
||||
key: "sharing-settings6",
|
||||
label: "Sharing settings",
|
||||
onClick: () => console.log("item 3 clicked"),
|
||||
},
|
||||
{
|
||||
disabled: false,
|
||||
icon: "/static/images/catalog.shared.react.svg",
|
||||
key: "sharing-settings7",
|
||||
label: "Sharing settings",
|
||||
onClick: () => console.log("item 3 clicked"),
|
||||
},
|
||||
{
|
||||
disabled: false,
|
||||
icon: "/static/images/catalog.shared.react.svg",
|
||||
key: "sharing-settings8",
|
||||
label: "Sharing settings",
|
||||
onClick: () => console.log("item 3 clicked"),
|
||||
},
|
||||
{
|
||||
disabled: false,
|
||||
icon: "/static/images/catalog.shared.react.svg",
|
||||
key: "sharing-settings9",
|
||||
label: "Sharing settings",
|
||||
onClick: () => console.log("item 3 clicked"),
|
||||
},
|
||||
{
|
||||
disabled: false,
|
||||
icon: "/static/images/catalog.shared.react.svg",
|
||||
key: "sharing-settings10",
|
||||
label: "Sharing settings",
|
||||
options: [
|
||||
{
|
||||
key: "key1",
|
||||
icon: "static/images/nav.logo.react.svg",
|
||||
label: "Item after separator",
|
||||
onClick: () => console.log("Button 1 clicked"),
|
||||
},
|
||||
{
|
||||
key: "key2",
|
||||
icon: "static/images/nav.logo.react.svg",
|
||||
label: "Item after separator",
|
||||
onClick: () => console.log("Button 2 clicked"),
|
||||
},
|
||||
],
|
||||
onClick: () => console.log("item 3 clicked"),
|
||||
},
|
||||
{
|
||||
disabled: false,
|
||||
icon: "/static/images/catalog.shared.react.svg",
|
||||
key: "sharing-settings11",
|
||||
label: "Sharing settings",
|
||||
onClick: () => console.log("item 3 clicked"),
|
||||
},
|
||||
{
|
||||
disabled: false,
|
||||
icon: "/static/images/catalog.shared.react.svg",
|
||||
key: "sharing-settings12",
|
||||
label: "Sharing settings",
|
||||
onClick: () => console.log("item 3 clicked"),
|
||||
},
|
||||
{
|
||||
disabled: false,
|
||||
icon: "/static/images/catalog.shared.react.svg",
|
||||
key: "sharing-settings13",
|
||||
label: "Sharing settings",
|
||||
onClick: () => console.log("item 3 clicked"),
|
||||
},
|
||||
];
|
||||
|
||||
const headerOptions = {
|
||||
icon: "/static/images/catalog.shared.react.svg",
|
||||
title: "File name",
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<NewContextMenu
|
||||
model={defaultModel}
|
||||
header={headerOptions}
|
||||
ref={cm}
|
||||
></NewContextMenu>
|
||||
|
||||
<div
|
||||
style={{
|
||||
width: "200px",
|
||||
height: "200px",
|
||||
backgroundColor: "red",
|
||||
display: "inline-block",
|
||||
}}
|
||||
onContextMenu={(e) => cm.current.show(e)}
|
||||
>
|
||||
{""}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export const Default = Template.bind({});
|
@ -1,11 +0,0 @@
|
||||
import React from "react";
|
||||
import { mount, shallow } from "enzyme";
|
||||
import NewContextMenu from ".";
|
||||
|
||||
describe("<MenuItem />", () => {
|
||||
it("renders without error", () => {
|
||||
const wrapper = mount(<NewContextMenu />);
|
||||
|
||||
expect(wrapper).toExist();
|
||||
});
|
||||
});
|
@ -1,59 +0,0 @@
|
||||
import styled, { css } from "styled-components";
|
||||
import { isMobile, isMobileOnly } from "react-device-detect";
|
||||
import { tablet, mobile } from "../utils/device";
|
||||
import Base from "../themes/base";
|
||||
|
||||
const styledTabletView = css`
|
||||
width: ${(props) => props.theme.newContextMenu.devices.tabletWidth};
|
||||
max-width: ${(props) => props.theme.newContextMenu.devices.tabletWidth};
|
||||
max-height: ${(props) => props.theme.newContextMenu.devices.maxHeight};
|
||||
left: ${(props) => props.theme.newContextMenu.devices.left};
|
||||
right: ${(props) => props.theme.newContextMenu.devices.right};
|
||||
bottom: ${(props) => props.theme.newContextMenu.devices.bottom};
|
||||
margin: ${(props) => props.theme.newContextMenu.devices.margin};
|
||||
`;
|
||||
|
||||
const styledMobileView = css`
|
||||
width: ${(props) => props.theme.newContextMenu.devices.mobileWidth};
|
||||
max-width: ${(props) => props.theme.newContextMenu.devices.mobileWidth};
|
||||
max-height: ${(props) => props.theme.newContextMenu.devices.maxHeight};
|
||||
left: ${(props) => props.theme.newContextMenu.devices.left};
|
||||
bottom: ${(props) => props.theme.newContextMenu.devices.bottom};
|
||||
`;
|
||||
|
||||
const StyledContextMenu = styled.div`
|
||||
.p-contextmenu {
|
||||
position: absolute;
|
||||
background: ${(props) => props.theme.newContextMenu.background};
|
||||
border: ${(props) => props.theme.newContextMenu.border};
|
||||
border-radius: ${(props) => props.theme.newContextMenu.borderRadius};
|
||||
-moz-border-radius: ${(props) => props.theme.newContextMenu.borderRadius};
|
||||
-webkit-border-radius: ${(props) =>
|
||||
props.theme.newContextMenu.borderRadius};
|
||||
box-shadow: ${(props) => props.theme.newContextMenu.boxShadow};
|
||||
-moz-box-shadow: ${(props) => props.theme.newContextMenu.boxShadow};
|
||||
-webkit-box-shadow: ${(props) => props.theme.newContextMenu.boxShadow};
|
||||
padding: ${(props) => props.theme.newContextMenu.padding};
|
||||
|
||||
@media ${tablet} {
|
||||
${(props) => props.changeView && !isMobile && styledTabletView}
|
||||
}
|
||||
|
||||
@media ${mobile} {
|
||||
${(props) => props.changeView && !isMobile && styledMobileView}
|
||||
}
|
||||
|
||||
${(props) =>
|
||||
props.changeView
|
||||
? isMobileOnly
|
||||
? styledMobileView
|
||||
: styledTabletView
|
||||
: null}
|
||||
}
|
||||
`;
|
||||
|
||||
StyledContextMenu.defaultProps = {
|
||||
theme: Base,
|
||||
};
|
||||
|
||||
export default StyledContextMenu;
|
Loading…
Reference in New Issue
Block a user