Shared:ContextMenu:Add max width context menu. Added trimming of overflowing text with ellipsis.

This commit is contained in:
Vlada Gazizova 2024-06-07 12:46:07 +03:00
parent 87a95b6d42
commit a0483cbd4c
5 changed files with 73 additions and 24 deletions

View File

@ -26,7 +26,7 @@
import styled, { css } from "styled-components";
import { Base, TTheme } from "../../themes";
import { tablet, mobile, getCorrectFourValuesStyle } from "../../utils";
import { mobile, isMobile, getCorrectFourValuesStyle } from "../../utils";
const styledTabletView = css<{ articleWidth: number }>`
position: fixed;
@ -116,11 +116,22 @@ const StyledContextMenu = styled.div<{
${(props) => props.changeView && styledMobileView}
}
@media ${mobile} {
${(props) => props.changeView && styledMobileView}
}
.scroll-body {
display: flex;
flex-direction: column;
justify-content: center;
padding-inline-end: 0 !important;
}
${!isMobile() &&
css`
max-width: calc(100vw - 32px);
`}
}
.contextmenu-header {
@ -212,6 +223,11 @@ const StyledContextMenu = styled.div<{
margin: 0;
padding: 0;
list-style: none;
${!isMobile() &&
css`
max-width: calc(100vw - 32px);
`}
}
.p-contextmenu .p-submenu-list {
@ -291,22 +307,23 @@ const StyledContextMenu = styled.div<{
cursor: default !important;
margin: ${(props) => props.theme.menuItem.separator.margin};
height: ${(props) => props.theme.menuItem.separator.height};
width: ${(props) => props.theme.menuItem.separator.width};
&:hover {
cursor: default !important;
}
@media ${mobile} {
margin-right: 8px !important;
width: calc(100% - 24px) !important;
}
}
.p-contextmenu .p-menuitem {
position: relative;
margin: ${(props) => props.theme.dropDownItem.margin};
min-width: max-content;
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 {
@ -399,12 +416,23 @@ StyledContextMenu.defaultProps = {
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 };

View File

@ -296,7 +296,7 @@ const ContextMenu = React.forwardRef((props: ContextMenuProps, ref) => {
}
}
if (menuRef.current) {
menuRef.current.style.left = `${left}px`;
menuRef.current.style.left = `${left || 16}px`;
menuRef.current.style.top = `${top}px`;
if (!mobileView) menuRef.current.style.width = `${width}px`;

View File

@ -67,6 +67,7 @@ const SubMenu = (props: {
const [model, setModel] = useState(props?.model);
const [isLoading, setIsLoading] = useState(false);
const [activeItem, setActiveItem] = useState<ContextMenuType | null>(null);
const [widthSubMenu, setWidthSubMenu] = useState<null | number>(null);
const subMenuRef = useRef<HTMLUListElement>(null);
@ -185,25 +186,33 @@ const SubMenu = (props: {
viewport.width - containerOffsetLeft - itemOuterWidth;
const freeSpaceLeft = containerOffsetLeft;
const submenuListMargin = 4;
const sectionPadding = 17;
const sectionPadding = 16;
if (isRtl) {
if (
!root &&
freeSpaceLeft > freeSpaceRight &&
subListWidth > containerOffsetLeft
) {
// If the menu extends beyond the screen
subMenuRef.current.style.width = `${containerOffsetLeft - submenuListMargin - sectionPadding}px`;
}
if (
subListWidth < containerOffsetLeft ||
(!root && freeSpaceLeft > freeSpaceRight)
) {
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 {
subMenuRef.current.style.left = `${itemOuterWidth}px`;
if (!root && subListWidth > freeSpaceRight) {
// If the menu extends beyond the screen
const newWidth = freeSpaceRight - 3 * submenuListMargin;
subMenuRef.current.style.width = `${newWidth}px`;
setWidthSubMenu(newWidth);
}
}
}
@ -212,8 +221,20 @@ const SubMenu = (props: {
viewport.width - DomHelpers.calculateScrollbarWidth();
if (!isRtl) {
if (notEnoughWidthRight && containerOffsetLeft > subListWidth) {
if (notEnoughWidthRight && freeSpaceLeft > freeSpaceRight) {
subMenuRef.current.style.left = `${-1 * subListWidth}px`;
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 {
subMenuRef.current.style.left = `${itemOuterWidth}px`;
@ -227,6 +248,7 @@ const SubMenu = (props: {
sectionPadding;
subMenuRef.current.style.width = `${newWidth}px`;
setWidthSubMenu(newWidth);
}
}
}
@ -504,6 +526,7 @@ const SubMenu = (props: {
ref={subMenuRef}
className={`${className} not-selectable`}
listHeight={height + paddingList}
widthSubMenu={widthSubMenu}
>
<Scrollbar style={{ height: listHeight }}>{submenu}</Scrollbar>
{submenuLower}

View File

@ -2760,9 +2760,8 @@ export const getBaseTheme = () => {
},
separator: {
borderBottom: `1px solid ${grayLightMid} !important`,
margin: "6px 0px 6px 16px !important",
margin: "6px 16px !important",
height: "1px !important",
width: "calc(100% - 16px) !important",
},
text: {
header: {

View File

@ -2739,9 +2739,8 @@ const Dark: TTheme = {
},
separator: {
borderBottom: `1px solid #474747 !important`,
margin: "6px 0px 6px 16px !important",
margin: "6px 16px !important",
height: "1px !important",
width: "calc(100% - 16px) !important",
},
text: {
header: {