UNPKG

@navinc/base-react-components

Version:
124 lines (120 loc) 6.82 kB
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; }; import { jsx as _jsx } from "react/jsx-runtime"; // @ts-expect-error -- mui doesn't support ESM import muiTooltipPkg, { tooltipClasses } from '@mui/material/node/Tooltip/index.js'; import { styled, css, useTheme } from 'styled-components'; import { IconButton } from './icon-button.js'; import { useIsLargerThanPhone } from './use-media-query.js'; import { useState } from 'react'; import { interopDefault } from '@navinc/utils'; const MuiTooltip = interopDefault(muiTooltipPkg); const getDarkText = (theme) => theme.inverseSurface; const getDarkBackground = (theme) => theme.inverseSurface; const getLightText = (theme) => theme.inverseOnSurface; const getLightBackground = (theme) => theme.inverseOnSurface; const InternalTooltip = (_a) => { var { title, children, maxWidth, minWidth, navTheme, isDark = false } = _a, props = __rest(_a, ["title", "children", "maxWidth", "minWidth", "navTheme", "isDark"]); return (_jsx(MuiTooltip, Object.assign({}, props, { title: _jsx("span", { "data-testid": "tooltip:content", children: title }), componentsProps: { tooltip: { sx: { color: () => (isDark ? getLightText(navTheme) : getDarkText(navTheme)), fontSize: '14px', lineHeight: '1.5', backgroundColor: () => (isDark ? getDarkBackground(navTheme) : getLightBackground(navTheme)), filter: () => `drop-shadow(1px 2px 4px ${navTheme.navNeutral300})`, minWidth: () => `${minWidth || '198px'}`, maxWidth: () => `${maxWidth || '300px'}`, padding: '12px 16px', '& p[class^="Copy"]': { color: () => (isDark ? getLightText(navTheme) : getDarkText(navTheme)), }, [`& .${tooltipClasses.arrow}`]: { color: () => (isDark ? 'black' : 'white'), fontSize: '16px', }, }, }, }, children: children }))); }; const heightWidth = ({ size }) => css ` height: ${size}; width: ${size}; `; // Necessary rules on the parent of target element in order for tooltip to position correctly, vertically. const StyledTooltipTarget = styled.span.withConfig({ displayName: "brc-sc-StyledTooltipTarget", componentId: "brc-sc-lgh686" }) ` display: inline-block; height: 100%; `; /** @deprecated use the wayfinder tooltip from @navinc/base-react-components/wayfinder instead */ export const TooltipTargetIcon = styled(IconButton).withConfig({ displayName: "brc-sc-TooltipTargetIcon", componentId: "brc-sc-1dhk5t0" }) ` color: ${({ theme }) => theme.onSurface}; border: none; ${heightWidth} :hover { color: ${({ theme }) => theme.onSurface}; } &:focus { border-radius: 2px; outline: none; box-shadow: ${({ theme }) => `0 0 0 2px ${theme.outlineVariant}`}; } `; const Wrapper = styled.span.withConfig({ displayName: "brc-sc-Wrapper", componentId: "brc-sc-ib3m0" }) ` ${heightWidth} `; /* <span data-testid="tooltip:target">: MuiTooltip requires a wrapper element before the target element, in this case the IconButton or 'target' component. It will add props specific to that wrapper element. We use only <span> here because tooltip is commonly used between <p> tags. */ const UnstyledTooltip = (_a) => { var { className, children, iconName = 'actions/circle-info', target, 'data-testid': dataTestId = '', arrow = true, isDark = false, placement, size } = _a, props = __rest(_a, ["className", "children", "iconName", "target", 'data-testid', "arrow", "isDark", "placement", "size"]); const navTheme = useTheme(); const isDesktop = useIsLargerThanPhone(); const wrapperSize = size || '24px'; return (_jsx(Wrapper, { className: className, "data-testid": dataTestId ? `tooltip ${dataTestId}` : 'tooltip', size: !target ? wrapperSize : undefined, children: _jsx(InternalTooltip, Object.assign({ arrow: arrow, isDark: isDark }, props, { navTheme: navTheme, placement: placement || (isDesktop ? 'right' : 'top'), title: children, children: size ? (_jsx("span", { "data-testid": "tooltip:target", children: target || _jsx(TooltipTargetIcon, { name: iconName, size: size, type: "button" }) })) : (_jsx(StyledTooltipTarget, { "data-testid": "tooltip:target", children: target || _jsx(TooltipTargetIcon, { name: iconName, type: "button" }) })) })) })); }; /** * @deprecated use the wayfinder tooltip from @navinc/base-react-components/wayfinder instead This is an **uncontrolled** tooltip by default. It will render a _right_ tooltip for desktop and a _top_ tooltip for mobile. The tooltip will try its best to render in a different placement if it does not fit on the screen, regardless of the `placement` prop. NOTE: You may need to press the storybook 'remount component' button after changing props in order to rerender Tooltip with updated props. **/ export const Tooltip = styled(UnstyledTooltip).withConfig({ displayName: "brc-sc-Tooltip", componentId: "brc-sc-1tl5qa1" }) ``; /** * @example * ``` * const ClickableTooltip = createClickableTooltip(Button, { placement: 'bottom', isDark: true }) * * <ClickableTooltip tooltip="This is my tooltip content" onClick={() => console.log('clicked')}>Click to open a tooltip</ClickableTooltip> * ``` * * @deprecated use the wayfinder tooltip from @navinc/base-react-components/wayfinder instead */ export const createClickableTooltip = (Component, tooltipProps = {}) => (_a) => { var { tooltip } = _a, props = __rest(_a, ["tooltip"]); const [isOpen, setIsOpen] = useState(false); if (!tooltip) { return _jsx(Component, Object.assign({}, props)); } return (_jsx(Tooltip, Object.assign({}, tooltipProps, { target: _jsx(Component, Object.assign({}, props, { onClick: (...args) => { var _a; setIsOpen((tmpIsOpen) => !tmpIsOpen); (_a = props.onClick) === null || _a === void 0 ? void 0 : _a.call(props, ...args); }, onBlur: (...args) => { var _a; setIsOpen(false); (_a = props.onBlur) === null || _a === void 0 ? void 0 : _a.call(props, ...args); } })), open: isOpen, children: tooltip }))); }; //# sourceMappingURL=tooltip.js.map