Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
dispatch({ type: "SELECT", payload: { id: defaultSelectedOption.id } });
}
}
}, [defaultValue, state.items]);
const [isOpen, setIsOpen] = useState(defaultIsOpen || false);
const [isMousingDown, setIsMousingDown] = useState(false);
// Store the refs of the components we'll be using
const controlRef = useRef();
const listBoxRef = useRef();
const valueIsControlled = value != null;
// id generation
const uuid = useId();
const controlId = `select-control-${uuid}`;
const listBoxId = `select-listbox-${uuid}`;
// Focus Management hook
useFocusManagement({ ...state, isOpen }, { listBoxRef, controlRef });
const { current: openIsControlled } = useRef(isOpenProp != null);
const _isOpen = openIsControlled ? isOpenProp : isOpen;
const openMenu = () => {
if (!openIsControlled) {
setIsOpen(true);
}
if (onOpen) {
onOpen();
}
return (refValue: any) => {
assignRef(refA, refValue);
assignRef(refB, refValue);
};
}, [refA, refB]);
return (refValue: any) => {
assignRef(refA, refValue);
assignRef(refB, refValue);
};
}, [refA, refB]);
(node: HTMLElement) => {
assignRef(ownRef, node);
handleOpen();
},
[ownRef, handleOpen],
if (shouldCloseMenu) {
closeMenu();
}
},
};
const { reference, popper } = usePopper({
placement: "right",
positionFixed: true,
});
useLogger(popper.styles);
const _controlRef = useForkRef(controlRef, reference as any);
const _listBoxRef = useForkRef(listBoxRef, popper as any);
const context = React.useMemo(
() => ({
props: {
selectOptionOnTab,
},
state: {
...state,
isOpen: _isOpen as boolean,
},
dispatch,
actions: {
closeMenu,
selectOption,
},
controlProps: {
document.activeElement) as HTMLElement);
if (shouldCloseMenu) {
closeMenu();
}
},
};
const { reference, popper } = usePopper({
placement: "right",
positionFixed: true,
});
useLogger(popper.styles);
const _controlRef = useForkRef(controlRef, reference as any);
const _listBoxRef = useForkRef(listBoxRef, popper as any);
const context = React.useMemo(
() => ({
props: {
selectOptionOnTab,
},
state: {
...state,
isOpen: _isOpen as boolean,
},
dispatch,
actions: {
closeMenu,
selectOption,
},
isDisabled,
isFocusable,
onMouseEnter,
onMouseLeave,
onKeyDown,
onClick,
...rest
}: OptionProps,
forwardedRef: React.Ref,
) => {
const { state, props, actions, dispatch } = useSelectContext();
const uuid = useId();
const id = idProp || uuid;
const ownRef = useRef(null);
const ref = useForkRef(forwardedRef, ownRef);
const isHighlighted = state.focusedId === id;
const isSelected = state.selectedId === id;
useLayoutEffect(() => {
if (isDisabled && !isFocusable) return;
dispatch({
type: "REGISTER",
payload: { ref: ownRef, id, value },
});
return () => {
dispatch({ type: "UNREGISTER", payload: { id } });
};
}, [dispatch, id, isDisabled, isFocusable, ref, value]);
return (
(
props: {
isReadOnly?: boolean;
isDisabled?: boolean;
isInvalid?: boolean;
children?: React.ReactNode;
},
ref,
) => {
const { state, controlProps, menuProps } = useSelectContext();
const _ref = useForkRef(ref, controlProps.ref);
const selected = state.items.find(item => item.id === state.selectedId);
return (
<button style="{{" aria-controls="{menuProps.id}" aria-expanded="{state.isOpen}" aria-haspopup="listbox" id="{controlProps.id}">
{selected ? (selected.ref.current as Node).textContent : "Select"}
</button>
);
},
(
{
value,
id: idProp,
isDisabled,
isFocusable,
onMouseEnter,
onMouseLeave,
onKeyDown,
onClick,
...rest
}: OptionProps,
forwardedRef: React.Ref,
) => {
const { state, props, actions, dispatch } = useSelectContext();
const uuid = useId();
const id = idProp || uuid;
const ownRef = useRef(null);
const ref = useForkRef(forwardedRef, ownRef);
const isHighlighted = state.focusedId === id;
const isSelected = state.selectedId === id;
useLayoutEffect(() => {
if (isDisabled && !isFocusable) return;
dispatch({
type: "REGISTER",
payload: { ref: ownRef, id, value },
});
return () => {
dispatch({ type: "UNREGISTER", payload: { id } });
};
function useFocusManagement(
state: State & { isOpen: boolean },
refs: { listBoxRef: React.RefObject; controlRef: React.RefObject },
) {
const { isOpen } = state;
const { listBoxRef, controlRef } = refs;
const prevIsOpen = usePrevious(isOpen);
useEffect(() => {
if (isOpen && listBoxRef && listBoxRef.current) {
listBoxRef.current.focus();
return;
}
if (prevIsOpen && !isOpen && controlRef && controlRef.current) {
controlRef.current.focus();
}
}, [isOpen, prevIsOpen, listBoxRef, controlRef]);
}