[UI Framework] KuiGalleryItem automatically becomes link or button (#14240)

* KuiGalleryItem automatically becomes link or button

* Add onClick tests

* Add doc example with onClick
This commit is contained in:
Tim Roes 2017-10-12 10:22:31 +02:00 committed by Tim Roes
parent b15d12ac23
commit b05549a002
5 changed files with 99 additions and 14 deletions

View file

@ -43,7 +43,7 @@ export default () => {
</KuiGalleryItemLabel>
</KuiGalleryItem>
<KuiGalleryItem>
<KuiGalleryItem onClick={() => window.alert('Clicked an item')}>
<KuiGalleryItemImage style={imageStyle}/>
<KuiGalleryItemLabel>

View file

@ -2,6 +2,7 @@ import React from 'react';
import { renderToHtml } from '../../services';
import {
GuideCode,
GuideDemo,
GuidePage,
GuideSection,
@ -27,7 +28,15 @@ export default props => (
>
<GuideText>
Use GalleryItem to show a gallery item.
It&rsquo;s an anchor and accepts all anchor properties.
If you specify an <GuideCode>href</GuideCode> property the item will render
as an HTML <GuideCode>a</GuideCode> element. If not, it will be rendered
as a <GuideCode>button</GuideCode> and you can attach an
<GuideCode>onClick</GuideCode> listener to it.
</GuideText>
<GuideText>
<strong>Note:</strong> You are not allowed to specify the <GuideCode>href</GuideCode> property
and the <GuideCode>onClick</GuideCode> property at the same time.
</GuideText>
<GuideDemo>

View file

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders KuiGalleryItem href 1`] = `
exports[`renders KuiGalleryItem with href 1`] = `
<a
aria-label="aria-label"
class="kuiGalleryItem testClass1 testClass2"
@ -10,3 +10,23 @@ exports[`renders KuiGalleryItem href 1`] = `
children
</a>
`;
exports[`renders KuiGalleryItem with onClick 1`] = `
<button
aria-label="aria-label"
class="kuiGalleryItem testClass1 testClass2"
data-test-subj="test subject string"
>
children
</button>
`;
exports[`renders KuiGalleryItem without href and onClick 1`] = `
<button
aria-label="aria-label"
class="kuiGalleryItem testClass1 testClass2"
data-test-subj="test subject string"
>
children
</button>
`;

View file

@ -2,18 +2,41 @@ import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
export const KuiGalleryItem = ({ children, className, ...rest }) => {
const checkHrefAndOnClick = (props, propName, componentName) => {
if (props.href && props.onClick) {
throw new Error(
`${componentName} must either specify an href property (if it should be a link) ` +
`or an onClick property (if it should be a button), but not both.`
);
}
};
export const KuiGalleryItem = ({ children, className, href, ...rest }) => {
const classes = classNames('kuiGalleryItem', className);
return (
<a
className={classes}
{...rest}
>
{children}
</a>
);
if (href) {
return (
<a
className={classes}
href={href}
{...rest}
>
{children}
</a>
);
} else {
return (
<button
className={classes}
{...rest}
>
{children}
</button>
);
}
};
KuiGalleryItem.propTypes = {
children: PropTypes.node,
className: PropTypes.string,
href: checkHrefAndOnClick,
onClick: PropTypes.func,
};

View file

@ -1,12 +1,45 @@
import React from 'react';
import { render } from 'enzyme';
import sinon from 'sinon';
import { render, shallow } from 'enzyme';
import { requiredProps } from '../../../test/required_props';
import {
KuiGalleryItem,
} from './gallery_item';
test('renders KuiGalleryItem href', () => {
test('renders KuiGalleryItem with href', () => {
const component = <KuiGalleryItem href="#" {...requiredProps}>children</KuiGalleryItem>;
expect(render(component)).toMatchSnapshot();
});
test('renders KuiGalleryItem with onClick', () => {
const component = <KuiGalleryItem onClick={() => {}} {...requiredProps}>children</KuiGalleryItem>;
expect(render(component)).toMatchSnapshot();
});
test('renders KuiGalleryItem without href and onClick', () => {
const component = <KuiGalleryItem {...requiredProps}>children</KuiGalleryItem>;
expect(render(component)).toMatchSnapshot();
});
test('onClick on KuiGalleryItem is not triggered without click', () => {
const onClickSpy = sinon.spy();
render(<KuiGalleryItem onClick={onClickSpy} {...requiredProps}>children</KuiGalleryItem>);
sinon.assert.notCalled(onClickSpy);
});
test('onClick on KuiGalleryItem is triggered when clicked', () => {
const onClickSpy = sinon.spy();
const element = shallow(<KuiGalleryItem onClick={onClickSpy} {...requiredProps}>children</KuiGalleryItem>);
element.simulate('click');
sinon.assert.calledOnce(onClickSpy);
});
test('KuiGalleryItem will throw when specified href and onClick', () => {
const consoleError = sinon.stub(console, 'error');
render(<KuiGalleryItem href="#" onClick={() => {}} {...requiredProps}>children</KuiGalleryItem>);
expect(consoleError.calledOnce).toBe(true);
const msg = consoleError.getCalls()[0].args[0];
expect(msg).toContain('Failed prop type');
console.error.restore();
});