mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-21 06:31:28 +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 { 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 = {
|
||||
type: 'bulleted-list'
|
||||
align?: string
|
||||
children: Descendant[]
|
||||
}
|
||||
|
||||
@@ -28,9 +33,17 @@ export type EditableVoidElement = {
|
||||
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 = {
|
||||
type: 'image'
|
||||
@@ -50,7 +63,11 @@ export type MentionElement = {
|
||||
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[] }
|
||||
|
||||
|
@@ -20,6 +20,7 @@ const HOTKEYS = {
|
||||
}
|
||||
|
||||
const LIST_TYPES = ['numbered-list', 'bulleted-list']
|
||||
const TEXT_ALIGN_TYPES = ['left', 'center', 'right', 'justify']
|
||||
|
||||
const RichTextExample = () => {
|
||||
const [value, setValue] = useState<Descendant[]>(initialValue)
|
||||
@@ -39,6 +40,10 @@ const RichTextExample = () => {
|
||||
<BlockButton format="block-quote" icon="format_quote" />
|
||||
<BlockButton format="numbered-list" icon="format_list_numbered" />
|
||||
<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>
|
||||
<Editable
|
||||
renderElement={renderElement}
|
||||
@@ -61,18 +66,30 @@ const RichTextExample = () => {
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
Transforms.unwrapNodes(editor, {
|
||||
match: n =>
|
||||
!Editor.isEditor(n) &&
|
||||
SlateElement.isElement(n) &&
|
||||
LIST_TYPES.includes(n.type),
|
||||
LIST_TYPES.includes(n.type) &&
|
||||
!TEXT_ALIGN_TYPES.includes(format),
|
||||
split: true,
|
||||
})
|
||||
const newProperties: Partial<SlateElement> = {
|
||||
type: isActive ? 'paragraph' : isList ? 'list-item' : format,
|
||||
let newProperties: Partial<SlateElement>
|
||||
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)
|
||||
|
||||
@@ -92,7 +109,7 @@ const toggleMark = (editor, format) => {
|
||||
}
|
||||
}
|
||||
|
||||
const isBlockActive = (editor, format) => {
|
||||
const isBlockActive = (editor, format, blockType = 'type') => {
|
||||
const { selection } = editor
|
||||
if (!selection) return false
|
||||
|
||||
@@ -100,7 +117,9 @@ const isBlockActive = (editor, format) => {
|
||||
Editor.nodes(editor, {
|
||||
at: Editor.unhangRange(editor, selection),
|
||||
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 style = { textAlign: element.align }
|
||||
switch (element.type) {
|
||||
case 'block-quote':
|
||||
return <blockquote {...attributes}>{children}</blockquote>
|
||||
return (
|
||||
<blockquote style={style} {...attributes}>
|
||||
{children}
|
||||
</blockquote>
|
||||
)
|
||||
case 'bulleted-list':
|
||||
return <ul {...attributes}>{children}</ul>
|
||||
return (
|
||||
<ul style={style} {...attributes}>
|
||||
{children}
|
||||
</ul>
|
||||
)
|
||||
case 'heading-one':
|
||||
return <h1 {...attributes}>{children}</h1>
|
||||
return (
|
||||
<h1 style={style} {...attributes}>
|
||||
{children}
|
||||
</h1>
|
||||
)
|
||||
case 'heading-two':
|
||||
return <h2 {...attributes}>{children}</h2>
|
||||
return (
|
||||
<h2 style={style} {...attributes}>
|
||||
{children}
|
||||
</h2>
|
||||
)
|
||||
case 'list-item':
|
||||
return <li {...attributes}>{children}</li>
|
||||
return (
|
||||
<li style={style} {...attributes}>
|
||||
{children}
|
||||
</li>
|
||||
)
|
||||
case 'numbered-list':
|
||||
return <ol {...attributes}>{children}</ol>
|
||||
return (
|
||||
<ol style={style} {...attributes}>
|
||||
{children}
|
||||
</ol>
|
||||
)
|
||||
default:
|
||||
return <p {...attributes}>{children}</p>
|
||||
return (
|
||||
<p style={style} {...attributes}>
|
||||
{children}
|
||||
</p>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +203,11 @@ const BlockButton = ({ format, icon }) => {
|
||||
const editor = useSlate()
|
||||
return (
|
||||
<Button
|
||||
active={isBlockActive(editor, format)}
|
||||
active={isBlockActive(
|
||||
editor,
|
||||
format,
|
||||
TEXT_ALIGN_TYPES.includes(format) ? 'align' : 'type'
|
||||
)}
|
||||
onMouseDown={event => {
|
||||
event.preventDefault()
|
||||
toggleBlock(editor, format)
|
||||
@@ -214,6 +266,7 @@ const initialValue: Descendant[] = [
|
||||
},
|
||||
{
|
||||
type: 'paragraph',
|
||||
align: 'center',
|
||||
children: [{ text: 'Try it out for yourself!' }],
|
||||
},
|
||||
]
|
||||
|
Reference in New Issue
Block a user