[Docs] Update with-slate example (#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)
This commit is contained in:
Henrik Wenz 2022-08-16 12:47:07 +02:00 committed by GitHub
parent 7a93093332
commit 3d3938b793
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 114 additions and 25 deletions

View file

@ -7,10 +7,15 @@
},
"dependencies": {
"next": "latest",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"slate": "^0.76.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"slate": "^0.82.0",
"slate-history": "0.66.0",
"slate-react": "^0.76.1"
"slate-react": "^0.82.0"
},
"devDependencies": {
"@types/node": "18.7.5",
"@types/react": "18.0.17",
"typescript": "4.7.4"
}
}

View file

@ -0,0 +1,20 @@
import { NextApiRequest, NextApiResponse } from 'next'
export default async function handleEditorStateChange(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method !== 'POST') {
return res
.setHeader('Allow', ['POST'])
.status(405)
.end(`Method ${req.method} Not Allowed`)
}
const editorState = JSON.parse(req.body)
console.log('TODO: Save editorState on the server', editorState)
res.json({
status: 'ok',
})
}

View file

@ -1,21 +0,0 @@
import { useState } from 'react'
import { createEditor } from 'slate'
import { Slate, Editable, withReact } from 'slate-react'
import { withHistory } from 'slate-history'
export default function IndexPage() {
const [editor] = useState(() => withReact(withHistory(createEditor())), [])
const [value, setValue] = useState([
{
children: [
{ text: 'This is editable plain text, just like a <textarea>!' },
],
},
])
return (
<Slate editor={editor} value={value} onChange={setValue}>
<Editable placeholder="Enter some plain text..." />
</Slate>
)
}

View file

@ -0,0 +1,51 @@
import { useState } from 'react'
import { createEditor, Descendant } from 'slate'
import { Slate, Editable, withReact } from 'slate-react'
import { withHistory } from 'slate-history'
import { InferGetServerSidePropsType } from 'next'
export async function getServerSideProps() {
return {
props: {
editorState: [
{
children: [
{ text: 'This is editable plain text, just like a <textarea>!' },
],
},
],
},
}
}
async function saveEditorState(edtorState: Descendant[]) {
const response = await fetch('/api/editor-state', {
method: 'POST',
body: JSON.stringify(edtorState),
})
return response.json()
}
export default function IndexPage({
editorState,
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
const [editor] = useState(() => withReact(withHistory(createEditor())))
return (
<Slate
editor={editor}
value={editorState}
onChange={async (value) => {
const isAstChange = editor.operations.some(
(op) => 'set_selection' !== op.type
)
if (isAstChange) {
// You might want to debounce the following call!
const responseData = await saveEditorState(value)
console.log('Send editor state to the server', responseData)
}
}}
>
<Editable placeholder="Enter some plain text..." />
</Slate>
)
}

View file

@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"incremental": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve"
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}

14
examples/with-slate/types/slate.d.ts vendored Normal file
View file

@ -0,0 +1,14 @@
import { BaseEditor } from 'slate'
import { ReactEditor } from 'slate-react'
import { HistoryEditor } from 'slate-history'
type CustomElement = { type?: 'paragraph'; children: CustomText[] }
type CustomText = { text: string; bold?: true }
declare module 'slate' {
interface CustomTypes {
Editor: BaseEditor & ReactEditor & HistoryEditor
Element: CustomElement
Text: CustomText
}
}