Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
const goToNextTab = () => {
const nextIndex = (enabledSelectedIndex + 1) % count;
updateActiveIndex(nextIndex);
};
const goToPrevTab = () => {
const nextIndex = (enabledSelectedIndex - 1 + count) % count;
updateActiveIndex(nextIndex);
};
const goToFirst = () => updateActiveIndex(0);
const goToLast = () => updateActiveIndex(count - 1);
const isHorizontal = tabs.orientation === "horizontal";
const isVertical = tabs.orientation === "vertical";
// Function to handle keyboard navigation
const onKeyDown = createOnKeyDown({
preventDefault: false,
keyMap: {
ArrowRight: () => isHorizontal && goToNextTab(),
ArrowLeft: () => isHorizontal && goToPrevTab(),
ArrowDown: event => {
event.preventDefault();
isVertical && goToNextTab();
},
ArrowUp: event => {
event.preventDefault();
isVertical && goToPrevTab();
},
Home: () => goToFirst(),
End: () => goToLast(),
},
});
menu.onOpen();
const firstItem = items[0];
const firstItemNode = firstItem.ref.current as HTMLElement;
ensureFocus(firstItemNode);
highlight(firstItem);
};
const showAndFocusLastItem = () => {
menu.onOpen();
const lastItem = items[items.length - 1];
const lastItemNode = lastItem.ref.current as HTMLElement;
ensureFocus(lastItemNode);
highlight(lastItem);
};
const onKeyDown = createOnKeyDown({
stopPropagation: event => event.key !== "Escape",
//@ts-ignore
keyMap: {
ArrowDown: !hasParent && showAndFocusFirstItem,
ArrowUp: !hasParent && showAndFocusLastItem,
ArrowRight: hasParent && showAndFocusFirstItem,
},
});
// merge the refs
const ref = useMergeRefs(menu.disclosureRef, menu.reference.ref, props.ref);
return {
...props,
ref,
id: menu.disclosureId,
document.removeEventListener("click", click);
};
}, [menu, hasParent]);
const onMouseEnter = () => {
// If we're in a nested menu,
// keep the menu open when we mouse into it
if (hasParent) {
menu.onOpen();
}
};
const [descendants, { next, previous, search }] = useDescendantCtx();
const [onSearch, keys] = useRapidKeydown();
const onKeyDown = createOnKeyDown({
stopPropagation: event => {
if (event.key === "Escape" && hasParent) return false;
return true;
},
onKeyDown: onSearch(keys => search(keys, "highlight")),
keyMap: {
Escape: menu.onClose,
ArrowDown: () => next("highlight"),
ArrowUp: () => previous("highlight"),
ArrowLeft: () => {
if (!hasParent) return;
menu.onClose();
const disclosureNode = menu.disclosureRef.current;
disclosureNode.focus();
},
},
const keyStep = step || (max - min) / 100;
const constrainAndUpdate = React.useCallback(
(value: number) => {
let nextValue = value;
nextValue = +roundValueToStep(nextValue, keyStep);
nextValue = constrainValue(nextValue, min, max);
updateValue(nextValue);
},
[keyStep, max, min, updateValue],
);
// Just a short-hand for `constrainAndUpdate`
const cAU = constrainAndUpdate;
const onKeyDown = createOnKeyDown({
stopPropagation: true,
keyMap: {
ArrowRight: () => cAU(value + keyStep),
ArrowUp: () => cAU(value + keyStep),
ArrowLeft: () => cAU(value - keyStep),
ArrowDown: () => cAU(value - keyStep),
PageUp: () => cAU(value + tenSteps),
PageDown: () => cAU(value - tenSteps),
Home: () => cAU(props.min),
End: () => cAU(props.max),
},
});
/**
* ARIA (Optional): To define a human readable representation of the value,
* we allow users pass aria-valuetext.
export function useSelectButton(props: any) {
const { selectedItem } = useSelectState();
const { controlRef, listBoxId } = useSelectOptions();
const { onToggle, isOpen, onOpen } = useSelectDisclosure();
const { next, previous, first, last, search } = useSelectActions();
const [onRapidKeyDown] = useRapidKeydown();
const onClick = React.useCallback(() => {
onToggle();
}, [onToggle]);
const onKeyDown = createOnKeyDown({
onKeyDown: onRapidKeyDown(keys => search(keys, "select")),
keyMap: {
ArrowUp: onOpen,
ArrowDown: onOpen,
ArrowRight: () => next("select"),
ArrowLeft: () => previous("select"),
Home: () => first("select"),
End: () => last("select"),
" ": event => {
event && event.preventDefault();
onToggle();
},
},
});
const selectedOptionText =
last("highlight");
};
const onClick = React.useCallback(() => {
if (isOpen) {
onClose();
reset("highlighted");
} else {
onOpen();
if (autoSelect) {
first("highlight");
}
}
}, [isOpen, onClose, onOpen, autoSelect, reset, first]);
const onKeyDown = createOnKeyDown({
keyMap: {
ArrowDown: focusOnFirstItem,
ArrowUp: focusOnLastItem,
},
});
const ref = useMergeRefs(menu.buttonRef, menu.reference.ref);
return {
...props,
"aria-haspopup": "menu",
"aria-expanded": menu.isOpen,
"aria-controls": menu.buttonId,
"data-active": menu.isOpen,
id: menu.buttonId,
role: "button",
export function useMenuList(props: UseMenuListOptions) {
const menu = useMenuCtx();
const [state, actions] = useSelection();
const [onRapidKeyDown] = useRapidKeydown();
const onKeyDown = createOnKeyDown({
onKeyDown: onRapidKeyDown(keys => actions.search(keys, "highlight")),
keyMap: {
ArrowDown: () => {
if (!state.highlightedItem) {
actions.first("highlight");
} else {
actions.next("highlight");
}
},
ArrowUp: () => {
if (!state.highlightedItem) {
actions.last("highlight");
} else {
actions.previous("highlight");
}
},