payloadcms / payload

Payload is the open-source, fullstack Next.js framework, giving you instant backend superpowers. Get a full TypeScript backend and admin panel instantly. Use Payload as a headless CMS or for building powerful applications.
https://payloadcms.com
MIT License
25.66k stars 1.63k forks source link

Support for adding plugins to Slate #119

Closed Ontopic closed 3 years ago

Ontopic commented 3 years ago

Thanks for a lovely framework and a nice job on the first video. Really hope you guys will get more traction soon 🤞 At least I'm recommending it to any client that will hear it.

Feature Request

I've found old commit messages (https://github.com/payloadcms/payload/search?q=%22slate-plugin%22&type=commits) where apparently slate-plugins (https://github.com/udecode/slate-plugins) was working with PayloadCMS. They've been working hard over there and are now at their first 1.0.~ (although still alpha) release. I was wondering if we can bring back support for integrating them or opening up more ways to connect with the SlateJS editor instance, also f.e. to hook into event listeners.

Use-Case

See the examples at https://slate-plugins-next.netlify.app/?path=/story/docs-intro--page

Additional Detail

Wondering why the integration was removed? Adding a separate parameter for the plugins on the richText field (not on the element- or leaf-level) could really open up a lot of extra possibilities.

I believe the integration should be made into src/admin/components/forms/field-types/RichText/RichText.tsx. If there are no objections I might be able to send in a pull request.

richardvanbergen commented 3 years ago

Agreed, so far the rich text stuff has been pretty painful. Most importantly to me... we need a decent image plugin that integrates with the existing media library system. I want to do it myself but it takes more time than I have right now.

jmikrut commented 3 years ago

Hi @Ontopic! Thanks for the kind words and the suggestions regarding Slate plugins.

Our first Slate implementation did indeed rely on slate-plugins but we ultimately determined that we wanted to stick more closely to the slate core vs. jumping to an abstraction too quickly.

I will say that in no way are we against revisiting this though. We are totally interested in evaluating it again, especially if it were to be a simple and unobtrusive add vs. having to rearchitect our current approach entirely.

We would be THRILLED if you were to send in a PR. We would absolutely collaborate heavily as well.

@JarrodMFlesch helped implement slate-plugins in the first place and might have some weigh-in here as well.

@richardvanbergen we do have a media element, integrating with existing media libraries, on the way actually. I don't have a firm ETA but that is definitely something that will make its way into Payload itself very soon. Same with simple alignment options. Will do my best to push this up in priority as I also see its value for sure!

We also plan to release some helper components, along with documentation, that will ideally make it much easier and more straightforward to implement custom RTE elements / leaves on your own. The Rich Text editor is definitely going to be receiving some TLC over the next few weeks!

Ontopic commented 3 years ago

Thanks for your quick reply. As I've seen other devs write; it's refreshing how you guys approach things. CMS's used to be something dreadful, now it is (starting 🙃 ) to feel right.

I have a fork locally I could slowly try to incorporate in a pull-request ready format, but for now I think a quick win would already be to allow more access to the props being send to the SlateJS Editor instance, mostly the event handlers.

Another step we could also consider is making use of a render prop (https://reactjs.org/docs/render-props.html) to allow switching out the current Editor component for the slate-plugin's counter-part?

jmikrut commented 3 years ago

Absolutely. We've always wanted to work with a CMS with this approach and that's honestly what spawned Payload.

I'm definitely up for exposing as many props as necessary through the field's config to the Editable component. That should be fairly trivial to do really! Maybe like this:

{
  name: 'yourRichTextField',
  type: 'richText',
  admin: {
    editableProps: {
      // props go here
    }
  }
}

Then we could just spread the props. Boom.

As for a render function, at that point, it might make more sense to just provide your own component entirely for the field via our custom components API, as there would be a decent amount of custom wiring that you'd have to do within your render function and I'm not sure how clean that pattern would be after all is said and done. Not saying this definitively, just a thought that comes up for me.

All good stuff nonetheless. I like this convo.

Ontopic commented 3 years ago

A custom component is what I've been looking into, starting with your RichText component copy / past and import the modules I'm not touching and wrapping it. More props on the RichText component would already solve a lot. Abstracting away the actions needed by Payload to keep "in-touch" with Slate could be bundled in a singleton / service being send down to the custom component for the RichText field. That way you have the same as for other custom fields right now; if you wanna go wild, you're responsible for triggering the appropriate Payload events, like https://github.com/payloadcms/payload/blob/master/docs/admin/components.mdx#sending-and-receiving-values-from-the-form, except of course more actions would have to be called.

Just some wild thoughts though. A simple way to replace the component and add events would go a long way.

richardvanbergen commented 3 years ago

I think the main issue with using @udecode/slate-plugins specifically is that it requires a context provider and there's no way to wrap the editor with that context. Unless I'm misreading the documentation.