From 76570d4018106a17269d8fb0c43c2e11b20b40be Mon Sep 17 00:00:00 2001 From: Winnie Tan Date: Wed, 26 Jul 2023 16:55:03 +1000 Subject: [PATCH 1/4] basic functionality done --- .../cse-ui-kit/assets/checklist-button.svg | 44 +++++++++ .../small_buttons/ChecklistButton.tsx | 23 +++++ .../editor/components/EditorBlock.tsx | 95 ++++++++++++++++++- .../buttons/EditorChecklistButton.tsx | 20 ++++ .../components/buttons/buttonHelpers.ts | 4 +- frontend/src/packages/editor/types.ts | 2 + 6 files changed, 181 insertions(+), 7 deletions(-) create mode 100644 frontend/src/cse-ui-kit/assets/checklist-button.svg create mode 100644 frontend/src/cse-ui-kit/small_buttons/ChecklistButton.tsx create mode 100644 frontend/src/packages/editor/components/buttons/EditorChecklistButton.tsx diff --git a/frontend/src/cse-ui-kit/assets/checklist-button.svg b/frontend/src/cse-ui-kit/assets/checklist-button.svg new file mode 100644 index 000000000..57c8c042d --- /dev/null +++ b/frontend/src/cse-ui-kit/assets/checklist-button.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/src/cse-ui-kit/small_buttons/ChecklistButton.tsx b/frontend/src/cse-ui-kit/small_buttons/ChecklistButton.tsx new file mode 100644 index 000000000..71152342e --- /dev/null +++ b/frontend/src/cse-ui-kit/small_buttons/ChecklistButton.tsx @@ -0,0 +1,23 @@ +import React, { MouseEventHandler } from 'react'; +import { StyledButton, buttonProps, scaleRate } from './small_buttons-Styled'; +import { ReactComponent as Code } from 'src/cse-ui-kit/assets/checklist-button.svg'; + +type Props = { + onClick?: MouseEventHandler; + onMouseDown?: MouseEventHandler; +} & buttonProps; + +export default function CodeButton({ + onClick, + onMouseDown, + ...styleProps +}: Props) { + return ( + + + + ); +} \ No newline at end of file diff --git a/frontend/src/packages/editor/components/EditorBlock.tsx b/frontend/src/packages/editor/components/EditorBlock.tsx index 83399d542..81a7f054c 100644 --- a/frontend/src/packages/editor/components/EditorBlock.tsx +++ b/frontend/src/packages/editor/components/EditorBlock.tsx @@ -1,9 +1,9 @@ import styled from 'styled-components'; -import { createEditor } from 'slate'; -import React, { FC, useMemo, useCallback } from 'react'; -import { Slate, Editable, withReact, RenderLeafProps } from 'slate-react'; +import React, { FC, useMemo, useCallback, Fragment } from 'react'; +import { Slate, Editable, withReact, RenderLeafProps, useSlateStatic, useReadOnly, ReactEditor } from 'slate-react'; +import { Editor, Transforms, Range, Point, createEditor, Descendant, Element as SlateElement } from 'slate' -import { CMSBlockProps } from '../types'; +import { CMSBlockProps, CustomEditor, CustomText } from '../types'; import EditorBoldButton from './buttons/EditorBoldButton'; import EditorItalicButton from './buttons/EditorItalicButton'; import EditorUnderlineButton from './buttons/EditorUnderlineButton'; @@ -12,10 +12,11 @@ import EditorSelectFont from './buttons/EditorSelectFont'; import EditorCenterAlignButton from './buttons/EditorCenterAlignButton'; import EditorLeftAlignButton from './buttons/EditorLeftAlignButton'; import EditorRightAlignButton from './buttons/EditorRightAlignButton'; +import EditorCodeButton from "./buttons/EditorCodeButton"; +import EditorChecklistButton from "./buttons/EditorChecklistButton"; import ContentBlock from "../../../cse-ui-kit/contentblock/contentblock-wrapper"; import { handleKey } from "./buttons/buttonHelpers"; -import EditorCodeButton from "./buttons/EditorCodeButton"; const defaultTextSize = 16; @@ -35,6 +36,8 @@ const Text = styled.span<{ quote: boolean; textSize: number; align: string; + checklist: boolean; + checked: boolean; }>` font-weight: ${(props) => (props.bold ? 600 : 400)}; font-style: ${(props) => (props.italic || props.quote ? 'italic' : 'normal')}; @@ -46,6 +49,47 @@ const Text = styled.span<{ background-color: ${(props) => props.code ? "#eee" : "#fff"}; `; + +const CheckListItemElement = (props: any) => { + console.log("?????? why"); + return ( +
+ + { + props.checked = event.target.checked + }} + /> + + + +
+ ) +} + + const Quote = styled.blockquote` border-left: 3px solid #9e9e9e; margin: 0px; @@ -73,9 +117,49 @@ const EditorBlock: FC = ({ code: leaf.code ?? false, align: leaf.align ?? 'left', textSize: leaf.textSize ?? defaultTextSize, + checklist: leaf.checklist ?? false, + checked: leaf.checklist ?? false, ...attributes, }; + + if (leaf.checklist) { + console.log(leaf.checked); + return ( +
+
+ + { + leaf.checked = event.target.checked; + console.log("what", event.target.checked); + }} + /> + +
+ + {children} + +
+ ) + } + return leaf.quote ? ( {children} ) : leaf.align == null ? ( @@ -100,6 +184,7 @@ const EditorBlock: FC = ({ + diff --git a/frontend/src/packages/editor/components/buttons/EditorChecklistButton.tsx b/frontend/src/packages/editor/components/buttons/EditorChecklistButton.tsx new file mode 100644 index 000000000..930b9b4d2 --- /dev/null +++ b/frontend/src/packages/editor/components/buttons/EditorChecklistButton.tsx @@ -0,0 +1,20 @@ +import React, { FC } from "react"; +import { useSlate } from "slate-react"; +import { toggleMark } from "./buttonHelpers"; +import ChecklistButton from "src/cse-ui-kit/small_buttons/ChecklistButton"; +import { Editor } from "slate"; + +const EditorChecklistButton: FC = () => { + const editor = useSlate(); + return ( + { + event.preventDefault(); + toggleMark(editor, "checklist") + }} + /> + ); +}; + +export default EditorChecklistButton; diff --git a/frontend/src/packages/editor/components/buttons/buttonHelpers.ts b/frontend/src/packages/editor/components/buttons/buttonHelpers.ts index 872f2af8a..49affa4fc 100644 --- a/frontend/src/packages/editor/components/buttons/buttonHelpers.ts +++ b/frontend/src/packages/editor/components/buttons/buttonHelpers.ts @@ -8,7 +8,7 @@ import { ReactEditor } from 'slate-react'; */ const toggleMark = ( editor: BaseEditor & ReactEditor, - format: 'bold' | 'italic' | 'underline' | 'quote' | 'code' + format: 'bold' | 'italic' | 'underline' | 'quote' | 'code' | 'checklist' | 'checked' ): void => { const isActive = isMarkActive(editor, format); @@ -27,7 +27,7 @@ const toggleMark = ( */ const isMarkActive = ( editor: BaseEditor & ReactEditor, - format: 'bold' | 'italic' | 'underline' | 'quote' | 'code' + format: 'bold' | 'italic' | 'underline' | 'quote' | 'code' | 'checklist' | 'checked' ): boolean => { // https://docs.slatejs.org/concepts/07-editor // Editor object exposes properties of the current editor diff --git a/frontend/src/packages/editor/types.ts b/frontend/src/packages/editor/types.ts index 438c0bb4c..645cd0438 100644 --- a/frontend/src/packages/editor/types.ts +++ b/frontend/src/packages/editor/types.ts @@ -16,6 +16,8 @@ export type CustomText = { type?: string; align?: string; code?: string; + checklist?: boolean; + checked?: boolean; }; export type CustomElement = { From 506dbd29b54d64cc0412c0b336d96c43caa567bb Mon Sep 17 00:00:00 2001 From: Winnie Tan Date: Sat, 26 Aug 2023 11:34:40 +1000 Subject: [PATCH 2/4] fixed strikethrough issue --- frontend/package.json | 1 + .../editor/components/EditorBlock.tsx | 105 +++++++----------- .../buttons/EditorChecklistButton.tsx | 1 + 3 files changed, 41 insertions(+), 66 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 85b63b9b6..d361a8d71 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -22,6 +22,7 @@ "redux-persist": "^6.0.0", "redux-saga": "1.1.3", "slate": "0.78.0", + "slate-history": "^0.93.0", "slate-react": "0.79.0", "socket.io": "^4.5.3", "socket.io-client": "^4.5.3", diff --git a/frontend/src/packages/editor/components/EditorBlock.tsx b/frontend/src/packages/editor/components/EditorBlock.tsx index 81a7f054c..828084b09 100644 --- a/frontend/src/packages/editor/components/EditorBlock.tsx +++ b/frontend/src/packages/editor/components/EditorBlock.tsx @@ -16,7 +16,8 @@ import EditorCodeButton from "./buttons/EditorCodeButton"; import EditorChecklistButton from "./buttons/EditorChecklistButton"; import ContentBlock from "../../../cse-ui-kit/contentblock/contentblock-wrapper"; -import { handleKey } from "./buttons/buttonHelpers"; +import { handleKey, toggleMark } from "./buttons/buttonHelpers"; +import { withHistory } from 'slate-history'; const defaultTextSize = 16; @@ -50,44 +51,48 @@ const Text = styled.span<{ `; -const CheckListItemElement = (props: any) => { - console.log("?????? why"); +const CheckListItemElement = ({children, attributes, leaf}: any) => { + const readOnly = useReadOnly() + const [checked, setChecked] = React.useState(false) return ( -
- +
- { - props.checked = event.target.checked + - - + { + // TODO: figure out why ReactEditor.findPath does not work + // const path = ReactEditor.findPath(editor as ReactEditor, leaf); + // const newProperties = { + // checked: event.target.checked, + // } + // Transforms.setNodes(editor, newProperties, { at: path }) + setChecked(event.target.checked); + }} + /> + +
+ - -
- ) -} + {children} + + +)} const Quote = styled.blockquote` @@ -105,7 +110,7 @@ const EditorBlock: FC = ({ showToolBar, onEditorClick, }) => { - const editor = useMemo(() => withReact(createEditor()), []); + const editor = useMemo(() => withHistory(withReact(createEditor())), []) const renderLeaf: (props: RenderLeafProps) => JSX.Element = useCallback( ({ attributes, children, leaf }) => { @@ -124,40 +129,8 @@ const EditorBlock: FC = ({ if (leaf.checklist) { - console.log(leaf.checked); - return ( -
-
- - { - leaf.checked = event.target.checked; - console.log("what", event.target.checked); - }} - /> - -
- - {children} - -
- ) + const checklistProps = {attributes, children, leaf} + return } return leaf.quote ? ( diff --git a/frontend/src/packages/editor/components/buttons/EditorChecklistButton.tsx b/frontend/src/packages/editor/components/buttons/EditorChecklistButton.tsx index 930b9b4d2..e667713fd 100644 --- a/frontend/src/packages/editor/components/buttons/EditorChecklistButton.tsx +++ b/frontend/src/packages/editor/components/buttons/EditorChecklistButton.tsx @@ -12,6 +12,7 @@ const EditorChecklistButton: FC = () => { onMouseDown={(event) => { event.preventDefault(); toggleMark(editor, "checklist") + toggleMark(editor, "checked") }} /> ); From f19968464183b7ed2299c2ee0cc1b6baebf392dc Mon Sep 17 00:00:00 2001 From: Winnie Tan Date: Sat, 26 Aug 2023 11:38:04 +1000 Subject: [PATCH 3/4] fixed style --- .../src/packages/editor/components/EditorBlock.tsx | 12 ++++++------ .../components/buttons/EditorChecklistButton.tsx | 1 - .../editor/components/buttons/buttonHelpers.ts | 4 ++-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/frontend/src/packages/editor/components/EditorBlock.tsx b/frontend/src/packages/editor/components/EditorBlock.tsx index 828084b09..559d9b882 100644 --- a/frontend/src/packages/editor/components/EditorBlock.tsx +++ b/frontend/src/packages/editor/components/EditorBlock.tsx @@ -1,9 +1,9 @@ import styled from 'styled-components'; -import React, { FC, useMemo, useCallback, Fragment } from 'react'; -import { Slate, Editable, withReact, RenderLeafProps, useSlateStatic, useReadOnly, ReactEditor } from 'slate-react'; -import { Editor, Transforms, Range, Point, createEditor, Descendant, Element as SlateElement } from 'slate' +import React, { FC, useMemo, useCallback } from 'react'; +import { Slate, Editable, withReact, RenderLeafProps, useReadOnly } from 'slate-react'; +import { createEditor } from 'slate' -import { CMSBlockProps, CustomEditor, CustomText } from '../types'; +import { CMSBlockProps } from '../types'; import EditorBoldButton from './buttons/EditorBoldButton'; import EditorItalicButton from './buttons/EditorItalicButton'; import EditorUnderlineButton from './buttons/EditorUnderlineButton'; @@ -16,7 +16,7 @@ import EditorCodeButton from "./buttons/EditorCodeButton"; import EditorChecklistButton from "./buttons/EditorChecklistButton"; import ContentBlock from "../../../cse-ui-kit/contentblock/contentblock-wrapper"; -import { handleKey, toggleMark } from "./buttons/buttonHelpers"; +import { handleKey } from "./buttons/buttonHelpers"; import { withHistory } from 'slate-history'; const defaultTextSize = 16; @@ -70,7 +70,7 @@ const CheckListItemElement = ({children, attributes, leaf}: any) => { type="checkbox" checked={checked} onChange={event => { - // TODO: figure out why ReactEditor.findPath does not work + // Figure out why ReactEditor.findPath does not work // const path = ReactEditor.findPath(editor as ReactEditor, leaf); // const newProperties = { // checked: event.target.checked, diff --git a/frontend/src/packages/editor/components/buttons/EditorChecklistButton.tsx b/frontend/src/packages/editor/components/buttons/EditorChecklistButton.tsx index e667713fd..930b9b4d2 100644 --- a/frontend/src/packages/editor/components/buttons/EditorChecklistButton.tsx +++ b/frontend/src/packages/editor/components/buttons/EditorChecklistButton.tsx @@ -12,7 +12,6 @@ const EditorChecklistButton: FC = () => { onMouseDown={(event) => { event.preventDefault(); toggleMark(editor, "checklist") - toggleMark(editor, "checked") }} /> ); diff --git a/frontend/src/packages/editor/components/buttons/buttonHelpers.ts b/frontend/src/packages/editor/components/buttons/buttonHelpers.ts index 49affa4fc..9d94e6cfd 100644 --- a/frontend/src/packages/editor/components/buttons/buttonHelpers.ts +++ b/frontend/src/packages/editor/components/buttons/buttonHelpers.ts @@ -8,7 +8,7 @@ import { ReactEditor } from 'slate-react'; */ const toggleMark = ( editor: BaseEditor & ReactEditor, - format: 'bold' | 'italic' | 'underline' | 'quote' | 'code' | 'checklist' | 'checked' + format: 'bold' | 'italic' | 'underline' | 'quote' | 'code' | 'checklist' ): void => { const isActive = isMarkActive(editor, format); @@ -27,7 +27,7 @@ const toggleMark = ( */ const isMarkActive = ( editor: BaseEditor & ReactEditor, - format: 'bold' | 'italic' | 'underline' | 'quote' | 'code' | 'checklist' | 'checked' + format: 'bold' | 'italic' | 'underline' | 'quote' | 'code' | 'checklist' ): boolean => { // https://docs.slatejs.org/concepts/07-editor // Editor object exposes properties of the current editor From 5b09a2864b6bab2da1e22097af26cce47fdbd20b Mon Sep 17 00:00:00 2001 From: Winnie Tan Date: Sat, 26 Aug 2023 11:48:55 +1000 Subject: [PATCH 4/4] fixed style --- frontend/src/packages/editor/components/EditorBlock.tsx | 2 -- frontend/src/packages/editor/types.ts | 1 - 2 files changed, 3 deletions(-) diff --git a/frontend/src/packages/editor/components/EditorBlock.tsx b/frontend/src/packages/editor/components/EditorBlock.tsx index 559d9b882..82ce6d0a8 100644 --- a/frontend/src/packages/editor/components/EditorBlock.tsx +++ b/frontend/src/packages/editor/components/EditorBlock.tsx @@ -37,8 +37,6 @@ const Text = styled.span<{ quote: boolean; textSize: number; align: string; - checklist: boolean; - checked: boolean; }>` font-weight: ${(props) => (props.bold ? 600 : 400)}; font-style: ${(props) => (props.italic || props.quote ? 'italic' : 'normal')}; diff --git a/frontend/src/packages/editor/types.ts b/frontend/src/packages/editor/types.ts index 645cd0438..fd7a82e3f 100644 --- a/frontend/src/packages/editor/types.ts +++ b/frontend/src/packages/editor/types.ts @@ -17,7 +17,6 @@ export type CustomText = { align?: string; code?: string; checklist?: boolean; - checked?: boolean; }; export type CustomElement = {