@octopusdeploy/design-system-components
Version:
The design systems component library.
77 lines (76 loc) • 4.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MenuItemInternalLink = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const css_1 = require("@emotion/css");
const material_1 = require("@mui/material");
const design_system_tokens_1 = require("@octopusdeploy/design-system-tokens");
const react_1 = require("react");
const OctopusRoutingContext_1 = require("../../../routing/OctopusRoutingContext");
const menuItemStyles_1 = require("../menuItemStyles");
exports.MenuItemInternalLink = (0, react_1.forwardRef)(({ path, label, onClick, autoFocus, size = "default", icon, shortDescription, showLinkAsActive = "never", disableImplicitEventTracking }, ref) => {
// We can't use the default li component that MenuItem renders here, because the parent element (CustomMenu or MenuList) is not a ul
return ((0, jsx_runtime_1.jsx)(material_1.MenuItem, { disableRipple: true, disableTouchRipple: true, component: LinkWrapper, path: path, label: label, onClick: onClick, showLinkAsActive: showLinkAsActive, autoFocus: autoFocus, size: size, ref: ref, icon: icon, shortDescription: shortDescription, disableImplicitEventTracking: disableImplicitEventTracking }));
});
exports.MenuItemInternalLink.displayName = "MenuItemInternalLink";
const LinkWrapper = (0, react_1.forwardRef)(({ path, showLinkAsActive, label, onClick, className, children, autoFocus, size, icon, shortDescription, disableImplicitEventTracking, ...other }, ref) => {
const Link = (0, OctopusRoutingContext_1.useOctopusLinkComponent)();
const isUrlActive = (0, OctopusRoutingContext_1.useIsUrlActive)();
const isActive = isUrlActive(path, showLinkAsActive);
const sizeClass = size === "compact" ? compactStyles : size === "default" ? defaultSizeStyles : spaciousStyles;
const classes = (0, css_1.cx)(className, menuItemLinkStyles, sizeClass);
const focusRef = (0, react_1.useRef)(null);
const combinedRef = (0, material_1.useForkRef)(focusRef, ref);
(0, react_1.useEffect)(() => {
if (autoFocus) {
focusRef.current?.focus();
}
}, [autoFocus]);
// Ideally we would wrap an anchor tag in an li like in this example: https://www.w3.org/TR/wai-aria-practices/examples/menu-button/menu-button-links.html
// <li role="none"><a role="menuitem">My Link</a></li>
// But if we do that, we lose out on keyboard navigation support from material ui's MenuList component
// Instead, we want to render an anchor tag so that we get the right native browser link behaviours,
// but make it appear like a menuitem for the accessibility tree
return ((0, jsx_runtime_1.jsxs)(Link, { "aria-disabled": undefined, role: "menuItem", "aria-label": label, href: path, "aria-current": isActive ? "page" : undefined, onClick: onClick, tabIndex: -1, className: classes, ref: combinedRef, disableImplicitEventTracking: disableImplicitEventTracking, ...other, children: [icon && (0, jsx_runtime_1.jsx)("div", { className: iconStyles, children: icon }), (0, jsx_runtime_1.jsxs)("div", { className: textContainerStyles, children: [label, shortDescription && (0, jsx_runtime_1.jsx)("span", { className: descriptionStyles, children: shortDescription })] }), children] }));
});
LinkWrapper.displayName = "LinkWrapper";
const menuItemLinkStyles = (0, css_1.cx)(menuItemStyles_1.menuItemStyles, (0, css_1.css)({
[`&.${menuItemStyles_1.menuItemClasses.root}`]: {
display: "flex",
alignItems: "center",
"&:hover": {
color: "inherit",
},
"&[aria-current=page]": {
color: design_system_tokens_1.themeTokens.color.text.selected,
},
},
}));
const compactStyles = (0, css_1.css)({
[`&.${menuItemStyles_1.menuItemClasses.root}`]: {
minHeight: "auto",
},
});
const defaultSizeStyles = (0, css_1.css)({
[`&.${menuItemStyles_1.menuItemClasses.root}`]: {
minHeight: design_system_tokens_1.space[48],
},
});
const spaciousStyles = (0, css_1.css)({
[`&.${menuItemStyles_1.menuItemClasses.root}`]: {
minHeight: design_system_tokens_1.space[64],
paddingTop: design_system_tokens_1.space[12],
paddingBottom: design_system_tokens_1.space[12],
},
});
const iconStyles = (0, css_1.css)({
paddingRight: design_system_tokens_1.space[8],
});
const textContainerStyles = (0, css_1.css)({
display: "flex",
flexDirection: "column",
});
const descriptionStyles = (0, css_1.css)({
font: design_system_tokens_1.text.body.regular.small,
color: design_system_tokens_1.themeTokens.color.text.secondary,
});