@redocly/theme
Version:
Shared UI components lib
32 lines (25 loc) • 1.24 kB
text/typescript
import { useEffect, useState } from 'react';
import type { Dispatch, SetStateAction } from 'react';
import type { ItemState } from '../../types/sidebar';
function isItemExpanded(item: ItemState) {
return (
item.active || item.hasActiveSubItem || item.expanded === 'true' || item.expanded === 'always'
);
}
export function useMenuItemExpanded(item: ItemState): [boolean, Dispatch<SetStateAction<boolean>>] {
const [isExpanded, setIsExpanded] = useState(isItemExpanded(item));
// we keep separate controlled value here so controlled updates have the same lifecycle as uncontrolled (via useEffect)
// it's important for transitions
const [controlledValue, setControlledValue] = useState(isItemExpanded(item));
useEffect(() => {
setIsExpanded(controlledValue);
}, [controlledValue]);
useEffect(() => {
const newValue = isItemExpanded(item);
setIsExpanded(newValue);
setControlledValue(newValue);
// we have different sensitivity to changes for items from openapi-docs sidebar and for items from portal sidebar
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [!item.modified ? item : item.active, item.hasActiveSubItem, item.expanded]);
return [isExpanded, setControlledValue];
}