From 877ae591cebd44f703a67dd67f0d039488d3ace0 Mon Sep 17 00:00:00 2001 From: hamed musallam Date: Fri, 10 Jan 2025 10:57:42 +0100 Subject: [PATCH 1/8] refactor: use styled emotion --- src/component/1d-2d/FieldEdition.tsx | 16 ++-- src/component/1d/ExclusionZoneAnnotation.tsx | 8 +- src/component/1d/FooterBanner.tsx | 11 ++- src/component/1d/LinesSeries.tsx | 8 +- src/component/1d/XAxis.tsx | 15 ++-- src/component/1d/YAxis.tsx | 10 +-- .../1d/integral/IntegralResizable.tsx | 36 ++------ .../elements/ActionsButtonsPopover.tsx | 39 ++++----- src/component/elements/Alert.tsx | 1 - src/component/elements/DialogBody.tsx | 10 +++ src/component/elements/Label.tsx | 11 +-- src/component/elements/NextPrev.tsx | 87 ++++++++++--------- .../dropDownButton/DropDownButton.tsx | 15 ++-- .../elements/export/ExportOptionsModal.tsx | 10 +-- src/component/elements/print/PrintContent.tsx | 10 +-- src/component/hooks/useSaveSettings.tsx | 1 - src/component/modal/AboutPredictionModal.tsx | 11 ++- .../modal/AboutSpectrumSimulationModal.tsx | 11 +-- src/component/modal/CopyClipboardModal.tsx | 12 +-- src/component/modal/EditPeakShapeModal.tsx | 12 +-- src/component/modal/ExportAsJcampModal.tsx | 12 +-- .../modal/ImportPublicationStringModal.tsx | 9 +- src/component/modal/LoadJCAMPModal.tsx | 11 +-- src/component/modal/LogsHistoryModal.tsx | 11 +-- .../modal/MoleculeStructureEditorModal.tsx | 11 +-- .../modal/MultipletAnalysisModal.tsx | 18 ++-- src/component/modal/PredictSpectraModal.tsx | 12 ++- src/component/modal/SaveAsModal.tsx | 10 +-- .../changeSum/ChangeSumModalContents.tsx | 22 ++--- .../editRange/forms/components/SignalTab.tsx | 20 ++--- .../modal/editZone/EditZoneModal.tsx | 11 +-- .../modal/setting/GeneralSettings.tsx | 62 +++++++------ .../panels/SpectraPanel/SpectraTabs.tsx | 21 +++-- .../base/setting/Spectrum2DSetting.tsx | 36 ++++---- .../editLink/Confirmation.tsx | 9 +- .../CorrelationTable/editLink/MoveLink.tsx | 9 +- .../DatabaseStructureSearchModal.tsx | 12 +-- .../reducer/actions/DomainActions.ts | 8 +- src/demo/test/TestHighlight.tsx | 38 ++++---- src/utils/clipboard/clipboardComponents.tsx | 12 +-- 40 files changed, 289 insertions(+), 399 deletions(-) create mode 100644 src/component/elements/DialogBody.tsx diff --git a/src/component/1d-2d/FieldEdition.tsx b/src/component/1d-2d/FieldEdition.tsx index b90244ef1c..55444ba5c5 100644 --- a/src/component/1d-2d/FieldEdition.tsx +++ b/src/component/1d-2d/FieldEdition.tsx @@ -1,7 +1,6 @@ -/** @jsxImportSource @emotion/react */ import type { PopoverProps } from '@blueprintjs/core'; -import { Popover } from '@blueprintjs/core'; -import { css } from '@emotion/react'; +import { Popover as BasePopover } from '@blueprintjs/core'; +import styled from '@emotion/styled'; import { yupResolver } from '@hookform/resolvers/yup'; import type { ReactNode } from 'react'; import { useState } from 'react'; @@ -11,6 +10,12 @@ import * as Yup from 'yup'; import { Input2Controller } from '../elements/Input2Controller.js'; import { NumberInput2Controller } from '../elements/NumberInput2Controller.js'; +const Popover = styled(BasePopover)` + .field-edition-popover { + border-radius: 5px; + } +`; + type InputType = 'number' | 'text'; interface FieldProps { @@ -52,11 +57,6 @@ export function FieldEdition(props: FieldEditionsProps) { return ( setIsOpen(false)} diff --git a/src/component/1d/ExclusionZoneAnnotation.tsx b/src/component/1d/ExclusionZoneAnnotation.tsx index d630e601c8..9f6d738a26 100644 --- a/src/component/1d/ExclusionZoneAnnotation.tsx +++ b/src/component/1d/ExclusionZoneAnnotation.tsx @@ -1,5 +1,4 @@ -/** @jsxImportSource @emotion/react */ -import { css } from '@emotion/react'; +import styled from '@emotion/styled'; import { Filters1D } from 'nmr-processing'; import { memo } from 'react'; @@ -16,7 +15,7 @@ interface ExclusionZoneProps { filterId: string; } -const style = css` +const Rect = styled.rect` &:hover { fill: #ff6f0057 !important; } @@ -43,9 +42,8 @@ function ExclusionZoneAnnotation({ return ( - width - margin.right || position.y > height - margin.bottom ) { - return
; + return ; } function getXIndex(xPosition) { @@ -135,7 +134,7 @@ function FooterBannerInner({ const isBrushing = step === 'brushing' && mouseButton === 'main'; return ( -
+
š¯›…: @@ -210,7 +209,7 @@ function FooterBannerInner({
)} -
+ ); } diff --git a/src/component/1d/LinesSeries.tsx b/src/component/1d/LinesSeries.tsx index 68910a9b33..6ea29adab9 100644 --- a/src/component/1d/LinesSeries.tsx +++ b/src/component/1d/LinesSeries.tsx @@ -1,5 +1,4 @@ -/** @jsxImportSource @emotion/react */ -import { css } from '@emotion/react'; +import styled from '@emotion/styled'; import type { Spectrum1D } from 'nmr-load-save'; import { get1DDataXY } from '../../data/data1d/Spectrum1D/get1DDataXY.js'; @@ -16,7 +15,7 @@ import { SPECTRA_BOTTOM_MARGIN } from './utilities/scale.js'; const BOX_SIZE = 10; -const style = css` +const Rect = styled.rect` fill: transparent; &:hover { @@ -76,8 +75,7 @@ function HeadlightRectStackMode(props: HeadlightRectStackModeProps) { } return ( - {show && ( - {label} - + )} {showGrid && ( - {show && ( - @@ -63,7 +61,7 @@ function YAxis(props: YAxisProps) { > {label} - + )} ); diff --git a/src/component/1d/integral/IntegralResizable.tsx b/src/component/1d/integral/IntegralResizable.tsx index d8cc813d61..17b15a1c0a 100644 --- a/src/component/1d/integral/IntegralResizable.tsx +++ b/src/component/1d/integral/IntegralResizable.tsx @@ -1,5 +1,4 @@ -/** @jsxImportSource @emotion/react */ -import { css } from '@emotion/react'; +import styled from '@emotion/styled'; import type { Integral } from 'nmr-processing'; import { useChartData } from '../../context/ChartContext.js'; @@ -11,21 +10,13 @@ import { useResizerStatus } from '../../hooks/useResizerStatus.js'; import { IntegralIndicator } from './IntegralIndicator.js'; -const stylesOnHover = css` - .highlight { - fill: transparent; +const Group = styled.g<{ isActive: boolean }>` + rect { + fill: ${(props) => (props.isActive ? '#ff6f0057' : 'transparent')}; } .target { - visibility: hidden; - } -`; - -const stylesHighlighted = css` - fill: #ff6f0057; - - .target { - visibility: visible; + visibility: ${(props) => (props.isActive ? 'visible' : 'hidden')}; } `; @@ -79,25 +70,14 @@ function IntegralResizable({ const width = x2 - x1; return ( - - + + - + ); }} diff --git a/src/component/elements/ActionsButtonsPopover.tsx b/src/component/elements/ActionsButtonsPopover.tsx index 7b0e9ccd67..46258d0ca1 100644 --- a/src/component/elements/ActionsButtonsPopover.tsx +++ b/src/component/elements/ActionsButtonsPopover.tsx @@ -1,12 +1,26 @@ -/** @jsxImportSource @emotion/react */ import type { PopoverProps } from '@blueprintjs/core'; import { Popover } from '@blueprintjs/core'; import type { Interpolation, Theme } from '@emotion/react'; -import { css } from '@emotion/react'; +import styled from '@emotion/styled'; import type { CSSProperties } from 'react'; import type { ButtonProps } from 'react-science/ui'; import { Button } from 'react-science/ui'; +const Container = styled.div>` + display: flex; + flex-direction: ${(props) => props.flexDirection}; + gap: ${(props) => props.gap}; + + button, + a[role='button'] { + border-radius: 50%; + min-width: 16px; + min-height: 16px; + font-size: 10px; + padding: 5px; + } +`; + export interface ActionsButtonsPopoverProps extends Omit { buttons: Array< @@ -42,24 +56,7 @@ export function ActionsButtonsPopover(props: ActionsButtonsPopoverProps) { interactionKind="hover" enforceFocus={false} content={ -
+ {buttons .filter((button) => button?.visible !== false) .map(({ title, visible, ...otherProps }, index) => ( @@ -69,7 +66,7 @@ export function ActionsButtonsPopover(props: ActionsButtonsPopoverProps) { {...otherProps} /> ))} -
+ } {...otherProps} > diff --git a/src/component/elements/Alert.tsx b/src/component/elements/Alert.tsx index ba4eb107be..8b5dab8b42 100644 --- a/src/component/elements/Alert.tsx +++ b/src/component/elements/Alert.tsx @@ -1,4 +1,3 @@ -/** @jsxImportSource @emotion/react */ import type { ButtonProps } from '@blueprintjs/core'; import { Button, Dialog, DialogBody, DialogFooter } from '@blueprintjs/core'; import styled from '@emotion/styled'; diff --git a/src/component/elements/DialogBody.tsx b/src/component/elements/DialogBody.tsx new file mode 100644 index 0000000000..82e4a1a8d2 --- /dev/null +++ b/src/component/elements/DialogBody.tsx @@ -0,0 +1,10 @@ +import { DialogBody as BaseDialogBody } from '@blueprintjs/core'; +import styled from '@emotion/styled'; +import type { CSSProperties } from 'react'; + +export const DialogBody = styled(BaseDialogBody)< + Pick +>` + padding: ${({ padding = '15px' }) => padding}; + background-color: ${({ backgroundColor = 'white' }) => backgroundColor}; +`; diff --git a/src/component/elements/Label.tsx b/src/component/elements/Label.tsx index 40642ddf54..44035150d3 100644 --- a/src/component/elements/Label.tsx +++ b/src/component/elements/Label.tsx @@ -1,9 +1,12 @@ -/** @jsxImportSource @emotion/react */ -import { css } from '@emotion/react'; +import styled from '@emotion/styled'; import type { CSSProperties, LabelHTMLAttributes, ReactNode } from 'react'; import Button from './Button.js'; +const ShortTitle = styled.span` + display: none; +`; + export interface LabelStyle { label?: CSSProperties; wrapper?: CSSProperties; @@ -53,9 +56,7 @@ export default function Label(props: LabelProps) { {title} )} {shortTitle && ( - - {shortTitle} - + {shortTitle} )} {description && ( void; style?: CSSProperties; } +const ArrowButton = styled.div<{ + direction: Direction; +}>` + display: inline-flex; + height: 40px; + width: 40px; + justify-content: center; + border-radius: 50%; + cursor: pointer; + align-items: center; + border: none; + transition: transform ease-in 0.1s; + background-color: #f7f7f7; + pointer-events: auto; + + &:hover { + transform: scale(1.1); + background-color: #607d8b !important; + color: white; + } + + img { + transform: translateX( + ${(props) => (props.direction === 'left' ? '-2' : '2')}px + ); + + &:focus { + outline: 0; + } + } +`; + function Arrow({ direction, onClick, style = {} }: ArrowProps) { return ( -
+ -
+ ); } @@ -72,6 +74,11 @@ const TransformController = styled.div<{ `, ); +const Content = styled.div<{ width: number }>` + width: ${(props) => props.width}px; + height: 100%; +`; + const transition = 0.45; interface NextPrevProps { @@ -141,15 +148,9 @@ export function NextPrev(props: NextPrevProps) { > {Children.map(children, (child: ReactElement) => { return ( -
+ {child} -
+ ); })} diff --git a/src/component/elements/dropDownButton/DropDownButton.tsx b/src/component/elements/dropDownButton/DropDownButton.tsx index 083ae00422..d75d538e45 100644 --- a/src/component/elements/dropDownButton/DropDownButton.tsx +++ b/src/component/elements/dropDownButton/DropDownButton.tsx @@ -1,12 +1,15 @@ -/** @jsxImportSource @emotion/react */ import { Popover, Button } from '@blueprintjs/core'; -import { css } from '@emotion/react'; +import styled from '@emotion/styled'; import type { CSSProperties, ReactNode } from 'react'; import { useEffect, useState } from 'react'; import { FaEllipsisH } from 'react-icons/fa'; import DropDownList from './DropDownList.js'; +const PopoverButton = styled(Button)` + border: 0.55px solid lightgray; + border-radius: 5px; +`; export interface DropDownListItem { key: string; label: string; @@ -80,17 +83,13 @@ function DropDownButton( /> } > - +
); } diff --git a/src/component/elements/export/ExportOptionsModal.tsx b/src/component/elements/export/ExportOptionsModal.tsx index 254e056d30..6e4a926882 100644 --- a/src/component/elements/export/ExportOptionsModal.tsx +++ b/src/component/elements/export/ExportOptionsModal.tsx @@ -1,15 +1,12 @@ -/** @jsxImportSource @emotion/react */ import { Button, Dialog, - DialogBody, DialogFooter, Radio, RadioGroup, SegmentedControl, Tag, } from '@blueprintjs/core'; -import { css } from '@emotion/react'; import { yupResolver } from '@hookform/resolvers/yup'; import type { AdvanceExportSettings, @@ -21,6 +18,7 @@ import { Controller, useForm } from 'react-hook-form'; import ActionButtons from '../ActionButtons.js'; import { CheckController } from '../CheckController.js'; +import { DialogBody } from '../DialogBody.js'; import type { LabelStyle } from '../Label.js'; import Label from '../Label.js'; import { NumberInput2Controller } from '../NumberInput2Controller.js'; @@ -160,11 +158,7 @@ function InnerExportOptionsModal(props: InnerExportOptionsModalProps) { canEscapeKeyClose autoFocus > - +
- + diff --git a/src/component/hooks/useSaveSettings.tsx b/src/component/hooks/useSaveSettings.tsx index edfee1c82d..f16693bbc1 100644 --- a/src/component/hooks/useSaveSettings.tsx +++ b/src/component/hooks/useSaveSettings.tsx @@ -1,4 +1,3 @@ -/** @jsxImportSource @emotion/react */ import { Dialog, DialogBody, DialogFooter } from '@blueprintjs/core'; import styled from '@emotion/styled'; import { yupResolver } from '@hookform/resolvers/yup'; diff --git a/src/component/modal/AboutPredictionModal.tsx b/src/component/modal/AboutPredictionModal.tsx index 23acee7844..5b67be6e17 100644 --- a/src/component/modal/AboutPredictionModal.tsx +++ b/src/component/modal/AboutPredictionModal.tsx @@ -1,12 +1,11 @@ -/** @jsxImportSource @emotion/react */ -import { Dialog, DialogBody } from '@blueprintjs/core'; -import { css } from '@emotion/react'; +import { Dialog } from '@blueprintjs/core'; +import styled from '@emotion/styled'; import { FaInfo } from 'react-icons/fa'; import { Toolbar, useOnOff } from 'react-science/ui'; -const styles = css` - background-color: white; +import { DialogBody as BasedDialogBody } from '../elements/DialogBody.js'; +const DialogBody = styled(BasedDialogBody)` ul { list-style-type: disc; margin-left: 25px; @@ -54,7 +53,7 @@ function AboutPredictionModal() { title="About prediction" style={{ width: '600px' }} > - +

If you are using our tools please cite us:

  • diff --git a/src/component/modal/AboutSpectrumSimulationModal.tsx b/src/component/modal/AboutSpectrumSimulationModal.tsx index 2192f54000..5f07f0cfac 100644 --- a/src/component/modal/AboutSpectrumSimulationModal.tsx +++ b/src/component/modal/AboutSpectrumSimulationModal.tsx @@ -1,10 +1,11 @@ -/** @jsxImportSource @emotion/react */ -import { Dialog, DialogBody } from '@blueprintjs/core'; -import { css } from '@emotion/react'; +import { Dialog } from '@blueprintjs/core'; +import styled from '@emotion/styled'; import { FaInfo } from 'react-icons/fa'; import { Toolbar, useOnOff } from 'react-science/ui'; -const styles = css` +import { DialogBody as BaseDialogBody } from '../elements/DialogBody.js'; + +const DialogBody = styled(BaseDialogBody)` background-color: white; ul { @@ -56,7 +57,7 @@ function AboutSpectrumSimulationModal() { title="About spectrum simulation" style={{ width: '600px' }} > - +

    If you are using our tools please cite us:

    • diff --git a/src/component/modal/CopyClipboardModal.tsx b/src/component/modal/CopyClipboardModal.tsx index e2596aa718..287f064911 100644 --- a/src/component/modal/CopyClipboardModal.tsx +++ b/src/component/modal/CopyClipboardModal.tsx @@ -1,9 +1,9 @@ -/** @jsxImportSource @emotion/react */ -import { Button, Dialog, DialogBody, DialogFooter } from '@blueprintjs/core'; -import { css } from '@emotion/react'; +import { Button, Dialog, DialogFooter } from '@blueprintjs/core'; import styled from '@emotion/styled'; import { FaCopy } from 'react-icons/fa'; +import { DialogBody } from '../elements/DialogBody.js'; + const Body = styled.div` padding: 5px; width: 100%; @@ -30,11 +30,7 @@ function InnerCopyClipboardModal(props: Required) { const { text, title, onClose, onCopyClick } = props; return ( - + diff --git a/src/component/modal/EditPeakShapeModal.tsx b/src/component/modal/EditPeakShapeModal.tsx index 9e54472d9d..c0ed9af772 100644 --- a/src/component/modal/EditPeakShapeModal.tsx +++ b/src/component/modal/EditPeakShapeModal.tsx @@ -1,6 +1,4 @@ -/** @jsxImportSource @emotion/react */ -import { Dialog, DialogBody, DialogFooter } from '@blueprintjs/core'; -import { css } from '@emotion/react'; +import { Dialog, DialogFooter } from '@blueprintjs/core'; import { yupResolver } from '@hookform/resolvers/yup'; import type { Peak1D } from 'nmr-processing'; import { useState } from 'react'; @@ -10,6 +8,7 @@ import * as Yup from 'yup'; import { useChartData } from '../context/ChartContext.js'; import { useDispatch } from '../context/DispatchContext.js'; import ActionButtons from '../elements/ActionButtons.js'; +import { DialogBody } from '../elements/DialogBody.js'; import type { LabelStyle } from '../elements/Label.js'; import Label from '../elements/Label.js'; import { NumberInput2Controller } from '../elements/NumberInput2Controller.js'; @@ -130,12 +129,7 @@ function InnerEditPeakShapeModal(props: Required) { onClose={onCloseDialog} title={`Peak Shape Edition ( ${valuePPM} PPM )`} > - + <>
+ ); } diff --git a/src/component/modal/PredictSpectraModal.tsx b/src/component/modal/PredictSpectraModal.tsx index b241f83a84..9298e2e939 100644 --- a/src/component/modal/PredictSpectraModal.tsx +++ b/src/component/modal/PredictSpectraModal.tsx @@ -1,6 +1,5 @@ -/** @jsxImportSource @emotion/react */ -import { Checkbox, Dialog, DialogBody, DialogFooter } from '@blueprintjs/core'; -import { css } from '@emotion/react'; +import { Checkbox, Dialog, DialogFooter } from '@blueprintjs/core'; +import styled from '@emotion/styled'; import { SvgNmrFt } from 'cheminfo-font'; import { useCallback, useMemo, useRef, useState } from 'react'; import { Toolbar, useOnOff } from 'react-science/ui'; @@ -15,13 +14,12 @@ import { useDispatch } from '../context/DispatchContext.js'; import { useLogger } from '../context/LoggerContext.js'; import { useToaster } from '../context/ToasterContext.js'; import Button from '../elements/Button.js'; +import { DialogBody as BaseDialogBody } from '../elements/DialogBody.js'; import type { SettingsRef } from '../panels/extra/utilities/settingImperativeHandle.js'; import PredictionPreferences from '../panels/predictionPanel/PredictionOptionsPanel.js'; import { useStateWithLocalStorage } from '../utility/LocalStorage.js'; -const styles = css` - background-color: white; - +const DialogBody = styled(BaseDialogBody)` .inner-content { flex: 1; } @@ -155,7 +153,7 @@ export function PredictSpectraModal({ style={{ width: 600, maxWidth: 1000 }} title="Prediction of NMR spectrum" > - + - +