diff --git a/packages/design-system-dashboard-cli/coverage/lcov-report/write-react-owners-to-csv.js.html b/packages/design-system-dashboard-cli/coverage/lcov-report/write-react-owners-to-csv.js.html
index 7bf63a620..ad96289e8 100644
--- a/packages/design-system-dashboard-cli/coverage/lcov-report/write-react-owners-to-csv.js.html
+++ b/packages/design-system-dashboard-cli/coverage/lcov-report/write-react-owners-to-csv.js.html
@@ -330,14 +330,13 @@
All files write-react-owners-to-csv.js
const today = require('./today');
const componentsToKeep = [
- 'AlertBox',
'ExpandingGroup',
'IconSearch',
'LoadingIndicator',
'TextInput',
];
-const hasMigrationScript = ['AlertBox', 'LoadingIndicator'];
+const hasMigrationScript = ['LoadingIndicator'];
function cleanPath(pathToClean) {
const cwd = process.cwd();
diff --git a/packages/react-components/index.js b/packages/react-components/index.js
index f5ed5bc3b..a3074f667 100644
--- a/packages/react-components/index.js
+++ b/packages/react-components/index.js
@@ -1,24 +1,19 @@
-import AlertBox, { ALERT_TYPE } from './AlertBox';
import Breadcrumbs from './Breadcrumbs';
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 TextInput from './TextInput';
import './i18n-setup';
export {
- AlertBox,
- ALERT_TYPE,
Breadcrumbs,
ExpandingGroup,
IconBase,
IconSearch,
LoadingIndicator,
- MaintenanceBanner,
Modal,
TextInput,
};
diff --git a/packages/react-components/src/components/AlertBox/AlertBox.jsx b/packages/react-components/src/components/AlertBox/AlertBox.jsx
deleted file mode 100644
index b8a91e8e3..000000000
--- a/packages/react-components/src/components/AlertBox/AlertBox.jsx
+++ /dev/null
@@ -1,203 +0,0 @@
-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 `` 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 ;
-
- const alertClass = classNames(
- 'usa-alert',
- `usa-alert-${this.props.status}`,
- { 'background-color-only': this.props.backgroundOnly },
- this.props.className,
- );
-
- const closeButton = this.props.onCloseAlert && (
-
- );
-
- const alertHeading = this.props.headline;
- const alertText = this.props.content || this.props.children;
- const H = `h${this.props.level}`;
-
- return (
- {
- this._ref = ref;
- }}
- >
-
- {alertHeading &&
{alertHeading}}
- {alertText &&
{alertText}
}
-
- {closeButton}
-
- );
- }
-}
-
-/* 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;
diff --git a/packages/react-components/src/components/AlertBox/AlertBox.mdx b/packages/react-components/src/components/AlertBox/AlertBox.mdx
deleted file mode 100644
index 2f2cb1263..000000000
--- a/packages/react-components/src/components/AlertBox/AlertBox.mdx
+++ /dev/null
@@ -1,102 +0,0 @@
----
-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'
-
-
-
-
-
-
-
-
{}}/>
-
- Content without heading.}
- status={ALERT_TYPE.INFO}/>
-
-
-```
-
-### Rendered Component
-
-
-
-
-
-
-
-
{}}/>
-
- Content without heading.}
- status={ALERT_TYPE.INFO}/>
-
-
-
diff --git a/packages/react-components/src/components/AlertBox/AlertBox.unit.spec.jsx b/packages/react-components/src/components/AlertBox/AlertBox.unit.spec.jsx
deleted file mode 100644
index 030ca79b4..000000000
--- a/packages/react-components/src/components/AlertBox/AlertBox.unit.spec.jsx
+++ /dev/null
@@ -1,221 +0,0 @@
-import React from 'react';
-import { shallow, mount } from 'enzyme';
-import { axeCheck } from '../../helpers/test-helpers';
-import { expect } from 'chai';
-import sinon from 'sinon';
-
-import AlertBox from './AlertBox.jsx';
-
-// Placeholder for required "content" element
-const Content = ;
-const Headline = 'Headline';
-const CloseBtnAriaLabelOptional = 'Close notification optional';
-function closeAlert() {
- //
-}
-
-describe('', () => {
- it('should be an empty div if invisible', () => {
- const wrapper = shallow(
- ,
- );
- expect(wrapper.html()).to.equal('');
- wrapper.unmount();
- });
-
- it('should have the expected classnames', () => {
- const wrapper = shallow(
- ,
- );
- expect(wrapper.find('.usa-alert').hasClass('usa-alert-info')).to.equal(
- true,
- );
- expect(
- wrapper.find('.usa-alert').hasClass('background-color-only'),
- ).to.equal(false);
- wrapper.unmount();
- });
-
- it('should have have `background-color-only` class added when `backgroundOnly` is `true`', () => {
- const wrapper = shallow(
- ,
- );
- expect(
- wrapper.find('.usa-alert').hasClass('background-color-only'),
- ).to.equal(true);
- wrapper.unmount();
- });
-
- it('should apply classes set via `className`', () => {
- const wrapper = shallow(
- ,
- );
- expect(wrapper.find('.usa-alert').hasClass('foo')).to.equal(true);
- wrapper.unmount();
- });
-
- it('should use level prop for headline element', () => {
- const wrapper = shallow(
- ,
- );
- expect(wrapper.find('.usa-alert-heading').is('h4')).to.equal(true);
- wrapper.unmount();
- });
-
- it('should pass aXe check when visible', () =>
- axeCheck());
-
- it('should pass aXe check when not visible', () =>
- axeCheck());
-
- it('should pass aXe check without a headline', () =>
- axeCheck());
-
- it('should pass aXe check with a headline', () =>
- axeCheck(
- ,
- ));
-
- it('should pass aXe check when it has a close button', () =>
- axeCheck(
- ,
- ));
-
- it('should pass aXe check when it has a close button with optional aria-label', () =>
- axeCheck(
- ,
- ));
-
- it('should pass aXe check when `backgroundOnly` is `true`', () =>
- axeCheck(
- ,
- ));
-
- describe('analytics event', function () {
- let wrapper;
-
- const HeadlineWithLink = (
- <>
- Headline with a link
- >
- );
-
- beforeEach(() => {
- wrapper = mount(
-
-
- ,
- );
- });
-
- afterEach(() => {
- wrapper.unmount();
- });
-
- it('should be triggered when link in AlertBox content is clicked', () => {
- const handleAnalyticsEvent = sinon.spy();
-
- global.document.body.addEventListener(
- 'component-library-analytics',
- handleAnalyticsEvent,
- );
-
- // Click link in content
- const testLink = wrapper.find('.usa-alert-text a');
- testLink.simulate('click');
-
- global.document.body.removeEventListener(
- 'component-library-analytics',
- handleAnalyticsEvent,
- );
-
- expect(
- handleAnalyticsEvent.calledWith(
- sinon.match.has('detail', {
- componentName: 'AlertBox',
- action: 'linkClick',
- details: {
- clickLabel: 'with a link',
- headline: HeadlineWithLink,
- status: 'info',
- backgroundOnly: true,
- closeable: false,
- },
- version: sinon.match.string,
- }),
- ),
- ).to.be.true;
- });
-
- it('should be triggered when link in AlertBox headline is clicked', () => {
- const handleAnalyticsEvent = sinon.spy();
-
- global.document.body.addEventListener(
- 'component-library-analytics',
- handleAnalyticsEvent,
- );
-
- // Click link in headline
- const testLink = wrapper.find('.usa-alert-heading a');
- testLink.simulate('click');
-
- global.document.body.removeEventListener(
- 'component-library-analytics',
- handleAnalyticsEvent,
- );
-
- expect(
- handleAnalyticsEvent.calledWith(
- sinon.match.has('detail', {
- componentName: 'AlertBox',
- action: 'linkClick',
- details: {
- clickLabel: 'with a link',
- headline: HeadlineWithLink,
- status: 'info',
- backgroundOnly: true,
- closeable: false,
- },
- version: sinon.match.string,
- }),
- ),
- ).to.be.true;
- });
- });
-});
diff --git a/packages/react-components/src/components/MaintenanceBanner/MaintenanceBanner.jsx b/packages/react-components/src/components/MaintenanceBanner/MaintenanceBanner.jsx
deleted file mode 100644
index 856dd04e1..000000000
--- a/packages/react-components/src/components/MaintenanceBanner/MaintenanceBanner.jsx
+++ /dev/null
@@ -1,185 +0,0 @@
-// Node modules.
-import React, { Component } from 'react';
-import PropTypes from 'prop-types';
-
-// Relative imports.
-import AlertBox from '../AlertBox/AlertBox';
-import {
- formatDate,
- isDateAfter,
- isDateBefore,
- isDateSameDay,
-} from '../../helpers/format-date';
-
-export const MAINTENANCE_BANNER = 'MAINTENANCE_BANNER';
-
-// @WARNING: This is currently only used once in vets-website.
-/**
- * Display a maintenance banner for a given time window.
- */
-export class MaintenanceBanner extends Component {
- static propTypes = {
- /**
- * The content of the banner for downtime.
- */
- content: PropTypes.string.isRequired,
- /**
- * A Date object used when downtime expires.
- */
- expiresAt: PropTypes.instanceOf(Date).isRequired,
- /**
- * A unique ID that will be used for conditionally rendering the banner based on if the user has dismissed it already.
- */
- id: PropTypes.string.isRequired,
- /**
- * Usually this is just window.localStorage
- */
- localStorage: PropTypes.shape({
- getItem: PropTypes.func.isRequired,
- setItem: PropTypes.func.isRequired,
- }),
- /**
- * A Date object used when downtime starts.
- */
- startsAt: PropTypes.instanceOf(Date).isRequired,
- /**
- * The title of the banner for downtime.
- */
- title: PropTypes.string.isRequired,
- /**
- * The content of the banner for pre-downtime.
- */
- warnContent: PropTypes.string,
- /**
- * A Date object used when pre-downtime starts.
- */
- warnStartsAt: PropTypes.instanceOf(Date),
- /**
- * The title of the banner for pre-downtime.
- */
- warnTitle: PropTypes.string,
- };
-
- constructor(props) {
- super(props);
- this.state = {
- dismissed:
- props.localStorage &&
- props.localStorage.getItem(MAINTENANCE_BANNER) === this.props.id,
- };
- }
-
- derivePostContent = () => {
- const { startsAt, expiresAt } = this.props;
-
- if (isDateSameDay(startsAt, expiresAt)) {
- return (
- <>
-
- Date: {formatDate(startsAt, 'dateFull')}
-
-
- Start/End time: {formatDate(startsAt, 'timeShort')}{' '}
- to {formatDate(expiresAt, 'timeShort')} ET
-
- >
- );
- }
-
- return (
- <>
-
- Start: {formatDate(startsAt)} ET
-
-
- End: {formatDate(expiresAt)} ET
-
- >
- );
- };
-
- onCloseAlert = () => {
- if (this.props.localStorage) {
- this.props.localStorage.setItem(MAINTENANCE_BANNER, this.props.id);
- }
- this.setState({ dismissed: true });
- };
-
- render() {
- const { derivePostContent, onCloseAlert } = this;
- const { dismissed } = this.state;
- const {
- content,
- expiresAt,
- id,
- startsAt,
- title,
- warnContent,
- warnStartsAt,
- warnTitle,
- } = this.props;
-
- // Derive dates.
- const now = new Date();
- const postContent = derivePostContent();
-
- // Escape early if the banner is dismissed.
- if (dismissed) {
- return null;
- }
-
- // Escape early if it's before when it should show.
- if (isDateBefore(now, warnStartsAt)) {
- return null;
- }
-
- // Escape early if it's after when it should show.
- if (isDateAfter(now, expiresAt)) {
- return null;
- }
-
- // Show pre-downtime.
- if (isDateBefore(now, startsAt)) {
- return (
-
-
- {warnContent}
- {postContent}
- >
- }
- headline={warnTitle}
- onCloseAlert={onCloseAlert}
- status="warning"
- />
-
- );
- }
-
- // Show downtime.
- return (
-
-
- {content}
- {postContent}
- >
- }
- headline={title}
- onCloseAlert={onCloseAlert}
- status="error"
- />
-
- );
- }
-}
-
-export default MaintenanceBanner;
diff --git a/packages/react-components/src/components/MaintenanceBanner/MaintenanceBanner.mdx b/packages/react-components/src/components/MaintenanceBanner/MaintenanceBanner.mdx
deleted file mode 100644
index cceb7bc48..000000000
--- a/packages/react-components/src/components/MaintenanceBanner/MaintenanceBanner.mdx
+++ /dev/null
@@ -1,51 +0,0 @@
----
-title: MaintenanceBanner
-name: MaintenanceBanner
----
-
-import MaintenanceBanner from './MaintenanceBanner';
-
-### Code:
-
-```javascript
-import MaintenanceBanner from '@department-of-veterans-affairs/component-library/MaintenanceBanner';
-
-// Derive startsAt, expiresAt and warnStartsAt
-const startsAt = new Date();
-const expiresAt = new Date();
-const warnStartsAt = new Date();
-expiresAt.setHours(expiresAt.getHours() + 24);
-warnStartsAt.setHours(warnStartsAt.getHours() - 12);
-
-;
-```
-
-### Rendered Component
-
-const startsAt = new Date();
-const expiresAt = new Date();
-const warnStartsAt = new Date();
-expiresAt.setHours(expiresAt.getHours() + 24);
-warnStartsAt.setHours(warnStartsAt.getHours() - 12);
-
-
-
-
diff --git a/packages/react-components/src/components/MaintenanceBanner/MaintenanceBanner.unit.spec.jsx b/packages/react-components/src/components/MaintenanceBanner/MaintenanceBanner.unit.spec.jsx
deleted file mode 100644
index 359973e4f..000000000
--- a/packages/react-components/src/components/MaintenanceBanner/MaintenanceBanner.unit.spec.jsx
+++ /dev/null
@@ -1,64 +0,0 @@
-// Node modules.
-import React from 'react';
-import { mount } from 'enzyme';
-import { expect } from 'chai';
-
-// Relative imports.
-import MaintenanceBanner from './MaintenanceBanner.jsx';
-import { formatDate } from '../../helpers/format-date.js';
-
-const deriveDefaultProps = (startsAt = new Date()) => {
- const expiresAt = new Date(startsAt);
- const warnStartsAt = new Date(startsAt);
- expiresAt.setHours(expiresAt.getHours() + 2);
- warnStartsAt.setHours(warnStartsAt.getHours() - 12);
-
- const formattedStartsAt = formatDate(startsAt);
- const formattedExpiresAt = formatDate(expiresAt);
-
- return {
- id: '1',
- startsAt,
- expiresAt,
- title: 'DS Logon is down for maintenance.',
- content:
- 'DS Logon is down for maintenance. Please use ID.me or MyHealtheVet to sign in or use online tools.',
- warnStartsAt,
- warnTitle: 'DS Logon will be down for maintenance',
- warnContent: `DS Logon will be unavailable from ${formattedStartsAt} to ${formattedExpiresAt} Please use ID.me or MyHealtheVet to sign in or use online tools during this time.`,
- };
-};
-
-describe('', () => {
- it("Escapes early if it's before when it should show.", () => {
- const date = new Date();
- date.setHours(date.getHours() + 13);
- const wrapper = mount();
- expect(wrapper.html()).to.equal(null);
- wrapper.unmount();
- });
-
- it('Shows pre-downtime.', () => {
- const date = new Date();
- date.setHours(date.getHours() + 2);
- const wrapper = mount();
- expect(wrapper.html()).to.not.equal(null);
- expect(wrapper.html()).to.include('vads-u-border-color--warning-message');
- wrapper.unmount();
- });
-
- it('Shows downtime.', () => {
- const wrapper = mount();
- expect(wrapper.html()).to.not.equal(null);
- expect(wrapper.html()).to.include('vads-u-border-color--secondary');
- wrapper.unmount();
- });
-
- it("Escapes early if it's after when it should show.", () => {
- const date = new Date();
- date.setHours(date.getHours() - 3);
- const wrapper = mount();
- expect(wrapper.html()).to.equal(null);
- wrapper.unmount();
- });
-});
diff --git a/packages/react-components/src/index.js b/packages/react-components/src/index.js
index 96e9d8960..cfa2887cd 100644
--- a/packages/react-components/src/index.js
+++ b/packages/react-components/src/index.js
@@ -1,22 +1,17 @@
-import AlertBox, { ALERT_TYPE } from './components/AlertBox/AlertBox';
import Breadcrumbs from './components/Breadcrumbs/Breadcrumbs';
import ExpandingGroup from './components/ExpandingGroup/ExpandingGroup';
import IconBase from './components/IconBase/IconBase';
import IconSearch from './components/IconSearch/IconSearch';
import LoadingIndicator from './components/LoadingIndicator/LoadingIndicator';
-import MaintenanceBanner from './components/MaintenanceBanner/MaintenanceBanner';
import Modal from './components/Modal/Modal';
import TextInput from './components/TextInput/TextInput';
export {
- AlertBox,
- ALERT_TYPE,
Breadcrumbs,
ExpandingGroup,
IconBase,
IconSearch,
LoadingIndicator,
- MaintenanceBanner,
Modal,
TextInput,
};
diff --git a/packages/storybook/stories/MaintenanceBanner.stories.jsx b/packages/storybook/stories/MaintenanceBanner.stories.jsx
deleted file mode 100644
index 81c7175d9..000000000
--- a/packages/storybook/stories/MaintenanceBanner.stories.jsx
+++ /dev/null
@@ -1,58 +0,0 @@
-/* eslint-disable no-console */
-import React from 'react';
-import { formatDate } from '../../react-components/src/helpers/format-date';
-import MaintenanceBanner from '../../react-components/src/components/MaintenanceBanner/MaintenanceBanner';
-import { StoryDocs } from './wc-helpers';
-
-export default {
- title: 'Components/Banner - Maintenance (React)',
- component: MaintenanceBanner,
- id: 'components/banners-maintenancebanner',
- argTypes: {
- startsAt: { control: { type: 'date' } },
- expiresAt: { control: { type: 'date' } },
- warnStartsAt: { control: { type: 'date' } },
- },
- parameters: {
- componentSubtitle: 'Maintenance banner React component',
- docs: {
- page: () => ,
- },
- },
-};
-
-const Template = args => {
- const startTime = args.startsAt;
- const endTime = args.expiresAt;
- const warnStart = args.warnStartsAt;
- console.group('Times passed to Template');
- console.log('startTime:', formatDate(startTime, 'timeShort'));
- console.log('endTime', formatDate(endTime, 'timeShort'));
- console.log('warnStart', formatDate(warnStart, 'timeShort'));
- console.groupEnd();
- return ;
-};
-
-const defaultArgs = {
- id: 'maintenence-banner-id',
- title: 'Site maintenance',
- warnTitle: 'Upcoming site maintenance',
- content:
- 'We’re working on VA.gov right now. If you have trouble signing in or using tools, check back after we’re finished. Thank you for your patience.',
- warnContent:
- 'We’ll be doing some work on VA.gov. The maintenance will last X hours. During that time, you won’t be able to sign in or use tools.',
- startsAt: new Date(),
- expiresAt: new Date(new Date().setHours(new Date().getHours() + 2)),
- warnStartsAt: new Date(new Date().setHours(new Date().getHours() - 1)),
-};
-
-export const DuringMaintenance = Template.bind(null);
-DuringMaintenance.args = { ...defaultArgs };
-
-export const BeforeMaintenance = Template.bind(null);
-BeforeMaintenance.args = {
- ...defaultArgs,
- startsAt: new Date(new Date().setHours(new Date().getHours() + 1)),
- expiresAt: new Date(new Date().setHours(new Date().getHours() + 2)),
- warnStartsAt: new Date(),
-};