@loadsmart/loadsmart-ui 5.14.3 → 5.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Drawer/Drawer.d.ts +3 -2
- package/dist/components/Drawer/Drawer.stories.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Drawer/Drawer.stories.tsx +3 -3
- package/src/components/Drawer/Drawer.test.tsx +24 -2
- package/src/components/Drawer/Drawer.tsx +29 -5
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import type {
|
|
2
|
+
import type { Meta, Story } from '@storybook/react/types-6-0'
|
|
3
3
|
|
|
4
4
|
import { Drawer, useDrawer } from '.'
|
|
5
5
|
import type { DrawerProps } from './Drawer'
|
|
@@ -31,7 +31,7 @@ export const Playground: Story<DrawerProps> = ({ open, ...others }: DrawerProps)
|
|
|
31
31
|
<div className="flex flex-col space-y-2">
|
|
32
32
|
<div className="flex items-center">
|
|
33
33
|
<Button onClick={show}>Open Drawer</Button>
|
|
34
|
-
<Drawer {...others} open={isOpen} onClose={hide}>
|
|
34
|
+
<Drawer {...others} open={isOpen} onClose={hide} onClickOutside={hide}>
|
|
35
35
|
<Drawer.Header>Drawer Header</Drawer.Header>
|
|
36
36
|
<Drawer.Body>
|
|
37
37
|
{TWENTY_SIZE_ARR.map((_, index) => (
|
|
@@ -60,7 +60,7 @@ export const SmallerContentPlayground: Story<DrawerProps> = ({ open, ...others }
|
|
|
60
60
|
<div className="flex flex-col space-y-2">
|
|
61
61
|
<div className="flex items-center">
|
|
62
62
|
<Button onClick={show}>Open Drawer</Button>
|
|
63
|
-
<Drawer {...others} open={isOpen} onClose={hide}>
|
|
63
|
+
<Drawer {...others} open={isOpen} onClose={hide} onClickOutside={hide}>
|
|
64
64
|
<Drawer.Header>Drawer Header</Drawer.Header>
|
|
65
65
|
<Drawer.Body>
|
|
66
66
|
{TWENTY_SIZE_ARR.slice(0, 3).map((_, index) => (
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import renderer, {
|
|
2
|
+
import renderer, { fire, screen } from '../../tests/renderer'
|
|
3
3
|
|
|
4
|
-
import Drawer from './Drawer'
|
|
5
4
|
import type { DrawerProps } from './Drawer'
|
|
5
|
+
import Drawer from './Drawer'
|
|
6
|
+
import { fireEvent, waitFor } from '@testing-library/react'
|
|
6
7
|
|
|
7
8
|
const setup = (props: DrawerProps) => renderer(<Drawer {...props} />).render()
|
|
8
9
|
|
|
@@ -28,6 +29,27 @@ describe('Drawer', () => {
|
|
|
28
29
|
expect(props.onClose).toHaveBeenCalled()
|
|
29
30
|
})
|
|
30
31
|
|
|
32
|
+
it('closes drawer only when clicking outside', async () => {
|
|
33
|
+
const props = {
|
|
34
|
+
open: true,
|
|
35
|
+
onClickOutside: jest.fn(),
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
setup(props)
|
|
39
|
+
|
|
40
|
+
fireEvent.mouseUp(screen.getByRole('dialog'))
|
|
41
|
+
|
|
42
|
+
await waitFor(() => {
|
|
43
|
+
expect(props.onClickOutside).not.toHaveBeenCalled()
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
fireEvent.mouseUp(screen.getByRole('complementary'))
|
|
47
|
+
|
|
48
|
+
await waitFor(() => {
|
|
49
|
+
expect(props.onClickOutside).toHaveBeenCalledTimes(1)
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
|
|
31
53
|
it('renders without close button', () => {
|
|
32
54
|
setup({
|
|
33
55
|
open: true,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { PropsWithChildren } from 'react'
|
|
2
|
+
import React, { ReactNode, useEffect, useRef, useState } from 'react'
|
|
2
3
|
import ReactDOM from 'react-dom'
|
|
3
4
|
import styled from 'styled-components'
|
|
4
5
|
|
|
@@ -7,13 +8,12 @@ import conditional, { whenProps } from 'tools/conditional'
|
|
|
7
8
|
import { getToken as token } from 'theming'
|
|
8
9
|
import DefaultCloseButton from 'common/CloseButton'
|
|
9
10
|
|
|
10
|
-
import type { PropsWithChildren } from 'react'
|
|
11
|
-
|
|
12
11
|
export interface DrawerProps {
|
|
13
12
|
children?: ReactNode
|
|
14
13
|
className?: string
|
|
15
14
|
open: boolean
|
|
16
15
|
onClose?: () => void
|
|
16
|
+
onClickOutside?: () => void
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
const StyledAside = styled.aside<Pick<DrawerProps, 'open'>>`
|
|
@@ -160,8 +160,16 @@ function DrawerFooter({
|
|
|
160
160
|
)
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
function Drawer({
|
|
163
|
+
function Drawer({
|
|
164
|
+
className,
|
|
165
|
+
children,
|
|
166
|
+
open,
|
|
167
|
+
onClose,
|
|
168
|
+
onClickOutside,
|
|
169
|
+
...others
|
|
170
|
+
}: DrawerProps): JSX.Element {
|
|
164
171
|
const [invisible, setInvisible] = useState(!open)
|
|
172
|
+
const ref = useRef<HTMLElement>(null)
|
|
165
173
|
|
|
166
174
|
function handleTransitionEnd() {
|
|
167
175
|
if (!open) {
|
|
@@ -175,8 +183,24 @@ function Drawer({ className, children, open, onClose, ...others }: DrawerProps):
|
|
|
175
183
|
}
|
|
176
184
|
}, [open])
|
|
177
185
|
|
|
186
|
+
useEffect(() => {
|
|
187
|
+
const currentRef = ref.current
|
|
188
|
+
|
|
189
|
+
if (currentRef && onClickOutside) {
|
|
190
|
+
const handleClick = (event: MouseEvent) => {
|
|
191
|
+
const hasClickedOutside = currentRef.isSameNode(event.target as Element)
|
|
192
|
+
|
|
193
|
+
if (hasClickedOutside) onClickOutside()
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
currentRef.addEventListener('mouseup', handleClick)
|
|
197
|
+
|
|
198
|
+
return () => currentRef.removeEventListener('mouseup', handleClick)
|
|
199
|
+
}
|
|
200
|
+
}, [onClickOutside])
|
|
201
|
+
|
|
178
202
|
return ReactDOM.createPortal(
|
|
179
|
-
<StyledAside open={!invisible}>
|
|
203
|
+
<StyledAside open={!invisible} ref={ref}>
|
|
180
204
|
<StyledSection
|
|
181
205
|
{...others}
|
|
182
206
|
className={className}
|