Skip to content

Instantly share code, notes, and snippets.

@adamdehaven
Created December 11, 2024 18:39
Show Gist options
  • Save adamdehaven/497535a9153c49876f92012f2f85b760 to your computer and use it in GitHub Desktop.
Save adamdehaven/497535a9153c49876f92012f2f85b760 to your computer and use it in GitHub Desktop.
Prose component for native SVG elements that handles transforming any child nodes (e.g. `path`) to lowercase so they are evaluated as native HTML
<template>
<component
:is="render"
v-bind="attrs"
:id="componentId"
class="prose-svg"
>
<slot />
</component>
</template>
<script setup lang="ts">
const { styles = '' } = defineProps<{ styles?: string }>()
const attrs = useAttrs()
const slots = useSlots()
const { componentId } = useCustomStyles(computed(() => styles), attrs.id as string)
// Function to recursively convert tag names to lowercase
const convertVNodeToLowercase = (vnode: any): any => {
if (vnode.type && typeof vnode.type === 'string') {
// Convert the tag name to lowercase if it's an HTML/SVG tag
vnode.type = vnode.type.toLowerCase()
}
// Recursively process children nodes
if (vnode.children) {
if (Array.isArray(vnode.children)) {
vnode.children = vnode.children.map(convertVNodeToLowercase)
} else if (vnode.children && vnode.children.type) {
vnode.children = convertVNodeToLowercase(vnode.children)
}
}
return vnode
}
// Safely handle the slot content
const slotContent = slots.default ? slots.default() : null
// If slot content exists, convert its tag names to lowercase
const lowercaseSlotContent = slotContent ? slotContent.map(convertVNodeToLowercase) : {}
// Render the svg element with custom attributes and lowercase children
const render = h(
'svg',
{},
lowercaseSlotContent, // Render the lowercase slot content inside the SVG
)
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment