Skip to content

Commit

Permalink
fix(drawer): Use useEffect to manage visibility
Browse files Browse the repository at this point in the history
Fix for when drawer is updated externally so
that `isOpen` change fires a component rerender.
  • Loading branch information
thyhjwb6 committed Apr 16, 2020
1 parent 09b2c70 commit efbeff4
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import React from 'react'
// @ts-nocheck
import React, { useState } from 'react'
import { renderToStaticMarkup } from 'react-dom/server'
import '@testing-library/jest-dom/extend-expect'
import { render, RenderResult, fireEvent } from '@testing-library/react'
import {
render,
RenderResult,
fireEvent,
waitFor,
} from '@testing-library/react'

import { Button } from '../Button'
import { Drawer } from '.'

describe('Drawer', () => {
Expand Down Expand Up @@ -70,4 +77,65 @@ describe('Drawer', () => {
})
})
})

describe('when the state is being updated externally', () => {
describe('and the drawer is instantiated as closed', () => {
beforeEach(() => {
const DrawerWithUpdate = () => {
const [isOpen, setIsOpen] = useState(false)

return (
<>
<Button
onClick={() => {
setIsOpen(!isOpen)
}}
>
{isOpen ? 'Hide' : 'Show'}
</Button>
<Drawer isOpen={isOpen} onClose={onCloseSpy}>
{children}
</Drawer>
</>
)
}

wrapper = render(<DrawerWithUpdate />)
})

it('should not contain the `is-open` class', () => {
expect(wrapper.getByTestId('drawer-wrapper').classList).not.toContain(
'is-open'
)
})

describe('and the button is clicked', () => {
beforeEach(() => {
wrapper.getByText('Show').click()

return waitFor(() => wrapper.queryAllByText('Hide'))
})

it('should contain the `is-open` class', () => {
expect(wrapper.getByTestId('drawer-wrapper').classList).toContain(
'is-open'
)
})

describe('and the button is clicked again', () => {
beforeEach(() => {
wrapper.getByText('Hide').click()

return waitFor(() => wrapper.queryAllByText('Show'))
})

it('should not contain the `is-open` class', () => {
expect(
wrapper.getByTestId('drawer-wrapper').classList
).not.toContain('is-open')
})
})
})
})
})
})
21 changes: 7 additions & 14 deletions packages/react-component-library/src/components/Drawer/Drawer.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,30 @@
import React, { useState } from 'react'
import React from 'react'
import classNames from 'classnames'
import { useOpenClose } from '../../hooks/useOpenClose'

interface DrawerProps extends ComponentWithClass {
children?: React.ReactNode
onClose?: (event: React.FormEvent<HTMLButtonElement>) => void
isOpen?: boolean
onClose?: (event: React.FormEvent<HTMLButtonElement>) => void
}

export const Drawer: React.FC<DrawerProps> = ({
children,
onClose,
isOpen = false,
isOpen,
}) => {
const [drawerOpen, setDrawerOpen] = useState(isOpen)
const { handleOnClose, open } = useOpenClose(isOpen, onClose)

const classes = classNames('rn-drawer', {
'is-open': drawerOpen,
'is-open': open,
})

function handleClick(event: React.FormEvent<HTMLButtonElement>) {
setDrawerOpen(false)

if (onClose) {
onClose(event)
}
}

return (
<div className={classes} data-testid="drawer-wrapper">
<div className="rn-drawer__inner">
<button
className="rn-drawer__close"
onClick={handleClick}
onClick={handleOnClose}
data-testid="drawer-close"
>
&times;
Expand Down

0 comments on commit efbeff4

Please sign in to comment.