114 | Quick Find 115 |
116 |123 | Settings 124 |
125 |196 | Saving... 197 |
198 | ) : ( 199 |200 | Saved{" "} 201 | 202 | {timeSinceShort(note.updatedAt)} ago 203 | 204 |
205 | )} 206 |dino.app
10 | 58 | {name} 59 |
60 | 92 |119 | {data?.getNote.title} 120 |
121 |31 | {name} 32 |
33 |{children}
; 17 | case "H1": 18 | return ( 19 |{children}
;
55 | case "image":
56 | return {el}
;
12 | }
13 |
14 | if (leaf.italic) {
15 | el = {el};
16 | }
17 |
18 | if (leaf.underline) {
19 | el = {el};
20 | }
21 |
22 | if (leaf.highlighted) {
23 | el = (
24 |
25 | {el}
26 |
27 | );
28 | }
29 |
30 | return {el};
31 | };
32 |
--------------------------------------------------------------------------------
/web/src/components/ui/editor/editor.tsx:
--------------------------------------------------------------------------------
1 | import { useApolloClient } from "@apollo/client";
2 | import areEqual from "deep-equal";
3 | import isHotkey from "is-hotkey";
4 | import isUrl from "is-url";
5 | import React, {
6 | createRef,
7 | useCallback,
8 | useEffect,
9 | useMemo,
10 | useRef,
11 | useState,
12 | } from "react";
13 | import { BaseEditor, createEditor, Descendant } from "slate";
14 | import { Editable, ReactEditor, Slate, withReact } from "slate-react";
15 | import {
16 | GetNoteQuery,
17 | UpdateNoteTitleDocument,
18 | useGetNoteQuery,
19 | useUpdateNoteMutation,
20 | useUpdateNoteTitleMutation,
21 | } from "../../../generated/graphql";
22 | import { Navbar, toggleStyle } from "../Navbar";
23 | import { renderElement } from "./core/renderElement";
24 | import { renderLeaf } from "./core/renderLeaf";
25 | import ContentEditable from "react-contenteditable";
26 | import { withHistory } from "slate-history";
27 |
28 | interface EditorProps {
29 | note: GetNoteQuery["getNote"];
30 | }
31 |
32 | type CustomElement = {
33 | type: string;
34 | url?: string;
35 | children: CustomText[];
36 | };
37 | type CustomText = { text: string };
38 | declare module "slate" {
39 | interface CustomTypes {
40 | Editor: BaseEditor & ReactEditor;
41 | Element: CustomElement;
42 | Text: CustomText;
43 | }
44 | }
45 | export type SlateEditor = BaseEditor & ReactEditor;
46 |
47 | const useEditorConfig = (editor: SlateEditor) => {
48 | const onKeyDown = useCallback(
49 | (event) => KeyBindings.onKeyDown(editor, event),
50 | [editor]
51 | );
52 | const { isVoid, isInline } = editor;
53 | editor.isVoid = (element) => {
54 | return ["image"].includes(element.type) || isVoid(element);
55 | editor.isInline = (element) =>
56 | ["link"].includes(element.type) || isInline(element);
57 | };
58 | return { renderElement, renderLeaf, onKeyDown };
59 | };
60 |
61 | const KeyBindings = {
62 | onKeyDown: (editor: any, event: any) => {
63 | if (isHotkey("mod+b", event)) {
64 | toggleStyle(editor, "bold");
65 | return;
66 | }
67 | if (isHotkey("mod+i", event)) {
68 | toggleStyle(editor, "italic");
69 | return;
70 | }
71 | if (isHotkey("mod+`", event)) {
72 | toggleStyle(editor, "code");
73 | return;
74 | }
75 | if (isHotkey("mod+u", event)) {
76 | toggleStyle(editor, "underline");
77 | return;
78 | }
79 | if (isHotkey("mod+h", event)) {
80 | toggleStyle(editor, "highlighted");
81 | return;
82 | }
83 | },
84 | };
85 |
86 | const useSelection = (editor: SlateEditor) => {
87 | const [selection, setSelection] = useState(editor.selection);
88 | const setSelectionOptimized = useCallback(
89 | (newSelection) => {
90 | // don't update the component state if selection hasn't changed.
91 | if (areEqual(selection, newSelection)) {
92 | return;
93 | }
94 | setSelection(newSelection);
95 | },
96 | [setSelection, selection]
97 | );
98 |
99 | return [selection, setSelectionOptimized];
100 | };
101 |
102 | export const Editor: React.FC{children}
195 |28 | We{"'"}ve sent an email with a link to change your 29 | password! 30 |
31 | )} 32 |
28 | Dino
is a new way to jot down your thoughts
29 | and all the stuff that you want to access easily and
30 | quickly. Cos
31 | {"'"} not everything is about productivity
32 |
60 | Unlike other tools, Dino
has a zero
61 | learning curve which means you can start using it
62 | without any confusion
63 |
85 | Dino
user interface is clean, minimal and
86 | organised so you only get to see your docs when you want
87 | to
88 |
22 | Dino
is a new way to jot down your thoughts
23 | and all the stuff that you want to access easily and
24 | quickly. Cos
25 | {"'"} not everything is about productivity
26 |
54 | Unlike other tools, Dino
has a zero
55 | learning curve which means you can start using it
56 | without any confusion
57 |
79 | Dino
user interface is clean, minimal and
80 | organised so you only get to see your docs when you want
81 | to
82 |