UNPKG

@redocly/theme

Version:

Shared UI components lib

85 lines 4.3 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.useNestedMenu = useNestedMenu; const react_router_dom_1 = require("react-router-dom"); const react_1 = require("react"); const use_menu_item_expanded_1 = require("./use-menu-item-expanded"); const use_collapse_1 = require("./use-collapse"); const load_and_navigate_1 = require("../../utils/load-and-navigate"); const urls_1 = require("../../utils/urls"); function useNestedMenu({ item, labelRef, nestedMenuRef }) { const [isExpanded, setIsExpanded] = (0, use_menu_item_expanded_1.useMenuItemExpanded)(item); // we need to know when the item is collapsed after transition to remove children from DOM const [canUnmount, setCanUnmount] = (0, react_1.useState)(!isExpanded); const navigate = (0, react_router_dom_1.useNavigate)(); const location = (0, react_router_dom_1.useLocation)(); const { style } = (0, use_collapse_1.useCollapse)({ isExpanded, collapseElRef: nestedMenuRef || { current: null }, onTransitionStateChange: (state) => { var _a; if (state === 'collapseEnd') { setCanUnmount(true); } if (state === 'expandStart') { setCanUnmount(false); } // signal that used in e2e tests to wait for the item to be expanded if (state === 'expandEnd') { (_a = labelRef === null || labelRef === void 0 ? void 0 : labelRef.current) === null || _a === void 0 ? void 0 : _a.dispatchEvent(new CustomEvent('menu:expand-end', { bubbles: true })); } }, }); function scrollIfNeeded(el, centerIfNeeded = false) { const rect = el.getBoundingClientRect(); const isInViewport = rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth); // Only scroll if element is in viewport to prevent page jumping // @ts-ignore if (isInViewport && typeof el.scrollIntoViewIfNeeded === 'function') { // @ts-ignore el.scrollIntoViewIfNeeded(centerIfNeeded); } } // scroll to active element if needed (0, react_1.useEffect)(() => { if (item.active && labelRef && labelRef.current) { scrollIfNeeded(labelRef.current, true); // center item on the first scroll } }, [labelRef, item.active]); // scroll to expanded element if needed (position could change after collapse) (0, react_1.useEffect)(() => { if (item.active && isExpanded && labelRef && labelRef.current) { scrollIfNeeded(labelRef.current); } }, [labelRef, isExpanded, item.active]); const handleExpand = (0, react_1.useCallback)(() => __awaiter(this, void 0, void 0, function* () { if (item.expanded === 'always' || (item.link && item.hasActiveSubItem && item.link !== (0, urls_1.withoutPathPrefix)(location.pathname))) { return; } const [firstChild] = item.items; if (!isExpanded && item.selectFirstItemOnExpand && firstChild.link) { yield (0, load_and_navigate_1.loadAndNavigate)({ navigate, to: (0, urls_1.withPathPrefix)(firstChild.link) }); } setIsExpanded(!isExpanded); }), [item, isExpanded, navigate, location.pathname, setIsExpanded]); return { isExpanded, canUnmount, style, handleExpand, }; } //# sourceMappingURL=use-nested-menu.js.map