first commit
This commit is contained in:
368
frontend/node_modules/rc-picker/es/PickerInput/Selector/Input.js
generated
vendored
Normal file
368
frontend/node_modules/rc-picker/es/PickerInput/Selector/Input.js
generated
vendored
Normal file
@@ -0,0 +1,368 @@
|
||||
import _extends from "@babel/runtime/helpers/esm/extends";
|
||||
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
||||
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
||||
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
|
||||
var _excluded = ["active", "showActiveCls", "suffixIcon", "format", "validateFormat", "onChange", "onInput", "helped", "onHelp", "onSubmit", "onKeyDown", "preserveInvalidOnBlur", "invalid", "clearIcon"];
|
||||
import classNames from 'classnames';
|
||||
import { useEvent } from 'rc-util';
|
||||
import useLayoutEffect from "rc-util/es/hooks/useLayoutEffect";
|
||||
import raf from "rc-util/es/raf";
|
||||
import * as React from 'react';
|
||||
import { leftPad } from "../../utils/miscUtil";
|
||||
import PickerContext from "../context";
|
||||
import useLockEffect from "../hooks/useLockEffect";
|
||||
import Icon from "./Icon";
|
||||
import MaskFormat from "./MaskFormat";
|
||||
import { getMaskRange } from "./util";
|
||||
|
||||
// Format logic
|
||||
//
|
||||
// First time on focus:
|
||||
// 1. check if the text is valid, if not fill with format
|
||||
// 2. set highlight cell to the first cell
|
||||
// Cells
|
||||
// 1. Selection the index cell, set inner `cacheValue` to ''
|
||||
// 2. Key input filter non-number char, patch after the `cacheValue`
|
||||
// 1. Replace the `cacheValue` with input align the cell length
|
||||
// 2. Re-selection the mask cell
|
||||
// 3. If `cacheValue` match the limit length or cell format (like 1 ~ 12 month), go to next cell
|
||||
|
||||
var Input = /*#__PURE__*/React.forwardRef(function (props, ref) {
|
||||
var active = props.active,
|
||||
_props$showActiveCls = props.showActiveCls,
|
||||
showActiveCls = _props$showActiveCls === void 0 ? true : _props$showActiveCls,
|
||||
suffixIcon = props.suffixIcon,
|
||||
format = props.format,
|
||||
validateFormat = props.validateFormat,
|
||||
onChange = props.onChange,
|
||||
onInput = props.onInput,
|
||||
helped = props.helped,
|
||||
onHelp = props.onHelp,
|
||||
onSubmit = props.onSubmit,
|
||||
onKeyDown = props.onKeyDown,
|
||||
_props$preserveInvali = props.preserveInvalidOnBlur,
|
||||
preserveInvalidOnBlur = _props$preserveInvali === void 0 ? false : _props$preserveInvali,
|
||||
invalid = props.invalid,
|
||||
clearIcon = props.clearIcon,
|
||||
restProps = _objectWithoutProperties(props, _excluded);
|
||||
var value = props.value,
|
||||
onFocus = props.onFocus,
|
||||
onBlur = props.onBlur,
|
||||
onMouseUp = props.onMouseUp;
|
||||
var _React$useContext = React.useContext(PickerContext),
|
||||
prefixCls = _React$useContext.prefixCls,
|
||||
_React$useContext$inp = _React$useContext.input,
|
||||
Component = _React$useContext$inp === void 0 ? 'input' : _React$useContext$inp;
|
||||
var inputPrefixCls = "".concat(prefixCls, "-input");
|
||||
|
||||
// ======================== Value =========================
|
||||
var _React$useState = React.useState(false),
|
||||
_React$useState2 = _slicedToArray(_React$useState, 2),
|
||||
focused = _React$useState2[0],
|
||||
setFocused = _React$useState2[1];
|
||||
var _React$useState3 = React.useState(value),
|
||||
_React$useState4 = _slicedToArray(_React$useState3, 2),
|
||||
internalInputValue = _React$useState4[0],
|
||||
setInputValue = _React$useState4[1];
|
||||
var _React$useState5 = React.useState(''),
|
||||
_React$useState6 = _slicedToArray(_React$useState5, 2),
|
||||
focusCellText = _React$useState6[0],
|
||||
setFocusCellText = _React$useState6[1];
|
||||
var _React$useState7 = React.useState(null),
|
||||
_React$useState8 = _slicedToArray(_React$useState7, 2),
|
||||
focusCellIndex = _React$useState8[0],
|
||||
setFocusCellIndex = _React$useState8[1];
|
||||
var _React$useState9 = React.useState(null),
|
||||
_React$useState10 = _slicedToArray(_React$useState9, 2),
|
||||
forceSelectionSyncMark = _React$useState10[0],
|
||||
forceSelectionSync = _React$useState10[1];
|
||||
var inputValue = internalInputValue || '';
|
||||
|
||||
// Sync value if needed
|
||||
React.useEffect(function () {
|
||||
setInputValue(value);
|
||||
}, [value]);
|
||||
|
||||
// ========================= Refs =========================
|
||||
var holderRef = React.useRef();
|
||||
var inputRef = React.useRef();
|
||||
React.useImperativeHandle(ref, function () {
|
||||
return {
|
||||
nativeElement: holderRef.current,
|
||||
inputElement: inputRef.current,
|
||||
focus: function focus(options) {
|
||||
inputRef.current.focus(options);
|
||||
},
|
||||
blur: function blur() {
|
||||
inputRef.current.blur();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// ======================== Format ========================
|
||||
var maskFormat = React.useMemo(function () {
|
||||
return new MaskFormat(format || '');
|
||||
}, [format]);
|
||||
var _React$useMemo = React.useMemo(function () {
|
||||
if (helped) {
|
||||
return [0, 0];
|
||||
}
|
||||
return maskFormat.getSelection(focusCellIndex);
|
||||
}, [maskFormat, focusCellIndex, helped]),
|
||||
_React$useMemo2 = _slicedToArray(_React$useMemo, 2),
|
||||
selectionStart = _React$useMemo2[0],
|
||||
selectionEnd = _React$useMemo2[1];
|
||||
|
||||
// ======================== Modify ========================
|
||||
// When input modify content, trigger `onHelp` if is not the format
|
||||
var onModify = function onModify(text) {
|
||||
if (text && text !== format && text !== value) {
|
||||
onHelp();
|
||||
}
|
||||
};
|
||||
|
||||
// ======================== Change ========================
|
||||
/**
|
||||
* Triggered by paste, keyDown and focus to show format
|
||||
*/
|
||||
var triggerInputChange = useEvent(function (text) {
|
||||
if (validateFormat(text)) {
|
||||
onChange(text);
|
||||
}
|
||||
setInputValue(text);
|
||||
onModify(text);
|
||||
});
|
||||
|
||||
// Directly trigger `onChange` if `format` is empty
|
||||
var onInternalChange = function onInternalChange(event) {
|
||||
// Hack `onChange` with format to do nothing
|
||||
if (!format) {
|
||||
var text = event.target.value;
|
||||
onModify(text);
|
||||
setInputValue(text);
|
||||
onChange(text);
|
||||
}
|
||||
};
|
||||
var onFormatPaste = function onFormatPaste(event) {
|
||||
// Get paste text
|
||||
var pasteText = event.clipboardData.getData('text');
|
||||
if (validateFormat(pasteText)) {
|
||||
triggerInputChange(pasteText);
|
||||
}
|
||||
};
|
||||
|
||||
// ======================== Mouse =========================
|
||||
// When `mouseDown` get focus, it's better to not to change the selection
|
||||
// Since the up position maybe not is the first cell
|
||||
var mouseDownRef = React.useRef(false);
|
||||
var onFormatMouseDown = function onFormatMouseDown() {
|
||||
mouseDownRef.current = true;
|
||||
};
|
||||
var onFormatMouseUp = function onFormatMouseUp(event) {
|
||||
var _ref = event.target,
|
||||
start = _ref.selectionStart;
|
||||
var closeMaskIndex = maskFormat.getMaskCellIndex(start);
|
||||
setFocusCellIndex(closeMaskIndex);
|
||||
|
||||
// Force update the selection
|
||||
forceSelectionSync({});
|
||||
onMouseUp === null || onMouseUp === void 0 || onMouseUp(event);
|
||||
mouseDownRef.current = false;
|
||||
};
|
||||
|
||||
// ====================== Focus Blur ======================
|
||||
var onFormatFocus = function onFormatFocus(event) {
|
||||
setFocused(true);
|
||||
setFocusCellIndex(0);
|
||||
setFocusCellText('');
|
||||
onFocus(event);
|
||||
};
|
||||
var onSharedBlur = function onSharedBlur(event) {
|
||||
onBlur(event);
|
||||
};
|
||||
var onFormatBlur = function onFormatBlur(event) {
|
||||
setFocused(false);
|
||||
onSharedBlur(event);
|
||||
};
|
||||
|
||||
// ======================== Active ========================
|
||||
// Check if blur need reset input value
|
||||
useLockEffect(active, function () {
|
||||
if (!active && !preserveInvalidOnBlur) {
|
||||
setInputValue(value);
|
||||
}
|
||||
});
|
||||
|
||||
// ======================= Keyboard =======================
|
||||
var onSharedKeyDown = function onSharedKeyDown(event) {
|
||||
if (event.key === 'Enter' && validateFormat(inputValue)) {
|
||||
onSubmit();
|
||||
}
|
||||
onKeyDown === null || onKeyDown === void 0 || onKeyDown(event);
|
||||
};
|
||||
var onFormatKeyDown = function onFormatKeyDown(event) {
|
||||
onSharedKeyDown(event);
|
||||
var key = event.key;
|
||||
|
||||
// Save the cache with cell text
|
||||
var nextCellText = null;
|
||||
|
||||
// Fill in the input
|
||||
var nextFillText = null;
|
||||
var maskCellLen = selectionEnd - selectionStart;
|
||||
var cellFormat = format.slice(selectionStart, selectionEnd);
|
||||
|
||||
// Cell Index
|
||||
var offsetCellIndex = function offsetCellIndex(offset) {
|
||||
setFocusCellIndex(function (idx) {
|
||||
var nextIndex = idx + offset;
|
||||
nextIndex = Math.max(nextIndex, 0);
|
||||
nextIndex = Math.min(nextIndex, maskFormat.size() - 1);
|
||||
return nextIndex;
|
||||
});
|
||||
};
|
||||
|
||||
// Range
|
||||
var offsetCellValue = function offsetCellValue(offset) {
|
||||
var _getMaskRange = getMaskRange(cellFormat),
|
||||
_getMaskRange2 = _slicedToArray(_getMaskRange, 3),
|
||||
rangeStart = _getMaskRange2[0],
|
||||
rangeEnd = _getMaskRange2[1],
|
||||
rangeDefault = _getMaskRange2[2];
|
||||
var currentText = inputValue.slice(selectionStart, selectionEnd);
|
||||
var currentTextNum = Number(currentText);
|
||||
if (isNaN(currentTextNum)) {
|
||||
return String(rangeDefault ? rangeDefault : offset > 0 ? rangeStart : rangeEnd);
|
||||
}
|
||||
var num = currentTextNum + offset;
|
||||
var range = rangeEnd - rangeStart + 1;
|
||||
return String(rangeStart + (range + num - rangeStart) % range);
|
||||
};
|
||||
switch (key) {
|
||||
// =============== Remove ===============
|
||||
case 'Backspace':
|
||||
case 'Delete':
|
||||
nextCellText = '';
|
||||
nextFillText = cellFormat;
|
||||
break;
|
||||
|
||||
// =============== Arrows ===============
|
||||
// Left key
|
||||
case 'ArrowLeft':
|
||||
nextCellText = '';
|
||||
offsetCellIndex(-1);
|
||||
break;
|
||||
|
||||
// Right key
|
||||
case 'ArrowRight':
|
||||
nextCellText = '';
|
||||
offsetCellIndex(1);
|
||||
break;
|
||||
|
||||
// Up key
|
||||
case 'ArrowUp':
|
||||
nextCellText = '';
|
||||
nextFillText = offsetCellValue(1);
|
||||
break;
|
||||
|
||||
// Down key
|
||||
case 'ArrowDown':
|
||||
nextCellText = '';
|
||||
nextFillText = offsetCellValue(-1);
|
||||
break;
|
||||
|
||||
// =============== Number ===============
|
||||
default:
|
||||
if (!isNaN(Number(key))) {
|
||||
nextCellText = focusCellText + key;
|
||||
nextFillText = nextCellText;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Update cell text
|
||||
if (nextCellText !== null) {
|
||||
setFocusCellText(nextCellText);
|
||||
if (nextCellText.length >= maskCellLen) {
|
||||
// Go to next cell
|
||||
offsetCellIndex(1);
|
||||
setFocusCellText('');
|
||||
}
|
||||
}
|
||||
|
||||
// Update the input text
|
||||
if (nextFillText !== null) {
|
||||
// Replace selection range with `nextCellText`
|
||||
var nextFocusValue =
|
||||
// before
|
||||
inputValue.slice(0, selectionStart) +
|
||||
// replace
|
||||
leftPad(nextFillText, maskCellLen) +
|
||||
// after
|
||||
inputValue.slice(selectionEnd);
|
||||
triggerInputChange(nextFocusValue.slice(0, format.length));
|
||||
}
|
||||
|
||||
// Always trigger selection sync after key down
|
||||
forceSelectionSync({});
|
||||
};
|
||||
|
||||
// ======================== Format ========================
|
||||
var rafRef = React.useRef();
|
||||
useLayoutEffect(function () {
|
||||
if (!focused || !format || mouseDownRef.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset with format if not match
|
||||
if (!maskFormat.match(inputValue)) {
|
||||
triggerInputChange(format);
|
||||
return;
|
||||
}
|
||||
|
||||
// Match the selection range
|
||||
inputRef.current.setSelectionRange(selectionStart, selectionEnd);
|
||||
|
||||
// Chrome has the bug anchor position looks not correct but actually correct
|
||||
rafRef.current = raf(function () {
|
||||
inputRef.current.setSelectionRange(selectionStart, selectionEnd);
|
||||
});
|
||||
return function () {
|
||||
raf.cancel(rafRef.current);
|
||||
};
|
||||
}, [maskFormat, format, focused, inputValue, focusCellIndex, selectionStart, selectionEnd, forceSelectionSyncMark, triggerInputChange]);
|
||||
|
||||
// ======================== Render ========================
|
||||
// Input props for format
|
||||
var inputProps = format ? {
|
||||
onFocus: onFormatFocus,
|
||||
onBlur: onFormatBlur,
|
||||
onKeyDown: onFormatKeyDown,
|
||||
onMouseDown: onFormatMouseDown,
|
||||
onMouseUp: onFormatMouseUp,
|
||||
onPaste: onFormatPaste
|
||||
} : {};
|
||||
return /*#__PURE__*/React.createElement("div", {
|
||||
ref: holderRef,
|
||||
className: classNames(inputPrefixCls, _defineProperty(_defineProperty({}, "".concat(inputPrefixCls, "-active"), active && showActiveCls), "".concat(inputPrefixCls, "-placeholder"), helped))
|
||||
}, /*#__PURE__*/React.createElement(Component, _extends({
|
||||
ref: inputRef,
|
||||
"aria-invalid": invalid,
|
||||
autoComplete: "off"
|
||||
}, restProps, {
|
||||
onKeyDown: onSharedKeyDown,
|
||||
onBlur: onSharedBlur
|
||||
// Replace with format
|
||||
}, inputProps, {
|
||||
// Value
|
||||
value: inputValue,
|
||||
onChange: onInternalChange
|
||||
})), /*#__PURE__*/React.createElement(Icon, {
|
||||
type: "suffix",
|
||||
icon: suffixIcon
|
||||
}), clearIcon);
|
||||
});
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
Input.displayName = 'Input';
|
||||
}
|
||||
export default Input;
|
||||
Reference in New Issue
Block a user