@navinc/base-react-components
Version:
Nav's Pattern Library
152 lines (150 loc) • 6.37 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import propTypes from 'prop-types';
import styled from 'styled-components';
import Copy from './copy';
import Icon from './icon.js';
import Link from './link.js';
import CDNIllustration from './cdn-illustration.js';
const styles = {
missingInfoAction: {
primaryColor: 'paleGold500',
secondaryColor: 'paleGold100',
defaultIcon: 'system/search',
defultActionIcon: 'actions/carrot-right',
},
improveAction: {
primaryColor: 'rose500',
secondaryColor: 'rose100',
defaultIcon: 'actions/circle-info',
defultActionIcon: 'actions/carrot-right',
},
positiveAction: {
primaryColor: 'greenSheen500',
secondaryColor: 'greenSheen100',
defaultIcon: 'feedback/thumbs-up',
defultActionIcon: 'actions/carrot-right',
},
neutralAction: {
primaryColor: 'lightBlue400',
secondaryColor: 'lightBlue100',
defaultIcon: 'actions/circle-info',
defultActionIcon: 'actions/carrot-right',
},
warning: {
primaryColor: 'tuscan200',
secondaryColor: 'tuscan100',
defaultIcon: 'actions/circle-warning',
defultActionIcon: 'actions/close',
},
error: {
primaryColor: 'copperRed200',
secondaryColor: 'copperRed100',
defaultIcon: 'actions/circle-warning',
defultActionIcon: 'actions/close',
},
};
export const StyledBanner = styled.aside `
box-shadow: 0 10px 11px -8px rgba(0, 0, 0, 0.12);
position: relative;
display: grid;
grid-template-rows: auto 1fr;
text-align: center;
padding: 16px;
border-radius: 12px;
overflow: hidden;
background-color: ${({ currentStyles, theme }) => theme[currentStyles.secondaryColor]};
cursor: ${({ hasLabel, onDismiss, hasAction }) => hasAction && !hasLabel && !onDismiss && 'pointer'};
&::before {
${({ currentStyles, shouldHideBorder, theme }) => !shouldHideBorder &&
`content: '';
width: 100%;
height: 8px;
position: absolute;
left: 0;
top: 0;
background: ${theme[currentStyles.primaryColor]};
border-radius: 14px 14px 0 0;`}
}
@media (${({ theme }) => theme.forLargerThanPhone}) {
grid-template-rows: auto;
grid-template-columns: auto 1fr;
padding-right: ${({ hasLabel }) => !hasLabel && '64px'};
text-align: left;
}
`;
export const StyledBannerAsLink = styled(StyledBanner).attrs(() => ({
as: 'a',
})) `
text-decoration: none;
`;
const BannerContainer = ({ currentStyles, action = () => { }, actionHref, hasLabel, children, className, shouldHideBorder, 'data-testid': dataTestId, }) => {
const sharedProps = {
className,
currentStyles,
hasLabel,
shouldHideBorder,
'data-testid': dataTestId,
};
if (!hasLabel) {
return actionHref ? (_jsx(StyledBannerAsLink, Object.assign({}, sharedProps, { href: actionHref }, { children: children }), void 0)) : (_jsx(StyledBanner, Object.assign({}, sharedProps, { onClick: action }, { children: children }), void 0));
}
else
return _jsx(StyledBanner, Object.assign({}, sharedProps, { children: children }), void 0);
};
export const TitleCopy = styled(Copy) `
@media (${({ theme }) => theme.forLargerThanPhone}) {
margin-right: 28px; /* need to give space for the (X) */
}
`;
const IconContainer = styled.div `
flex: 0 0 24px;
height: auto;
@media (${({ theme }) => theme.forLargerThanPhone}) {
margin-right: 16px;
}
`;
const Content = styled.div `
flex: 1 1 auto;
& > ${Copy}, & > ${Link} {
flex: 1 1 100%;
}
`;
export const ActionIcon = styled(Icon) `
cursor: pointer;
position: absolute;
right: 16px;
top: 16px;
width: auto;
height: 24px;
color: ${({ theme, defaultcolor = theme.neutral500, name }) => (name === 'close' ? theme.neutral500 : defaultcolor)};
`;
const ChildrenWrapper = styled.div `
width: '100%';
`;
const StyledIcon = styled(Icon) `
color: ${({ theme, color }) => theme[color]};
`;
export const Banner = ({ action, actionHref, actionLabel, actionIcon, actionTarget = '', actionTrackingContext = {}, children, className, copy, expandedStyles = {}, icon, onDismiss, shouldHideBorder, CDNIllustrationIcon, title, type = 'neutralAction', }) => {
var _a;
const hasLabel = !!actionLabel;
const hasAction = !!action || !!actionHref;
const currentStyles = (_a = Object.assign(Object.assign({}, styles), expandedStyles)[type]) !== null && _a !== void 0 ? _a : styles.neutralAction;
const { primaryColor, defaultIcon, defultActionIcon } = currentStyles;
return (_jsxs(BannerContainer, Object.assign({ currentStyles: currentStyles, action: action, actionHref: actionHref, hasLabel: hasLabel, shouldHideBorder: shouldHideBorder, onDismiss: onDismiss, className: className, "data-testid": `banner:${type}` }, { children: [_jsx(IconContainer, { children: CDNIllustrationIcon ? (_jsx(CDNIllustration, { filename: CDNIllustrationIcon }, void 0)) : (_jsx(StyledIcon, { name: icon || defaultIcon, color: primaryColor, "data-testid": "banner-icon" }, void 0)) }, void 0), _jsxs(Content, { children: [title && _jsx(TitleCopy, Object.assign({ bold: true }, { children: title }), void 0), copy && _jsx(Copy, { children: copy }, void 0), !!children && _jsx(ChildrenWrapper, { children: children }, void 0), hasLabel && hasAction && (_jsx(Link, Object.assign({ bold: true, href: actionHref, onClick: action, target: actionTarget, trackingContext: actionTrackingContext }, { children: actionLabel }), void 0))] }, void 0), !onDismiss && !hasLabel && hasAction && (_jsx(ActionIcon, { name: actionIcon || defultActionIcon, defaultcolor: primaryColor, "data-testid": "action-icon" }, void 0)), onDismiss && _jsx(ActionIcon, { onClick: onDismiss, "data-testid": "banner-dismiss", name: "actions/close" }, void 0)] }), void 0));
};
Banner.propTypes = {
action: propTypes.func,
actionHref: propTypes.string,
actionLabel: propTypes.node,
type: propTypes.string,
icon: propTypes.string,
actionIcon: propTypes.string,
title: propTypes.node,
copy: propTypes.node,
onDismiss: propTypes.func,
expandedStyles: propTypes.object,
shouldHideBorder: propTypes.bool,
};
const StyledBannerExp = styled(Banner) ``;
export default StyledBannerExp;
//# sourceMappingURL=banner.js.map