Skip to content

Commit 70333a9

Browse files
Support <slot> children when using as="template" (#1548)
* Extract renderTemplate logic * Flatten Fragments when rendering * Update changelog
1 parent 4e13a0e commit 70333a9

File tree

16 files changed

+147
-216
lines changed

16 files changed

+147
-216
lines changed

packages/@headlessui-vue/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
- Add `by` prop for `Listbox`, `Combobox` and `RadioGroup` ([#1482](https://github.com/tailwindlabs/headlessui/pull/1482))
1313
- Add `@headlessui/tailwindcss` plugin ([#1487](https://github.com/tailwindlabs/headlessui/pull/1487))
1414

15+
### Fixed
16+
17+
- Support `<slot>` children when using `as="template"` ([#1548](https://github.com/tailwindlabs/headlessui/pull/1548))
18+
1519
## [1.6.4] - 2022-05-29
1620

1721
### Fixed

packages/@headlessui-vue/src/components/combobox/combobox.test.ts

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
computed,
1010
PropType,
1111
} from 'vue'
12-
import { render } from '../../test-utils/vue-testing-library'
12+
import { createRenderTemplate, render } from '../../test-utils/vue-testing-library'
1313
import {
1414
Combobox,
1515
ComboboxInput,
@@ -89,21 +89,7 @@ function getDefaultComponents() {
8989
}
9090
}
9191

92-
function renderTemplate(input: string | Partial<DefineComponent>) {
93-
let defaultComponents = getDefaultComponents()
94-
95-
if (typeof input === 'string') {
96-
return render(defineComponent({ template: input, components: defaultComponents }))
97-
}
98-
99-
return render(
100-
defineComponent(
101-
Object.assign({}, input, {
102-
components: { ...defaultComponents, ...input.components },
103-
}) as Parameters<typeof defineComponent>[0]
104-
)
105-
)
106-
}
92+
const renderTemplate = createRenderTemplate(getDefaultComponents())
10793

10894
describe('safeguards', () => {
10995
it.each([

packages/@headlessui-vue/src/components/dialog/dialog.test.ts

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
ConcreteComponent,
88
onMounted,
99
} from 'vue'
10-
import { render } from '../../test-utils/vue-testing-library'
10+
import { createRenderTemplate, render } from '../../test-utils/vue-testing-library'
1111

1212
import {
1313
Dialog,
@@ -58,29 +58,15 @@ beforeAll(() => {
5858

5959
afterAll(() => jest.restoreAllMocks())
6060

61-
function renderTemplate(input: string | ComponentOptionsWithoutProps) {
62-
let defaultComponents = {
63-
Dialog,
64-
DialogOverlay,
65-
DialogBackdrop,
66-
DialogPanel,
67-
DialogTitle,
68-
DialogDescription,
69-
TabSentinel,
70-
}
71-
72-
if (typeof input === 'string') {
73-
return render(defineComponent({ template: input, components: defaultComponents }))
74-
}
75-
76-
return render(
77-
defineComponent(
78-
Object.assign({}, input, {
79-
components: { ...defaultComponents, ...input.components },
80-
}) as Parameters<typeof defineComponent>[0]
81-
)
82-
)
83-
}
61+
const renderTemplate = createRenderTemplate({
62+
Dialog,
63+
DialogOverlay,
64+
DialogBackdrop,
65+
DialogPanel,
66+
DialogTitle,
67+
DialogDescription,
68+
TabSentinel,
69+
})
8470

8571
describe('Safe guards', () => {
8672
it.each([

packages/@headlessui-vue/src/components/disclosure/disclosure.test.ts

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { defineComponent, nextTick, ref, watch, h, ComponentOptionsWithoutProps } from 'vue'
2-
import { render } from '../../test-utils/vue-testing-library'
2+
import { createRenderTemplate, render } from '../../test-utils/vue-testing-library'
33
import { Disclosure, DisclosureButton, DisclosurePanel } from './disclosure'
44
import { suppressConsoleLogs } from '../../test-utils/suppress-console-logs'
55
import {
@@ -19,21 +19,11 @@ jest.mock('../../hooks/use-id')
1919

2020
afterAll(() => jest.restoreAllMocks())
2121

22-
function renderTemplate(input: string | ComponentOptionsWithoutProps) {
23-
let defaultComponents = { Disclosure, DisclosureButton, DisclosurePanel }
24-
25-
if (typeof input === 'string') {
26-
return render(defineComponent({ template: input, components: defaultComponents }))
27-
}
28-
29-
return render(
30-
defineComponent(
31-
Object.assign({}, input, {
32-
components: { ...defaultComponents, ...input.components },
33-
}) as Parameters<typeof defineComponent>[0]
34-
)
35-
)
36-
}
22+
const renderTemplate = createRenderTemplate({
23+
Disclosure,
24+
DisclosureButton,
25+
DisclosurePanel,
26+
})
3727

3828
describe('Safe guards', () => {
3929
it.each([

packages/@headlessui-vue/src/components/focus-trap/focus-trap.test.ts

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { defineComponent, ref, nextTick, onMounted, ComponentOptionsWithoutProps
33
import { FocusTrap } from './focus-trap'
44
import { assertActiveElement, getByText } from '../../test-utils/accessibility-assertions'
55
import { suppressConsoleLogs } from '../../test-utils/suppress-console-logs'
6-
import { render } from '../../test-utils/vue-testing-library'
6+
import { createRenderTemplate, render } from '../../test-utils/vue-testing-library'
77
import { click, press, shift, Keys } from '../../test-utils/interactions'
88
import { html } from '../../test-utils/html'
99

@@ -16,21 +16,9 @@ beforeAll(() => {
1616

1717
afterAll(() => jest.restoreAllMocks())
1818

19-
function renderTemplate(input: string | ComponentOptionsWithoutProps) {
20-
let defaultComponents = { FocusTrap }
21-
22-
if (typeof input === 'string') {
23-
return render(defineComponent({ template: input, components: defaultComponents }))
24-
}
25-
26-
return render(
27-
defineComponent(
28-
Object.assign({}, input, {
29-
components: { ...defaultComponents, ...input.components },
30-
}) as Parameters<typeof defineComponent>[0]
31-
)
32-
)
33-
}
19+
const renderTemplate = createRenderTemplate({
20+
FocusTrap,
21+
})
3422

3523
it('should focus the first focusable element inside the FocusTrap', async () => {
3624
renderTemplate(

packages/@headlessui-vue/src/components/listbox/listbox.test.tsx

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
reactive,
88
ComponentOptionsWithoutProps,
99
} from 'vue'
10-
import { render } from '../../test-utils/vue-testing-library'
10+
import { createRenderTemplate, render } from '../../test-utils/vue-testing-library'
1111
import { Listbox, ListboxLabel, ListboxButton, ListboxOptions, ListboxOption } from './listbox'
1212
import { suppressConsoleLogs } from '../../test-utils/suppress-console-logs'
1313
import {
@@ -66,21 +66,13 @@ function nextFrame() {
6666
})
6767
}
6868

69-
function renderTemplate(input: string | ComponentOptionsWithoutProps) {
70-
let defaultComponents = { Listbox, ListboxLabel, ListboxButton, ListboxOptions, ListboxOption }
71-
72-
if (typeof input === 'string') {
73-
return render(defineComponent({ template: input, components: defaultComponents }))
74-
}
75-
76-
return render(
77-
defineComponent(
78-
Object.assign({}, input, {
79-
components: { ...defaultComponents, ...input.components },
80-
}) as Parameters<typeof defineComponent>[0]
81-
)
82-
)
83-
}
69+
const renderTemplate = createRenderTemplate({
70+
Listbox,
71+
ListboxLabel,
72+
ListboxButton,
73+
ListboxOptions,
74+
ListboxOption,
75+
})
8476

8577
describe('safeguards', () => {
8678
it.each([

packages/@headlessui-vue/src/components/menu/menu.test.tsx

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
ref,
88
watch,
99
} from 'vue'
10-
import { render } from '../../test-utils/vue-testing-library'
10+
import { createRenderTemplate, render } from '../../test-utils/vue-testing-library'
1111
import { Menu, MenuButton, MenuItems, MenuItem } from './menu'
1212
import { TransitionChild } from '../transitions/transition'
1313
import { suppressConsoleLogs } from '../../test-utils/suppress-console-logs'
@@ -61,21 +61,7 @@ function nextFrame() {
6161
})
6262
}
6363

64-
function renderTemplate(input: string | ComponentOptionsWithoutProps) {
65-
let defaultComponents = { Menu, MenuButton, MenuItems, MenuItem }
66-
67-
if (typeof input === 'string') {
68-
return render(defineComponent({ template: input, components: defaultComponents }))
69-
}
70-
71-
return render(
72-
defineComponent(
73-
Object.assign({}, input, {
74-
components: { ...defaultComponents, ...input.components },
75-
}) as Parameters<typeof defineComponent>[0]
76-
)
77-
)
78-
}
64+
const renderTemplate = createRenderTemplate({ Menu, MenuButton, MenuItems, MenuItem })
7965

8066
describe('Safe guards', () => {
8167
it.each([

packages/@headlessui-vue/src/components/popover/popover.test.ts

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { defineComponent, nextTick, ref, watch, h, ComponentOptionsWithoutProps } from 'vue'
2-
import { render } from '../../test-utils/vue-testing-library'
2+
import { createRenderTemplate, render } from '../../test-utils/vue-testing-library'
33

44
import { Popover, PopoverGroup, PopoverButton, PopoverPanel, PopoverOverlay } from './popover'
55
import { Portal } from '../portal/portal'
@@ -28,29 +28,19 @@ beforeAll(() => {
2828

2929
afterAll(() => jest.restoreAllMocks())
3030

31-
function renderTemplate(input: string | ComponentOptionsWithoutProps) {
32-
let defaultComponents = {
31+
function getDefaultComponents() {
32+
return {
3333
Popover,
3434
PopoverGroup,
3535
PopoverButton,
3636
PopoverPanel,
3737
PopoverOverlay,
3838
Portal,
3939
}
40-
41-
if (typeof input === 'string') {
42-
return render(defineComponent({ template: input, components: defaultComponents }))
43-
}
44-
45-
return render(
46-
defineComponent(
47-
Object.assign({}, input, {
48-
components: { ...defaultComponents, ...input.components },
49-
}) as Parameters<typeof defineComponent>[0]
50-
)
51-
)
5240
}
5341

42+
const renderTemplate = createRenderTemplate(getDefaultComponents())
43+
5444
describe('Safe guards', () => {
5545
it.each([
5646
['PopoverButton', PopoverButton],

packages/@headlessui-vue/src/components/portal/portal.test.ts

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { h, defineComponent, ref, nextTick, ComponentOptionsWithoutProps, createSSRApp } from 'vue'
22

3-
import { render } from '../../test-utils/vue-testing-library'
3+
import { createRenderTemplate, render } from '../../test-utils/vue-testing-library'
44
import { renderToString } from 'vue/server-renderer'
55
import { Portal, PortalGroup } from './portal'
66
import { click } from '../../test-utils/interactions'
@@ -23,21 +23,7 @@ beforeAll(() => {
2323

2424
afterAll(() => jest.restoreAllMocks())
2525

26-
function renderTemplate(input: string | ComponentOptionsWithoutProps) {
27-
let defaultComponents = { Portal, PortalGroup }
28-
29-
if (typeof input === 'string') {
30-
return render(defineComponent({ template: input, components: defaultComponents }))
31-
}
32-
33-
return render(
34-
defineComponent(
35-
Object.assign({}, input, {
36-
components: { ...defaultComponents, ...input.components },
37-
}) as Parameters<typeof defineComponent>[0]
38-
)
39-
)
40-
}
26+
const renderTemplate = createRenderTemplate({ Portal, PortalGroup })
4127

4228
async function ssrRenderTemplate(input: string | ComponentOptionsWithoutProps) {
4329
let defaultComponents = { Portal, PortalGroup }

packages/@headlessui-vue/src/components/radio-group/radio-group.test.ts

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { defineComponent, nextTick, ref, watch, reactive, ComponentOptionsWithoutProps } from 'vue'
2-
import { render } from '../../test-utils/vue-testing-library'
2+
import { createRenderTemplate, render } from '../../test-utils/vue-testing-library'
33

44
import { RadioGroup, RadioGroupOption, RadioGroupLabel, RadioGroupDescription } from './radio-group'
55

@@ -34,21 +34,12 @@ function nextFrame() {
3434
})
3535
}
3636

37-
function renderTemplate(input: string | ComponentOptionsWithoutProps) {
38-
let defaultComponents = { RadioGroup, RadioGroupOption, RadioGroupLabel, RadioGroupDescription }
39-
40-
if (typeof input === 'string') {
41-
return render(defineComponent({ template: input, components: defaultComponents }))
42-
}
43-
44-
return render(
45-
defineComponent(
46-
Object.assign({}, input, {
47-
components: { ...defaultComponents, ...input.components },
48-
}) as Parameters<typeof defineComponent>[0]
49-
)
50-
)
51-
}
37+
const renderTemplate = createRenderTemplate({
38+
RadioGroup,
39+
RadioGroupOption,
40+
RadioGroupLabel,
41+
RadioGroupDescription,
42+
})
5243

5344
describe('Safe guards', () => {
5445
it.each([['RadioGroupOption', RadioGroupOption]])(

0 commit comments

Comments
 (0)