import React, { RefObject, SyntheticEvent, useRef, useState } from 'react' import { createOrderedValues } from 'react-document-order' const ControlOrder = createOrderedValues>() const useUpDownBehaviour = (ref: RefObject) => { const first = ControlOrder.useFirst() const previous = ControlOrder.useValueBefore(ref) const next = ControlOrder.useValueAfter(ref) const last = ControlOrder.useLast() return { onKeyDownCapture: (e: SyntheticEvent) => { if (e.nativeEvent.key === "ArrowUp") { e.preventDefault(); (e.nativeEvent.metaKey ? first : previous)?.current?.focus() } else if (e.nativeEvent.key === "ArrowDown") { e.preventDefault(); (e.nativeEvent.metaKey ? last : next)?.current?.focus() } } } } const Item = ({ onRemove }: { onRemove: () => void }) => { const ref = useRef(null) ControlOrder.useRegister(ref) return
} const AddButton = ({ label, onClick }: { label: string, onClick: () => void }) => { const ref = useRef(null) ControlOrder.useRegister(ref) return } const List = ({ addLabel }: { addLabel: string }) => { const [{ ids, nextId }, setState] = useState({ ids: [] as ReadonlyArray, nextId: 0 }) return (
{ids.map((id, i) =>
setState({ ids: [...ids.slice(0, i), ...ids.slice(i + 1)], nextId })} />
)}
setState({ ids: [...ids, nextId], nextId: nextId + 1 })} />
) } export default function ToDoList() { return (

Squint hard enough, and it's a hierarchical to-do list UI.

Anyway, hit a few add buttons in various orders, and then see how you can use the arrow kets to navigate up and down among the text inputs and add-buttons in document order. Use the meta key (command key on MacOS) to move to the top or bottom of the controls in the list.

) }