| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- import React from "react";
- import PropTypes from "prop-types";
- import { Button, Icon } from "@mui/material";
- import { useSlate } from "slate-react";
- import { Editor, Transforms, Element as SlateElement } from "slate";
- const LIST_TYPES = ["numbered-list", "bulleted-list"];
- const TEXT_ALIGN_TYPES = ["left", "center", "right", "justify"];
- const BlockButton = ({ format, icon }) => {
- const editor = useSlate();
- return (
- <Button
- active={isBlockActive(
- editor,
- format,
- TEXT_ALIGN_TYPES.includes(format) ? "align" : "type"
- )}
- onMouseDown={(event) => {
- event.preventDefault();
- toggleBlock(editor, format);
- }}
- >
- <Icon>{icon}</Icon>
- </Button>
- );
- };
- const isBlockActive = (editor, format, blockType = "type") => {
- const { selection } = editor;
- if (!selection) return false;
-
- const [match] = Array.from(
- Editor.nodes(editor, {
- at: Editor.unhangRange(editor, selection),
- match: (n) =>
- !Editor.isEditor(n) &&
- SlateElement.isElement(n) &&
- n[blockType] === format,
- })
- );
-
- return !!match;
- };
- const toggleBlock = (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) &&
- !TEXT_ALIGN_TYPES.includes(format),
- split: true,
- });
- let newProperties;
- 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);
-
- if (!isActive && isList) {
- const block = { type: format, children: [] };
- Transforms.wrapNodes(editor, block);
- }
- };
- BlockButton.propTypes = {
- format: PropTypes.any,
- icon: PropTypes.any,
- };
- export default BlockButton;
|