Skip to content

Commit 6ab848c

Browse files
author
Roshan Jossy
committed
fix type issues, editor js window in ssr
1 parent e8e724e commit 6ab848c

File tree

6 files changed

+137
-129
lines changed

6 files changed

+137
-129
lines changed

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
node_modules
22
out
3+
src/components/story/editorTools.ts

src/components/Button.tsx

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
import { ReactNode } from "react"
1+
import { ReactNode } from 'react'
22

33
type ButtonProps = {
4-
children: ReactNode
5-
handleClick?: () => void
4+
children: ReactNode
5+
onClick?: () => void
66
}
77

8-
const Button = ({children, handleClick}: ButtonProps) => {
9-
return(
10-
<button
11-
type="button"
12-
className="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center mr-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
13-
onClick={handleClick}
14-
>
15-
{children}
16-
</button>
17-
)
8+
const Button = ({ children, onClick: onClick }: ButtonProps) => {
9+
return (
10+
<button
11+
type="button"
12+
className="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center mr-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
13+
onClick={onClick}
14+
>
15+
{children}
16+
</button>
17+
)
1818
}
1919

20-
export default Button
20+
export default Button

src/components/story/StoryEditor.tsx

Lines changed: 92 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,109 +1,108 @@
1-
import EditorJS from '@editorjs/editorjs';
2-
import React, { useEffect, useRef, useState } from 'react';
3-
import { graphql, useMutation } from 'react-relay';
4-
import Card from '../Card';
5-
import { EDITOR_JS_TOOLS } from './editorTools';
1+
import EditorJS, { LogLevels, OutputData } from '@editorjs/editorjs'
2+
import React, { useEffect, useRef, useState } from 'react'
3+
import { graphql, useMutation } from 'react-relay'
4+
import Button from '../Button'
5+
import Card from '../Card'
6+
import { EDITOR_JS_TOOLS } from './editorTools'
67

7-
const DEFAULT_INITIAL_DATA = () => {
8+
const DEFAULT_INITIAL_DATA = (): OutputData => {
89
return {
9-
"time": new Date().getTime(),
10-
"blocks": [
10+
time: new Date().getTime(),
11+
blocks: [
1112
{
12-
"type": "header",
13-
"data": {
14-
"text": "This is my awesome editor!",
15-
"level": 1
16-
}
13+
type: 'header',
14+
data: {
15+
text: 'This is my awesome editor!',
16+
level: 1,
17+
},
1718
},
18-
]
19+
],
1920
}
2021
}
2122

22-
const getAbstract = (content) => {
23+
const getAbstract = (content: OutputData) => {
2324
let abstract = ''
24-
for(let i =0; i< content.blocks.length; i++){
25-
if (content.blocks[i].type == "header" || content.blocks[i].type =="paragraph") {
25+
for (let i = 0; i < content.blocks.length; i++) {
26+
if (
27+
content.blocks[i].type == 'header' ||
28+
content.blocks[i].type == 'paragraph'
29+
) {
2630
abstract += content.blocks[i].data.text
2731
}
28-
if (abstract.length >= 200) break;
32+
if (abstract.length >= 200) break
2933
}
30-
return abstract;
34+
return abstract
3135
}
32-
33-
const EDITTOR_HOLDER_ID = 'editorjs';
3436

35-
export default function Editor () {
36-
const [postTitle, setPostTitle] = useState('Your Title Goes Here')
37-
const ejInstance = useRef();
38-
const [editorData, setEditorData] = React.useState(DEFAULT_INITIAL_DATA);
39-
40-
useEffect(() => {
41-
if (!ejInstance.current) {
42-
initEditor();
43-
}
44-
return () => {
45-
ejInstance.current.destroy();
46-
ejInstance.current = null;
37+
const EDITTOR_HOLDER_ID = 'editorjs'
38+
39+
export default function Editor() {
40+
const [postTitle, setPostTitle] = useState('Your Title Goes Here')
41+
const ejInstance = useRef<EditorJS | null>()
42+
const [editorData, setEditorData] = React.useState(DEFAULT_INITIAL_DATA)
43+
44+
useEffect(() => {
45+
if (!ejInstance.current) {
46+
initEditor()
47+
}
48+
return () => {
49+
ejInstance?.current?.destroy()
50+
ejInstance.current = null
51+
}
52+
}, [])
53+
54+
const initEditor = () => {
55+
const editor = new EditorJS({
56+
holder: EDITTOR_HOLDER_ID,
57+
data: editorData,
58+
onReady: () => {
59+
ejInstance.current = editor
60+
},
61+
onChange: async () => {
62+
const content = await editor.saver.save()
63+
setEditorData(content)
64+
},
65+
autofocus: true,
66+
tools: EDITOR_JS_TOOLS,
67+
inlineToolbar: true,
68+
})
69+
}
70+
const [commitMutation, isMutationInFlight] = useMutation(
71+
graphql`
72+
mutation StoryEditorCreateMutation($input: StoryInput!) {
73+
createStory(story: $input) {
74+
id
75+
}
4776
}
48-
}, []);
49-
50-
const initEditor = () => {
51-
const editor = new EditorJS({
52-
holder: EDITTOR_HOLDER_ID,
53-
logLevel: "ERROR",
54-
data: editorData,
55-
onReady: () => {
56-
ejInstance.current = editor;
77+
`
78+
)
79+
const handleStorySubmit = () => {
80+
commitMutation({
81+
variables: {
82+
input: {
83+
title: postTitle,
84+
contentJson: JSON.stringify(editorData),
85+
abstractContent: getAbstract(editorData),
86+
urlSuffix: postTitle.toLowerCase().replace(' ', '-').substring(0, 32),
87+
thumbnail: '',
5788
},
58-
onChange: async () => {
59-
let content = await editor.saver.save();
60-
// Put your logic here to save this data to your DB
61-
setEditorData(content);
62-
},
63-
autofocus: true,
64-
tools: EDITOR_JS_TOOLS,
65-
inlineToolbar: true,
66-
placehodler: 'water'
67-
});
68-
};
69-
const [commitMutation, isMutationInFlight] = useMutation(
70-
graphql`
71-
mutation StoryEditorCreateMutation($input: StoryInput!) {
72-
createStory(story:$input) {
73-
id
74-
}
89+
},
90+
})
91+
}
92+
return (
93+
<Card classes="prose max-w-none">
94+
<div>
95+
<div id={EDITTOR_HOLDER_ID}> </div>
96+
</div>
97+
<style jsx>
98+
{`
99+
[contenteditable]:focus {
100+
outline: 0px solid transparent;
101+
border-bottom: 1px dashed #aaa;
75102
}
76-
`
77-
);
78-
const handleStorySubmit = () => {
79-
commitMutation({
80-
variables: {
81-
input: {
82-
title: postTitle,
83-
contentJson: JSON.stringify(editorData),
84-
abstractContent: getAbstract(editorData),
85-
urlSuffix: postTitle.toLowerCase().replace(" ", "-").substring(0, 32),
86-
thumbnail: ''
87-
},
88-
},
89-
})
90-
}
91-
return (
92-
<Card classes="prose">
93-
<h1 contentEditable onInput={(e) => setPostTitle(e.target.textContent)}>{postTitle}</h1>
94-
<div>
95-
<div id={EDITTOR_HOLDER_ID}> </div>
96-
</div>
97-
<style jsx>
98-
{`
99-
[contenteditable]:focus {
100-
outline: 0px solid transparent;
101-
border-bottom: 1px dashed #aaa;
102-
}
103-
`}
104-
</style>
105-
<button onClick={() => handleStorySubmit()}>submit </button>
106-
</Card>
107-
)
108-
109-
}
103+
`}
104+
</style>
105+
<Button onClick={() => handleStorySubmit()}>Submit </Button>
106+
</Card>
107+
)
108+
}

src/index.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
declare module '@editorjs/table'
2+
declare module '@editorjs/list'
3+
declare module '@editorjs/code'
4+
declare module '@editorjs/image'
5+
declare module '@editorjs/header'

src/pages/home.tsx

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
import Button from "../components/Button";
1+
import Button from '../components/Button'
22

33
export default function Home() {
4-
const handleLogin = async () => {
5-
fetch('https://api.github.com')
6-
}
7-
return(
8-
<div className="container p-8">
9-
<Button handleClick={handleLogin}>
10-
Login with GitHub
11-
</Button>
12-
</div>
13-
)
14-
}
4+
const handleLogin = async () => {
5+
fetch('https://api.github.com')
6+
}
7+
return (
8+
<div className="container p-8">
9+
<Button onClick={handleLogin}>Login with GitHub</Button>
10+
</div>
11+
)
12+
}

src/pages/story.tsx

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
import dynamic from 'next/dynamic'
22
import Layout from '../components/Layout'
33

4-
const Editor = dynamic(() => import('../components/story/StoryEditor'))
5-
export default function Story () {
6-
return (
7-
<div>
8-
<Layout sidebarContentRight={<div>Promoted</div>} sidebarContentLeft={<div/>}>
9-
<Editor />
10-
</Layout>
11-
</div>
12-
)
13-
}
4+
const Editor = dynamic(() => import('../components/story/StoryEditor'), {
5+
ssr: false,
6+
})
7+
export default function Story() {
8+
return (
9+
<div>
10+
<Layout
11+
sidebarContentRight={<div>Promoted</div>}
12+
sidebarContentLeft={<div>Reactions</div>}
13+
>
14+
<Editor />
15+
</Layout>
16+
</div>
17+
)
18+
}

0 commit comments

Comments
 (0)