Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:reach/reach-ui into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
Chance Strickland committed Jun 23, 2020
2 parents a7bb5d1 + 65938b5 commit 98101d4
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 28 deletions.
29 changes: 29 additions & 0 deletions packages/rect/examples/change-observed-ref.example.tsx
@@ -0,0 +1,29 @@
import React from "react";
import { useRect } from "@reach/rect";

let name = "Change the observed ref";

function Example() {
const refLeft = React.useRef<HTMLTextAreaElement>(null);
const refRight = React.useRef<HTMLTextAreaElement>(null);
const [whichRect, setWhichRect] = React.useState(true);
const rect = useRect(whichRect ? refLeft : refRight);
return (
<div>
<pre>
{whichRect ? "left" : "right"}: {JSON.stringify(rect, null, 2)}
</pre>
<button onClick={() => setWhichRect(!whichRect)}>
Toggle Observed Ref
</button>
<div>
<textarea ref={refLeft} defaultValue="resize this" />
<textarea ref={refRight} defaultValue="resize this" />
</div>
</div>
);
}

Example.story = { name };
export const Comp = Example;
export default { title: "Rect" };
2 changes: 1 addition & 1 deletion packages/rect/package.json
Expand Up @@ -13,7 +13,7 @@
"build": "ts-node ../../scripts/build"
},
"dependencies": {
"@reach/observe-rect": "1.1.0",
"@reach/observe-rect": "1.2.0",
"@reach/utils": "0.10.4",
"prop-types": "^15.7.2",
"tslib": "^2.0.0"
Expand Down
59 changes: 36 additions & 23 deletions packages/rect/src/index.tsx
Expand Up @@ -65,7 +65,10 @@ export type RectProps = {
*
* @see Docs https://reacttraining.com/reach-ui/rect#rect-onchange
*/
children(args: { rect: PRect | null; ref: React.Ref<any> }): JSX.Element;
children(args: {
rect: PRect | null;
ref: React.RefObject<any>;
}): JSX.Element;
};

if (__DEV__) {
Expand All @@ -86,48 +89,58 @@ if (__DEV__) {
* @param observe
* @param onChange
*/
export function useRect<T extends HTMLElement = HTMLElement>(
nodeRef: React.RefObject<T>,
export function useRect<T extends Element = HTMLElement>(
nodeRef: React.RefObject<T | undefined | null>,
observe: boolean = true,
onChange?: (rect: DOMRect) => void
): null | DOMRect {
let [element, setElement] = useState(nodeRef.current);
let initialRectSet = useRef(false);
let [rect, setRect] = useState<DOMRect | null>(null);
let observerRef = useRef<any>(null);
let onChangeRef = useRef<typeof onChange>();

useIsomorphicLayoutEffect(() => {
const cleanup = () => {
observerRef.current && observerRef.current.unobserve();
};
onChangeRef.current = onChange;
});

if (!nodeRef.current) {
console.warn("You need to place the ref");
return cleanup;
useIsomorphicLayoutEffect(() => {
if (nodeRef.current !== element) {
setElement(nodeRef.current);
}
});

if (!observerRef.current) {
observerRef.current = observeRect(nodeRef.current, (rect: DOMRect) => {
onChange && onChange(rect);
setRect(rect);
});
useIsomorphicLayoutEffect(() => {
if (element && !initialRectSet.current) {
initialRectSet.current = true;
setRect(element.getBoundingClientRect());
}
}, [element]);

if (!initialRectSet.current) {
initialRectSet.current = true;
setRect(nodeRef.current.getBoundingClientRect());
useIsomorphicLayoutEffect(() => {
let observer: ReturnType<typeof observeRect>;
if (!element) {
console.warn("You need to place the ref");
return cleanup;
}

observe && observerRef.current.observe();
observer = observeRect(element, (rect) => {
onChangeRef.current && onChangeRef.current(rect);
setRect(rect);
});

observe && observer.observe();
return cleanup;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [observe, onChange]);

function cleanup() {
observer && observer.unobserve();
}
}, [observe, element]);

return rect;
}

export default Rect;

export type PartialRect = Partial<PRect>;

export type PRect = Partial<DOMRect> & {
readonly bottom: number;
readonly height: number;
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Expand Up @@ -3112,10 +3112,10 @@
dependencies:
"@types/node" ">= 8"

"@reach/observe-rect@1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@reach/observe-rect/-/observe-rect-1.1.0.tgz#4e967a93852b6004c3895d9ed8d4e5b41895afde"
integrity sha512-kE+jvoj/OyJV24C03VvLt5zclb9ArJi04wWXMMFwQvdZjdHoBlN4g0ZQFjyy/ejPF1Z/dpUD5dhRdBiUmIGZTA==
"@reach/observe-rect@1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@reach/observe-rect/-/observe-rect-1.2.0.tgz#d7a6013b8aafcc64c778a0ccb83355a11204d3b2"
integrity sha512-Ba7HmkFgfQxZqqaeIWWkNK0rEhpxVQHIoVyW1YDSkGsGIXzcaW4deC8B0pZrNSSyLTdIk7y+5olKt5+g0GmFIQ==

"@reach/router@^1.2.1", "@reach/router@^1.3.3":
version "1.3.3"
Expand Down

0 comments on commit 98101d4

Please sign in to comment.