UNPKG

@octopusdeploy/design-system-components

Version:
77 lines (76 loc) 4.6 kB
"use strict"; 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, });