diff --git a/packages/design-system-dashboard-cli/README.md b/packages/design-system-dashboard-cli/README.md
index 54da8efb8..9e1399be7 100644
--- a/packages/design-system-dashboard-cli/README.md
+++ b/packages/design-system-dashboard-cli/README.md
@@ -75,6 +75,8 @@ If you supply search terms, it'll filter the result.
![filtered result](./img/filtered-result.png)
+If you supply the string `uswds` as a search term, it'll return all web component and react binding usages where the uswds prop is being used.
+
**Note:** Search terms are case sensitive!
Search terms may be regex.
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 59ad019fd..7bf63a620 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
@@ -331,7 +331,6 @@
All files write-react-owners-to-csv.js
const componentsToKeep = [
'AlertBox',
- 'Checkbox',
'ExpandingGroup',
'IconSearch',
'LoadingIndicator',
diff --git a/packages/design-system-dashboard-cli/src/find-ds-components.js b/packages/design-system-dashboard-cli/src/find-ds-components.js
index de2328d2e..45378d932 100644
--- a/packages/design-system-dashboard-cli/src/find-ds-components.js
+++ b/packages/design-system-dashboard-cli/src/find-ds-components.js
@@ -143,6 +143,9 @@ function findUsedReactComponents(vwModules, regexPattern) {
* Search vets-website and the content build for design system components.
*
* @param searchStrings {string[]} - The components to display usage for
+ *
+ * Passing in the string 'uswds' will output a list of all web components and
+ * web component react bindings where the uswds prop is used
*/
function findComponents(searchStrings) {
const vwModules = readAllModules(`${repos['vets-website']}/src`);
@@ -163,18 +166,30 @@ function findComponents(searchStrings) {
);
const wcTagRegex = /<(va-[^\s>]+)/gms;
- const vwWebComponents = search(vwModules, wcTagRegex);
- const contentBuildWC = search(contentTemplates, wcTagRegex);
+ const wcUswds3Regex = /<(Va[^\s]+|va-[^\s]+)(\s|\n)[^>]*?uswds/gms;
- const vwComponents = [
- ...usedReactComponents,
- ...vwWebComponents,
- ...usedReactBindings,
- ];
+ let vwWebComponents;
+ let contentBuildWC;
+ let vwComponents;
- const data = tallyResults(vwComponents, contentBuildWC);
+ if (searchStrings?.includes('uswds')) {
+ vwWebComponents = search(vwModules, wcUswds3Regex);
+ contentBuildWC = search(contentTemplates, wcUswds3Regex);
+ vwComponents = [...vwWebComponents];
+ } else {
+ vwWebComponents = search(vwModules, wcTagRegex);
+ contentBuildWC = search(contentTemplates, wcTagRegex);
+ vwComponents = [
+ ...usedReactComponents,
+ ...vwWebComponents,
+ ...usedReactBindings,
+ ];
+ }
- return filterSearchedComponents(data, searchStrings);
+ const data = tallyResults(vwComponents, contentBuildWC);
+ return searchStrings?.includes('uswds')
+ ? data
+ : filterSearchedComponents(data, searchStrings);
}
if (require.main === module) {
diff --git a/packages/design-system-dashboard-cli/src/search-files.js b/packages/design-system-dashboard-cli/src/search-files.js
index 8fb6c6f19..3c5bba33b 100644
--- a/packages/design-system-dashboard-cli/src/search-files.js
+++ b/packages/design-system-dashboard-cli/src/search-files.js
@@ -26,6 +26,8 @@ function readAllModules(rootDir) {
`${rootDir}/**/_mock-form/**`,
`${rootDir}/**/*.unit.@(js|jsx)`,
`${rootDir}/**/*.spec.@(js|jsx)`,
+ `${rootDir}/**/ds-playground/**`,
+ `${rootDir}/**/ds-v3-playground/**`,
],
});
diff --git a/packages/design-system-dashboard-cli/src/write-react-owners-to-csv.js b/packages/design-system-dashboard-cli/src/write-react-owners-to-csv.js
index 406d99145..bf2bae4f4 100644
--- a/packages/design-system-dashboard-cli/src/write-react-owners-to-csv.js
+++ b/packages/design-system-dashboard-cli/src/write-react-owners-to-csv.js
@@ -7,7 +7,6 @@ const today = require('./today');
const componentsToKeep = [
'AlertBox',
'Breadcrumbs',
- 'Checkbox',
'ExpandingGroup',
'IconSearch',
'Modal',
diff --git a/packages/react-components/index.js b/packages/react-components/index.js
index 641a0cf56..dd731a0c9 100644
--- a/packages/react-components/index.js
+++ b/packages/react-components/index.js
@@ -1,6 +1,5 @@
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';
@@ -14,7 +13,6 @@ export {
AlertBox,
ALERT_TYPE,
Breadcrumbs,
- Checkbox,
ExpandingGroup,
IconBase,
IconSearch,
diff --git a/packages/react-components/src/components/Checkbox/Checkbox.jsx b/packages/react-components/src/components/Checkbox/Checkbox.jsx
deleted file mode 100644
index ba5835816..000000000
--- a/packages/react-components/src/components/Checkbox/Checkbox.jsx
+++ /dev/null
@@ -1,170 +0,0 @@
-import PropTypes from 'prop-types';
-import React from 'react';
-import { uniqueId } from '../../helpers/utilities';
-
-import dispatchAnalyticsEvent from '../../helpers/analytics';
-
-class Checkbox extends React.Component {
- constructor() {
- super();
- this.handleChange = this.handleChange.bind(this);
- }
-
- UNSAFE_componentWillMount() {
- this.inputId = uniqueId('errorable-checkbox-');
- }
-
- handleChange(domEvent) {
- const isChecked = domEvent.target.checked;
-
- if (isChecked && this.props.enableAnalytics) {
- dispatchAnalyticsEvent({
- componentName: 'Checkbox',
- action: 'change',
- details: {
- label: this.props.label,
- labelAboveCheckbox: this.props.labelAboveCheckbox,
- required: this.props.required,
- },
- });
- }
-
- this.props.onValueChange(isChecked);
- }
-
- render() {
- // TODO: extract error logic into a utility function
- // Calculate error state.
- let errorSpan = '';
- let errorSpanId = undefined;
- if (this.props.errorMessage) {
- errorSpanId = `${this.inputId}-error-message`;
- errorSpan = (
-
- Error {this.props.errorMessage}
-
- );
- }
-
- // Calculate required.
- let requiredSpan = undefined;
- if (this.props.required) {
- requiredSpan = (*Required) ;
- }
-
- let className = `form-checkbox${
- this.props.errorMessage ? ' usa-input-error' : ''
- }`;
- if (this.props.className !== undefined) {
- className = `${className} ${this.props.className}`;
- }
-
- return (
-
- {this.props.labelAboveCheckbox && (
-
- {this.props.labelAboveCheckbox}
-
- )}
- {errorSpan}
-
-
- {this.props.label}
- {requiredSpan}
-
-
- );
- }
-}
-
-Checkbox.propTypes = {
- /**
- * If the checkbox is checked or not
- */
- checked: PropTypes.bool,
- /**
- * Optionally adds one or more CSS classes to the NAV element
- */
- className: PropTypes.string,
- /**
- * Error message for the modal
- */
- errorMessage: PropTypes.string,
- /**
- * Name for the modal
- */
- name: PropTypes.string,
- /**
- * Label [string or object] for the checkbox. Either this or ariaLabelledBy is required.
- */
- /* eslint-disable consistent-return */
- label: (props, propName, componentName) => {
- const validTypes = ['string', 'object'];
-
- if (!props.label && !props.ariaLabelledBy) {
- return new Error(
- `Either ${propName} or ariaLabelledBy property is required in ${componentName}, but both are missing.`,
- );
- }
-
- if (props.label && !validTypes.includes(typeof props.label)) {
- return new Error(
- `${componentName}’s label property type is invalid -- should be one of
- these types: ${validTypes.join(', ')}.`,
- );
- }
- },
- /* eslint-enable consistent-return */
- /**
- * Descriptive text to sit above the checkbox and label
- */
- labelAboveCheckbox: PropTypes.string,
- /**
- * aria-labelledby attribute [string] (external-heading ID). Either this or label is required.
- */
- /* eslint-disable consistent-return */
- ariaLabelledBy: (props, propName, componentName) => {
- if (!props.label && !props.ariaLabelledBy) {
- return new Error(
- `Either ${propName} or label property is required in ${componentName}, but both are missing.`,
- );
- }
-
- if (props.ariaLabelledBy && typeof props.ariaLabelledBy !== 'string') {
- return new Error(
- `${componentName}’s ariaLabelledBy property type is invalid -- should be
- string.`,
- );
- }
- },
- /* eslint-enable consistent-return */
- /**
- * Handler for when the checkbox is changed
- */
- onValueChange: PropTypes.func.isRequired,
- /**
- * If the checkbox is required or not
- */
- required: PropTypes.bool,
- /**
- * Analytics tracking function(s) will be called. Form components
- * are disabled by default due to PII/PHI concerns.
- */
- enableAnalytics: PropTypes.bool,
-};
-
-export default Checkbox;
diff --git a/packages/react-components/src/components/Checkbox/Checkbox.mdx b/packages/react-components/src/components/Checkbox/Checkbox.mdx
deleted file mode 100644
index 88aebda23..000000000
--- a/packages/react-components/src/components/Checkbox/Checkbox.mdx
+++ /dev/null
@@ -1,73 +0,0 @@
----
-title: Checkbox
-name: Checkbox
-tags: checkbox, component
----
-
-import Checkbox from './Checkbox'
-
-### Code:
-```javascript
-import Checkbox from '@department-of-veterans-affairs/component-library/Checkbox'
-
-
- value}
- id='default'
- errorMessage=''
- required={true}
- title='Checkbox'
- />
- value}
- id='default'
- errorMessage='Error message'
- required={true}
- title='Checkbox'
- />
- External heading [label-substitute]
- value}
- id='default'
- errorMessage=''
- required={true}
- title='Checkbox'
- />
-
-```
-
-### Rendered Component
-
- value}
- id='default'
- errorMessage=''
- required={true}
- title='Checkbox'
- />
- value}
- id='default'
- errorMessage='Error message'
- required={true}
- title='Checkbox'
- />
- External heading [label-substitute]
- value}
- id='default'
- errorMessage=''
- required={true}
- title='Checkbox'
- />
-
diff --git a/packages/react-components/src/components/Checkbox/Checkbox.unit.spec.jsx b/packages/react-components/src/components/Checkbox/Checkbox.unit.spec.jsx
deleted file mode 100644
index 44911ea46..000000000
--- a/packages/react-components/src/components/Checkbox/Checkbox.unit.spec.jsx
+++ /dev/null
@@ -1,204 +0,0 @@
-import React from 'react';
-import { expect } from 'chai';
-import { mount, shallow } from 'enzyme';
-import { axeCheck } from '../../helpers/test-helpers';
-import Checkbox from './Checkbox.jsx';
-import sinon from 'sinon';
-import { testAnalytics } from '../../helpers/test-helpers';
-
-describe(' ', () => {
- it('should render without the labelAboveCheckbox', () => {
- const tree = shallow( {}} />);
- expect(tree.text()).to.contain('test');
- tree.unmount();
- });
-
- it('should render with the labelAboveCheckbox', () => {
- const tree = shallow(
- {}}
- />,
- );
- expect(tree.text()).to.contain('test');
- expect(tree.text()).to.contain('this is a checkbox');
- tree.unmount();
- });
-
- it('should pass aXe check', () =>
- axeCheck( {}} />));
- it('ensure checked changes propagate', () => {
- const handleChangeSpy = sinon.spy(Checkbox.prototype, 'handleChange');
- const tree = shallow( {}} />);
- const event = { target: { checked: true } };
-
- const checkBox = () => tree.find('[type="checkbox"]');
- checkBox().simulate('change', event);
- expect(handleChangeSpy.calledOnce).to.be.true;
- tree.unmount();
- });
- it('no error styles when errorMessage undefined', () => {
- const tree = shallow(
- {}} />,
- );
-
- // No error classes.
- expect(tree.children('.usa-input-error')).to.have.lengthOf(0);
- expect(tree.children('.usa-input-error-label')).to.have.lengthOf(0);
- expect(tree.children('.usa-input-error-message')).to.have.lengthOf(0);
-
- // Ensure no unnecessary class names on label w/o error..
- const labels = tree.children('label');
- expect(labels).to.have.lengthOf(1);
- expect(labels.prop('className')).to.be.equal(
- undefined,
- 'Unnecessary class names on label without error',
- );
-
- // No error means no aria-describedby to not confuse screen readers.
- const inputs = tree.find('input');
- expect(inputs).to.have.lengthOf(1);
- expect(inputs.prop('aria-describedby')).to.be.equal(
- undefined,
- 'Unnecessary aria-describedby',
- );
- tree.unmount();
- });
-
- it('has error styles when errorMessage is set', () => {
- const tree = shallow(
- {}}
- />,
- );
-
- // Ensure all error classes set.
- expect(tree.find('.usa-input-error')).to.have.lengthOf(1);
-
- const labels = tree.find('.usa-input-error-label');
- expect(labels).to.have.lengthOf(1);
-
- const errorMessages = tree.find('.usa-input-error-message');
- expect(errorMessages).to.have.lengthOf(1);
- expect(errorMessages.text()).to.equal('Error error message');
-
- // No error means no aria-describedby to not confuse screen readers.
- const inputs = tree.find('input');
- expect(inputs).to.have.lengthOf(1);
- expect(inputs.prop('aria-describedby')).to.not.be.equal(undefined);
- expect(inputs.prop('aria-describedby')).to.equal(errorMessages.prop('id'));
- tree.unmount();
- });
-
- it('required=false does not have required asterisk', () => {
- const tree = shallow(
- {}} />,
- );
-
- expect(tree.find('label').text()).to.equal('my label');
- tree.unmount();
- });
-
- it('required=true has required asterisk', () => {
- const tree = shallow(
- {}} />,
- );
-
- const label = tree.find('label');
- expect(label.text()).to.equal('my label(*Required)');
- tree.unmount();
- });
-
- it('label attribute propagates', () => {
- const tree = shallow(
- {}} />,
- );
-
- // Ensure label text is correct.
- const labels = tree.find('label');
- expect(labels).to.have.lengthOf(1);
- expect(labels.text()).to.equal('my label');
-
- // Ensure label htmlFor is attached to input id.
- const inputs = tree.find('input');
- expect(inputs).to.have.lengthOf(1);
- expect(inputs.prop('id')).to.not.be.equal(undefined);
- expect(inputs.prop('id')).to.equal(labels.prop('htmlFor'));
- tree.unmount();
- });
-
- it('adds aria-labelledby attribute', () => {
- const tree = shallow(
- {}} />,
- );
-
- // Ensure label text is empty string.
- const labels = tree.find('label');
- expect(labels).to.have.lengthOf(1);
- expect(labels.text()).to.equal('');
-
- // Ensure label aria-labelledby is attached to input id.
- const inputs = tree.find('input');
- expect(inputs).to.have.lengthOf(1);
- expect(inputs.prop('aria-labelledby')).to.equal('headingId');
- tree.unmount();
- });
-
- describe('analytics event', function () {
- it('should NOT be triggered when enableAnalytics is not true', () => {
- const wrapper = shallow(
- {}}
- />,
- );
-
- const spy = testAnalytics(wrapper, () => {
- const event = { target: { checked: true } };
- wrapper.find('[type="checkbox"]').simulate('change', event);
- });
-
- expect(spy.called).to.be.false;
-
- wrapper.unmount();
- });
-
- it('should be triggered when Checkbox is checked', () => {
- const wrapper = mount(
- {}}
- enableAnalytics
- required={false}
- />,
- );
-
- const spy = testAnalytics(wrapper, wrapper => {
- const event = { target: { checked: true } };
- wrapper.find('[type="checkbox"]').simulate('change', event);
- });
-
- expect(
- spy.calledWith(
- sinon.match.has('detail', {
- componentName: 'Checkbox',
- action: 'change',
- details: {
- label: 'test',
- labelAboveCheckbox: 'this is a checkbox',
- required: false,
- },
- version: sinon.match.string,
- }),
- ),
- ).to.be.true;
-
- wrapper.unmount();
- });
- });
-});
diff --git a/packages/react-components/src/index.js b/packages/react-components/src/index.js
index 1f0de2182..25850a8b6 100644
--- a/packages/react-components/src/index.js
+++ b/packages/react-components/src/index.js
@@ -1,6 +1,5 @@
import AlertBox, { ALERT_TYPE } from './components/AlertBox/AlertBox';
import Breadcrumbs from './components/Breadcrumbs/Breadcrumbs';
-import Checkbox from './components/Checkbox/Checkbox';
import ExpandingGroup from './components/ExpandingGroup/ExpandingGroup';
import IconBase from './components/IconBase/IconBase';
import IconSearch from './components/IconSearch/IconSearch';
@@ -12,7 +11,6 @@ export {
AlertBox,
ALERT_TYPE,
Breadcrumbs,
- Checkbox,
ExpandingGroup,
IconBase,
IconSearch,