From f298d1469b95d8b331395eb507cfbed2bbca45da Mon Sep 17 00:00:00 2001 From: mrdrogdrog Date: Sat, 13 Jun 2020 01:22:27 +0200 Subject: [PATCH] Add editor split component (#198) Add split and split divider component --- package.json | 3 +- .../common/split-divider/split-divider.scss | 7 +++ .../common/split-divider/split-divider.tsx | 15 +++++ src/components/common/splitter/splitter.scss | 14 +++++ src/components/common/splitter/splitter.tsx | 63 +++++++++++++++++++ src/components/editor/editor.tsx | 32 +++++++--- .../markdown-preview/markdown-preview.tsx | 2 +- .../editor/task-bar/editor-view-mode.tsx | 2 +- yarn.lock | 5 ++ 9 files changed, 130 insertions(+), 13 deletions(-) create mode 100644 src/components/common/split-divider/split-divider.scss create mode 100644 src/components/common/split-divider/split-divider.tsx create mode 100644 src/components/common/splitter/splitter.scss create mode 100644 src/components/common/splitter/splitter.tsx diff --git a/package.json b/package.json index ae2c0002a..d04cf4cb4 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,8 @@ "react-router-dom": "5.2.0", "react-scripts": "3.4.1", "redux": "4.0.5", - "typescript": "3.9.5" + "typescript": "3.9.5", + "use-media": "1.4.0" }, "scripts": { "start": "react-scripts start", diff --git a/src/components/common/split-divider/split-divider.scss b/src/components/common/split-divider/split-divider.scss new file mode 100644 index 000000000..eea29308c --- /dev/null +++ b/src/components/common/split-divider/split-divider.scss @@ -0,0 +1,7 @@ +.split-divider { + width: 10px; + background: white; + z-index: 1; + cursor: col-resize; + box-shadow: 3px 0 6px #e7e7e7; +} diff --git a/src/components/common/split-divider/split-divider.tsx b/src/components/common/split-divider/split-divider.tsx new file mode 100644 index 000000000..5433e350b --- /dev/null +++ b/src/components/common/split-divider/split-divider.tsx @@ -0,0 +1,15 @@ +import React from 'react' +import './split-divider.scss' + +export interface SplitDividerProps { + onGrab: () => void +} + +export const SplitDivider: React.FC = ({ onGrab }) => { + return ( +
onGrab()} + onTouchStart={() => onGrab()} + className={'split-divider'}/> + ) +} diff --git a/src/components/common/splitter/splitter.scss b/src/components/common/splitter/splitter.scss new file mode 100644 index 000000000..bcd80480c --- /dev/null +++ b/src/components/common/splitter/splitter.scss @@ -0,0 +1,14 @@ +.splitter { + &.left { + flex: 0 1 100%; + min-width: 200px; + } + + &.right { + flex: 1 0 200px; + } + + &.separator { + display: flex; + } +} diff --git a/src/components/common/splitter/splitter.tsx b/src/components/common/splitter/splitter.tsx new file mode 100644 index 000000000..c125f4f3d --- /dev/null +++ b/src/components/common/splitter/splitter.tsx @@ -0,0 +1,63 @@ +import React, { ReactElement, useRef, useState } from 'react' +import { ShowIf } from '../show-if/show-if' +import { SplitDivider } from '../split-divider/split-divider' +import './splitter.scss' + +export interface SplitterProps { + left: ReactElement + right: ReactElement + containerClassName?: string + showLeft: boolean + showRight: boolean +} + +export const Splitter: React.FC = ({ containerClassName, left, right, showLeft, showRight }) => { + const [split, setSplit] = useState(50) + const realSplit = Math.max(0, Math.min(100, (showRight ? split : 100))) + const [doResizing, setDoResizing] = useState(false) + const splitContainer = useRef(null) + + const recalculateSize = (mouseXPosition: number): void => { + if (!splitContainer.current) { + return + } + const x = mouseXPosition - splitContainer.current.offsetLeft + + const newSize = x / splitContainer.current.clientWidth + setSplit(newSize * 100) + } + + return ( +
setDoResizing(false)} + onTouchEnd={() => setDoResizing(false)} + onMouseMove={(mouseEvent) => { + if (doResizing) { + recalculateSize(mouseEvent.pageX) + mouseEvent.preventDefault() + } + }} + onTouchMove={(touchEvent) => { + if (doResizing) { + recalculateSize(touchEvent.touches[0].pageX) + } + }} + > + +
+ {left} +
+
+ +
+ setDoResizing(true)}/> +
+
+ +
+ {right} +
+
+
+ ) +} diff --git a/src/components/editor/editor.tsx b/src/components/editor/editor.tsx index c579ef746..a5b50ee05 100644 --- a/src/components/editor/editor.tsx +++ b/src/components/editor/editor.tsx @@ -1,7 +1,9 @@ -import React from 'react' +import React, { useEffect, useState } from 'react' import { useSelector } from 'react-redux' +import useMedia from 'use-media' import { ApplicationState } from '../../redux' -import { ShowIf } from '../common/show-if/show-if' +import { setEditorModeConfig } from '../../redux/editor/methods' +import { Splitter } from '../common/splitter/splitter' import { EditorWindow } from './editor-window/editor-window' import { MarkdownPreview } from './markdown-preview/markdown-preview' import { EditorMode } from './task-bar/editor-view-mode' @@ -13,18 +15,28 @@ interface RouteParameters { const Editor: React.FC = () => { const editorMode: EditorMode = useSelector((state: ApplicationState) => state.editorConfig.editorMode) + const isWide = useMedia({ minWidth: 576 }) + const [firstDraw, setFirstDraw] = useState(true) + + useEffect(() => { + setFirstDraw(false) + }, []) + + useEffect(() => { + if (!firstDraw && !isWide && editorMode === EditorMode.BOTH) { + setEditorModeConfig(EditorMode.PREVIEW) + } + }, [editorMode, firstDraw, isWide]) return (
-
- - - - - - -
+ } + showRight={editorMode === EditorMode.PREVIEW || (editorMode === EditorMode.BOTH)} + right={} + containerClassName={'overflow-hidden'}/>
) } diff --git a/src/components/editor/markdown-preview/markdown-preview.tsx b/src/components/editor/markdown-preview/markdown-preview.tsx index 4b133dc86..be7a5128b 100644 --- a/src/components/editor/markdown-preview/markdown-preview.tsx +++ b/src/components/editor/markdown-preview/markdown-preview.tsx @@ -2,7 +2,7 @@ import React from 'react' const MarkdownPreview: React.FC = () => { return ( -
+
Hello, MarkdownPreview!
) diff --git a/src/components/editor/task-bar/editor-view-mode.tsx b/src/components/editor/task-bar/editor-view-mode.tsx index 1eba4ff63..5dc493bef 100644 --- a/src/components/editor/task-bar/editor-view-mode.tsx +++ b/src/components/editor/task-bar/editor-view-mode.tsx @@ -19,7 +19,7 @@ export const EditorViewMode: React.FC = () => { { setEditorModeConfig(value) }}> diff --git a/yarn.lock b/yarn.lock index 87d78cee8..de8c833ac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11319,6 +11319,11 @@ url@^0.11.0: punycode "1.3.2" querystring "0.2.0" +use-media@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/use-media/-/use-media-1.4.0.tgz#e777bf1f382a7aacabbd1f9ce3da2b62e58b2a98" + integrity sha512-XsgyUAf3nhzZmEfhc5MqLHwyaPjs78bgytpVJ/xDl0TF4Bptf3vEpBNBBT/EIKOmsOc8UbuECq3mrP3mt1QANA== + use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"