@atlaskit/analytics-next
Version:
React components, HOCs and hooks to assist with tracking user activity with React components
121 lines • 4.47 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import React, { Component } from 'react';
import PropTypes from 'prop-types';
/**
* The withAnalytics HOC wraps a component and provides the `fireAnalyticsEvent`
* and `firePrivateAnalyticsEvent` methods to it as props. It contains the logic
* for how to fire events, including handling the analyticsId and analyticsData
* props. The `map` argument may be an object or a function that returns an object.
* The properties of the `map` object/result can be strings (the name of the event
* that will be fired) or functions (which are responsible for firing the event).
* You can specify a default `analyticsId` and `analyticsData` with the `defaultProps`
* param. Please be aware that specifying a default `analyticsId` will cause public
* events to always fire for your component unless it has been set to a falsy by
* the component consumer.
*
* @param WrappedComponent
* @param map
* @param defaultProps
* @param withDelegation
*/
const withAnalytics = (WrappedComponent, map = {}, defaultProps = {}, withDelegation) => {
var _WithAnalytics;
return _WithAnalytics = class WithAnalytics extends Component {
constructor(props) {
super(props);
_defineProperty(this, "delegateAnalyticsEvent", (analyticsId, data, isPrivate) => {
const {
onAnalyticsEvent
} = this.context;
if (!onAnalyticsEvent) {
return;
}
onAnalyticsEvent(analyticsId, data, isPrivate);
});
_defineProperty(this, "fireAnalyticsEvent", (name, data) => {
const {
analyticsData,
analyticsId
} = this.props;
const {
onAnalyticsEvent
} = this.context;
if (!analyticsId || !onAnalyticsEvent) {
return;
}
const eventData = {
...analyticsData,
...data
};
onAnalyticsEvent(`${analyticsId}.${name}`, eventData, false);
});
_defineProperty(this, "privateAnalyticsEvent", (name, data) => {
const {
onAnalyticsEvent
} = this.context;
if (!onAnalyticsEvent) {
return;
}
onAnalyticsEvent(`${name}`, data, true);
});
_defineProperty(this, "getParentAnalyticsData", name => {
const {
getParentAnalyticsData
} = this.context;
let parentData = {};
if (typeof getParentAnalyticsData === 'function' && this.props.analyticsId) {
const {
analyticsId
} = this.props;
parentData = getParentAnalyticsData(`${analyticsId}.${name}`, false);
}
return parentData;
});
this.state = {
evaluatedMap: {}
};
}
componentDidMount() {
this.setState({
evaluatedMap: typeof map === 'function' ? map(this.fireAnalyticsEvent) : map
});
}
render() {
const {
analyticsId,
analyticsData,
...componentProps
} = this.props;
Object.keys(this.state.evaluatedMap).forEach(prop => {
const handler = this.state.evaluatedMap[prop];
const originalProp = componentProps[prop];
componentProps[prop] = (...args) => {
if (typeof handler === 'function') {
handler(...args);
} else {
this.fireAnalyticsEvent(handler);
}
if (typeof originalProp === 'function') {
originalProp(...args);
}
};
});
return /*#__PURE__*/React.createElement(WrappedComponent, _extends({
fireAnalyticsEvent: this.fireAnalyticsEvent,
firePrivateAnalyticsEvent: this.privateAnalyticsEvent,
getParentAnalyticsData: this.getParentAnalyticsData,
delegateAnalyticsEvent: withDelegation ? this.delegateAnalyticsEvent : undefined,
analyticsId: analyticsId,
ref: this.props.innerRef
}, componentProps));
}
}, _defineProperty(_WithAnalytics, "displayName", `WithAnalytics(${WrappedComponent.displayName || WrappedComponent.name})`), _defineProperty(_WithAnalytics, "contextTypes", {
onAnalyticsEvent: PropTypes.func,
getParentAnalyticsData: PropTypes.func
}), _defineProperty(_WithAnalytics, "defaultProps", {
analyticsId: defaultProps.analyticsId,
analyticsData: defaultProps.analyticsData
}), _WithAnalytics;
};
export default withAnalytics;