Skip to content

Commit 795ce09

Browse files
committed
feat(render): add wrapper component option
1 parent 0abee6f commit 795ce09

File tree

2 files changed

+46
-19
lines changed

2 files changed

+46
-19
lines changed

src/__tests__/render.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,24 @@ it('supports fragments', () => {
9090
cleanup()
9191
expect(document.body.innerHTML).toBe('')
9292
})
93+
94+
test('renders options.wrapper around node', () => {
95+
const WrapperComponent = ({children}) => (
96+
<div data-testid="wrapper">{children}</div>
97+
)
98+
99+
const {container, getByTestId} = render(<div data-testid="inner" />, {
100+
wrapper: WrapperComponent,
101+
})
102+
103+
expect(getByTestId('wrapper')).toBeInTheDocument()
104+
expect(container.firstChild).toMatchInlineSnapshot(`
105+
<div
106+
data-testid="wrapper"
107+
>
108+
<div
109+
data-testid="inner"
110+
/>
111+
</div>
112+
`)
113+
})

src/index.js

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,13 @@ const mountedContainers = new Set()
1111

1212
function render(
1313
ui,
14-
{container, baseElement = container, queries, hydrate = false} = {},
14+
{
15+
container,
16+
baseElement = container,
17+
queries,
18+
hydrate = false,
19+
wrapper: WrapperComponent,
20+
} = {},
1521
) {
1622
if (!container) {
1723
// default to document.body instead of documentElement to avoid output of potentially-large
@@ -25,13 +31,18 @@ function render(
2531
// they're passing us a custom container or not.
2632
mountedContainers.add(container)
2733

34+
const wrapUiIfNeeded = innerElement =>
35+
WrapperComponent
36+
? React.createElement(WrapperComponent, null, innerElement)
37+
: innerElement
38+
2839
if (hydrate) {
2940
act(() => {
30-
ReactDOM.hydrate(ui, container)
41+
ReactDOM.hydrate(wrapUiIfNeeded(ui), container)
3142
})
3243
} else {
3344
act(() => {
34-
ReactDOM.render(ui, container)
45+
ReactDOM.render(wrapUiIfNeeded(ui), container)
3546
})
3647
}
3748
return {
@@ -41,7 +52,7 @@ function render(
4152
debug: (el = baseElement) => console.log(prettyDOM(el)),
4253
unmount: () => ReactDOM.unmountComponentAtNode(container),
4354
rerender: rerenderUi => {
44-
render(rerenderUi, {container, baseElement})
55+
render(wrapUiIfNeeded(rerenderUi), {container, baseElement})
4556
// Intentionally do not return anything to avoid unnecessarily complicating the API.
4657
// folks can use all the same utilities we return in the first place that are bound to the container
4758
},
@@ -70,25 +81,20 @@ function testHook(callback, options = {}) {
7081
const result = {
7182
current: null,
7283
}
73-
const toRender = () => {
74-
const hookRender = (
75-
<TestHook callback={callback}>
76-
{res => {
77-
result.current = res
78-
}}
79-
</TestHook>
80-
)
81-
if (options.wrapper) {
82-
return React.createElement(options.wrapper, null, hookRender)
83-
}
84-
return hookRender
85-
}
86-
const {unmount, rerender: rerenderComponent} = render(toRender())
84+
const toRender = () => (
85+
<TestHook callback={callback}>
86+
{res => {
87+
result.current = res
88+
}}
89+
</TestHook>
90+
)
91+
92+
const {unmount, rerender: rerenderComponent} = render(toRender(), options)
8793
return {
8894
result,
8995
unmount,
9096
rerender: () => {
91-
rerenderComponent(toRender())
97+
rerenderComponent(toRender(), options)
9298
},
9399
}
94100
}

0 commit comments

Comments
 (0)