Input reimplemented with hooks

This commit is contained in:
NikolaBorislavovHristov 2019-04-22 15:16:07 +03:00
parent e5d0289a70
commit 6c5c82a8d5
2 changed files with 44 additions and 54 deletions

View file

@ -1,7 +1,9 @@
const FocusableProvider = require('./FocusableProvider');
const useFocusable = require('./useFocusable');
const withFocusable = require('./withFocusable');
module.exports = {
FocusableProvider,
useFocusable,
withFocusable
};

View file

@ -1,6 +1,6 @@
const React = require('react');
const PropTypes = require('prop-types');
const { withFocusable } = require('../FocusableContext');
const { useFocusable } = require('../FocusableContext');
const ENTER_KEY_CODE = 13;
const BUTTON_INPUT_TYPES = ['button', 'link', 'submit', 'checkbox'];
@ -16,75 +16,63 @@ const TAG_NAMES_FOR_TYPE = {
search: 'input'
};
class Input extends React.PureComponent {
onKeyUp = (event) => {
if (typeof this.props.onKeyUp === 'function') {
this.props.onKeyUp(event);
const Input = React.forwardRef(({ type, children, ...props }, ref) => {
const onKeyUp = React.useCallback((event) => {
if (typeof props.onKeyUp === 'function') {
props.onKeyUp(event);
}
if (!event.defaultPrevented && event.which === ENTER_KEY_CODE) {
if (BUTTON_INPUT_TYPES.includes(this.props.type)) {
if (BUTTON_INPUT_TYPES.includes(type)) {
event.currentTarget.click();
} else if (TEXT_INPUT_TYPES.includes(this.props.type)) {
if (typeof this.props.onSubmit === 'function') {
this.props.onSubmit(event);
} else if (TEXT_INPUT_TYPES.includes(type)) {
if (typeof props.onSubmit === 'function') {
props.onSubmit(event);
}
}
}
}
onDrag = (event) => {
if (typeof this.props.onDrag === 'function') {
this.props.onDrag(event);
}, [props.onKeyUp, props.onSubmit, type]);
const onDrag = React.useCallback((event) => {
if (typeof props.onDrag === 'function') {
props.onDrag(event);
}
if (!event.defaultPrevented && BUTTON_INPUT_TYPES.includes(this.props.type)) {
if (!event.defaultPrevented && BUTTON_INPUT_TYPES.includes(type)) {
event.currentTarget.blur();
}
}
onMouseOut = (event) => {
if (typeof this.props.onMouseOut === 'function') {
this.props.onMouseOut(event);
}, [props.onDrag, type]);
const onMouseOut = React.useCallback((event) => {
if (typeof props.onMouseOut === 'function') {
props.onMouseOut(event);
}
if (!event.defaultPrevented && BUTTON_INPUT_TYPES.includes(this.props.type)) {
if (!event.defaultPrevented && BUTTON_INPUT_TYPES.includes(type)) {
event.currentTarget.blur();
}
}
render() {
const { forwardedRef, focusable, type, children, ...props } = this.props;
const tagName = TAG_NAMES_FOR_TYPE[type];
const elementProps = {
...props,
ref: forwardedRef,
type: tagName === 'input' ? type : null,
tabIndex: focusable ? 0 : -1,
onKeyUp: this.onKeyUp,
onDrag: this.onDrag,
onMouseOut: this.onMouseOut
};
return React.createElement(tagName, elementProps, children);
}
}
}, [props.onMouseOut, type]);
const focusable = useFocusable();
const tagName = TAG_NAMES_FOR_TYPE[type];
const elementProps = {
...props,
ref: ref,
type: tagName === 'input' ? type : null,
tabIndex: focusable ? 0 : -1,
onKeyUp: onKeyUp,
onDrag: onDrag,
onMouseOut: onMouseOut
};
return React.createElement(tagName, elementProps, children);
});
Input.propTypes = {
type: PropTypes.oneOf([...BUTTON_INPUT_TYPES, ...TEXT_INPUT_TYPES]).isRequired,
focusable: PropTypes.bool.isRequired
};
Input.defaultProps = {
focusable: false
type: PropTypes.oneOf([
...BUTTON_INPUT_TYPES,
...TEXT_INPUT_TYPES
]).isRequired,
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node
])
};
const InputWithFocusable = withFocusable(Input);
InputWithFocusable.displayName = 'InputWithFocusable';
const InputWithForwardedRef = React.forwardRef((props, ref) => (
<InputWithFocusable {...props} forwardedRef={ref} />
));
InputWithForwardedRef.displayName = 'InputWithForwardedRef';
module.exports = InputWithForwardedRef;
module.exports = Input;