@navinc/base-react-components
Version:
Nav's Pattern Library
211 lines (210 loc) • 10.1 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { Component } from 'react';
import styled from 'styled-components';
import debounce from 'lodash.debounce';
import propTypes from 'prop-types';
import { Button } from '../../button.js';
import { Copy } from '../../copy.js';
import { Header } from '../../header.js';
import { KebabMenu } from './parts/kebab-menu.js';
const depricationWarning = (isInUse, warning) => {
isInUse && console.warn(warning);
};
/* Marks the bottom of the card's content. */
const WayMark = styled.hr.withConfig({ displayName: "brc-sc-WayMark", componentId: "brc-sc-1mybk47" }) `
border: none;
margin: 0;
height: 0;
`;
WayMark.displayName = 'WayMark';
const CARD_BODY_PADDING_BOTTOM = 32;
// eslint-disable-next-line import/no-unused-modules -- imported by a TS file. no-unused-modules is not detecting for some reason.
export const CardHeader = styled(Copy).attrs(() => ({ size: 'sm' })).withConfig({ displayName: "brc-sc-CardHeader", componentId: "brc-sc-1g3db6f" }) `
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
min-height: 24px;
padding-bottom: 16px;
color: ${({ theme }) => theme.neutral400};
`;
CardHeader.displayName = 'CardHeader';
// eslint-disable-next-line import/no-unused-modules -- imported by a TS file. no-unused-modules is not detecting for some reason.
export const Title = styled(Header).attrs(() => ({ size: 'md' })).withConfig({ displayName: "brc-sc-Title", componentId: "brc-sc-f96nx6" }) `
padding-bottom: 16px;
`;
Title.displayName = 'Title';
// eslint-disable-next-line import/no-unused-modules -- imported by a TS file. no-unused-modules is not detecting for some reason.
export const CardBody = styled.div.withConfig({ displayName: "brc-sc-CardBody", componentId: "brc-sc-1nb3yec" }) `
position: relative; /* required to get offsetTop of Waymark from Card */
padding-bottom: ${CARD_BODY_PADDING_BOTTOM}px;
${({ height, shouldNotAnimate }) => shouldNotAnimate ? '' : 'transition: height 250ms ease-in-out;' + `height: ${height}px;`}
overflow: hidden;
${Copy} {
max-width: 520px;
}
`;
CardBody.displayName = 'CardBody';
const StyledCard = styled.div.withConfig({ displayName: "brc-sc-StyledCard", componentId: "brc-sc-pqvnml" }) `
position: relative;
flex: 1 1 100%;
padding: 24px;
border-radius: 4px;
background-color: ${({ theme }) => theme.white};
overflow: hidden;
box-shadow:
0 0 3px 0 ${({ theme }) => theme.neutral300},
0 1px 2px 0 ${({ theme }) => theme.neutral300};
${({ isCardHidden, theme }) => isCardHidden &&
`
& > ${CardHeader} {
border-top: 4px solid ${theme.good};
}
`};
`;
StyledCard.displayName = 'StyledCard';
const CloseIcon = styled.img.withConfig({ displayName: "brc-sc-CloseIcon", componentId: "brc-sc-1158fbm" }) `
padding-left: 8px;
`;
CloseIcon.displayName = 'CloseIcon';
const CheckMark = styled.img.withConfig({ displayName: "brc-sc-CheckMark", componentId: "brc-sc-hullcb" }) `
padding-right: 8px;
`;
CheckMark.displayName = 'CheckMark';
const DismissCard = styled.div.withConfig({ displayName: "brc-sc-DismissCard", componentId: "brc-sc-74ktuf" }) `
position: absolute;
right: 8px;
display: inline-block;
height: 100%;
padding: 16px;
border-left: 2px solid ${({ theme }) => theme.neutral300};
cursor: pointer;
`;
DismissCard.displayName = 'DismissCard';
const Undo = styled(Copy).withConfig({ displayName: "brc-sc-Undo", componentId: "brc-sc-1xe53pa" }) `
cursor: pointer;
font-weight: bold;
margin-right: 64px;
`;
Undo.displayName = 'Undo';
const BackButton = styled(Button).withConfig({ displayName: "brc-sc-BackButton", componentId: "brc-sc-1w1q2nw" }) `
padding: 8px;
margin-right: auto;
`;
BackButton.displayName = 'BackButton';
// eslint-disable-next-line import/no-unused-modules -- imported by a TS file. no-unused-modules is not detecting for some reason.
export const NextButton = styled(Button).withConfig({ displayName: "brc-sc-NextButton", componentId: "brc-sc-175zu7w" }) `
&[disabled] {
background-color: unset;
border-color: transparent;
color: ${({ theme }) => theme.neutral400};
cursor: default;
}
`;
NextButton.displayName = 'NextButton';
const Kebab = styled.img.attrs(() => ({
src: 'https://dxkdvuv3hanyu.cloudfront.net/design-assets/icons/kebab-menu.svg',
})).withConfig({ displayName: "brc-sc-Kebab", componentId: "brc-sc-15rz6dx" }) `
position: absolute;
top: 16px;
right: 8px;
padding: 8px;
cursor: pointer;
`;
Kebab.displayName = 'Kebab';
const Footer = styled.div.withConfig({ displayName: "brc-sc-Footer", componentId: "brc-sc-1vr9y3j" }) `
display: flex;
align-items: center;
justify-content: flex-end;
padding-top: 16px;
border-top: 1px solid ${({ theme }) => theme.neutral300};
`;
Footer.displayName = 'Footer';
class _Card extends Component {
constructor() {
super(...arguments);
this.state = {
isKebabMenuVisible: false,
isCardHidden: false,
isCardDismissed: false,
contentHeight: 0,
};
this.toggleKebabMenu = (event) => {
event.stopPropagation();
this._mounted && this.setState({ isKebabMenuVisible: !this.state.isKebabMenuVisible });
};
this.togglehideCard = (event) => {
event.stopPropagation();
if (this.state.isKebabMenuVisible) {
this.toggleKebabMenu(event);
}
this._mounted && this.setState(({ isCardHidden }) => ({ isCardHidden: !isCardHidden }));
};
this.dismissCard = (_event) => {
this._mounted && this.setState(() => ({ isCardDismissed: true }));
};
this.setRef = (name) => (ref) => {
this[name] = ref;
};
this.setHeight = debounce(() => {
if (this._mounted && !this.props.shouldNotAnimate) {
this.setState(() => {
var _a, _b;
return ({
contentHeight: ((_b = (_a = this.wayMark) === null || _a === void 0 ? void 0 : _a.offsetTop) !== null && _b !== void 0 ? _b : 0) + CARD_BODY_PADDING_BOTTOM,
});
});
}
}, 250, { leading: true });
}
render() {
const { buttonCopy, buttonLabel = buttonCopy, children, className, labelCopy, cardLabel = labelCopy, hasAsyncNextButton, isLoading, onBack, onNext, onHide = () => { }, onToggleKebab = () => { }, titleCopy, title = titleCopy, buttonDisabled, buttonForm, kebabMenuItems = [], hasFooter = !!(onNext || onBack || buttonForm), shouldNotAnimate, } = this.props;
const { isKebabMenuVisible, isCardHidden, isCardDismissed } = this.state;
if (isCardDismissed)
return null;
return (_jsxs(StyledCard, { className: className, isCardHidden: isCardHidden, children: [cardLabel && _jsx(CardHeader, { children: cardLabel }), !!kebabMenuItems.length && (_jsx(Kebab, { "data-testid": "deprecated-card:kebab", onClick: (event) => {
this.toggleKebabMenu(event);
onToggleKebab(event);
} })), isKebabMenuVisible && (_jsx(KebabMenu, { kebabMenuItems: kebabMenuItems, onHide: onHide, togglehideCard: this.togglehideCard, toggleKebabMenu: this.toggleKebabMenu })), title && _jsx(Title, { children: title }), _jsxs(CardBody, { height: this.state.contentHeight, shouldNotAnimate: shouldNotAnimate, children: [children, _jsx(WayMark, { ref: this.setRef('wayMark') })] }), hasFooter && (_jsxs(Footer, { children: [onBack && (_jsx(BackButton, { onClick: onBack, variation: "noOutline", children: _jsx("img", { src: "https://dxkdvuv3hanyu.cloudfront.net/icons/card_back_arrow.svg", alt: "back arrow" }) })), !hasAsyncNextButton && onNext && (_jsx(NextButton, { isLoading: isLoading, onClick: onNext, size: "cardButton", variation: "noOutline", disabled: buttonDisabled, form: buttonForm, children: buttonLabel })), hasAsyncNextButton && onNext && (_jsx(Button, { isLoading: isLoading, onClick: onNext, children: buttonLabel }))] }))] }));
}
componentDidMount() {
this._mounted = true;
this.setHeight();
window.addEventListener('resize', this.setHeight);
depricationWarning(this.props.buttonCopy, 'The `buttonCopy` property on the `Card` component has been depricated and renamed to `buttonLabel`');
depricationWarning(this.props.titleCopy, 'The `titleCopy` property on the `Card` component has been depricated and renamed to `title`');
depricationWarning(this.props.controlledHeight, 'The `controlledHeight` property on the `Card` component has been depricated. All card components have a transition animation when heights change. The consumer of the Card component does not need to set explicit heights.');
depricationWarning(this.props.labelCopy, 'The `labelCopy` property on the `Card` component has been depricated and renamed `cardLabel`.');
}
componentDidUpdate() {
var _a, _b;
if (this.state.contentHeight !== ((_b = (_a = this.wayMark) === null || _a === void 0 ? void 0 : _a.offsetTop) !== null && _b !== void 0 ? _b : 0)) {
this.setHeight();
}
}
componentWillUnmount() {
this._mounted = false;
window.removeEventListener('resize', this.setHeight);
}
}
_Card.propTypes = {
buttonCopy: propTypes.string,
children: propTypes.node,
className: propTypes.string,
hasFooter: propTypes.bool,
labelCopy: propTypes.string,
onBack: propTypes.func,
onDismiss: propTypes.func,
onNext: propTypes.func,
onHide: propTypes.func,
onToggleKebab: propTypes.func,
onUndo: propTypes.func,
titleCopy: propTypes.string,
buttonDisabled: propTypes.bool,
buttonForm: propTypes.string,
controlledHeight: propTypes.bool,
kebabMenuItems: propTypes.array,
shouldNotAnimate: propTypes.bool,
};
export const Card = styled(_Card).withConfig({ displayName: "brc-sc-Card", componentId: "brc-sc-10oqygk" }) ``;
//# sourceMappingURL=index.js.map