diff --git a/packages/react/package.json b/packages/react/package.json
index 83886549a026..5f4c480d2954 100644
--- a/packages/react/package.json
+++ b/packages/react/package.json
@@ -94,6 +94,7 @@
"babel-preset-carbon": "^0.3.0",
"browserify-zlib": "^0.2.0",
"browserslist-config-carbon": "^11.0.0",
+ "clipboardy": "^2.1.0",
"css-loader": "^6.5.1",
"enquirer": "^2.3.6",
"fast-glob": "^3.2.7",
diff --git a/packages/react/src/components/ProgressIndicator/ProgressIndicator-story.js b/packages/react/src/components/ProgressIndicator/ProgressIndicator-story.js
deleted file mode 100644
index 9b739b9769d4..000000000000
--- a/packages/react/src/components/ProgressIndicator/ProgressIndicator-story.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * Copyright IBM Corp. 2016, 2018
- *
- * This source code is licensed under the Apache-2.0 license found in the
- * LICENSE file in the root directory of this source tree.
- */
-
-import React from 'react';
-import { withKnobs, number, boolean, text } from '@storybook/addon-knobs';
-import { action } from '@storybook/addon-actions';
-import { ProgressIndicator, ProgressStep } from '../ProgressIndicator';
-import ProgressIndicatorSkeleton from '../ProgressIndicator/ProgressIndicator.Skeleton';
-import mdx from './ProgressIndicator.mdx';
-
-export default {
- title: 'Components/ProgressIndicator',
- component: ProgressIndicator,
- decorators: [withKnobs],
- parameters: {
- docs: {
- page: mdx,
- },
- },
- subcomponents: {
- ProgressStep,
- },
-};
-
-export const Default = () => (
-
-
-
-
-
-
-
-);
-
-export const Interactive = () => (
-
-
-
-
-
-);
-
-Interactive.storyName = 'interactive';
-
-export const Skeleton = () => ;
-
-Skeleton.storyName = 'skeleton';
diff --git a/packages/react/src/components/ProgressIndicator/ProgressIndicator-test.js b/packages/react/src/components/ProgressIndicator/ProgressIndicator-test.js
deleted file mode 100644
index 235452e7b01b..000000000000
--- a/packages/react/src/components/ProgressIndicator/ProgressIndicator-test.js
+++ /dev/null
@@ -1,185 +0,0 @@
-/**
- * Copyright IBM Corp. 2016, 2018
- *
- * This source code is licensed under the Apache-2.0 license found in the
- * LICENSE file in the root directory of this source tree.
- */
-
-import React from 'react';
-import { ProgressIndicator, ProgressStep } from '../ProgressIndicator';
-import ProgressIndicatorSkeleton from '../ProgressIndicator/ProgressIndicator.Skeleton';
-import { shallow, mount } from 'enzyme';
-
-const prefix = 'cds';
-
-describe('ProgressIndicator', () => {
- describe('Renders as expected', () => {
- const progress = (
-
-
-
-
-
-
-
-
- );
- const list = shallow(progress);
- const mountedList = mount(progress);
-
- beforeEach(() => {
- mountedList.setProps({ currentIndex: 3 });
- });
-
- it('should be a ul element', () => {
- expect(list.find('ul').length).toEqual(1);
- });
-
- it('should render children as expected', () => {
- expect(list.find(ProgressStep).length).toEqual(6);
- });
-
- it('should have the initial currentIndex from props', () => {
- expect(list.state().currentIndex).toEqual(3);
- });
-
- it('should update state when currentIndex is changed', () => {
- list.setProps({ currentIndex: 1 });
- expect(list.state().currentIndex).toEqual(1);
- list.setProps({ currentIndex: 0 });
- expect(list.state().currentIndex).toEqual(0);
- });
-
- it('should avoid updating state unless actual change in currentIndex is detected', () => {
- list.setProps({ currentIndex: 1 });
- list.setState({ currentIndex: 2 });
- list.setProps({ currentIndex: 1 });
- expect(list.state().currentIndex).toEqual(2);
- });
-
- it('should trigger onChange if clicked', () => {
- const mockOnChange = jest.fn();
-
- mountedList.setProps({ onChange: mockOnChange });
- mountedList.find(ProgressStep).at(0).find('button').simulate('click');
- expect(mockOnChange).toHaveBeenCalledWith(0);
- });
-
- describe('ProgressStep', () => {
- it('should render with correct base className', () => {
- expect(
- mountedList
- .find(ProgressStep)
- .at(0)
- .children()
- .hasClass(`${prefix}--progress-step`)
- ).toEqual(true);
- });
-
- it('should render with a label', () => {
- expect(mountedList.find(ProgressStep).at(0).prop('label')).toEqual(
- 'label'
- );
- });
-
- it('should render with a description', () => {
- expect(
- mountedList.find(ProgressStep).at(0).prop('description')
- ).toEqual('Step 1: Getting Started with Node.js');
- });
-
- it('should render description in
node', () => {
- expect(mountedList.find('ProgressStep title').at(0).text()).toEqual(
- 'Step 1: Getting Started with Node.js'
- );
- });
-
- describe('current', () => {
- it('should render a current ProgressStep with correct className', () => {
- expect(
- mountedList
- .find(ProgressStep)
- .at(3)
- .children()
- .hasClass(`${prefix}--progress-step--current`)
- ).toEqual(true);
- });
-
- it('should render a current ProgressStep with correct props', () => {
- expect(mountedList.find(ProgressStep).at(3).prop('current')).toBe(
- true
- );
- });
- });
-
- describe('complete', () => {
- it('should render any completed ProgressSteps with correct className', () => {
- expect(
- mountedList
- .find(ProgressStep)
- .at(0)
- .children()
- .hasClass(`${prefix}--progress-step--complete`)
- ).toEqual(true);
- });
- it('should render any completed ProgressSteps with correct props', () => {
- expect(list.find(ProgressStep).at(0).prop('complete')).toBe(true);
- });
- });
-
- describe('incomplete', () => {
- it('should render any incomplete ProgressSteps with correct className', () => {
- expect(
- mountedList
- .find(ProgressStep)
- .at(5)
- .children()
- .hasClass(`${prefix}--progress-step--incomplete`)
- ).toEqual(true);
- });
- it('should render any incomplete ProgressSteps with correct props', () => {
- expect(list.find(ProgressStep).at(5).prop('complete')).toBe(false);
- });
-
- it('should render any clickable ProgressSteps with correct classname', () => {
- mountedList.setProps({ onChange: jest.fn() });
- expect(
- mountedList.find(`.${prefix}--progress-step-button`)
- ).toHaveLength(6); // one button for each div
- expect(
- mountedList.find(`.${prefix}--progress-step-button--unclickable`)
- ).toHaveLength(1); // only the current step should be unclickable
- });
- });
- });
- });
-});
-
-describe('ProgressIndicatorSkeleton', () => {
- describe('Renders as expected', () => {
- const wrapper = shallow( );
-
- it('Has the expected classes', () => {
- expect(wrapper.hasClass(`${prefix}--skeleton`)).toEqual(true);
- expect(wrapper.hasClass(`${prefix}--progress`)).toEqual(true);
- });
- });
-});
diff --git a/packages/react/src/components/ProgressIndicator/ProgressIndicator.js b/packages/react/src/components/ProgressIndicator/ProgressIndicator.js
index 64ec6bc98481..81a772f8eb53 100644
--- a/packages/react/src/components/ProgressIndicator/ProgressIndicator.js
+++ b/packages/react/src/components/ProgressIndicator/ProgressIndicator.js
@@ -5,17 +5,17 @@
* LICENSE file in the root directory of this source tree.
*/
+import cx from 'classnames';
import PropTypes from 'prop-types';
-import React, { Component } from 'react';
-import classnames from 'classnames';
+import React, { useState } from 'react';
+import { keys, matches } from '../../internal/keyboard';
import {
CheckmarkOutline,
Warning,
CircleDash,
Incomplete,
} from '@carbon/icons-react';
-import { keys, matches } from '../../internal/keyboard';
-import { usePrefix, PrefixContext } from '../../internal/usePrefix';
+import { usePrefix } from '../../internal/usePrefix';
const defaultTranslations = {
'carbon.progress-step.complete': 'Complete',
@@ -27,8 +27,97 @@ const defaultTranslations = {
function translateWithId(messageId) {
return defaultTranslations[messageId];
}
+function ProgressIndicator({
+ children,
+ className: customClassName,
+ currentIndex: controlledIndex = 0,
+ onChange,
+ spaceEqually,
+ vertical,
+ ...rest
+}) {
+ const prefix = usePrefix();
+ const [currentIndex, setCurrentIndex] = useState(controlledIndex);
+ const [prevControlledIndex, setPrevControlledIndex] =
+ useState(controlledIndex);
+ const className = cx({
+ [`${prefix}--progress`]: true,
+ [`${prefix}--progress--vertical`]: vertical,
+ [`${prefix}--progress--space-equal`]: spaceEqually && !vertical,
+ [customClassName]: customClassName,
+ });
+
+ if (controlledIndex !== prevControlledIndex) {
+ setCurrentIndex(controlledIndex);
+ setPrevControlledIndex(controlledIndex);
+ }
+
+ return (
+
+ {React.Children.map(children, (child, index) => {
+ // only setup click handlers if onChange event is passed
+ const onClick = onChange ? () => onChange(index) : undefined;
+ if (index === currentIndex) {
+ return React.cloneElement(child, {
+ complete: child.props.complete,
+ current: child.props.complete ? false : true,
+ index,
+ onClick,
+ });
+ }
+ if (index < currentIndex) {
+ return React.cloneElement(child, {
+ complete: true,
+ index,
+ onClick,
+ });
+ }
+ if (index > currentIndex) {
+ return React.cloneElement(child, {
+ complete: child.props.complete || false,
+ index,
+ onClick,
+ });
+ }
+ return null;
+ })}
+
+ );
+}
+
+ProgressIndicator.propTypes = {
+ /**
+ * Provide `` components to be rendered in the
+ * ``
+ */
+ children: PropTypes.node,
+
+ /**
+ * Provide an optional className to be applied to the containing node
+ */
+ className: PropTypes.string,
+
+ /**
+ * Optionally specify the current step array index
+ */
+ currentIndex: PropTypes.number,
-export function ProgressStep({
+ /**
+ * Optional callback called if a ProgressStep is clicked on. Returns the index of the step.
+ */
+ onChange: PropTypes.func,
+
+ /**
+ * Specify whether the progress steps should be split equally in size in the div
+ */
+ spaceEqually: PropTypes.bool,
+ /**
+ * Determines whether or not the ProgressIndicator should be rendered vertically.
+ */
+ vertical: PropTypes.bool,
+};
+
+function ProgressStep({
label,
description,
className,
@@ -42,7 +131,7 @@ export function ProgressStep({
...rest
}) {
const prefix = usePrefix();
- const classes = classnames({
+ const classes = cx({
[`${prefix}--progress-step`]: true,
[`${prefix}--progress-step--current`]: current,
[`${prefix}--progress-step--complete`]: complete,
@@ -105,7 +194,7 @@ export function ProgressStep({
` components to be rendered in the
- * ``
- */
- children: PropTypes.node,
-
- /**
- * Provide an optional className to be applied to the containing node
- */
- className: PropTypes.string,
-
- /**
- * Optionally specify the current step array index
- */
- currentIndex: PropTypes.number,
-
- /**
- * Optional callback called if a ProgressStep is clicked on. Returns the index of the step.
- */
- onChange: PropTypes.func,
-
- /**
- * Specify whether the progress steps should be split equally in size in the div
- */
- spaceEqually: PropTypes.bool,
- /**
- * Determines whether or not the ProgressIndicator should be rendered vertically.
- */
- vertical: PropTypes.bool,
- };
-
- static contextType = PrefixContext;
-
- static defaultProps = {
- currentIndex: 0,
- };
-
- static getDerivedStateFromProps({ currentIndex }, state) {
- const { prevCurrentIndex } = state;
- return prevCurrentIndex === currentIndex
- ? null
- : {
- currentIndex,
- prevCurrentIndex: currentIndex,
- };
- }
-
- renderSteps = () => {
- const { onChange } = this.props;
-
- return React.Children.map(this.props.children, (child, index) => {
- // only setup click handlers if onChange event is passed
- const onClick = onChange ? () => onChange(index) : undefined;
- if (index === this.state.currentIndex) {
- return React.cloneElement(child, {
- current: true,
- index,
- onClick,
- });
- }
- if (index < this.state.currentIndex) {
- return React.cloneElement(child, {
- complete: true,
- index,
- onClick,
- });
- }
- if (index > this.state.currentIndex) {
- return React.cloneElement(child, {
- complete: child.props.complete || false,
- index,
- onClick,
- });
- }
- return null;
- });
- };
-
- render() {
- const {
- className,
- currentIndex, // eslint-disable-line no-unused-vars
- vertical,
- spaceEqually,
- ...other
- } = this.props;
- const prefix = this.context;
- const classes = classnames({
- [`${prefix}--progress`]: true,
- [`${prefix}--progress--vertical`]: vertical,
- [`${prefix}--progress--space-equal`]: spaceEqually && !vertical,
- [className]: className,
- });
- return (
-
- );
- }
-}
+export { ProgressIndicator, ProgressStep };
diff --git a/packages/react/src/components/ProgressIndicator/next/ProgressIndicator.stories.js b/packages/react/src/components/ProgressIndicator/ProgressIndicator.stories.js
similarity index 93%
rename from packages/react/src/components/ProgressIndicator/next/ProgressIndicator.stories.js
rename to packages/react/src/components/ProgressIndicator/ProgressIndicator.stories.js
index b12d409dc4d1..97b8a2b522a6 100644
--- a/packages/react/src/components/ProgressIndicator/next/ProgressIndicator.stories.js
+++ b/packages/react/src/components/ProgressIndicator/ProgressIndicator.stories.js
@@ -6,12 +6,8 @@
*/
import React from 'react';
-import {
- ProgressIndicator,
- ProgressStep,
- ProgressIndicatorSkeleton,
-} from '../';
-import mdx from '../ProgressIndicator.mdx';
+import { ProgressIndicator, ProgressStep, ProgressIndicatorSkeleton } from './';
+import mdx from './ProgressIndicator.mdx';
export default {
title: 'Components/ProgressIndicator',
diff --git a/packages/react/src/components/ProgressIndicator/__tests__/ProgressIndicator-test.js b/packages/react/src/components/ProgressIndicator/__tests__/ProgressIndicator-test.js
new file mode 100644
index 000000000000..ab47d2411ec6
--- /dev/null
+++ b/packages/react/src/components/ProgressIndicator/__tests__/ProgressIndicator-test.js
@@ -0,0 +1,279 @@
+/**
+ * Copyright IBM Corp. 2022
+ *
+ * This source code is licensed under the Apache-2.0 license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import React from 'react';
+import { ProgressIndicator, ProgressStep } from '../ProgressIndicator';
+import userEvent from '@testing-library/user-event';
+import { render, screen } from '@testing-library/react';
+
+describe('ProgressIndicator', () => {
+ describe('renders as expected - Component API', () => {
+ it('should spread extra props onto outermost element', () => {
+ const { container } = render(
+
+
+
+
+ );
+
+ expect(container.firstChild).toHaveAttribute('data-testid', 'test-id');
+ });
+
+ it('should support a custom `className` prop on the outermost element', () => {
+ const { container } = render(
+
+
+
+
+ );
+
+ expect(container.firstChild).toHaveClass('custom-class');
+ });
+
+ it('should respect currentIndex prop', () => {
+ render(
+
+
+
+
+ );
+
+ expect(screen.getAllByRole('listitem')[0]).toHaveClass(
+ 'cds--progress-step--current'
+ );
+ });
+
+ it('should call onChange when expected', () => {
+ const onChange = jest.fn();
+ render(
+
+
+
+
+ );
+
+ userEvent.click(screen.getByTitle('First step'));
+
+ expect(onChange).toHaveBeenCalled();
+ });
+
+ it('should respect spaceEqually prop', () => {
+ render(
+
+
+
+
+ );
+
+ expect(screen.getByRole('list')).toHaveClass(
+ 'cds--progress--space-equal'
+ );
+ });
+
+ it('should respect vertical prop', () => {
+ render(
+
+
+
+
+ );
+
+ expect(screen.getByRole('list')).toHaveClass('cds--progress--vertical');
+ });
+ });
+});
+
+describe('ProgressStep', () => {
+ describe('renders as expected - Component API', () => {
+ it('should spread extra props onto outermost element', () => {
+ const { container } = render(
+
+ );
+
+ expect(container.firstChild.firstChild).toHaveAttribute(
+ 'data-testid',
+ 'test-id'
+ );
+ });
+
+ it('should support a custom `className` prop on the outermost element', () => {
+ const { container } = render(
+
+ );
+
+ expect(container.firstChild).toHaveClass('custom-class');
+ });
+
+ it('should respect complete prop', () => {
+ render( );
+
+ expect(screen.getByText('Complete')).toBeInTheDocument();
+ expect(screen.getByRole('listitem')).toHaveClass(
+ 'cds--progress-step--complete'
+ );
+ });
+
+ it('should respect current prop', () => {
+ render( );
+
+ expect(screen.getByText('Current')).toBeInTheDocument();
+ expect(screen.getByRole('listitem')).toHaveClass(
+ 'cds--progress-step--current'
+ );
+ });
+
+ it('should respect description prop', () => {
+ render( );
+
+ expect(screen.getByText('First step')).toBeInTheDocument();
+ });
+
+ it('should respect disabled prop', () => {
+ render( );
+
+ expect(screen.getByRole('listitem')).toHaveClass(
+ 'cds--progress-step--disabled'
+ );
+ expect(screen.getByRole('button')).toHaveAttribute('disabled');
+ expect(screen.getByRole('button')).toHaveClass(
+ 'cds--progress-step-button--unclickable'
+ );
+ });
+
+ it('should respect index prop', () => {
+ render( );
+
+ expect(screen.getByRole('button')).toHaveAttribute('index', '3');
+ });
+
+ it('should respect invalid prop', () => {
+ render( );
+
+ expect(screen.getByText('Invalid')).toBeDefined();
+ });
+
+ it('should respect label prop', () => {
+ render( );
+
+ expect(screen.getByRole('button')).toHaveAttribute('title', 'First step');
+ });
+
+ it('should call onClick when expected', () => {
+ const onClick = jest.fn();
+ render( );
+
+ userEvent.click(screen.getByRole('button'));
+ expect(onClick).toHaveBeenCalled();
+ });
+
+ it('should respect secondaryLabel prop', () => {
+ render(
+
+ );
+
+ expect(screen.getByText('Prompt for step')).toBeInTheDocument();
+ });
+
+ it('should respect translateWithId prop', () => {
+ const translations = {
+ 'carbon.progress-step.complete': 'Terminé',
+ 'carbon.progress-step.incomplete': 'Partiel',
+ 'carbon.progress-step.current': 'Actuel',
+ 'carbon.progress-step.invalid': 'Non valide',
+ };
+
+ render(
+
+ {
+ return translations[messageId];
+ }}
+ />
+ {
+ return translations[messageId];
+ }}
+ />
+ {
+ return translations[messageId];
+ }}
+ />
+ {
+ return translations[messageId];
+ }}
+ />
+
+ );
+
+ expect(screen.getByText('Terminé')).toBeInTheDocument();
+ expect(screen.getByText('Actuel')).toBeInTheDocument();
+ expect(screen.getByText('Non valide')).toBeInTheDocument();
+ expect(screen.getByText('Partiel')).toBeInTheDocument();
+ });
+ });
+});
diff --git a/packages/react/src/components/ProgressIndicator/index.js b/packages/react/src/components/ProgressIndicator/index.js
index 68b46bee774e..52b92fd26258 100644
--- a/packages/react/src/components/ProgressIndicator/index.js
+++ b/packages/react/src/components/ProgressIndicator/index.js
@@ -5,16 +5,5 @@
* LICENSE file in the root directory of this source tree.
*/
-import * as FeatureFlags from '@carbon/feature-flags';
-import { default as ProgressIndicatorSkeleton } from './ProgressIndicator.Skeleton';
-import {
- ProgressIndicator as ProgressIndicatorClassic,
- ProgressStep,
-} from './ProgressIndicator';
-import { ProgressIndicator as ProgressIndicatorNext } from './next/ProgressIndicator';
-
-const ProgressIndicator = FeatureFlags.enabled('enable-v11-release')
- ? ProgressIndicatorNext
- : ProgressIndicatorClassic;
-
-export { ProgressIndicator, ProgressIndicatorSkeleton, ProgressStep };
+export { default as ProgressIndicatorSkeleton } from './ProgressIndicator.Skeleton';
+export * from './ProgressIndicator';
diff --git a/packages/react/src/components/ProgressIndicator/next/ProgressIndicator.js b/packages/react/src/components/ProgressIndicator/next/ProgressIndicator.js
deleted file mode 100644
index d977d1adb5fa..000000000000
--- a/packages/react/src/components/ProgressIndicator/next/ProgressIndicator.js
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * Copyright IBM Corp. 2016, 2018
- *
- * This source code is licensed under the Apache-2.0 license found in the
- * LICENSE file in the root directory of this source tree.
- */
-
-import cx from 'classnames';
-import PropTypes from 'prop-types';
-import React, { useState } from 'react';
-import { usePrefix } from '../../../internal/usePrefix';
-
-function ProgressIndicator({
- children,
- className: customClassName,
- currentIndex: controlledIndex = 0,
- onChange,
- spaceEqually,
- vertical,
- ...rest
-}) {
- const prefix = usePrefix();
- const [currentIndex, setCurrentIndex] = useState(controlledIndex);
- const [prevControlledIndex, setPrevControlledIndex] =
- useState(controlledIndex);
- const className = cx({
- [`${prefix}--progress`]: true,
- [`${prefix}--progress--vertical`]: vertical,
- [`${prefix}--progress--space-equal`]: spaceEqually && !vertical,
- [customClassName]: customClassName,
- });
-
- if (controlledIndex !== prevControlledIndex) {
- setCurrentIndex(controlledIndex);
- setPrevControlledIndex(controlledIndex);
- }
-
- return (
-
- {React.Children.map(children, (child, index) => {
- // only setup click handlers if onChange event is passed
- const onClick = onChange ? () => onChange(index) : undefined;
- if (index === currentIndex) {
- return React.cloneElement(child, {
- complete: child.props.complete,
- current: child.props.complete ? false : true,
- index,
- onClick,
- });
- }
- if (index < currentIndex) {
- return React.cloneElement(child, {
- complete: true,
- index,
- onClick,
- });
- }
- if (index > currentIndex) {
- return React.cloneElement(child, {
- complete: child.props.complete || false,
- index,
- onClick,
- });
- }
- return null;
- })}
-
- );
-}
-
-ProgressIndicator.propTypes = {
- /**
- * Provide `` components to be rendered in the
- * ``
- */
- children: PropTypes.node,
-
- /**
- * Provide an optional className to be applied to the containing node
- */
- className: PropTypes.string,
-
- /**
- * Optionally specify the current step array index
- */
- currentIndex: PropTypes.number,
-
- /**
- * Optional callback called if a ProgressStep is clicked on. Returns the index of the step.
- */
- onChange: PropTypes.func,
-
- /**
- * Specify whether the progress steps should be split equally in size in the div
- */
- spaceEqually: PropTypes.bool,
- /**
- * Determines whether or not the ProgressIndicator should be rendered vertically.
- */
- vertical: PropTypes.bool,
-};
-
-export { ProgressIndicator };
diff --git a/packages/react/src/components/ProgressIndicator/next/__tests__/ProgressIndicator-test.js b/packages/react/src/components/ProgressIndicator/next/__tests__/ProgressIndicator-test.js
deleted file mode 100644
index 578afcb1f6d0..000000000000
--- a/packages/react/src/components/ProgressIndicator/next/__tests__/ProgressIndicator-test.js
+++ /dev/null
@@ -1,166 +0,0 @@
-/**
- * Copyright IBM Corp. 2016, 2018
- *
- * This source code is licensed under the Apache-2.0 license found in the
- * LICENSE file in the root directory of this source tree.
- */
-
-import { mount } from 'enzyme';
-import React from 'react';
-import { ProgressIndicator } from '../ProgressIndicator';
-import { ProgressStep } from '../../';
-
-const prefix = 'cds';
-
-function getActiveIndex(wrapper) {
- return wrapper
- .find(`.${prefix}--progress-step--current`)
- .parent()
- .prop('index');
-}
-
-describe('ProgressIndicator', () => {
- describe('Renders as expected', () => {
- let list;
-
- beforeEach(() => {
- list = mount(
-
-
-
-
-
-
-
-
- );
- });
-
- it('should be a ul element', () => {
- expect(list.find('ul').length).toEqual(1);
- });
-
- it('should render children as expected', () => {
- expect(list.find(ProgressStep).length).toEqual(6);
- });
-
- it('should have the initial currentIndex from props', () => {
- expect(getActiveIndex(list)).toEqual(3);
- });
-
- it('should update state when currentIndex is changed', () => {
- list.setProps({ currentIndex: 1 });
- expect(getActiveIndex(list)).toEqual(1);
- list.setProps({ currentIndex: 0 });
- expect(getActiveIndex(list)).toEqual(0);
- });
-
- it('should trigger onChange if clicked', () => {
- const mockOnChange = jest.fn();
-
- list.setProps({ onChange: mockOnChange });
- list.find(ProgressStep).at(0).find('button').simulate('click');
- expect(mockOnChange).toHaveBeenCalledWith(0);
- });
-
- describe('ProgressStep', () => {
- it('should render with correct base className', () => {
- expect(
- list
- .find(ProgressStep)
- .at(0)
- .children()
- .hasClass(`${prefix}--progress-step`)
- ).toEqual(true);
- });
-
- it('should render with a label', () => {
- expect(list.find(ProgressStep).at(0).prop('label')).toEqual('label');
- });
-
- it('should render with a description', () => {
- expect(list.find(ProgressStep).at(0).prop('description')).toEqual(
- 'Step 1: Getting Started with Node.js'
- );
- });
-
- it('should render description in node', () => {
- expect(list.find('ProgressStep title').at(0).text()).toEqual(
- 'Step 1: Getting Started with Node.js'
- );
- });
-
- describe('current', () => {
- it('should render a current ProgressStep with correct className', () => {
- expect(
- list
- .find(ProgressStep)
- .at(3)
- .children()
- .hasClass(`${prefix}--progress-step--current`)
- ).toEqual(true);
- });
-
- it('should render a current ProgressStep with correct props', () => {
- expect(list.find(ProgressStep).at(3).prop('current')).toBe(true);
- });
- });
-
- describe('complete', () => {
- it('should render any completed ProgressSteps with correct className', () => {
- expect(
- list
- .find(ProgressStep)
- .at(0)
- .children()
- .hasClass(`${prefix}--progress-step--complete`)
- ).toEqual(true);
- });
- it('should render any completed ProgressSteps with correct props', () => {
- expect(list.find(ProgressStep).at(0).prop('complete')).toBe(true);
- });
- });
-
- describe('incomplete', () => {
- it('should render any incomplete ProgressSteps with correct className', () => {
- expect(
- list
- .find(ProgressStep)
- .at(5)
- .children()
- .hasClass(`${prefix}--progress-step--incomplete`)
- ).toEqual(true);
- });
- it('should render any incomplete ProgressSteps with correct props', () => {
- expect(list.find(ProgressStep).at(5).prop('complete')).toBe(false);
- });
-
- it('should render any clickable ProgressSteps with correct classname', () => {
- list.setProps({ onChange: jest.fn() });
- expect(list.find(`.${prefix}--progress-step-button`)).toHaveLength(6); // one button for each div
- expect(
- list.find(`.${prefix}--progress-step-button--unclickable`)
- ).toHaveLength(1); // only the current step should be unclickable
- });
- });
- });
- });
-});
diff --git a/packages/react/tasks/build-test-rtl.js b/packages/react/tasks/build-test-rtl.js
index c7699438684e..ebb72c821cd0 100644
--- a/packages/react/tasks/build-test-rtl.js
+++ b/packages/react/tasks/build-test-rtl.js
@@ -1,5 +1,6 @@
'use strict';
+const clipboard = require('clipboardy');
const prettier = require('prettier');
const CarbonComponents = require('@carbon/react');
const enquirer = require('enquirer');
@@ -215,6 +216,22 @@ async function main() {
const testFile = writeTestFile(props, componentName, isSubComponent);
+ if (pathToComponent === '') {
+ const { copy } = await enquirer.prompt([
+ {
+ type: 'confirm',
+ name: 'copy',
+ message:
+ 'Looks like no component path was found, do you want to copy the created tests?',
+ },
+ ]);
+
+ if (copy) {
+ clipboard.writeSync(testFile);
+ }
+ return;
+ }
+
await fs.writeFile(pathToComponent, testFile);
console.log(`Test file created for ${componentName}! 🎉`);
diff --git a/yarn.lock b/yarn.lock
index 077a33be37b1..1c460f924eaa 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2178,6 +2178,7 @@ __metadata:
browserify-zlib: ^0.2.0
browserslist-config-carbon: ^11.0.0
classnames: 2.3.1
+ clipboardy: ^2.1.0
copy-to-clipboard: ^3.3.1
css-loader: ^6.5.1
downshift: 5.2.1