Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

Custom leaf component not rendering

default discord avatar
davthomxyz2 years ago
3

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 />
  </ElementButton>
);

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

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
    notchr2 years ago
    @815030835815776278

    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,

    https://github.com/payloadcms/website-cms/blob/main/src/fields/richText/br/Button/index.tsx
  • default discord avatar
    davthomxyz2 years 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
    lucaceck95last year

    i'm working on a leaf element


    that's my code



    Button/index.tsx


    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 />
      </LeafButton>
    )
    
    export default ToolbarButton


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


    const Icon = () => (
      <svg
        xmlns="http://www.w3.org/2000/svg"
        viewBox="0 0 25 25"
      >
        <path
          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"
          fill="currentColor"
        />
        <path
          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"
          fill="currentColor"
        />
      </svg>
    );


    Leaf/index.tsx


    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}
        {...attributes}>
          {children}
        </span>
    );
    export default SpanLeafElement;


    index.tsx


    import Button from "./Button";
    import Leaf from "./Leaf";
    import { withSpanLeaf } from "./plugin";
    
    const spanLeaf: RichTextCustomLeaf = {
      name: "spanleaf",
      Button,
      Leaf,
      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



    UPDATE:


    seems that i fix the problem...



    const ToolbarButton = () => (
      <LeafButton format="spanleaf">
        <Icon />
      </LeafButton>
    )
Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get dedicated engineering support directly from the Payload team.