增加微信小程序版

This commit is contained in:
uiiang
2021-09-08 16:04:03 +08:00
parent e420fdf8fd
commit 1c29c3a737
207 changed files with 5936 additions and 0 deletions

View File

@@ -0,0 +1,287 @@
import baseComponent from '../helpers/baseComponent'
import classNames from '../helpers/classNames'
import eventsMixin from '../helpers/eventsMixin'
import NP from './utils'
const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || Math.pow(2, 53) - 1
const toNumberWhenUserInput = (num) => {
if (/\.\d*0$/.test(num) || num.length > 16) {
return num
}
if (isNaN(num)) {
return num
}
return Number(num)
}
const getValidValue = (value, min, max) => {
let val = parseFloat(value)
if (isNaN(val)) {
return value
}
if (val < min) {
val = min
}
if (val > max) {
val = max
}
return val
}
const defaultEvents = {
onChange() {},
onFocus() {},
onBlur() {},
}
baseComponent({
behaviors: [eventsMixin({ defaultEvents })],
externalClasses: ['wux-sub-class', 'wux-input-class', 'wux-add-class'],
relations: {
'../field/index': {
type: 'ancestor',
},
},
properties: {
prefixCls: {
type: String,
value: 'wux-input-number',
},
shape: {
type: String,
value: 'square',
},
min: {
type: Number,
value: -MAX_SAFE_INTEGER,
},
max: {
type: Number,
value: MAX_SAFE_INTEGER,
},
step: {
type: Number,
value: 1,
},
defaultValue: {
type: Number,
value: 0,
},
value: {
type: Number,
value: 0,
},
disabled: {
type: Boolean,
value: true,
},
longpress: {
type: Boolean,
value: false,
},
color: {
type: String,
value: 'balanced',
},
controlled: {
type: Boolean,
value: false,
},
},
data: {
inputValue: 0,
disabledMin: false,
disabledMax: false,
},
computed: {
classes: ['prefixCls, shape, color, disabledMin, disabledMax', function(prefixCls, shape, color, disabledMin, disabledMax) {
const wrap = classNames(prefixCls, {
[`${prefixCls}--${shape}`]: shape,
})
const sub = classNames(`${prefixCls}__selector`, {
[`${prefixCls}__selector--sub`]: true,
[`${prefixCls}__selector--${color}`]: color,
[`${prefixCls}__selector--disabled`]: disabledMin,
})
const add = classNames(`${prefixCls}__selector`, {
[`${prefixCls}__selector--add`]: true,
[`${prefixCls}__selector--${color}`]: color,
[`${prefixCls}__selector--disabled`]: disabledMax,
})
const icon = `${prefixCls}__icon`
const input = `${prefixCls}__input`
return {
wrap,
sub,
add,
icon,
input,
}
}],
},
observers: {
value(newVal) {
if (this.data.controlled) {
this.setValue(newVal, false)
}
},
'inputValue, min, max'(inputValue, min, max) {
const disabledMin = inputValue <= min
const disabledMax = inputValue >= max
this.setData({
disabledMin,
disabledMax,
})
},
},
methods: {
/**
* 更新值
*/
updated(inputValue) {
if (this.hasFieldDecorator) return
if (this.data.inputValue !== inputValue) {
this.setData({ inputValue })
}
},
/**
* 设置值
*/
setValue(value, runCallbacks = true) {
const { min, max } = this.data
const inputValue = NP.strip(getValidValue(value, min, max))
this.updated(inputValue)
if (runCallbacks) {
this.triggerEvent('change', { value: inputValue })
}
},
/**
* 数字计算函数
*/
calculation(type, isLoop) {
const {
disabledMax,
disabledMin,
inputValue,
step,
longpress,
controlled,
} = this.data
// add
if (type === 'add') {
if (disabledMax) return
this.setValue(NP.plus(inputValue, step))
}
// sub
if (type === 'sub') {
if (disabledMin) return
this.setValue(NP.minus(inputValue, step))
}
// longpress
if (longpress && isLoop) {
this.timeout = setTimeout(() => this.calculation(type, isLoop), 100)
}
},
/**
* 当键盘输入时,触发 input 事件
*/
onInput(e) {
this.clearInputTimer()
this.inputTime = setTimeout(() => {
const value = toNumberWhenUserInput(e.detail.value)
this.setValue(value)
}, 300)
},
/**
* 输入框聚焦时触发
*/
onFocus(e) {
this.triggerEvent('focus', e.detail)
},
/**
* 输入框失去焦点时触发
*/
onBlur(e) {
// always set input value same as value
this.setData({
inputValue: this.data.inputValue,
})
this.triggerEvent('blur', e.detail)
},
/**
* 手指触摸后超过350ms再离开
*/
onLongpress(e) {
const { type } = e.currentTarget.dataset
const { longpress } = this.data
if (longpress) {
this.calculation(type, true)
}
},
/**
* 手指触摸后马上离开
*/
onTap(e) {
const { type } = e.currentTarget.dataset
const { longpress } = this.data
if (!longpress || longpress && !this.timeout) {
this.calculation(type, false)
}
},
/**
* 手指触摸动作结束
*/
onTouchEnd() {
this.clearTimer()
},
/**
* 手指触摸动作被打断,如来电提醒,弹窗
*/
onTouchCancel() {
this.clearTimer()
},
/**
* 清除长按的定时器
*/
clearTimer() {
if (this.timeout) {
clearTimeout(this.timeout)
this.timeout = null
}
},
/**
* 清除输入框的定时器
*/
clearInputTimer() {
if (this.inputTime) {
clearTimeout(this.inputTime)
this.inputTime = null
}
},
},
attached() {
const { defaultValue, value, controlled } = this.data
const inputValue = controlled ? value : defaultValue
this.setValue(inputValue, false)
},
detached() {
this.clearTimer()
this.clearInputTimer()
},
})

View File

@@ -0,0 +1,6 @@
{
"component": true,
"usingComponents": {
"wux-icon": "../icon/index"
}
}

View File

@@ -0,0 +1,9 @@
<view class="wux-class {{ classes.wrap }}">
<view bindlongpress="onLongpress" bindtap="onTap" bindtouchend="onTouchEnd" touchcancel="onTouchCancel" data-type="sub" class="wux-sub-class {{ classes.sub }}">
<wux-icon wux-class="{{ classes.icon }}" type="ios-remove"></wux-icon>
</view>
<input bindinput="onInput" bindfocus="onFocus" bindblur="onBlur" value="{{ inputValue }}" disabled="{{ disabled }}" type="number" class="wux-input-class {{ classes.input }}" />
<view bindlongpress="onLongpress" bindtap="onTap" bindtouchend="onTouchEnd" touchcancel="onTouchCancel" data-type="add" class="wux-add-class {{ classes.add }}">
<wux-icon wux-class="{{ classes.icon }}" type="ios-add"></wux-icon>
</view>
</view>

View File

@@ -0,0 +1,118 @@
.wux-input-number {
position: relative;
display: -ms-flexbox;
display: flex
}
.wux-input-number__input {
width: 96rpx;
height: 52rpx;
font-size: 32rpx;
line-height: 52rpx;
color: rgba(0,0,0,.65);
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
border: 2rpx solid #e8e8e8;
padding: 6rpx 0;
text-align: center;
min-height: inherit;
box-sizing: border-box
}
.wux-input-number__selector {
width: 68rpx;
height: 52rpx;
font-size: 48rpx;
line-height: 52rpx;
color: #33cd5f;
border: 2rpx solid #e8e8e8;
box-sizing: border-box;
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: center;
justify-content: center
}
.wux-input-number__selector--disabled {
color: #ccc!important
}
.wux-input-number__selector--sub {
border-right: none;
padding: 6rpx 20rpx;
border-radius: 4rpx 0 0 4rpx
}
.wux-input-number__selector--add {
border-left: none;
padding: 6rpx 16rpx;
border-radius: 0 4rpx 4rpx 0
}
.wux-input-number__icon {
font-size: inherit!important;
vertical-align: middle;
line-height: inherit
}
.wux-input-number--circle .wux-input-number__input {
border-color: transparent
}
.wux-input-number--circle .wux-input-number__selector {
width: 52rpx;
border-radius: 50%;
border: 2rpx solid #33cd5f
}
.wux-input-number--circle .wux-input-number__selector--disabled {
border-color: #ccc!important
}
.wux-input-number .wux-input-number__selector--light {
color: #ddd
}
.wux-input-number--circle .wux-input-number__selector--light {
border-color: #ddd
}
.wux-input-number .wux-input-number__selector--stable {
color: #b2b2b2
}
.wux-input-number--circle .wux-input-number__selector--stable {
border-color: #b2b2b2
}
.wux-input-number .wux-input-number__selector--positive {
color: #387ef5
}
.wux-input-number--circle .wux-input-number__selector--positive {
border-color: #387ef5
}
.wux-input-number .wux-input-number__selector--calm {
color: #11c1f3
}
.wux-input-number--circle .wux-input-number__selector--calm {
border-color: #11c1f3
}
.wux-input-number .wux-input-number__selector--assertive {
color: #ef473a
}
.wux-input-number--circle .wux-input-number__selector--assertive {
border-color: #ef473a
}
.wux-input-number .wux-input-number__selector--balanced {
color: #33cd5f
}
.wux-input-number--circle .wux-input-number__selector--balanced {
border-color: #33cd5f
}
.wux-input-number .wux-input-number__selector--energized {
color: #ffc900
}
.wux-input-number--circle .wux-input-number__selector--energized {
border-color: #ffc900
}
.wux-input-number .wux-input-number__selector--royal {
color: #886aea
}
.wux-input-number--circle .wux-input-number__selector--royal {
border-color: #886aea
}
.wux-input-number .wux-input-number__selector--dark {
color: #444
}
.wux-input-number--circle .wux-input-number__selector--dark {
border-color: #444
}

View File

@@ -0,0 +1,135 @@
/**
* https://github.com/nefe/number-precision
*/
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
/**
* @desc 解决浮动运算问题,避免小数点后产生多位数和计算精度损失。
* 问题示例2.3 + 2.4 = 4.6999999999999991.0 - 0.9 = 0.09999999999999998
*/
/**
* 把错误的数据转正
* strip(0.09999999999999998)=0.1
*/
function strip(num, precision) {
if (precision === void 0) { precision = 12; }
return +parseFloat(num.toPrecision(precision));
}
/**
* Return digits length of a number
* @param {*number} num Input number
*/
function digitLength(num) {
// Get digit length of e
var eSplit = num.toString().split(/[eE]/);
var len = (eSplit[0].split('.')[1] || '').length - (+(eSplit[1] || 0));
return len > 0 ? len : 0;
}
/**
* 把小数转成整数,支持科学计数法。如果是小数则放大成整数
* @param {*number} num 输入数
*/
function float2Fixed(num) {
if (num.toString().indexOf('e') === -1) {
return Number(num.toString().replace('.', ''));
}
var dLen = digitLength(num);
return dLen > 0 ? strip(num * Math.pow(10, dLen)) : num;
}
/**
* 检测数字是否越界,如果越界给出提示
* @param {*number} num 输入数
*/
function checkBoundary(num) {
if (_boundaryCheckingState) {
if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) {
console.warn(num + " is beyond boundary when transfer to integer, the results may not be accurate");
}
}
}
/**
* 精确乘法
*/
function times(num1, num2) {
var others = [];
for (var _i = 2; _i < arguments.length; _i++) {
others[_i - 2] = arguments[_i];
}
if (others.length > 0) {
return times.apply(void 0, [times(num1, num2), others[0]].concat(others.slice(1)));
}
var num1Changed = float2Fixed(num1);
var num2Changed = float2Fixed(num2);
var baseNum = digitLength(num1) + digitLength(num2);
var leftValue = num1Changed * num2Changed;
checkBoundary(leftValue);
return leftValue / Math.pow(10, baseNum);
}
/**
* 精确加法
*/
function plus(num1, num2) {
var others = [];
for (var _i = 2; _i < arguments.length; _i++) {
others[_i - 2] = arguments[_i];
}
if (others.length > 0) {
return plus.apply(void 0, [plus(num1, num2), others[0]].concat(others.slice(1)));
}
var baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
return (times(num1, baseNum) + times(num2, baseNum)) / baseNum;
}
/**
* 精确减法
*/
function minus(num1, num2) {
var others = [];
for (var _i = 2; _i < arguments.length; _i++) {
others[_i - 2] = arguments[_i];
}
if (others.length > 0) {
return minus.apply(void 0, [minus(num1, num2), others[0]].concat(others.slice(1)));
}
var baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
return (times(num1, baseNum) - times(num2, baseNum)) / baseNum;
}
/**
* 精确除法
*/
function divide(num1, num2) {
var others = [];
for (var _i = 2; _i < arguments.length; _i++) {
others[_i - 2] = arguments[_i];
}
if (others.length > 0) {
return divide.apply(void 0, [divide(num1, num2), others[0]].concat(others.slice(1)));
}
var num1Changed = float2Fixed(num1);
var num2Changed = float2Fixed(num2);
checkBoundary(num1Changed);
checkBoundary(num2Changed);
return times((num1Changed / num2Changed), Math.pow(10, digitLength(num2) - digitLength(num1)));
}
/**
* 四舍五入
*/
function round(num, ratio) {
var base = Math.pow(10, ratio);
return divide(Math.round(times(num, base)), base);
}
var _boundaryCheckingState = true;
/**
* 是否进行边界检查,默认开启
* @param flag 标记开关true 为开启false 为关闭,默认为 true
*/
function enableBoundaryChecking(flag) {
if (flag === void 0) { flag = true; }
_boundaryCheckingState = flag;
}
var index = { strip: strip, plus: plus, minus: minus, times: times, divide: divide, round: round, digitLength: digitLength, float2Fixed: float2Fixed, enableBoundaryChecking: enableBoundaryChecking };
export default index;