storyblok / richtext

A custom javascript resolver for the Storyblok Richtext field.
MIT License
6 stars 3 forks source link

[Feature Request] Pass default resolver as parameter #104

Open apfelbox opened 1 day ago

apfelbox commented 1 day ago

When customizing the resolver of an element, it would be great to get the default resolver passed in. Because some time you may only want to add some attributes, but keep the remaining logic intact. To reuse the example from your announcement post:

const html = richTextResolver({
  resolvers: {
    [MarkTypes.LINK]: (node, defaultResolver) => {
      node.attrs.class = "text-blue-500 hover:text-blue-700 underline transition-colors duration-200 ease-in-out";
      return defaultResolver(node);
    },
  },
}).render(doc);

To be fair, with the current structure that is kind of inconvenient, as the attrs and the node are combined, but it is still possible.

This would be way more readable if it looked like this:

const html = richTextResolver({
  resolvers: {
    [MarkTypes.LINK]: (tag, attrs, children) => {
      return defaultResolver(
        tag,
        {...attrs, class: "text-blue-500 hover:text-blue-700 underline transition-colors duration-200 ease-in-out"},
        children,
      );
    },
  },
}).render(doc);

But maybe that is out of scope.


Expected Behavior

It would be great to have this feature.

Current Behavior

Not implemented yet

Steps to Reproduce

n/a

markus-gx commented 1 day ago

I guess I just add a comment here, since I have a nearly identical Feature request.

I have a scenario where I need to shift the heading levels (h1, h2, etc.) by n. Essentially, if n = 2, an h1 becomes an h3. I didn’t find a solution within the current implementation. My initial idea was to use the resolver option with [BlockType.HEADING] (node) => {}. This would work, but I’d need to write my own headingResolver.

Since a developer might not think of all possible cases like the authors/contributors with resolving headings, I ended up copying the defaultRenderFn and headingResolver from the richtext class to modify the function with the behavior I needed.

My idea for the PR would be to export the standard resolvers with an additional options parameter to override rules. This could result in something like:

const {render, headingResolver} = richTextResolver({
  resolvers: {
    [BlockTypes.HEADING]: (node) => headingResolver(node, {level: node.level + 2})
  }
})