Created
April 19, 2018 19:16
-
-
Save GeDiez/62dc5c97893aeb0591f8a6131a72786b to your computer and use it in GitHub Desktop.
MAIN FUNCTION: HOC NucleusWrapper @description it HOC lets add custom events to html tags. @Usage you only need to import the HOC as follow: import NucleusWrapper from '../NucleusWrapper' then make a component with: const MiComponent = NucleusWrapper('mi-component') notice: this HOC just receives string tag as parameters. finally you can add you…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
MAIN FUCTION: HOC NucleusWrapper | |
@description | |
it HOC lets add custom events to html tags. | |
@usage | |
you only need to import the HOC as follow: | |
import NucleusWrapper from '../NucleusWrapper' | |
then make a component with: | |
const MiComponent = NucleusWrapper('mi-component') | |
notice: this HOC just receives string tag as parameters. | |
finally you can add your events like any React component, for example: | |
if you has a event named customClick you should add a prop in this way | |
<MiComponent onCustomClick={() => {}}>text o node of React</MiComponent> | |
it has two RESTRICTIONS: | |
1.- your custom event should be pass with "on- prefix and use camelcase | |
2.- the value of prop should be a function | |
*/ | |
import React, { Component } from 'react'; | |
import PropTypes from 'prop-types'; | |
/** | |
* getEvents: receives all props it filter | |
* regarding restrictions mentioned above | |
*/ | |
const getEvents = props => { | |
const keys = Object.keys(props); | |
if (keys.length === 0) return false; | |
return keys.reduce((arr, key) => { | |
const callback = props[key]; | |
const name = key.replace(/^on[A-Z]/, substr => | |
substr.slice(-1).toLowerCase() | |
); | |
if (!!key.match(/^on[A-Z]/) !== true || typeof callback !== 'function') | |
return arr; | |
return [...arr, { name, callback }]; | |
}, []); | |
}; | |
const bindEventsToElement = (element, events) => { | |
events.forEach(event => { | |
element.addEventListener(event.name, event.callback); | |
}); | |
}; | |
const removeEventsToElement = (element, events) => { | |
events.forEach(event => { | |
element.removeEventListener(event.name, event.callback); | |
}); | |
}; | |
const NucleusWrapper = Tag => | |
class extends Component { | |
static propTypes = { | |
children: PropTypes.node, | |
}; | |
static defaultProps = { | |
children: null, | |
}; | |
constructor(props) { | |
super(props); | |
this.events = getEvents(props); | |
} | |
componentDidMount() { | |
bindEventsToElement(this.tag, this.events); | |
} | |
componentWillUnmount() { | |
removeEventsToElement(this.events); | |
} | |
render() { | |
const { children } = this.props; | |
return ( | |
<Tag | |
ref={e => { | |
this.tag = e; | |
}} | |
{...this.props} | |
> | |
{children} | |
</Tag> | |
); | |
} | |
}; | |
export default NucleusWrapper; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment