How to use the @reach/utils.useForkedRef function in @reach/utils

To help you get started, we’ve selected a few @reach/utils examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github reach / reach-ui / packages / accordion / src / index.js View on Github external
* We only need an array of refs for our triggers for keyboard navigation, and
   * we already know the index because we can constrain Accordion children to
   * only AccordionItems. So we shouldn't need to do any funky render dancing
   * here, just update the ref in the same order if the index changes.
   */
  const setFocusableTriggerRefs = useCallback(
    node => {
      if (node && !disabled) {
        focusableTriggerNodes.current[index] = node;
      }
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [disabled, index]
  );

  const ref = useForkedRef(forwardedRef, ownRef, setFocusableTriggerRefs);

  function handleClick(event) {
    event.preventDefault();
    if (disabled) {
      return;
    }
    ownRef.current.focus();
    onSelectPanel(index);
  }

  function handleKeyDown(event) {
    const { key, ctrlKey } = event;
    const { current: focusNodes } = focusableTriggerNodes;
    const firstItem = focusNodes[0];
    const lastItem = focusNodes[focusNodes.length - 1];
    const nextItem = focusNodes[index + 1];
github reach / reach-ui / packages / menu-button / src / index.js View on Github external
export const MenuButton = forwardRef(function MenuButton(
  { onKeyDown, onMouseDown, id, ...props },
  forwardedRef
) {
  const {
    buttonRef,
    menuId,
    state: { buttonId, isOpen },
    dispatch
  } = useMenuContext();
  const ref = useForkedRef(buttonRef, forwardedRef);

  useEffect(() => {
    let newButtonId = id != null ? id : makeId("menu-button", menuId);
    if (buttonId !== newButtonId) {
      dispatch({
        type: SET_BUTTON_ID,
        payload: newButtonId
      });
    }
  }, [buttonId, dispatch, id, menuId]);

  function handleKeyDown(event) {
    switch (event.key) {
      case "ArrowDown":
      case "ArrowUp":
        event.preventDefault(); // prevent scroll
github reach / reach-ui / packages / menu-button / src / index.js View on Github external
export const MenuPopover = forwardRef(function MenuPopover(
  { children, onBlur, style, ...props },
  forwardedRef
) {
  const {
    buttonRef,
    dispatch,
    menuRef,
    popoverRef,
    state: { isOpen }
  } = useMenuContext();

  const ref = useForkedRef(popoverRef, forwardedRef);

  function handleBlur(event) {
    const { relatedTarget } = event;
    requestAnimationFrame(() => {
      // We on want to close only if focus rests outside the menu
      if (
        document.activeElement !== menuRef.current &&
        document.activeElement !== buttonRef.current &&
        popoverRef.current
      ) {
        if (
          !popoverRef.current.contains(relatedTarget || document.activeElement)
        ) {
          dispatch({ type: CLOSE_MENU });
        }
      }
github reach / reach-ui / packages / combobox / src / index.js View on Github external
value: controlledValue,
    ...props
  },
  forwardedRef
) {
  const {
    data: { navigationValue, value, lastActionType },
    inputRef,
    state,
    transition,
    listboxId,
    autocompletePropRef,
    openOnFocus
  } = useContext(ComboboxContext);

  const ref = useForkedRef(inputRef, forwardedRef);

  // Because we close the List on blur, we need to track if the blur is
  // caused by clicking inside the list, and if so, don't close the List.
  const selectOnClickRef = useRef(false);

  const handleKeyDown = useKeyDown();

  const handleBlur = useBlur();

  const isControlled = controlledValue != null;

  useLayoutEffect(() => {
    autocompletePropRef.current = autocomplete;
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [autocomplete]);
github reach / reach-ui / packages / tooltip / src / index.js View on Github external
ref: forwardedRef,
  DEBUG_STYLE
} = {}) {
  const id = useId(idProp);

  const [isVisible, setIsVisible] = useState(
    DEBUG_STYLE
      ? true
      : id === null
      ? false
      : context.id === id && state === VISIBLE
  );

  // hopefully they always pass a ref if they ever pass one
  const ownRef = useRef();
  const ref = useForkedRef(forwardedRef, ownRef);
  const triggerRect = useRect(ownRef, isVisible);

  useEffect(() => {
    return subscribe(() => {
      if (
        context.id === id &&
        (state === VISIBLE || state === LEAVING_VISIBLE)
      ) {
        setIsVisible(true);
      } else {
        setIsVisible(false);
      }
    });
  }, [id]);

  useEffect(() => checkStyles("tooltip"));
github reach / reach-ui / packages / menu-button / src / index.js View on Github external
const setValueTextFromDom = useCallback(
    node => {
      if (node) {
        ownRef.current = node;
        if (
          !valueTextProp ||
          (node.textContent && valueText !== node.textContent)
        ) {
          setValueText(node.textContent);
        }
      }
    },
    [valueText, valueTextProp]
  );

  const ref = useForkedRef(forwardedRef, setValueTextFromDom);

  const mouseEventStarted = useRef(false);

  /*
   * By default, we assume valueText is a unique value for all menu items, so it
   * should be sufficient as an unique identifier we can use to find our index.
   * However there may be some use cases where this is not the case and an
   * explicit unique index may be provided by the app.
   */
  const key = indexProp ?? valueText;

  const index = useDescendant(key, ownRef);
  const isSelected = index === selectionIndex;

  function select() {
    dispatch({
github reach / reach-ui / packages / dialog / src / index.js View on Github external
const DialogInner = forwardRef(function DialogInner(
  {
    allowPinchZoom,
    initialFocusRef,
    onClick,
    onDismiss = noop,
    onMouseDown,
    onKeyDown,
    ...props
  },
  forwardedRef
) {
  const mouseDownTarget = useRef(null);
  const overlayNode = useRef(null);
  const ref = useForkedRef(overlayNode, forwardedRef);

  useEffect(() => createAriaHider(overlayNode.current), []);

  return (
     {
        if (initialFocusRef && initialFocusRef.current) {
          initialFocusRef.current.focus();
        }
      }}
    >
github reach / reach-ui / packages / slider / src / index.js View on Github external
const {
    ariaLabelledBy,
    disabled,
    handlePosition,
    handleRef,
    isVertical,
    onHandleKeyDown,
    orientation,
    setHasFocus,
    sliderMin,
    sliderMax,
    value,
    valueText
  } = useSliderContext();

  const ref = useForkedRef(handleRef, forwardedRef);
  const dataAttributes = makeDataAttributes("slider-handle", {
    orientation,
    disabled
  });

  return (
github reach / reach-ui / packages / slider / src / index.js View on Github external
warning(
    !(isControlled && controlledValue == null),
    "Slider is changing from controlled to uncontrolled. Slider should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled Slider for the lifetime of the component. Check the `value` prop being passed in."
  );

  warning(
    !(!isControlled && controlledValue != null),
    "Slider is changing from uncontrolled to controlled. Slider should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled Slider for the lifetime of the component. Check the `value` prop being passed in."
  );

  const id = useId(rest.id);

  const trackRef = useRef(null);
  const handleRef = useRef(null);
  const sliderRef = useRef(null);
  const ref = useForkedRef(sliderRef, forwardedRef);

  const [hasFocus, setHasFocus] = useState(false);
  const [isPointerDown, setPointerDown] = useState(false);
  const [internalValue, setValue] = useState(defaultValue || min);

  const { ref: x, ...handleDimensions } = useDimensions(handleRef);

  const _value = isControlled ? controlledValue : internalValue;
  const value = getAllowedValue(_value, min, max);
  const trackPercent = valueToPercent(value, min, max);
  const isVertical = orientation === SLIDER_ORIENTATION_VERTICAL;
  const step = stepProp || 1;

  const handleSize = isVertical
    ? handleDimensions.height
    : handleDimensions.width;
github reach / reach-ui / packages / popover / src / index.js View on Github external
const PopoverImpl = forwardRef(function PopoverImpl(
  { targetRef, position = positionDefault, style, ...rest },
  forwardedRef
) {
  const popoverRef = useRef();
  const popoverRect = useRect(popoverRef);
  const targetRect = useRect(targetRef);
  const ref = useForkedRef(popoverRef, forwardedRef);

  useSimulateTabNavigationForReactTree(targetRef, popoverRef);

  return (
    <div style="{{" data-reach-popover="">
  );
});</div>

@reach/utils

Internal, shared utilities for Reach UI.

MIT
Latest version published 2 years ago

Package Health Score

82 / 100
Full package analysis

Similar packages