Skip to content

Commit 7b72057

Browse files
committed
Add useOutsideClick hook and documentation
1 parent 6339580 commit 7b72057

File tree

5 files changed

+87
-0
lines changed

5 files changed

+87
-0
lines changed

src/hooks/styles.stories.css

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
.dropdown-wrapper {
2+
align-items: center;
3+
border: 1px solid var(--structure-color-600);
4+
border-radius: 4px;
5+
display: flex;
6+
flex-direction: column;
7+
height: 500px;
8+
justify-content: center;
9+
width: 500px;
10+
11+
--dropdown-width: 250px;
12+
}

src/hooks/useOutsideClick/index.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { useEffect, RefObject } from 'react';
2+
3+
export const useOutsideClick = (callback: () => void, ref: RefObject<HTMLDivElement>) => {
4+
const handleClick = (e: Event) => {
5+
if (ref.current && !ref.current.contains(<HTMLElement>e.target)) {
6+
callback();
7+
}
8+
};
9+
10+
useEffect(() => {
11+
document.addEventListener("click", handleClick);
12+
13+
return () => {
14+
document.removeEventListener("click", handleClick);
15+
};
16+
});
17+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
hello there
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import React, { useState, useRef } from 'react';
2+
import Dropdown from '@/components/Dropdown';
3+
import { useOutsideClick } from '@/hooks/useOutsideClick';
4+
import { Meta } from '@storybook/react';
5+
import styles from '../styles.stories.css';
6+
import mdx from './useOutsideClick.stories.mdx';
7+
8+
const Demo = () => {
9+
const [selectedItem, setSelectedItem] = useState({});
10+
const ref = useRef(null);
11+
12+
useOutsideClick(() => alert('You clicked outside the dropdown'), ref);
13+
14+
const options = [
15+
{
16+
label: 'Option 1',
17+
value: '1'
18+
},
19+
{
20+
label: 'Option 2',
21+
value: '2'
22+
}
23+
];
24+
25+
return (
26+
<div className={styles['dropdown-wrapper']}>
27+
<h4>Click outside of the Dropdown</h4>
28+
<div ref={ref}>
29+
<Dropdown
30+
onChange={setSelectedItem}
31+
options={options}
32+
getItemLabel={item => item.label}
33+
getItemKey={item => item.value}
34+
getItemValue={item => item.value}
35+
getListTitle={item => item.label}
36+
selected={selectedItem}
37+
selectorText="Select"
38+
/>
39+
</div>
40+
</div>
41+
);
42+
};
43+
44+
export default {
45+
title: 'Hooks/useOutsideClick',
46+
component: Demo,
47+
parameters: {
48+
docs: {
49+
page: mdx
50+
},
51+
},
52+
} as Meta;
53+
54+
const Template = () => <Demo />;
55+
export const Default = Template.bind({});

src/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,5 @@ export { default as Toggle } from '@/components/Toggle';
2929
export { default as Tooltip } from '@/components/Tooltip';
3030
export { default as UploadAvatar } from '@/components/UploadAvatar';
3131
export * from '@/components/Grid';
32+
33+
export { useOutsideClick } from '@/hooks/useOutsideClick';

0 commit comments

Comments
 (0)