UNPKG

@activecollab/components

Version:

ActiveCollab Components

126 lines 4.39 kB
import React, { useState, useRef, useCallback, useMemo, Children, cloneElement, useEffect, useLayoutEffect } from "react"; import classNames from "classnames"; import { StyledNavListItemMore } from "./Item/Styles"; import { StyledNav, StyledNavAsSelect, StyledNavList } from "./Styles"; import { useResizeObserver } from "../../utils"; import { ExpandSingle } from "../Expanders/ExpandSingle"; import { Select } from "../Select/Select"; export const Nav = _ref => { var _dimensions$width, _childDimensions$widt; let { children, alignment = "left", onSelect, className, role = "bold", targetId } = _ref; const [active, setActive] = useState(0); const [moreOpened, setMoreOpened] = useState(false); const [type, setType] = useState("inline"); const setMoreOpen = useCallback(() => setMoreOpened(true), []); const setMoreClose = useCallback(() => setMoreOpened(false), []); const navItemNames = useMemo(() => { return children ? Children.toArray(children).map(item => { var _item$props; return item == null || (_item$props = item.props) == null ? void 0 : _item$props.name; }) : []; }, [children]); const allOptions = useMemo(() => { return navItemNames == null ? void 0 : navItemNames.map((name, index) => { return { id: index, name: name }; }); }, [navItemNames]); const navRef = useRef(null); const wrapRef = useRef(null); const dimensions = useResizeObserver(wrapRef); const childDimensions = useResizeObserver(navRef); const parentWidth = (_dimensions$width = dimensions == null ? void 0 : dimensions.width) != null ? _dimensions$width : 0; const childWidth = (_childDimensions$widt = childDimensions == null ? void 0 : childDimensions.width) != null ? _childDimensions$widt : 0; const [childrenWidth, setChildrenWidth] = useState(childWidth); useLayoutEffect(() => { if (type === "inline") setChildrenWidth(childWidth); }, [childWidth, type]); const onClick = useCallback(e => { if (e.metaKey || e.ctrlKey) { return; } if (e.target && e.currentTarget.dataset.index && !e.currentTarget.dataset.disabled) { const index = Number(e.currentTarget.dataset.index); setActive(index); if (onSelect) { onSelect(index); } } }, [onSelect]); const onMoreOptionClick = useCallback(id => { setActive(id); if (onSelect) { onSelect(id); } }, [onSelect]); useMemo(() => { Children.forEach(children, (child, index) => { if (child && child.props.active) { setActive(index); } }); }, [children]); const navAsSelect = useMemo(() => { return /*#__PURE__*/React.createElement(StyledNavAsSelect, { id: targetId, $active: true }, /*#__PURE__*/React.createElement("span", null, navItemNames[active]), /*#__PURE__*/React.createElement(ExpandSingle, { expanded: moreOpened, fill: "currentColor" })); }, [active, moreOpened, navItemNames, targetId]); useEffect(() => { if (!navRef.current || !wrapRef.current) return; if (!childrenWidth || !parentWidth) return; if (childrenWidth < parentWidth) { setType("inline"); } else { setType("dropdown"); } }, [childrenWidth, parentWidth]); if (!children) return; return /*#__PURE__*/React.createElement(StyledNav, { className: classNames("c-nav", className), $align: alignment, $role: role, ref: wrapRef }, /*#__PURE__*/React.createElement(StyledNavList, { ref: navRef }, type === "inline" && Children.toArray(children).map((child, index) => { const element = child; return /*#__PURE__*/cloneElement(element, { active: index === active, role, onClick, "data-index": index, "data-disabled": element.props.disabled }); }), type === "dropdown" ? /*#__PURE__*/React.createElement(StyledNavListItemMore, { name: navItemNames[active], role: role }, /*#__PURE__*/React.createElement(Select, { selected: active, target: navAsSelect, disabledInternalSort: true, options: allOptions, type: "single", mode: "normal", forceCloseMenu: true, disableSearch: true, keepSameOptionsOrder: true, onChange: onMoreOptionClick, onSelectOpen: setMoreOpen, onSelectClose: setMoreClose })) : null)); }; Nav.displayName = "Nav"; //# sourceMappingURL=Nav.js.map