Skip to content

Commit

Permalink
feat(react): refactor composed modal to functional component (#10060)
Browse files Browse the repository at this point in the history
* feat(react): update composed modal to functional component

* feat(react): refactor ComposedModal to functional component

* chore(react): remove console.logs

* fix(react): export ComposedModal under feature flag

* Update packages/react/src/components/ComposedModal/next/ComposedModal.js

Co-authored-by: Scott Strubberg <[email protected]>

* Update packages/react/src/components/ComposedModal/next/ComposedModal.js

Co-authored-by: Scott Strubberg <[email protected]>

Co-authored-by: Scott Strubberg <[email protected]>
  • Loading branch information
abbeyhrt and sstrubberg authored Nov 9, 2021
1 parent 3bd0462 commit 40f3768
Show file tree
Hide file tree
Showing 5 changed files with 764 additions and 2 deletions.
10 changes: 8 additions & 2 deletions packages/react/src/components/ComposedModal/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@

import * as FeatureFlags from '@carbon/feature-flags';
import { ModalHeader as ModalHeaderNext } from './next/ModalHeader';
import ComposedModal, {
import { default as ComposedModalNext } from './next/ComposedModal';
import {
default as ComposedModalClassic,
ModalHeader as ModalHeaderClassic,
ModalBody,
ModalFooter,
Expand All @@ -17,6 +19,10 @@ export const ModalHeader = FeatureFlags.enabled('enable-v11-release')
? ModalHeaderNext
: ModalHeaderClassic;

export { ComposedModal, ModalBody, ModalFooter };
export const ComposedModal = FeatureFlags.enabled('enable-v11-release')
? ComposedModalNext
: ComposedModalClassic;

export { ModalBody, ModalFooter };

export default from './ComposedModal';
118 changes: 118 additions & 0 deletions packages/react/src/components/ComposedModal/next/ComposedModal-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/**
* 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 { mount } from 'enzyme';
import ComposedModal from './ComposedModal';
import { ModalHeader } from './ModalHeader';
import { ModalFooter } from '../ComposedModal';
import { settings } from 'carbon-components';

const { prefix } = settings;

describe('<ComposedModal />', () => {
let container;

afterEach(() => {
if (container && container.parentNode) {
container.parentNode.removeChild(container);
}
container = null;
});

it('renders', () => {
const wrapper = mount(<ComposedModal open />);
expect(wrapper).toMatchSnapshot();
});

it('changes the open state upon change in props', () => {
const wrapper = mount(<ComposedModal open />);

expect(
document.body.classList.contains('bx--body--with-modal-open')
).toEqual(true);
wrapper.setProps({ open: false });
expect(
document.body.classList.contains('bx--body--with-modal-open')
).toEqual(false);
});

it('should change class of <body> upon open state', () => {
const wrapper = mount(<ComposedModal open />);
expect(
document.body.classList.contains('bx--body--with-modal-open')
).toEqual(true);
wrapper.unmount();
expect(
document.body.classList.contains('bx--body--with-modal-open')
).toEqual(false);
mount(<ComposedModal open={false} />);
expect(
document.body.classList.contains('bx--body--with-modal-open')
).toEqual(false);
});

it('calls onClick upon user-initiated closing', () => {
const onClose = jest.fn();
const wrapper = mount(
<ComposedModal open onClose={onClose}>
<ModalHeader />
</ComposedModal>
);
const button = wrapper.find(`.${prefix}--modal-close`).first();
button.simulate('click');
expect(
document.body.classList.contains('bx--body--with-modal-open')
).toEqual(false);
expect(onClose.mock.calls.length).toBe(1);
});

it('provides a way to prevent upon user-initiated closing', () => {
const onClose = jest.fn(() => false);
const wrapper = mount(
<ComposedModal open onClose={onClose}>
<ModalHeader />
</ComposedModal>
);
const button = wrapper.find(`.${prefix}--modal-close`).first();
button.simulate('click');
expect(
document.body.classList.contains('bx--body--with-modal-open')
).toEqual(true);
});

it('should focus on the primary actionable button in ModalFooter by default', () => {
container = document.createElement('div');
container.id = 'container';
document.body.appendChild(container);
mount(
<ComposedModal open>
<ModalFooter primaryButtonText="Save" />
</ComposedModal>,
{ attachTo: document.querySelector('#container') }
);
expect(
document.activeElement.classList.contains(`${prefix}--btn--primary`)
).toEqual(true);
});

it('should focus on the element that matches selectorPrimaryFocus', () => {
container = document.createElement('div');
container.id = 'container';
document.body.appendChild(container);
mount(
<ComposedModal open selectorPrimaryFocus={`.${prefix}--modal-close`}>
<ModalHeader label="Optional Label" title="Example" />
<ModalFooter primaryButtonText="Save" />
</ComposedModal>,
{ attachTo: document.querySelector('#container') }
);
expect(
document.activeElement.classList.contains(`${prefix}--modal-close`)
).toEqual(true);
});
});
Loading

0 comments on commit 40f3768

Please sign in to comment.