There are no notes for this item.
Prop | Required? | Type | Default | Description |
---|---|---|---|---|
headline | No | node | ||
content | Yes | node | ||
isVisible | Yes | bool | ||
onCloseAlert | No | func | ||
scrollOnShow | No | bool | ||
status | Yes | enum |
<div id="reactMount" data-tpl="alertbox">
<div aria-live="polite" class="usa-alert usa-alert-warning">
<div class="usa-alert-body">
<div class="usa-alert-heading">Default alert</div>
<div class="usa-alert-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam id felis pulvinar ligula ultricies sollicitudin eget nec dui. Cras augue velit, pellentesque sit amet nisl ut, tristique suscipit sem. Cras sollicitudin auctor mattis.</div>
</div>
<div class="cf"></div>
</div>
</div>
<script>
window.currentProps = {
"package": {
"name": "department-of-veteran-affairs/jean-pants",
"version": "0.1.0"
},
"assetPath": "/design-system/",
"isProduction": true,
"componentSourcePath": "./AlertBox.jsx",
"headline": "Default alert",
"content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam id felis pulvinar ligula ultricies sollicitudin eget nec dui. Cras augue velit, pellentesque sit amet nisl ut, tristique suscipit sem. Cras sollicitudin auctor mattis.",
"status": "warning",
"isVisible": true
}
</script>
import React from 'react';
import AlertBox from './AlertBox';
export default function AlertBoxExample(props) {
return (
<AlertBox
headline={props.headline}
content={props.content}
status={props.status}
isVisible={props.isVisible}/>
);
}
package:
name: department-of-veteran-affairs/jean-pants
version: 0.1.0
assetPath: /design-system/
isProduction: true
componentSourcePath: ./AlertBox.jsx
headline: Default alert
content: >-
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam id felis
pulvinar ligula ultricies sollicitudin eget nec dui. Cras augue velit,
pellentesque sit amet nisl ut, tristique suscipit sem. Cras sollicitudin
auctor mattis.
status: warning
isVisible: true
import PropTypes from 'prop-types';
import React from 'react';
import classNames from 'classnames';
class AlertBox extends React.Component {
constructor(props) {
super(props);
this.scrollToAlert = this.scrollToAlert.bind(this);
}
shouldComponentUpdate(nextProps) {
const visibilityChanged = this.props.isVisible !== nextProps.isVisible;
const contentChanged = this.props.content !== nextProps.content;
const statusChanged = this.props.status !== nextProps.status;
return visibilityChanged || contentChanged || statusChanged;
}
componentDidUpdate() {
if (this.props.isVisible && this.props.scrollOnShow) {
this.scrollToAlert();
}
}
scrollToAlert() {
const isInView = window.scrollY <= this._ref.offsetTop;
if (this._ref && !isInView) {
this._ref.scrollIntoView({
block: 'end',
behavior: 'smooth'
});
}
}
render() {
if (!this.props.isVisible) {
return <div aria-live="polite"/>;
}
const alertClass = classNames(
'usa-alert',
`usa-alert-${this.props.status}`
);
let closeButton;
if (this.props.onCloseAlert) {
closeButton = (
<button className="va-alert-close" aria-label="Close notification" onClick={this.props.onCloseAlert}>
<i className="fa fa-close" aria-label="Close icon"></i>
</button>
);
}
const headline = this.props.headline && (<div className="usa-alert-heading">{this.props.headline}</div>);
return (
<div
aria-live="polite"
className={alertClass}
ref={(ref) => { this._ref = ref; }}>
<div className="usa-alert-body">
{headline}
<div className="usa-alert-text">
{this.props.content}
</div>
</div>
{closeButton}
<div className="cf"></div>
</div>
);
}
}
AlertBox.propTypes = {
// optional headline
headline: PropTypes.node,
// body content is required -- this is the bulk of the alert
content: PropTypes.node.isRequired,
// is the alert visible? useful for alerts triggered by app interaction
isVisible: PropTypes.bool.isRequired,
// this is useful if the alerbox can be dismissed or closed
onCloseAlert: PropTypes.func,
// if true, page scrolls to alert
scrollOnShow: PropTypes.bool,
// determines the color of the alert box: blue, red, green, yellow respectively
status: PropTypes.oneOf([
'info',
'error',
'success',
'warning'
]).isRequired
};
export default AlertBox;
import React from 'react';
import { shallow } from 'enzyme';
import { axeCheck } from '../../../../lib/testing/helpers';
import { expect } from 'chai';
import AlertBox from './AlertBox.jsx';
// Placeholder for required "content" element
const Content = (<p/>);
const Headline = 'Headline';
function closeAlert() {
//
}
describe('<AlertBox />', () => {
it('should be an empty div if invisible', () => {
const wrapper = shallow(<AlertBox
content={Content}
status="info"
isVisible={false}/>);
expect(wrapper.html()).to.equal('<div aria-live="polite"></div>');
});
it('should have the expected classname', () => {
const wrapper = shallow(<AlertBox
content={Content}
status="info"
isVisible/>);
expect(wrapper.find('.usa-alert').hasClass('usa-alert-info')).to.equal(true);
});
it('should pass aXe check when visible', () => {
return axeCheck(<AlertBox
content={Content}
status="info"
isVisible/>);
});
it('should pass aXe check when not visible', () => {
return axeCheck(<AlertBox
content={Content}
status="info"
isVisible={false}/>);
});
it('should pass aXe check without a headline', () => {
return axeCheck(<AlertBox
content={Content}
status="info"
isVisible/>);
});
it('should pass aXe check with a headline', () => {
return axeCheck(<AlertBox
headline={Headline}
content={Content}
status="info"
isVisible/>);
});
it('should pass aXe check when it has a close button', () => {
return axeCheck(<AlertBox
headline={Headline}
content={Content}
onCloseAlert={closeAlert()}
status="info"
isVisible/>);
});
});