choo-taro-ui-vue3
Version:
Taro UI Rewritten in Vue 3.0
470 lines (435 loc) • 13.3 kB
JavaScript
import { defineComponent, computed, toRef, createCommentVNode, resolveComponent, createVNode, normalizeClass, withCtx, normalizeStyle, mergeProps, openBlock, createBlock } from 'vue';
import { pxTransform } from '../utils';
/** Detect free variable `global` from Node.js. */
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
/** Used as a reference to the global object. */
var root = freeGlobal || freeSelf || Function('return this')();
/** Built-in value references. */
var Symbol$1 = root.Symbol;
/**
* A specialized version of `_.map` for arrays without support for iteratee
* shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns the new mapped array.
*/
function arrayMap(array, iteratee) {
var index = -1,
length = array == null ? 0 : array.length,
result = Array(length);
while (++index < length) {
result[index] = iteratee(array[index], index, array);
}
return result;
}
/**
* Checks if `value` is classified as an `Array` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an array, else `false`.
* @example
*
* _.isArray([1, 2, 3]);
* // => true
*
* _.isArray(document.body.children);
* // => false
*
* _.isArray('abc');
* // => false
*
* _.isArray(_.noop);
* // => false
*/
var isArray = Array.isArray;
/** Used for built-in method references. */
var objectProto$1 = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto$1.hasOwnProperty;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var nativeObjectToString$1 = objectProto$1.toString;
/** Built-in value references. */
var symToStringTag$1 = Symbol$1 ? Symbol$1.toStringTag : undefined;
/**
* A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the raw `toStringTag`.
*/
function getRawTag(value) {
var isOwn = hasOwnProperty.call(value, symToStringTag$1),
tag = value[symToStringTag$1];
try {
value[symToStringTag$1] = undefined;
var unmasked = true;
} catch (e) {}
var result = nativeObjectToString$1.call(value);
if (unmasked) {
if (isOwn) {
value[symToStringTag$1] = tag;
} else {
delete value[symToStringTag$1];
}
}
return result;
}
/** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var nativeObjectToString = objectProto.toString;
/**
* Converts `value` to a string using `Object.prototype.toString`.
*
* @private
* @param {*} value The value to convert.
* @returns {string} Returns the converted string.
*/
function objectToString(value) {
return nativeObjectToString.call(value);
}
/** `Object#toString` result references. */
var nullTag = '[object Null]',
undefinedTag = '[object Undefined]';
/** Built-in value references. */
var symToStringTag = Symbol$1 ? Symbol$1.toStringTag : undefined;
/**
* The base implementation of `getTag` without fallbacks for buggy environments.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the `toStringTag`.
*/
function baseGetTag(value) {
if (value == null) {
return value === undefined ? undefinedTag : nullTag;
}
return (symToStringTag && symToStringTag in Object(value))
? getRawTag(value)
: objectToString(value);
}
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/
function isObjectLike(value) {
return value != null && typeof value == 'object';
}
/** `Object#toString` result references. */
var symbolTag = '[object Symbol]';
/**
* Checks if `value` is classified as a `Symbol` primitive or object.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
* @example
*
* _.isSymbol(Symbol.iterator);
* // => true
*
* _.isSymbol('abc');
* // => false
*/
function isSymbol(value) {
return typeof value == 'symbol' ||
(isObjectLike(value) && baseGetTag(value) == symbolTag);
}
/** Used as references for various `Number` constants. */
var INFINITY = 1 / 0;
/** Used to convert symbols to primitives and strings. */
var symbolProto = Symbol$1 ? Symbol$1.prototype : undefined,
symbolToString = symbolProto ? symbolProto.toString : undefined;
/**
* The base implementation of `_.toString` which doesn't convert nullish
* values to empty strings.
*
* @private
* @param {*} value The value to process.
* @returns {string} Returns the string.
*/
function baseToString(value) {
// Exit early for strings to avoid a performance hit in some environments.
if (typeof value == 'string') {
return value;
}
if (isArray(value)) {
// Recursively convert values (susceptible to call stack limits).
return arrayMap(value, baseToString) + '';
}
if (isSymbol(value)) {
return symbolToString ? symbolToString.call(value) : '';
}
var result = (value + '');
return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
}
/**
* Converts `value` to a string. An empty string is returned for `null`
* and `undefined` values. The sign of `-0` is preserved.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to convert.
* @returns {string} Returns the converted string.
* @example
*
* _.toString(null);
* // => ''
*
* _.toString(-0);
* // => '-0'
*
* _.toString([1, 2, 3]);
* // => '1,2,3'
*/
function toString(value) {
return value == null ? '' : baseToString(value);
}
function addNum(num1, num2) {
let sq1, sq2;
try {
sq1 = toString(num1).split(".")[1].length;
} catch (e) {
sq1 = 0;
}
try {
sq2 = toString(num2).split(".")[1].length;
} catch (e) {
sq2 = 0;
}
const m = Math.pow(10, Math.max(sq1, sq2));
return (Math.round(num1 * m) + Math.round(num2 * m)) / m;
}
function parseValue(num) {
if (num === "")
return "0";
const numStr = toString(num);
if (numStr.indexOf("0") === 0 && numStr.indexOf(".") === -1) {
return toString(parseFloat(num));
}
return toString(num);
}
const AtInputNumber = defineComponent({
name: "AtInputNumber",
emits: {
"blur": null,
"update:modelValue": null,
"error-input"(errCb) {
return !!(errCb && typeof errCb === "object" && ["OVER", "LOW", "DISABLED"].includes(errCb.type) && typeof errCb.errorValue === "number");
}
},
props: {
type: {
type: String,
default: "number"
},
modelValue: {
type: [Number, String],
default: 1
},
min: {
type: Number,
default: 0
},
max: {
type: Number,
default: 100
},
step: {
type: Number,
default: 1
},
size: {
type: String,
default: "normal"
},
width: {
type: Number,
default: 120
},
disabled: Boolean,
disabledInput: Boolean
},
setup(props, { emit }) {
const inputValue = computed({
get: () => Number(handleValue(props.modelValue)),
set: (value) => emit("update:modelValue", value)
});
const inputStyle = computed(() => ({
width: props.width ? `${pxTransform(props.width)}` : ""
}));
const rootClasses = computed(() => ({
"at-input-number": true,
"at-input-number--lg": props.size === "large"
}));
const minusBtnClasses = computed(() => ({
"at-input-number__btn": true,
"at-input-number--disabled": inputValue.value <= props.min || props.disabled
}));
const plusBtnClasses = computed(() => ({
"at-input-number__btn": true,
"at-input-number--disabled": inputValue.value >= props.max || props.disabled
}));
function handleClick(clickType, e) {
const belowMin = clickType === "minus" && inputValue.value <= props.min;
const overMax = clickType === "plus" && inputValue.value >= props.max;
if (belowMin || overMax || props.disabled) {
const deltaValue2 = clickType === "minus" ? -props.step : props.step;
const errorValue = addNum(inputValue.value, deltaValue2);
if (props.disabled) {
handleError({
type: "DISABLED",
errorValue
});
} else {
handleError({
type: belowMin ? "LOW" : "OVER",
errorValue
});
}
return;
}
const deltaValue = clickType === "minus" ? -props.step : props.step;
let newValue = addNum(inputValue.value, deltaValue);
newValue = Number(handleValue(newValue));
inputValue.value = newValue;
}
function handleValue(value) {
let resultValue = value === "" ? props.min : value;
if (resultValue > props.max) {
resultValue = props.max;
handleError({
type: "OVER",
errorValue: resultValue
});
}
if (resultValue < props.min) {
resultValue = props.min;
handleError({
type: "LOW",
errorValue: resultValue
});
}
if (resultValue && !Number(resultValue)) {
resultValue = parseFloat(String(resultValue)) || props.min;
handleError({
type: "OVER",
errorValue: resultValue
});
}
resultValue = parseValue(String(resultValue));
return resultValue;
}
function handleInput(e) {
if (props.disabled)
return;
const { value } = e.target;
const newValue = handleValue(value);
inputValue.value = Number(newValue);
}
function handleBlur(e) {
emit("blur", e);
}
function handleError(errorValue) {
emit("error-input", errorValue);
}
return {
type: toRef(props, "type"),
disabled: toRef(props, "disabled"),
disabledInput: toRef(props, "disabledInput"),
inputValue,
inputStyle,
rootClasses,
plusBtnClasses,
minusBtnClasses,
handleBlur,
handleInput,
handleClick
};
}
});
// Binding optimization for webpack code-split
const _createCommentVNode = createCommentVNode, _resolveComponent = resolveComponent, _createVNode = createVNode, _normalizeClass = normalizeClass, _withCtx = withCtx, _normalizeStyle = normalizeStyle, _mergeProps = mergeProps, _openBlock = openBlock, _createBlock = createBlock;
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_taro_text = process.env.TARO_ENV === "h5" ? _resolveComponent("taro-text") : "text";
const _component_taro_view = process.env.TARO_ENV === "h5" ? _resolveComponent("taro-view") : "view";
const _component_taro_input = process.env.TARO_ENV === "h5" ? _resolveComponent("taro-input") : "input";
return (_openBlock(), _createBlock(_component_taro_view, _mergeProps(_ctx.$attrs, { class: _ctx.rootClasses }), {
default: _withCtx(() => [
_createCommentVNode(" minus button "),
_createVNode(_component_taro_view, {
class: _normalizeClass(_ctx.minusBtnClasses),
onTap: _cache[0] || (_cache[0] = $event => (_ctx.handleClick('minus', $event)))
}, {
default: _withCtx(() => [
_createVNode(_component_taro_text, { class: "at-icon at-icon-subtract at-input-number__btn-subtract" })
]),
_: 1 /* STABLE */
}, 8 /* PROPS */, ["class"]),
_createCommentVNode(" input box "),
_createVNode(_component_taro_input, {
class: "at-input-number__input",
style: _normalizeStyle(_ctx.inputStyle),
type: _ctx.type,
value: _ctx.inputValue,
disabled: _ctx.disabledInput || _ctx.disabled,
onBlur: _ctx.handleBlur,
onInput: _ctx.handleInput
}, null, 8 /* PROPS */, ["style", "type", "value", "disabled", "onBlur", "onInput"]),
_createCommentVNode(" plus button "),
_createVNode(_component_taro_view, {
class: _normalizeClass(_ctx.plusBtnClasses),
onTap: _cache[1] || (_cache[1] = $event => (_ctx.handleClick('plus', $event)))
}, {
default: _withCtx(() => [
_createVNode(_component_taro_text, { class: "at-icon at-icon-add at-input-number__btn-add" })
]),
_: 1 /* STABLE */
}, 8 /* PROPS */, ["class"])
]),
_: 1 /* STABLE */
}, 16 /* FULL_PROPS */, ["class"]))
}
AtInputNumber.render = _sfc_render;
export default AtInputNumber;