Initial commit for project Spoon!
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
export { useIsMobile } from './use-mobile';
|
||||
export { useOnClickOutside } from './use-on-click-outside';
|
||||
@@ -0,0 +1,21 @@
|
||||
import * as React from 'react';
|
||||
|
||||
const MOBILE_BREAKPOINT = 768;
|
||||
|
||||
export const useIsMobile = () => {
|
||||
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(
|
||||
undefined,
|
||||
);
|
||||
|
||||
React.useEffect(() => {
|
||||
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
||||
const onChange = () => {
|
||||
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
||||
};
|
||||
mql.addEventListener('change', onChange);
|
||||
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
||||
return () => mql.removeEventListener('change', onChange);
|
||||
}, []);
|
||||
|
||||
return !!isMobile;
|
||||
};
|
||||
@@ -0,0 +1,59 @@
|
||||
import * as React from 'react';
|
||||
|
||||
type EventType =
|
||||
| 'mousedown'
|
||||
| 'mouseup'
|
||||
| 'touchstart'
|
||||
| 'touchend'
|
||||
| 'focusin'
|
||||
| 'focusout';
|
||||
|
||||
export const useOnClickOutside = <T extends Element>(
|
||||
ref: React.RefObject<T | null> | React.RefObject<T | null>[],
|
||||
handler: (event: MouseEvent | TouchEvent | FocusEvent) => void,
|
||||
eventType: EventType = 'mousedown',
|
||||
eventListenerOptions: AddEventListenerOptions = {},
|
||||
): void => {
|
||||
const savedHandler = React.useRef(handler);
|
||||
|
||||
React.useLayoutEffect(() => {
|
||||
savedHandler.current = handler;
|
||||
}, [handler]);
|
||||
|
||||
React.useEffect(() => {
|
||||
const listener = (event: MouseEvent | TouchEvent | FocusEvent) => {
|
||||
const target = event.target as Node;
|
||||
|
||||
// Do nothing if the target is not connected element with document
|
||||
if (!target.isConnected) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isOutside = Array.isArray(ref)
|
||||
? ref
|
||||
.filter((r) => Boolean(r.current))
|
||||
.every((r) => r.current && !r.current.contains(target))
|
||||
: ref.current && !ref.current.contains(target);
|
||||
|
||||
if (isOutside) {
|
||||
savedHandler.current(event);
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener(
|
||||
eventType,
|
||||
listener as EventListener,
|
||||
eventListenerOptions,
|
||||
);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener(
|
||||
eventType,
|
||||
listener as EventListener,
|
||||
eventListenerOptions,
|
||||
);
|
||||
};
|
||||
}, [ref, eventType, eventListenerOptions]);
|
||||
};
|
||||
|
||||
export type { EventType };
|
||||
Reference in New Issue
Block a user