craft.js
craft.js copied to clipboard
Rich Text Editor - Is there an example?
Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
Is it possible to use a Rich Text Editor for editing the text content. Is there an example on how this can be done?
Describe the solution you'd like A clear and concise description of what you want to happen.
I would like to see Rich Text Editor added to examples and documentation.
I guess it would be pretty easy to integrate some external solution like CKE5, the problem is that it won't feel really seamless with Craft's UI. E.g. imagine you have a block of text inside an RTE and editors would want to insert a heading in the middle of it. They'd have to first break it apart into two Craft blocks, insert one more node in-between, doesn't feel like a great UX to me.
Actually @prevwong had released a package for v2 of craft that can integrate slate-js: https://www.npmjs.com/package/@craftjs/slate . It's still quite fresh and not everything works perfectly, but UX is somewhat decent. I'm going to work on example that shows how it can be used together when i have a moment 🤞
@matdru @prevwong Awesome! Could you give me a hint where the source of that package is located? I wanted to get some insights to figure out in the meantime how to use it but found nothing so far.
@janus-reith The slate
code is located here, and you can use it by installing one of the v.0.2.0-alpha.x
versions of the @craftjs/core
and @craftjs/slate
packages on NPM.
A word of caution though - the slate package is far from perfect and it's not very performant with larger documents. This is due to the current approach of synching Craft and Slate states together which requires the use of deep equals and other transformations.
The good news is that I'm trying to work on introducing an Operations system to Craft (similar to Slate) that would allow us to translate Slate operations to Craft (and vice versa) directly, so this should technically help us achieve much better performance (and flexibility)!
Edit: A demo project using the slate package: https://github.com/prevwong/craft-rte if you wanna try it out (The APIs will definitely change in the future)
@prevwong Awesome, will try right away, thanks for these details! Right now, my primary use case would only involve some very basic styled text passages which probably won't be nested heavily.
Although for some different future use case I also had that other approach in mind that Notion and Gutenberg Editor take, where the main element is editable text itself, performance would certainly become important there - I wonder how far craftjs and slate could blend for that purpose or if it would even make sense, I guess that outer element could just be handled by craft and spawn Slate-based components when starting to type or something like that. Edit: I just tried out your example and realized that this is exactly what it does, amazing!
I investigated few solutions and at the time I found that implementing it directly on a Text component and then just use it across the different elements was the best course of action.
Here is a video https://youtu.be/AFYcSMYjd3o
The hover function looks something like this
function HoverButton(fontSize, textAlign, weight, tag, color) { return ( <div> <ButtonGroup size="sm" color="red" isAttached variant="outline"> <EditButton cmd="italic" name="I" border="3px 0 0 0" /> </ButtonGroup> </div> ); }
and this is an example of how to modify the selection using execCommand
function EditButton(props) { return ( <Button key={props.cmd} onMouseDown={(evt) => { evt.preventDefault(); document.execCommand(props.cmd, false, evt.target.value); }} > {props.name} </Button> ); }
function EditButton(props) { return ( <Button key={props.cmd} onMouseDown={(evt) => { evt.preventDefault(); document.execCommand(props.cmd, false, evt.target.value); }} > {props.name} </Button> ); }
Looks really nice what you showcase in your video! I refrained from using document.execCommand so far because I was unclear about the spec.
Your right, even though its deprecated it is still usable, with a few font-size hacks to be honest. However I think it will be a quick port to use https://w3c.github.io/input-events/
Has there been any progress on this? I don't see the slate package in the repo anymore, is it still supported?
@Mozzius i believe it lives in next
branch with experimental flag since it iss way too early to guarantee a stable API at this point.
My mistake, I looked at next
but not in experimental