diff --git a/site/examples/custom-types.d.ts b/site/examples/custom-types.d.ts index 720cc54f6..d7ccb300f 100644 --- a/site/examples/custom-types.d.ts +++ b/site/examples/custom-types.d.ts @@ -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[] } diff --git a/site/examples/richtext.tsx b/site/examples/richtext.tsx index 02001854a..cc1d4f19d 100644 --- a/site/examples/richtext.tsx +++ b/site/examples/richtext.tsx @@ -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(initialValue) @@ -39,6 +40,10 @@ 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 = { - type: isActive ? 'paragraph' : isList ? 'list-item' : format, + let newProperties: Partial + if (TEXT_ALIGN_TYPES.includes(format)) { + newProperties = { + align: isActive ? undefined : format, + } + } else { + newProperties = { + type: isActive ? 'paragraph' : isList ? 'list-item' : format, + } } Transforms.setNodes(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
{children}
+ return ( +
+ {children} +
+ ) case 'bulleted-list': - return
    {children}
+ return ( +
    + {children} +
+ ) case 'heading-one': - return

{children}

+ return ( +

+ {children} +

+ ) case 'heading-two': - return

{children}

+ return ( +

+ {children} +

+ ) case 'list-item': - return
  • {children}
  • + return ( +
  • + {children} +
  • + ) case 'numbered-list': - return
      {children}
    + return ( +
      + {children} +
    + ) default: - return

    {children}

    + return ( +

    + {children} +

    + ) } } @@ -155,7 +203,11 @@ const BlockButton = ({ format, icon }) => { const editor = useSlate() return (