-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: pass HTML serializer children as string #29
Conversation
OK, I'm confused. Don't you want to just update The excessive wrapping here looks weird to me 🤔 |
It depends where we want to do the string concatenation. We can't just call We could conditionally check within I think from a "purity" sense, however, we should keep custom behavior outside the low-level library. |
OK got it! Totally missed that children can be an array of anything. Therefore indeed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, just a quick refactor maybe, you might already have ruled it out for some reasons I missed though 🤔
src/asHTML.ts
Outdated
const prepareHTMLMapSerializer = ( | ||
serializer: HTMLMapSerializer, | ||
): RichTextFunctionSerializer<string> => { | ||
return wrapMapSerializer({ | ||
heading1: withStringifiedChildren(serializer.heading1), | ||
heading2: withStringifiedChildren(serializer.heading2), | ||
heading3: withStringifiedChildren(serializer.heading3), | ||
heading4: withStringifiedChildren(serializer.heading4), | ||
heading5: withStringifiedChildren(serializer.heading5), | ||
heading6: withStringifiedChildren(serializer.heading6), | ||
paragraph: withStringifiedChildren(serializer.paragraph), | ||
preformatted: withStringifiedChildren(serializer.preformatted), | ||
strong: withStringifiedChildren(serializer.strong), | ||
em: withStringifiedChildren(serializer.em), | ||
listItem: withStringifiedChildren(serializer.listItem), | ||
oListItem: withStringifiedChildren(serializer.oListItem), | ||
list: withStringifiedChildren(serializer.list), | ||
oList: withStringifiedChildren(serializer.oList), | ||
image: withStringifiedChildren(serializer.image), | ||
embed: withStringifiedChildren(serializer.embed), | ||
hyperlink: withStringifiedChildren(serializer.hyperlink), | ||
label: withStringifiedChildren(serializer.label), | ||
span: withStringifiedChildren(serializer.span), | ||
}); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about just updating the existing keys of the provided map serializer here? Something along the following:
const prepareHTMLMapSerializer = (serializer: HTMLMapSerializer): RichTextFunctionSerializer<string> => {
return wrapMapSerializer(Object.entries(serializer).reduce((acc, [key, value]) => {
if (value) {
acc[key] = (payload) => value({ ...payload, children: payload.children.join("") });
}
return acc;
}, {}));
}
Could help with bundle size without impacting too much performances since the map is not meant to grow over the available tags?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only reason I went with the big object is to resolve type errors. I just tried again with the shorter reducer/for...in method and still couldn't find a way to get it to work without @ts-expect-error
.
If you have any ideas on how to do it with working types, I'd love to use that version instead!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll give it a try
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, this is painful indeed, cannot get beyond that because it tries to merge every parameters possible:
const prepareHTMLMapSerializer = (
serializer: HTMLMapSerializer
): RichTextFunctionSerializer<string> => {
return wrapMapSerializer(
(Object.entries(serializer) as [keyof HTMLMapSerializer, HTMLMapSerializer[keyof HTMLMapSerializer]][])
.reduce<RichTextMapSerializer<string>>(
(acc, [key, value]) => {
if (value) {
acc[key] = (payload) => value({ ...payload, children: payload.children.join("") });
}
return acc;
},
{}
)
);
};
Thanks for reviewing! I'll leave this as a draft for now. I'm not totally happy with the excessive |
Yup, kinda share the same feeling too~ I think we experienced the same issue already with https://github.com/prismicio/prismic-richtext/blob/v2/src/wrapMapSerializer.ts#L29-L42 (we could have done a huge |
Ah yes, that looks like the same issue. Although it isn't ideal, I prefer keeping the bundle size down by using reduce or for...in with Thanks, I'll make these changes today and leave it open for review. |
@lihbr Ready for review! |
Types of changes
Description
This PR changes behavior with custom Rich Text HTML serializers. Rather than pass children as an array of strings, we can pass children as a concatenated string. This is done under the assumption that since we are returning HTML, a single string is always desired.
This saves the user the step of calling
String.prototype.join
themselves.The following HTML serializers are now valid:
Without this PR,
children
would need to be converted to a string viachildren.join('')
.Checklist: