Skip to content

Commit

Permalink
#4048 - Right-click menu appears away from structure or is not visibl…
Browse files Browse the repository at this point in the history
…e at all on canvas (#4062)

* #4048 - Right-click menu appears away from structure or is not visible at all on canvas #4048

- added rendering of context menus out of element with container-type: size
- added moving context menu if it does not fit ketcher editor root element

---------

Co-authored-by: Roman Rodionov <roman_rodionov@epam.com>
  • Loading branch information
rrodionov91 and rrodionov91 authored Feb 9, 2024
1 parent d21854f commit 6022471
Show file tree
Hide file tree
Showing 16 changed files with 164 additions and 83 deletions.
9 changes: 6 additions & 3 deletions example/src/ModeControl/ModeControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
import { useState, useRef } from 'react';
import styled from '@emotion/styled';
import { Button, Popover } from '@mui/material';
import { Icon } from 'ketcher-react';
import { Icon, KETCHER_ROOT_NODE_CSS_SELECTOR } from 'ketcher-react';
import { KETCHER_MACROMOLECULES_ROOT_NODE_SELECTOR } from 'ketcher-macromolecules';

interface IStyledIconProps {
expanded?: boolean;
Expand Down Expand Up @@ -99,7 +100,6 @@ const ModeLabel = styled('span')`
`;

const ModeControlButton = styled('div')`
width: 162px;
height: 28px;
display: flex;
align-items: center;
Expand Down Expand Up @@ -185,7 +185,10 @@ export const ModeControl = ({ toggle, isPolymerEditor }: ModeProps) => {
open={isExpanded}
onClose={onClose}
anchorEl={btnRef.current}
container={btnRef.current}
container={
document.querySelector(KETCHER_ROOT_NODE_CSS_SELECTOR) ||
document.querySelector(KETCHER_MACROMOLECULES_ROOT_NODE_SELECTOR)
}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ async function atomDefaultSettings(page: Page) {

async function ringBondCountQuery(page: Page, menuItem: string) {
await page.getByText(menuItem).click();
await page.locator('button:nth-child(5)').first().click();
await page
.getByRole('menuitem', { name: 'Ring bond count', exact: true })
.getByTestId('3-option')
.click();
}

async function substitutionCountQuery(page: Page, menuItem: string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1560,7 +1560,7 @@ test.describe('Atom Properties', () => {
// eslint-disable-next-line no-magic-numbers
const atomIndices = [2, 4, 5];
// eslint-disable-next-line no-magic-numbers
const optionIndices = [2, 5, 11];
const optionIndices = ['As drawn-option', '3-option', '9-option'];

await drawBenzeneRing(page);

Expand Down Expand Up @@ -1737,7 +1737,7 @@ test.describe('Atom Properties', () => {
// eslint-disable-next-line no-magic-numbers
const anyAtom = [0, 1, 2, 3, 4, 5];
// eslint-disable-next-line no-magic-numbers
const optionIndex = [3, 2, 3, 'Unsaturated', 7, 'aliphatic'];
const optionIndex = ['0-option', 2, 3, 'Unsaturated', 7, 'aliphatic'];

await drawBenzeneRing(page);

Expand All @@ -1747,7 +1747,7 @@ test.describe('Atom Properties', () => {

switch (i) {
case 0:
await selectRingBondCountOption(page, atomIndex, option as number);
await selectRingBondCountOption(page, atomIndex, option as string);
break;
case 1:
await selectHCountOption(page, atomIndex, option as number);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,15 @@ export async function selectElementFromExtendedTable(
export async function selectRingBondCountOption(
page: Page,
atomIndex: number,
optionIndex: number,
optionTestId: string,
) {
await clickOnAtom(page, 'C', atomIndex, 'right');
await page.getByText('Query properties').click();
await page.getByText('Ring bond count').click();
await page.locator(`button:nth-child(${optionIndex})`).first().click();
await page
.getByRole('menuitem', { name: 'Ring bond count', exact: true })
.getByTestId(optionTestId)
.click();
await resetCurrentTool(page);
}

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import { IconButton } from 'ketcher-react';
import styled from '@emotion/styled';
import { EditorQuerySelector } from '../../constants';
import { KETCHER_MACROMOLECULES_ROOT_NODE_SELECTOR } from '../../constants';
import { useState } from 'react';

const requestFullscreen = (element: HTMLElement) => {
Expand Down Expand Up @@ -61,7 +61,8 @@ export const FullscreenButton = (props) => {
const toggleFullscreen = () => {
// TODO: add selector / ref prop when will be shared component
const fullscreenElement: HTMLElement =
document.querySelector(EditorQuerySelector) || document.documentElement;
document.querySelector(KETCHER_MACROMOLECULES_ROOT_NODE_SELECTOR) ||
document.documentElement;
fullScreenMode ? exitFullscreen() : requestFullscreen(fullscreenElement);
setFullScreenMode(!fullScreenMode);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const RowMain = styled.div(({ theme }) => ({
display: 'flex',
justifyContent: 'space-between',
columnGap: '12px',
containerType: 'size',
}));

const Row = styled.div(({ theme }) => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import { fireEvent, render, screen } from '@testing-library/react';
import { ModalContainer } from 'components/modal/modalContainer';
import { RnaBuilder } from 'components/monomerLibrary/RnaBuilder';
import { MONOMER_TYPES } from 'src/constants';
import { EditorClassName, MONOMER_TYPES } from 'src/constants';
import mockedPresets from './mockedPresets.json';

jest.mock('../../../src/helpers/dom.ts', () => {
Expand Down Expand Up @@ -70,11 +70,13 @@ describe('RNA ContextMenu', () => {
it('should render contextMenu correctly', () => {
render(
withThemeAndStoreProvider(
<RnaBuilder
libraryName={MONOMER_TYPES.RNA}
duplicatePreset={duplicatePreset}
editPreset={editPreset}
/>,
<div className={EditorClassName}>
<RnaBuilder
libraryName={MONOMER_TYPES.RNA}
duplicatePreset={duplicatePreset}
editPreset={editPreset}
/>
</div>,
{
library: {
searchFilter: '',
Expand All @@ -95,11 +97,13 @@ describe('RNA ContextMenu', () => {
it("should disable 'Delete Preset' menu when trying to delete default preset", () => {
render(
withThemeAndStoreProvider(
<RnaBuilder
libraryName={MONOMER_TYPES.RNA}
duplicatePreset={duplicatePreset}
editPreset={editPreset}
/>,
<div className={EditorClassName}>
<RnaBuilder
libraryName={MONOMER_TYPES.RNA}
duplicatePreset={duplicatePreset}
editPreset={editPreset}
/>
</div>,
{
library: {
searchFilter: '',
Expand All @@ -121,7 +125,7 @@ describe('RNA ContextMenu', () => {
it("should enable 'Delete Preset' when trying to delete non-default preset", () => {
render(
withThemeAndStoreProvider(
<div>
<div className={EditorClassName}>
<RnaBuilder
libraryName={MONOMER_TYPES.RNA}
duplicatePreset={duplicatePreset}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { CONTEXT_MENU_ID } from './types';
import { selectCurrentTabIndex, setSelectedTabIndex } from 'state/library';
import { selectActivePresetForContextMenu } from 'state/rna-builder';
import { StyledMenu } from './styles';
import { createPortal } from 'react-dom';
import { KETCHER_MACROMOLECULES_ROOT_NODE_SELECTOR } from '../../constants';

export const RNAContextMenu = () => {
const RNA_TAB_INDEX = 2;
Expand Down Expand Up @@ -72,7 +74,16 @@ export const RNAContextMenu = () => {
return items;
};

return (
<StyledMenu id={CONTEXT_MENU_ID.FOR_RNA}>{assembleMenuItems()}</StyledMenu>
const ketcherEditorRootElement = document.querySelector(
KETCHER_MACROMOLECULES_ROOT_NODE_SELECTOR,
);

return ketcherEditorRootElement
? createPortal(
<StyledMenu id={CONTEXT_MENU_ID.FOR_RNA}>
{assembleMenuItems()}
</StyledMenu>,
ketcherEditorRootElement,
)
: null;
};
2 changes: 1 addition & 1 deletion packages/ketcher-macromolecules/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export type LibraryNameType =
| keyof typeof MONOMER_TYPES;

export const EditorClassName = 'Ketcher-polymer-editor-root';
export const EditorQuerySelector = `.${EditorClassName}`;
export const KETCHER_MACROMOLECULES_ROOT_NODE_SELECTOR = `.${EditorClassName}`;

export const preview = {
width: 230,
Expand Down
1 change: 1 addition & 0 deletions packages/ketcher-macromolecules/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@
***************************************************************************/

export * from './Editor';
export * from './constants';
1 change: 0 additions & 1 deletion packages/ketcher-macromolecules/src/styledComponents.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import styled from '@emotion/styled';

export const EditorWrapper = styled.div(() => ({
containerType: 'size',
height: '100%',
}));
2 changes: 0 additions & 2 deletions packages/ketcher-react/src/Editor.module.less
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@
Arial, sans-serif;
background-color: @color-background-canvas-light;
color: @main-color;
/* stylelint-disable-next-line */
container-type: size;

select {
padding: 0 8px !important;
Expand Down
2 changes: 2 additions & 0 deletions packages/ketcher-react/src/script/ui/App/App.module.less
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
'toolbar-bottom toolbar-bottom toolbar-bottom';
grid-template-columns: minmax(36px, max-content) 1fr minmax(36px, max-content);
grid-template-rows: auto 1fr auto;
/* stylelint-disable-next-line */
container-type: size;
}

.canvas {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,6 @@ export const AbbreviationLookup = ({ options }: Props) => {
);

useLayoutEffect(() => {
inputRef.current?.focus();

const containerHeight = autocompleteRef.current?.offsetHeight ?? 0;
const containerWidth = autocompleteRef.current?.offsetWidth ?? 0;

Expand All @@ -98,6 +96,8 @@ export const AbbreviationLookup = ({ options }: Props) => {
top: `${top}px`,
});

inputRef.current?.focus();

// TODO extract to a separate hook or utils
return () => {
(
Expand Down
Loading

0 comments on commit 6022471

Please sign in to comment.