Skip to content

Commit a93b49c

Browse files
committed
fix(runtime-vapor): dynamic component attrs fallthrough
1 parent 1ef6e6e commit a93b49c

File tree

3 files changed

+65
-9
lines changed

3 files changed

+65
-9
lines changed

packages/runtime-vapor/__tests__/componentAttrs.spec.ts

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { type Ref, nextTick, ref } from '@vue/runtime-dom'
22
import {
33
createComponent,
4+
createDynamicComponent,
5+
createSlot,
46
defineVaporComponent,
57
renderEffect,
68
setClass,
@@ -277,7 +279,43 @@ describe('attribute fallthrough', () => {
277279
expect(getCSS()).not.toContain('font-size:bold')
278280
})
279281

280-
test('parent value should take priority', async () => {
282+
it('should fallthrough attrs to dynamic component', async () => {
283+
const Comp = defineVaporComponent({
284+
setup() {
285+
const n1 = createDynamicComponent(
286+
() => 'button',
287+
null,
288+
{
289+
default: () => {
290+
const n0 = createSlot('default', null)
291+
return n0
292+
},
293+
},
294+
true,
295+
)
296+
return n1
297+
},
298+
})
299+
300+
const { html } = define({
301+
setup() {
302+
return createComponent(
303+
Comp,
304+
{
305+
class: () => 'foo',
306+
},
307+
null,
308+
true,
309+
)
310+
},
311+
}).render()
312+
313+
expect(html()).toBe(
314+
'<button class="foo"><!--slot--></button><!--dynamic-component-->',
315+
)
316+
})
317+
318+
it('parent value should take priority', async () => {
281319
const parentVal = ref('parent')
282320
const childVal = ref('child')
283321

packages/runtime-vapor/src/component.ts

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
unregisterHMR,
2626
warn,
2727
} from '@vue/runtime-dom'
28-
import { type Block, insert, isBlock, remove } from './block'
28+
import { type Block, DynamicFragment, insert, isBlock, remove } from './block'
2929
import {
3030
type ShallowRef,
3131
markRaw,
@@ -249,14 +249,16 @@ export function createComponent(
249249
if (
250250
instance.hasFallthrough &&
251251
component.inheritAttrs !== false &&
252-
instance.block instanceof Element &&
253252
Object.keys(instance.attrs).length
254253
) {
255-
renderEffect(() => {
256-
isApplyingFallthroughProps = true
257-
setDynamicProps(instance.block as Element, [instance.attrs])
258-
isApplyingFallthroughProps = false
259-
})
254+
const el = getRootElement(instance)
255+
if (el) {
256+
renderEffect(() => {
257+
isApplyingFallthroughProps = true
258+
setDynamicProps(el, [instance.attrs])
259+
isApplyingFallthroughProps = false
260+
})
261+
}
260262
}
261263

262264
resetTracking()
@@ -545,3 +547,18 @@ export function getExposed(
545547
)
546548
}
547549
}
550+
551+
function getRootElement({
552+
block,
553+
}: VaporComponentInstance): Element | undefined {
554+
if (block instanceof Element) {
555+
return block
556+
}
557+
558+
if (block instanceof DynamicFragment) {
559+
const { nodes } = block
560+
if (nodes instanceof Element && (nodes as any).$root) {
561+
return nodes
562+
}
563+
}
564+
}

packages/runtime-vapor/src/componentProps.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,8 @@ export function hasAttrFromRawProps(rawProps: RawProps, key: string): boolean {
210210
if (dynamicSources) {
211211
let i = dynamicSources.length
212212
while (i--) {
213-
if (hasOwn(resolveSource(dynamicSources[i]), key)) {
213+
const source = resolveSource(dynamicSources[i])
214+
if (source && hasOwn(source, key)) {
214215
return true
215216
}
216217
}

0 commit comments

Comments
 (0)