From 162e4ac57162265d12ce9e7aae0c594ec18b4eb5 Mon Sep 17 00:00:00 2001 From: Anastasiia Moskvina Date: Tue, 12 Apr 2022 12:02:32 +0300 Subject: [PATCH] fix design --- .../ketcher-react/src/icons/files/delete.svg | 4 + .../ketcher-react/src/icons/files/edit.svg | 4 +- .../ketcher-react/src/icons/files/search.svg | 4 +- .../src/icons/files/template-dialog.svg | 6 + packages/ketcher-react/src/icons/index.tsx | 4 + .../ui/dialog/template/TemplateDialog.tsx | 24 ++- .../dialog/template/TemplateTable.module.less | 99 ++++++++---- .../ui/dialog/template/TemplateTable.tsx | 57 ++++--- .../dialog/template/template-lib.module.less | 153 ++++++++++++++---- .../ui/views/components/Dialog/Dialog.tsx | 10 +- 10 files changed, 268 insertions(+), 97 deletions(-) create mode 100644 packages/ketcher-react/src/icons/files/delete.svg create mode 100644 packages/ketcher-react/src/icons/files/template-dialog.svg diff --git a/packages/ketcher-react/src/icons/files/delete.svg b/packages/ketcher-react/src/icons/files/delete.svg new file mode 100644 index 0000000000..93b85bac7d --- /dev/null +++ b/packages/ketcher-react/src/icons/files/delete.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/ketcher-react/src/icons/files/edit.svg b/packages/ketcher-react/src/icons/files/edit.svg index 5a12e5afd0..3c37b4c101 100644 --- a/packages/ketcher-react/src/icons/files/edit.svg +++ b/packages/ketcher-react/src/icons/files/edit.svg @@ -1,3 +1,3 @@ - - + + diff --git a/packages/ketcher-react/src/icons/files/search.svg b/packages/ketcher-react/src/icons/files/search.svg index 6318e04d58..d4322dac8c 100644 --- a/packages/ketcher-react/src/icons/files/search.svg +++ b/packages/ketcher-react/src/icons/files/search.svg @@ -1,3 +1,3 @@ - - + + diff --git a/packages/ketcher-react/src/icons/files/template-dialog.svg b/packages/ketcher-react/src/icons/files/template-dialog.svg new file mode 100644 index 0000000000..0353965616 --- /dev/null +++ b/packages/ketcher-react/src/icons/files/template-dialog.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/ketcher-react/src/icons/index.tsx b/packages/ketcher-react/src/icons/index.tsx index c13b691722..cf3e332e1c 100644 --- a/packages/ketcher-react/src/icons/index.tsx +++ b/packages/ketcher-react/src/icons/index.tsx @@ -46,6 +46,7 @@ import CopyKetIcon from './files/copy-ket.svg' import CopyMolIcon from './files/copy-mol.svg' import CutIcon from './files/cut.svg' import DearomIcon from './files/dearom.svg' +import DeleteIcon from './files/delete.svg' import DropdownIcon from './files/dropdown.svg' import EnhancedStereoIcon from './files/enhanced-stereo.svg' import EditIcon from './files/edit.svg' @@ -110,6 +111,7 @@ import Template4Icon from './files/template-4.svg' import Template5Icon from './files/template-5.svg' import Template6Icon from './files/template-6.svg' import Template7Icon from './files/template-7.svg' +import TemplateDialogIcon from './files/template-dialog.svg' import TemplateLibIcon from './files/template-lib.svg' import TextBold from './files/text-bold.svg' import TextIcon from './files/text.svg' @@ -180,6 +182,7 @@ const icons = { 'copy-ket': CopyKetIcon, cut: CutIcon, dearom: DearomIcon, + delete: DeleteIcon, dropdown: DropdownIcon, 'enhanced-stereo': EnhancedStereoIcon, edit: EditIcon, @@ -252,6 +255,7 @@ const icons = { 'template-5': Template5Icon, 'template-6': Template6Icon, 'template-7': Template7Icon, + 'template-dialog': TemplateDialogIcon, 'template-lib': TemplateLibIcon, text: TextIcon, 'text-bold': TextBold, diff --git a/packages/ketcher-react/src/script/ui/dialog/template/TemplateDialog.tsx b/packages/ketcher-react/src/script/ui/dialog/template/TemplateDialog.tsx index 4267cb372e..f010c76e3f 100644 --- a/packages/ketcher-react/src/script/ui/dialog/template/TemplateDialog.tsx +++ b/packages/ketcher-react/src/script/ui/dialog/template/TemplateDialog.tsx @@ -108,6 +108,13 @@ const filterLibSelector = createSelector( const FUNCTIONAL_GROUPS = 'Functional Groups' +const HeaderContent = () => ( +
+ + Templates +
+) + const TemplateDialog: FC = (props) => { const { filter, @@ -173,7 +180,7 @@ const TemplateDialog: FC = (props) => { return ( } className={`${classes.dialog_body}`} params={omit(['group'], rest)} result={() => result()} @@ -191,7 +198,7 @@ const TemplateDialog: FC = (props) => { ? 'Save template library to SDF' : 'Save functional groups to SDF'} , - 'OK' + 'Add to canvas' ]} >
@@ -200,10 +207,11 @@ const TemplateDialog: FC = (props) => { type="search" value={filter} onChange={(value) => onFilter(value)} + placeholder="Search by elements..." />
- + = (props) => {
-
+
{Object.keys(filteredTemplateLib).length ? ( Object.keys(filteredTemplateLib).map((groupName) => { const shouldGroupBeRended = expandedAccordions.includes(groupName) return ( = (props) => { ) }) ) : ( -
+
)} @@ -263,15 +272,16 @@ const TemplateDialog: FC = (props) => { {filteredFG?.length ? ( -
+
) : ( -
+
)} diff --git a/packages/ketcher-react/src/script/ui/dialog/template/TemplateTable.module.less b/packages/ketcher-react/src/script/ui/dialog/template/TemplateTable.module.less index 03b9e8f6cc..cc71182705 100644 --- a/packages/ketcher-react/src/script/ui/dialog/template/TemplateTable.module.less +++ b/packages/ketcher-react/src/script/ui/dialog/template/TemplateTable.module.less @@ -19,71 +19,104 @@ .tableContent { display: grid; - grid-gap: 30px 8px; + grid-gap: 0 8px; grid-template-columns: repeat(4, 100px); - padding-bottom: 20px; +} + +.structTitle { + padding: 0 7px; + text-align: center; + margin: 6px 0 12px; + border: 1px solid transparent; + border-radius: 6px; + overflow: hidden; + max-width: 100px; + max-height: 30px; +} + +.twoRowsTitleTable { + grid-auto-rows: 147px; +} + +.oneRowTitleTable { + grid-auto-rows: 134px; + + .structTitle { + max-height: 16px; + } } .struct { box-sizing: border-box; - width: 98%; - height: 98%; + width: 100px; + height: 100px; border: 1px solid @color-grey-5; border-radius: 5px; + background-color: @color-background-primary; &:hover { background: @form-hover-background; } + + & svg { + width: 100px; + height: 100px; + left: -2px; + top: -1px; + } +} + +.selectedTitle { + background-color: fade(@color-background-primary, 70%); } .td { position: relative; - height: 93px; - height: 100px; - - &::after { - position: absolute; - top: 100%; - color: @color-text-primary; - content: attr(title); - overflow: hidden; - max-width: 100%; - } &.selected .struct { - background-color: lighten(@form-selected-background, 15%); + background-color: fade(@color-primary, 5%); + border: 2px solid @color-primary; } } -.btnContainer { - display: flex; - flex-direction: row; - position: absolute; - right: 8px; - bottom: 8px; - margin: 0 4px 2px 0; - - .attachButton { + .button { .btn(); margin: 0; border-radius: 0; - width: 12px; - height: 12px; + width: 18px; + height: 18px; border: none; - color: @color-primary; + color: #636363; background-color: transparent; cursor: pointer; + padding: 0; + + & > svg { + width: inherit; + height: inherit; + } + + &:hover, &:active { + & path { + fill: @color-button-primary-hover; + } + } } .deleteButton { - margin: 0; - border-radius: 0; - border: 1px solid @border-color; + position: absolute; + top: 5px; + right: 5px; + } + + .editButton { + position: absolute; + top: 78px; + right: 5px; } -} -div.struct { +div.structure { padding: 0; // TODO: tmp hack to fit viewbox background-color: @color-background-primary; } diff --git a/packages/ketcher-react/src/script/ui/dialog/template/TemplateTable.tsx b/packages/ketcher-react/src/script/ui/dialog/template/TemplateTable.tsx index 90247c5c23..bab4c588ea 100644 --- a/packages/ketcher-react/src/script/ui/dialog/template/TemplateTable.tsx +++ b/packages/ketcher-react/src/script/ui/dialog/template/TemplateTable.tsx @@ -39,6 +39,7 @@ interface TemplateTableProps { onSelect: (tmpl: Template) => void onDelete?: (tmpl: Template) => void onAttach?: (tmpl: Template) => void + titleRows?: 1 | 2 } const getSettingsSelector = (state) => state.options.settings @@ -63,16 +64,27 @@ const RenderTmpl: FC<{ } const TemplateTable: FC = (props) => { - const { templates, selected, onSelect, onDelete, onAttach } = props + const { + templates, + selected, + onSelect, + onDelete, + onAttach, + titleRows = 2 + } = props const options = useSelector((state) => getSettingsSelector(state)) return ( -
+
{templates.map((tmpl, i) => { return (
= (props) => { className={classes.struct} onClick={() => onSelect(tmpl)} /> -
- {tmpl.props.group === 'User Templates' && ( - - )} - {tmpl.props.group !== 'Functional Groups' && ( - - )} +
+ {greekify(tmplName(tmpl, i))}
+ {tmpl.props.group === 'User Templates' && ( + + )} + {tmpl.props.group !== 'Functional Groups' && ( + + )}
) })} diff --git a/packages/ketcher-react/src/script/ui/dialog/template/template-lib.module.less b/packages/ketcher-react/src/script/ui/dialog/template/template-lib.module.less index 7a348a47f8..6f378e8371 100644 --- a/packages/ketcher-react/src/script/ui/dialog/template/template-lib.module.less +++ b/packages/ketcher-react/src/script/ui/dialog/template/template-lib.module.less @@ -17,6 +17,9 @@ @import '../../../../style/mixins'; @import '../../../../style/variables'; +@shadow-color: #DEE1E4; +@scroll-color: #A5AFB9; + .warning { color: @error-color; @@ -25,47 +28,85 @@ } } +.dialogHeader { + display: flex; + align-items: center; + gap: 4px; + padding-left: 3px; + + & > svg { + width: 18px; + height: 18px; + } +} + .dialog_body { background-color: @color-background-primary; color: @color-text-primary; + width: 452px; & > header, footer { - margin: 10px 0; - padding: 0 15px; + margin: 0; } - & > div[class^='Dialog-module_dialog_body'] { + & > header { + padding: 10px 12px; + + button { + & > svg { + width: 18px; + height: 18px; + } + } + } + + & > div { display: flex; flex-direction: column; - margin: 10px 0; + margin: 0; overflow: hidden; } + & > footer { + box-shadow: 0 -6px 6px 0 @shadow-color; + z-index: 10; + padding: 16px 12px 12px; + + & > input { + .button-main(); + } + + & > button, input { + border-radius: 6px; + } + } + .inputContainer { position: relative; input[type='search'] { width: 424px; - padding-left: 30px; + padding-left: 35px; background-color: @color-primary-light; - margin: 0 15px 20px 15px; + margin: 0 14px 16px 14px; + height: 28px; + + &::placeholder { + font-weight: 400; + opacity: 90%; + } } .searchIcon { - width: 18px; - height: 18px; + width: 28px; + height: 28px; position: absolute; - top: 6px; - left: 20px; + top: 0; + left: 14px; color: @color-primary; } } - .tabPanel { - width: 448px; - box-sizing: border-box; - } - .accordionSummary { flex-direction: row-reverse; font-size: 14px; @@ -85,16 +126,31 @@ background-color: @color-primary-light; overflow-y: auto; overflow-x: hidden; - margin-right: 3px; - .scrollbar_thin(); - } - - .searchResultContainer { - padding: 8px 16px; + + ::-webkit-scrollbar-track { + background-color: transparent; + } + + &::-webkit-scrollbar { + background-color: @color-primary-light; + width: 6px; + height: 6px; + } + + &::-webkit-scrollbar-thumb { + background-color: fade(@scroll-color, 85%); + border-radius: 10px; + -webkit-border-radius: 10px; + } + + &::-webkit-scrollbar-thumb:active, + &::-webkit-scrollbar-thumb:hover { + background-color: @scroll-color; + } } - .FGSearchContainer { - padding: 8px 16px; + .resultsContainer { + padding: 12px 14px 4px; background-color: @color-primary-light; } @@ -105,11 +161,18 @@ :global(.MuiTabs-flexContainer) { background-color: @color-primary-light; + padding-left: 14px; + } + + :global(.MuiAccordionSummary-content) { + align-items: end; } :global(.MuiAccordionDetails-root) { background-color: @color-primary-light; + box-shadow: inset 0 -2px 8px 0 @shadow-color; width: 424px; + padding: 12px 14px 4px; } :global(.MuiPaper-root.MuiAccordion-root) { @@ -118,33 +181,61 @@ :global(.MuiPaper-root.MuiAccordion-root::before), :global(.MuiPaper-root.MuiAccordion-root.Mui-expanded::before) { - background-color: @color-grey-5; + opacity: 0; + } + + :global(.MuiPaper-root) { + &:not(:last-child)::after { + content: ''; + position: absolute; + left: 0; + bottom: 0; + right: 0; + height: 1px; width: 424px; margin: 0 auto; + background-color: @color-grey-5; opacity: 1; + } + } + + :global(.MuiPaper-root.Mui-expanded) { + &::after { + opacity: 0; + } + } + + :global(.MuiButtonBase-root.MuiTab-root), + :global(.MuiTabs-root) { + min-height: 32px; + height: 32px; + } + + .tabs { + box-shadow: 0 6px 6px 0 @shadow-color; + z-index: 10; } :global(.MuiButtonBase-root.MuiTab-root) { text-transform: none; - color: @color-text-black; + color: fade(@color-text-black, 70%); + padding: 12px 10px 8px; + line-height: 12px; } :global(.MuiTab-root.Mui-selected) { font-weight: 600; + color: @color-text-black; } :global(.MuiPaper-root.MuiAccordion-root.Mui-expanded) { margin: 0; } - :global(.MuiButtonBase-root.MuiTab-root.Mui-selected) { - color: @color-text-black; - } - :global(.MuiButtonBase-root.MuiAccordionSummary-root.Mui-expanded), :global(.MuiButtonBase-root.MuiAccordionSummary-root.MuiAccordionSummary-gutters) { - min-height: 43px; - height: 43px; + min-height: 40px; + height: 40px; padding-left: 12px; } } diff --git a/packages/ketcher-react/src/script/ui/views/components/Dialog/Dialog.tsx b/packages/ketcher-react/src/script/ui/views/components/Dialog/Dialog.tsx index 17ff18d427..f70450c3a2 100644 --- a/packages/ketcher-react/src/script/ui/views/components/Dialog/Dialog.tsx +++ b/packages/ketcher-react/src/script/ui/views/components/Dialog/Dialog.tsx @@ -32,7 +32,7 @@ export interface DialogParams extends DialogParamsCallProps { } interface DialogProps { - title: string + title?: string params: DialogParams buttons?: Array buttonsTop?: Array @@ -48,6 +48,10 @@ interface DialogCallProps { type Props = DialogProps & DialogCallProps +const buttonsNameMap = { + 'Add to canvas': 'OK' +} + const Dialog: FC = (props) => { const { children, @@ -142,7 +146,9 @@ const Dialog: FC = (props) => { )} value={button} disabled={isButtonOk(button) && !valid()} - onClick={() => exit(button)} + onClick={() => + exit(buttonsNameMap[button] ? buttonsNameMap[button] : button) + } /> ) )}