--- title: useDescendants description: "`useDescendants` is a custom hook that manages descendants." links: - source: https://github.com/yamada-ui/yamada-ui/tree/main/packages/react/src/hooks/use-descendants --- ```tsx const { useDescendants, useDescendant, DescendantsContext } = createDescendants() const ref = useRef(null) const descendants = useDescendants() const onFocus = useCallback( (ev: FocusEvent) => { if (ev.target !== ref.current) return const descendant = descendants.enabledFirstValue() if (descendant) { descendant.node.focus() if (ref.current) ref.current.tabIndex = -1 } }, [descendants], ) const onBlur = useCallback((ev: FocusEvent) => { if (contains(ref.current, ev.relatedTarget)) return if (ref.current) ref.current.tabIndex = 0 }, []) const Item: FC<{ index: number }> = ({ index }) => { const { descendants, register } = useDescendant() const onKeyDown = useCallback( (ev: KeyboardEvent) => { runKeyAction(ev, { ArrowDown: () => { const descendant = descendants.enabledNextValue(index) if (descendant) descendant.node.focus() }, ArrowUp: () => { const descendant = descendants.enabledPrevValue(index) if (descendant) descendant.node.focus() }, Home: () => { const descendant = descendants.enabledFirstValue() if (descendant) descendant.node.focus() }, End: () => { const descendant = descendants.enabledLastValue() if (descendant) descendant.node.focus() }, }) }, [descendants], ) return (
Item {index}
) } return ( {Array.from({ length: 5 }).map((_, index) => ( ))} ) ``` ## Usage ```tsx import { createDescendants } from "@yamada-ui/react" ``` ```tsx import { createDescendants } from "@/components/ui" ``` ```tsx import { createDescendants } from "@workspaces/ui" ``` ```tsx const { DescendantsContext, useDescendant, useDescendantRegister, useDescendants, useDescendantsContext, } = createDescendants() ``` ```tsx const descendants = useDescendants() ``` ```tsx const { descendants, register } = useDescendant() ``` ### Disable descendant To disable a descendant, set the `disabled` prop to `true` on `useDescendant`. ```tsx const { useDescendants, useDescendant, DescendantsContext } = createDescendants() const ref = useRef(null) const descendants = useDescendants() const onFocus = useCallback( (ev: FocusEvent) => { if (ev.target !== ref.current) return const descendant = descendants.enabledFirstValue() if (descendant) { descendant.node.focus() if (ref.current) ref.current.tabIndex = -1 } }, [descendants], ) const onBlur = useCallback((ev: FocusEvent) => { if (contains(ref.current, ev.relatedTarget)) return if (ref.current) ref.current.tabIndex = 0 }, []) const Item: FC<{ index: number; disabled?: boolean }> = ({ index, disabled, }) => { const { descendants, register } = useDescendant({ disabled }) const onKeyDown = useCallback( (ev: KeyboardEvent) => { runKeyAction(ev, { ArrowDown: () => { const descendant = descendants.enabledNextValue(index) if (descendant) descendant.node.focus() }, ArrowUp: () => { const descendant = descendants.enabledPrevValue(index) if (descendant) descendant.node.focus() }, Home: () => { const descendant = descendants.enabledFirstValue() if (descendant) descendant.node.focus() }, End: () => { const descendant = descendants.enabledLastValue() if (descendant) descendant.node.focus() }, }) }, [descendants], ) return (
Item {index}
) } return ( {Array.from({ length: 5 }).map((_, index) => ( ))} ) ```