Files
TheGame/packages/web/lib/hooks/useBoundingRect.ts
vidvidvid ec8182d7da Role Onboarding using Quest Chains (#1150)
* feat: set up quests dashboard

move quest explorer to /quests/general

* feat: prepare containers for path-of-the-engaged and initiation quests

* chore(release): 0.2.0

* feat: add metacollab and web 3 onboarding categories

* feat: move initiation quests from notion -> metaOS

awyiss it's happening

* chore: lint quickfix

* feat: add descriptions, objectives, checkbox, collapse/expand

* add Dockerfile to .gitignore

* go

* quick fix

* upload proof modal

* config and install

* upload proof works

* show status of quests (pending, etc..)

* remove initiation & update engaged quests

* fix quest categories

add bridgebuilders, builders, patrons, fix icons

* typecheck fix

* fix address for bridgebuilders quests

* design of chain progress + small fix

* minor fixes

* using latest version of quest-chains sdk

* basic UI for quests

* using children for react-markdown

* better styling for quest tiles

* completed quest chain styling

* fixed toasts

* fixed imageLink

* added link to quest chains

* minor fixes

* added back to onboarding paths link

* fixed external link icon as absolute pos

* reduce gaps for mobile

Co-authored-by: Vid <vid@meisterlabs.com>
Co-authored-by: dan13ram <dan13ram@gmail.com>
2022-10-08 19:05:42 +01:00

72 lines
1.6 KiB
TypeScript

import { MutableRefObject, useEffect, useRef, useState } from 'react';
const debounce = (
limit: number,
callback: () => void,
): ((e: Event) => void) => {
let timeoutId: number;
return (e: Event) => {
if (timeoutId) {
clearTimeout(timeoutId);
}
timeoutId = setTimeout(callback, limit, e);
};
};
type Dimension = {
width?: number;
height?: number;
top?: number;
left?: number;
x?: number;
y?: number;
right?: number;
bottom?: number;
};
const getDimensionObject = (node: HTMLDivElement | null): Dimension => {
if (!node) return {};
const rect = node.getBoundingClientRect();
return {
width: rect.width,
height: rect.height,
top: rect.top,
left: rect.left,
x: rect.x,
y: rect.y,
right: rect.right,
bottom: rect.bottom,
};
};
export const useBoundingRect = (
limit = 100,
): [MutableRefObject<HTMLDivElement | null>, Dimension] => {
const [dimensions, setDOMRects] = useState<Dimension>({});
const ref = useRef<HTMLDivElement | null>(null);
useEffect(() => {
if (typeof window !== 'undefined' && ref.current) {
const measure = () =>
window.requestAnimationFrame(() =>
setDOMRects(getDimensionObject(ref.current)),
);
measure();
const listener = debounce(limit, measure);
window.addEventListener('resize', listener);
window.addEventListener('scroll', listener);
return () => {
window.removeEventListener('resize', listener);
window.removeEventListener('scroll', listener);
};
}
return () => undefined;
}, [limit]);
return [ref, dimensions];
};