Custom leaf component not rendering

default discord avatar
3 months ago

Hey! I'm having some trouble getting a custom leaf's component to render in the Slate editor.

(Video attached) I expected when I used the highilighted text button that the next would get larger, but that didn't wasn't happening. In browser devtools, there doesn't appear to be a change in the HTML when clicking the button either.

Here's my code:

// highlighted-text.tsx

import { ElementButton } from "payload/components/rich-text";
import { PaintBrushIcon } from "@heroicons/react/24/outline";
import { RichTextCustomElement } from "payload/types";

import "./highlighted-text.scss";

const HighlightedTextButton: React.FC<{ path: string }> = () => (
  <ElementButton format={""}>
    <PaintBrushIcon />

const HighlightedTextLeaf: React.FC<{
  attributes: any;
  element: any;
  children?: React.ReactNode;
}> = ({ attributes, children }) => (
  <span {...attributes}>
    <div className="highlighted-text">{children}</div>

export const highlightedTextLeaf: RichTextCustomElement = {
  name: "highlighted-text",
  Button: HighlightedTextButton,
  Element: HighlightedTextLeaf,
  plugins: [],

# highlighted-text.scss

@import "~payload/scss";

.highilighted-text {
  font-size: base(.8);
  margin-bottom: base(.5);
  • default discord avatar
    3 months ago

    @davthomxyz I'm pretty bad with React/JSX, but I think the format="" needs to be a string right?

    (Looking at official custom leaf examples, the button seems to always have format="action")

    For instance,
  • default discord avatar
    3 months ago

    Ah good catch, let me try that

    Didn't work 😦

    Update: That code actually worked as an element, but not a leaf

    Update: It was because I was using the <ElementButton> component not the <LeafButton> component

  • default discord avatar
    2 months ago

    i'm working on a leaf element

    that's my code


    import React from 'react'
    import { LeafButton } from 'payload/components/rich-text'
    import Icon from '../Icon'
    const baseClass = 'color'
    const ToolbarButton: React.FC<{ path: string }> = () => (
      <LeafButton children={baseClass} format="spanleaf">
        <Icon />
    export default ToolbarButton

    Icon/index.tsx (copied from LargeText element on payload demo)

    const Icon = () => (
        viewBox="0 0 25 25"
          d="M6.61695 9.94917L3.16602 19.25H4.65415L5.37256 17.2102H9.41361L10.1448 19.25H11.7356L8.23337 9.94917H6.61695ZM5.80874 15.9787L7.37384 11.5399L8.96461 15.9787H5.80874Z"
          d="M14.2739 5.75H16.7691L21.8339 19.25H19.2457L18.1843 16.2521H12.7098L11.667 19.25H9.24635L14.2739 5.75ZM13.3988 14.2783H17.4767L15.4284 8.48724L13.3988 14.2783Z"


    import React from 'react';
    import './index.scss';
    const baseClass = 'rich-text-spanleaf';
    const SpanLeafElement: React.FC<{
      attributes: any
      element: any
      children: React.ReactNode
    }> = ({ attributes, children }) => (
        <span className={baseClass}
    export default SpanLeafElement;


    import Button from "./Button";
    import Leaf from "./Leaf";
    import { withSpanLeaf } from "./plugin";
    const spanLeaf: RichTextCustomLeaf = {
      name: "spanleaf",
      plugins: [withSpanLeaf],
    export default spanLeaf;

    every works fine..

    but i have a problem on build.

    src/fields/richText/spanLeaf/Button/index.tsx(9,15): error TS2710: 'children' are specified twice. The attribute named 'children' will be overwritten.

    i don't know how to fix it


    seems that i fix the problem...

    const ToolbarButton = () => (
      <LeafButton format="spanleaf">
        <Icon />
Open the post
Continue the discussion in Discord
Like what we're doing?
Star us on GitHub!


Connect with the Payload Community on Discord



Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.