UNPKG

@wordpress/components

Version:
256 lines (215 loc) 5.76 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _element = require("@wordpress/element"); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _lodash = require("lodash"); var _reactUseGesture = require("react-use-gesture"); var _keycodes = require("@wordpress/keycodes"); var _utils = require("./utils"); var _inputControlStyles = require("./styles/input-control-styles"); var _state = require("./state"); var _values = require("../utils/values"); var _utils2 = require("../utils"); /** * External dependencies */ /** * WordPress dependencies */ /** * Internal dependencies */ function InputField({ disabled = false, dragDirection = 'n', dragThreshold = 10, id, isDragEnabled = false, isFocused, isPressEnterToChange = false, onBlur = _lodash.noop, onChange = _lodash.noop, onDrag = _lodash.noop, onDragEnd = _lodash.noop, onDragStart = _lodash.noop, onFocus = _lodash.noop, onKeyDown = _lodash.noop, onValidate = _lodash.noop, size = 'default', setIsFocused, stateReducer = state => state, value: valueProp, type, ...props }, ref) { const { // State state, // Actions change, commit, drag, dragEnd, dragStart, invalidate, pressDown, pressEnter, pressUp, reset, update } = (0, _state.useInputControlStateReducer)(stateReducer, { isDragEnabled, value: valueProp, isPressEnterToChange }); const { _event, value, isDragging, isDirty } = state; const wasDirtyOnBlur = (0, _element.useRef)(false); const dragCursor = (0, _utils.useDragCursor)(isDragging, dragDirection); /* * Handles synchronization of external and internal value state. * If not focused and did not hold a dirty value[1] on blur * updates the value from the props. Otherwise if not holding * a dirty value[1] propagates the value and event through onChange. * [1] value is only made dirty if isPressEnterToChange is true */ (0, _utils2.useUpdateEffect)(() => { if (valueProp === value) { return; } if (!isFocused && !wasDirtyOnBlur.current) { update(valueProp); } else if (!isDirty) { onChange(value, { event: _event }); wasDirtyOnBlur.current = false; } }, [value, isDirty, isFocused, valueProp]); const handleOnBlur = event => { onBlur(event); setIsFocused(false); /** * If isPressEnterToChange is set, this commits the value to * the onChange callback. */ if (isPressEnterToChange && isDirty) { wasDirtyOnBlur.current = true; if (!(0, _values.isValueEmpty)(value)) { handleOnCommit(event); } else { reset(valueProp); } } }; const handleOnFocus = event => { onFocus(event); setIsFocused(true); }; const handleOnChange = event => { const nextValue = event.target.value; change(nextValue, event); }; const handleOnCommit = event => { const nextValue = event.target.value; try { onValidate(nextValue, event); commit(nextValue, event); } catch (err) { invalidate(err, event); } }; const handleOnKeyDown = event => { const { keyCode } = event; onKeyDown(event); switch (keyCode) { case _keycodes.UP: pressUp(event); break; case _keycodes.DOWN: pressDown(event); break; case _keycodes.ENTER: pressEnter(event); if (isPressEnterToChange) { event.preventDefault(); handleOnCommit(event); } break; } }; const dragGestureProps = (0, _reactUseGesture.useDrag)(dragProps => { const { distance, dragging, event } = dragProps; // The event is persisted to prevent errors in components using this // to check if a modifier key was held while dragging. event.persist(); if (!distance) return; event.stopPropagation(); /** * Quick return if no longer dragging. * This prevents unnecessary value calculations. */ if (!dragging) { onDragEnd(dragProps); dragEnd(dragProps); return; } onDrag(dragProps); drag(dragProps); if (!isDragging) { onDragStart(dragProps); dragStart(dragProps); } }, { threshold: dragThreshold, enabled: isDragEnabled }); const dragProps = isDragEnabled ? dragGestureProps() : {}; /* * Works around the odd UA (e.g. Firefox) that does not focus inputs of * type=number when their spinner arrows are pressed. */ let handleOnMouseDown; if (type === 'number') { handleOnMouseDown = event => { var _props$onMouseDown; (_props$onMouseDown = props.onMouseDown) === null || _props$onMouseDown === void 0 ? void 0 : _props$onMouseDown.call(props, event); if (event.target !== event.target.ownerDocument.activeElement) { event.target.focus(); } }; } return (0, _element.createElement)(_inputControlStyles.Input, (0, _extends2.default)({}, props, dragProps, { className: "components-input-control__input", disabled: disabled, dragCursor: dragCursor, isDragging: isDragging, id: id, onBlur: handleOnBlur, onChange: handleOnChange, onFocus: handleOnFocus, onKeyDown: handleOnKeyDown, onMouseDown: handleOnMouseDown, ref: ref, size: size, value: value, type: type })); } const ForwardedComponent = (0, _element.forwardRef)(InputField); var _default = ForwardedComponent; exports.default = _default; //# sourceMappingURL=input-field.js.map