Skip to content

Commit

Permalink
feat(AlertBanner): add className, onKeyDownClose, closeBtnProps and o…
Browse files Browse the repository at this point in the history
…therProps to container
  • Loading branch information
bfbiggs authored and pauljeter committed Jun 25, 2019
1 parent 80fa1e3 commit 7296c05
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 93 deletions.
6 changes: 3 additions & 3 deletions react/src/lib/Alert/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,20 @@ class Alert extends React.PureComponent {
}

Alert.defaultProps = {
dismissBtnProps: null,
closable: true,
dismissBtnProps: null,
message: '',
title: '',
type: 'info',
};

Alert.propTypes = {
/** @prop Props to be passed to dismiss button | null */
dismissBtnProps: PropTypes.object,
/** @prop Optional css class string | '' */
className: PropTypes.string,
/** @prop To show/hide Close button of the Alert | true */
closable: PropTypes.bool,
/** @prop Props to be passed to dismiss button | null */
dismissBtnProps: PropTypes.object,
/** @prop Optional Alert message | '' */
message: PropTypes.string,
/** @prop Set Alert visibility */
Expand Down
15 changes: 14 additions & 1 deletion react/src/lib/Alert/tests/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@ describe('tests for <Alert />', () => {
expect(container.find('.md-alert').length).toEqual(1);
});

it('should pass otherProps to container', () => {
const container = mount(<Alert show closable={false} id='testid' />);

expect(container.find('#testid').exists()).toEqual(true);
});

it('should pass className prop', () => {
const container = mount(<Alert show className='testing' closable={false} />);

expect(container.find('.testing').exists()).toEqual(true);
expect(container.find('Alert').hasClass('testing')).toEqual(true);
});

it('should render title', () => {
const container = shallow(<Alert show title="test" />);

Expand Down Expand Up @@ -66,7 +79,7 @@ describe('tests for <Alert />', () => {
expect(count).toEqual(1);
});

it('should pass otherProps prop', () => {
it('should pass dismissBtnProps prop', () => {
const container = mount(<Alert show type="error" dismissBtnProps={{ ariaLabel: 'test' }} />);

expect(container.find('Button').props().ariaLabel).toEqual('test');
Expand Down
94 changes: 64 additions & 30 deletions react/src/lib/AlertBanner/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,57 +5,91 @@ import PropTypes from 'prop-types';
import { Icon } from '@momentum-ui/react';

const AlertBanner = props => {
const { show, type, closable, children, onHide } = props;

const handleKeyPress = e => {
e.preventDefault();
if (e.which === 32 || e.which === 13) {
return onHide(e);
} else if (e.charCode === 32 || e.charCode === 13) {
return onHide(e);
const {
className,
closable,
closeBtnProps,
children,
onHide,
onKeyDownClose,
show,
type,
...otherProps
} = props;

const handleKeyDown = e => {
if (
e.which === 32
|| e.charCode === 32
|| e.which === 13
|| e.charCode === 13
) {
onHide && onHide(e);
e.preventDefault();
}

onKeyDownClose && onKeyDownClose(e);
};

return (
show && (
<div type={type}>
<div className={`md-alert-banner ` + `md-alert-banner--${type}`}>
<div className="md-alert-banner__text">{children}</div>
{closable && (
<div
className="md-alert-banner__close"
onClick={onHide}
tabIndex={0}
onKeyPress={handleKeyPress}
role={'button'}
>
<Icon name="cancel_16"/>
</div>
)}
<div
className={
`md-alert-banner` +
` md-alert-banner--${type}` +
`${(className && ` ${className}`) || ''}`
}
{...otherProps}
>
<div className='md-alert-banner__text'>
{children}
</div>
{closable && (
<div
className='md-alert-banner__close'
{...onHide && { onClick: e => onHide(e) }}
{...(onHide || onKeyDownClose) && {
onKeyDown: e => handleKeyDown(e),
role: 'button',
tabIndex: 0
}}
{...closeBtnProps}
>
<Icon name='cancel_16'/>
</div>
)}
</div>
)
);
};

AlertBanner.defaultProps = {
children: null,
type: 'info',
className: '',
closable: false,
onHide: () => {},
closeBtnProps: null,
onKeyDownClose: null,
onHide: null,
type: 'info',
};

AlertBanner.propTypes = {
/** @prop Set AlertBanner visibility */
show: PropTypes.bool.isRequired,
/** @prop Optional css class string | '' */
className: PropTypes.string,
/** @prop Sets the visibility of AlertBanner's close button | false */
closable: PropTypes.bool,
/** @prop Props to be passed to close button | null */
closeBtnProps: PropTypes.object,
/** @prop Children nodes to render inside AccordionHeader | null */
children: PropTypes.node,
/** @prop Invoked when the user presses on the AlertBanner's close button | null */
onHide: PropTypes.func,
/** @prop Optional callback function invoked on keydown of close button | null */
onKeyDownClose: PropTypes.func,
/** @prop Set AlertBanner visibility */
show: PropTypes.bool.isRequired,
/** @prop Sets the AlertBanner type | 'info' */
type: PropTypes.oneOf(['info', 'warning', 'error']),
/** @prop Mandatory handler invoked when the user presses on the AlertBanner's close button or hit's the esc key | () => {} */
onHide: PropTypes.func,
/** @prop Sets the visibility of AlertBanner's close button | false */
closable: PropTypes.bool,
};

AlertBanner.displayName = 'AlertBanner';
Expand Down
87 changes: 28 additions & 59 deletions react/src/lib/AlertBanner/tests/__snapshots__/index.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ exports[`tests for <AlertBanner /> should match SnapShot 1`] = `
ShallowWrapper {
Symbol(enzyme.__root__): [Circular],
Symbol(enzyme.__unrendered__): <AlertBanner
className=""
closable={false}
onHide={[Function]}
closeBtnProps={null}
onHide={null}
onKeyDownClose={null}
show={true}
type="info"
/>,
Expand All @@ -23,17 +26,34 @@ ShallowWrapper {
"key": undefined,
"nodeType": "host",
"props": Object {
"children": <div
className="md-alert-banner md-alert-banner--info"
>
"children": Array [
<div
className="md-alert-banner__text"
/>
</div>,
"type": "info",
/>,
false,
],
"className": "md-alert-banner md-alert-banner--info",
},
"ref": null,
"rendered": Object {
"rendered": Array [
Object {
"instance": null,
"key": undefined,
"nodeType": "host",
"props": Object {
"children": null,
"className": "md-alert-banner__text",
},
"ref": null,
"rendered": null,
"type": "div",
},
false,
],
"type": "div",
},
Symbol(enzyme.__nodes__): Array [
Object {
"instance": null,
"key": undefined,
"nodeType": "host",
Expand Down Expand Up @@ -64,57 +84,6 @@ ShallowWrapper {
],
"type": "div",
},
"type": "div",
},
Symbol(enzyme.__nodes__): Array [
Object {
"instance": null,
"key": undefined,
"nodeType": "host",
"props": Object {
"children": <div
className="md-alert-banner md-alert-banner--info"
>
<div
className="md-alert-banner__text"
/>
</div>,
"type": "info",
},
"ref": null,
"rendered": Object {
"instance": null,
"key": undefined,
"nodeType": "host",
"props": Object {
"children": Array [
<div
className="md-alert-banner__text"
/>,
false,
],
"className": "md-alert-banner md-alert-banner--info",
},
"ref": null,
"rendered": Array [
Object {
"instance": null,
"key": undefined,
"nodeType": "host",
"props": Object {
"children": null,
"className": "md-alert-banner__text",
},
"ref": null,
"rendered": null,
"type": "div",
},
false,
],
"type": "div",
},
"type": "div",
},
],
Symbol(enzyme.__options__): Object {
"adapter": ReactSixteenAdapter {
Expand Down
75 changes: 75 additions & 0 deletions react/src/lib/AlertBanner/tests/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,25 @@ describe('tests for <AlertBanner />', () => {
expect(container).toMatchSnapshot();
});

it('should pass className prop', () => {
const container = mount(<AlertBanner show className='testing' />);

expect(container.find('.testing').exists()).toEqual(true);
expect(container.find('AlertBanner').hasClass('testing')).toEqual(true);
});

it('should pass closeBtnProps', () => {
const container = mount(<AlertBanner show closable closeBtnProps={{ 'aria-label': 'test' }} />);

expect(container.find('.md-alert-banner__close').props()['aria-label']).toEqual('test');
});

it('should pass otherProps to container', () => {
const container = mount(<AlertBanner show id='testid' />);

expect(container.find('#testid').exists()).toEqual(true);
});

it('should default to type "info"', () => {
const container = shallow(<AlertBanner show />);

Expand Down Expand Up @@ -49,4 +68,60 @@ describe('tests for <AlertBanner />', () => {
container.find('.md-alert-banner__close').simulate('click');
expect(onClose).toHaveBeenCalled();
});

it('should close the banner on keyDown of Space', () => {
const onClose = jest.fn();

const container = mount(
<AlertBanner type="info" closable show onHide={onClose}>
ShowBanner
</AlertBanner>
);

container.find('.md-alert-banner__close').simulate('keyDown', { which: 13 });
expect(onClose).toHaveBeenCalled();
container.find('.md-alert-banner__close').simulate('keyDown', { charCode: 13 });
expect(onClose).toHaveBeenCalledTimes(2);
});

it('should close the banner on keyDown of Enter', () => {
const onClose = jest.fn();

const container = mount(
<AlertBanner type="info" closable show onHide={onClose}>
ShowBanner
</AlertBanner>
);

container.find('.md-alert-banner__close').simulate('keyDown', { which: 32 });
expect(onClose).toHaveBeenCalled();
container.find('.md-alert-banner__close').simulate('keyDown', { charCode: 32 });
expect(onClose).toHaveBeenCalledTimes(2);
});

it('should do nothing on keyDown of letter d', () => {
const onClose = jest.fn();

const container = mount(
<AlertBanner type="info" closable show onHide={onClose}>
ShowBanner
</AlertBanner>
);

container.find('.md-alert-banner__close').simulate('keyDown', { which: 100 });
expect(onClose).toHaveBeenCalledTimes(0);
});

it('should pass onKeyDownClose function', () => {
const onKeyDown = jest.fn();

const container = mount(
<AlertBanner type="info" closable show onKeyDownClose={onKeyDown}>
ShowBanner
</AlertBanner>
);

container.find('.md-alert-banner__close').simulate('keyDown', { which: 100 });
expect(onKeyDown).toHaveBeenCalled();
});
});

0 comments on commit 7296c05

Please sign in to comment.