Skip to content

Commit

Permalink
Merge pull request #268 from miqh/feature/improve-badge
Browse files Browse the repository at this point in the history
Improve badge for click tracking and links
  • Loading branch information
tcbegley committed Oct 24, 2019
2 parents 44d79f2 + 4f3146a commit cdf342f
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 4 deletions.
50 changes: 46 additions & 4 deletions src/components/Badge.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
import React from 'react';
import PropTypes from 'prop-types';
import {omit} from 'ramda';
import {Badge as RSBadge} from 'reactstrap';
import Link from '../private/Link';

const Badge = props => {
const {children, loading_state, ...otherProps} = props;
const {children, href, loading_state, setProps, ...otherProps} = props;

const incrementClicks = () => {
if (setProps) {
setProps({
n_clicks: props.n_clicks + 1,
n_clicks_timestamp: Date.now()
});
}
};

otherProps[href ? 'preOnClick' : 'onClick'] = incrementClicks;

return (
<RSBadge
{...omit(['setProps'], otherProps)}
tag={href && Link}
href={href}
{...otherProps}
data-dash-is-loading={
(loading_state && loading_state.is_loading) || undefined
}
Expand All @@ -17,6 +31,11 @@ const Badge = props => {
);
};

Badge.defaultProps = {
n_clicks: 0,
n_clicks_timestamp: -1
};

Badge.propTypes = {
/**
* The ID of this component, used to identify dash components
Expand Down Expand Up @@ -84,7 +103,30 @@ Badge.propTypes = {
* Holds the name of the component that is loading
*/
component_name: PropTypes.string
})
}),

/**
* If true, the browser will treat this as an external link,
* forcing a page refresh at the new location. If false,
* this just changes the location without triggering a page
* refresh. Use this if you are observing dcc.Location, for
* instance. Defaults to true for absolute URLs and false
* otherwise.
*/
external_link: PropTypes.bool,

/**
* An integer that represents the number of times
* that this element has been clicked on.
*/
n_clicks: PropTypes.number,

/**
* An integer that represents the time (in ms since 1970)
* at which n_clicks changed. This can be used to tell
* which button was changed most recently.
*/
n_clicks_timestamp: PropTypes.number
};

export default Badge;
25 changes: 25 additions & 0 deletions src/components/__tests__/Badge.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import {mount, shallow} from 'enzyme';

import Badge from '../Badge';

describe('Badge', () => {
it('should track clicks', () => {
const mockSetProps = jest.fn();
const wrapper = shallow(<Badge setProps={mockSetProps}>Badge</Badge>);
wrapper.simulate('click');
expect(mockSetProps.mock.calls).toHaveLength(1);
expect(mockSetProps.mock.calls[0][0].n_clicks).toBe(1);
expect(typeof mockSetProps.mock.calls[0][0].n_clicks_timestamp).toBe(
'number'
);
});

it('should render as link when href is set', () => {
const href = '#href';
const wrapper = mount(<Badge href={href}>Badge</Badge>);
const linkComponent = wrapper.find('a');
expect(linkComponent.exists()).toBe(true);
expect(linkComponent.prop('href')).toEqual(href);
});
});

0 comments on commit cdf342f

Please sign in to comment.