Skip to content

Commit 3d3938b

Browse files
authoredAug 16, 2022
[Docs] Update with-slate example (vercel#39639)
## Changelog - Migrated `with-slate` example to typescript - Updated dependencies to latest stable versions - Added api route to demonstrate saving of `editorState` ## Documentation / Examples - [x] Make sure the linting passes by running `pnpm lint` - [x] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples)
1 parent 7a93093 commit 3d3938b

File tree

6 files changed

+114
-25
lines changed

6 files changed

+114
-25
lines changed
 

‎examples/with-slate/package.json

+9-4
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@
77
},
88
"dependencies": {
99
"next": "latest",
10-
"react": "^18.0.0",
11-
"react-dom": "^18.0.0",
12-
"slate": "^0.76.1",
10+
"react": "^18.2.0",
11+
"react-dom": "^18.2.0",
12+
"slate": "^0.82.0",
1313
"slate-history": "0.66.0",
14-
"slate-react": "^0.76.1"
14+
"slate-react": "^0.82.0"
15+
},
16+
"devDependencies": {
17+
"@types/node": "18.7.5",
18+
"@types/react": "18.0.17",
19+
"typescript": "4.7.4"
1520
}
1621
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { NextApiRequest, NextApiResponse } from 'next'
2+
3+
export default async function handleEditorStateChange(
4+
req: NextApiRequest,
5+
res: NextApiResponse
6+
) {
7+
if (req.method !== 'POST') {
8+
return res
9+
.setHeader('Allow', ['POST'])
10+
.status(405)
11+
.end(`Method ${req.method} Not Allowed`)
12+
}
13+
14+
const editorState = JSON.parse(req.body)
15+
console.log('TODO: Save editorState on the server', editorState)
16+
17+
res.json({
18+
status: 'ok',
19+
})
20+
}

‎examples/with-slate/pages/index.js

-21
This file was deleted.

‎examples/with-slate/pages/index.tsx

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { useState } from 'react'
2+
import { createEditor, Descendant } from 'slate'
3+
import { Slate, Editable, withReact } from 'slate-react'
4+
import { withHistory } from 'slate-history'
5+
import { InferGetServerSidePropsType } from 'next'
6+
7+
export async function getServerSideProps() {
8+
return {
9+
props: {
10+
editorState: [
11+
{
12+
children: [
13+
{ text: 'This is editable plain text, just like a <textarea>!' },
14+
],
15+
},
16+
],
17+
},
18+
}
19+
}
20+
21+
async function saveEditorState(edtorState: Descendant[]) {
22+
const response = await fetch('/api/editor-state', {
23+
method: 'POST',
24+
body: JSON.stringify(edtorState),
25+
})
26+
return response.json()
27+
}
28+
29+
export default function IndexPage({
30+
editorState,
31+
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
32+
const [editor] = useState(() => withReact(withHistory(createEditor())))
33+
return (
34+
<Slate
35+
editor={editor}
36+
value={editorState}
37+
onChange={async (value) => {
38+
const isAstChange = editor.operations.some(
39+
(op) => 'set_selection' !== op.type
40+
)
41+
if (isAstChange) {
42+
// You might want to debounce the following call!
43+
const responseData = await saveEditorState(value)
44+
console.log('Send editor state to the server', responseData)
45+
}
46+
}}
47+
>
48+
<Editable placeholder="Enter some plain text..." />
49+
</Slate>
50+
)
51+
}

‎examples/with-slate/tsconfig.json

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es5",
4+
"lib": ["dom", "dom.iterable", "esnext"],
5+
"allowJs": true,
6+
"skipLibCheck": true,
7+
"strict": true,
8+
"forceConsistentCasingInFileNames": true,
9+
"noEmit": true,
10+
"incremental": true,
11+
"esModuleInterop": true,
12+
"module": "esnext",
13+
"moduleResolution": "node",
14+
"resolveJsonModule": true,
15+
"isolatedModules": true,
16+
"jsx": "preserve"
17+
},
18+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
19+
"exclude": ["node_modules"]
20+
}

‎examples/with-slate/types/slate.d.ts

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { BaseEditor } from 'slate'
2+
import { ReactEditor } from 'slate-react'
3+
import { HistoryEditor } from 'slate-history'
4+
5+
type CustomElement = { type?: 'paragraph'; children: CustomText[] }
6+
type CustomText = { text: string; bold?: true }
7+
8+
declare module 'slate' {
9+
interface CustomTypes {
10+
Editor: BaseEditor & ReactEditor & HistoryEditor
11+
Element: CustomElement
12+
Text: CustomText
13+
}
14+
}

0 commit comments

Comments
 (0)
Please sign in to comment.