Merge pull request #422 from ONLYOFFICE/feature/new-context-menu
Feature/new context menu
This commit is contained in:
commit
f1a184f8c5
@ -1256,71 +1256,10 @@ class ContextOptionsStore {
|
|||||||
!contextOptions.includes("finalize-version") &&
|
!contextOptions.includes("finalize-version") &&
|
||||||
contextOptions.includes("show-version-history");
|
contextOptions.includes("show-version-history");
|
||||||
|
|
||||||
const versionActions = isDesktop()
|
const versionActions = onlyShowVersionHistory
|
||||||
? onlyShowVersionHistory
|
? [
|
||||||
? [
|
|
||||||
{
|
|
||||||
id: "option_show-version-history",
|
|
||||||
key: "show-version-history",
|
|
||||||
label: t("ShowVersionHistory"),
|
|
||||||
icon: HistoryReactSvgUrl,
|
|
||||||
onClick: () =>
|
|
||||||
this.showVersionHistory(
|
|
||||||
item.id,
|
|
||||||
item.security,
|
|
||||||
item?.requestToken,
|
|
||||||
),
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: [
|
|
||||||
{
|
|
||||||
id: "option_version",
|
|
||||||
key: "version",
|
|
||||||
label: t("VersionHistory"),
|
|
||||||
icon: HistoryFinalizedReactSvgUrl,
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
id: "option_finalize-version",
|
|
||||||
key: "finalize-version",
|
|
||||||
label: t("FinalizeVersion"),
|
|
||||||
icon: HistoryFinalizedReactSvgUrl,
|
|
||||||
onClick: () =>
|
|
||||||
isEditing
|
|
||||||
? this.onShowEditingToast(t)
|
|
||||||
: this.finalizeVersion(item.id, item.security),
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "option_version-history",
|
|
||||||
key: "show-version-history",
|
|
||||||
label: t("ShowVersionHistory"),
|
|
||||||
icon: HistoryReactSvgUrl,
|
|
||||||
onClick: () =>
|
|
||||||
this.showVersionHistory(
|
|
||||||
item.id,
|
|
||||||
item.security,
|
|
||||||
item?.requestToken,
|
|
||||||
),
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: [
|
|
||||||
{
|
{
|
||||||
id: "option_finalize-version",
|
id: "option_show-version-history",
|
||||||
key: "finalize-version",
|
|
||||||
label: t("FinalizeVersion"),
|
|
||||||
icon: HistoryFinalizedReactSvgUrl,
|
|
||||||
onClick: () =>
|
|
||||||
isEditing
|
|
||||||
? this.onShowEditingToast(t)
|
|
||||||
: this.finalizeVersion(item.id),
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "option_version-history",
|
|
||||||
key: "show-version-history",
|
key: "show-version-history",
|
||||||
label: t("ShowVersionHistory"),
|
label: t("ShowVersionHistory"),
|
||||||
icon: HistoryReactSvgUrl,
|
icon: HistoryReactSvgUrl,
|
||||||
@ -1332,8 +1271,43 @@ class ContextOptionsStore {
|
|||||||
),
|
),
|
||||||
disabled: false,
|
disabled: false,
|
||||||
},
|
},
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
{
|
||||||
|
id: "option_version",
|
||||||
|
key: "version",
|
||||||
|
label: t("VersionHistory"),
|
||||||
|
icon: HistoryFinalizedReactSvgUrl,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
id: "option_finalize-version",
|
||||||
|
key: "finalize-version",
|
||||||
|
label: t("FinalizeVersion"),
|
||||||
|
icon: HistoryFinalizedReactSvgUrl,
|
||||||
|
onClick: () =>
|
||||||
|
isEditing
|
||||||
|
? this.onShowEditingToast(t)
|
||||||
|
: this.finalizeVersion(item.id, item.security),
|
||||||
|
disabled: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "option_version-history",
|
||||||
|
key: "show-version-history",
|
||||||
|
label: t("ShowVersionHistory"),
|
||||||
|
icon: HistoryReactSvgUrl,
|
||||||
|
onClick: () =>
|
||||||
|
this.showVersionHistory(
|
||||||
|
item.id,
|
||||||
|
item.security,
|
||||||
|
item?.requestToken,
|
||||||
|
),
|
||||||
|
disabled: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
];
|
];
|
||||||
const moveActions = isDesktop()
|
|
||||||
|
const moveActions = !isInfoPanel
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
id: "option_move-or-copy",
|
id: "option_move-or-copy",
|
||||||
@ -1815,7 +1789,7 @@ class ContextOptionsStore {
|
|||||||
const pluginItems = this.onLoadPlugins(item);
|
const pluginItems = this.onLoadPlugins(item);
|
||||||
|
|
||||||
if (pluginItems.length > 0) {
|
if (pluginItems.length > 0) {
|
||||||
if (!isDesktop() || pluginItems.length === 1) {
|
if (pluginItems.length === 1) {
|
||||||
pluginItems.forEach((plugin) => {
|
pluginItems.forEach((plugin) => {
|
||||||
options.splice(1, 0, {
|
options.splice(1, 0, {
|
||||||
id: `option_${plugin.key}`,
|
id: `option_${plugin.key}`,
|
||||||
|
@ -26,21 +26,7 @@
|
|||||||
|
|
||||||
import styled, { css } from "styled-components";
|
import styled, { css } from "styled-components";
|
||||||
import { Base, TTheme, globalColors } from "../../themes";
|
import { Base, TTheme, globalColors } from "../../themes";
|
||||||
import { tablet, mobile, getCorrectFourValuesStyle } from "../../utils";
|
import { mobile, getCorrectFourValuesStyle } from "../../utils";
|
||||||
|
|
||||||
const styledTabletView = css<{ articleWidth: number }>`
|
|
||||||
position: fixed;
|
|
||||||
width: ${(props) => props.theme.newContextMenu.devices.tabletWidth};
|
|
||||||
max-width: ${(props) => props.theme.newContextMenu.devices.tabletWidth};
|
|
||||||
max-height: ${(props) => props.theme.newContextMenu.devices.maxHeight};
|
|
||||||
inset-inline-start: ${(props) =>
|
|
||||||
props.articleWidth
|
|
||||||
? `${props.articleWidth}px`
|
|
||||||
: props.theme.newContextMenu.devices.left};
|
|
||||||
inset-inline-end: ${(props) => props.theme.newContextMenu.devices.right};
|
|
||||||
bottom: ${(props) => props.theme.newContextMenu.devices.bottom};
|
|
||||||
margin: ${(props) => props.theme.newContextMenu.devices.margin};
|
|
||||||
`;
|
|
||||||
|
|
||||||
const styledMobileView = css`
|
const styledMobileView = css`
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@ -97,14 +83,13 @@ const StyledContextMenu = styled.div<{
|
|||||||
box-shadow: ${(props) => props.theme.newContextMenu.boxShadow};
|
box-shadow: ${(props) => props.theme.newContextMenu.boxShadow};
|
||||||
-moz-box-shadow: ${(props) => props.theme.newContextMenu.boxShadow};
|
-moz-box-shadow: ${(props) => props.theme.newContextMenu.boxShadow};
|
||||||
-webkit-box-shadow: ${(props) => props.theme.newContextMenu.boxShadow};
|
-webkit-box-shadow: ${(props) => props.theme.newContextMenu.boxShadow};
|
||||||
padding: ${(props) => props.theme.newContextMenu.padding};
|
|
||||||
|
|
||||||
@media ${tablet} {
|
.scroll-body {
|
||||||
${(props) => props.changeView && styledTabletView}
|
display: flex;
|
||||||
}
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
@media ${mobile} {
|
padding-inline-end: 0 !important;
|
||||||
${(props) => props.changeView && styledMobileView}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +190,6 @@ const StyledContextMenu = styled.div<{
|
|||||||
box-shadow: ${(props) => props.theme.dropDown.boxShadow};
|
box-shadow: ${(props) => props.theme.dropDown.boxShadow};
|
||||||
-moz-box-shadow: ${(props) => props.theme.dropDown.boxShadow};
|
-moz-box-shadow: ${(props) => props.theme.dropDown.boxShadow};
|
||||||
-webkit-box-shadow: ${(props) => props.theme.dropDown.boxShadow};
|
-webkit-box-shadow: ${(props) => props.theme.dropDown.boxShadow};
|
||||||
padding: 4px 0px;
|
|
||||||
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -226,7 +210,7 @@ const StyledContextMenu = styled.div<{
|
|||||||
position: relative;
|
position: relative;
|
||||||
border: ${(props) => props.theme.dropDownItem.border};
|
border: ${(props) => props.theme.dropDownItem.border};
|
||||||
margin: ${(props) => props.theme.dropDownItem.margin};
|
margin: ${(props) => props.theme.dropDownItem.margin};
|
||||||
padding: ${(props) => props.theme.dropDownItem.padding};
|
padding: 0 16px;
|
||||||
font-family: ${(props) => props.theme.fontFamily};
|
font-family: ${(props) => props.theme.fontFamily};
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
background: none;
|
background: none;
|
||||||
@ -241,10 +225,6 @@ const StyledContextMenu = styled.div<{
|
|||||||
|
|
||||||
-webkit-touch-callout: none;
|
-webkit-touch-callout: none;
|
||||||
|
|
||||||
@media ${tablet} {
|
|
||||||
padding: 0 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: ${(props) =>
|
background-color: ${(props) =>
|
||||||
props.noHover
|
props.noHover
|
||||||
@ -275,7 +255,7 @@ const StyledContextMenu = styled.div<{
|
|||||||
cursor: default !important;
|
cursor: default !important;
|
||||||
margin: ${(props) => props.theme.menuItem.separator.margin};
|
margin: ${(props) => props.theme.menuItem.separator.margin};
|
||||||
height: ${(props) => props.theme.menuItem.separator.height};
|
height: ${(props) => props.theme.menuItem.separator.height};
|
||||||
width: ${(props) => props.theme.menuItem.separator.width};
|
|
||||||
&:hover {
|
&:hover {
|
||||||
cursor: default !important;
|
cursor: default !important;
|
||||||
}
|
}
|
||||||
@ -284,6 +264,14 @@ const StyledContextMenu = styled.div<{
|
|||||||
.p-contextmenu .p-menuitem {
|
.p-contextmenu .p-menuitem {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: ${(props) => props.theme.dropDownItem.margin};
|
margin: ${(props) => props.theme.dropDownItem.margin};
|
||||||
|
|
||||||
|
max-width: calc(-32px + 100vw);
|
||||||
|
width: fit-content;
|
||||||
|
min-width: inherit;
|
||||||
|
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
.p-contextmenu .scroll-body .p-menuitem {
|
.p-contextmenu .scroll-body .p-menuitem {
|
||||||
@ -361,10 +349,47 @@ const StyledContextMenu = styled.div<{
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
transition: opacity 250ms;
|
transition: opacity 250ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.p-contextmenu {
|
||||||
|
@media ${mobile} {
|
||||||
|
${(props) => props.changeView && styledMobileView}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media not ${mobile} {
|
||||||
|
max-width: calc(100vw - 32px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-contextmenu ul {
|
||||||
|
@media not ${mobile} {
|
||||||
|
max-width: calc(100vw - 32px);
|
||||||
|
}
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
StyledContextMenu.defaultProps = {
|
StyledContextMenu.defaultProps = {
|
||||||
theme: Base,
|
theme: Base,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const StyledList = styled.ul<{
|
||||||
|
listHeight: number;
|
||||||
|
widthSubMenu: null | number;
|
||||||
|
}>`
|
||||||
|
& > :first-child {
|
||||||
|
.scroll-body {
|
||||||
|
height: ${(props) => `${props.listHeight}px`};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > :nth-child(1) {
|
||||||
|
${(props) =>
|
||||||
|
props.widthSubMenu &&
|
||||||
|
css`
|
||||||
|
.p-menuitem {
|
||||||
|
max-width: ${`${props.widthSubMenu}px`};
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
export { StyledContextMenu };
|
export { StyledContextMenu };
|
||||||
|
@ -57,6 +57,8 @@ import {
|
|||||||
ContextMenuRefType,
|
ContextMenuRefType,
|
||||||
} from "./ContextMenu.types";
|
} from "./ContextMenu.types";
|
||||||
|
|
||||||
|
const marginBorder = 16; // Indentation from the border of the screen
|
||||||
|
|
||||||
const ContextMenu = React.forwardRef<ContextMenuRefType, ContextMenuProps>(
|
const ContextMenu = React.forwardRef<ContextMenuRefType, ContextMenuProps>(
|
||||||
(props, ref) => {
|
(props, ref) => {
|
||||||
const [visible, setVisible] = React.useState(false);
|
const [visible, setVisible] = React.useState(false);
|
||||||
@ -65,9 +67,11 @@ const ContextMenu = React.forwardRef<ContextMenuRefType, ContextMenuProps>(
|
|||||||
const [model, setModel] = React.useState<ContextMenuModel[] | null>(null);
|
const [model, setModel] = React.useState<ContextMenuModel[] | null>(null);
|
||||||
const [changeView, setChangeView] = React.useState(false);
|
const [changeView, setChangeView] = React.useState(false);
|
||||||
const [showMobileMenu, setShowMobileMenu] = React.useState(false);
|
const [showMobileMenu, setShowMobileMenu] = React.useState(false);
|
||||||
const [onLoad, setOnLoad] = React.useState<
|
const [mobileSubMenuItems, setMobileSubMenuItems] = React.useState<
|
||||||
undefined | (() => Promise<ContextMenuModel[]>)
|
ContextMenuModel[] | undefined
|
||||||
>(undefined);
|
>([]);
|
||||||
|
const [mobileHeader, setMobileHeader] = React.useState<string>("");
|
||||||
|
|
||||||
const [articleWidth, setArticleWidth] = React.useState(0);
|
const [articleWidth, setArticleWidth] = React.useState(0);
|
||||||
|
|
||||||
const prevReshow = React.useRef(false);
|
const prevReshow = React.useRef(false);
|
||||||
@ -211,7 +215,7 @@ const ContextMenu = React.forwardRef<ContextMenuRefType, ContextMenuProps>(
|
|||||||
? rects.left - currentLeftOffset - currentRightOffset
|
? rects.left - currentLeftOffset - currentRightOffset
|
||||||
: event.pageX + 1;
|
: event.pageX + 1;
|
||||||
let top = rects ? rects.top : event.pageY + 1;
|
let top = rects ? rects.top : event.pageY + 1;
|
||||||
const width =
|
let width =
|
||||||
menuRef.current && menuRef.current.offsetParent
|
menuRef.current && menuRef.current.offsetParent
|
||||||
? menuRef.current.offsetWidth
|
? menuRef.current.offsetWidth
|
||||||
: DomHelpers.getHiddenElementOuterWidth(menuRef.current);
|
: DomHelpers.getHiddenElementOuterWidth(menuRef.current);
|
||||||
@ -221,29 +225,30 @@ const ContextMenu = React.forwardRef<ContextMenuRefType, ContextMenuProps>(
|
|||||||
: DomHelpers.getHiddenElementOuterHeight(menuRef.current);
|
: DomHelpers.getHiddenElementOuterHeight(menuRef.current);
|
||||||
const viewport = DomHelpers.getViewport();
|
const viewport = DomHelpers.getViewport();
|
||||||
|
|
||||||
|
const mobileView =
|
||||||
|
isMobileUtils() && (height > 210 || ignoreChangeView);
|
||||||
|
|
||||||
|
if (!mobileView) {
|
||||||
|
const options =
|
||||||
|
menuRef?.current?.getElementsByClassName("p-menuitem");
|
||||||
|
const optionsWidth: number[] = [];
|
||||||
|
|
||||||
|
if (options) {
|
||||||
|
Array.from(options).forEach((option) =>
|
||||||
|
optionsWidth.push(option.clientWidth),
|
||||||
|
);
|
||||||
|
|
||||||
|
const widthMaxContent = Math.max(...optionsWidth);
|
||||||
|
|
||||||
|
width = widthMaxContent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (theme.interfaceDirection === "rtl" && !rects && left > width) {
|
if (theme.interfaceDirection === "rtl" && !rects && left > width) {
|
||||||
left = event.pageX - width + 1;
|
left = event.pageX - width + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (mobileView) {
|
||||||
isTabletUtils() &&
|
|
||||||
(height > 483 ||
|
|
||||||
(isMobileOnly && window.innerHeight < window.innerWidth))
|
|
||||||
) {
|
|
||||||
const article = document.getElementById("article-container");
|
|
||||||
|
|
||||||
let currentArticleWidth = 0;
|
|
||||||
if (article) {
|
|
||||||
currentArticleWidth = article.offsetWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
setChangeView(true);
|
|
||||||
setArticleWidth(currentArticleWidth);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isMobileUtils() && (height > 210 || ignoreChangeView)) {
|
|
||||||
setChangeView(true);
|
setChangeView(true);
|
||||||
setArticleWidth(0);
|
setArticleWidth(0);
|
||||||
|
|
||||||
@ -267,7 +272,8 @@ const ContextMenu = React.forwardRef<ContextMenuRefType, ContextMenuProps>(
|
|||||||
|
|
||||||
// fit
|
// fit
|
||||||
if (top < document.body.scrollTop) {
|
if (top < document.body.scrollTop) {
|
||||||
top = document.body.scrollTop;
|
if (document.body.scrollTop === 0) top = marginBorder;
|
||||||
|
else top = document.body.scrollTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (containerRef) {
|
if (containerRef) {
|
||||||
@ -281,8 +287,10 @@ const ContextMenu = React.forwardRef<ContextMenuRefType, ContextMenuProps>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (menuRef.current) {
|
if (menuRef.current) {
|
||||||
menuRef.current.style.left = `${left}px`;
|
menuRef.current.style.left = `${left || marginBorder}px`;
|
||||||
menuRef.current.style.top = `${top}px`;
|
menuRef.current.style.top = `${top}px`;
|
||||||
|
|
||||||
|
if (!mobileView) menuRef.current.style.width = `${width}px`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -410,14 +418,20 @@ const ContextMenu = React.forwardRef<ContextMenuRefType, ContextMenuProps>(
|
|||||||
};
|
};
|
||||||
}, [documentResizeListener, onHide, visible]);
|
}, [documentResizeListener, onHide, visible]);
|
||||||
|
|
||||||
const onMobileItemClick = (
|
const onMobileItemClick = async (
|
||||||
e: React.MouseEvent | React.ChangeEvent<HTMLInputElement>,
|
e: React.MouseEvent | React.ChangeEvent<HTMLInputElement>,
|
||||||
|
label: string,
|
||||||
|
items?: ContextMenuModel[],
|
||||||
loadFunc?: () => Promise<ContextMenuModel[]>,
|
loadFunc?: () => Promise<ContextMenuModel[]>,
|
||||||
) => {
|
) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
setShowMobileMenu(true);
|
setShowMobileMenu(true);
|
||||||
if (loadFunc) setOnLoad(loadFunc);
|
|
||||||
|
const res = loadFunc ? await loadFunc() : items;
|
||||||
|
setMobileSubMenuItems(res);
|
||||||
|
|
||||||
|
setMobileHeader(label);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onBackClick = (e: React.MouseEvent<HTMLDivElement>) => {
|
const onBackClick = (e: React.MouseEvent<HTMLDivElement>) => {
|
||||||
@ -517,7 +531,7 @@ const ContextMenu = React.forwardRef<ContextMenuRefType, ContextMenuProps>(
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<Text className="text" truncate dir="auto">
|
<Text className="text" truncate dir="auto">
|
||||||
{header.title}
|
{showMobileMenu ? mobileHeader : header.title}
|
||||||
</Text>
|
</Text>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -527,7 +541,7 @@ const ContextMenu = React.forwardRef<ContextMenuRefType, ContextMenuProps>(
|
|||||||
root
|
root
|
||||||
resetMenu={resetMenu}
|
resetMenu={resetMenu}
|
||||||
onLeafClick={onLeafClick}
|
onLeafClick={onLeafClick}
|
||||||
onLoad={onLoad}
|
mobileSubMenuItems={mobileSubMenuItems}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<SubMenu
|
<SubMenu
|
||||||
@ -535,8 +549,9 @@ const ContextMenu = React.forwardRef<ContextMenuRefType, ContextMenuProps>(
|
|||||||
root
|
root
|
||||||
resetMenu={resetMenu}
|
resetMenu={resetMenu}
|
||||||
onLeafClick={onLeafClick}
|
onLeafClick={onLeafClick}
|
||||||
changeView={changeView}
|
|
||||||
onMobileItemClick={onMobileItemClick}
|
onMobileItemClick={onMobileItemClick}
|
||||||
|
changeView={changeView}
|
||||||
|
withHeader={withHeader}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -44,9 +44,9 @@ const MobileSubMenu = (props: {
|
|||||||
onLeafClick: (e: React.MouseEvent) => void;
|
onLeafClick: (e: React.MouseEvent) => void;
|
||||||
root?: boolean;
|
root?: boolean;
|
||||||
resetMenu: boolean;
|
resetMenu: boolean;
|
||||||
onLoad?: () => Promise<ContextMenuModel[]>;
|
mobileSubMenuItems?: ContextMenuModel[];
|
||||||
}) => {
|
}) => {
|
||||||
const { onLeafClick, root, resetMenu, onLoad } = props;
|
const { onLeafClick, root, resetMenu, mobileSubMenuItems } = props;
|
||||||
|
|
||||||
const [submenu, setSubmenu] = useState<null | ContextMenuModel[]>(null);
|
const [submenu, setSubmenu] = useState<null | ContextMenuModel[]>(null);
|
||||||
|
|
||||||
@ -91,16 +91,12 @@ const MobileSubMenu = (props: {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const fetchSubMenu = React.useCallback(async () => {
|
|
||||||
const res = await onLoad?.();
|
|
||||||
if (res) setSubmenu(res);
|
|
||||||
|
|
||||||
position();
|
|
||||||
}, [position, setSubmenu, onLoad]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (onLoad) fetchSubMenu();
|
if (!mobileSubMenuItems?.length) return;
|
||||||
}, [onLoad, fetchSubMenu]);
|
|
||||||
|
setSubmenu(mobileSubMenuItems);
|
||||||
|
position();
|
||||||
|
}, [mobileSubMenuItems, mobileSubMenuItems?.length, position]);
|
||||||
|
|
||||||
const onItemClick = (e: React.MouseEvent, item: ContextMenuType) => {
|
const onItemClick = (e: React.MouseEvent, item: ContextMenuType) => {
|
||||||
const { disabled, url, onClick, items, action } = item;
|
const { disabled, url, onClick, items, action } = item;
|
||||||
|
@ -33,20 +33,22 @@ import { useTheme } from "styled-components";
|
|||||||
import ArrowIcon from "PUBLIC_DIR/images/arrow.right.react.svg";
|
import ArrowIcon from "PUBLIC_DIR/images/arrow.right.react.svg";
|
||||||
import OutsdideIcon from "PUBLIC_DIR/images/arrow.outside.react.svg";
|
import OutsdideIcon from "PUBLIC_DIR/images/arrow.outside.react.svg";
|
||||||
import { isMobile as isMobileDevice } from "react-device-detect";
|
import { isMobile as isMobileDevice } from "react-device-detect";
|
||||||
|
import { classNames, ObjectUtils, DomHelpers, isMobile } from "../../../utils";
|
||||||
import { classNames, ObjectUtils, DomHelpers } from "../../../utils";
|
|
||||||
import { ContextMenuSkeleton } from "../../../skeletons/context-menu";
|
import { ContextMenuSkeleton } from "../../../skeletons/context-menu";
|
||||||
|
|
||||||
import { Scrollbar } from "../../scrollbar";
|
|
||||||
import { ToggleButton } from "../../toggle-button";
|
import { ToggleButton } from "../../toggle-button";
|
||||||
|
import { Scrollbar } from "../../scrollbar";
|
||||||
|
|
||||||
import { SubMenuItem } from "../ContextMenu.styled";
|
import { SubMenuItem, StyledList } from "../ContextMenu.styled";
|
||||||
import {
|
import {
|
||||||
ContextMenuModel,
|
ContextMenuModel,
|
||||||
ContextMenuType,
|
ContextMenuType,
|
||||||
SeparatorType,
|
SeparatorType,
|
||||||
} from "../ContextMenu.types";
|
} from "../ContextMenu.types";
|
||||||
|
|
||||||
|
const submenuListMargin = 4; // Indentation of the second level menu from the first level
|
||||||
|
const sectionPadding = 16; // Screen margin
|
||||||
|
|
||||||
const SubMenu = (props: {
|
const SubMenu = (props: {
|
||||||
model: ContextMenuModel[];
|
model: ContextMenuModel[];
|
||||||
root?: boolean;
|
root?: boolean;
|
||||||
@ -57,23 +59,28 @@ const SubMenu = (props: {
|
|||||||
) => void;
|
) => void;
|
||||||
onMobileItemClick?: (
|
onMobileItemClick?: (
|
||||||
e: React.MouseEvent | React.ChangeEvent<HTMLInputElement>,
|
e: React.MouseEvent | React.ChangeEvent<HTMLInputElement>,
|
||||||
loadFunc: () => Promise<ContextMenuModel[]>,
|
label: string,
|
||||||
|
items?: ContextMenuModel[],
|
||||||
|
loadFunc?: () => Promise<ContextMenuModel[]>,
|
||||||
) => void;
|
) => void;
|
||||||
changeView?: boolean;
|
|
||||||
onLoad?: () => Promise<ContextMenuModel[]>;
|
onLoad?: () => Promise<ContextMenuModel[]>;
|
||||||
|
changeView?: boolean;
|
||||||
|
withHeader?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
onLeafClick,
|
onLeafClick,
|
||||||
root,
|
root,
|
||||||
resetMenu,
|
resetMenu,
|
||||||
changeView,
|
|
||||||
onMobileItemClick,
|
onMobileItemClick,
|
||||||
onLoad,
|
onLoad,
|
||||||
|
changeView,
|
||||||
|
withHeader,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const [model, setModel] = useState(props?.model);
|
const [model, setModel] = useState(props?.model);
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [activeItem, setActiveItem] = useState<ContextMenuType | null>(null);
|
const [activeItem, setActiveItem] = useState<ContextMenuType | null>(null);
|
||||||
|
const [widthSubMenu, setWidthSubMenu] = useState<null | number>(null);
|
||||||
|
|
||||||
const subMenuRef = useRef<HTMLUListElement>(null);
|
const subMenuRef = useRef<HTMLUListElement>(null);
|
||||||
|
|
||||||
@ -92,15 +99,19 @@ const SubMenu = (props: {
|
|||||||
e: React.MouseEvent | React.ChangeEvent<HTMLInputElement>,
|
e: React.MouseEvent | React.ChangeEvent<HTMLInputElement>,
|
||||||
item: ContextMenuType,
|
item: ContextMenuType,
|
||||||
) => {
|
) => {
|
||||||
const { url, onClick, items, action } = item;
|
const { disabled, url, onClick, items, action, label } = item;
|
||||||
|
|
||||||
if (item.onLoad) {
|
if (isMobile() && label && (items || item.onLoad)) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
if (!isMobileDevice) return;
|
if (items) onMobileItemClick?.(e, label as string, items, undefined);
|
||||||
|
else if (item.onLoad)
|
||||||
onMobileItemClick?.(e, item.onLoad);
|
onMobileItemClick?.(e, label as string, undefined, item.onLoad);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disabled) {
|
||||||
|
e.preventDefault();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +137,9 @@ const SubMenu = (props: {
|
|||||||
const containerOffset = DomHelpers.getOffset(parentItem);
|
const containerOffset = DomHelpers.getOffset(parentItem);
|
||||||
const viewport = DomHelpers.getViewport();
|
const viewport = DomHelpers.getViewport();
|
||||||
|
|
||||||
const subListWidth = subMenuRef.current?.offsetParent
|
const options = subMenuRef.current?.getElementsByClassName("p-menuitem");
|
||||||
|
|
||||||
|
let subListWidth = subMenuRef.current?.offsetParent
|
||||||
? subMenuRef.current.offsetWidth
|
? subMenuRef.current.offsetWidth
|
||||||
: DomHelpers.getHiddenElementOuterWidth(subMenuRef.current);
|
: DomHelpers.getHiddenElementOuterWidth(subMenuRef.current);
|
||||||
|
|
||||||
@ -136,42 +149,90 @@ const SubMenu = (props: {
|
|||||||
|
|
||||||
const isRtl = theme.interfaceDirection === "rtl";
|
const isRtl = theme.interfaceDirection === "rtl";
|
||||||
|
|
||||||
|
if (!isMobile() && options) {
|
||||||
|
const optionsWidth: number[] = [];
|
||||||
|
Array.from(options).forEach((option) =>
|
||||||
|
optionsWidth.push(Math.ceil(option.getBoundingClientRect().width)),
|
||||||
|
);
|
||||||
|
|
||||||
|
const widthMaxContent = Math.max(...optionsWidth);
|
||||||
|
|
||||||
|
if (root) subListWidth = subListWidth || widthMaxContent;
|
||||||
|
else if (!subMenuRef?.current?.style.width)
|
||||||
|
subListWidth = Math.max(subListWidth, widthMaxContent);
|
||||||
|
}
|
||||||
|
|
||||||
if (subMenuRef.current) {
|
if (subMenuRef.current) {
|
||||||
subMenuRef.current.style.top = "0px";
|
let subMenuRefTop = null;
|
||||||
|
|
||||||
|
if (!isMobile()) {
|
||||||
|
if (root) subMenuRef.current.style.width = `${subListWidth}px`;
|
||||||
|
else if (!subMenuRef?.current?.style.width) {
|
||||||
|
subMenuRef.current.style.width = `${subListWidth}px`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isMobile() && !root) {
|
||||||
|
const firstList = parentItem?.firstChild as HTMLElement;
|
||||||
|
|
||||||
|
const menuItemActive = firstList.querySelector(
|
||||||
|
".p-menuitem-active",
|
||||||
|
) as HTMLElement;
|
||||||
|
|
||||||
|
const top = menuItemActive.offsetTop;
|
||||||
|
const scroller = firstList.querySelector(".scroller") as HTMLElement;
|
||||||
|
const scrollTop = scroller.scrollTop;
|
||||||
|
const positionActiveItem = top - scrollTop;
|
||||||
|
|
||||||
|
subMenuRefTop = positionActiveItem - 2;
|
||||||
|
subMenuRef.current.style.top = `${subMenuRefTop}px`;
|
||||||
|
}
|
||||||
|
|
||||||
const submenuRects = subMenuRef.current.getBoundingClientRect();
|
const submenuRects = subMenuRef.current.getBoundingClientRect();
|
||||||
|
|
||||||
if (submenuRects.bottom > viewport.height) {
|
if (submenuRects.bottom > viewport.height && subMenuRefTop) {
|
||||||
const submenuMargin = 16;
|
const submenuMargin = 16;
|
||||||
const topOffset = submenuRects.bottom - viewport.height + submenuMargin;
|
|
||||||
|
|
||||||
subMenuRef.current.style.top = `${-1 * topOffset}px`;
|
const topOffset =
|
||||||
|
subMenuRefTop -
|
||||||
|
(submenuRects.bottom - viewport.height) -
|
||||||
|
submenuMargin;
|
||||||
|
|
||||||
|
subMenuRef.current.style.top = `${topOffset}px`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const containerOffsetLeft = parseInt(`${containerOffset.left}`, 10);
|
const containerOffsetLeft = parseInt(`${containerOffset.left}`, 10);
|
||||||
const freeSpaceRight =
|
const freeSpaceRight =
|
||||||
viewport.width - containerOffsetLeft - itemOuterWidth;
|
viewport.width - containerOffsetLeft - itemOuterWidth;
|
||||||
const freeSpaceLeft = containerOffsetLeft;
|
const freeSpaceLeft = containerOffsetLeft;
|
||||||
const submenuListMargin = 4;
|
|
||||||
const sectionPadding = 17;
|
|
||||||
|
|
||||||
if (isRtl) {
|
if (isRtl) {
|
||||||
if (
|
|
||||||
!root &&
|
|
||||||
freeSpaceLeft > freeSpaceRight &&
|
|
||||||
subListWidth > containerOffsetLeft
|
|
||||||
) {
|
|
||||||
// If the menu extends beyond the screen
|
|
||||||
subMenuRef.current.style.width = `${containerOffsetLeft - submenuListMargin - sectionPadding}px`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
subListWidth < containerOffsetLeft ||
|
subListWidth < containerOffsetLeft ||
|
||||||
(!root && freeSpaceLeft > freeSpaceRight)
|
(!root && freeSpaceLeft > freeSpaceRight)
|
||||||
) {
|
) {
|
||||||
subMenuRef.current.style.left = `${-1 * subListWidth}px`;
|
subMenuRef.current.style.left = `${-1 * subListWidth}px`;
|
||||||
|
|
||||||
|
if (!root && subListWidth > containerOffsetLeft) {
|
||||||
|
// If the menu extends beyond the screen
|
||||||
|
const newWidth =
|
||||||
|
containerOffsetLeft - submenuListMargin - sectionPadding;
|
||||||
|
|
||||||
|
subMenuRef.current.style.width = `${newWidth}px`;
|
||||||
|
setWidthSubMenu(newWidth);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
subMenuRef.current.style.left = `${itemOuterWidth}px`;
|
subMenuRef.current.style.left = `${itemOuterWidth}px`;
|
||||||
|
|
||||||
|
if (!root) subMenuRef.current.style.marginLeft = `4px`;
|
||||||
|
|
||||||
|
if (!root && subListWidth > freeSpaceRight) {
|
||||||
|
// If the menu extends beyond the screen
|
||||||
|
const newWidth = freeSpaceRight - 3 * submenuListMargin;
|
||||||
|
|
||||||
|
subMenuRef.current.style.width = `${newWidth}px`;
|
||||||
|
setWidthSubMenu(newWidth);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,8 +241,22 @@ const SubMenu = (props: {
|
|||||||
viewport.width - DomHelpers.calculateScrollbarWidth();
|
viewport.width - DomHelpers.calculateScrollbarWidth();
|
||||||
|
|
||||||
if (!isRtl) {
|
if (!isRtl) {
|
||||||
if (notEnoughWidthRight && containerOffsetLeft > subListWidth) {
|
if (notEnoughWidthRight && freeSpaceLeft > freeSpaceRight) {
|
||||||
subMenuRef.current.style.left = `${-1 * subListWidth}px`;
|
subMenuRef.current.style.left = `${-1 * subListWidth}px`;
|
||||||
|
|
||||||
|
if (!root) subMenuRef.current.style.marginLeft = `-4px`;
|
||||||
|
|
||||||
|
if (
|
||||||
|
notEnoughWidthRight &&
|
||||||
|
!root &&
|
||||||
|
subListWidth > containerOffsetLeft
|
||||||
|
) {
|
||||||
|
// If the menu extends beyond the screen
|
||||||
|
const newWidth = containerOffsetLeft - 12;
|
||||||
|
|
||||||
|
subMenuRef.current.style.width = `${newWidth}px`;
|
||||||
|
setWidthSubMenu(newWidth);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
subMenuRef.current.style.left = `${itemOuterWidth}px`;
|
subMenuRef.current.style.left = `${itemOuterWidth}px`;
|
||||||
|
|
||||||
@ -195,6 +270,7 @@ const SubMenu = (props: {
|
|||||||
sectionPadding;
|
sectionPadding;
|
||||||
|
|
||||||
subMenuRef.current.style.width = `${newWidth}px`;
|
subMenuRef.current.style.width = `${newWidth}px`;
|
||||||
|
setWidthSubMenu(newWidth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -231,29 +307,6 @@ const SubMenu = (props: {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
const renderSubMenu = (item: ContextMenuType) => {
|
|
||||||
const loaderItem = {
|
|
||||||
id: "link-loader-option",
|
|
||||||
key: "link-loader",
|
|
||||||
isLoader: true,
|
|
||||||
label: <ContextMenuSkeleton />,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (item.items || item.onLoad) {
|
|
||||||
return (
|
|
||||||
<SubMenu
|
|
||||||
model={item.onLoad ? [loaderItem] : item.items || []}
|
|
||||||
resetMenu={item !== activeItem}
|
|
||||||
onLeafClick={onLeafClick}
|
|
||||||
// onEnter={onEnter}
|
|
||||||
onLoad={item.onLoad}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderMenuitem = (
|
const renderMenuitem = (
|
||||||
item: ContextMenuType,
|
item: ContextMenuType,
|
||||||
index: number,
|
index: number,
|
||||||
@ -301,7 +354,7 @@ const SubMenu = (props: {
|
|||||||
const subMenuIcon = (item.items || item.onLoad) && (
|
const subMenuIcon = (item.items || item.onLoad) && (
|
||||||
<ArrowIcon className={subMenuIconClassName} />
|
<ArrowIcon className={subMenuIconClassName} />
|
||||||
);
|
);
|
||||||
const subMenu = renderSubMenu(item);
|
|
||||||
const dataKeys = Object.fromEntries(
|
const dataKeys = Object.fromEntries(
|
||||||
Object.entries(item).filter((el) => el[0].indexOf("data-") === 0),
|
Object.entries(item).filter((el) => el[0].indexOf("data-") === 0),
|
||||||
);
|
);
|
||||||
@ -367,7 +420,6 @@ const SubMenu = (props: {
|
|||||||
onMouseEnter={(e) => onItemMouseEnter(e, item)}
|
onMouseEnter={(e) => onItemMouseEnter(e, item)}
|
||||||
>
|
>
|
||||||
{content}
|
{content}
|
||||||
{subMenu}
|
|
||||||
<ToggleButton
|
<ToggleButton
|
||||||
isChecked={item.checked || false}
|
isChecked={item.checked || false}
|
||||||
onChange={onClick}
|
onChange={onClick}
|
||||||
@ -389,7 +441,6 @@ const SubMenu = (props: {
|
|||||||
onMouseEnter={(e) => onItemMouseEnter(e, item)}
|
onMouseEnter={(e) => onItemMouseEnter(e, item)}
|
||||||
>
|
>
|
||||||
{content}
|
{content}
|
||||||
{subMenu}
|
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -428,78 +479,100 @@ const SubMenu = (props: {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const renderMenu = () => {
|
const renderMenu = () => {
|
||||||
if (model) {
|
if (!model) return null;
|
||||||
if (changeView) {
|
|
||||||
const newModel = model.filter(
|
return model.map((item: ContextMenuModel, index: number) => {
|
||||||
(item: ContextMenuModel) => item && !item.disabled,
|
if (item?.disabled) return null;
|
||||||
|
return renderItem(item, index);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderSubMenuLower = () => {
|
||||||
|
if (!model) return null;
|
||||||
|
const submenu: JSX.Element[] = [];
|
||||||
|
|
||||||
|
const loaderItem = {
|
||||||
|
id: "link-loader-option",
|
||||||
|
key: "link-loader",
|
||||||
|
isLoader: true,
|
||||||
|
label: <ContextMenuSkeleton />,
|
||||||
|
};
|
||||||
|
|
||||||
|
model.forEach((item) => {
|
||||||
|
const contextMenuTypeItem = item as ContextMenuType;
|
||||||
|
|
||||||
|
if (contextMenuTypeItem?.items || contextMenuTypeItem?.onLoad) {
|
||||||
|
submenu.push(
|
||||||
|
<SubMenu
|
||||||
|
key={`sub-menu_${item.id}`}
|
||||||
|
model={
|
||||||
|
contextMenuTypeItem?.onLoad
|
||||||
|
? [loaderItem]
|
||||||
|
: contextMenuTypeItem?.items || []
|
||||||
|
}
|
||||||
|
resetMenu={item !== activeItem}
|
||||||
|
onLeafClick={onLeafClick}
|
||||||
|
onLoad={contextMenuTypeItem?.onLoad}
|
||||||
|
/>,
|
||||||
);
|
);
|
||||||
const rowHeights: number[] = newModel.map((item: ContextMenuModel) => {
|
|
||||||
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 + 5;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Scrollbar style={{ height: listHeight }}>
|
|
||||||
{model.map((item: ContextMenuModel, index: number) => {
|
|
||||||
if (!item || item?.disabled) return null;
|
|
||||||
|
|
||||||
return renderItem(item, index);
|
|
||||||
})}
|
|
||||||
</Scrollbar>
|
|
||||||
);
|
|
||||||
|
|
||||||
// return (
|
|
||||||
// <VariableSizeList
|
|
||||||
// height={listHeight}
|
|
||||||
// width={"auto"}
|
|
||||||
// itemCount={newModel.length}
|
|
||||||
// itemSize={getItemSize}
|
|
||||||
// itemData={newModel}
|
|
||||||
// outerElementType={CustomScrollbarsVirtualList}
|
|
||||||
// >
|
|
||||||
// {renderItem}
|
|
||||||
// </VariableSizeList>
|
|
||||||
// );
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return model.map((item: ContextMenuModel, index: number) => {
|
return submenu;
|
||||||
if (item?.disabled) return null;
|
|
||||||
return renderItem(item, index);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const className = classNames({ "p-submenu-list": !root });
|
const className = classNames({ "p-submenu-list": !root });
|
||||||
const submenu = renderMenu();
|
const submenu = renderMenu();
|
||||||
const active = isActive();
|
const active = isActive();
|
||||||
|
const submenuLower = renderSubMenuLower();
|
||||||
|
|
||||||
return (
|
if (model.length) {
|
||||||
<CSSTransition
|
const newModel = model.filter(
|
||||||
nodeRef={subMenuRef}
|
(item: ContextMenuModel) => item && !item.disabled,
|
||||||
classNames="p-contextmenusub"
|
);
|
||||||
in={active}
|
const rowHeights: number[] = newModel.map((item: ContextMenuModel) => {
|
||||||
timeout={{ enter: 0, exit: 0 }}
|
if (!item) return 0;
|
||||||
unmountOnExit
|
if (item.isSeparator) return 13;
|
||||||
onEnter={onEnter}
|
return 36;
|
||||||
>
|
});
|
||||||
<ul ref={subMenuRef} className={`${className} not-selectable`}>
|
|
||||||
{submenu}
|
const height = rowHeights.reduce((a, b) => a + b);
|
||||||
</ul>
|
const viewport = DomHelpers.getViewport();
|
||||||
</CSSTransition>
|
const paddingList = 12;
|
||||||
);
|
const marginsList = 32;
|
||||||
|
const backdrop = 64;
|
||||||
|
const header = 55;
|
||||||
|
|
||||||
|
const listHeight =
|
||||||
|
changeView && withHeader
|
||||||
|
? height + paddingList + header > viewport.height
|
||||||
|
? viewport.height - backdrop - header - paddingList
|
||||||
|
: height + paddingList
|
||||||
|
: height + paddingList + marginsList > viewport.height
|
||||||
|
? viewport.height - marginsList
|
||||||
|
: height + paddingList;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CSSTransition
|
||||||
|
nodeRef={subMenuRef}
|
||||||
|
classNames="p-contextmenusub"
|
||||||
|
in={active}
|
||||||
|
timeout={{ enter: 0, exit: 0 }}
|
||||||
|
unmountOnExit
|
||||||
|
onEnter={onEnter}
|
||||||
|
>
|
||||||
|
<StyledList
|
||||||
|
ref={subMenuRef}
|
||||||
|
className={`${className} not-selectable`}
|
||||||
|
listHeight={height + paddingList}
|
||||||
|
widthSubMenu={widthSubMenu}
|
||||||
|
>
|
||||||
|
<Scrollbar style={{ height: listHeight }}>{submenu}</Scrollbar>
|
||||||
|
{submenuLower}
|
||||||
|
</StyledList>
|
||||||
|
</CSSTransition>
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export { SubMenu };
|
export { SubMenu };
|
||||||
|
@ -2511,9 +2511,8 @@ export const getBaseTheme = () => {
|
|||||||
},
|
},
|
||||||
separator: {
|
separator: {
|
||||||
borderBottom: `1px solid ${grayLightMid} !important`,
|
borderBottom: `1px solid ${grayLightMid} !important`,
|
||||||
margin: "6px 16px 6px 16px !important",
|
margin: "6px 16px !important",
|
||||||
height: "1px !important",
|
height: "1px !important",
|
||||||
width: "calc(100% - 32px) !important",
|
|
||||||
},
|
},
|
||||||
text: {
|
text: {
|
||||||
header: {
|
header: {
|
||||||
@ -2534,7 +2533,7 @@ export const getBaseTheme = () => {
|
|||||||
background: "none",
|
background: "none",
|
||||||
svgFill: black,
|
svgFill: black,
|
||||||
header: {
|
header: {
|
||||||
height: "49px",
|
height: "55px",
|
||||||
borderBottom: `1px solid ${grayLightMid}`,
|
borderBottom: `1px solid ${grayLightMid}`,
|
||||||
marginBottom: "6px",
|
marginBottom: "6px",
|
||||||
},
|
},
|
||||||
@ -2544,7 +2543,7 @@ export const getBaseTheme = () => {
|
|||||||
padding: "0 12px",
|
padding: "0 12px",
|
||||||
mobile: {
|
mobile: {
|
||||||
height: "36px",
|
height: "36px",
|
||||||
padding: "0 16px 6px",
|
padding: "6px 16px",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
newContextMenu: {
|
newContextMenu: {
|
||||||
@ -2552,7 +2551,6 @@ export const getBaseTheme = () => {
|
|||||||
borderRadius: "6px",
|
borderRadius: "6px",
|
||||||
mobileBorderRadius: "6px 6px 0 0",
|
mobileBorderRadius: "6px 6px 0 0",
|
||||||
boxShadow: `0px 8px 16px 0px ${boxShadowColor}`,
|
boxShadow: `0px 8px 16px 0px ${boxShadowColor}`,
|
||||||
padding: "6px 0px",
|
|
||||||
border: "none",
|
border: "none",
|
||||||
devices: {
|
devices: {
|
||||||
maxHeight: "calc(100vh - 64px)",
|
maxHeight: "calc(100vh - 64px)",
|
||||||
|
@ -2498,7 +2498,6 @@ const Dark: TTheme = {
|
|||||||
borderBottom: `1px solid ${grayDarkStrong} !important`,
|
borderBottom: `1px solid ${grayDarkStrong} !important`,
|
||||||
margin: "6px 16px 6px 16px !important",
|
margin: "6px 16px 6px 16px !important",
|
||||||
height: "1px !important",
|
height: "1px !important",
|
||||||
width: "calc(100% - 32px) !important",
|
|
||||||
},
|
},
|
||||||
text: {
|
text: {
|
||||||
header: {
|
header: {
|
||||||
@ -2519,7 +2518,7 @@ const Dark: TTheme = {
|
|||||||
background: "none",
|
background: "none",
|
||||||
svgFill: white,
|
svgFill: white,
|
||||||
header: {
|
header: {
|
||||||
height: "49px",
|
height: "55px",
|
||||||
borderBottom: `1px solid ${grayDarkStrong}`,
|
borderBottom: `1px solid ${grayDarkStrong}`,
|
||||||
marginBottom: "6px",
|
marginBottom: "6px",
|
||||||
},
|
},
|
||||||
@ -2529,7 +2528,7 @@ const Dark: TTheme = {
|
|||||||
padding: "0 12px",
|
padding: "0 12px",
|
||||||
mobile: {
|
mobile: {
|
||||||
height: "36px",
|
height: "36px",
|
||||||
padding: "0 16px 6px",
|
padding: "6px 16px",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
newContextMenu: {
|
newContextMenu: {
|
||||||
@ -2537,7 +2536,6 @@ const Dark: TTheme = {
|
|||||||
borderRadius: "6px",
|
borderRadius: "6px",
|
||||||
mobileBorderRadius: "6px 6px 0 0",
|
mobileBorderRadius: "6px 6px 0 0",
|
||||||
boxShadow: `0px 8px 16px 0px ${boxShadowDarkColor}`,
|
boxShadow: `0px 8px 16px 0px ${boxShadowDarkColor}`,
|
||||||
padding: "6px 0px",
|
|
||||||
border: `1px solid ${grayDarkStrong}`,
|
border: `1px solid ${grayDarkStrong}`,
|
||||||
devices: {
|
devices: {
|
||||||
maxHeight: "calc(100vh - 64px)",
|
maxHeight: "calc(100vh - 64px)",
|
||||||
|
Loading…
Reference in New Issue
Block a user