You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy-pasting content between incompatible implementations of Slate-based editors creates an exception, or put another way, it seems Plate cannot handle elements with an unfamiliar/unrecognized type attribute value.
Let's say you have a Plate editor and another Slate editor in another software package - in my case Keystone. These editors both use the Slate data format (application/x-slate-fragment), but element type is coded differently. For example:
paragraph instead of p
heading along with level: n instead of h1, h2, etc
code instead of code_block
And so on. While the pasting operation is successful (text appears unformatted), the type survived in the underlying AST. It's when you want to perform operations on these elements -- for example reformatting headers -- that you get a big nasty error:
Unhandled Runtime Error
Error: Rendered more hooks than during the previous render.
..\extensions\plate\plate-ui\dropdown-menu.tsx (171:21) @ _value
169 | const onOpenChange = useCallback(
170 | ( _value = ! open ) => {
> 171 | setOpen( _value )
| ^
172 | },
173 | [ open ],
174 | )
A screenshot of the error is attached. Evidently, the problem is in the DropdownMenu component (called by TurnIntoDropdownMenu) that I installed via the CLI. I've included the code for both. The Plate installation is close to vanilla, as I'm just getting familiar with Plate.
Code
Here's some incompatible markup (after pasting rich text into Plate) that will trigger an error:
I think in the general case, where manually handling conversions between different Slate editors isn't feasible, the best solution would be to prevent Slate fragments from being copied between incompatible editors in the first place.
In addition to the application/x-slate-fragment data type on the clipboard, Slate editors also encode the fragment in the text/html data using a data-slate-fragment HTML attribute on the first copied element.
withReact already has a clipboardFragmentKey option that can be used to customise application/x-slate-fragment, but there's currently no way of customising data-slate-fragment.
@galloppinggryphon Would you be able to make a PR on Slate such that the clipboardFragmentKey option is used for generating the HTML attribute name? You'll need to modify with-react.ts and dom.ts to refactor all hardcoded occurrences of data-slate-fragment.
To minimise the risk of breaking apps' custom logic, I think the defaults should remain the same. This might look like (simplified):
// Change the default from 'x-slate-fragment' to 'slate-fragment'exportconstwithReact=(editor: T,clipboardFormatKey='slate-fragment')=>{constdataType=`application/x-${clipboardFormatKey}`// default 'application/x-slate-fragment'constattributeName=`data-${clipboardFormatKey}`// default 'data-slate-fragment'// ...}
Once this logic is in place, we can modify packages/core/src/client/plugins/react/createReactPlugin.ts in Plate to make clipboardFormatKey customisable, perhaps through a convenient prop on the <Plate> component.
Description
The problem
Copy-pasting content between incompatible implementations of Slate-based editors creates an exception, or put another way, it seems Plate cannot handle elements with an unfamiliar/unrecognized
type
attribute value.Let's say you have a Plate editor and another Slate editor in another software package - in my case Keystone. These editors both use the Slate data format (
application/x-slate-fragment
), but element type is coded differently. For example:paragraph
instead ofp
heading
along withlevel: n
instead ofh1
,h2
, etccode
instead ofcode_block
And so on. While the pasting operation is successful (text appears unformatted), the
type
survived in the underlying AST. It's when you want to perform operations on these elements -- for example reformatting headers -- that you get a big nasty error:A screenshot of the error is attached. Evidently, the problem is in the
DropdownMenu
component (called byTurnIntoDropdownMenu
) that I installed via the CLI. I've included the code for both. The Plate installation is close to vanilla, as I'm just getting familiar with Plate.Code
Here's some incompatible markup (after pasting rich text into Plate) that will trigger an error:
dropdown-menu.tsx
turn-into-dropdown-menu.tsx
Workaround
For my own purposes, I created a small plugin to convert Keystone Slate JSON to Plate JSON. This fixes the problem and also retains formatting.
slate-deserializer-plugin.ts
Reproduction URL
No response
Reproduction steps
1. Paste content from another (incompatible) Slate implementation 2. Attempt to switch the type of an element 3. Watch it throw an exception
Plate version
36.2.1
Slate React version
0.107.1
Screenshots
![React exception](https://github.com/user-attachments/assets/3af59cee-1663-409a-9a89-26c79730feae)
Logs
No response
Browsers
Firefox
Funding
The text was updated successfully, but these errors were encountered: