From e153478f6eb22bf8503d5f2509a6816f2afda954 Mon Sep 17 00:00:00 2001 From: KristinaKasyanovskaya Date: Fri, 9 Aug 2024 00:35:54 +0500 Subject: [PATCH 1/2] feat:update toggle button style --- .../ToggleButtonGroup.module.less | 96 +++++++---- .../ToggleButtonGroup/ToggleButtonGroup.tsx | 162 +++++++++++++++--- 2 files changed, 206 insertions(+), 52 deletions(-) diff --git a/packages/ketcher-react/src/components/ToggleButtonGroup/ToggleButtonGroup.module.less b/packages/ketcher-react/src/components/ToggleButtonGroup/ToggleButtonGroup.module.less index 06504a3dbe..49e48aad88 100644 --- a/packages/ketcher-react/src/components/ToggleButtonGroup/ToggleButtonGroup.module.less +++ b/packages/ketcher-react/src/components/ToggleButtonGroup/ToggleButtonGroup.module.less @@ -14,33 +14,71 @@ * limitations under the License. ***************************************************************************/ -@import '../../style/mixins.less'; -@import '../../style/variables.less'; - -.button { - .btn(); - - cursor: pointer; - height: 24px; - white-space: nowrap; - font-size: 12px; - color: @color-grey-6!important; - border-color: @color-grey-6!important; - text-transform: none!important; - - &:hover { - color: @color-spec-button-primary-hover!important; - } -} - -.button.selected, -.button:active { - background: @color-primary!important; - color: #fff!important; - - &:hover { - background-color: @color-spec-button-primary-hover!important; - } -} - + @import '../../style/mixins.less'; + @import '../../style/variables.less'; + .button { + .btn(); + + cursor: pointer; + height: 28px!important; + white-space: nowrap; + font-size: 12px; + color: @color-grey-6!important; + background-color: #F3F8F9!important; + text-transform: none!important; + margin: 2px!important; + border-color: transparent!important; + + &:hover { + background-color: #E1E5EA!important; + } + } + + .button.selected, + .button:active { + background: @color-primary!important; + color: #fff!important; + + &:hover { + background-color: @color-spec-button-primary-hover!important; + } + } + + + .buttonGroupContainer { + display: inline-flex!important; + flex-direction: column!important; + align-items: start!important; + padding: 2px!important; + box-sizing: border-box!important; + } + + .textButtonGroupColumn { + flex-direction: column; + width: 101px!important; + } + + .textButtonGroupRow { + flex-direction: row; + } + + .buttonGroupContainerSpecific { + width: auto!important; + box-sizing: border-box!important; + } + + .buttonSpecific { + height: 28px!important; + } + + .contexify { + min-width: 0 !important; + } + + .contexify_submenu[data-target-label-submenu="true"] { + min-width: 0 !important; + width: 109px !important; + padding: 4px; + } + \ No newline at end of file diff --git a/packages/ketcher-react/src/components/ToggleButtonGroup/ToggleButtonGroup.tsx b/packages/ketcher-react/src/components/ToggleButtonGroup/ToggleButtonGroup.tsx index 4c475bd6b1..a7b27fa202 100644 --- a/packages/ketcher-react/src/components/ToggleButtonGroup/ToggleButtonGroup.tsx +++ b/packages/ketcher-react/src/components/ToggleButtonGroup/ToggleButtonGroup.tsx @@ -1,7 +1,14 @@ import { ToggleButton, ToggleButtonGroup } from '@mui/material'; import classes from './ToggleButtonGroup.module.less'; import clsx from 'clsx'; -import { useCallback, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; +import { useContextMenu } from 'react-contexify'; + +const STRICT_TARGET_LABELS = [ + ['Unsaturated', 'Saturated'], + ['none', 'aromatic', 'aliphatic'], + ['none', 'anticlockwise', 'clockwise'], +]; export default function ButtonGroup({ buttons, @@ -12,36 +19,145 @@ export default function ButtonGroup({ onClick: (value: T) => void; defaultValue: T; }) { - const [value, setValue] = useState(defaultValue); + useContextMenu({ id: 'context-menu-id' }); + + const [value, setValue] = useState(defaultValue); const handleChange = useCallback( - (event: React.MouseEvent, value: T) => { + (event: React.MouseEvent, newValue: T) => { event.stopPropagation(); - onClick(value); - setValue(value); + onClick(newValue); + setValue(newValue); }, [onClick], ); + const filterTextButtons = (buttons: { label: string; value: T }[]) => + buttons.filter( + ({ label }) => isNaN(Number(label.trim())) || label.trim() === '', + ); + + const filterNumericButtons = (buttons: { label: string; value: T }[]) => + buttons.filter( + ({ label }) => !isNaN(Number(label.trim())) && label.trim() !== '', + ); + + const textButtons = filterTextButtons(buttons); + const numericButtons = filterNumericButtons(buttons); + + const getButtonClass = (buttonValue: T) => + clsx(classes.button, { + [classes.buttonSpecific]: + textButtons.length > 0 && numericButtons.length === 0, + [classes.textButton]: textButtons.some( + ({ value }) => value === buttonValue, + ), + [classes.numericButton]: numericButtons.some( + ({ value }) => value === buttonValue, + ), + [classes.selected]: buttonValue === value, + }); + + const applyStylesToTargetLabelSubmenus = () => { + const submenus = document.querySelectorAll('.contexify_submenu'); + submenus.forEach((submenu) => { + const items = Array.from(submenu.querySelectorAll('.MuiButtonBase-root')); + const itemLabels = items + .map((item) => item.textContent?.trim()) + .filter((label): label is string => !!label); + + const isTargetSubmenu = STRICT_TARGET_LABELS.some( + (targetLabels) => + targetLabels.length === itemLabels.length && + targetLabels.every((label, index) => label === itemLabels[index]), + ); + + if (isTargetSubmenu) { + const submenuElement = submenu as HTMLElement; + submenuElement.setAttribute('data-target-label-submenu', 'true'); + submenuElement.style.setProperty('min-width', '0px', 'important'); + } + }); + }; + + useEffect(() => { + const observer = new MutationObserver((mutations) => { + mutations.forEach((mutation) => { + if (mutation.addedNodes.length) { + applyStylesToTargetLabelSubmenus(); + } + }); + }); + + observer.observe(document.body, { childList: true, subtree: true }); + + return () => { + observer.disconnect(); + }; + }, [textButtons, numericButtons]); + + useEffect(() => { + const contextMenuHandler = () => { + applyStylesToTargetLabelSubmenus(); + }; + + document.addEventListener('contextmenu', contextMenuHandler); + + return () => { + document.removeEventListener('contextmenu', contextMenuHandler); + }; + }, []); + return ( - 0 && numericButtons.length > 0, + [classes.buttonGroupContainerOnlyText]: + textButtons.length > 0 && numericButtons.length === 0, + })} + id="context-menu-id" > - {buttons.map(({ label, value: buttonValue }) => ( - handleChange(event, buttonValue)} - className={clsx(classes.button, { - [classes.selected]: buttonValue === value, - })} - style={{ flex: '1 0 25%', margin: '2px', borderRadius: '3px' }} - > - {label || 'none'} - - ))} - + 0 && numericButtons.length === 0, + [classes.textButtonGroupRow]: numericButtons.length > 0, + })} + value={value} + onChange={(_, newValue) => newValue !== null && setValue(newValue)} + > + {textButtons.map(({ label, value: buttonValue }) => ( + + buttonValue !== undefined && handleChange(event, buttonValue) + } + className={getButtonClass(buttonValue)} + style={{ margin: '3px', borderRadius: '3px' }} + > + {label || 'none'} + + ))} + +
+ {numericButtons.map(({ label, value: buttonValue }) => ( + + buttonValue !== undefined && handleChange(event, buttonValue) + } + className={getButtonClass(buttonValue)} + > + {label} + + ))} +
+ ); } From 408171b35a54dd0406dbb8ed8f3e5f065f1f4260 Mon Sep 17 00:00:00 2001 From: KristinaKasyanovskaya Date: Tue, 13 Aug 2024 13:06:47 +0500 Subject: [PATCH 2/2] feat: add changes in modal window styles --- .../ToggleButtonGroup.module.less | 30 +++++++------------ .../ContextMenu/ContextMenu.module.less | 15 ++++------ .../ketcher-react/src/style/variables.less | 4 +-- 3 files changed, 17 insertions(+), 32 deletions(-) diff --git a/packages/ketcher-react/src/components/ToggleButtonGroup/ToggleButtonGroup.module.less b/packages/ketcher-react/src/components/ToggleButtonGroup/ToggleButtonGroup.module.less index 49e48aad88..624ec2a207 100644 --- a/packages/ketcher-react/src/components/ToggleButtonGroup/ToggleButtonGroup.module.less +++ b/packages/ketcher-react/src/components/ToggleButtonGroup/ToggleButtonGroup.module.less @@ -23,7 +23,7 @@ cursor: pointer; height: 28px!important; white-space: nowrap; - font-size: 12px; + font-size: 14px; color: @color-grey-6!important; background-color: #F3F8F9!important; text-transform: none!important; @@ -62,23 +62,13 @@ .textButtonGroupRow { flex-direction: row; } - - .buttonGroupContainerSpecific { - width: auto!important; - box-sizing: border-box!important; - } - - .buttonSpecific { - height: 28px!important; - } - - .contexify { - min-width: 0 !important; - } - + +.buttonSpecific { + height: 28px!important; +} + .contexify_submenu[data-target-label-submenu="true"] { - min-width: 0 !important; - width: 109px !important; - padding: 4px; - } - \ No newline at end of file + min-width: 0 !important; + width: 109px !important; + padding: 4px; +} diff --git a/packages/ketcher-react/src/script/ui/views/components/ContextMenu/ContextMenu.module.less b/packages/ketcher-react/src/script/ui/views/components/ContextMenu/ContextMenu.module.less index ba7f568820..6b085918fb 100644 --- a/packages/ketcher-react/src/script/ui/views/components/ContextMenu/ContextMenu.module.less +++ b/packages/ketcher-react/src/script/ui/views/components/ContextMenu/ContextMenu.module.less @@ -21,20 +21,20 @@ .contextMenu { // Reference https://fkhadra.github.io/react-contexify/how-to-style --contexify-menu-bgColor: @color-background-primary; - --contexify-item-color: @color-text-secondary; + --contexify-item-color: @color-text-primary; --contexify-activeItem-color: @color-text-secondary; - --contexify-activeItem-bgColor: @color-dropdown-hover; + --contexify-activeItem-bgColor: @color-grey-3; --contexify-rightSlot-color: @color-text-secondary; --contexify-activeRightSlot-color: @color-text-secondary; - --contexify-arrow-color: @color-grey-5; - --contexify-activeArrow-color: @color-grey-5; + --contexify-arrow-color: @color-text-primary; + --contexify-activeArrow-color: @color-text-primary; --contexify-menu-shadow: 0 2px 5px 0 rgba(@main-color, 0.54); --contexify-zIndex: 1; --contexify-menu-minWidth: 160px; --contexify-menu-padding: 4px; --contexify-menu-radius: 4px; --contexify-menu-negatePadding: var(--contexify-menu-padding); - --contexify-itemContent-padding: 3px 20px; + --contexify-itemContent-padding: @item-content-padding; --contexify-activeItem-radius: 0; position: fixed; @@ -81,9 +81,4 @@ margin: 3px 0; } - .subMenu { - :global(.contexify_rightSlot) { - margin-right: -15px; - } - } } diff --git a/packages/ketcher-react/src/style/variables.less b/packages/ketcher-react/src/style/variables.less index ee6c01d503..03f20dfd10 100644 --- a/packages/ketcher-react/src/style/variables.less +++ b/packages/ketcher-react/src/style/variables.less @@ -36,7 +36,7 @@ @margin-left-right: 12px; @padding-modal: 12px; - +@item-content-padding: 3px 0 3px 13px; @color-gray: #dddddd; //using for changing color of SVG for checkboxes and radiobuttons @@ -213,4 +213,4 @@ @atom-periodic-noble-gas: #c2ffff; @atom-periodic-lanthanide: #f4c8f4; @atom-periodic-actinide: #fd98cb; -@atom-periodic-unknown-properties: #e8e8e8; +@atom-periodic-unknown-properties: #e8e8e8; \ No newline at end of file