mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-21 22:45:18 +02:00
Add Simple Alignment to richtext example (#4867)
This commit is contained in:
25
site/examples/custom-types.d.ts
vendored
25
site/examples/custom-types.d.ts
vendored
@@ -10,10 +10,15 @@ import {
|
|||||||
import { ReactEditor } from 'slate-react'
|
import { ReactEditor } from 'slate-react'
|
||||||
import { HistoryEditor } from 'slate-history'
|
import { HistoryEditor } from 'slate-history'
|
||||||
|
|
||||||
export type BlockQuoteElement = { type: 'block-quote'; children: Descendant[] }
|
export type BlockQuoteElement = {
|
||||||
|
type: 'block-quote'
|
||||||
|
align?: string
|
||||||
|
children: Descendant[]
|
||||||
|
}
|
||||||
|
|
||||||
export type BulletedListElement = {
|
export type BulletedListElement = {
|
||||||
type: 'bulleted-list'
|
type: 'bulleted-list'
|
||||||
|
align?: string
|
||||||
children: Descendant[]
|
children: Descendant[]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,9 +33,17 @@ export type EditableVoidElement = {
|
|||||||
children: EmptyText[]
|
children: EmptyText[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type HeadingElement = { type: 'heading'; children: Descendant[] }
|
export type HeadingElement = {
|
||||||
|
type: 'heading'
|
||||||
|
align?: string
|
||||||
|
children: Descendant[]
|
||||||
|
}
|
||||||
|
|
||||||
export type HeadingTwoElement = { type: 'heading-two'; children: Descendant[] }
|
export type HeadingTwoElement = {
|
||||||
|
type: 'heading-two'
|
||||||
|
align?: string
|
||||||
|
children: Descendant[]
|
||||||
|
}
|
||||||
|
|
||||||
export type ImageElement = {
|
export type ImageElement = {
|
||||||
type: 'image'
|
type: 'image'
|
||||||
@@ -50,7 +63,11 @@ export type MentionElement = {
|
|||||||
children: CustomText[]
|
children: CustomText[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ParagraphElement = { type: 'paragraph'; children: Descendant[] }
|
export type ParagraphElement = {
|
||||||
|
type: 'paragraph'
|
||||||
|
align?: string
|
||||||
|
children: Descendant[]
|
||||||
|
}
|
||||||
|
|
||||||
export type TableElement = { type: 'table'; children: TableRow[] }
|
export type TableElement = { type: 'table'; children: TableRow[] }
|
||||||
|
|
||||||
|
@@ -20,6 +20,7 @@ const HOTKEYS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const LIST_TYPES = ['numbered-list', 'bulleted-list']
|
const LIST_TYPES = ['numbered-list', 'bulleted-list']
|
||||||
|
const TEXT_ALIGN_TYPES = ['left', 'center', 'right', 'justify']
|
||||||
|
|
||||||
const RichTextExample = () => {
|
const RichTextExample = () => {
|
||||||
const [value, setValue] = useState<Descendant[]>(initialValue)
|
const [value, setValue] = useState<Descendant[]>(initialValue)
|
||||||
@@ -39,6 +40,10 @@ const RichTextExample = () => {
|
|||||||
<BlockButton format="block-quote" icon="format_quote" />
|
<BlockButton format="block-quote" icon="format_quote" />
|
||||||
<BlockButton format="numbered-list" icon="format_list_numbered" />
|
<BlockButton format="numbered-list" icon="format_list_numbered" />
|
||||||
<BlockButton format="bulleted-list" icon="format_list_bulleted" />
|
<BlockButton format="bulleted-list" icon="format_list_bulleted" />
|
||||||
|
<BlockButton format="left" icon="format_align_left" />
|
||||||
|
<BlockButton format="center" icon="format_align_center" />
|
||||||
|
<BlockButton format="right" icon="format_align_right" />
|
||||||
|
<BlockButton format="justify" icon="format_align_justify" />
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
<Editable
|
<Editable
|
||||||
renderElement={renderElement}
|
renderElement={renderElement}
|
||||||
@@ -61,18 +66,30 @@ const RichTextExample = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const toggleBlock = (editor, format) => {
|
const toggleBlock = (editor, format) => {
|
||||||
const isActive = isBlockActive(editor, format)
|
const isActive = isBlockActive(
|
||||||
|
editor,
|
||||||
|
format,
|
||||||
|
TEXT_ALIGN_TYPES.includes(format) ? 'align' : 'type'
|
||||||
|
)
|
||||||
const isList = LIST_TYPES.includes(format)
|
const isList = LIST_TYPES.includes(format)
|
||||||
|
|
||||||
Transforms.unwrapNodes(editor, {
|
Transforms.unwrapNodes(editor, {
|
||||||
match: n =>
|
match: n =>
|
||||||
!Editor.isEditor(n) &&
|
!Editor.isEditor(n) &&
|
||||||
SlateElement.isElement(n) &&
|
SlateElement.isElement(n) &&
|
||||||
LIST_TYPES.includes(n.type),
|
LIST_TYPES.includes(n.type) &&
|
||||||
|
!TEXT_ALIGN_TYPES.includes(format),
|
||||||
split: true,
|
split: true,
|
||||||
})
|
})
|
||||||
const newProperties: Partial<SlateElement> = {
|
let newProperties: Partial<SlateElement>
|
||||||
type: isActive ? 'paragraph' : isList ? 'list-item' : format,
|
if (TEXT_ALIGN_TYPES.includes(format)) {
|
||||||
|
newProperties = {
|
||||||
|
align: isActive ? undefined : format,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newProperties = {
|
||||||
|
type: isActive ? 'paragraph' : isList ? 'list-item' : format,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Transforms.setNodes<SlateElement>(editor, newProperties)
|
Transforms.setNodes<SlateElement>(editor, newProperties)
|
||||||
|
|
||||||
@@ -92,7 +109,7 @@ const toggleMark = (editor, format) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const isBlockActive = (editor, format) => {
|
const isBlockActive = (editor, format, blockType = 'type') => {
|
||||||
const { selection } = editor
|
const { selection } = editor
|
||||||
if (!selection) return false
|
if (!selection) return false
|
||||||
|
|
||||||
@@ -100,7 +117,9 @@ const isBlockActive = (editor, format) => {
|
|||||||
Editor.nodes(editor, {
|
Editor.nodes(editor, {
|
||||||
at: Editor.unhangRange(editor, selection),
|
at: Editor.unhangRange(editor, selection),
|
||||||
match: n =>
|
match: n =>
|
||||||
!Editor.isEditor(n) && SlateElement.isElement(n) && n.type === format,
|
!Editor.isEditor(n) &&
|
||||||
|
SlateElement.isElement(n) &&
|
||||||
|
n[blockType] === format,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -113,21 +132,50 @@ const isMarkActive = (editor, format) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Element = ({ attributes, children, element }) => {
|
const Element = ({ attributes, children, element }) => {
|
||||||
|
const style = { textAlign: element.align }
|
||||||
switch (element.type) {
|
switch (element.type) {
|
||||||
case 'block-quote':
|
case 'block-quote':
|
||||||
return <blockquote {...attributes}>{children}</blockquote>
|
return (
|
||||||
|
<blockquote style={style} {...attributes}>
|
||||||
|
{children}
|
||||||
|
</blockquote>
|
||||||
|
)
|
||||||
case 'bulleted-list':
|
case 'bulleted-list':
|
||||||
return <ul {...attributes}>{children}</ul>
|
return (
|
||||||
|
<ul style={style} {...attributes}>
|
||||||
|
{children}
|
||||||
|
</ul>
|
||||||
|
)
|
||||||
case 'heading-one':
|
case 'heading-one':
|
||||||
return <h1 {...attributes}>{children}</h1>
|
return (
|
||||||
|
<h1 style={style} {...attributes}>
|
||||||
|
{children}
|
||||||
|
</h1>
|
||||||
|
)
|
||||||
case 'heading-two':
|
case 'heading-two':
|
||||||
return <h2 {...attributes}>{children}</h2>
|
return (
|
||||||
|
<h2 style={style} {...attributes}>
|
||||||
|
{children}
|
||||||
|
</h2>
|
||||||
|
)
|
||||||
case 'list-item':
|
case 'list-item':
|
||||||
return <li {...attributes}>{children}</li>
|
return (
|
||||||
|
<li style={style} {...attributes}>
|
||||||
|
{children}
|
||||||
|
</li>
|
||||||
|
)
|
||||||
case 'numbered-list':
|
case 'numbered-list':
|
||||||
return <ol {...attributes}>{children}</ol>
|
return (
|
||||||
|
<ol style={style} {...attributes}>
|
||||||
|
{children}
|
||||||
|
</ol>
|
||||||
|
)
|
||||||
default:
|
default:
|
||||||
return <p {...attributes}>{children}</p>
|
return (
|
||||||
|
<p style={style} {...attributes}>
|
||||||
|
{children}
|
||||||
|
</p>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +203,11 @@ const BlockButton = ({ format, icon }) => {
|
|||||||
const editor = useSlate()
|
const editor = useSlate()
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
active={isBlockActive(editor, format)}
|
active={isBlockActive(
|
||||||
|
editor,
|
||||||
|
format,
|
||||||
|
TEXT_ALIGN_TYPES.includes(format) ? 'align' : 'type'
|
||||||
|
)}
|
||||||
onMouseDown={event => {
|
onMouseDown={event => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
toggleBlock(editor, format)
|
toggleBlock(editor, format)
|
||||||
@@ -214,6 +266,7 @@ const initialValue: Descendant[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'paragraph',
|
type: 'paragraph',
|
||||||
|
align: 'center',
|
||||||
children: [{ text: 'Try it out for yourself!' }],
|
children: [{ text: 'Try it out for yourself!' }],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
Reference in New Issue
Block a user