react#RefObject TypeScript Examples

The following examples show how to use react#RefObject. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utils.tsx    From OpenBA-NextGenTV with MIT License 7 votes vote down vote up
textScrollUp = (textContainer: RefObject<HTMLDivElement>) => {
  let currentScroll = textContainer.current?.scrollTop || 0;

  const scrollElementTo = () => {
    textContainer.current?.scrollTo({
      top: currentScroll,
      behavior: 'smooth',
    });
  };

  currentScroll = currentScroll >= 100 ? (currentScroll -= 100) : 0;
  scrollElementTo();
}
Example #2
Source File: index.ts    From anchor-web-app with Apache License 2.0 6 votes vote down vote up
export function useStateRef<T>(value: T): RefObject<T> {
  const ref: MutableRefObject<T> = useRef<T>(value);

  useEffect(() => {
    ref.current = value;
  }, [value]);

  return ref;
}
Example #3
Source File: TemplateName.tsx    From react-tutorials with MIT License 6 votes vote down vote up
TemplateName = () /* or ( props : ITemplateNameProps ) */ => {
  const [myState, setMyState] = useState<Boolean>(true)
  const ref: RefObject<HTMLDivElement> = React.createRef()

  useEffect(() => {
    draw()
  })

  const draw = () => {
    d3.select(ref.current).append('p').text('Hello World')
    d3.select('svg')
      .append('g')
      .attr('transform', 'translate(250, 0)')
      .append('rect').attr('width', 500)
      .attr('height', 500)
      .attr('fill', 'tomato')
  }

  return (
    <div className="TemplateName" ref={ref}>
      <svg width="500" height="500">
        <g transform="translate(0, 0)">
          <rect width="500" height="500" fill="green" />
        </g>
      </svg>
    </div>
  )
}
Example #4
Source File: useGetBoundingClientRect.ts    From react-datasheet-grid with MIT License 6 votes vote down vote up
useGetBoundingClientRect = (
  ref: RefObject<HTMLElement>,
  delay = 200
) => {
  const boundingRect = useRef<DOMRect | null>(null)

  const throttledCompute = useMemo(
    () =>
      throttle(delay, true, () => {
        setTimeout(
          () =>
            (boundingRect.current =
              ref.current?.getBoundingClientRect() || null),
          0
        )
      }),
    [ref, delay]
  )

  return useCallback(
    (force = false) => {
      if (force) {
        boundingRect.current = ref.current?.getBoundingClientRect() || null
      } else {
        throttledCompute()
      }
      return boundingRect.current
    },
    [ref, throttledCompute]
  )
}
Example #5
Source File: useEventListener.test.tsx    From frontend with GNU General Public License v3.0 6 votes vote down vote up
describe('useEventListener hook', () => {
  test('should bind event listener and call with event on window object', () => {
    const eventListener = jest.fn<void, [MouseEvent]>();
    renderHook(() => {
      useEventListener('click', eventListener);
    });

    fireEvent.click(window);
    expect(eventListener).toHaveBeenCalledTimes(1);
    expect(eventListener).toHaveBeenCalledWith(expect.any(Event));
  });

  test('should unbind event listener', () => {
    const targetElement = document.body;
    const eventListener = jest.fn<void, [MouseEvent]>();
    const { result } = renderHook(() => useRef(targetElement));
    const { unmount } = renderHook(() => {
      useEventListener('click', eventListener, result.current);
    });

    fireEvent.click(targetElement);
    expect(eventListener).toHaveBeenCalledTimes(1);

    unmount();

    fireEvent.click(targetElement);
    expect(eventListener).toHaveBeenCalledTimes(1);
  });

  test('should not call handler function when addEventListener is not support', () => {
    const targetElement = { current: {} } as RefObject<HTMLElement>;
    const eventListener = jest.fn<void, [MouseEvent]>();

    renderHook(() => {
      useEventListener('click', eventListener, targetElement);
    });
    expect(eventListener).toHaveBeenCalledTimes(0);
  });
});
Example #6
Source File: useRefEffect.ts    From MLH-Fellow-Map with MIT License 6 votes vote down vote up
function useRefEffect<T = unknown>({
  effect,
  ref,
}: {
  effect: (val: T | null) => void;
  ref: RefObject<T>;
}) {
  useEffect(() => {
    effect(ref.current);
  }, [effect, ref]);
}
Example #7
Source File: useClickOutside.ts    From sybil-interface with GNU General Public License v3.0 6 votes vote down vote up
function useOnClickOutside<T extends HTMLElement = HTMLElement>(ref: RefObject<T>, handler: (event: Event) => void) {
  useEffect(() => {
    const listener = (event: Event) => {
      const el = ref?.current
      // Do nothing if clicking ref's element or descendent elements
      if (!el || el.contains((event?.target as Node) || null)) {
        return
      }
      handler(event)
    }
    document.addEventListener(`mousedown`, listener)
    document.addEventListener(`touchstart`, listener)
    return () => {
      document.removeEventListener(`mousedown`, listener)
      document.removeEventListener(`touchstart`, listener)
    }
    // Reload only if ref or handler changes
  }, [ref, handler])
}
Example #8
Source File: DateDropdown.tsx    From ant-extensions with MIT License 6 votes vote down vote up
DateDropdown: React.FC<
  {
    dropdown: RefObject<Popover>;
  } & BaseProps
> = React.memo(({ dropdown: { current: popup }, ...props }) => {
  const { t } = useTranslation(I18nKey);

  const activeTab = useMemo<Type>(() => superDateType(props.value), [props.value]);

  return (
    <Tabs
      destroyInactiveTabPane
      defaultActiveKey={activeTab}
      animated={{ tabPane: false, inkBar: true }}
      onChange={() => {
        popup && popup.forceUpdate();
      }}
    >
      <Tabs.TabPane key={Type.QUICK} tab={t("label.quick")} data-testid="tab-quick">
        <DatePresets {...props} />
      </Tabs.TabPane>
      <Tabs.TabPane key={Type.ABSOLUTE} tab={t("label.absolute")} data-testid="tab-absolute">
        <DatePicker {...props} />
      </Tabs.TabPane>
    </Tabs>
  );
})
Example #9
Source File: hookUtils.ts    From airmessage-web with Apache License 2.0 6 votes vote down vote up
/**
 * Binds the mounted state of the current function component to a reference to a boolean
 */
export function useIsUnmounted(): RefObject<boolean> {
	const isUnmounted = useRef(false);
	useEffect(() => {
		return () => {
			isUnmounted.current = true;
		};
	}, []);
	return isUnmounted;
}
Example #10
Source File: useOutsideClick.ts    From hub with Apache License 2.0 6 votes vote down vote up
export default function useOutsideClick(
  refs: RefObject<HTMLElement>[],
  enabled: boolean,
  onClickOutside: (e: MouseEvent) => void
): [boolean] {
  const [isActive, setActive] = useState(false);

  const isOutside = useCallback(
    (e: MouseEvent) => {
      const test = refs.map((ref) => {
        if (isNull(ref.current)) return true;
        return !ref.current.contains(e.target as HTMLElement);
      });

      return test.every(Boolean);
    },
    [refs]
  );

  const onEvent = useCallback(
    (e: MouseEvent) => {
      if (isOutside(e) && enabled) {
        setActive(true);
        onClickOutside(e);
      }
    },
    [isOutside, onClickOutside, enabled]
  );

  useEffect(() => {
    document.addEventListener('mousedown', onEvent);

    return () => {
      document.removeEventListener('mousedown', onEvent);
    };
  }, [refs, onClickOutside, onEvent]);

  return [isActive];
}
Example #11
Source File: useClickOutside.ts    From checklist with MIT License 6 votes vote down vote up
useClickOutside = (ref: RefObject<any>, handler: () => void) => {
  const events = ['mousedown', 'touchstart'];

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const detectClickOutside = (event: any) => !ref?.current?.contains(event.target) && handler();

  useEffect(() => {
    events.forEach(e => {
      document.addEventListener(e, detectClickOutside);
    });

    return () => {
      events.forEach(e => {
        document.removeEventListener(e, detectClickOutside);
      });
    };
  });
}
Example #12
Source File: useDynamicFontSize.tsx    From amazon-chime-live-events with Apache License 2.0 6 votes vote down vote up
useDynamicFontSize = (ref: RefObject<HTMLElement>) => {
  const [fontSize, setFontSize] = useState<string>();

  useLayoutEffect(() => {
    if (!ref.current) {
      return;
    }

    const { width } = ref.current.getBoundingClientRect();
    setFontSize(getNamePlateFontSize(width));
  }, []);

  useEffect(() => {
    const el = ref.current;

    if (!el) {
      return;
    }

    const handleResize = debounce(50, (entries: any) => {
      const { width } = entries[0].contentRect;
      setFontSize(getNamePlateFontSize(width));
    });

    const resizeObserver = new ResizeObserver(handleResize);
    resizeObserver.observe(el);

    return () => resizeObserver.unobserve(el);
  }, []);

  return fontSize;
}
Example #13
Source File: useClickOutside.tsx    From amazon-chime-sdk-smart-video-sending-demo with Apache License 2.0 6 votes vote down vote up
export function useClickOutside(ref: RefObject<HTMLElement>, onClickOutside: (e: MouseEvent | TouchEvent) => void) {

  const isOutside = (e: MouseEvent | TouchEvent) => {
    return !!ref.current && !ref.current.contains(e.target as HTMLElement);
  }

  const onMouseDown = (e: MouseEvent | TouchEvent) => {
    if (isOutside(e)) {
      onClickOutside(e);
    }
  };

  useEffect(
    () => {
      document.addEventListener('mousedown', onMouseDown);
      document.addEventListener('touchstart', onMouseDown);

      return () => {
        document.removeEventListener('mousedown', onMouseDown);
        document.removeEventListener('touchstart', onMouseDown);
      };
    }
  ), [onClickOutside];
}
Example #14
Source File: Field.hook.ts    From ke with MIT License 6 votes vote down vote up
export function useField(
  leafHook: (key: FieldKey) => [FieldData, (updater: Updater<FieldData>) => void],
  key: FieldKey,
  controlRef?: RefObject<ControlRefProps>
): UseFieldResult {
  const [{ value, isTouched }, updateLeaf] = leafHook(key)

  useEffect(() => {
    updateLeaf((prev) => mergeField(prev, { relatedRef: controlRef || null }))
  }, [controlRef, updateLeaf])

  const onChange = useCallback(
    (val) => {
      updateLeaf((prev) =>
        mergeField(prev, {
          value: val,
          isTouched: true,
        })
      )
    },
    [updateLeaf]
  )

  return {
    value,
    onChange,
    isTouched,
  }
}
Example #15
Source File: useCreateAnimation.ts    From fe-foundation with Apache License 2.0 6 votes vote down vote up
export function useCreateAnimation<T>(
    elem: RefObject<HTMLElement> | HTMLElement | null,
    options: IAnimationOptions<T>
): Animation<T> {
    const animation = useSingleton(() => new Animation<T>());
    const {onReady, onStart, onEnd, validTarget, ...extra} = options;

    const elemGetter = useContainer(elem);

    const onReadyCallback = useRefCallback(onReady);
    const onStartCallback = useRefCallback(onStart);
    const onEndCallback = useRefCallback(onEnd);

    useEffect(() => {
        animation.setEle(elemGetter());
        animation.updateOptions({...extra, validTarget: validTarget?.current});
    });

    useEffect(() => {
        animation.addListener('animate-ready', onReadyCallback);
        animation.addListener('animate-start', onStartCallback);
        animation.addListener('animate-end', onEndCallback);

        return () => {
            animation.removeListener('animate-ready', onReadyCallback);
            animation.removeListener('animate-start', onStartCallback);
            animation.removeListener('animate-end', onEndCallback);
        };
    }, []);

    return animation;
}
Example #16
Source File: animateUtil.ts    From clearflask with Apache License 2.0 6 votes vote down vote up
export function animateWrapper<StateUpdate>(
  isMountedGetter: () => boolean,
  inViewObserverRef: RefObject<InViewObserver>,
  settingsGetter: () => StateSettings,
  setState: (state: StateUpdate, callback: () => void) => void,
): ((opts?: {
  sleepInMs?: number;
  setState?: StateUpdate;
}) => Promise<boolean>) {
  return async opts => {
    if (opts?.sleepInMs && opts.sleepInMs > 0) await new Promise<void>(resolve => setTimeout(resolve, opts.sleepInMs));
    await inViewObserverRef.current?.get();
    if (!isPageVisible()) await waitUntilPageVisible();
    if (!isMountedGetter()) return true;
    if (!!settingsGetter().demoUserIsInteracting) return true;
    const newState = opts?.setState;
    try {
      if (newState !== undefined) await new Promise<void>(resolve => {
        setState(newState, resolve)
      });
    } catch (er) {
      console.log(er, opts);
      return true;
    }
    if (!isMountedGetter()) return true;
    return false;
  };
}
Example #17
Source File: Stream.tsx    From stream-react with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
/**
 * Hook for syncing properties to the SDK api when they change
 */
function useProperty<T, Key extends keyof T>(
  name: Key,
  ref: RefObject<T | undefined>,
  value: T[Key]
) {
  useEffect(() => {
    if (!ref.current) return;
    const el = ref.current;
    el[name] = value;
  }, [name, value, ref]);
}
Example #18
Source File: TableContent.tsx    From datajoint-labbook with MIT License 6 votes vote down vote up
/**
   * Helper function to construct the ReactRef arrays for the number of tuples shown per page
   * @returns an Array of RefObject for each of the entry in the table on the current page
   */
  constructTupleReferenceArray() {
    let tuplesReference: Array<RefObject<HTMLTableRowElement>> = [];
    for (let i = 0; i < this.props.tuplePerPage; i++) {
      tuplesReference.push(React.createRef());
    }

    return tuplesReference;
  }
Example #19
Source File: useFocus.ts    From baleen3 with Apache License 2.0 6 votes vote down vote up
export function useFocus<T extends HTMLElement>(ref: RefObject<T>): [boolean] {
  const [value, setValue] = useState(false)

  const handleOnFocus = (): void => {
    setValue(true)
  }

  const handleOnBlur = (): void => {
    setValue(false)
  }

  useEffect(
    () => {
      const node = ref.current
      if (node !== null) {
        node.addEventListener('focus', handleOnFocus, true)
        node.addEventListener('blur', handleOnBlur, true)

        return (): void => {
          node.removeEventListener('focus', handleOnFocus, true)
          node.removeEventListener('blur', handleOnBlur, true)
        }
      }
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [ref.current] // Recall only if ref changes
  )

  return [value]
}
Example #20
Source File: canvasUtils.ts    From excalideck with MIT License 6 votes vote down vote up
export function renderCanvas(
    containerRef: RefObject<HTMLDivElement>,
    canvas: HTMLCanvasElement
) {
    if (containerRef.current !== null) {
        const clone = cloneCanvas(canvas);
        if (containerRef.current.firstChild) {
            containerRef.current.firstChild.replaceWith(clone);
        } else {
            containerRef.current.appendChild(clone);
        }
    }
}
Example #21
Source File: LibraryMenu.tsx    From excalidraw with MIT License 6 votes vote down vote up
useOnClickOutside = (
  ref: RefObject<HTMLElement>,
  cb: (event: MouseEvent) => void,
) => {
  useEffect(() => {
    const listener = (event: MouseEvent) => {
      if (!ref.current) {
        return;
      }

      if (
        event.target instanceof Element &&
        (ref.current.contains(event.target) ||
          !document.body.contains(event.target))
      ) {
        return;
      }

      cb(event);
    };
    document.addEventListener("pointerdown", listener, false);

    return () => {
      document.removeEventListener("pointerdown", listener);
    };
  }, [ref, cb]);
}
Example #22
Source File: LayerUI.tsx    From excalidraw-embed with MIT License 6 votes vote down vote up
function useOnClickOutside(
  ref: RefObject<HTMLElement>,
  cb: (event: MouseEvent) => void,
) {
  useEffect(() => {
    const listener = (event: MouseEvent) => {
      if (!ref.current) {
        return;
      }

      if (
        event.target instanceof Element &&
        (ref.current.contains(event.target) ||
          !document.body.contains(event.target))
      ) {
        return;
      }

      cb(event);
    };
    document.addEventListener("pointerdown", listener, false);

    return () => {
      document.removeEventListener("pointerdown", listener);
    };
  }, [ref, cb]);
}
Example #23
Source File: useOnClickOutside.tsx    From limit-orders-lib with GNU General Public License v3.0 6 votes vote down vote up
export function useOnClickOutside<T extends HTMLElement>(
  node: RefObject<T | undefined>,
  handler: undefined | (() => void)
) {
  const handlerRef = useRef<undefined | (() => void)>(handler);
  useEffect(() => {
    handlerRef.current = handler;
  }, [handler]);

  useEffect(() => {
    const handleClickOutside = (e: MouseEvent) => {
      if (node.current?.contains(e.target as Node) ?? false) {
        return;
      }
      if (handlerRef.current) handlerRef.current();
    };

    document.addEventListener("mousedown", handleClickOutside);

    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
    };
  }, [node]);
}
Example #24
Source File: useOnClickOutside.tsx    From goose-frontend-amm with GNU General Public License v3.0 6 votes vote down vote up
export function useOnClickOutside<T extends HTMLElement>(
  node: RefObject<T | undefined>,
  handler: undefined | (() => void)
) {
  const handlerRef = useRef<undefined | (() => void)>(handler)
  useEffect(() => {
    handlerRef.current = handler
  }, [handler])

  useEffect(() => {
    const handleClickOutside = (e: MouseEvent) => {
      if (node.current?.contains(e.target as Node) ?? false) {
        return
      }
      if (handlerRef.current) handlerRef.current()
    }

    document.addEventListener('mousedown', handleClickOutside)

    return () => {
      document.removeEventListener('mousedown', handleClickOutside)
    }
  }, [node])
}
Example #25
Source File: useStickyState.ts    From design-systems-cli with MIT License 6 votes vote down vote up
useStickyState = <T extends HTMLElement>(
  element: RefObject<T | null>
) => {
  const [isSticky, setIsSticky] = useState(false);

  useEffect(() => {
    const { current: stickyTarget } = element;

    if (!stickyTarget || !window) {
      return;
    }

    const parentElement = getScrollParent(stickyTarget);

    if (!parentElement) {
      return;
    }

    const calculateIsSticky = debounce(() => {
      const pTop = parentElement.scrollTop;
      const tTop = stickyTarget.getBoundingClientRect().top;
      const difference = Math.round(Math.abs(pTop - tTop));
      const triggerDistance = window
        .getComputedStyle(stickyTarget)
        .getPropertyValue("top");

      setIsSticky(difference !== Math.abs(parseInt(triggerDistance, 10)));
    }, 25);

    calculateIsSticky();

    parentElement.addEventListener("scroll", calculateIsSticky);

    return () => parentElement.removeEventListener("scroll", calculateIsSticky);
  }, [element]);

  return isSticky;
}
Example #26
Source File: GridList.tsx    From react-gridlist with MIT License 6 votes vote down vote up
function useElementSize(ref: RefObject<Element>): ElementSize | null {
	let [elementSize, setElementSize] = useState(() => {
		if (ref.current) {
			return getElementSize(ref.current)
		} else {
			return null
		}
	})

	let elementSizeRef = useConstRef(elementSize)

	useEffect(() => {
		let observer = new ResizeObserver((entries) => {
			let nextElementSize = getElementSize(entries[0].target)
			if (
				elementSizeRef.current === null ||
				!isSameElementSize(elementSizeRef.current, nextElementSize)
			) {
				setElementSize(nextElementSize)
			}
		})
		if (ref.current) observer.observe(ref.current)
		return () => observer.disconnect()
	}, [ref])

	return elementSize
}
Example #27
Source File: useEventListener.ts    From usehooks-ts with MIT License 6 votes vote down vote up
function useEventListener<
  KW extends keyof WindowEventMap,
  KH extends keyof HTMLElementEventMap,
  T extends HTMLElement | void = void,
>(
  eventName: KW | KH,
  handler: (
    event: WindowEventMap[KW] | HTMLElementEventMap[KH] | Event,
  ) => void,
  element?: RefObject<T>,
) {
  // Create a ref that stores handler
  const savedHandler = useRef(handler)

  useIsomorphicLayoutEffect(() => {
    savedHandler.current = handler
  }, [handler])

  useEffect(() => {
    // Define the listening target
    const targetElement: T | Window = element?.current || window
    if (!(targetElement && targetElement.addEventListener)) {
      return
    }

    // Create event listener that calls handler function stored in ref
    const eventListener: typeof handler = event => savedHandler.current(event)

    targetElement.addEventListener(eventName, eventListener)

    // Remove event listener on cleanup
    return () => {
      targetElement.removeEventListener(eventName, eventListener)
    }
  }, [eventName, element])
}
Example #28
Source File: useOutsideClick.ts    From core with GNU Affero General Public License v3.0 6 votes vote down vote up
useOutsideClick = (ref: RefObject<HTMLElement>, callback: () => void) => {
	const handleClick = e => {
		if (ref.current && !ref.current.contains(e.target)) {
			callback()
		}
	}

	useEffect(() => {
		document.addEventListener('click', handleClick)

		return () => {
			document.removeEventListener('click', handleClick)
		}
	})
}
Example #29
Source File: useInViewScroll.ts    From framer-motion-hooks with MIT License 6 votes vote down vote up
useInViewScroll = (
  el: RefObject<HTMLElement>,
  options: IOptions = {}
): MotionValue<number> => {
  const progress = useMotionValue(0)
  const { scrollY } = useViewportScroll()

  useEffect(() => {
    const handleScrollProgress = () => {
      const node = el.current
      if (!node) return

      const threshold = options.threshold || 0

      const elPosY = node.getBoundingClientRect().top + scrollY.get()
      const elHeight = node.scrollHeight

      const viewIntersect = Math.max(elPosY - window.innerHeight, 0)
      const current = scrollY.get() - viewIntersect - threshold
      const total = Math.min(window.innerHeight, elPosY) + elHeight - threshold

      const quotient = current / total

      if (quotient > 0 && quotient < 1) {
        progress.set(quotient)
      }
    }

    handleScrollProgress()
    const unsubscribeFromScroll = scrollY.onChange(handleScrollProgress)

    return () => unsubscribeFromScroll()
  }, [el, options])

  return progress
}