Mirror: React hooks for accessible, common web interactions. UI super powers without the UI.
1import { useRef, ForwardedRef } from 'react';
2import { Ref } from './types';
3
4type RefWithState<T extends HTMLElement> = Ref<T> & {
5 _forwarded?: ForwardedRef<T>;
6 _current?: T | null;
7};
8
9export function useForwardedRef<T extends HTMLElement>(
10 forwarded: ForwardedRef<T>
11): Ref<T> {
12 const ref = useRef<RefWithState<T> | null>(null);
13 if (!ref.current || ref.current._forwarded !== forwarded) {
14 ref.current = Object.defineProperty({ _forwarded: forwarded }, 'current', {
15 enumerable: true,
16 configurable: true,
17 get() {
18 return this._current || null;
19 },
20 set(value: T | null) {
21 this._current = value;
22 if (typeof this._forwarded === 'function') {
23 this._forwarded(value);
24 } else if (forwarded) {
25 this._forwarded.current = value;
26 }
27 },
28 }) as RefWithState<T>;
29 }
30 return ref.current;
31}