Skip to content

Commit

Permalink
fix(Primitive): avoid using comment node as firstChildren (#783)
Browse files Browse the repository at this point in the history
  • Loading branch information
zernonia committed Mar 25, 2024
1 parent ed73054 commit 12965aa
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 6 deletions.
21 changes: 21 additions & 0 deletions packages/radix-vue/src/Primitive/Primitive.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,27 @@ describe('test Primitive functionalities', () => {
expect(wrapper.find('button').exists()).toBe(true)
})

it('should by pass the comment tag', () => {
const wrapper = mount(Primitive, {
props: {
as: 'template',
},
attrs: {
'data-parent-attr': '',
},
slots: {
default: `
<!-- this is a comment -->
<div data-child-attr>Child class</div>
`,
},
})

const element = wrapper.find('div')
expect(element.attributes('data-parent-attr')).toBe('')
expect(element.attributes('data-child-attr')).toBe('')
})

it('should renders div element with custom attribute', () => {
const wrapper = mount(Primitive, {
attrs: {
Expand Down
35 changes: 29 additions & 6 deletions packages/radix-vue/src/Primitive/Slot.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,36 @@
import { cloneVNode, defineComponent, mergeProps } from 'vue'
import { type VNode, cloneVNode, defineComponent, mergeProps } from 'vue'
import { renderSlotFragments } from '@/shared'

function groupChildren(children: VNode[]) {
let firstChildren: VNode | undefined
const commentChildrenBeforeFirst: VNode[] = []
const otherChildren: VNode[] = []

for (let i = 0; i < children.length; i++) {
const child = children[i]
if (!firstChildren) {
if (child.type === Symbol.for('v-cmt')) { // check if the vnode is comment type (https://github.com/vuejs/core/blob/caeb8a68811a1b0f799632582289fcf169fb673c/packages/runtime-core/src/vnode.ts#L66)
commentChildrenBeforeFirst.push(child)
continue
}
firstChildren = child
}
else {
otherChildren.push(child)
}
}
return { firstChildren, otherChildren, commentChildrenBeforeFirst }
}

export const Slot = defineComponent({
name: 'PrimitiveSlot',
inheritAttrs: false,
setup(_, { attrs, slots }) {
return () => {
if (!slots.default)
return null
const childrens = renderSlotFragments(slots.default())

const [firstChildren, ...otherChildren] = childrens
const children = renderSlotFragments(slots.default())
const { firstChildren, otherChildren, commentChildrenBeforeFirst } = groupChildren(children)

if (firstChildren) {
// remove props ref from being inferred
Expand All @@ -31,10 +51,13 @@ export const Slot = defineComponent({
}
}

return childrens.length === 1 ? cloned : [cloned, ...otherChildren]
if (commentChildrenBeforeFirst.length)
return [...commentChildrenBeforeFirst, cloned, ...otherChildren]

return [cloned, ...otherChildren]
}

return childrens
return children
}
},
})

0 comments on commit 12965aa

Please sign in to comment.