@neo4j-ndl/react
Version:
React implementation of Neo4j Design System
168 lines (167 loc) • 9.91 kB
JavaScript
/**
*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [http://neo4j.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
"use strict";
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SideNavigation = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const defaultImports_1 = require("../_common/defaultImports");
const divider_1 = require("../divider");
const icon_button_1 = require("../icon-button");
const icons_1 = require("../icons");
const typography_1 = require("../typography");
const getExpandIconName = (position, isExpanded) => {
if (isExpanded) {
return position === 'left' ? ((0, jsx_runtime_1.jsx)(icons_1.CollapseExpandLeftIcon, { className: "n-size-full" })) : ((0, jsx_runtime_1.jsx)(icons_1.CollapseExpandRightIcon, { className: "n-size-full" }));
}
else {
return position === 'left' ? ((0, jsx_runtime_1.jsx)(icons_1.CollapseExpandRightIcon, { className: "n-size-full" })) : ((0, jsx_runtime_1.jsx)(icons_1.CollapseExpandLeftIcon, { className: "n-size-full" }));
}
};
const SideNavigationComponent = (0, react_1.forwardRef)(function SideNavigationComponent({ isExpanded, children, className, onExpandedChange, hasIconMenu = false, position = 'left', size: defaultSize = 'large', htmlAttributes, }, ref) {
// Typescript unable to infer the default value correctly in the parameter.
const size = defaultSize;
const setOnExpandedChange = (0, react_1.useCallback)(() => {
if (onExpandedChange !== undefined) {
onExpandedChange(!isExpanded);
}
}, [isExpanded, onExpandedChange]);
const classes = (0, defaultImports_1.classNames)('ndl-side-navigation', className, {
'ndl-expanded': isExpanded,
'ndl-side-navigation-minimized-small': !isExpanded && size === 'small',
[`ndl-${position}`]: position,
});
const icon = getExpandIconName(position, isExpanded);
return ((0, jsx_runtime_1.jsx)(SideNavigationContext.Provider, { value: { isExpanded, hasIconMenu, size }, children: (0, jsx_runtime_1.jsxs)("div", Object.assign({ className: classes, ref: ref }, (!isExpanded &&
!hasIconMenu && {
role: 'presentation',
onClick: setOnExpandedChange,
}), htmlAttributes, { children: [(0, jsx_runtime_1.jsx)("nav", { className: "ndl-side-navigation-nav", children: children }), onExpandedChange !== undefined && ((0, jsx_runtime_1.jsx)(icon_button_1.IconButton, { className: "ndl-side-navigation-drawer-button", onClick: setOnExpandedChange, ariaLabel: isExpanded ? 'collapse-navigation' : 'expand-navigation', size: size === 'small' ? 'medium' : 'large', isClean: true, htmlAttributes: {
'data-testid': 'ndl-side-nav-expand-btn',
title: `${isExpanded ? 'Collapse' : 'Expand'} side navigation`,
}, children: icon }))] })) }));
});
SideNavigationComponent.displayName = 'SideNavigation';
const SideNavigationContext = (0, react_1.createContext)(null);
const useSideNavigationContext = () => (0, react_1.useContext)(SideNavigationContext);
const SideNavigationListContext = (0, react_1.createContext)(null);
const useSideNavigationListContext = () => (0, react_1.useContext)(SideNavigationListContext);
const SideNavigationList = (0, react_1.forwardRef)(function SideNavigationList({ children, className, htmlAttributes }, ref) {
var _a, _b;
const classes = (0, defaultImports_1.classNames)('ndl-side-navigation-nav-list', className);
const { level } = (_a = useSideNavigationListContext()) !== null && _a !== void 0 ? _a : {
level: -1,
};
const { isExpanded, hasIconMenu, size } = (_b = useSideNavigationContext()) !== null && _b !== void 0 ? _b : {
isExpanded: true,
hasIconMenu: false,
size: 'small',
};
if (!isExpanded && !hasIconMenu)
return null;
return ((0, jsx_runtime_1.jsx)(SideNavigationListContext.Provider, { value: { level: level + 1, size }, children: (0, jsx_runtime_1.jsx)("ul", Object.assign({ className: classes, ref: ref }, htmlAttributes, { children: children })) }));
});
SideNavigationList.displayName = 'SideNavigation.List';
const SideNavigationItem = (0, react_1.forwardRef)(function SideNavigationItem(_a, ref) {
var _b, _c;
var { className, children, icon, as, isSelected = false, isSelectable = true, style = {}, htmlAttributes } = _a, restProps = __rest(_a, ["className", "children", "icon", "as", "isSelected", "isSelectable", "style", "htmlAttributes"]);
const Component = as || 'a';
const { level } = (_b = useSideNavigationListContext()) !== null && _b !== void 0 ? _b : { level: 0 };
const { isExpanded, hasIconMenu, size } = (_c = useSideNavigationContext()) !== null && _c !== void 0 ? _c : {
isExpanded: true,
hasIconMenu: false,
size: 'small',
};
const defaultPaddingLeft = level ? 0 : size === 'small' ? 8 : 12;
const paddingLeft = isExpanded ? defaultPaddingLeft + level * 32 : 0;
const itemClasses = (0, defaultImports_1.classNames)(className, {
'ndl-side-navigation-nav-item': size === 'large',
'ndl-side-navigation-nav-item-small': size === 'small',
'ndl-expanded': isExpanded,
});
const innerClasses = (0, defaultImports_1.classNames)('ndl-side-navigation-inner-item', {
'ndl-selected': isSelected,
'ndl-selectable': isSelectable,
});
if (hasIconMenu && !icon) {
throw new Error('SideNavigation is an IconMenu but icon is not defined! Set an icon on this SideNavigationItem or set `hasIconMenu` to false on SideNavigation');
}
else if (!hasIconMenu && icon) {
throw new Error('SideNavigation is not an IconMenu but icon is defined! Remove the icon or set `hasIconMenu` to true on SideNavigation to allow icons');
}
if (!isExpanded && !(icon && hasIconMenu))
return null;
return ((0, jsx_runtime_1.jsx)("li", { className: itemClasses, children: (0, jsx_runtime_1.jsxs)(Component, Object.assign({ className: innerClasses, style: Object.assign({ paddingLeft }, style), ref: ref }, restProps, htmlAttributes, { children: [hasIconMenu && icon && (0, jsx_runtime_1.jsx)("span", { className: "ndl-icon", children: icon }), isExpanded && children] })) }));
});
const SideNavigationItemBadge = (0, react_1.forwardRef)(function SideNavigationItemBadge(_a, ref) {
var _b;
var { children, type = 'info' } = _a, restProps = __rest(_a, ["children", "type"]);
const { isExpanded } = (_b = useSideNavigationContext()) !== null && _b !== void 0 ? _b : {
isExpanded: true,
};
if (!isExpanded) {
return null;
}
const badgeClasses = (0, defaultImports_1.classNames)('ndl-badge', {
'ndl-info': type === 'info',
'ndl-warning': type === 'warning',
'ndl-critical': type === 'critical',
});
return ((0, jsx_runtime_1.jsx)(typography_1.Typography, Object.assign({ as: "span", className: badgeClasses, variant: "subheading-small" }, restProps, { ref: ref, children: children })));
});
SideNavigationItemBadge.displayName = 'SideNavigation.ItemBadge';
const SideNavigationGroupHeader = (0, react_1.forwardRef)(function SideNavigationGroupHeader({ children, className, as, style, htmlAttributes, }, ref) {
var _a;
const Component = as !== null && as !== void 0 ? as : 'li';
const { isExpanded, hasIconMenu, size } = (_a = useSideNavigationContext()) !== null && _a !== void 0 ? _a : {
isExpanded: true,
hasIconMenu: false,
};
const classes = (0, defaultImports_1.classNames)(className, {
'ndl-side-navigation-nav-item': size === 'large',
'ndl-side-navigation-nav-item-small': size === 'small',
});
const paddingLeft = isExpanded ? (size === 'small' ? '8px' : '16px') : '0';
return ((0, jsx_runtime_1.jsx)(Component, Object.assign({ className: classes, style: Object.assign({ paddingLeft }, style) }, htmlAttributes, { children: (0, jsx_runtime_1.jsxs)("div", { className: "ndl-side-navigation-inner-item ndl-side-navigation-group-header", ref: ref, children: [!isExpanded && hasIconMenu && (0, jsx_runtime_1.jsx)(divider_1.Divider, {}), isExpanded && children] }) })));
});
// Issue with TypeScript forwardRef and subcomponents: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/34757#issuecomment-894053907
/**
* @deprecated Use new SideNavigation from @neo4j-ndl/react/next instead.
*/
const SideNavigation = Object.assign(SideNavigationComponent, {
GroupHeader: SideNavigationGroupHeader,
Item: SideNavigationItem,
ItemBadge: SideNavigationItemBadge,
List: SideNavigationList,
});
exports.SideNavigation = SideNavigation;
//# sourceMappingURL=SideNavigation.js.map