import * as env from 'exenv' import * as PropTypes from 'prop-types' import * as React from 'react' import { instance } from './lib/index' import { InputEventListener, InputTargetElement } from './types' interface EventStackProps { /** An event name on which we will subscribe. */ name: string /** An event handler or array of event handlers. */ on: InputEventListener /** A name of pool. */ pool?: string /** A DOM element on which we will subscribe. */ target?: InputTargetElement } /** * This component exposes the EventStack API as public and provides a declarative way to manage it. */ export default class EventStack extends React.PureComponent { static propTypes = { /** An event name on which we will subscribe. */ name: PropTypes.string.isRequired, /** An event handler or array of event handlers. */ on: PropTypes.oneOfType([PropTypes.func, PropTypes.arrayOf(PropTypes.func)]).isRequired, /** A name of pool. */ pool: PropTypes.string, /** A DOM element on which we will subscribe. */ target: PropTypes.oneOfType([ PropTypes.oneOf(['document', 'window']), // Heads up! // This condition for SSR safety. PropTypes.instanceOf(env.canUseDOM ? HTMLElement : Object), PropTypes.shape({ current: PropTypes.object, }) ]), } static defaultProps = { pool: 'default', target: 'document', } componentDidMount() { this.subscribe(this.props) } componentDidUpdate(prevProps: EventStackProps) { this.unsubscribe(prevProps) this.subscribe(this.props) } componentWillUnmount() { this.unsubscribe(this.props) } subscribe(props: Readonly) { const { name, on, pool, target } = props instance.sub(name, on, { pool, target }) } unsubscribe(props: Readonly) { const { name, on, pool, target } = props instance.unsub(name, on, { pool, target }) } render() { return null } }