diff --git a/src/component/elements/DropdownMenu.tsx b/src/component/elements/DropdownMenu.tsx new file mode 100644 index 0000000000..288156ed17 --- /dev/null +++ b/src/component/elements/DropdownMenu.tsx @@ -0,0 +1,39 @@ +import { + Menu, + MenuItem, + MenuItemProps, + Popover, + PopoverProps, +} from '@blueprintjs/core'; + +export interface DropdownMenuItem extends MenuItemProps { + data?: object; +} + +export interface DropdownMenuProps + extends Omit { + options: DropdownMenuItem[]; + onSelect: (data?: object) => void; +} + +export function DropdownMenu(props: DropdownMenuProps) { + const { options, onSelect, children, ...other } = props; + + const content = ( + + {options.map((option) => ( + onSelect(option?.data)} + /> + ))} + + ); + + return ( + + {children} + + ); +} diff --git a/src/component/elements/ToolbarMenu.tsx b/src/component/elements/ToolbarMenu.tsx deleted file mode 100644 index e71e56a44b..0000000000 --- a/src/component/elements/ToolbarMenu.tsx +++ /dev/null @@ -1,188 +0,0 @@ -/** @jsxImportSource @emotion/react */ -import { css } from '@emotion/react'; -import { - ReactNode, - useState, - useCallback, - useRef, - useLayoutEffect, -} from 'react'; -import { Toolbar } from 'react-science/ui'; - -import { BoundingBox } from './MenuButton'; - -const menuStyles = css` - .menu { - box-shadow: 0 0 10px rgb(0 0 0 / 50%); - margin: 0; - border-radius: 5px; - display: flex; - flex-direction: column; - position: absolute; - z-index: 99999; - padding: 2px; - background-color: white; - - button:hover { - background-color: #fafafa; - } - } - - .menu-cover { - position: fixed; - width: 100%; - height: 100%; - top: 0; - left: 0; - z-index: 1; - } - - .menu-item { - background-color: transparent; - border: none; - border-bottom: 0.55px solid whitesmoke; - height: 35px; - outline: outline; - display: table-cell; - vertical-align: middle; - text-align: left; - padding: 0 10px; - - svg { - display: inline-block; - } - - :focus { - outline: none !important; - } - - span { - font-size: 10px; - padding: 0 10px; - } - } -`; - -interface MenuItemProps { - icon: ReactNode; - label: string; - onClick?: () => void; -} - -function MenuItem({ icon, label, onClick }: MenuItemProps) { - return ( - - ); -} - -interface MenuListProps { - items: Array; - onClick: (element: MenuItemProps & { id: string }) => void; - boxBounding?: BoundingBox; -} - -function MenuList({ - items, - boxBounding = { x: 0, y: 0, width: 0, height: 0 }, - onClick, -}: MenuListProps) { - const listRef = useRef(); - const [translate, setTranslate] = useState({ - x: boxBounding.width, - y: boxBounding.height, - }); - - useLayoutEffect(() => { - const boxSize = listRef.current.getBoundingClientRect(); - setTranslate((oldTransform) => { - let y = boxBounding.height; - if (boxSize.bottom > window.innerHeight) { - y = boxBounding.height * 2 + (boxSize.bottom - window.innerHeight); - } - return { - ...oldTransform, - y, - }; - }); - }, [boxBounding.height]); - - return ( -
- {items?.map((item) => { - return ( - onClick(item)} /> - ); - })} -
- ); -} - -interface MenuButtonProps { - component: ReactNode; - toolTip: string; - items?: Array; - onClick?: (element: MenuItemProps & { id: string }) => void; -} - -export default function ToolbarMenu({ - component, - toolTip = '', - items = [], - onClick = () => null, -}: MenuButtonProps) { - const menuButtonRef = useRef(null); - const [isShown, showMenu] = useState(false); - - const closeMenuButton = useCallback(() => { - showMenu(false); - }, []); - - const handleClick = useCallback(() => { - showMenu((flag) => !flag); - }, []); - - const clickHandler = useCallback( - (e) => { - showMenu(false); - onClick(e); - }, - [onClick], - ); - - const boxBounding = useCallback(() => { - return menuButtonRef.current?.getBoundingClientRect(); - }, []); - - return ( -
-
- - {component} - -
- {isShown && ( - - )} - - {isShown &&
} -
- ); -} diff --git a/src/component/header/Header.tsx b/src/component/header/Header.tsx index b81768de73..5ffb0d7db0 100644 --- a/src/component/header/Header.tsx +++ b/src/component/header/Header.tsx @@ -154,7 +154,7 @@ function HeaderInner(props: HeaderInnerProps) { }} >
- +
@@ -179,15 +179,14 @@ function HeaderInner(props: HeaderInnerProps) { {!general?.hideLogs && }
- + {!general?.hideHelp && ( window.open(docsBaseUrl, '_blank')} - > - - + icon={} + /> )} {!hideGeneralSettings && ( @@ -199,9 +198,8 @@ function HeaderInner(props: HeaderInnerProps) { onClick={onEnableFullscreen} title="Full Screen" className="windowButton" - > - - + icon={} + /> )}
diff --git a/src/component/modal/aboutUs/AboutUsModal.tsx b/src/component/modal/aboutUs/AboutUsModal.tsx index c1948076a6..58128cf620 100644 --- a/src/component/modal/aboutUs/AboutUsModal.tsx +++ b/src/component/modal/aboutUs/AboutUsModal.tsx @@ -96,11 +96,11 @@ function AboutUsModal() { <> */} - - + icon={} + /> + = { }, }; -const LabelWrapper = ({ children }) => { - return

{children}

; -}; - -const MOL_EXPORT_MENU: DropdownMenuProps<{ id: string }, void>['options'] = [ +const MOL_EXPORT_MENU: DropdownMenuProps['options'] = [ { - type: 'option', icon: , - label: Copy as molfile V3, + text: 'Copy as molfile V3', data: { id: 'molfileV3', }, }, { - type: 'option', icon: , - label: Copy as molfile V2, + text: 'Copy as molfile V2', data: { id: 'molfileV2', }, }, { - type: 'option', icon: , - label: Copy as PNG, + text: 'Copy as PNG', data: { id: 'png', }, }, { - type: 'option', icon: , - label: Export as SVG, + text: 'Export as SVG', data: { id: 'svg', }, @@ -145,7 +137,7 @@ export default function MoleculePanelHeader({ (selected) => { const molecule = molecules?.[currentIndex]; if (molecule) { - switch (selected?.data.id) { + switch (selected?.id) { case 'molfileV3': saveAsMolHandler(molecule.molfile); break; @@ -222,11 +214,7 @@ export default function MoleculePanelHeader({ {renderSource === 'predictionPanel' && } {renderSource === 'moleculePanel' && ( - + , - label: 'Import from file system (Press Ctrl + O)', + text: 'Import from file system (Press Ctrl + O)', + data: { + id: 'importFile', + }, }, { - id: 'importJDX', icon: , - label: 'Add JCAMP-DX from URL', + text: 'Add JCAMP-DX from URL', + data: { + id: 'importJDX', + }, }, { - id: 'importPublicationString', icon: , - label: 'Import from publication string', + text: 'Import from publication string', + data: { + id: 'importPublicationString', + }, }, { - id: 'importMetaInformation', icon: , - label: 'Import meta information', + text: 'Import meta information', + data: { + id: 'importMetaInformation', + }, }, ]; -const EXPORT_MENU = [ +const EXPORT_MENU: DropdownMenuProps['options'] = [ { - id: 'svg', icon: , - label: 'Export as SVG', + text: 'Export as SVG', + data: { + id: 'svg', + }, }, { - id: 'png', icon: , - label: 'Export as PNG', + text: 'Export as PNG', + data: { + id: 'png', + }, }, { - id: 'json', icon: , - label: 'Save data ( Press Ctrl + S )', + text: 'Save data ( Press Ctrl + S )', + data: { + id: 'json', + }, }, { - id: 'advance_save', icon: , - label: 'Save data as ( Press Ctrl + Shift + S )', + text: 'Save data as ( Press Ctrl + Shift + S )', + data: { + id: 'advance_save', + }, }, { - id: 'nmre', icon: , - label: 'Save NMRE data', + text: 'Save NMRE data', + data: { + id: 'nmre', + }, }, { - id: 'copy', icon: , - label: 'Copy image to Clipboard ( Press Ctrl + C )', + text: 'Copy image to Clipboard ( Press Ctrl + C )', + data: { + id: 'copy', + }, }, ]; @@ -207,26 +227,25 @@ function BasicToolBarInner({ /> {isButtonVisible('import') && ( - } - toolTip="Import" - onClick={(element) => { - importHandler(element); - return null; + { + importHandler(data); }} - items={importMenu} - /> + options={importMenu} + > + } /> + )} {isButtonVisible('exportAs') && ( - } - toolTip="Export As" - onClick={(element) => { - exportHandler(element); - return null; + { + exportHandler(data); }} - items={exportMenu} - /> + options={exportMenu} + > + } /> + )} {isButtonVisible('spectraStackAlignments') && ftCounter > 1 && ( @@ -235,13 +254,14 @@ function BasicToolBarInner({ className="cheminfo" title="Spectra alignment ( Press s )" onClick={changeDisplayViewModeHandler} - > - {verticalAlign === 'stack' ? ( - - ) : ( - - )} - + icon={ + verticalAlign === 'stack' ? ( + + ) : ( + + ) + } + /> )} {isButtonVisible('realImaginary') && ( - - + icon={} + /> )} {isButtonVisible('spectraCenterAlignments') && (ftCounter > 0 || fidCounter > 0) && ( @@ -264,15 +283,16 @@ function BasicToolBarInner({ } onClick={alignSpectrumsVerticallyHandler} className="cheminfo" - > -
- {verticalAlign === 'bottom' ? ( - - ) : ( - - )} -
- + icon={ +
+ {verticalAlign === 'bottom' ? ( + + ) : ( + + )} +
+ } + /> )} ); diff --git a/src/component/toolbar/FunctionToolBar.tsx b/src/component/toolbar/FunctionToolBar.tsx index c5741d92f2..b5d52f8cf1 100644 --- a/src/component/toolbar/FunctionToolBar.tsx +++ b/src/component/toolbar/FunctionToolBar.tsx @@ -88,9 +88,8 @@ function FunctionToolBarInner({ id="zoom-out" onClick={handleFullZoomOut} title="Horizontal zoom out ( Press f ), Horizontal and Vertical zoom out, double click ( Press ff )" - > - - + icon={} + /> )} {isButtonVisible('peakPicking') && ( @@ -229,9 +228,8 @@ function FunctionToolBarInner({ className="cheminfo" title={`${options.fft.label} ( Press t )`} onClick={handleOnFFTFilter} - > - - + icon={} + /> )} {isButtonVisible('fftDimension1') && ( - - + icon={} + /> )} {isButtonVisible('fftDimension2') && ( - - + icon={} + /> )} ); diff --git a/src/component/toolbar/ToolBar.tsx b/src/component/toolbar/ToolBar.tsx index 560af98390..3621b264bc 100644 --- a/src/component/toolbar/ToolBar.tsx +++ b/src/component/toolbar/ToolBar.tsx @@ -12,7 +12,7 @@ interface ToolBarInnerProps { function ToolBarInner({ selectedTool }: ToolBarInnerProps) { return ( - +