Skip to content

Commit e558894

Browse files
committed
feat(richtext-lexical): Upload html serializer: Output picture element if the image has multiple sizes, improve absolute URL creation
1 parent 37aa99f commit e558894

File tree

1 file changed

+50
-4
lines changed
  • packages/richtext-lexical/src/field/features/Upload

1 file changed

+50
-4
lines changed

packages/richtext-lexical/src/field/features/Upload/index.ts

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ export type UploadFeatureProps = {
2020
}
2121
}
2222

23+
/**
24+
* Get the absolute URL for an upload URL by potentially prepending the serverURL
25+
*/
26+
function getAbsoluteURL(url: string): string {
27+
return url?.startsWith('http') ? url : (payload?.config?.serverURL || '') + url
28+
}
29+
2330
export const UploadFeature = (props?: UploadFeatureProps): FeatureProvider => {
2431
return {
2532
feature: () => {
@@ -29,17 +36,56 @@ export const UploadFeature = (props?: UploadFeatureProps): FeatureProvider => {
2936
converters: {
3037
html: {
3138
converter: async ({ node }) => {
32-
const uploadDocument = await payload.findByID({
39+
const uploadDocument: any = await payload.findByID({
3340
id: node.value.id,
3441
collection: node.relationTo,
3542
})
36-
const url = (payload?.config?.serverURL || '') + uploadDocument?.url
43+
const url: string = getAbsoluteURL(uploadDocument?.url as string)
3744

45+
/**
46+
* If the upload is not an image, return a link to the upload
47+
*/
3848
if (!(uploadDocument?.mimeType as string)?.startsWith('image')) {
39-
return `<a href="${url}" rel="noopener noreferrer">Upload node which is not an image</a>`
49+
return `<a href="${url}" rel="noopener noreferrer">${uploadDocument.filename}</a>`
50+
}
51+
52+
/**
53+
* If the upload is a simple image with no different sizes, return a simple img tag
54+
*/
55+
if (!uploadDocument?.sizes || !Object.keys(uploadDocument?.sizes).length) {
56+
return `<img src="${url}" alt="${uploadDocument?.filename}" width="${uploadDocument?.width}" height="${uploadDocument?.height}"/>`
57+
}
58+
59+
/**
60+
* If the upload is an image with different sizes, return a picture element
61+
*/
62+
let pictureHTML = '<picture>'
63+
64+
// Iterate through each size in the data.sizes object
65+
for (const size in uploadDocument.sizes) {
66+
const imageSize = uploadDocument.sizes[size]
67+
68+
// Skip if any property of the size object is null
69+
if (
70+
!imageSize.width ||
71+
!imageSize.height ||
72+
!imageSize.mimeType ||
73+
!imageSize.filesize ||
74+
!imageSize.filename ||
75+
!imageSize.url
76+
) {
77+
continue
78+
}
79+
const imageSizeURL: string = getAbsoluteURL(imageSize?.url as string)
80+
81+
pictureHTML += `<source srcset="${imageSizeURL}" media="(max-width: ${imageSize.width}px)" type="${imageSize.mimeType}">`
4082
}
4183

42-
return `<img src="${url}" alt="${uploadDocument?.filename}" width="${uploadDocument?.width}" height="${uploadDocument?.height}"/>`
84+
// Add the default img tag
85+
pictureHTML += `<img src="${url}" alt="Image" width="${uploadDocument.width}" height="${uploadDocument.height}">`
86+
pictureHTML += '</picture>'
87+
88+
return pictureHTML
4389
},
4490
nodeTypes: [UploadNode.getType()],
4591
} as HTMLConverter<SerializedUploadNode>,

0 commit comments

Comments
 (0)