Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert deprecated React components from previous release #913

Merged
merged 6 commits into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@department-of-veterans-affairs/component-library",
"description": "VA.gov component library. Includes React and web components.",
"version": "25.0.0",
"version": "26.0.0",
Copy link
Contributor Author

@jamigibbs jamigibbs Oct 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updating core because I will be creating a release after it is merged.

"license": "MIT",
"scripts": {
"build": "webpack"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,12 +330,15 @@ <h1><a href="index.html">All files</a> write-react-owners-to-csv.js</h1>
const today = require('./today');
&nbsp;
const componentsToKeep = [
'AlertBox',
'Checkbox',
'ExpandingGroup',
'IconSearch',
'LoadingIndicator',
'TextInput',
];
&nbsp;
const hasMigrationScript = [];
const hasMigrationScript = ['AlertBox', 'LoadingIndicator'];
&nbsp;
function cleanPath(pathToClean) {
const cwd = process.cwd();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ const today = require('./today');
const componentsToKeep = [
'AlertBox',
'Breadcrumbs',
'Checkbox',
'ExpandingGroup',
'IconSearch',
'LoadingIndicator',
'Modal',
'OMBInfo',
'TextInput',
];

const hasMigrationScript = ['AlertBox'];
const hasMigrationScript = ['AlertBox', 'LoadingIndicator'];

function cleanPath(pathToClean) {
const cwd = process.cwd();
Expand Down
11 changes: 11 additions & 0 deletions packages/react-components/index.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
import AlertBox, { ALERT_TYPE } from './AlertBox';
import Breadcrumbs from './Breadcrumbs';
import Checkbox from './Checkbox';
import ExpandingGroup from './ExpandingGroup';
import IconBase from './IconBase';
import IconSearch from './IconSearch';
import LoadingIndicator from './LoadingIndicator';
import MaintenanceBanner from './MaintenanceBanner';
import Modal from './Modal';
import OMBInfo from './OMBInfo';
import TextInput from './TextInput';

import './i18n-setup';

export {
AlertBox,
ALERT_TYPE,
Breadcrumbs,
Checkbox,
ExpandingGroup,
IconBase,
IconSearch,
LoadingIndicator,
MaintenanceBanner,
Modal,
OMBInfo,
TextInput,
};
2 changes: 1 addition & 1 deletion packages/react-components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@department-of-veterans-affairs/react-components",
"version": "21.0.0",
"version": "22.0.0",
"description": "VA.gov component library in React",
"keywords": [
"react",
Expand Down
203 changes: 203 additions & 0 deletions packages/react-components/src/components/AlertBox/AlertBox.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import classNames from 'classnames';
import dispatchAnalyticsEvent from '../../helpers/analytics';

// Enum used to set the AlertBox's `status` prop
export const ALERT_TYPE = Object.freeze({
INFO: 'info', // Blue border, black circled 'i'
ERROR: 'error', // Red border, red circled exclamation
SUCCESS: 'success', // Green border, green checkmark
WARNING: 'warning', // Yellow border, black triangle exclamation
CONTINUE: 'continue', // Green border, green lock
});

/**
* This component is no longer supported, please use `<va-alert>` instead.
*/
class AlertBox extends Component {
constructor(props) {
super(props);
this.handleAlertBodyClick = this.handleAlertBodyClick.bind(this);
}

componentDidMount() {
this.scrollToAlert();
}

componentWillUnmount() {
clearTimeout(this.scrollToAlertTimeout);
}

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() {
this.scrollToAlert();
}

scrollToAlert = () => {
if (!this._ref || !this._ref.scrollIntoView) {
return;
}

// Without using the setTimeout, React has not added the element
// to the DOM when it calls scrollIntoView()
if (this.props.isVisible && this.props.scrollOnShow) {
clearTimeout(this.scrollToAlertTimeout);
this.scrollToAlertTimeout = setTimeout(() => {
this._ref.scrollIntoView({
block: this.props.scrollPosition,
behavior: 'smooth',
});
}, 0);
}
};

handleAlertBodyClick(e) {
if (!this.props.disableAnalytics) {
// If it's a link being clicked, dispatch an analytics event
if (e.target?.tagName === 'A') {
dispatchAnalyticsEvent({
componentName: 'AlertBox',
action: 'linkClick',
details: {
clickLabel: e.target.innerText,
headline: this.props.headline,
status: this.props.status,
backgroundOnly: this.props.backgroundOnly,
closeable: !!this.props.onCloseAlert,
},
});
}
}
}

render() {
if (!this.props.isVisible) return <div aria-live="polite" />;

const alertClass = classNames(
'usa-alert',
`usa-alert-${this.props.status}`,
{ 'background-color-only': this.props.backgroundOnly },
this.props.className,
);

const closeButton = this.props.onCloseAlert && (
<button
className="va-alert-close"
aria-label={this.props.closeBtnAriaLabel}
onClick={this.props.onCloseAlert}
>
<i className="fas fa-times-circle" aria-label="Close icon" />
</button>
);

const alertHeading = this.props.headline;
const alertText = this.props.content || this.props.children;
const H = `h${this.props.level}`;

return (
<div
className={alertClass}
ref={ref => {
this._ref = ref;
}}
>
<div className="usa-alert-body" onClick={this.handleAlertBodyClick}>
{alertHeading && <H className="usa-alert-heading">{alertHeading}</H>}
{alertText && <div className="usa-alert-text">{alertText}</div>}
</div>
{closeButton}
</div>
);
}
}

/* eslint-disable consistent-return */
AlertBox.propTypes = {
/**
* Determines the color and icon of the alert box.
*/
status: PropTypes.oneOf(Object.values(ALERT_TYPE)).isRequired,

/**
* Show or hide the alert. Useful for alerts triggered by app interaction.
*/
isVisible: PropTypes.bool,
/**
* Child elements (content)
*/
children: PropTypes.node,
/**
* Body content of the alert, which can also be passed via children.
*/
content: PropTypes.node,

/**
* Optional headline.
*/
headline: PropTypes.node,

/**
* Optional Close button aria-label.
*/
closeBtnAriaLabel: PropTypes.string,

/**
* Close event handler if the alert can be dismissed or closed.
*/
onCloseAlert: PropTypes.func,

/**
* If true, page scrolls to alert when it is shown.
*/
scrollOnShow: PropTypes.bool,

/**
* Defaults to 'start' but customizable.
*/
scrollPosition: PropTypes.string,

/**
* Optional class name to add to the alert box.
*/
className: PropTypes.string,

/**
* If true, renders an AlertBox with only a background color, without an
* accented left edge or an icon
*/
backgroundOnly: PropTypes.bool,

/**
* The header level to use with the headline prop, must be a number 1-6
*/
level(props, propName) {
const level = parseInt(props[propName], 10);
if (Number.isNaN(level) || level < 1 || level > 6) {
return new Error(
`Invalid prop: AlertBox level must be a number from 1-6, was passed ${props[propName]}`,
);
}
},
/**
* Analytics tracking function(s) will not be called
*/
disableAnalytics: PropTypes.bool,
};
/* eslint-enable consistent-return */

AlertBox.defaultProps = {
scrollPosition: 'start',
isVisible: true,
backgroundOnly: false,
closeBtnAriaLabel: 'Close notification',
level: 3,
};

export default AlertBox;
102 changes: 102 additions & 0 deletions packages/react-components/src/components/AlertBox/AlertBox.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
title: AlertBox
name: AlertBox
tags: informational, warning, error, success, continue, dismissable
---

import AlertBox, { ALERT_TYPE } from './AlertBox'


### Code:
```javascript
import AlertBox, { ALERT_TYPE } from '@department-of-veterans-affairs/component-library/AlertBox'

<div className="usa-width-one-whole">
<AlertBox
headline='Informational 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={ALERT_TYPE.INFO}
isVisible/>
<AlertBox
headline="Warning 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={ALERT_TYPE.WARNING} />
<AlertBox
headline="Error 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={ALERT_TYPE.ERROR} />
<AlertBox
headline="Success 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={ALERT_TYPE.SUCCESS} />
<AlertBox
headline="Continue 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={ALERT_TYPE.CONTINUE} />
<AlertBox
headline="Dismissable 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={ALERT_TYPE.INFO}
isVisible
onCloseAlert={() => {}}/>
<AlertBox
headline="Hidden 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={ALERT_TYPE.INFO}
isVisible={false}/>
<AlertBox
content={<p>Content without heading.</p>}
status={ALERT_TYPE.INFO}/>
<AlertBox
headline="Informational backgroundOnly 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={ALERT_TYPE.INFO}
backgroundOnly />
</div>
```

### Rendered Component
<div className="site-c-reactcomp__rendered">
<div>
<AlertBox
headline="Informational 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={ALERT_TYPE.INFO}
isVisible/>
<AlertBox
headline="Warning 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={ALERT_TYPE.WARNING} />
<AlertBox
headline="Error 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={ALERT_TYPE.ERROR} />
<AlertBox
headline="Success 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={ALERT_TYPE.SUCCESS} />
<AlertBox
headline="Continue 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={ALERT_TYPE.CONTINUE} />
<AlertBox
headline="Dismissable 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={ALERT_TYPE.INFO}
isVisible
onCloseAlert={() => {}}/>
<AlertBox
headline="Hidden 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={ALERT_TYPE.INFO}
isVisible={false}/>
<AlertBox
content={<p>Content without heading.</p>}
status={ALERT_TYPE.INFO}/>
<AlertBox
headline="Background Only 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={ALERT_TYPE.INFO}
backgroundOnly />
</div>
</div>
Loading
Loading