From ffb53e14d41ee93ee0188f3bd9be0b878603c7dc Mon Sep 17 00:00:00 2001 From: zerosoul Date: Mon, 28 Mar 2022 20:47:17 +0800 Subject: [PATCH] refactor: markdown UX --- src/common/component/EmojiPicker.js | 4 + .../component/MarkdownEditer/components.js | 74 ----- src/common/component/MarkdownEditer/index.js | 31 -- .../component/MarkdownEditer/index.slate.js | 280 ------------------ src/common/component/MarkdownEditer/styled.js | 62 ---- src/common/component/MarkdownEditor/index.js | 88 ++++++ .../components/MarkBallonToolbar.js | 54 ++++ .../components/withStyledPlaceHolders.js | 19 ++ src/common/component/MarkdownInput/config.js | 116 ++++++++ src/common/component/MarkdownInput/index.js | 122 ++++++++ src/common/component/MarkdownInput/plugins.js | 44 +++ src/common/component/MarkdownInput/styled.js | 13 + .../MarkdownInput/values/nodeTypes.js | 24 ++ .../component/MarkdownInput/values/utils.js | 63 ++++ .../component/MarkdownInput/values/values.js | 275 +++++++++++++++++ src/common/component/MarkdownStyleOverride.js | 94 ++++++ .../component/MixedInput/ImageElement.js | 40 +++ src/common/component/MixedInput/config.js | 53 ++++ src/common/component/MixedInput/index.js | 163 ++++++++++ src/common/component/MixedInput/plugins.js | 21 ++ src/common/component/MixedInput/styled.js | 19 ++ .../component/MixedInput/values/nodeTypes.js | 6 + .../component/MixedInput/values/utils.js | 30 ++ src/common/component/MrakdownRender.js | 82 ++++- src/common/component/RichEditor/index.js | 3 +- src/common/component/Send/Replying.js | 27 +- src/common/component/Send/Toolbar.js | 69 +++-- src/common/component/Send/index.js | 167 +++++------ src/common/component/Send/styled.js | 14 +- src/index.js | 2 + 30 files changed, 1485 insertions(+), 574 deletions(-) delete mode 100644 src/common/component/MarkdownEditer/components.js delete mode 100644 src/common/component/MarkdownEditer/index.js delete mode 100644 src/common/component/MarkdownEditer/index.slate.js delete mode 100644 src/common/component/MarkdownEditer/styled.js create mode 100644 src/common/component/MarkdownEditor/index.js create mode 100644 src/common/component/MarkdownInput/components/MarkBallonToolbar.js create mode 100644 src/common/component/MarkdownInput/components/withStyledPlaceHolders.js create mode 100644 src/common/component/MarkdownInput/config.js create mode 100644 src/common/component/MarkdownInput/index.js create mode 100644 src/common/component/MarkdownInput/plugins.js create mode 100644 src/common/component/MarkdownInput/styled.js create mode 100644 src/common/component/MarkdownInput/values/nodeTypes.js create mode 100644 src/common/component/MarkdownInput/values/utils.js create mode 100644 src/common/component/MarkdownInput/values/values.js create mode 100644 src/common/component/MarkdownStyleOverride.js create mode 100644 src/common/component/MixedInput/ImageElement.js create mode 100644 src/common/component/MixedInput/config.js create mode 100644 src/common/component/MixedInput/index.js create mode 100644 src/common/component/MixedInput/plugins.js create mode 100644 src/common/component/MixedInput/styled.js create mode 100644 src/common/component/MixedInput/values/nodeTypes.js create mode 100644 src/common/component/MixedInput/values/utils.js diff --git a/src/common/component/EmojiPicker.js b/src/common/component/EmojiPicker.js index 54176165..d6bee8e9 100644 --- a/src/common/component/EmojiPicker.js +++ b/src/common/component/EmojiPicker.js @@ -1,5 +1,7 @@ // import React from 'react' +// import { NimblePicker } from "emoji-mart"; import { Picker } from "emoji-mart"; +// import data from "emoji-mart/data/"; import "emoji-mart/css/emoji-mart.css"; import styled from "styled-components"; const StyledWrapper = styled.div` @@ -14,6 +16,8 @@ export default function EmojiPicker({ onSelect, ...rest }) { return ( ( - - ) -); - -export const Icon = React.forwardRef(({ className, ...props }, ref) => ( - -)); - -export const Menu = React.forwardRef(({ className, ...props }, ref) => ( -
* { - display: inline-block; - } - & > * + * { - margin-left: 15px; - } - ` - )} - /> -)); - -export const Toolbar = React.forwardRef(({ className, ...props }, ref) => ( - -)); diff --git a/src/common/component/MarkdownEditer/index.js b/src/common/component/MarkdownEditer/index.js deleted file mode 100644 index 48c26302..00000000 --- a/src/common/component/MarkdownEditer/index.js +++ /dev/null @@ -1,31 +0,0 @@ -import Editor from "rich-markdown-editor"; -import styled from "styled-components"; -const Styled = styled.div` - padding-top: 8px; - .mde { - padding: 4px; - height: 150px; - > div { - height: 100%; - .ProseMirror { - overflow: scroll; - height: 100%; - max-height: 300px; - padding: 5px 28px; - } - } - } -`; -export default function MarkdownEditer({ value, updateValue }) { - return ( - - - - ); -} diff --git a/src/common/component/MarkdownEditer/index.slate.js b/src/common/component/MarkdownEditer/index.slate.js deleted file mode 100644 index 930098a2..00000000 --- a/src/common/component/MarkdownEditer/index.slate.js +++ /dev/null @@ -1,280 +0,0 @@ -import { useCallback, useMemo, useState } from "react"; -import isHotkey from "is-hotkey"; -import { Editable, withReact, useSlate, Slate } from "slate-react"; -import { - Editor, - Transforms, - createEditor, - Element as SlateElement, -} from "slate"; -import { withHistory } from "slate-history"; - -import Styled from "./styled"; -import { Button, Icon, Toolbar } from "./components"; - -const HOTKEYS = { - "mod+b": "bold", - "mod+i": "italic", - "mod+u": "underline", - "mod+`": "code", -}; - -const LIST_TYPES = ["numbered-list", "bulleted-list"]; -const TEXT_ALIGN_TYPES = ["left", "center", "right", "justify"]; - -const MarkdownEditor = () => { - const [value, setValue] = useState(initialValue); - const renderElement = useCallback((props) => , []); - const renderLeaf = useCallback((props) => , []); - const editor = useMemo(() => withHistory(withReact(createEditor())), []); - - return ( - - setValue(value)} - > - - - - - - {/* - */} - - - - - - - - - { - for (const hotkey in HOTKEYS) { - if (isHotkey(hotkey, event)) { - event.preventDefault(); - const mark = HOTKEYS[hotkey]; - toggleMark(editor, mark); - } - } - }} - /> - - - ); -}; - -const toggleBlock = (editor, format) => { - const isActive = isBlockActive( - editor, - format, - TEXT_ALIGN_TYPES.includes(format) ? "align" : "type" - ); - const isList = LIST_TYPES.includes(format); - - Transforms.unwrapNodes(editor, { - match: (n) => - !Editor.isEditor(n) && - SlateElement.isElement(n) && - LIST_TYPES.includes(n.type) && - !TEXT_ALIGN_TYPES.includes(format), - split: true, - }); - let newProperties; - if (TEXT_ALIGN_TYPES.includes(format)) { - newProperties = { - align: isActive ? undefined : format, - }; - } else { - newProperties = { - type: isActive ? "paragraph" : isList ? "list-item" : format, - }; - } - Transforms.setNodes < SlateElement > (editor, newProperties); - - if (!isActive && isList) { - const block = { type: format, children: [] }; - Transforms.wrapNodes(editor, block); - } -}; - -const toggleMark = (editor, format) => { - const isActive = isMarkActive(editor, format); - - if (isActive) { - Editor.removeMark(editor, format); - } else { - Editor.addMark(editor, format, true); - } -}; - -const isBlockActive = (editor, format, blockType = "type") => { - const { selection } = editor; - if (!selection) return false; - - const [match] = Array.from( - Editor.nodes(editor, { - at: Editor.unhangRange(editor, selection), - match: (n) => - !Editor.isEditor(n) && - SlateElement.isElement(n) && - n[blockType] === format, - }) - ); - - return !!match; -}; - -const isMarkActive = (editor, format) => { - const marks = Editor.marks(editor); - return marks ? marks[format] === true : false; -}; - -const Element = ({ attributes, children, element }) => { - const style = { textAlign: element.align }; - switch (element.type) { - case "block-quote": - return ( -
- {children} -
- ); - case "bulleted-list": - return ( -
    - {children} -
- ); - case "heading-one": - return ( -

- {children} -

- ); - case "heading-two": - return ( -

- {children} -

- ); - case "list-item": - return ( -
  • - {children} -
  • - ); - case "numbered-list": - return ( -
      - {children} -
    - ); - default: - return ( -

    - {children} -

    - ); - } -}; - -const Leaf = ({ attributes, children, leaf }) => { - if (leaf.bold) { - children = {children}; - } - - if (leaf.code) { - children = {children}; - } - - if (leaf.italic) { - children = {children}; - } - - if (leaf.underline) { - children = {children}; - } - - return {children}; -}; - -const BlockButton = ({ format, icon }) => { - const editor = useSlate(); - return ( - - ); -}; - -const MarkButton = ({ format, icon }) => { - const editor = useSlate(); - return ( - - ); -}; - -const initialValue = [ - { - type: "paragraph", - children: [ - { text: "This is editable " }, - { text: "rich", bold: true }, - { text: " text, " }, - { text: "much", italic: true }, - { text: " better than a " }, - { text: "