preact-arco-design
Version:
Arco Design React UI Library.
621 lines (535 loc) • 17.7 kB
JavaScript
import _typeof from "@babel/runtime/helpers/typeof";
var __assign = this && this.__assign || function () {
__assign = Object.assign || function (t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) {
if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) {
function adopt(value) {
return value instanceof P ? value : new P(function (resolve) {
resolve(value);
});
}
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
}
function rejected(value) {
try {
step(generator["throw"](value));
} catch (e) {
reject(e);
}
}
function step(result) {
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
}
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = this && this.__generator || function (thisArg, body) {
var _ = {
label: 0,
sent: function sent() {
if (t[0] & 1) throw t[1];
return t[1];
},
trys: [],
ops: []
},
f,
y,
t,
g;
return g = {
next: verb(0),
"throw": verb(1),
"return": verb(2)
}, typeof Symbol === "function" && (g[Symbol.iterator] = function () {
return this;
}), g;
function verb(n) {
return function (v) {
return step([n, v]);
};
}
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) {
try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0:
case 1:
t = op;
break;
case 4:
_.label++;
return {
value: op[1],
done: false
};
case 5:
_.label++;
y = op[1];
op = [0];
continue;
case 7:
op = _.ops.pop();
_.trys.pop();
continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
_ = 0;
continue;
}
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
_.label = op[1];
break;
}
if (op[0] === 6 && _.label < t[1]) {
_.label = t[1];
t = op;
break;
}
if (t && _.label < t[2]) {
_.label = t[2];
_.ops.push(op);
break;
}
if (t[2]) _.ops.pop();
_.trys.pop();
continue;
}
op = body.call(thisArg, _);
} catch (e) {
op = [6, e];
y = 0;
} finally {
f = t = 0;
}
}
if (op[0] & 5) throw op[1];
return {
value: op[0] ? op[1] : void 0,
done: true
};
}
};
var __read = this && this.__read || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o),
r,
ar = [],
e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) {
ar.push(r.value);
}
} catch (error) {
e = {
error: error
};
} finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
} finally {
if (e) throw e.error;
}
}
return ar;
};
var __spreadArray = this && this.__spreadArray || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
import React, { useContext, useState, useRef, useImperativeHandle, useEffect } from "preact/compat";
import { CSSTransition, TransitionGroup } from "preact-transition-group-4";
import { ConfigContext } from "../ConfigProvider";
import Tag from "../Tag";
import useMergeValue from "../_util/hooks/useMergeValue";
import cs from "../_util/classNames";
import InputComponent from "../Input/input-element";
import IconHover from "../_class/icon-hover";
import IconClose from "../../icon/react-icon/IconClose";
import { isObject, isArray } from "../_util/is";
import getHotkeyHandler from "../_util/getHotkeyHandler";
import { Backspace } from "../_util/keycode";
import { pickTriggerPropsFromRest } from "../_util/constant";
import useMergeProps from "../_util/hooks/useMergeProps";
import Draggable from "../_class/Draggable";
var CSS_TRANSITION_DURATION = 300;
var REACT_KEY_FOR_INPUT = "__input_".concat(Math.random().toFixed(10).slice(2));
var keepFocus = function keepFocus(e) {
e.target.tagName !== 'INPUT' && e.preventDefault();
};
var formatValue = function formatValue(value) {
if (!isArray(value)) {
return [];
}
return value.map(function (item) {
return isObject(item) ? __assign(__assign({}, item), {
label: 'label' in item ? item.label : item.value,
value: item.value,
closable: item.closable
}) : {
label: item,
value: item
};
});
}; // Deal with the delay of recomputing input width
var useComputeAutoWidthDelay = function useComputeAutoWidthDelay(value) {
var refDelay = useRef(0);
var refPrevValueLength = useRef(value.length);
useEffect(function () {
refDelay.current = value.length === 0 && refPrevValueLength.current > 0 ? CSS_TRANSITION_DURATION : 0;
refPrevValueLength.current = value.length;
}, [value]);
return refDelay;
};
var UsedTransitionGroup = function UsedTransitionGroup(_a) {
var prefixCls = _a.prefixCls,
children = _a.children,
animation = _a.animation;
return animation ? React.createElement(TransitionGroup, {
component: "div",
className: "".concat(prefixCls, "-inner")
}, children) : React.createElement("div", {
className: "".concat(prefixCls, "-inner")
}, children);
};
var defaultProps = {
animation: true,
validate: function validate(inputValue, values) {
return inputValue && values.every(function (item) {
return item.value !== inputValue;
});
}
};
function InputTag(baseProps, ref) {
var _a;
var _this = this;
var _b = useContext(ConfigContext),
getPrefixCls = _b.getPrefixCls,
ctxSize = _b.size,
componentConfig = _b.componentConfig,
rtl = _b.rtl;
var props = useMergeProps(baseProps, defaultProps, componentConfig === null || componentConfig === void 0 ? void 0 : componentConfig.InputTag);
var className = props.className,
style = props.style,
placeholder = props.placeholder,
error = props.error,
disabled = props.disabled,
readOnly = props.readOnly,
allowClear = props.allowClear,
autoFocus = props.autoFocus,
labelInValue = props.labelInValue,
disableInput = props.disableInput,
animation = props.animation,
saveOnBlur = props.saveOnBlur,
dragToSort = props.dragToSort,
icon = props.icon,
suffix = props.suffix,
validate = props.validate,
renderTag = props.renderTag,
tagClassName = props.tagClassName,
onInputChange = props.onInputChange,
_onKeyDown = props.onKeyDown,
onPaste = props.onPaste,
onChange = props.onChange,
_onFocus = props.onFocus,
_onBlur = props.onBlur,
_onPressEnter = props.onPressEnter,
onRemove = props.onRemove,
onClear = props.onClear,
_onClick = props.onClick;
var prefixCls = getPrefixCls('input-tag');
var size = 'size' in props ? props.size : ctxSize;
var inputRef = useRef();
var _c = __read(useState(false), 2),
focused = _c[0],
setFocused = _c[1];
var _d = __read(useMergeValue([], {
defaultValue: 'defaultValue' in props ? formatValue(props.defaultValue) : undefined,
value: 'value' in props ? formatValue(props.value) : undefined
}), 2),
value = _d[0],
setValue = _d[1];
var _e = __read(useMergeValue('', {
value: props.inputValue
}), 2),
inputValue = _e[0],
setInputValue = _e[1];
var refDelay = useComputeAutoWidthDelay(value);
var draggable = !!(dragToSort && !readOnly && !disabled);
useImperativeHandle(ref, function () {
return {
blur: inputRef.current && inputRef.current.blur,
focus: inputRef.current && inputRef.current.focus
};
}, []);
var valueChangeHandler = function valueChangeHandler(value, reason) {
if (disabled || readOnly) {
return;
}
if (!('value' in props)) {
setValue(value);
}
onChange && onChange(labelInValue ? value : value.map(function (x) {
return x.value;
}), reason);
};
var tagCloseHandler = function tagCloseHandler(itemValue, index, event) {
onRemove && onRemove(itemValue, index, event);
valueChangeHandler(__spreadArray(__spreadArray([], __read(value.slice(0, index)), false), __read(value.slice(index + 1)), false), 'remove');
};
var hotkeyHandler = getHotkeyHandler(new Map([[Backspace.code, function (event) {
if (!event.target.value && value.length) {
for (var index = value.length - 1; index >= 0; index--) {
var itemValue = value[index];
if (itemValue.closable !== false) {
tagCloseHandler(itemValue, index, event);
return;
}
}
}
}]]));
var tryAddInputValueToTag = function tryAddInputValueToTag() {
return __awaiter(_this, void 0, void 0, function () {
var validateResult, _a, error_1;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_b.trys.push([0, 4,, 5]);
if (!(typeof validate === 'function')) return [3
/*break*/
, 2];
return [4
/*yield*/
, validate(inputValue, value)];
case 1:
_a = _b.sent();
return [3
/*break*/
, 3];
case 2:
_a = true;
_b.label = 3;
case 3:
validateResult = _a;
if (validateResult) {
valueChangeHandler(value.concat({
value: validateResult === true ? inputValue : validateResult,
label: inputValue
}), 'add');
setInputValue('');
}
return [3
/*break*/
, 5];
case 4:
error_1 = _b.sent();
console.error(error_1);
return [3
/*break*/
, 5];
case 5:
return [2
/*return*/
];
}
});
});
};
var mergedRenderTag = function mergedRenderTag(item, index) {
var _a;
var itemValue = item.value,
label = item.label;
var closable = !readOnly && !disabled && item.closable !== false;
var onClose = function onClose(event) {
tagCloseHandler(item, index, event);
};
if (renderTag) {
return renderTag({
value: itemValue,
label: label,
closable: closable,
onClose: onClose
}, index, value);
}
return React.createElement(Tag, {
visible: true,
className: cs("".concat(prefixCls, "-tag"), (_a = {}, _a[tagClassName] = tagClassName, _a)),
closable: closable,
closeIcon: icon && icon.removeIcon,
onClose: onClose
}, React.createElement("span", {
title: typeof label === 'string' ? label : undefined,
className: "".concat(prefixCls, "-tag-content")
}, typeof label === 'string' ? label.replace(/\s/g, "\xA0") : label));
};
var clearIcon = allowClear && !disabled && !readOnly && value.length ? React.createElement(IconHover, {
size: size,
key: "clearIcon",
className: "".concat(prefixCls, "-clear-icon"),
onClick: function onClick(e) {
e.stopPropagation();
valueChangeHandler([], 'clear');
if (!focused) {
inputRef.current && inputRef.current.focus();
}
onClear && onClear();
},
onMouseDown: keepFocus
}, icon && icon.clearIcon || React.createElement(IconClose, null)) : null;
var hasSuffix = !!(clearIcon || suffix); // CSSTransition needs to be a direct child of TransitionGroup, otherwise the animation will NOT work
// https://github.com/arco-design/arco-design/issues/622
var childrenWithAnimation = value.map(function (x, i) {
// Check whether two tags have same value. If so, set different key for them to avoid only rendering one tag.
var isRepeat = value.findIndex(function (item) {
return item.value === x.value;
}) !== i;
var eleTag = mergedRenderTag(x, i);
return React.isValidElement(eleTag) ? React.createElement(CSSTransition, {
key: _typeof(x.value) === 'object' ? i : isRepeat ? "".concat(x.value, "-").concat(i) : x.value,
timeout: CSS_TRANSITION_DURATION,
classNames: "zoomIn"
}, eleTag) : eleTag;
}).concat(React.createElement(CSSTransition, {
key: REACT_KEY_FOR_INPUT,
timeout: CSS_TRANSITION_DURATION,
classNames: "zoomIn"
}, React.createElement(InputComponent, {
autoComplete: "off",
size: size,
disabled: disabled || disableInput,
readOnly: readOnly,
ref: inputRef,
autoFocus: autoFocus,
placeholder: !value.length ? placeholder : '',
prefixCls: "".concat(prefixCls, "-input"),
autoFitWidth: {
delay: function delay() {
return refDelay.current;
}
},
onPressEnter: function onPressEnter(e) {
return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
inputValue && e.preventDefault();
_onPressEnter && _onPressEnter(e);
return [4
/*yield*/
, tryAddInputValueToTag()];
case 1:
_a.sent();
return [2
/*return*/
];
}
});
});
},
onFocus: function onFocus(e) {
if (!disabled && !readOnly) {
setFocused(true);
_onFocus && _onFocus(e);
}
},
onBlur: function onBlur(e) {
return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
setFocused(false);
_onBlur && _onBlur(e);
if (!saveOnBlur) return [3
/*break*/
, 2];
return [4
/*yield*/
, tryAddInputValueToTag()];
case 1:
_a.sent();
_a.label = 2;
case 2:
setInputValue('');
return [2
/*return*/
];
}
});
});
},
value: inputValue,
onChange: function onChange(v, e) {
setInputValue(v); // Only fire callback on user input to ensure parent component can get real input value on controlled mode.
onInputChange && onInputChange(v, e);
},
onKeyDown: function onKeyDown(event) {
hotkeyHandler(event);
_onKeyDown && _onKeyDown(event);
},
onPaste: onPaste
})));
return React.createElement("div", __assign({}, pickTriggerPropsFromRest(props), {
style: style,
className: cs(prefixCls, (_a = {}, _a["".concat(prefixCls, "-size-").concat(size)] = size, _a["".concat(prefixCls, "-disabled")] = disabled, _a["".concat(prefixCls, "-error")] = error, _a["".concat(prefixCls, "-focus")] = focused, _a["".concat(prefixCls, "-readonly")] = readOnly, _a["".concat(prefixCls, "-has-suffix")] = hasSuffix, _a["".concat(prefixCls, "-has-placeholder")] = !value.length, _a["".concat(prefixCls, "-rtl")] = rtl, _a), className),
onMouseDown: function onMouseDown(event) {
focused && keepFocus(event);
},
onClick: function onClick(e) {
!focused && inputRef.current && inputRef.current.focus();
if (_onClick) {
_onClick(e);
}
}
}), React.createElement("div", {
className: "".concat(prefixCls, "-view")
}, React.createElement(UsedTransitionGroup, {
prefixCls: prefixCls,
animation: animation
}, draggable ? React.createElement(Draggable, {
itemWrapperStyle: {
display: 'inline-block'
},
direction: "horizontal",
onIndexChange: function onIndexChange(index, prevIndex) {
var moveItem = function moveItem(arr, fromIndex, toIndex) {
arr = arr.slice();
var isMoveLeft = fromIndex > toIndex;
var _a = __read(arr.splice(fromIndex, 1), 1),
item = _a[0];
arr.splice(isMoveLeft ? toIndex : toIndex - 1, 0, item);
return arr;
};
valueChangeHandler(moveItem(value, prevIndex, index), 'sort');
}
}, childrenWithAnimation) : childrenWithAnimation), hasSuffix && React.createElement("div", {
className: "".concat(prefixCls, "-suffix"),
onMouseDown: keepFocus
}, clearIcon, suffix)));
}
var InputTagRef = React.forwardRef(InputTag);
InputTagRef.displayName = 'InputTag';
export default InputTagRef;