nornj-react
Version:
React bindings for NornJ template engine.
97 lines (85 loc) • 2.76 kB
JavaScript
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import nj, { registerExtension } from 'nornj';
import React, { Component } from 'react';
import { debounce } from '../utils';
class DebounceWrapClass extends Component {
constructor(props) {
super(props);
this.componentConfig = void 0;
this.changeEventName = void 0;
this.$this = void 0;
this.emitChangeDebounced = void 0;
this.emitChange = args => {
this.props[this.changeEventName].apply(this.$this, args);
};
this.handleChange = this.handleChange.bind(this);
const {
debounceDirectiveOptions: {
tagName,
context: {
$this
},
props: directiveProps,
value
}
} = this.props;
const _args = directiveProps && directiveProps.arguments;
this.componentConfig = nj.getComponentConfig(tagName) || {};
this.changeEventName = _args && _args[0].name || this.componentConfig.changeEventName || 'onChange';
this.$this = $this;
this.emitChangeDebounced = debounce(this.emitChange, value() || 100);
}
componentDidUpdate(prevProps) {
const {
debounceDirectiveOptions: {
value: prevValue
}
} = prevProps;
const {
debounceDirectiveOptions: {
value
}
} = this.props;
const newValue = value();
if (newValue != null && newValue != prevValue()) {
this.emitChangeDebounced = debounce(this.emitChange, newValue);
}
}
handleChange(e) {
// React pools events, so we read the value before debounce.
// Alternately we could call `event.persist()` and pass the entire event.
// For more info see reactjs.org/docs/events.html#event-pooling
e && e.persist && e.persist();
this.emitChangeDebounced(arguments);
}
render() {
const {
DebounceTag,
debounceDirectiveOptions,
innerRef,
...others
} = this.props;
return React.createElement(DebounceTag, _extends({
ref: innerRef
}, others, {
[this.changeEventName]: this.handleChange
}));
}
}
const DebounceWrap = React.forwardRef((props, ref) => React.createElement(DebounceWrapClass, _extends({
innerRef: ref
}, props)));
registerExtension('debounce', options => {
const {
tagName,
setTagName,
tagProps
} = options;
setTagName(DebounceWrap);
tagProps.DebounceTag = tagName;
tagProps.debounceDirectiveOptions = options;
}, {
useExpressionInProps: true,
onlyGlobal: true,
isDirective: true
});