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);
}
@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,
https://github.com/payloadcms/website-cms/blob/main/src/fields/richText/br/Button/index.tsxAh 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
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
Discord
online
Get help straight from the Payload team with an Enterprise License.