UNPKG

@bianic-ui/descendant

Version:

Register child nodes of a react element for better accessibility

99 lines (86 loc) 3.16 kB
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } import { useCallback, useMemo, useState } from "react"; import { useSafeLayoutEffect, useForceUpdate } from "@bianic-ui/hooks"; export function useDescendant(props) { var { context, element, index: indexProp, disabled, focusable } = props, rest = _objectWithoutPropertiesLoose(props, ["context", "element", "index", "disabled", "focusable"]); var forceUpdate = useForceUpdate(); var { register, unregister, descendants } = context; useSafeLayoutEffect(() => { if (!element) { forceUpdate(); } /** * Don't register this descendant if it's disabled and not focusable */ if (disabled && !focusable) return; /** * else, register the descendant */ register(_extends({ element, disabled, focusable }, rest)); /** * when it unmounts, unregister the descendant */ return () => { if (element) { unregister(element); } }; //eslint-disable-next-line }, [element, disabled, focusable, ...Object.values(rest)]); var index = indexProp != null ? indexProp : descendants.findIndex(descendant => descendant.element === element); return index; } export function useDescendants() { var [descendants, setDescendants] = useState([]); var register = useCallback((_ref) => { var { element } = _ref, rest = _objectWithoutPropertiesLoose(_ref, ["element"]); if (!element) return; //@ts-ignore setDescendants(prevDescendants => { if (prevDescendants.find(item => item.element === element) == null) { var index = prevDescendants.findIndex(item => { if (!item.element || !element) return false; return Boolean(item.element.compareDocumentPosition(element) & Node.DOCUMENT_POSITION_PRECEDING); }); var newItem = _extends({ element }, rest); if (index === -1) { return [...prevDescendants, newItem]; } return [...prevDescendants.slice(0, index), newItem, ...prevDescendants.slice(index)]; } return prevDescendants; }); }, []); var unregister = useCallback(element => { if (!element) return; setDescendants(descendants => descendants.filter(descendant => element !== descendant.element)); }, []); var context = useMemo(() => { return { descendants, register, unregister }; }, [descendants, register, unregister]); return context; } //# sourceMappingURL=use-descendant.js.map