@atlaskit/dropdown-menu
Version:
A dropdown menu displays a list of actions or options to a user.
49 lines (46 loc) • 2.13 kB
JavaScript
import { useCallback, useContext, useState } from 'react';
import { fg } from '@atlaskit/platform-feature-flags/fg';
import { CheckboxGroupContext } from '../context/checkbox-group-context';
import { SelectionStoreContext } from '../context/selection-store-context';
/**
* Custom hook to handle checkbox state for dropdown menu.
* It works in tandem with the selection store context when the
* component is uncontrolled.
*/
const useCheckboxState = ({
isSelected,
id,
defaultSelected
}) => {
const {
setItemState,
getItemState
} = useContext(SelectionStoreContext);
const groupId = useContext(CheckboxGroupContext);
const persistedIsSelected = getItemState(groupId, id);
const [localIsSelected, setLocalIsSelected] = useState(
// Initial state is set depending on value being defined or not.
// This state is only utilised if the checkbox is uncontrolled.
() => persistedIsSelected !== undefined ? persistedIsSelected : defaultSelected || false);
const setLocalState = useCallback(newValue => {
// With `platform-dst-top-layer`, read the store when the callback runs, not the value
// from render time. The first render writes the default to the store during render, so
// a value captured in that render is still `undefined`.
const nextValue = newValue(fg('platform-dst-top-layer') ? getItemState(groupId, id) : persistedIsSelected);
setLocalIsSelected(nextValue);
setItemState(groupId, id, nextValue);
}, [setItemState, getItemState, persistedIsSelected, groupId, id]);
// Checkbox is controlled - do nothing!
if (typeof isSelected === 'boolean') {
return [isSelected, () => false];
}
// Checkbox is going through its first render pass!
if (persistedIsSelected === undefined) {
// Set the item so we have this state to access next time the checkbox renders (either by mounting or re-rendering!)
setItemState(groupId, id, defaultSelected || false);
}
// Return the value and setter!
// Remember this flow is only returned if the checkbox is uncontrolled.
return [localIsSelected, setLocalState];
};
export default useCheckboxState;