UNPKG

@hypothesis/frontend-shared

Version:

Shared components, styles and utilities for Hypothesis projects

79 lines (76 loc) 2.68 kB
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } import { useRef } from 'preact/hooks'; /** * Object ref which synchronizes its value to another ref. */ class SyncedRef { /** * @param [target] - Initial target for this ref to synchronize to. * This is not called/set until the {@link current} property of the * SyncedRef is set. This makes the target behave close to how it would * if used in place of the SyncedRef. */ constructor(target) { _defineProperty(this, "_target", void 0); _defineProperty(this, "_value", void 0); this._target = target; this._value = null; } get current() { return this._value; } set current(value) { this._value = value; this._updateTarget(); } get target() { return this._target; } set target(target) { if (target === this._target) { return; } this._target = target; // If the target changes after the initial render, we currently synchronize // the value immediately. This is different than what happens if the target // were passed to an element directly, as it would be updated only after the // render. this._updateTarget(); } _updateTarget() { const value = this._value; if (typeof this._target === 'function') { this._target(value); } else if (this._target) { this._target.current = value; } } } /** * Return an object ref which synchronizes its value to another "target" ref. * * This is useful when a component needs an object ref for an element for * internal use, but also wants to allow the caller to get a ref for the same * element. * * The target ref can be either a callback or an object. * * @example * function Widget({ elementRef }) { * const ref = useSyncedRef(elementRef); * * useEffect(() => { * ref.current.focus(); * }, []); * * return <input ref={ref}>...</input>; * } */ export function useSyncedRef(targetRef) { const container = useRef(new SyncedRef(targetRef)); container.current.target = targetRef; return container.current; } //# sourceMappingURL=use-synced-ref.js.map