slate#Transforms TypeScript Examples

The following examples show how to use slate#Transforms. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utilities.tsx    From payload with MIT License 7 votes vote down vote up
wrapLink = (editor: Editor, url?: string, newTab?: boolean): void => {
  const { selection, blurSelection } = editor;

  if (blurSelection) {
    Transforms.select(editor, blurSelection);
  }

  if (isElementActive(editor, 'link')) {
    unwrapLink(editor);
  } else {
    const selectionToUse = selection || blurSelection;

    const isCollapsed = selectionToUse && Range.isCollapsed(selectionToUse);

    const link = {
      type: 'link',
      url,
      newTab,
      children: isCollapsed ? [{ text: url }] : [],
    };

    if (isCollapsed) {
      Transforms.insertNodes(editor, link);
    } else {
      Transforms.wrapNodes(editor, link, { split: true });
      Transforms.collapse(editor, { edge: 'end' });
    }
  }
}
Example #2
Source File: block.ts    From slate-yjs-example with MIT License 6 votes vote down vote up
toggleBlock = (editor: Editor, format: string): void => {
  const isActive = isBlockActive(editor, format);
  const isList = LIST_TYPES.includes(format);

  Transforms.unwrapNodes(editor, {
    match: (n) => LIST_TYPES.includes(n.type as any),
    split: true,
  });

  Transforms.setNodes(editor, {
    type: isActive ? "paragraph" : isList ? "list-item" : format,
  });

  if (!isActive && isList) {
    const block = { type: format, children: [] };
    Transforms.wrapNodes(editor, block);
  }
}
Example #3
Source File: RichEditor.tsx    From Full-Stack-React-TypeScript-and-Node with MIT License 6 votes vote down vote up
toggleBlock = (editor: Editor, format: string) => {
  const isActive = isBlockActive(editor, format);
  const isList = LIST_TYPES.includes(format);

  Transforms.unwrapNodes(editor, {
    match: (n) => LIST_TYPES.includes(n.type as string),
    split: true,
  });

  Transforms.setNodes(editor, {
    type: isActive ? "paragraph" : isList ? "list-item" : format,
  });

  if (!isActive && isList) {
    const block = { type: format, children: [] };
    Transforms.wrapNodes(editor, block);
  }
}
Example #4
Source File: transforms.ts    From fantasy-editor with MIT License 6 votes vote down vote up
toggleBlock = (editor: Editor, format: string) => {
  const active = isBlockActive(editor, format);
  Transforms.setNodes(
    editor,
    {
      type: active ? 'paragraph' : format,
    },
    { split: false },
  );
}
Example #5
Source File: Editor.tsx    From react-editor-kit with MIT License 6 votes vote down vote up
handleKeyUp = (
  event: React.KeyboardEvent<HTMLDivElement>,
  plugins: Plugin[],
  state: EditorState
) => {
  const { editor } = state;
  const { selection } = editor;
  if (!selection) {
    return;
  }
  const [, path] = SlateEditor.node(editor, selection as Location);
  if (!path.length) {
    return;
  }
  const [parent] = SlateEditor.parent(editor, path);
  if (parent) {
    for (let plugin of plugins) {
      if (plugin.triggers) {
        for (let trigger of plugin.triggers) {
          const matches = findMatches(trigger.pattern, editor, trigger.range);
          if (matches.length) {
            event.preventDefault();
            if (trigger.clear == undefined || trigger.clear) {
              const range = matches[0].range;
              Transforms.delete(editor, { at: range });
            }
            if (trigger.onMatch) {
              trigger.onMatch(state, matches, plugin);
            } else if (plugin.actions) {
              //If onMatch is not set then execute the default PluginAction
              plugin.actions[0].action(state, plugin, { matches });
            }
          }
        }
      }
    }
  }
}
Example #6
Source File: index.tsx    From payload with MIT License 6 votes vote down vote up
insertButton = (editor, { href, label, style, newTab = false }: any) => {
  const text = { text: ' ' };
  const button = {
    type: 'button',
    href,
    style,
    newTab,
    label,
    children: [
      text,
    ],
  };

  const nodes = [button, { children: [{ text: '' }] }];

  if (editor.blurSelection) {
    Transforms.select(editor, editor.blurSelection);
  }

  Transforms.insertNodes(editor, nodes);

  const currentPath = editor.selection.anchor.path[0];
  const newSelection = { anchor: { path: [currentPath + 1, 0], offset: 0 }, focus: { path: [currentPath + 1, 0], offset: 0 } };

  Transforms.select(editor, newSelection);
  ReactEditor.focus(editor);
}
Example #7
Source File: rich-text.tsx    From platyplus with MIT License 6 votes vote down vote up
toggleBlock = (editor, format) => {
  const isActive = isBlockActive(editor, format)
  const isList = LIST_TYPES.includes(format)

  Transforms.unwrapNodes(editor, {
    match: (n) =>
      !Editor.isEditor(n) &&
      SlateElement.isElement(n) &&
      LIST_TYPES.includes(n.type),
    split: true
  })
  const newProperties: Partial<SlateElement> = {
    type: isActive ? 'paragraph' : isList ? 'list-item' : format
  }
  Transforms.setNodes(editor, newProperties)

  if (!isActive && isList) {
    const block = { type: format, children: [] }
    Transforms.wrapNodes(editor, block)
  }
}
Example #8
Source File: client.ts    From slate-ot with MIT License 6 votes vote down vote up
doc.subscribe((err: any) => {
  if (err) {
    throw err;
  }

  e.children = doc.data.children;
  console.log(JSON.stringify(e.children));

  doc.on('op', (op: Operation | Operation[], options: any) => {
    if (options.source === clientId) return;

    const ops = Array.isArray(op) ? op : [op];

    for (const o of ops) {
      console.log(op);
      Transforms.transform(e, o);
    }
  });

  e.apply({
    type: 'insert_node',
    path: [0],
    node: { children: [{ text: 'a quick brown fox' }] },
  });
});
Example #9
Source File: mappingAdvanced.tsx    From ui-schema with MIT License 6 votes vote down vote up
mappingAdvanced: ElementMapping = {
    // eslint-disable-next-line react/display-name
    [pluginOptions.todo_li.type]: ({element, children}) => {
        const editor = useSlateStatic()
        // @ts-ignore
        const {checked} = element
        const readOnly = useReadOnly()
        return <div contentEditable={false}>
            <Checkbox
                checked={Boolean(checked)}
                onChange={(e) => {
                    const path = ReactEditor.findPath(editor as ReactEditor, element)

                    Transforms.setNodes(
                        editor,
                        // @ts-ignore
                        {checked: e.target.checked},
                        {at: path}
                    )
                }}
                disabled={readOnly}
                size={'small'}
                style={{padding: 4}}
            />
            <span
                contentEditable={!readOnly}
                suppressContentEditableWarning
                style={{outline: 0}}
            >
                {children}
            </span>
        </div>
    },
}
Example #10
Source File: images.component.ts    From slate-angular with MIT License 6 votes vote down vote up
createImageNode(imgUrl: string) {
        const imageNode: ImageElement = {
            type: 'image',
            url: imgUrl,
            children: [
                {
                    text: ''
                }
            ]
        }
        Transforms.insertNodes(this.editor, imageNode);
    }
Example #11
Source File: link.ts    From slate-yjs-example with MIT License 5 votes vote down vote up
unwrapLink = (editor: Editor): void => {
  Transforms.unwrapNodes(editor, { match: (n) => n.type === "link" });
}
Example #12
Source File: button-align.tsx    From fantasy-editor with MIT License 5 votes vote down vote up
ButtonAlign: FunctionComponent<Props> = props => {
  const [visible, setVisible] = useState(false);
  const editor = useSlate();

  const match = findBlockActive(editor, alignList);
  const value: string = match?.[0]?.type || BLOCK_ALIGN_LEFT;
  const [mark, setMark] = useState<Range | null>(null);

  const onClick = (e: any) => {
    e.domEvent.preventDefault();
    const selectValue = e.key;
    if (selectValue !== value && mark) {
      ReactEditor.focus(editor);
      Transforms.select(editor, mark);
      if (match) {
        Transforms.unwrapNodes(editor, {
          match: n => n.type === match?.[0]?.type,
          split: true,
        });
      }
      Transforms.wrapNodes(editor, {
        type: selectValue,
        children: [],
      });
    }
    setVisible(false);
  };

  const show = () => {
    const { selection } = editor;
    setMark(selection);
    setVisible(true);
  };

  const menu = (
    <Menu onClick={onClick} className="fc-btn-align-overlay">
      <MenuItem key={BLOCK_ALIGN_LEFT}>
        <IconAlignLeft />
      </MenuItem>
      <MenuItem key={BLOCK_ALIGN_CENTER}>
        <IconAlignCenter />
      </MenuItem>
      <MenuItem key={BLOCK_ALIGN_RIGHT}>
        <IconAlignRight />
      </MenuItem>
      <MenuItem key={BLOCK_ALIGN_JUSTIFY}>
        <IconAlignJustify />
      </MenuItem>
    </Menu>
  );

  return (
    <Dropdown trigger={['click']} overlay={menu} visible={visible} onVisibleChange={setVisible} disabled={isBlockActive(editor, BLOCK_CODE)}>
      <DropdownButton width={45} onMouseDown={show} disabled={isBlockActive(editor, BLOCK_CODE)}>
        {value === BLOCK_ALIGN_CENTER ? (
          <IconAlignCenter />
        ) : value === BLOCK_ALIGN_RIGHT ? (
          <IconAlignRight />
        ) : value === BLOCK_ALIGN_JUSTIFY ? (
          <IconAlignJustify />
        ) : (
          <IconAlignLeft />
        )}
      </DropdownButton>
    </Dropdown>
  );
}