Skip to content

Commit

Permalink
fix(slots): functional component text slots
Browse files Browse the repository at this point in the history
  • Loading branch information
TheAlexLichter committed Jun 18, 2018
1 parent bc736fb commit e1d576b
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 40 deletions.
2 changes: 1 addition & 1 deletion flow/options.flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ declare type Options = {
propsData?: Object,
mocks?: Object,
methods?: Object,
slots?: Object,
slots?: SlotsObject,
scopedSlots?: Object,
localVue?: Component,
provide?: Object,
Expand Down
17 changes: 11 additions & 6 deletions packages/create-instance/add-slots.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ function startsWithTag (str) {
return str && str.trim()[0] === '<'
}

function createVNodesForSlot (
export function createVNodesForSlot (
h: Function,
slotValue: SlotValue,
name: string
Expand All @@ -30,12 +30,17 @@ export function createSlotVNodes (
return Object.keys(slots).reduce((acc, key) => {
const content = slots[key]
if (Array.isArray(content)) {
const nodes = content.reduce((accInner, slotDef) => {
return accInner.concat(createVNodesForSlot(h, slotDef, key))
}, [])
const nodes = content.map(slotDef => createVNodesForSlot(h, slotDef, key))
return acc.concat(nodes)
} else {
return acc.concat(createVNodesForSlot(h, content, key))
}

return acc.concat(createVNodesForSlot(h, content, key))
}, [])
}

export function createFunctionalSlotVNodes (
h: Function,
slots: SlotsObject
) {
return createSlotVNodes(h, slots)
}
35 changes: 2 additions & 33 deletions packages/create-instance/create-functional-component.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,8 @@
// @flow

import { compileToFunctions } from 'vue-template-compiler'
import { throwError } from 'shared/util'
import { validateSlots } from './validate-slots'

function createFunctionalSlots (slots = {}, h) {
if (Array.isArray(slots.default)) {
return slots.default.map(h)
}

if (typeof slots.default === 'string') {
return [h(compileToFunctions(slots.default))]
}
const children = []
Object.keys(slots).forEach(slotType => {
if (Array.isArray(slots[slotType])) {
slots[slotType].forEach(slot => {
const component =
typeof slot === 'string' ? compileToFunctions(slot) : slot
const newSlot = h(component)
newSlot.data.slot = slotType
children.push(newSlot)
})
} else {
const component =
typeof slots[slotType] === 'string'
? compileToFunctions(slots[slotType])
: slots[slotType]
const slot = h(component)
slot.data.slot = slotType
children.push(slot)
}
})
return children
}
import { createFunctionalSlotVNodes } from './add-slots'

export default function createFunctionalComponent (
component: Component,
Expand All @@ -56,7 +25,7 @@ export default function createFunctionalComponent (
mountingOptions.context.children.map(
x => (typeof x === 'function' ? x(h) : x)
)) ||
createFunctionalSlots(mountingOptions.slots, h)
createFunctionalSlotVNodes(h, mountingOptions.slots)
)
},
name: component.name,
Expand Down
19 changes: 19 additions & 0 deletions test/specs/mounting-options/slots.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,25 @@ describeWithMountingMethods('options.slots', mountingMethod => {
}
})

it('mounts functional component with text slot', () => {
const TestComponent = {
name: 'component-with-slots',
functional: true,
render: (h, ctx) => h('div', ctx.data, [ctx.slots().default, ctx.slots().header])
}
const wrapper = mountingMethod(TestComponent, {
slots: {
default: 'hello,',
header: 'world'
}
})
if (mountingMethod.name === 'renderToString') {
expect(wrapper).contains('hello,world')
} else {
expect(wrapper.text()).to.contain('hello,world')
}
})

it('mounts component with named slot if passed component in slot object', () => {
const wrapper = mountingMethod(ComponentWithSlots, {
slots: {
Expand Down

0 comments on commit e1d576b

Please sign in to comment.