Commit b969f804 by 程默

update vant

parent e3599455
<template> <template>
<div class="domain">abc</div> <div class="domain">abc
<van-button type="primary">按钮</van-button>
</div>
</template> </template>
<script> <script>
......
{ {
"usingComponents": {
"van-button": "/static/vant/button/index"
} }
}
\ No newline at end of file
...@@ -10,32 +10,32 @@ VantComponent({ ...@@ -10,32 +10,32 @@ VantComponent({
description: String, description: String,
round: { round: {
type: Boolean, type: Boolean,
value: true value: true,
}, },
zIndex: { zIndex: {
type: Number, type: Number,
value: 100 value: 100,
}, },
actions: { actions: {
type: Array, type: Array,
value: [] value: [],
}, },
overlay: { overlay: {
type: Boolean, type: Boolean,
value: true value: true,
}, },
closeOnClickOverlay: { closeOnClickOverlay: {
type: Boolean, type: Boolean,
value: true value: true,
}, },
closeOnClickAction: { closeOnClickAction: {
type: Boolean, type: Boolean,
value: true value: true,
}, },
safeAreaInsetBottom: { safeAreaInsetBottom: {
type: Boolean, type: Boolean,
value: true value: true,
} },
}, },
methods: { methods: {
onSelect(event) { onSelect(event) {
...@@ -57,6 +57,6 @@ VantComponent({ ...@@ -57,6 +57,6 @@ VantComponent({
onClickOverlay() { onClickOverlay() {
this.$emit('click-overlay'); this.$emit('click-overlay');
this.onClose(); this.onClose();
} },
} },
}); });
...@@ -11,15 +11,15 @@ ...@@ -11,15 +11,15 @@
close-on-click-overlay="{{ closeOnClickOverlay }}" close-on-click-overlay="{{ closeOnClickOverlay }}"
bind:close="onClickOverlay" bind:close="onClickOverlay"
> >
<view wx:if="{{ title }}" class="van-hairline--bottom van-action-sheet__header"> <view wx:if="{{ title }}" class="van-action-sheet__header">
{{ title }} {{ title }}
<van-icon <van-icon
name="close" name="cross"
custom-class="van-action-sheet__close" custom-class="van-action-sheet__close"
bind:click="onClose" bind:click="onClose"
/> />
</view> </view>
<view wx:if="{{ description }}" class="van-action-sheet__description"> <view wx:if="{{ description }}" class="van-action-sheet__description van-hairline--bottom">
{{ description }} {{ description }}
</view> </view>
<view wx:if="{{ actions && actions.length }}"> <view wx:if="{{ actions && actions.length }}">
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
wx:key="index" wx:key="index"
open-type="{{ item.openType }}" open-type="{{ item.openType }}"
style="{{ item.color ? 'color: ' + item.color : '' }}" style="{{ item.color ? 'color: ' + item.color : '' }}"
class="{{ utils.bem('action-sheet__item', { disabled: item.disabled || item.loading }) }} van-hairline--top {{ item.className || '' }}" class="{{ utils.bem('action-sheet__item', { disabled: item.disabled || item.loading }) }} {{ item.className || '' }}"
hover-class="van-action-sheet__item--hover" hover-class="van-action-sheet__item--hover"
data-index="{{ index }}" data-index="{{ index }}"
bind:tap="onSelect" bind:tap="onSelect"
...@@ -49,14 +49,15 @@ ...@@ -49,14 +49,15 @@
> >
<block wx:if="{{ !item.loading }}"> <block wx:if="{{ !item.loading }}">
{{ item.name }} {{ item.name }}
<text wx:if="{{ item.subname }}" class="van-action-sheet__subname" >{{ item.subname }}</text> <view wx:if="{{ item.subname }}" class="van-action-sheet__subname" >{{ item.subname }}</view>
</block> </block>
<van-loading wx:else custom-class="van-action-sheet__loading" size="20px" /> <van-loading wx:else custom-class="van-action-sheet__loading" size="22px" />
</button> </button>
</view> </view>
<slot /> <slot />
<block wx:if="{{ cancelText }}">
<view class="van-action-sheet__gap" />
<view <view
wx:if="{{ cancelText }}"
class="van-action-sheet__cancel" class="van-action-sheet__cancel"
hover-class="van-action-sheet__cancel--hover" hover-class="van-action-sheet__cancel--hover"
hover-stay-time="70" hover-stay-time="70"
...@@ -64,4 +65,5 @@ ...@@ -64,4 +65,5 @@
> >
{{ cancelText }} {{ cancelText }}
</view> </view>
</block>
</van-popup> </van-popup>
@import '../common/index.wxss';.van-action-sheet{max-height:90%!important;max-height:var(--action-sheet-max-height,90%)!important;color:#323233;color:var(--action-sheet-item-text-color,#323233)}.van-action-sheet__cancel,.van-action-sheet__item{text-align:center;font-size:16px;font-size:var(--action-sheet-item-font-size,16px);line-height:50px;line-height:var(--action-sheet-item-height,50px);background-color:#fff;background-color:var(--action-sheet-item-background,#fff)}.van-action-sheet__cancel--hover,.van-action-sheet__item--hover{background-color:#f2f3f5;background-color:var(--active-color,#f2f3f5)}.van-action-sheet__cancel:before{display:block;content:" ";height:8px;height:var(--action-sheet-cancel-padding-top,8px);background-color:#f7f8fa;background-color:var(--action-sheet-cancel-padding-color,#f7f8fa)}.van-action-sheet__item--disabled{color:#c8c9cc;color:var(--action-sheet-item-disabled-text-color,#c8c9cc)}.van-action-sheet__item--disabled.van-action-sheet__item--hover{background-color:#fff;background-color:var(--action-sheet-item-background,#fff)}.van-action-sheet__subname{margin-left:4px;margin-left:var(--padding-base,4px);font-size:12px;font-size:var(--action-sheet-subname-font-size,12px);color:#646566;color:var(--action-sheet-subname-color,#646566)}.van-action-sheet__header{text-align:center;font-weight:500;font-weight:var(--font-weight-bold,500);font-size:16px;font-size:var(--action-sheet-header-font-size,16px);line-height:44px;line-height:var(--action-sheet-header-height,44px)}.van-action-sheet__description{text-align:center;padding:16px;padding:var(--padding-md,16px);color:#646566;color:var(--action-sheet-description-color,#646566);font-size:14px;font-size:var(--action-sheet-description-font-size,14px);line-height:20px;line-height:var(--action-sheet-description-line-height,20px)}.van-action-sheet__close{position:absolute!important;top:0;right:0;line-height:inherit!important;padding:0 12px;padding:var(--action-sheet-close-icon-padding,0 12px);font-size:18px!important;font-size:var(--action-sheet-close-icon-size,18px)!important;color:#969799;color:var(--action-sheet-close-icon-color,#969799)}.van-action-sheet__loading{display:-webkit-flex!important;display:flex!important;height:50px;height:var(--action-sheet-item-height,50px)} @import '../common/index.wxss';.van-action-sheet{max-height:90%!important;max-height:var(--action-sheet-max-height,90%)!important;color:#323233;color:var(--action-sheet-item-text-color,#323233)}.van-action-sheet__cancel,.van-action-sheet__item{padding:14px 16px;text-align:center;font-size:16px;font-size:var(--action-sheet-item-font-size,16px);line-height:22px;line-height:var(--action-sheet-item-line-height,22px);background-color:#fff;background-color:var(--action-sheet-item-background,#fff)}.van-action-sheet__cancel--hover,.van-action-sheet__item--hover{background-color:#f2f3f5;background-color:var(--active-color,#f2f3f5)}.van-action-sheet__cancel:after,.van-action-sheet__item:after{border-width:0}.van-action-sheet__cancel{color:#646566;color:var(--action-sheet-cancel-text-color,#646566)}.van-action-sheet__gap{display:block;height:8px;height:var(--action-sheet-cancel-padding-top,8px);background-color:#f7f8fa;background-color:var(--action-sheet-cancel-padding-color,#f7f8fa)}.van-action-sheet__item--disabled{color:#c8c9cc;color:var(--action-sheet-item-disabled-text-color,#c8c9cc)}.van-action-sheet__item--disabled.van-action-sheet__item--hover{background-color:#fff;background-color:var(--action-sheet-item-background,#fff)}.van-action-sheet__subname{margin-top:8px;margin-top:var(--padding-xs,8px);font-size:12px;font-size:var(--action-sheet-subname-font-size,12px);color:#969799;color:var(--action-sheet-subname-color,#969799);line-height:20px;line-height:var(--action-sheet-subname-line-height,20px)}.van-action-sheet__header{text-align:center;font-weight:500;font-weight:var(--font-weight-bold,500);font-size:16px;font-size:var(--action-sheet-header-font-size,16px);line-height:48px;line-height:var(--action-sheet-header-height,48px)}.van-action-sheet__description{text-align:center;padding:20px 16px;padding:20px var(--padding-md,16px);color:#969799;color:var(--action-sheet-description-color,#969799);font-size:14px;font-size:var(--action-sheet-description-font-size,14px);line-height:20px;line-height:var(--action-sheet-description-line-height,20px)}.van-action-sheet__close{position:absolute!important;top:0;right:0;line-height:inherit!important;padding:0 16px;padding:var(--action-sheet-close-icon-padding,0 16px);font-size:22px!important;font-size:var(--action-sheet-close-icon-size,22px)!important;color:#c8c9cc;color:var(--action-sheet-close-icon-color,#c8c9cc)}.van-action-sheet__loading{display:-webkit-flex!important;display:flex!important}
\ No newline at end of file \ No newline at end of file
import { VantComponent } from '../common/component'; import { VantComponent } from '../common/component';
import { pickerProps } from '../picker/shared'; import { pickerProps } from '../picker/shared';
const COLUMNSPLACEHOLDERCODE = '000000'; import { requestAnimationFrame } from '../common/utils';
const EMPTY_CODE = '000000';
VantComponent({ VantComponent({
classes: ['active-class', 'toolbar-class', 'column-class'], classes: ['active-class', 'toolbar-class', 'column-class'],
props: Object.assign(Object.assign({}, pickerProps), { value: { props: Object.assign(Object.assign({}, pickerProps), {
value: {
type: String, type: String,
observer(value) { observer(value) {
this.code = value; this.code = value;
this.setValues(); this.setValues();
}, },
}, areaList: { },
areaList: {
type: Object, type: Object,
value: {}, value: {},
observer: 'setValues' observer: 'setValues',
}, columnsNum: { },
columnsNum: {
type: null, type: null,
value: 3, value: 3,
observer(value) { },
this.setData({ columnsPlaceholder: {
displayColumns: this.data.columns.slice(0, +value)
});
}
}, columnsPlaceholder: {
type: Array, type: Array,
observer(val) { observer(val) {
this.setData({ this.setData({
...@@ -29,19 +29,19 @@ VantComponent({ ...@@ -29,19 +29,19 @@ VantComponent({
province: val[0] || '', province: val[0] || '',
city: val[1] || '', city: val[1] || '',
county: val[2] || '', county: val[2] || '',
} },
}); });
} },
} }), },
}),
data: { data: {
columns: [{ values: [] }, { values: [] }, { values: [] }], columns: [{ values: [] }, { values: [] }, { values: [] }],
displayColumns: [{ values: [] }, { values: [] }, { values: [] }], typeToColumnsPlaceholder: {},
typeToColumnsPlaceholder: {}
}, },
mounted() { mounted() {
setTimeout(() => { requestAnimationFrame(() => {
this.setValues(); this.setValues();
}, 0); });
}, },
methods: { methods: {
getPicker() { getPicker() {
...@@ -56,7 +56,7 @@ VantComponent({ ...@@ -56,7 +56,7 @@ VantComponent({
onConfirm(event) { onConfirm(event) {
const { index } = event.detail; const { index } = event.detail;
let { value } = event.detail; let { value } = event.detail;
value = this.parseOutputValues(value); value = this.parseValues(value);
this.emit('confirm', { value, index }); this.emit('confirm', { value, index });
}, },
emit(type, detail) { emit(type, detail) {
...@@ -64,17 +64,17 @@ VantComponent({ ...@@ -64,17 +64,17 @@ VantComponent({
delete detail.value; delete detail.value;
this.$emit(type, detail); this.$emit(type, detail);
}, },
// parse output columns data parseValues(values) {
parseOutputValues(values) {
const { columnsPlaceholder } = this.data; const { columnsPlaceholder } = this.data;
return values.map((value, index) => { return values.map((value, index) => {
// save undefined value if (
if (!value) value &&
return value; (!value.code || value.name === columnsPlaceholder[index])
value = JSON.parse(JSON.stringify(value)); ) {
if (!value.code || value.name === columnsPlaceholder[index]) { return Object.assign(Object.assign({}, value), {
value.code = ''; code: '',
value.name = ''; name: '',
});
} }
return value; return value;
}); });
...@@ -85,8 +85,8 @@ VantComponent({ ...@@ -85,8 +85,8 @@ VantComponent({
this.setValues().then(() => { this.setValues().then(() => {
this.$emit('change', { this.$emit('change', {
picker, picker,
values: this.parseOutputValues(picker.getValues()), values: this.parseValues(picker.getValues()),
index index,
}); });
}); });
}, },
...@@ -95,29 +95,33 @@ VantComponent({ ...@@ -95,29 +95,33 @@ VantComponent({
return (areaList && areaList[`${type}_list`]) || {}; return (areaList && areaList[`${type}_list`]) || {};
}, },
getList(type, code) { getList(type, code) {
const { typeToColumnsPlaceholder } = this.data;
let result = [];
if (type !== 'province' && !code) { if (type !== 'province' && !code) {
return result; return [];
} }
const { typeToColumnsPlaceholder } = this.data;
const list = this.getConfig(type); const list = this.getConfig(type);
result = Object.keys(list).map(code => ({ let result = Object.keys(list).map((code) => ({
code, code,
name: list[code] name: list[code],
})); }));
if (code) { if (code != null) {
// oversea code // oversea code
if (code[0] === '9' && type === 'city') { if (code[0] === '9' && type === 'city') {
code = '9'; code = '9';
} }
result = result.filter(item => item.code.indexOf(code) === 0); result = result.filter((item) => item.code.indexOf(code) === 0);
} }
if (typeToColumnsPlaceholder[type] && result.length) { if (typeToColumnsPlaceholder[type] && result.length) {
// set columns placeholder // set columns placeholder
const codeFill = type === 'province' ? '' : type === 'city' ? COLUMNSPLACEHOLDERCODE.slice(2, 4) : COLUMNSPLACEHOLDERCODE.slice(4, 6); const codeFill =
type === 'province'
? ''
: type === 'city'
? EMPTY_CODE.slice(2, 4)
: EMPTY_CODE.slice(4, 6);
result.unshift({ result.unshift({
code: `${code}${codeFill}`, code: `${code}${codeFill}`,
name: typeToColumnsPlaceholder[type] name: typeToColumnsPlaceholder[type],
}); });
} }
return result; return result;
...@@ -138,44 +142,63 @@ VantComponent({ ...@@ -138,44 +142,63 @@ VantComponent({
return 0; return 0;
}, },
setValues() { setValues() {
const county = this.getConfig('county');
let { code } = this;
if (!code) {
if (this.data.columnsPlaceholder.length) {
code = COLUMNSPLACEHOLDERCODE;
}
else if (Object.keys(county)[0]) {
code = Object.keys(county)[0];
}
else {
code = '';
}
}
const province = this.getList('province');
const city = this.getList('city', code.slice(0, 2));
const picker = this.getPicker(); const picker = this.getPicker();
if (!picker) { if (!picker) {
return; return;
} }
let code = this.code || this.getDefaultCode();
const provinceList = this.getList('province');
const cityList = this.getList('city', code.slice(0, 2));
const stack = []; const stack = [];
stack.push(picker.setColumnValues(0, province, false)); const indexes = [];
stack.push(picker.setColumnValues(1, city, false)); const { columnsNum } = this.data;
if (city.length && code.slice(2, 4) === '00') { if (columnsNum >= 1) {
[{ code }] = city; stack.push(picker.setColumnValues(0, provinceList, false));
indexes.push(this.getIndex('province', code));
}
if (columnsNum >= 2) {
stack.push(picker.setColumnValues(1, cityList, false));
indexes.push(this.getIndex('city', code));
if (cityList.length && code.slice(2, 4) === '00') {
[{ code }] = cityList;
}
}
if (columnsNum === 3) {
stack.push(
picker.setColumnValues(
2,
this.getList('county', code.slice(0, 4)),
false
)
);
indexes.push(this.getIndex('county', code));
} }
stack.push(picker.setColumnValues(2, this.getList('county', code.slice(0, 4)), false));
return Promise.all(stack) return Promise.all(stack)
.catch(() => { }) .catch(() => {})
.then(() => picker.setIndexes([ .then(() => picker.setIndexes(indexes))
this.getIndex('province', code), .catch(() => {});
this.getIndex('city', code), },
this.getIndex('county', code) getDefaultCode() {
])) const { columnsPlaceholder } = this.data;
.catch(() => { }); if (columnsPlaceholder.length) {
return EMPTY_CODE;
}
const countyCodes = Object.keys(this.getConfig('county'));
if (countyCodes[0]) {
return countyCodes[0];
}
const cityCodes = Object.keys(this.getConfig('city'));
if (cityCodes[0]) {
return cityCodes[0];
}
return '';
}, },
getValues() { getValues() {
const picker = this.getPicker(); const picker = this.getPicker();
return picker ? picker.getValues().filter(value => !!value) : []; if (!picker) {
return [];
}
return this.parseValues(picker.getValues().filter((value) => !!value));
}, },
getDetail() { getDetail() {
const values = this.getValues(); const values = this.getValues();
...@@ -184,7 +207,7 @@ VantComponent({ ...@@ -184,7 +207,7 @@ VantComponent({
country: '', country: '',
province: '', province: '',
city: '', city: '',
county: '' county: '',
}; };
if (!values.length) { if (!values.length) {
return area; return area;
...@@ -194,8 +217,7 @@ VantComponent({ ...@@ -194,8 +217,7 @@ VantComponent({
if (area.code[0] === '9') { if (area.code[0] === '9') {
area.country = names[1] || ''; area.country = names[1] || '';
area.province = names[2] || ''; area.province = names[2] || '';
} } else {
else {
area.province = names[0] || ''; area.province = names[0] || '';
area.city = names[1] || ''; area.city = names[1] || '';
area.county = names[2] || ''; area.county = names[2] || '';
...@@ -205,6 +227,6 @@ VantComponent({ ...@@ -205,6 +227,6 @@ VantComponent({
reset(code) { reset(code) {
this.code = code || ''; this.code = code || '';
return this.setValues(); return this.setValues();
} },
} },
}); });
<wxs src="./index.wxs" module="computed" />
<van-picker <van-picker
class="van-area__picker" class="van-area__picker"
active-class="active-class" active-class="active-class"
...@@ -7,7 +9,7 @@ ...@@ -7,7 +9,7 @@
value-key="name" value-key="name"
title="{{ title }}" title="{{ title }}"
loading="{{ loading }}" loading="{{ loading }}"
columns="{{ displayColumns }}" columns="{{ computed.displayColumns(columns, columnsNum) }}"
item-height="{{ itemHeight }}" item-height="{{ itemHeight }}"
visible-item-count="{{ visibleItemCount }}" visible-item-count="{{ visibleItemCount }}"
cancel-button-text="{{ cancelButtonText }}" cancel-button-text="{{ cancelButtonText }}"
......
/* eslint-disable */
function displayColumns(columns, columnsNum) {
return columns.slice(0, +columnsNum);
}
module.exports = {
displayColumns: displayColumns,
};
import { VantComponent } from '../common/component'; import { VantComponent } from '../common/component';
import { button } from '../mixins/button'; import { button } from '../mixins/button';
import { openType } from '../mixins/open-type'; import { openType } from '../mixins/open-type';
import { canIUseFormFieldButton } from '../common/version';
const mixins = [button, openType];
if (canIUseFormFieldButton()) {
mixins.push('wx://form-field-button');
}
VantComponent({ VantComponent({
mixins: [button, openType], mixins,
classes: ['hover-class', 'loading-class'], classes: ['hover-class', 'loading-class'],
data: { data: {
baseStyle: '' baseStyle: '',
}, },
props: { props: {
formType: String,
icon: String, icon: String,
classPrefix: {
type: String,
value: 'van-icon',
},
plain: Boolean, plain: Boolean,
block: Boolean, block: Boolean,
round: Boolean, round: Boolean,
...@@ -20,49 +30,29 @@ VantComponent({ ...@@ -20,49 +30,29 @@ VantComponent({
customStyle: String, customStyle: String,
loadingType: { loadingType: {
type: String, type: String,
value: 'circular' value: 'circular',
}, },
type: { type: {
type: String, type: String,
value: 'default' value: 'default',
}, },
dataset: null,
size: { size: {
type: String, type: String,
value: 'normal' value: 'normal',
}, },
loadingSize: { loadingSize: {
type: String, type: String,
value: '20px' value: '20px',
}, },
color: { color: String,
type: String,
observer(color) {
let style = '';
if (color) {
style += `color: ${this.data.plain ? color : 'white'};`;
if (!this.data.plain) {
// Use background instead of backgroundColor to make linear-gradient work
style += `background: ${color};`;
}
// hide border when color is linear-gradient
if (color.indexOf('gradient') !== -1) {
style += 'border: 0;';
}
else {
style += `border-color: ${color};`;
}
}
if (style !== this.data.baseStyle) {
this.setData({ baseStyle: style });
}
}
}
}, },
methods: { methods: {
onClick() { onClick() {
if (!this.data.disabled && !this.data.loading) { if (!this.data.loading) {
this.$emit('click'); this.$emit('click');
} }
} },
} noop() {},
},
}); });
<wxs src="../wxs/utils.wxs" module="utils" /> <wxs src="../wxs/utils.wxs" module="utils" />
<wxs src="./index.wxs" module="computed" />
<button <button
id="{{ id }}" id="{{ id }}"
data-detail="{{ dataset }}"
class="custom-class {{ utils.bem('button', [type, size, { block, round, plain, square, loading, disabled, hairline, unclickable: disabled || loading }]) }} {{ hairline ? 'van-hairline--surround' : '' }}" class="custom-class {{ utils.bem('button', [type, size, { block, round, plain, square, loading, disabled, hairline, unclickable: disabled || loading }]) }} {{ hairline ? 'van-hairline--surround' : '' }}"
hover-class="van-button--active hover-class" hover-class="van-button--active hover-class"
lang="{{ lang }}" lang="{{ lang }}"
style="{{ baseStyle }} {{ customStyle }}" form-type="{{ formType }}"
open-type="{{ openType }}" style="{{ computed.rootStyle({ plain, color }) }} {{ customStyle }}"
open-type="{{ disabled ? '' : openType }}"
business-id="{{ businessId }}" business-id="{{ businessId }}"
session-from="{{ sessionFrom }}" session-from="{{ sessionFrom }}"
send-message-title="{{ sendMessageTitle }}" send-message-title="{{ sendMessageTitle }}"
...@@ -15,7 +18,7 @@ ...@@ -15,7 +18,7 @@
show-message-card="{{ showMessageCard }}" show-message-card="{{ showMessageCard }}"
app-parameter="{{ appParameter }}" app-parameter="{{ appParameter }}"
aria-label="{{ ariaLabel }}" aria-label="{{ ariaLabel }}"
bindtap="onClick" bindtap="{{ !disabled ? 'onClick' : 'noop' }}"
bindgetuserinfo="bindGetUserInfo" bindgetuserinfo="bindGetUserInfo"
bindcontact="bindContact" bindcontact="bindContact"
bindgetphonenumber="bindGetPhoneNumber" bindgetphonenumber="bindGetPhoneNumber"
...@@ -28,12 +31,9 @@ ...@@ -28,12 +31,9 @@
custom-class="loading-class" custom-class="loading-class"
size="{{ loadingSize }}" size="{{ loadingSize }}"
type="{{ loadingType }}" type="{{ loadingType }}"
color="{{ loadingColor(type,color,plain) }}" color="{{ computed.loadingColor({ type, color, plain }) }}"
/> />
<view <view wx:if="{{ loadingText }}" class="van-button__loading-text">
wx:if="{{ loadingText }}"
class="van-button__loading-text"
>
{{ loadingText }} {{ loadingText }}
</view> </view>
</block> </block>
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
wx:if="{{ icon }}" wx:if="{{ icon }}"
size="1.2em" size="1.2em"
name="{{ icon }}" name="{{ icon }}"
class-prefix="{{ classPrefix }}"
class="van-button__icon" class="van-button__icon"
custom-style="line-height: inherit;" custom-style="line-height: inherit;"
/> />
...@@ -50,19 +51,3 @@ ...@@ -50,19 +51,3 @@
</view> </view>
</block> </block>
</button> </button>
<wxs module="loadingColor">
function get(type, color,plain) {
if(plain) {
return color ? color: '#c9c9c9';
}
if(type === 'default') {
return '#c9c9c9';
}
return 'white';
}
module.exports = get;
</wxs>
/* eslint-disable */
var style = require('../wxs/style.wxs');
function rootStyle(data) {
if (!data.color) {
return '';
}
var properties = {
color: data.plain ? data.color : '#fff',
background: data.plain ? null : data.color,
};
// hide border when color is linear-gradient
if (data.color.indexOf('gradient') !== -1) {
properties.border = 0;
} else {
properties['border-color'] = data.color;
}
return style(properties);
}
function loadingColor(data) {
if (data.plain) {
return data.color ? data.color : '#c9c9c9';
}
if (data.type === 'default') {
return '#c9c9c9';
}
return '#fff';
}
module.exports = {
rootStyle: rootStyle,
loadingColor: loadingColor,
};
<wxs src="./index.wxs" module="computed"></wxs>
<template name="calendar">
<view class="van-calendar">
<header
title="{{ title }}"
showTitle="{{ showTitle }}"
subtitle="{{ subtitle }}"
showSubtitle="{{ showSubtitle }}"
>
<slot name="title" slot="title"></slot>
</header>
<scroll-view class="van-calendar__body" scroll-y scroll-into-view="{{ scrollIntoView }}">
<month
wx:for="{{ computed.getMonths(minDate, maxDate) }}"
wx:key="index"
id="month{{ index }}"
class="month"
data-date="{{ item }}"
date="{{ item }}"
type="{{ type }}"
color="{{ color }}"
minDate="{{ minDate }}"
maxDate="{{ maxDate }}"
showMark="{{ showMark }}"
formatter="{{ formatter }}"
rowHeight="{{ rowHeight }}"
currentDate="{{ currentDate }}"
showSubtitle="{{ showSubtitle }}"
allowSameDay="{{ allowSameDay }}"
showMonthTitle="{{ index !== 0 || !showSubtitle }}"
bind:click="onClickDay"
/>
</scroll-view>
<view class="van-calendar__footer {{ safeAreaInsetBottom ? 'van-calendar__footer--safe-area-inset-bottom' : '' }}">
<slot name="footer"></slot>
</view>
<view class="van-calendar__footer {{ safeAreaInsetBottom ? 'van-calendar__footer--safe-area-inset-bottom' : '' }}">
<van-button
wx:if="{{ showConfirm }}"
round
block
type="danger"
color="{{ color }}"
custom-class="van-calendar__confirm"
disabled="{{ computed.getButtonDisabled(type, currentDate) }}"
nativeType="text"
bind:click="onConfirm"
>
{{ computed.getButtonDisabled(type, currentDate) ? confirmDisabledText : confirmText }}
</van-button>
</view>
</view>
</template>
import { VantComponent } from '../../../common/component';
VantComponent({
props: {
title: {
type: String,
value: '日期选择',
},
subtitle: String,
showTitle: Boolean,
showSubtitle: Boolean,
},
data: {
weekdays: ['日', '一', '二', '三', '四', '五', '六'],
},
methods: {},
});
<view class="van-calendar__header">
<block wx:if="{{ showTitle }}">
<view class="van-calendar__header-title"><slot name="title"></slot></view>
<view class="van-calendar__header-title">{{ title }}</view>
</block>
<view wx:if="{{ showSubtitle }}" class="van-calendar__header-subtitle">
{{ subtitle }}
</view>
<view class="van-calendar__weekdays">
<view wx:for="{{ weekdays }}" wx:key="index" class="van-calendar__weekday">
{{ item }}
</view>
</view>
</view>
@import '../../../common/index.wxss';.van-calendar__header{-webkit-flex-shrink:0;flex-shrink:0;box-shadow:0 2px 10px rgba(125,126,128,.16);box-shadow:var(--calendar-header-box-shadow,0 2px 10px rgba(125,126,128,.16))}.van-calendar__header-subtitle,.van-calendar__header-title{text-align:center;height:44px;height:var(--calendar-header-title-height,44px);font-weight:500;font-weight:var(--font-weight-bold,500);line-height:44px;line-height:var(--calendar-header-title-height,44px)}.van-calendar__header-title+.van-calendar__header-title,.van-calendar__header-title:empty{display:none}.van-calendar__header-title:empty+.van-calendar__header-title{display:block!important}.van-calendar__weekdays{display:-webkit-flex;display:flex}.van-calendar__weekday{-webkit-flex:1;flex:1;text-align:center;font-size:12px;font-size:var(--calendar-weekdays-font-size,12px);line-height:30px;line-height:var(--calendar-weekdays-height,30px)}
\ No newline at end of file
import { VantComponent } from '../../../common/component';
import {
getMonthEndDay,
compareDay,
getPrevDay,
getNextDay,
} from '../../utils';
VantComponent({
props: {
date: {
type: null,
observer: 'setDays',
},
type: {
type: String,
observer: 'setDays',
},
color: String,
minDate: {
type: null,
observer: 'setDays',
},
maxDate: {
type: null,
observer: 'setDays',
},
showMark: Boolean,
rowHeight: [Number, String],
formatter: {
type: null,
observer: 'setDays',
},
currentDate: {
type: [null, Array],
observer: 'setDays',
},
allowSameDay: Boolean,
showSubtitle: Boolean,
showMonthTitle: Boolean,
},
data: {
visible: true,
days: [],
},
methods: {
onClick(event) {
const { index } = event.currentTarget.dataset;
const item = this.data.days[index];
if (item.type !== 'disabled') {
this.$emit('click', item);
}
},
setDays() {
const days = [];
const startDate = new Date(this.data.date);
const year = startDate.getFullYear();
const month = startDate.getMonth();
const totalDay = getMonthEndDay(
startDate.getFullYear(),
startDate.getMonth() + 1
);
for (let day = 1; day <= totalDay; day++) {
const date = new Date(year, month, day);
const type = this.getDayType(date);
let config = {
date,
type,
text: day,
bottomInfo: this.getBottomInfo(type),
};
if (this.data.formatter) {
config = this.data.formatter(config);
}
days.push(config);
}
this.setData({ days });
},
getMultipleDayType(day) {
const { currentDate } = this.data;
if (!Array.isArray(currentDate)) {
return '';
}
const isSelected = (date) =>
currentDate.some((item) => compareDay(item, date) === 0);
if (isSelected(day)) {
const prevDay = getPrevDay(day);
const nextDay = getNextDay(day);
const prevSelected = isSelected(prevDay);
const nextSelected = isSelected(nextDay);
if (prevSelected && nextSelected) {
return 'multiple-middle';
}
if (prevSelected) {
return 'end';
}
return nextSelected ? 'start' : 'multiple-selected';
}
return '';
},
getRangeDayType(day) {
const { currentDate, allowSameDay } = this.data;
if (!Array.isArray(currentDate)) {
return;
}
const [startDay, endDay] = currentDate;
if (!startDay) {
return;
}
const compareToStart = compareDay(day, startDay);
if (!endDay) {
return compareToStart === 0 ? 'start' : '';
}
const compareToEnd = compareDay(day, endDay);
if (compareToStart === 0 && compareToEnd === 0 && allowSameDay) {
return 'start-end';
}
if (compareToStart === 0) {
return 'start';
}
if (compareToEnd === 0) {
return 'end';
}
if (compareToStart > 0 && compareToEnd < 0) {
return 'middle';
}
},
getDayType(day) {
const { type, minDate, maxDate, currentDate } = this.data;
if (compareDay(day, minDate) < 0 || compareDay(day, maxDate) > 0) {
return 'disabled';
}
if (type === 'single') {
return compareDay(day, currentDate) === 0 ? 'selected' : '';
}
if (type === 'multiple') {
return this.getMultipleDayType(day);
}
/* istanbul ignore else */
if (type === 'range') {
return this.getRangeDayType(day);
}
},
getBottomInfo(type) {
if (this.data.type === 'range') {
if (type === 'start') {
return '开始';
}
if (type === 'end') {
return '结束';
}
if (type === 'start-end') {
return '开始/结束';
}
}
},
},
});
<wxs src="./index.wxs" module="computed"></wxs>
<wxs src="../../../wxs/utils.wxs" module="utils" />
<view class="van-calendar__month" style="{{ computed.getMonthStyle(visible, date, rowHeight) }}">
<view wx:if="{{ showMonthTitle }}" class="van-calendar__month-title">
{{ computed.formatMonthTitle(date) }}
</view>
<view wx:if="{{ visible }}" class="van-calendar__days">
<view wx:if="{{ showMark }}" class="van-calendar__month-mark">
{{ computed.getMark(date) }}
</view>
<view
wx:for="{{ days }}"
wx:key="index"
style="{{ computed.getDayStyle(item.type, index, date, rowHeight, color) }}"
class="{{ utils.bem('calendar__day', [item.type]) }} {{ item.className }}"
data-index="{{ index }}"
bindtap="onClick"
>
<view wx:if="{{ item.type === 'selected' }}" class="van-calendar__selected-day" style="background: {{ color }}">
<view wx:if="{{ item.topInfo }}" class="van-calendar__top-info">{{ item.topInfo }}</view>
{{ item.text }}
<view wx:if="{{ item.bottomInfo }}" class="van-calendar__bottom-info">
{{ item.bottomInfo }}
</view>
</view>
<view wx:else>
<view wx:if="{{ item.topInfo }}" class="van-calendar__top-info">{{ item.topInfo }}</view>
{{ item.text }}
<view wx:if="{{ item.bottomInfo }}" class="van-calendar__bottom-info">
{{ item.bottomInfo }}
</view>
</view>
</view>
</view>
</view>
/* eslint-disable */
var utils = require('../../utils.wxs');
function getMark(date) {
return getDate(date).getMonth() + 1;
}
var ROW_HEIGHT = 64;
function getDayStyle(type, index, date, rowHeight, color) {
var style = [];
var offset = getDate(date).getDay();
if (index === 0) {
style.push(['margin-left', (100 * offset) / 7 + '%']);
}
if (rowHeight !== ROW_HEIGHT) {
style.push(['height', rowHeight + 'px']);
}
if (color) {
if (
type === 'start' ||
type === 'end' ||
type === 'multiple-selected' ||
type === 'multiple-middle'
) {
style.push(['background', color]);
} else if (type === 'middle') {
style.push(['color', color]);
}
}
return style
.map(function(item) {
return item.join(':');
})
.join(';');
}
function formatMonthTitle(date) {
date = getDate(date);
return date.getFullYear() + '年' + (date.getMonth() + 1) + '月';
}
function getMonthStyle(visible, date, rowHeight) {
if (!visible) {
date = getDate(date);
var totalDay = utils.getMonthEndDay(
date.getFullYear(),
date.getMonth() + 1
);
var offset = getDate(date).getDay();
var padding = Math.ceil((totalDay + offset) / 7) * rowHeight;
return 'padding-bottom:' + padding + 'px';
}
}
module.exports = {
getMark: getMark,
getDayStyle: getDayStyle,
formatMonthTitle: formatMonthTitle,
getMonthStyle: getMonthStyle
};
@import '../../../common/index.wxss';.van-calendar{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;height:100%;background-color:#fff;background-color:var(--calendar-background-color,#fff)}.van-calendar__month-title{text-align:center;height:44px;height:var(--calendar-header-title-height,44px);font-weight:500;font-weight:var(--font-weight-bold,500);font-size:14px;font-size:var(--calendar-month-title-font-size,14px);line-height:44px;line-height:var(--calendar-header-title-height,44px)}.van-calendar__days{position:relative;display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap;-webkit-user-select:none;user-select:none}.van-calendar__month-mark{position:absolute;top:50%;left:50%;z-index:0;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);pointer-events:none;color:rgba(242,243,245,.8);color:var(--calendar-month-mark-color,rgba(242,243,245,.8));font-size:160px;font-size:var(--calendar-month-mark-font-size,160px)}.van-calendar__day,.van-calendar__selected-day{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;text-align:center}.van-calendar__day{position:relative;width:14.285%;height:64px;height:var(--calendar-day-height,64px);font-size:16px;font-size:var(--calendar-day-font-size,16px)}.van-calendar__day--end,.van-calendar__day--multiple-middle,.van-calendar__day--multiple-selected,.van-calendar__day--start,.van-calendar__day--start-end{color:#fff;color:var(--calendar-range-edge-color,#fff);background-color:#ee0a24;background-color:var(--calendar-range-edge-background-color,#ee0a24)}.van-calendar__day--start{border-radius:4px 0 0 4px;border-radius:var(--border-radius-md,4px) 0 0 var(--border-radius-md,4px)}.van-calendar__day--end{border-radius:0 4px 4px 0;border-radius:0 var(--border-radius-md,4px) var(--border-radius-md,4px) 0}.van-calendar__day--multiple-selected,.van-calendar__day--start-end{border-radius:4px;border-radius:var(--border-radius-md,4px)}.van-calendar__day--middle{color:#ee0a24;color:var(--calendar-range-middle-color,#ee0a24)}.van-calendar__day--middle:after{position:absolute;top:0;right:0;bottom:0;left:0;background-color:currentColor;content:"";opacity:.1;opacity:var(--calendar-range-middle-background-opacity,.1)}.van-calendar__day--disabled{cursor:default;color:#c8c9cc;color:var(--calendar-day-disabled-color,#c8c9cc)}.van-calendar__bottom-info,.van-calendar__top-info{position:absolute;right:0;left:0;font-size:10px;font-size:var(--calendar-info-font-size,10px);line-height:14px;line-height:var(--calendar-info-line-height,14px)}@media (max-width:350px){.van-calendar__bottom-info,.van-calendar__top-info{font-size:9px}}.van-calendar__top-info{top:6px}.van-calendar__bottom-info{bottom:6px}.van-calendar__selected-day{width:54px;width:var(--calendar-selected-day-size,54px);height:54px;height:var(--calendar-selected-day-size,54px);color:#fff;color:var(--calendar-selected-day-color,#fff);background-color:#ee0a24;background-color:var(--calendar-selected-day-background-color,#ee0a24);border-radius:4px;border-radius:var(--border-radius-md,4px)}
\ No newline at end of file
import { VantComponent } from '../common/component';
import {
ROW_HEIGHT,
getNextDay,
compareDay,
copyDates,
calcDateNum,
formatMonthTitle,
compareMonth,
getMonths,
getDayByOffset,
} from './utils';
import Toast from '../toast/toast';
import { requestAnimationFrame } from '../common/utils';
VantComponent({
props: {
title: {
type: String,
value: '日期选择',
},
color: String,
show: {
type: Boolean,
observer(val) {
if (val) {
this.initRect();
this.scrollIntoView();
}
},
},
formatter: null,
confirmText: {
type: String,
value: '确定',
},
rangePrompt: String,
defaultDate: {
type: [Number, Array],
observer(val) {
this.setData({ currentDate: val });
this.scrollIntoView();
},
},
allowSameDay: Boolean,
confirmDisabledText: String,
type: {
type: String,
value: 'single',
observer: 'reset',
},
minDate: {
type: null,
value: Date.now(),
},
maxDate: {
type: null,
value: new Date(
new Date().getFullYear(),
new Date().getMonth() + 6,
new Date().getDate()
).getTime(),
},
position: {
type: String,
value: 'bottom',
},
rowHeight: {
type: [Number, String],
value: ROW_HEIGHT,
},
round: {
type: Boolean,
value: true,
},
poppable: {
type: Boolean,
value: true,
},
showMark: {
type: Boolean,
value: true,
},
showTitle: {
type: Boolean,
value: true,
},
showConfirm: {
type: Boolean,
value: true,
},
showSubtitle: {
type: Boolean,
value: true,
},
safeAreaInsetBottom: {
type: Boolean,
value: true,
},
closeOnClickOverlay: {
type: Boolean,
value: true,
},
maxRange: {
type: [Number, String],
value: null,
},
},
data: {
subtitle: '',
currentDate: null,
scrollIntoView: '',
},
created() {
this.setData({
currentDate: this.getInitialDate(),
});
},
mounted() {
if (this.data.show || !this.data.poppable) {
this.initRect();
this.scrollIntoView();
}
},
methods: {
reset() {
this.setData({ currentDate: this.getInitialDate() });
this.scrollIntoView();
},
initRect() {
if (this.contentObserver != null) {
this.contentObserver.disconnect();
}
const contentObserver = this.createIntersectionObserver({
thresholds: [0, 0.1, 0.9, 1],
observeAll: true,
});
this.contentObserver = contentObserver;
contentObserver.relativeTo('.van-calendar__body');
contentObserver.observe('.month', (res) => {
if (res.boundingClientRect.top <= res.relativeRect.top) {
// @ts-ignore
this.setData({ subtitle: formatMonthTitle(res.dataset.date) });
}
});
},
getInitialDate() {
const { type, defaultDate, minDate } = this.data;
if (type === 'range') {
const [startDay, endDay] = defaultDate || [];
return [
startDay || minDate,
endDay || getNextDay(new Date(minDate)).getTime(),
];
}
if (type === 'multiple') {
return defaultDate || [minDate];
}
return defaultDate || minDate;
},
scrollIntoView() {
requestAnimationFrame(() => {
const {
currentDate,
type,
show,
poppable,
minDate,
maxDate,
} = this.data;
// @ts-ignore
const targetDate = type === 'single' ? currentDate : currentDate[0];
const displayed = show || !poppable;
if (!targetDate || !displayed) {
return;
}
const months = getMonths(minDate, maxDate);
months.some((month, index) => {
if (compareMonth(month, targetDate) === 0) {
this.setData({ scrollIntoView: `month${index}` });
return true;
}
return false;
});
});
},
onOpen() {
this.$emit('open');
},
onOpened() {
this.$emit('opened');
},
onClose() {
this.$emit('close');
},
onClosed() {
this.$emit('closed');
},
onClickDay(event) {
const { date } = event.detail;
const { type, currentDate, allowSameDay } = this.data;
if (type === 'range') {
// @ts-ignore
const [startDay, endDay] = currentDate;
if (startDay && !endDay) {
const compareToStart = compareDay(date, startDay);
if (compareToStart === 1) {
this.select([startDay, date], true);
} else if (compareToStart === -1) {
this.select([date, null]);
} else if (allowSameDay) {
this.select([date, date]);
}
} else {
this.select([date, null]);
}
} else if (type === 'multiple') {
let selectedIndex;
// @ts-ignore
const selected = currentDate.some((dateItem, index) => {
const equal = compareDay(dateItem, date) === 0;
if (equal) {
selectedIndex = index;
}
return equal;
});
if (selected) {
// @ts-ignore
const cancelDate = currentDate.splice(selectedIndex, 1);
this.setData({ currentDate });
this.unselect(cancelDate);
} else {
// @ts-ignore
this.select([...currentDate, date]);
}
} else {
this.select(date, true);
}
},
unselect(dateArray) {
const date = dateArray[0];
if (date) {
this.$emit('unselect', copyDates(date));
}
},
select(date, complete) {
if (complete && this.data.type === 'range') {
const valid = this.checkRange(date);
if (!valid) {
// auto selected to max range if showConfirm
if (this.data.showConfirm) {
this.emit([
date[0],
getDayByOffset(date[0], this.data.maxRange - 1),
]);
} else {
this.emit(date);
}
return;
}
}
this.emit(date);
if (complete && !this.data.showConfirm) {
this.onConfirm();
}
},
emit(date) {
const getTime = (date) => (date instanceof Date ? date.getTime() : date);
this.setData({
currentDate: Array.isArray(date) ? date.map(getTime) : getTime(date),
});
this.$emit('select', copyDates(date));
},
checkRange(date) {
const { maxRange, rangePrompt } = this.data;
if (maxRange && calcDateNum(date) > maxRange) {
Toast({
context: this,
message: rangePrompt || `选择天数不能超过 ${maxRange} 天`,
});
return false;
}
return true;
},
onConfirm() {
if (
this.data.type === 'range' &&
!this.checkRange(this.data.currentDate)
) {
return;
}
wx.nextTick(() => {
// @ts-ignore
this.$emit('confirm', copyDates(this.data.currentDate));
});
},
},
});
{
"component": true,
"usingComponents": {
"header": "./components/header/index",
"month": "./components/month/index",
"van-button": "../button/index",
"van-popup": "../popup/index",
"van-toast": "../toast/index"
}
}
<wxs src="./index.wxs" module="computed" />
<import src="./calendar.wxml" />
<van-popup
wx:if="{{ poppable }}"
custom-class="van-calendar__popup--{{ position }}"
close-icon-class="van-calendar__close-icon"
show="{{ show }}"
round="{{ round }}"
position="{{ position }}"
closeable="{{ showTitle || showSubtitle }}"
close-on-click-overlay="{{ closeOnClickOverlay }}"
bind:enter="onOpen"
bind:close="onClose"
bind:after-enter="onOpened"
bind:after-leave="onClosed"
>
<template
is="calendar"
data="{{ title, subtitle, showTitle, showSubtitle, minDate, maxDate, type, color, showMark, formatter, rowHeight, currentDate, safeAreaInsetBottom, showConfirm, confirmDisabledText, confirmText, scrollIntoView, allowSameDay }}"
/>
</van-popup>
<template
wx:else
is="calendar"
data="{{ title, subtitle, showTitle, showSubtitle, minDate, maxDate, type, color, showMark, formatter, rowHeight, currentDate, safeAreaInsetBottom, showConfirm, confirmDisabledText, confirmText, scrollIntoView, allowSameDay }}"
/>
<van-toast id="van-toast" />
/* eslint-disable */
var utils = require('./utils.wxs');
function getMonths(minDate, maxDate) {
var months = [];
var cursor = getDate(minDate);
cursor.setDate(1);
do {
months.push(cursor.getTime());
cursor.setMonth(cursor.getMonth() + 1);
} while (utils.compareMonth(cursor, getDate(maxDate)) !== 1);
return months;
}
function getButtonDisabled(type, currentDate) {
if (currentDate == null) {
return true;
}
if (type === 'range') {
return !currentDate[0] || !currentDate[1];
}
if (type === 'multiple') {
return !currentDate.length;
}
return !currentDate;
}
module.exports = {
getMonths: getMonths,
getButtonDisabled: getButtonDisabled
};
@import '../common/index.wxss';.van-calendar{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;height:100%;height:var(--calendar-height,100%);background-color:#fff;background-color:var(--calendar-background-color,#fff)}.van-calendar__close-icon{top:11px}.van-calendar__popup--bottom,.van-calendar__popup--top{height:80%;height:var(--calendar-popup-height,80%)}.van-calendar__popup--left,.van-calendar__popup--right{height:100%}.van-calendar__body{-webkit-flex:1;flex:1;overflow:auto;-webkit-overflow-scrolling:touch}.van-calendar__footer{-webkit-flex-shrink:0;flex-shrink:0;padding:0 16px;padding:0 var(--padding-md,16px)}.van-calendar__footer--safe-area-inset-bottom{padding-bottom:env(safe-area-inset-bottom)}.van-calendar__footer+.van-calendar__footer,.van-calendar__footer:empty{display:none}.van-calendar__footer:empty+.van-calendar__footer{display:block!important}.van-calendar__confirm{height:36px!important;height:var(--calendar-confirm-button-height,36px)!important;margin:7px 0!important;margin:var(--calendar-confirm-button-margin,7px 0)!important;line-height:34px!important;line-height:var(--calendar-confirm-button-line-height,34px)!important}
\ No newline at end of file
export declare const ROW_HEIGHT = 64;
export declare function formatMonthTitle(date: Date): string;
export declare function compareMonth(
date1: Date | number,
date2: Date | number
): 0 | 1 | -1;
export declare function compareDay(
day1: Date | number,
day2: Date | number
): 0 | 1 | -1;
export declare function getDayByOffset(date: Date, offset: number): Date;
export declare function getPrevDay(date: Date): Date;
export declare function getNextDay(date: Date): Date;
export declare function calcDateNum(date: [Date, Date]): number;
export declare function copyDates(dates: Date | Date[]): Date | Date[];
export declare function getMonthEndDay(year: number, month: number): number;
export declare function getMonths(minDate: number, maxDate: number): number[];
export const ROW_HEIGHT = 64;
export function formatMonthTitle(date) {
if (!(date instanceof Date)) {
date = new Date(date);
}
return `${date.getFullYear()}${date.getMonth() + 1}月`;
}
export function compareMonth(date1, date2) {
if (!(date1 instanceof Date)) {
date1 = new Date(date1);
}
if (!(date2 instanceof Date)) {
date2 = new Date(date2);
}
const year1 = date1.getFullYear();
const year2 = date2.getFullYear();
const month1 = date1.getMonth();
const month2 = date2.getMonth();
if (year1 === year2) {
return month1 === month2 ? 0 : month1 > month2 ? 1 : -1;
}
return year1 > year2 ? 1 : -1;
}
export function compareDay(day1, day2) {
if (!(day1 instanceof Date)) {
day1 = new Date(day1);
}
if (!(day2 instanceof Date)) {
day2 = new Date(day2);
}
const compareMonthResult = compareMonth(day1, day2);
if (compareMonthResult === 0) {
const date1 = day1.getDate();
const date2 = day2.getDate();
return date1 === date2 ? 0 : date1 > date2 ? 1 : -1;
}
return compareMonthResult;
}
export function getDayByOffset(date, offset) {
date = new Date(date);
date.setDate(date.getDate() + offset);
return date;
}
export function getPrevDay(date) {
return getDayByOffset(date, -1);
}
export function getNextDay(date) {
return getDayByOffset(date, 1);
}
export function calcDateNum(date) {
const day1 = new Date(date[0]).getTime();
const day2 = new Date(date[1]).getTime();
return (day2 - day1) / (1000 * 60 * 60 * 24) + 1;
}
export function copyDates(dates) {
if (Array.isArray(dates)) {
return dates.map((date) => {
if (date === null) {
return date;
}
return new Date(date);
});
}
return new Date(dates);
}
export function getMonthEndDay(year, month) {
return 32 - new Date(year, month - 1, 32).getDate();
}
export function getMonths(minDate, maxDate) {
const months = [];
const cursor = new Date(minDate);
cursor.setDate(1);
do {
months.push(cursor.getTime());
cursor.setMonth(cursor.getMonth() + 1);
} while (compareMonth(cursor, maxDate) !== 1);
return months;
}
/* eslint-disable */
function getMonthEndDay(year, month) {
return 32 - getDate(year, month - 1, 32).getDate();
}
function compareMonth(date1, date2) {
date1 = getDate(date1);
date2 = getDate(date2);
var year1 = date1.getFullYear();
var year2 = date2.getFullYear();
var month1 = date1.getMonth();
var month2 = date2.getMonth();
if (year1 === year2) {
return month1 === month2 ? 0 : month1 > month2 ? 1 : -1;
}
return year1 > year2 ? 1 : -1;
}
module.exports = {
getMonthEndDay: getMonthEndDay,
compareMonth: compareMonth
};
...@@ -7,7 +7,7 @@ VantComponent({ ...@@ -7,7 +7,7 @@ VantComponent({
'thumb-class', 'thumb-class',
'title-class', 'title-class',
'price-class', 'price-class',
'origin-price-class' 'origin-price-class',
], ],
mixins: [link], mixins: [link],
props: { props: {
...@@ -18,7 +18,7 @@ VantComponent({ ...@@ -18,7 +18,7 @@ VantComponent({
title: String, title: String,
price: { price: {
type: String, type: String,
observer: 'updatePrice' observer: 'updatePrice',
}, },
centered: Boolean, centered: Boolean,
lazyLoad: Boolean, lazyLoad: Boolean,
...@@ -26,12 +26,12 @@ VantComponent({ ...@@ -26,12 +26,12 @@ VantComponent({
originPrice: String, originPrice: String,
thumbMode: { thumbMode: {
type: String, type: String,
value: 'aspectFit' value: 'aspectFit',
}, },
currency: { currency: {
type: String, type: String,
value: '¥' value: '¥',
} },
}, },
methods: { methods: {
updatePrice() { updatePrice() {
...@@ -39,11 +39,11 @@ VantComponent({ ...@@ -39,11 +39,11 @@ VantComponent({
const priceArr = price.toString().split('.'); const priceArr = price.toString().split('.');
this.setData({ this.setData({
integerStr: priceArr[0], integerStr: priceArr[0],
decimalStr: priceArr[1] ? `.${priceArr[1]}` : '' decimalStr: priceArr[1] ? `.${priceArr[1]}` : '',
}); });
}, },
onClickThumb() { onClickThumb() {
this.jumpLink('thumbLink'); this.jumpLink('thumbLink');
} },
} },
}); });
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
lazy-load="{{ lazyLoad }}" lazy-load="{{ lazyLoad }}"
class="van-card__img thumb-class" class="van-card__img thumb-class"
/> />
<slot name="thumb" /> <slot wx:else name="thumb" />
<van-tag <van-tag
wx:if="{{ tag }}" wx:if="{{ tag }}"
mark mark
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
> >
{{ tag }} {{ tag }}
</van-tag> </van-tag>
<slot wx:else name="tag" />
</view> </view>
<view class="van-card__content {{ utils.bem('card__content', { center: centered }) }}"> <view class="van-card__content {{ utils.bem('card__content', { center: centered }) }}">
...@@ -34,9 +35,14 @@ ...@@ -34,9 +35,14 @@
<view class="van-card__bottom"> <view class="van-card__bottom">
<slot name="price-top" /> <slot name="price-top" />
<view wx:if="{{ price || price === 0 }}" class="van-card__price price-class">{{ currency }}<text class="van-card__price-integer">{{ integerStr }}</text><text class="van-card__price-decimal">{{ decimalStr }}</text></view> <view wx:if="{{ price || price === 0 }}" class="van-card__price price-class">
<text>{{ currency }}</text>
<text class="van-card__price-integer">{{ integerStr }}</text>
<text class="van-card__price-decimal">{{ decimalStr }}</text>
</view>
<slot wx:else name="price" /> <slot wx:else name="price" />
<view wx:if="{{ originPrice || originPrice === 0 }}" class="van-card__origin-price origin-price-class">{{ currency }} {{ originPrice }}</view> <view wx:if="{{ originPrice || originPrice === 0 }}" class="van-card__origin-price origin-price-class">{{ currency }} {{ originPrice }}</view>
<slot wx:else name="origin-price" />
<view wx:if="{{ num }}" class="van-card__num num-class">x {{ num }}</view> <view wx:if="{{ num }}" class="van-card__num num-class">x {{ num }}</view>
<slot wx:else name="num" /> <slot wx:else name="num" />
<slot name="bottom" /> <slot name="bottom" />
......
@import '../common/index.wxss';.van-card{position:relative;box-sizing:border-box;padding:8px 16px;padding:var(--card-padding,8px 16px);font-size:12px;font-size:var(--card-font-size,12px);color:#323233;color:var(--card-text-color,#323233);background-color:#fafafa;background-color:var(--card-background-color,#fafafa)}.van-card__header{display:-webkit-flex;display:flex}.van-card__header--center{-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center}.van-card__thumb{position:relative;-webkit-flex:none;flex:none;width:88px;width:var(--card-thumb-size,88px);height:88px;height:var(--card-thumb-size,88px);margin-right:8px;margin-right:var(--padding-xs,8px)}.van-card__thumb:empty{display:none}.van-card__img{width:100%;height:100%;border-radius:8px;border-radius:var(--border-radius-lg,8px)}.van-card__content{position:relative;display:-webkit-flex;display:flex;-webkit-flex:1;flex:1;-webkit-flex-direction:column;flex-direction:column;-webkit-justify-content:space-between;justify-content:space-between;min-width:0;min-height:88px;min-height:var(--card-thumb-size,88px)}.van-card__content--center{-webkit-justify-content:center;justify-content:center}.van-card__desc,.van-card__title{word-wrap:break-word}.van-card__title{font-weight:700;line-height:16px;line-height:var(--card-title-line-height,16px)}.van-card__desc{line-height:20px;line-height:var(--card-desc-line-height,20px);color:#646566;color:var(--card-desc-color,#646566)}.van-card__bottom{line-height:20px}.van-card__price{display:inline-block;font-weight:700;color:#ee0a24;color:var(--card-price-color,#ee0a24);font-size:12px;font-size:var(--card-price-font-size,12px)}.van-card__price-integer{font-size:16px;font-size:var(--card-price-integer-font-size,16px)}.van-card__price-decimal,.van-card__price-integer{font-family:Avenir-Heavy,PingFang SC,Helvetica Neue,Arial,sans-serif;font-family:var(--card-price-font-family,Avenir-Heavy,PingFang SC,Helvetica Neue,Arial,sans-serif)}.van-card__origin-price{display:inline-block;margin-left:5px;text-decoration:line-through;font-size:10px;font-size:var(--card-origin-price-font-size,10px);color:#646566;color:var(--card-origin-price-color,#646566)}.van-card__num{float:right}.van-card__tag{position:absolute;top:2px;left:0}.van-card__footer{-webkit-flex:none;flex:none;width:100%;text-align:right} @import '../common/index.wxss';.van-card{position:relative;box-sizing:border-box;padding:8px 16px;padding:var(--card-padding,8px 16px);font-size:12px;font-size:var(--card-font-size,12px);color:#323233;color:var(--card-text-color,#323233);background-color:#fafafa;background-color:var(--card-background-color,#fafafa)}.van-card__header{display:-webkit-flex;display:flex}.van-card__header--center{-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center}.van-card__thumb{position:relative;-webkit-flex:none;flex:none;width:88px;width:var(--card-thumb-size,88px);height:88px;height:var(--card-thumb-size,88px);margin-right:8px;margin-right:var(--padding-xs,8px)}.van-card__thumb:empty{display:none}.van-card__img{width:100%;height:100%;border-radius:8px;border-radius:var(--border-radius-lg,8px)}.van-card__content{position:relative;display:-webkit-flex;display:flex;-webkit-flex:1;flex:1;-webkit-flex-direction:column;flex-direction:column;-webkit-justify-content:space-between;justify-content:space-between;min-width:0;min-height:88px;min-height:var(--card-thumb-size,88px)}.van-card__content--center{-webkit-justify-content:center;justify-content:center}.van-card__desc,.van-card__title{word-wrap:break-word}.van-card__title{font-weight:700;line-height:16px;line-height:var(--card-title-line-height,16px)}.van-card__desc{line-height:20px;line-height:var(--card-desc-line-height,20px);color:#646566;color:var(--card-desc-color,#646566)}.van-card__bottom{line-height:20px}.van-card__price{display:inline-block;font-weight:700;color:#ee0a24;color:var(--card-price-color,#ee0a24);font-size:12px;font-size:var(--card-price-font-size,12px)}.van-card__price-integer{font-size:16px;font-size:var(--card-price-integer-font-size,16px)}.van-card__price-decimal,.van-card__price-integer{font-family:Avenir-Heavy,PingFang SC,Helvetica Neue,Arial,sans-serif;font-family:var(--card-price-font-family,Avenir-Heavy,PingFang SC,Helvetica Neue,Arial,sans-serif)}.van-card__origin-price{display:inline-block;margin-left:5px;text-decoration:line-through;font-size:10px;font-size:var(--card-origin-price-font-size,10px);color:#646566;color:var(--card-origin-price-color,#646566)}.van-card__num{float:right}.van-card__tag{position:absolute!important;top:2px;left:0}.van-card__footer{-webkit-flex:none;flex:none;width:100%;text-align:right}
\ No newline at end of file \ No newline at end of file
...@@ -4,7 +4,7 @@ VantComponent({ ...@@ -4,7 +4,7 @@ VantComponent({
title: String, title: String,
border: { border: {
type: Boolean, type: Boolean,
value: true value: true,
} },
} },
}); });
...@@ -6,7 +6,7 @@ VantComponent({ ...@@ -6,7 +6,7 @@ VantComponent({
'label-class', 'label-class',
'value-class', 'value-class',
'right-icon-class', 'right-icon-class',
'hover-class' 'hover-class',
], ],
mixins: [link], mixins: [link],
props: { props: {
...@@ -25,13 +25,14 @@ VantComponent({ ...@@ -25,13 +25,14 @@ VantComponent({
useLabelSlot: Boolean, useLabelSlot: Boolean,
border: { border: {
type: Boolean, type: Boolean,
value: true value: true,
} },
titleStyle: String,
}, },
methods: { methods: {
onClick(event) { onClick(event) {
this.$emit('click', event.detail); this.$emit('click', event.detail);
this.jumpLink(); this.jumpLink();
} },
} },
}); });
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
<slot wx:else name="icon" /> <slot wx:else name="icon" />
<view <view
style="{{ titleWidth ? 'max-width:' + titleWidth + ';min-width:' + titleWidth : '' }}" style="{{ (titleWidth ? 'max-width:' + titleWidth + ';min-width:' + titleWidth + ';' : '') + titleStyle }}"
class="van-cell__title title-class" class="van-cell__title title-class"
> >
<block wx:if="{{ title }}">{{ title }}</block> <block wx:if="{{ title }}">{{ title }}</block>
......
@import '../common/index.wxss';.van-cell{position:relative;display:-webkit-flex;display:flex;box-sizing:border-box;width:100%;padding:10px 16px;padding:var(--cell-vertical-padding,10px) var(--cell-horizontal-padding,16px);font-size:14px;font-size:var(--cell-font-size,14px);line-height:24px;line-height:var(--cell-line-height,24px);color:#323233;color:var(--cell-text-color,#323233);background-color:#fff;background-color:var(--cell-background-color,#fff)}.van-cell:after{position:absolute;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;content:" ";pointer-events:none;top:auto;right:0;bottom:0;left:16px;border-bottom:1px solid #ebedf0;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.van-cell--borderless:after{display:none}.van-cell-group{background-color:#fff;background-color:var(--cell-background-color,#fff)}.van-cell__label{margin-top:3px;margin-top:var(--cell-label-margin-top,3px);font-size:12px;font-size:var(--cell-label-font-size,12px);line-height:18px;line-height:var(--cell-label-line-height,18px);color:#969799;color:var(--cell-label-color,#969799)}.van-cell__value{overflow:hidden;text-align:right;vertical-align:middle;color:#969799;color:var(--cell-value-color,#969799)}.van-cell__title,.van-cell__value{-webkit-flex:1;flex:1}.van-cell__title:empty,.van-cell__value:empty{display:none}.van-cell__left-icon-wrap,.van-cell__right-icon-wrap{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;height:24px;height:var(--cell-line-height,24px);font-size:16px;font-size:var(--cell-icon-size,16px)}.van-cell__left-icon-wrap{margin-right:5px}.van-cell__right-icon-wrap{margin-left:5px;color:#969799;color:var(--cell-right-icon-color,#969799)}.van-cell__left-icon{vertical-align:middle}.van-cell__left-icon,.van-cell__right-icon{line-height:24px;line-height:var(--cell-line-height,24px)}.van-cell--clickable.van-cell--hover{background-color:#f2f3f5;background-color:var(--cell-active-color,#f2f3f5)}.van-cell--required{overflow:visible}.van-cell--required:before{position:absolute;content:"*";left:8px;left:var(--padding-xs,8px);font-size:14px;font-size:var(--cell-font-size,14px);color:#ee0a24;color:var(--cell-required-color,#ee0a24)}.van-cell--center{-webkit-align-items:center;align-items:center}.van-cell--large{padding-top:12px;padding-top:var(--cell-large-vertical-padding,12px);padding-bottom:12px;padding-bottom:var(--cell-large-vertical-padding,12px)}.van-cell--large .van-cell__title{font-size:16px;font-size:var(--cell-large-title-font-size,16px)}.van-cell--large .van-cell__label{font-size:14px;font-size:var(--cell-large-label-font-size,14px)} @import '../common/index.wxss';.van-cell{position:relative;display:-webkit-flex;display:flex;box-sizing:border-box;width:100%;padding:10px 16px;padding:var(--cell-vertical-padding,10px) var(--cell-horizontal-padding,16px);font-size:14px;font-size:var(--cell-font-size,14px);line-height:24px;line-height:var(--cell-line-height,24px);color:#323233;color:var(--cell-text-color,#323233);background-color:#fff;background-color:var(--cell-background-color,#fff)}.van-cell:after{position:absolute;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;content:" ";pointer-events:none;right:16px;bottom:0;left:16px;border-bottom:1px solid #ebedf0;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.van-cell--borderless:after{display:none}.van-cell-group{background-color:#fff;background-color:var(--cell-background-color,#fff)}.van-cell__label{margin-top:3px;margin-top:var(--cell-label-margin-top,3px);font-size:12px;font-size:var(--cell-label-font-size,12px);line-height:18px;line-height:var(--cell-label-line-height,18px);color:#969799;color:var(--cell-label-color,#969799)}.van-cell__value{overflow:hidden;text-align:right;vertical-align:middle;color:#969799;color:var(--cell-value-color,#969799)}.van-cell__title,.van-cell__value{-webkit-flex:1;flex:1}.van-cell__title:empty,.van-cell__value:empty{display:none}.van-cell__left-icon-wrap,.van-cell__right-icon-wrap{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;height:24px;height:var(--cell-line-height,24px);font-size:16px;font-size:var(--cell-icon-size,16px)}.van-cell__left-icon-wrap{margin-right:4px;margin-right:var(--padding-base,4px)}.van-cell__right-icon-wrap{margin-left:4px;margin-left:var(--padding-base,4px);color:#969799;color:var(--cell-right-icon-color,#969799)}.van-cell__left-icon{vertical-align:middle}.van-cell__left-icon,.van-cell__right-icon{line-height:24px;line-height:var(--cell-line-height,24px)}.van-cell--clickable.van-cell--hover{background-color:#f2f3f5;background-color:var(--cell-active-color,#f2f3f5)}.van-cell--required{overflow:visible}.van-cell--required:before{position:absolute;content:"*";left:8px;left:var(--padding-xs,8px);font-size:14px;font-size:var(--cell-font-size,14px);color:#ee0a24;color:var(--cell-required-color,#ee0a24)}.van-cell--center{-webkit-align-items:center;align-items:center}.van-cell--large{padding-top:12px;padding-top:var(--cell-large-vertical-padding,12px);padding-bottom:12px;padding-bottom:var(--cell-large-vertical-padding,12px)}.van-cell--large .van-cell__title{font-size:16px;font-size:var(--cell-large-title-font-size,16px)}.van-cell--large .van-cell__value{font-size:16px;font-size:var(--cell-large-value-font-size,16px)}.van-cell--large .van-cell__label{font-size:14px;font-size:var(--cell-large-label-font-size,14px)}
\ No newline at end of file \ No newline at end of file
...@@ -13,12 +13,12 @@ VantComponent({ ...@@ -13,12 +13,12 @@ VantComponent({
max: Number, max: Number,
value: { value: {
type: Array, type: Array,
observer: 'updateChildren' observer: 'updateChildren',
}, },
disabled: { disabled: {
type: Boolean, type: Boolean,
observer: 'updateChildren' observer: 'updateChildren',
} },
}, },
methods: { methods: {
updateChildren() { updateChildren() {
...@@ -28,8 +28,8 @@ VantComponent({ ...@@ -28,8 +28,8 @@ VantComponent({
const { value, disabled } = this.data; const { value, disabled } = this.data;
child.setData({ child.setData({
value: value.indexOf(child.data.name) !== -1, value: value.indexOf(child.data.name) !== -1,
parentDisabled: disabled parentDisabled: disabled,
}); });
} },
} },
}); });
...@@ -20,22 +20,21 @@ VantComponent({ ...@@ -20,22 +20,21 @@ VantComponent({
labelDisabled: Boolean, labelDisabled: Boolean,
shape: { shape: {
type: String, type: String,
value: 'round' value: 'round',
}, },
iconSize: { iconSize: {
type: null, type: null,
value: 20 value: 20,
} },
}, },
data: { data: {
parentDisabled: false parentDisabled: false,
}, },
methods: { methods: {
emitChange(value) { emitChange(value) {
if (this.parent) { if (this.parent) {
this.setParentValue(this.parent, value); this.setParentValue(this.parent, value);
} } else {
else {
emit(this, value); emit(this, value);
} }
}, },
...@@ -63,14 +62,13 @@ VantComponent({ ...@@ -63,14 +62,13 @@ VantComponent({
parentValue.push(name); parentValue.push(name);
emit(parent, parentValue); emit(parent, parentValue);
} }
} } else {
else {
const index = parentValue.indexOf(name); const index = parentValue.indexOf(name);
if (index !== -1) { if (index !== -1) {
parentValue.splice(index, 1); parentValue.splice(index, 1);
emit(parent, parentValue); emit(parent, parentValue);
} }
} }
} },
} },
}); });
/* eslint-disable */ /* eslint-disable */
var utils = require('../wxs/utils.wxs'); var style = require('../wxs/style.wxs');
var addUnit = require('../wxs/add-unit.wxs');
function iconStyle(checkedColor, value, disabled, parentDisabled, iconSize) { function iconStyle(checkedColor, value, disabled, parentDisabled, iconSize) {
var styles = [['font-size', utils.addUnit(iconSize)]]; var styles = {
'font-size': addUnit(iconSize),
};
if (checkedColor && value && !disabled && !parentDisabled) { if (checkedColor && value && !disabled && !parentDisabled) {
styles.push(['border-color', checkedColor]); styles['border-color'] = checkedColor;
styles.push(['background-color', checkedColor]); styles['background-color'] = checkedColor;
} }
return styles return style(styles);
.map(function(item) {
return item.join(':');
})
.join(';');
} }
module.exports = { module.exports = {
iconStyle: iconStyle iconStyle: iconStyle,
}; };
/// <reference types="miniprogram-api-typings" />
declare type CanvasContext = WechatMiniprogram.CanvasContext;
export declare function adaptor(
ctx: CanvasContext & Record<string, unknown>
): CanvasContext;
export {};
export function adaptor(ctx) {
// @ts-ignore
return Object.assign(ctx, {
setStrokeStyle(val) {
ctx.strokeStyle = val;
},
setLineWidth(val) {
ctx.lineWidth = val;
},
setLineCap(val) {
ctx.lineCap = val;
},
setFillStyle(val) {
ctx.fillStyle = val;
},
setFontSize(val) {
ctx.font = String(val);
},
setGlobalAlpha(val) {
ctx.globalAlpha = val;
},
setLineJoin(val) {
ctx.lineJoin = val;
},
setTextAlign(val) {
ctx.textAlign = val;
},
setMiterLimit(val) {
ctx.miterLimit = val;
},
setShadow(offsetX, offsetY, blur, color) {
ctx.shadowOffsetX = offsetX;
ctx.shadowOffsetY = offsetY;
ctx.shadowBlur = blur;
ctx.shadowColor = color;
},
setTextBaseline(val) {
ctx.textBaseline = val;
},
createCircularGradient() {},
draw() {},
});
}
import { VantComponent } from '../common/component'; import { VantComponent } from '../common/component';
import { isObj } from '../common/utils';
import { BLUE, WHITE } from '../common/color'; import { BLUE, WHITE } from '../common/color';
import { adaptor } from './canvas';
import { isObj } from '../common/validator';
import { getSystemInfoSync } from '../common/utils';
function format(rate) { function format(rate) {
return Math.min(Math.max(rate, 0), 100); return Math.min(Math.max(rate, 0), 100);
} }
...@@ -12,62 +14,95 @@ VantComponent({ ...@@ -12,62 +14,95 @@ VantComponent({
text: String, text: String,
lineCap: { lineCap: {
type: String, type: String,
value: 'round' value: 'round',
}, },
value: { value: {
type: Number, type: Number,
value: 0, value: 0,
observer: 'reRender' observer: 'reRender',
}, },
speed: { speed: {
type: Number, type: Number,
value: 50 value: 50,
}, },
size: { size: {
type: Number, type: Number,
value: 100, value: 100,
observer() {
this.drawCircle(this.currentValue);
},
}, },
fill: String, fill: String,
layerColor: { layerColor: {
type: String, type: String,
value: WHITE value: WHITE,
}, },
color: { color: {
type: [String, Object], type: [String, Object],
value: BLUE, value: BLUE,
observer: 'setHoverColor' observer() {
this.setHoverColor().then(() => {
this.drawCircle(this.currentValue);
});
},
},
type: {
type: String,
value: '',
}, },
strokeWidth: { strokeWidth: {
type: Number, type: Number,
value: 4 value: 4,
}, },
clockwise: { clockwise: {
type: Boolean, type: Boolean,
value: true value: true,
} },
}, },
data: { data: {
hoverColor: BLUE hoverColor: BLUE,
}, },
methods: { methods: {
getContext() { getContext() {
if (!this.ctx) { const { type, size } = this.data;
this.ctx = wx.createCanvasContext('van-circle', this); if (type === '') {
const ctx = wx.createCanvasContext('van-circle', this);
return Promise.resolve(ctx);
}
const dpr = getSystemInfoSync().pixelRatio;
return new Promise((resolve) => {
wx.createSelectorQuery()
.in(this)
.select('#van-circle')
.node()
.exec((res) => {
const canvas = res[0].node;
const ctx = canvas.getContext(type);
if (!this.inited) {
this.inited = true;
canvas.width = size * dpr;
canvas.height = size * dpr;
ctx.scale(dpr, dpr);
} }
return this.ctx; resolve(adaptor(ctx));
});
});
}, },
setHoverColor() { setHoverColor() {
const context = this.getContext();
const { color, size } = this.data; const { color, size } = this.data;
let hoverColor = color;
if (isObj(color)) { if (isObj(color)) {
return this.getContext().then((context) => {
const LinearColor = context.createLinearGradient(size, 0, 0, 0); const LinearColor = context.createLinearGradient(size, 0, 0, 0);
Object.keys(color) Object.keys(color)
.sort((a, b) => parseFloat(a) - parseFloat(b)) .sort((a, b) => parseFloat(a) - parseFloat(b))
.map(key => LinearColor.addColorStop(parseFloat(key) / 100, color[key])); .map((key) =>
hoverColor = LinearColor; LinearColor.addColorStop(parseFloat(key) / 100, color[key])
);
this.hoverColor = LinearColor;
});
} }
this.setData({ hoverColor }); this.hoverColor = color;
return Promise.resolve();
}, },
presetCanvas(context, strokeStyle, beginAngle, endAngle, fill) { presetCanvas(context, strokeStyle, beginAngle, endAngle, fill) {
const { strokeWidth, lineCap, clockwise, size } = this.data; const { strokeWidth, lineCap, clockwise, size } = this.data;
...@@ -89,17 +124,17 @@ VantComponent({ ...@@ -89,17 +124,17 @@ VantComponent({
this.presetCanvas(context, layerColor, 0, PERIMETER, fill); this.presetCanvas(context, layerColor, 0, PERIMETER, fill);
}, },
renderHoverCircle(context, formatValue) { renderHoverCircle(context, formatValue) {
const { clockwise, hoverColor } = this.data; const { clockwise } = this.data;
// 结束角度 // 结束角度
const progress = PERIMETER * (formatValue / 100); const progress = PERIMETER * (formatValue / 100);
const endAngle = clockwise const endAngle = clockwise
? BEGIN_ANGLE + progress ? BEGIN_ANGLE + progress
: 3 * Math.PI - (BEGIN_ANGLE + progress); : 3 * Math.PI - (BEGIN_ANGLE + progress);
this.presetCanvas(context, hoverColor, BEGIN_ANGLE, endAngle); this.presetCanvas(context, this.hoverColor, BEGIN_ANGLE, endAngle);
}, },
drawCircle(currentValue) { drawCircle(currentValue) {
const context = this.getContext();
const { size } = this.data; const { size } = this.data;
this.getContext().then((context) => {
context.clearRect(0, 0, size, size); context.clearRect(0, 0, size, size);
this.renderLayerCircle(context); this.renderLayerCircle(context);
const formatValue = format(currentValue); const formatValue = format(currentValue);
...@@ -107,6 +142,7 @@ VantComponent({ ...@@ -107,6 +142,7 @@ VantComponent({
this.renderHoverCircle(context, formatValue); this.renderHoverCircle(context, formatValue);
} }
context.draw(); context.draw();
});
}, },
reRender() { reRender() {
// tofector 动画暂时没有想到好的解决方案 // tofector 动画暂时没有想到好的解决方案
...@@ -121,13 +157,11 @@ VantComponent({ ...@@ -121,13 +157,11 @@ VantComponent({
if (this.currentValue !== value) { if (this.currentValue !== value) {
if (this.currentValue < value) { if (this.currentValue < value) {
this.currentValue += STEP; this.currentValue += STEP;
} } else {
else {
this.currentValue -= STEP; this.currentValue -= STEP;
} }
this.drawCircle(this.currentValue); this.drawCircle(this.currentValue);
} } else {
else {
this.clearInterval(); this.clearInterval();
} }
}, 1000 / speed); }, 1000 / speed);
...@@ -137,15 +171,15 @@ VantComponent({ ...@@ -137,15 +171,15 @@ VantComponent({
clearInterval(this.interval); clearInterval(this.interval);
this.interval = null; this.interval = null;
} }
}
}, },
created() { },
const { value } = this.data; mounted() {
this.currentValue = value; this.currentValue = this.data.value;
this.drawCircle(value); this.setHoverColor().then(() => {
this.drawCircle(this.currentValue);
});
}, },
destroyed() { destroyed() {
this.ctx = null;
this.clearInterval(); this.clearInterval();
} },
}); });
<wxs src="../wxs/utils.wxs" module="utils" /> <wxs src="../wxs/utils.wxs" module="utils" />
<view class="van-circle"> <view class="van-circle">
<canvas class="van-circle__canvas" style="width: {{ utils.addUnit(size) }};height:{{ utils.addUnit(size) }}" canvas-id="van-circle"></canvas> <canvas class="van-circle__canvas" type="{{ type }}" style="width: {{ utils.addUnit(size) }};height:{{ utils.addUnit(size) }}" id="van-circle" canvas-id="van-circle"></canvas>
<view wx:if="{{ !text }}" class="van-circle__text"> <view wx:if="{{ !text }}" class="van-circle__text">
<slot></slot> <slot></slot>
</view> </view>
......
...@@ -7,18 +7,20 @@ VantComponent({ ...@@ -7,18 +7,20 @@ VantComponent({
}, },
props: { props: {
span: Number, span: Number,
offset: Number offset: Number,
}, },
data: { data: {
viewStyle: '' viewStyle: '',
}, },
methods: { methods: {
setGutter(gutter) { setGutter(gutter) {
const padding = `${gutter / 2}px`; const padding = `${gutter / 2}px`;
const viewStyle = gutter ? `padding-left: ${padding}; padding-right: ${padding};` : ''; const viewStyle = gutter
? `padding-left: ${padding}; padding-right: ${padding};`
: '';
if (viewStyle !== this.data.viewStyle) { if (viewStyle !== this.data.viewStyle) {
this.setData({ viewStyle }); this.setData({ viewStyle });
} }
} },
} },
}); });
/// <reference types="miniprogram-api-typings" />
export declare function setContentAnimate(
context: WechatMiniprogram.Component.TrivialInstance,
expanded: boolean,
mounted: boolean
): void;
import { canIUseAnimate } from '../common/version';
import { getRect } from '../common/utils';
function useAnimate(context, expanded, mounted, height) {
const selector = '.van-collapse-item__wrapper';
if (expanded) {
context.animate(
selector,
[
{ height: 0, ease: 'ease-in-out', offset: 0 },
{ height: `${height}px`, ease: 'ease-in-out', offset: 1 },
{ height: `auto`, ease: 'ease-in-out', offset: 1 },
],
mounted ? 300 : 0,
() => {
context.clearAnimation(selector);
}
);
return;
}
context.animate(
selector,
[
{ height: `${height}px`, ease: 'ease-in-out', offset: 0 },
{ height: 0, ease: 'ease-in-out', offset: 1 },
],
300,
() => {
context.clearAnimation(selector);
}
);
}
function useAnimation(context, expanded, mounted, height) {
const animation = wx.createAnimation({
duration: 0,
timingFunction: 'ease-in-out',
});
if (expanded) {
if (height === 0) {
animation.height('auto').top(1).step();
} else {
animation
.height(height)
.top(1)
.step({
duration: mounted ? 300 : 1,
})
.height('auto')
.step();
}
context.setData({
animation: animation.export(),
});
return;
}
animation.height(height).top(0).step({ duration: 1 }).height(0).step({
duration: 300,
});
context.setData({
animation: animation.export(),
});
}
export function setContentAnimate(context, expanded, mounted) {
getRect(context, '.van-collapse-item__content')
.then((rect) => rect.height)
.then((height) => {
canIUseAnimate()
? useAnimate(context, expanded, mounted, height)
: useAnimation(context, expanded, mounted, height);
});
}
import { VantComponent } from '../common/component'; import { VantComponent } from '../common/component';
const nextTick = () => new Promise(resolve => setTimeout(resolve, 20)); import { setContentAnimate } from './animate';
VantComponent({ VantComponent({
classes: ['title-class', 'content-class'], classes: ['title-class', 'content-class'],
relation: { relation: {
...@@ -17,33 +17,24 @@ VantComponent({ ...@@ -17,33 +17,24 @@ VantComponent({
clickable: Boolean, clickable: Boolean,
border: { border: {
type: Boolean, type: Boolean,
value: true value: true,
}, },
isLink: { isLink: {
type: Boolean, type: Boolean,
value: true value: true,
} },
}, },
data: { data: {
contentHeight: 0,
expanded: false, expanded: false,
transition: false
}, },
mounted() { mounted() {
this.updateExpanded() this.updateExpanded();
.then(nextTick) this.mounted = true;
.then(() => {
const data = { transition: true };
if (this.data.expanded) {
data.contentHeight = 'auto';
}
this.setData(data);
});
}, },
methods: { methods: {
updateExpanded() { updateExpanded() {
if (!this.parent) { if (!this.parent) {
return Promise.resolve(); return;
} }
const { value, accordion } = this.parent.data; const { value, accordion } = this.parent.data;
const { children = [] } = this.parent; const { children = [] } = this.parent;
...@@ -53,26 +44,10 @@ VantComponent({ ...@@ -53,26 +44,10 @@ VantComponent({
const expanded = accordion const expanded = accordion
? value === currentName ? value === currentName
: (value || []).some((name) => name === currentName); : (value || []).some((name) => name === currentName);
const stack = [];
if (expanded !== this.data.expanded) { if (expanded !== this.data.expanded) {
stack.push(this.updateStyle(expanded)); setContentAnimate(this, expanded, this.mounted);
}
stack.push(this.set({ index, expanded }));
return Promise.all(stack);
},
updateStyle(expanded) {
return this.getRect('.van-collapse-item__content')
.then((rect) => rect.height)
.then((height) => {
if (expanded) {
return this.set({
contentHeight: height ? `${height}px` : 'auto'
});
} }
return this.set({ contentHeight: `${height}px` }) this.setData({ index, expanded });
.then(nextTick)
.then(() => this.set({ contentHeight: 0 }));
});
}, },
onClick() { onClick() {
if (this.data.disabled) { if (this.data.disabled) {
...@@ -83,12 +58,5 @@ VantComponent({ ...@@ -83,12 +58,5 @@ VantComponent({
const currentName = name == null ? index : name; const currentName = name == null ? index : name;
this.parent.switch(currentName, !expanded); this.parent.switch(currentName, !expanded);
}, },
onTransitionEnd() { },
if (this.data.expanded) {
this.setData({
contentHeight: 'auto'
});
}
}
}
}); });
...@@ -31,9 +31,9 @@ ...@@ -31,9 +31,9 @@
/> />
</van-cell> </van-cell>
<view <view
class="{{ utils.bem('collapse-item__wrapper', { transition }) }}" class="{{ utils.bem('collapse-item__wrapper') }}"
style="height: {{ contentHeight }};" style="height: 0;"
bind:transitionend="onTransitionEnd" animation="{{ animation }}"
> >
<view <view
class="van-collapse-item__content content-class" class="van-collapse-item__content content-class"
......
@import '../common/index.wxss';.van-collapse-item__title .van-cell__right-icon{-webkit-transform:rotate(90deg);transform:rotate(90deg);transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;transition:-webkit-transform var(--collapse-item-transition-duration,.3s);transition:transform var(--collapse-item-transition-duration,.3s);transition:transform var(--collapse-item-transition-duration,.3s),-webkit-transform var(--collapse-item-transition-duration,.3s)}.van-collapse-item__title--expanded .van-cell__right-icon{-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.van-collapse-item__title--disabled .van-cell,.van-collapse-item__title--disabled .van-cell__right-icon{color:#c8c9cc!important;color:var(--collapse-item-title-disabled-color,#c8c9cc)!important}.van-collapse-item__title--disabled .van-cell--hover{background-color:#fff!important;background-color:var(--white,#fff)!important}.van-collapse-item__wrapper{overflow:hidden}.van-collapse-item__wrapper--transition{transition:height .3s ease-in-out}.van-collapse-item__content{padding:15px;padding:var(--collapse-item-content-padding,15px);color:#969799;color:var(--collapse-item-content-text-color,#969799);font-size:13px;font-size:var(--collapse-item-content-font-size,13px);line-height:1.5;line-height:var(--collapse-item-content-line-height,1.5);background-color:#fff;background-color:var(--collapse-item-content-background-color,#fff)} @import '../common/index.wxss';.van-collapse-item__title .van-cell__right-icon{-webkit-transform:rotate(90deg);transform:rotate(90deg);transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;transition:-webkit-transform var(--collapse-item-transition-duration,.3s);transition:transform var(--collapse-item-transition-duration,.3s);transition:transform var(--collapse-item-transition-duration,.3s),-webkit-transform var(--collapse-item-transition-duration,.3s)}.van-collapse-item__title--expanded .van-cell__right-icon{-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.van-collapse-item__title--disabled .van-cell,.van-collapse-item__title--disabled .van-cell__right-icon{color:#c8c9cc!important;color:var(--collapse-item-title-disabled-color,#c8c9cc)!important}.van-collapse-item__title--disabled .van-cell--hover{background-color:#fff!important;background-color:var(--white,#fff)!important}.van-collapse-item__wrapper{overflow:hidden}.van-collapse-item__content{padding:15px;padding:var(--collapse-item-content-padding,15px);color:#969799;color:var(--collapse-item-content-text-color,#969799);font-size:13px;font-size:var(--collapse-item-content-font-size,13px);line-height:1.5;line-height:var(--collapse-item-content-line-height,1.5);background-color:#fff;background-color:var(--collapse-item-content-background-color,#fff)}
\ No newline at end of file \ No newline at end of file
...@@ -8,16 +8,16 @@ VantComponent({ ...@@ -8,16 +8,16 @@ VantComponent({
props: { props: {
value: { value: {
type: null, type: null,
observer: 'updateExpanded' observer: 'updateExpanded',
}, },
accordion: { accordion: {
type: Boolean, type: Boolean,
observer: 'updateExpanded' observer: 'updateExpanded',
}, },
border: { border: {
type: Boolean, type: Boolean,
value: true value: true,
} },
}, },
methods: { methods: {
updateExpanded() { updateExpanded() {
...@@ -27,16 +27,21 @@ VantComponent({ ...@@ -27,16 +27,21 @@ VantComponent({
}, },
switch(name, expanded) { switch(name, expanded) {
const { accordion, value } = this.data; const { accordion, value } = this.data;
const changeItem = name;
if (!accordion) { if (!accordion) {
name = expanded name = expanded
? (value || []).concat(name) ? (value || []).concat(name)
: (value || []).filter((activeName) => activeName !== name); : (value || []).filter((activeName) => activeName !== name);
} } else {
else {
name = expanded ? name : ''; name = expanded ? name : '';
} }
if (expanded) {
this.$emit('open', changeItem);
} else {
this.$emit('close', changeItem);
}
this.$emit('change', name); this.$emit('change', name);
this.$emit('input', name); this.$emit('input', name);
} },
} },
}); });
...@@ -2,24 +2,29 @@ import { basic } from '../mixins/basic'; ...@@ -2,24 +2,29 @@ import { basic } from '../mixins/basic';
const relationFunctions = { const relationFunctions = {
ancestor: { ancestor: {
linked(parent) { linked(parent) {
// @ts-ignore
this.parent = parent; this.parent = parent;
}, },
unlinked() { unlinked() {
// @ts-ignore
this.parent = null; this.parent = null;
}, },
}, },
descendant: { descendant: {
linked(child) { linked(child) {
// @ts-ignore
this.children = this.children || []; this.children = this.children || [];
// @ts-ignore
this.children.push(child); this.children.push(child);
}, },
unlinked(child) { unlinked(child) {
this.children = (this.children || []).filter(it => it !== child); // @ts-ignore
this.children = (this.children || []).filter((it) => it !== child);
}, },
}, },
}; };
function mapKeys(source, target, map) { function mapKeys(source, target, map) {
Object.keys(map).forEach(key => { Object.keys(map).forEach((key) => {
if (source[key]) { if (source[key]) {
target[map[key]] = source[key]; target[map[key]] = source[key];
} }
...@@ -52,7 +57,7 @@ function makeRelation(options, vantOptions, relation) { ...@@ -52,7 +57,7 @@ function makeRelation(options, vantOptions, relation) {
relationFunctions[type].unlinked.bind(this)(node); relationFunctions[type].unlinked.bind(this)(node);
unlinked && unlinked.bind(this)(node); unlinked && unlinked.bind(this)(node);
}, },
} },
}); });
} }
function VantComponent(vantOptions = {}) { function VantComponent(vantOptions = {}) {
...@@ -67,7 +72,7 @@ function VantComponent(vantOptions = {}) { ...@@ -67,7 +72,7 @@ function VantComponent(vantOptions = {}) {
mounted: 'ready', mounted: 'ready',
relations: 'relations', relations: 'relations',
destroyed: 'detached', destroyed: 'detached',
classes: 'externalClasses' classes: 'externalClasses',
}); });
const { relation } = vantOptions; const { relation } = vantOptions;
if (relation) { if (relation) {
...@@ -83,10 +88,18 @@ function VantComponent(vantOptions = {}) { ...@@ -83,10 +88,18 @@ function VantComponent(vantOptions = {}) {
if (vantOptions.field) { if (vantOptions.field) {
options.behaviors.push('wx://form-field'); options.behaviors.push('wx://form-field');
} }
if (options.properties) {
Object.keys(options.properties).forEach((name) => {
if (Array.isArray(options.properties[name])) {
// miniprogram do not allow multi type
options.properties[name] = null;
}
});
}
// add default options // add default options
options.options = { options.options = {
multipleSlots: true, multipleSlots: true,
addGlobalClass: true addGlobalClass: true,
}; };
Component(options); Component(options);
} }
......
.van-ellipsis{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.van-multi-ellipsis--l2{-webkit-line-clamp:2}.van-multi-ellipsis--l2,.van-multi-ellipsis--l3{display:-webkit-box;overflow:hidden;text-overflow:ellipsis;-webkit-box-orient:vertical}.van-multi-ellipsis--l3{-webkit-line-clamp:3}.van-clearfix:after{display:table;clear:both;content:""}.van-hairline,.van-hairline--bottom,.van-hairline--left,.van-hairline--right,.van-hairline--surround,.van-hairline--top,.van-hairline--top-bottom{position:relative}.van-hairline--bottom:after,.van-hairline--left:after,.van-hairline--right:after,.van-hairline--surround:after,.van-hairline--top-bottom:after,.van-hairline--top:after,.van-hairline:after{position:absolute;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;content:" ";pointer-events:none;top:-50%;right:-50%;bottom:-50%;left:-50%;border:0 solid #eee;-webkit-transform:scale(.5);transform:scale(.5)}.van-hairline--top:after{border-top-width:1px}.van-hairline--left:after{border-left-width:1px}.van-hairline--right:after{border-right-width:1px}.van-hairline--bottom:after{border-bottom-width:1px}.van-hairline--top-bottom:after{border-width:1px 0}.van-hairline--surround:after{border-width:1px} .van-ellipsis{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.van-multi-ellipsis--l2{-webkit-line-clamp:2}.van-multi-ellipsis--l2,.van-multi-ellipsis--l3{display:-webkit-box;overflow:hidden;text-overflow:ellipsis;-webkit-box-orient:vertical}.van-multi-ellipsis--l3{-webkit-line-clamp:3}.van-clearfix:after{display:table;clear:both;content:""}.van-hairline,.van-hairline--bottom,.van-hairline--left,.van-hairline--right,.van-hairline--surround,.van-hairline--top,.van-hairline--top-bottom{position:relative}.van-hairline--bottom:after,.van-hairline--left:after,.van-hairline--right:after,.van-hairline--surround:after,.van-hairline--top-bottom:after,.van-hairline--top:after,.van-hairline:after{position:absolute;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;content:" ";pointer-events:none;top:-50%;right:-50%;bottom:-50%;left:-50%;border:0 solid #ebedf0;-webkit-transform:scale(.5);transform:scale(.5)}.van-hairline--top:after{border-top-width:1px}.van-hairline--left:after{border-left-width:1px}.van-hairline--right:after{border-right-width:1px}.van-hairline--bottom:after{border-bottom-width:1px}.van-hairline--top-bottom:after{border-width:1px 0}.van-hairline--surround:after{border-width:1px}
\ No newline at end of file \ No newline at end of file
.van-hairline,.van-hairline--bottom,.van-hairline--left,.van-hairline--right,.van-hairline--surround,.van-hairline--top,.van-hairline--top-bottom{position:relative}.van-hairline--bottom:after,.van-hairline--left:after,.van-hairline--right:after,.van-hairline--surround:after,.van-hairline--top-bottom:after,.van-hairline--top:after,.van-hairline:after{position:absolute;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;content:" ";pointer-events:none;top:-50%;right:-50%;bottom:-50%;left:-50%;border:0 solid #eee;-webkit-transform:scale(.5);transform:scale(.5)}.van-hairline--top:after{border-top-width:1px}.van-hairline--left:after{border-left-width:1px}.van-hairline--right:after{border-right-width:1px}.van-hairline--bottom:after{border-bottom-width:1px}.van-hairline--top-bottom:after{border-width:1px 0}.van-hairline--surround:after{border-width:1px} .van-hairline,.van-hairline--bottom,.van-hairline--left,.van-hairline--right,.van-hairline--surround,.van-hairline--top,.van-hairline--top-bottom{position:relative}.van-hairline--bottom:after,.van-hairline--left:after,.van-hairline--right:after,.van-hairline--surround:after,.van-hairline--top-bottom:after,.van-hairline--top:after,.van-hairline:after{position:absolute;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;content:" ";pointer-events:none;top:-50%;right:-50%;bottom:-50%;left:-50%;border:0 solid #ebedf0;-webkit-transform:scale(.5);transform:scale(.5)}.van-hairline--top:after{border-top-width:1px}.van-hairline--left:after{border-left-width:1px}.van-hairline--right:after{border-right-width:1px}.van-hairline--bottom:after{border-bottom-width:1px}.van-hairline--top-bottom:after{border-width:1px 0}.van-hairline--surround:after{border-width:1px}
\ No newline at end of file \ No newline at end of file
/// <reference types="miniprogram-api-typings" /> /// <reference types="miniprogram-api-typings" />
export declare function isDef(value: any): boolean;
export declare function isObj(x: any): boolean;
export declare function isNumber(value: any): boolean;
export declare function range(num: number, min: number, max: number): number; export declare function range(num: number, min: number, max: number): number;
export declare function nextTick(fn: Function): void; export declare function nextTick(cb: (...args: any[]) => void): void;
export declare function getSystemInfoSync(): WechatMiniprogram.GetSystemInfoSuccessCallbackResult; export declare function getSystemInfoSync(): WechatMiniprogram.GetSystemInfoSyncResult;
export declare function addUnit(value?: string | number): string | undefined; export declare function addUnit(value?: string | number): string | undefined;
export declare function requestAnimationFrame(
cb: () => void
): number | WechatMiniprogram.NodesRef;
export declare function pickExclude(obj: unknown, keys: string[]): {};
export declare function getRect(
context: WechatMiniprogram.Component.TrivialInstance,
selector: string
): Promise<WechatMiniprogram.BoundingClientRectCallbackResult>;
export declare function getAllRect(
context: WechatMiniprogram.Component.TrivialInstance,
selector: string
): Promise<WechatMiniprogram.BoundingClientRectCallbackResult[]>;
export declare function groupSetData(
context: WechatMiniprogram.Component.TrivialInstance,
cb: () => void
): void;
export declare function toPromise(
promiseLike: Promise<unknown> | unknown
): Promise<unknown>;
export function isDef(value) { import { isDef, isNumber, isPlainObject, isPromise } from './validator';
return value !== undefined && value !== null; import { canIUseGroupSetData, canIUseNextTick } from './version';
}
export function isObj(x) {
const type = typeof x;
return x !== null && (type === 'object' || type === 'function');
}
export function isNumber(value) {
return /^\d+(\.\d+)?$/.test(value);
}
export function range(num, min, max) { export function range(num, min, max) {
return Math.min(Math.max(num, min), max); return Math.min(Math.max(num, min), max);
} }
export function nextTick(fn) { export function nextTick(cb) {
if (canIUseNextTick()) {
wx.nextTick(cb);
} else {
setTimeout(() => { setTimeout(() => {
fn(); cb();
}, 1000 / 30); }, 1000 / 30);
}
} }
let systemInfo = null; let systemInfo;
export function getSystemInfoSync() { export function getSystemInfoSync() {
if (systemInfo == null) { if (systemInfo == null) {
systemInfo = wx.getSystemInfoSync(); systemInfo = wx.getSystemInfoSync();
...@@ -30,3 +26,60 @@ export function addUnit(value) { ...@@ -30,3 +26,60 @@ export function addUnit(value) {
value = String(value); value = String(value);
return isNumber(value) ? `${value}px` : value; return isNumber(value) ? `${value}px` : value;
} }
export function requestAnimationFrame(cb) {
const systemInfo = getSystemInfoSync();
if (systemInfo.platform === 'devtools') {
return setTimeout(() => {
cb();
}, 1000 / 30);
}
return wx
.createSelectorQuery()
.selectViewport()
.boundingClientRect()
.exec(() => {
cb();
});
}
export function pickExclude(obj, keys) {
if (!isPlainObject(obj)) {
return {};
}
return Object.keys(obj).reduce((prev, key) => {
if (!keys.includes(key)) {
prev[key] = obj[key];
}
return prev;
}, {});
}
export function getRect(context, selector) {
return new Promise((resolve) => {
wx.createSelectorQuery()
.in(context)
.select(selector)
.boundingClientRect()
.exec((rect = []) => resolve(rect[0]));
});
}
export function getAllRect(context, selector) {
return new Promise((resolve) => {
wx.createSelectorQuery()
.in(context)
.selectAll(selector)
.boundingClientRect()
.exec((rect = []) => resolve(rect[0]));
});
}
export function groupSetData(context, cb) {
if (canIUseGroupSetData()) {
context.groupSetData(cb);
} else {
cb();
}
}
export function toPromise(promiseLike) {
if (isPromise(promiseLike)) {
return promiseLike;
}
return Promise.resolve(promiseLike);
}
export declare function isFunction(val: unknown): val is Function;
export declare function isPlainObject(
val: unknown
): val is Record<string, unknown>;
export declare function isPromise<T = unknown>(val: unknown): val is Promise<T>;
export declare function isDef(value: unknown): boolean;
export declare function isObj(x: unknown): x is Record<string, unknown>;
export declare function isNumber(value: string): boolean;
export declare function isBoolean(value: unknown): value is boolean;
export declare function isImageUrl(url: string): boolean;
export declare function isVideoUrl(url: string): boolean;
export function isFunction(val) {
return typeof val === 'function';
}
export function isPlainObject(val) {
return val !== null && typeof val === 'object' && !Array.isArray(val);
}
export function isPromise(val) {
return isPlainObject(val) && isFunction(val.then) && isFunction(val.catch);
}
export function isDef(value) {
return value !== undefined && value !== null;
}
export function isObj(x) {
const type = typeof x;
return x !== null && (type === 'object' || type === 'function');
}
export function isNumber(value) {
return /^\d+(\.\d+)?$/.test(value);
}
export function isBoolean(value) {
return typeof value === 'boolean';
}
const IMAGE_REGEXP = /\.(jpeg|jpg|gif|png|svg|webp|jfif|bmp|dpg)/i;
const VIDEO_REGEXP = /\.(mp4|mpg|mpeg|dat|asf|avi|rm|rmvb|mov|wmv|flv|mkv)/i;
export function isImageUrl(url) {
return IMAGE_REGEXP.test(url);
}
export function isVideoUrl(url) {
return VIDEO_REGEXP.test(url);
}
export declare function canIUseModel(): boolean;
export declare function canIUseFormFieldButton(): boolean;
export declare function canIUseAnimate(): boolean;
export declare function canIUseGroupSetData(): boolean;
export declare function canIUseNextTick(): boolean;
import { getSystemInfoSync } from './utils';
function compareVersion(v1, v2) {
v1 = v1.split('.');
v2 = v2.split('.');
const len = Math.max(v1.length, v2.length);
while (v1.length < len) {
v1.push('0');
}
while (v2.length < len) {
v2.push('0');
}
for (let i = 0; i < len; i++) {
const num1 = parseInt(v1[i], 10);
const num2 = parseInt(v2[i], 10);
if (num1 > num2) {
return 1;
}
if (num1 < num2) {
return -1;
}
}
return 0;
}
export function canIUseModel() {
const system = getSystemInfoSync();
return compareVersion(system.SDKVersion, '2.9.3') >= 0;
}
export function canIUseFormFieldButton() {
const system = getSystemInfoSync();
return compareVersion(system.SDKVersion, '2.10.3') >= 0;
}
export function canIUseAnimate() {
const system = getSystemInfoSync();
return compareVersion(system.SDKVersion, '2.9.0') >= 0;
}
export function canIUseGroupSetData() {
const system = getSystemInfoSync();
return compareVersion(system.SDKVersion, '2.4.0') >= 0;
}
export function canIUseNextTick() {
return wx.canIUse('nextTick');
}
...@@ -9,20 +9,20 @@ VantComponent({ ...@@ -9,20 +9,20 @@ VantComponent({
millisecond: Boolean, millisecond: Boolean,
time: { time: {
type: Number, type: Number,
observer: 'reset' observer: 'reset',
}, },
format: { format: {
type: String, type: String,
value: 'HH:mm:ss' value: 'HH:mm:ss',
}, },
autoStart: { autoStart: {
type: Boolean, type: Boolean,
value: true value: true,
} },
}, },
data: { data: {
timeData: parseTimeData(0), timeData: parseTimeData(0),
formattedTime: '0' formattedTime: '0',
}, },
destroyed() { destroyed() {
clearTimeout(this.tid); clearTimeout(this.tid);
...@@ -55,8 +55,7 @@ VantComponent({ ...@@ -55,8 +55,7 @@ VantComponent({
tick() { tick() {
if (this.data.millisecond) { if (this.data.millisecond) {
this.microTick(); this.microTick();
} } else {
else {
this.macroTick(); this.macroTick();
} }
}, },
...@@ -89,12 +88,12 @@ VantComponent({ ...@@ -89,12 +88,12 @@ VantComponent({
this.$emit('change', timeData); this.$emit('change', timeData);
} }
this.setData({ this.setData({
formattedTime: parseFormat(this.data.format, timeData) formattedTime: parseFormat(this.data.format, timeData),
}); });
if (remain === 0) { if (remain === 0) {
this.pause(); this.pause();
this.$emit('finish'); this.$emit('finish');
} }
} },
} },
}); });
...@@ -20,7 +20,7 @@ export function parseTimeData(time) { ...@@ -20,7 +20,7 @@ export function parseTimeData(time) {
hours, hours,
minutes, minutes,
seconds, seconds,
milliseconds milliseconds,
}; };
} }
export function parseFormat(format, timeData) { export function parseFormat(format, timeData) {
...@@ -28,26 +28,22 @@ export function parseFormat(format, timeData) { ...@@ -28,26 +28,22 @@ export function parseFormat(format, timeData) {
let { hours, minutes, seconds, milliseconds } = timeData; let { hours, minutes, seconds, milliseconds } = timeData;
if (format.indexOf('DD') === -1) { if (format.indexOf('DD') === -1) {
hours += days * 24; hours += days * 24;
} } else {
else {
format = format.replace('DD', padZero(days)); format = format.replace('DD', padZero(days));
} }
if (format.indexOf('HH') === -1) { if (format.indexOf('HH') === -1) {
minutes += hours * 60; minutes += hours * 60;
} } else {
else {
format = format.replace('HH', padZero(hours)); format = format.replace('HH', padZero(hours));
} }
if (format.indexOf('mm') === -1) { if (format.indexOf('mm') === -1) {
seconds += minutes * 60; seconds += minutes * 60;
} } else {
else {
format = format.replace('mm', padZero(minutes)); format = format.replace('mm', padZero(minutes));
} }
if (format.indexOf('ss') === -1) { if (format.indexOf('ss') === -1) {
milliseconds += seconds * 1000; milliseconds += seconds * 1000;
} } else {
else {
format = format.replace('ss', padZero(seconds)); format = format.replace('ss', padZero(seconds));
} }
return format.replace('SSS', padZero(milliseconds, 3)); return format.replace('SSS', padZero(milliseconds, 3));
......
import { VantComponent } from '../common/component'; import { VantComponent } from '../common/component';
import { isDef } from '../common/utils'; import { isDef } from '../common/validator';
import { pickerProps } from '../picker/shared'; import { pickerProps } from '../picker/shared';
const currentYear = new Date().getFullYear(); const currentYear = new Date().getFullYear();
function isValidDate(date) { function isValidDate(date) {
...@@ -20,8 +20,9 @@ function times(n, iteratee) { ...@@ -20,8 +20,9 @@ function times(n, iteratee) {
return result; return result;
} }
function getTrueValue(formattedValue) { function getTrueValue(formattedValue) {
if (!formattedValue) if (formattedValue === undefined) {
return; formattedValue = '1';
}
while (isNaN(parseInt(formattedValue, 10))) { while (isNaN(parseInt(formattedValue, 10))) {
formattedValue = formattedValue.slice(1); formattedValue = formattedValue.slice(1);
} }
...@@ -30,62 +31,73 @@ function getTrueValue(formattedValue) { ...@@ -30,62 +31,73 @@ function getTrueValue(formattedValue) {
function getMonthEndDay(year, month) { function getMonthEndDay(year, month) {
return 32 - new Date(year, month - 1, 32).getDate(); return 32 - new Date(year, month - 1, 32).getDate();
} }
const defaultFormatter = (_, value) => value; const defaultFormatter = (type, value) => value;
VantComponent({ VantComponent({
classes: ['active-class', 'toolbar-class', 'column-class'], classes: ['active-class', 'toolbar-class', 'column-class'],
props: Object.assign(Object.assign({}, pickerProps), { value: { props: Object.assign(Object.assign({}, pickerProps), {
value: {
type: null, type: null,
observer: 'updateValue' observer: 'updateValue',
}, filter: null, type: { },
filter: null,
type: {
type: String, type: String,
value: 'datetime', value: 'datetime',
observer: 'updateValue' observer: 'updateValue',
}, showToolbar: { },
showToolbar: {
type: Boolean, type: Boolean,
value: true value: true,
}, formatter: { },
formatter: {
type: null, type: null,
value: defaultFormatter value: defaultFormatter,
}, minDate: { },
minDate: {
type: Number, type: Number,
value: new Date(currentYear - 10, 0, 1).getTime(), value: new Date(currentYear - 10, 0, 1).getTime(),
observer: 'updateValue' observer: 'updateValue',
}, maxDate: { },
maxDate: {
type: Number, type: Number,
value: new Date(currentYear + 10, 11, 31).getTime(), value: new Date(currentYear + 10, 11, 31).getTime(),
observer: 'updateValue' observer: 'updateValue',
}, minHour: { },
minHour: {
type: Number, type: Number,
value: 0, value: 0,
observer: 'updateValue' observer: 'updateValue',
}, maxHour: { },
maxHour: {
type: Number, type: Number,
value: 23, value: 23,
observer: 'updateValue' observer: 'updateValue',
}, minMinute: { },
minMinute: {
type: Number, type: Number,
value: 0, value: 0,
observer: 'updateValue' observer: 'updateValue',
}, maxMinute: { },
maxMinute: {
type: Number, type: Number,
value: 59, value: 59,
observer: 'updateValue' observer: 'updateValue',
} }), },
}),
data: { data: {
innerValue: Date.now(), innerValue: Date.now(),
columns: [] columns: [],
}, },
methods: { methods: {
updateValue() { updateValue() {
const { data } = this; const { data } = this;
const val = this.correctValue(this.data.value); const val = this.correctValue(data.value);
const isEqual = val === data.innerValue; const isEqual = val === data.innerValue;
if (!isEqual) { if (!isEqual) {
this.updateColumnValue(val).then(() => { this.updateColumnValue(val).then(() => {
this.$emit('input', val); this.$emit('input', val);
}); });
} } else {
else {
this.updateColumns(); this.updateColumns();
} }
}, },
...@@ -94,21 +106,22 @@ VantComponent({ ...@@ -94,21 +106,22 @@ VantComponent({
this.picker = this.selectComponent('.van-datetime-picker'); this.picker = this.selectComponent('.van-datetime-picker');
const { picker } = this; const { picker } = this;
const { setColumnValues } = picker; const { setColumnValues } = picker;
picker.setColumnValues = (...args) => setColumnValues.apply(picker, [...args, false]); picker.setColumnValues = (...args) =>
setColumnValues.apply(picker, [...args, false]);
} }
return this.picker; return this.picker;
}, },
updateColumns() { updateColumns() {
const { formatter = defaultFormatter } = this.data; const { formatter = defaultFormatter } = this.data;
const results = this.getOriginColumns().map(column => ({ const results = this.getOriginColumns().map((column) => ({
values: column.values.map(value => formatter(column.type, value)) values: column.values.map((value) => formatter(column.type, value)),
})); }));
return this.set({ columns: results }); return this.set({ columns: results });
}, },
getOriginColumns() { getOriginColumns() {
const { filter } = this.data; const { filter } = this.data;
const results = this.getRanges().map(({ type, range }) => { const results = this.getRanges().map(({ type, range }) => {
let values = times(range[1] - range[0] + 1, index => { let values = times(range[1] - range[0] + 1, (index) => {
let value = range[0] + index; let value = range[0] + index;
value = type === 'year' ? `${value}` : padZero(value); value = type === 'year' ? `${value}` : padZero(value);
return value; return value;
...@@ -126,42 +139,52 @@ VantComponent({ ...@@ -126,42 +139,52 @@ VantComponent({
return [ return [
{ {
type: 'hour', type: 'hour',
range: [data.minHour, data.maxHour] range: [data.minHour, data.maxHour],
}, },
{ {
type: 'minute', type: 'minute',
range: [data.minMinute, data.maxMinute] range: [data.minMinute, data.maxMinute],
} },
]; ];
} }
const { maxYear, maxDate, maxMonth, maxHour, maxMinute } = this.getBoundary('max', data.innerValue); const {
const { minYear, minDate, minMonth, minHour, minMinute } = this.getBoundary('min', data.innerValue); maxYear,
maxDate,
maxMonth,
maxHour,
maxMinute,
} = this.getBoundary('max', data.innerValue);
const {
minYear,
minDate,
minMonth,
minHour,
minMinute,
} = this.getBoundary('min', data.innerValue);
const result = [ const result = [
{ {
type: 'year', type: 'year',
range: [minYear, maxYear] range: [minYear, maxYear],
}, },
{ {
type: 'month', type: 'month',
range: [minMonth, maxMonth] range: [minMonth, maxMonth],
}, },
{ {
type: 'day', type: 'day',
range: [minDate, maxDate] range: [minDate, maxDate],
}, },
{ {
type: 'hour', type: 'hour',
range: [minHour, maxHour] range: [minHour, maxHour],
}, },
{ {
type: 'minute', type: 'minute',
range: [minMinute, maxMinute] range: [minMinute, maxMinute],
} },
]; ];
if (data.type === 'date') if (data.type === 'date') result.splice(3, 2);
result.splice(3, 2); if (data.type === 'year-month') result.splice(2, 3);
if (data.type === 'year-month')
result.splice(2, 3);
return result; return result;
}, },
correctValue(value) { correctValue(value) {
...@@ -170,8 +193,7 @@ VantComponent({ ...@@ -170,8 +193,7 @@ VantComponent({
const isDateType = data.type !== 'time'; const isDateType = data.type !== 'time';
if (isDateType && !isValidDate(value)) { if (isDateType && !isValidDate(value)) {
value = data.minDate; value = data.minDate;
} } else if (!isDateType && !value) {
else if (!isDateType && !value) {
const { minHour } = data; const { minHour } = data;
value = `${padZero(minHour)}:00`; value = `${padZero(minHour)}:00`;
} }
...@@ -218,7 +240,7 @@ VantComponent({ ...@@ -218,7 +240,7 @@ VantComponent({
[`${type}Month`]: month, [`${type}Month`]: month,
[`${type}Date`]: date, [`${type}Date`]: date,
[`${type}Hour`]: hour, [`${type}Hour`]: hour,
[`${type}Minute`]: minute [`${type}Minute`]: minute,
}; };
}, },
onCancel() { onCancel() {
...@@ -231,12 +253,16 @@ VantComponent({ ...@@ -231,12 +253,16 @@ VantComponent({
const { data } = this; const { data } = this;
let value; let value;
const picker = this.getPicker(); const picker = this.getPicker();
const originColumns = this.getOriginColumns();
if (data.type === 'time') { if (data.type === 'time') {
const indexes = picker.getIndexes(); const indexes = picker.getIndexes();
value = `${+data.columns[0].values[indexes[0]]}:${+data.columns[1].values[indexes[1]]}`; value = `${+originColumns[0].values[indexes[0]]}:${+originColumns[1]
} .values[indexes[1]]}`;
else { } else {
const values = picker.getValues(); const indexes = picker.getIndexes();
const values = indexes.map(
(value, index) => originColumns[index].values[value]
);
const year = getTrueValue(values[0]); const year = getTrueValue(values[0]);
const month = getTrueValue(values[1]); const month = getTrueValue(values[1]);
const maxDate = getMonthEndDay(year, month); const maxDate = getMonthEndDay(year, month);
...@@ -261,37 +287,38 @@ VantComponent({ ...@@ -261,37 +287,38 @@ VantComponent({
}, },
updateColumnValue(value) { updateColumnValue(value) {
let values = []; let values = [];
const { type, formatter = defaultFormatter } = this.data; const { type } = this.data;
const formatter = this.data.formatter || defaultFormatter;
const picker = this.getPicker(); const picker = this.getPicker();
if (type === 'time') { if (type === 'time') {
const pair = value.split(':'); const pair = value.split(':');
values = [ values = [formatter('hour', pair[0]), formatter('minute', pair[1])];
formatter('hour', pair[0]), } else {
formatter('minute', pair[1])
];
}
else {
const date = new Date(value); const date = new Date(value);
values = [ values = [
formatter('year', `${date.getFullYear()}`), formatter('year', `${date.getFullYear()}`),
formatter('month', padZero(date.getMonth() + 1)) formatter('month', padZero(date.getMonth() + 1)),
]; ];
if (type === 'date') { if (type === 'date') {
values.push(formatter('day', padZero(date.getDate()))); values.push(formatter('day', padZero(date.getDate())));
} }
if (type === 'datetime') { if (type === 'datetime') {
values.push(formatter('day', padZero(date.getDate())), formatter('hour', padZero(date.getHours())), formatter('minute', padZero(date.getMinutes()))); values.push(
formatter('day', padZero(date.getDate())),
formatter('hour', padZero(date.getHours())),
formatter('minute', padZero(date.getMinutes()))
);
} }
} }
return this.set({ innerValue: value }) return this.set({ innerValue: value })
.then(() => this.updateColumns()) .then(() => this.updateColumns())
.then(() => picker.setValues(values)); .then(() => picker.setValues(values));
} },
}, },
created() { created() {
const innerValue = this.correctValue(this.data.value); const innerValue = this.correctValue(this.data.value);
this.updateColumnValue(innerValue).then(() => { this.updateColumnValue(innerValue).then(() => {
this.$emit('input', innerValue); this.$emit('input', innerValue);
}); });
} },
}); });
...@@ -3,9 +3,11 @@ import { Weapp } from './weapp'; ...@@ -3,9 +3,11 @@ import { Weapp } from './weapp';
declare type RecordToAny<T> = { declare type RecordToAny<T> = {
[K in keyof T]: any; [K in keyof T]: any;
}; };
export declare type CombinedComponentInstance<Data, Props, Methods> = Methods & WechatMiniprogram.Component.TrivialInstance & Weapp.FormField & { export declare type CombinedComponentInstance<Data, Props, Methods> = Methods &
WechatMiniprogram.Component.TrivialInstance &
Weapp.FormField & {
data: Data & RecordToAny<Props>; data: Data & RecordToAny<Props>;
}; };
export interface VantComponentOptions<Data, Props, Methods, Instance> { export interface VantComponentOptions<Data, Props, Methods, Instance> {
data?: Data; data?: Data;
field?: boolean; field?: boolean;
......
...@@ -6,61 +6,6 @@ export declare namespace Weapp { ...@@ -6,61 +6,6 @@ export declare namespace Weapp {
value: any; value: any;
}; };
} }
interface Target {
id: string;
tagName: string;
dataset: {
[key: string]: any;
};
}
export interface Event {
/**
* 代表事件的类型。
*/
type: string;
/**
* 页面打开到触发事件所经过的毫秒数。
*/
timeStamp: number;
/**
* 触发事件的源组件。
*/
target: Target;
/**
* 事件绑定的当前组件。
*/
currentTarget: Target;
/**
* 额外的信息
*/
detail: any;
}
interface Touch {
/**
* 触摸点的标识符
*/
identifier: number;
/**
* 距离文档左上角的距离,文档的左上角为原点 ,横向为X轴,纵向为Y轴
*/
pageX: number;
/**
* 距离文档左上角的距离,文档的左上角为原点 ,横向为X轴,纵向为Y轴
*/
pageY: number;
/**
* 距离页面可显示区域(屏幕除去导航条)左上角距离,横向为X轴,纵向为Y轴
*/
clientX: number;
/**
* 距离页面可显示区域(屏幕除去导航条)左上角距离,横向为X轴,纵向为Y轴
*/
clientY: number;
}
export interface TouchEvent extends Event {
touches: Array<Touch>;
changedTouches: Array<Touch>;
}
/** /**
* relation定义,miniprogram-api-typings缺少this定义 * relation定义,miniprogram-api-typings缺少this定义
*/ */
...@@ -68,18 +13,32 @@ export declare namespace Weapp { ...@@ -68,18 +13,32 @@ export declare namespace Weapp {
/** 目标组件的相对关系 */ /** 目标组件的相对关系 */
type: 'parent' | 'child' | 'ancestor' | 'descendant'; type: 'parent' | 'child' | 'ancestor' | 'descendant';
/** 关系生命周期函数,当关系被建立在页面节点树中时触发,触发时机在组件attached生命周期之后 */ /** 关系生命周期函数,当关系被建立在页面节点树中时触发,触发时机在组件attached生命周期之后 */
linked?(this: Instance, target: WechatMiniprogram.Component.TrivialInstance): void; linked?(
this: Instance,
target: WechatMiniprogram.Component.TrivialInstance
): void;
/** 关系生命周期函数,当关系在页面节点树中发生改变时触发,触发时机在组件moved生命周期之后 */ /** 关系生命周期函数,当关系在页面节点树中发生改变时触发,触发时机在组件moved生命周期之后 */
linkChanged?(this: Instance, target: WechatMiniprogram.Component.TrivialInstance): void; linkChanged?(
this: Instance,
target: WechatMiniprogram.Component.TrivialInstance
): void;
/** 关系生命周期函数,当关系脱离页面节点树时触发,触发时机在组件detached生命周期之后 */ /** 关系生命周期函数,当关系脱离页面节点树时触发,触发时机在组件detached生命周期之后 */
unlinked?(this: Instance, target: WechatMiniprogram.Component.TrivialInstance): void; unlinked?(
this: Instance,
target: WechatMiniprogram.Component.TrivialInstance
): void;
/** 如果这一项被设置,则它表示关联的目标节点所应具有的behavior,所有拥有这一behavior的组件节点都会被关联 */ /** 如果这一项被设置,则它表示关联的目标节点所应具有的behavior,所有拥有这一behavior的组件节点都会被关联 */
target?: string; target?: string;
} }
/** /**
* obverser定义,miniprogram-api-typings缺少this定义 * obverser定义,miniprogram-api-typings缺少this定义
*/ */
type Observer<Instance, T> = (this: Instance, newVal: T, oldVal: T, changedPath: Array<string | number>) => void; type Observer<Instance, T> = (
this: Instance,
newVal: T,
oldVal: T,
changedPath: Array<string | number>
) => void;
/** /**
* methods定义,miniprogram-api-typings缺少this定义 * methods定义,miniprogram-api-typings缺少this定义
*/ */
...@@ -89,15 +48,27 @@ export declare namespace Weapp { ...@@ -89,15 +48,27 @@ export declare namespace Weapp {
export interface ComputedOption<Instance> { export interface ComputedOption<Instance> {
[name: string]: (this: Instance) => any; [name: string]: (this: Instance) => any;
} }
type PropertyType = StringConstructor | NumberConstructor | BooleanConstructor | ArrayConstructor | ObjectConstructor | FunctionConstructor | null; type PropertyType =
| StringConstructor
| NumberConstructor
| BooleanConstructor
| ArrayConstructor
| ObjectConstructor
| FunctionConstructor
| null;
export interface PropertyOption { export interface PropertyOption {
[name: string]: PropertyType | PropertyType[] | { [name: string]:
| PropertyType
| PropertyType[]
| {
/** 属性类型 */ /** 属性类型 */
type: PropertyType | PropertyType[]; type: PropertyType | PropertyType[];
/** 属性初始值 */ /** 属性初始值 */
value?: any; value?: any;
/** 属性值被更改时的响应函数 */ /** 属性值被更改时的响应函数 */
observer?: string | Observer<WechatMiniprogram.Component.TrivialInstance, any>; observer?:
| string
| Observer<WechatMiniprogram.Component.TrivialInstance, any>;
/** 属性的类型(可以指定多个) */ /** 属性的类型(可以指定多个) */
optionalTypes?: PropertyType[]; optionalTypes?: PropertyType[];
}; };
......
/// <reference types="miniprogram-api-typings" /> /// <reference types="miniprogram-api-typings" />
declare type DialogAction = 'confirm' | 'cancel'; export declare type Action = 'confirm' | 'cancel' | 'overlay';
declare type DialogOptions = { interface DialogOptions {
lang?: string; lang?: string;
show?: boolean; show?: boolean;
title?: string; title?: string;
width?: string | number; width?: string | number | null;
zIndex?: number; zIndex?: number;
context?: WechatMiniprogram.Page.TrivialInstance | WechatMiniprogram.Component.TrivialInstance; theme?: string;
context?:
| WechatMiniprogram.Page.TrivialInstance
| WechatMiniprogram.Component.TrivialInstance;
message?: string; message?: string;
overlay?: boolean; overlay?: boolean;
selector?: string; selector?: string;
...@@ -14,7 +17,11 @@ declare type DialogOptions = { ...@@ -14,7 +17,11 @@ declare type DialogOptions = {
className?: string; className?: string;
customStyle?: string; customStyle?: string;
transition?: string; transition?: string;
/**
* @deprecated use beforeClose instead
*/
asyncClose?: boolean; asyncClose?: boolean;
beforeClose?: null | (() => Promise<void> | void);
businessId?: number; businessId?: number;
sessionFrom?: string; sessionFrom?: string;
overlayStyle?: string; overlayStyle?: string;
...@@ -30,18 +37,44 @@ declare type DialogOptions = { ...@@ -30,18 +37,44 @@ declare type DialogOptions = {
showCancelButton?: boolean; showCancelButton?: boolean;
closeOnClickOverlay?: boolean; closeOnClickOverlay?: boolean;
confirmButtonOpenType?: string; confirmButtonOpenType?: string;
};
interface Dialog {
(options: DialogOptions): Promise<DialogAction>;
alert?: (options: DialogOptions) => Promise<DialogAction>;
confirm?: (options: DialogOptions) => Promise<DialogAction>;
close?: () => void;
stopLoading?: () => void;
install?: () => void;
setDefaultOptions?: (options: DialogOptions) => void;
resetDefaultOptions?: () => void;
defaultOptions?: DialogOptions;
currentOptions?: DialogOptions;
} }
declare const Dialog: Dialog; declare const Dialog: {
(options: DialogOptions): Promise<
WechatMiniprogram.Component.Instance<
Record<string, any>,
Record<string, any>,
Record<string, any>,
Record<string, any>,
false
>
>;
alert(
options: DialogOptions
): Promise<
WechatMiniprogram.Component.Instance<
Record<string, any>,
Record<string, any>,
Record<string, any>,
Record<string, any>,
false
>
>;
confirm(
options: DialogOptions
): Promise<
WechatMiniprogram.Component.Instance<
Record<string, any>,
Record<string, any>,
Record<string, any>,
Record<string, any>,
false
>
>;
close(): void;
stopLoading(): void;
currentOptions: DialogOptions;
defaultOptions: DialogOptions;
setDefaultOptions(options: DialogOptions): void;
resetDefaultOptions(): void;
};
export default Dialog; export default Dialog;
let queue = []; let queue = [];
function getContext() { const defaultOptions = {
const pages = getCurrentPages(); show: false,
return pages[pages.length - 1];
}
const Dialog = options => {
options = Object.assign(Object.assign({}, Dialog.currentOptions), options);
return new Promise((resolve, reject) => {
const context = options.context || getContext();
const dialog = context.selectComponent(options.selector);
delete options.context;
delete options.selector;
if (dialog) {
dialog.setData(Object.assign({ onCancel: reject, onConfirm: resolve }, options));
queue.push(dialog);
}
else {
console.warn('未找到 van-dialog 节点,请确认 selector 及 context 是否正确');
}
});
};
Dialog.defaultOptions = {
show: true,
title: '', title: '',
width: null, width: null,
theme: 'default',
message: '', message: '',
zIndex: 100, zIndex: 100,
overlay: true, overlay: true,
selector: '#van-dialog', selector: '#van-dialog',
className: '', className: '',
asyncClose: false, asyncClose: false,
beforeClose: null,
transition: 'scale', transition: 'scale',
customStyle: '', customStyle: '',
messageAlign: '', messageAlign: '',
...@@ -38,26 +20,65 @@ Dialog.defaultOptions = { ...@@ -38,26 +20,65 @@ Dialog.defaultOptions = {
showConfirmButton: true, showConfirmButton: true,
showCancelButton: false, showCancelButton: false,
closeOnClickOverlay: false, closeOnClickOverlay: false,
confirmButtonOpenType: '' confirmButtonOpenType: '',
};
let currentOptions = Object.assign({}, defaultOptions);
function getContext() {
const pages = getCurrentPages();
return pages[pages.length - 1];
}
const Dialog = (options) => {
options = Object.assign(Object.assign({}, currentOptions), options);
return new Promise((resolve, reject) => {
const context = options.context || getContext();
const dialog = context.selectComponent(options.selector);
delete options.context;
delete options.selector;
if (dialog) {
dialog.setData(
Object.assign(
{
callback: (action, instance) => {
action === 'confirm' ? resolve(instance) : reject(instance);
},
},
options
)
);
wx.nextTick(() => {
dialog.setData({ show: true });
});
queue.push(dialog);
} else {
console.warn(
'未找到 van-dialog 节点,请确认 selector 及 context 是否正确'
);
}
});
}; };
Dialog.alert = Dialog; Dialog.alert = (options) => Dialog(options);
Dialog.confirm = options => Dialog(Object.assign({ showCancelButton: true }, options)); Dialog.confirm = (options) =>
Dialog(Object.assign({ showCancelButton: true }, options));
Dialog.close = () => { Dialog.close = () => {
queue.forEach(dialog => { queue.forEach((dialog) => {
dialog.close(); dialog.close();
}); });
queue = []; queue = [];
}; };
Dialog.stopLoading = () => { Dialog.stopLoading = () => {
queue.forEach(dialog => { queue.forEach((dialog) => {
dialog.stopLoading(); dialog.stopLoading();
}); });
}; };
Dialog.setDefaultOptions = options => { Dialog.currentOptions = currentOptions;
Object.assign(Dialog.currentOptions, options); Dialog.defaultOptions = defaultOptions;
Dialog.setDefaultOptions = (options) => {
currentOptions = Object.assign(Object.assign({}, currentOptions), options);
Dialog.currentOptions = currentOptions;
}; };
Dialog.resetDefaultOptions = () => { Dialog.resetDefaultOptions = () => {
Dialog.currentOptions = Object.assign({}, Dialog.defaultOptions); currentOptions = Object.assign({}, defaultOptions);
Dialog.currentOptions = currentOptions;
}; };
Dialog.resetDefaultOptions(); Dialog.resetDefaultOptions();
export default Dialog; export default Dialog;
import { VantComponent } from '../common/component'; import { VantComponent } from '../common/component';
import { button } from '../mixins/button'; import { button } from '../mixins/button';
import { openType } from '../mixins/open-type'; import { openType } from '../mixins/open-type';
import { GRAY, BLUE } from '../common/color'; import { GRAY, RED } from '../common/color';
import { toPromise } from '../common/utils';
VantComponent({ VantComponent({
mixins: [button, openType], mixins: [button, openType],
props: { props: {
...@@ -9,15 +10,20 @@ VantComponent({ ...@@ -9,15 +10,20 @@ VantComponent({
type: Boolean, type: Boolean,
observer(show) { observer(show) {
!show && this.stopLoading(); !show && this.stopLoading();
} },
}, },
title: String, title: String,
message: String, message: String,
theme: {
type: String,
value: 'default',
},
useSlot: Boolean, useSlot: Boolean,
className: String, className: String,
customStyle: String, customStyle: String,
asyncClose: Boolean, asyncClose: Boolean,
messageAlign: String, messageAlign: String,
beforeClose: null,
overlayStyle: String, overlayStyle: String,
useTitleSlot: Boolean, useTitleSlot: Boolean,
showCancelButton: Boolean, showCancelButton: Boolean,
...@@ -26,42 +32,42 @@ VantComponent({ ...@@ -26,42 +32,42 @@ VantComponent({
width: null, width: null,
zIndex: { zIndex: {
type: Number, type: Number,
value: 2000 value: 2000,
}, },
confirmButtonText: { confirmButtonText: {
type: String, type: String,
value: '确认' value: '确认',
}, },
cancelButtonText: { cancelButtonText: {
type: String, type: String,
value: '取消' value: '取消',
}, },
confirmButtonColor: { confirmButtonColor: {
type: String, type: String,
value: BLUE value: RED,
}, },
cancelButtonColor: { cancelButtonColor: {
type: String, type: String,
value: GRAY value: GRAY,
}, },
showConfirmButton: { showConfirmButton: {
type: Boolean, type: Boolean,
value: true value: true,
}, },
overlay: { overlay: {
type: Boolean, type: Boolean,
value: true value: true,
}, },
transition: { transition: {
type: String, type: String,
value: 'scale' value: 'scale',
} },
}, },
data: { data: {
loading: { loading: {
confirm: false, confirm: false,
cancel: false cancel: false,
} },
}, },
methods: { methods: {
onConfirm() { onConfirm() {
...@@ -73,38 +79,43 @@ VantComponent({ ...@@ -73,38 +79,43 @@ VantComponent({
onClickOverlay() { onClickOverlay() {
this.onClose('overlay'); this.onClose('overlay');
}, },
handleAction(action) { close(action) {
if (this.data.asyncClose) { this.setData({ show: false });
this.setData({ wx.nextTick(() => {
[`loading.${action}`]: true this.$emit('close', action);
}); const { callback } = this.data;
if (callback) {
callback(action, this);
} }
this.onClose(action);
},
close() {
this.setData({
show: false
}); });
}, },
stopLoading() { stopLoading() {
this.setData({ this.setData({
loading: { loading: {
confirm: false, confirm: false,
cancel: false cancel: false,
} },
}); });
}, },
onClose(action) { handleAction(action) {
if (!this.data.asyncClose) {
this.close();
}
this.$emit('close', action);
// 把 dialog 实例传递出去,可以通过 stopLoading() 在外部关闭按钮的 loading
this.$emit(action, { dialog: this }); this.$emit(action, { dialog: this });
const callback = this.data[action === 'confirm' ? 'onConfirm' : 'onCancel']; const { asyncClose, beforeClose } = this.data;
if (callback) { if (!asyncClose && !beforeClose) {
callback(this); this.close(action);
return;
} }
this.setData({
[`loading.${action}`]: true,
});
if (beforeClose) {
toPromise(beforeClose(action)).then((value) => {
if (value) {
this.close(action);
} else {
this.stopLoading();
} }
});
} }
},
},
}); });
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
"component": true, "component": true,
"usingComponents": { "usingComponents": {
"van-popup": "../popup/index", "van-popup": "../popup/index",
"van-button": "../button/index" "van-button": "../button/index",
"van-goods-action": "../goods-action/index",
"van-goods-action-button": "../goods-action-button/index"
} }
} }
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
z-index="{{ zIndex }}" z-index="{{ zIndex }}"
overlay="{{ overlay }}" overlay="{{ overlay }}"
transition="{{ transition }}" transition="{{ transition }}"
custom-class="van-dialog {{ className }}" custom-class="van-dialog van-dialog--{{ theme }} {{ className }}"
custom-style="width: {{ utils.addUnit(width) }};{{ customStyle }}" custom-style="width: {{ utils.addUnit(width) }};{{ customStyle }}"
overlay-style="{{ overlayStyle }}" overlay-style="{{ overlayStyle }}"
close-on-click-overlay="{{ closeOnClickOverlay }}" close-on-click-overlay="{{ closeOnClickOverlay }}"
...@@ -13,21 +13,63 @@ ...@@ -13,21 +13,63 @@
> >
<view <view
wx:if="{{ title || useTitleSlot }}" wx:if="{{ title || useTitleSlot }}"
class="van-dialog__header {{ message || useSlot ? '' : 'van-dialog--isolated' }}" class="{{ utils.bem('dialog__header', { isolated: !(message || useSlot) }) }}"
> >
<slot wx:if="{{ useTitleSlot }}" name="title" /> <slot wx:if="{{ useTitleSlot }}" name="title" />
<block wx:elif="{{ title }}"> {{ title }}</block> <block wx:elif="{{ title }}">{{ title }}</block>
</view> </view>
<slot wx:if="{{ useSlot }}" /> <slot wx:if="{{ useSlot }}" />
<view <view
wx:elif="{{ message }}" wx:elif="{{ message }}"
class="van-dialog__message {{ title ? 'van-dialog__message--has-title' : '' }} {{ messageAlign ? 'van-dialog__message--' + messageAlign : '' }}" class="{{ utils.bem('dialog__message', [theme, messageAlign, { hasTitle: title }]) }}"
> >
<text class="van-dialog__message-text">{{ message }}</text> <text class="van-dialog__message-text">{{ message }}</text>
</view> </view>
<view class="van-hairline--top van-dialog__footer"> <van-goods-action wx:if="{{ theme === 'round-button' }}" custom-class="van-dialog__footer--round-button">
<van-goods-action-button
wx:if="{{ showCancelButton }}"
size="large"
loading="{{ loading.cancel }}"
class="van-dialog__button van-hairline--right"
custom-class="van-dialog__cancel"
custom-style="color: {{ cancelButtonColor }}"
bind:click="onCancel"
>
{{ cancelButtonText }}
</van-goods-action-button>
<van-goods-action-button
wx:if="{{ showConfirmButton }}"
size="large"
class="van-dialog__button"
loading="{{ loading.confirm }}"
custom-class="van-dialog__confirm"
custom-style="color: {{ confirmButtonColor }}"
open-type="{{ confirmButtonOpenType }}"
lang="{{ lang }}"
business-id="{{ businessId }}"
session-from="{{ sessionFrom }}"
send-message-title="{{ sendMessageTitle }}"
send-message-path="{{ sendMessagePath }}"
send-message-img="{{ sendMessageImg }}"
show-message-card="{{ showMessageCard }}"
app-parameter="{{ appParameter }}"
bind:click="onConfirm"
bindgetuserinfo="bindGetUserInfo"
bindcontact="bindContact"
bindgetphonenumber="bindGetPhoneNumber"
binderror="bindError"
bindlaunchapp="bindLaunchApp"
bindopensetting="bindOpenSetting"
>
{{ confirmButtonText }}
</van-goods-action-button>
</van-goods-action>
<view wx:else class="van-hairline--top van-dialog__footer">
<van-button <van-button
wx:if="{{ showCancelButton }}" wx:if="{{ showCancelButton }}"
size="large" size="large"
......
@import '../common/index.wxss';.van-dialog{top:45%!important;overflow:hidden;width:320px;width:var(--dialog-width,320px);font-size:16px;font-size:var(--dialog-font-size,16px);border-radius:16px;border-radius:var(--dialog-border-radius,16px);background-color:#fff;background-color:var(--dialog-background-color,#fff)}@media (max-width:321px){.van-dialog{width:90%;width:var(--dialog-small-screen-width,90%)}}.van-dialog__header{text-align:center;padding-top:24px;padding-top:var(--dialog-header-padding-top,24px);font-weight:500;font-weight:var(--dialog-header-font-weight,500);line-height:24px;line-height:var(--dialog-header-line-height,24px)}.van-dialog__header--isolated{padding:24px 0;padding:var(--dialog-header-isolated-padding,24px 0)}.van-dialog__message{overflow-y:auto;text-align:center;-webkit-overflow-scrolling:touch;font-size:14px;font-size:var(--dialog-message-font-size,14px);line-height:20px;line-height:var(--dialog-message-line-height,20px);max-height:60vh;max-height:var(--dialog-message-max-height,60vh);padding:24px;padding:var(--dialog-message-padding,24px)}.van-dialog__message-text{word-wrap:break-word}.van-dialog__message--has-title{padding-top:12px;padding-top:var(--dialog-has-title-message-padding-top,12px);color:#646566;color:var(--dialog-has-title-message-text-color,#646566)}.van-dialog__message--left{text-align:left}.van-dialog__message--right{text-align:right}.van-dialog__footer{display:-webkit-flex;display:flex}.van-dialog__button{-webkit-flex:1;flex:1}.van-dialog__cancel,.van-dialog__confirm{border:0!important}.van-dialog-bounce-enter{-webkit-transform:translate3d(-50%,-50%,0) scale(.7);transform:translate3d(-50%,-50%,0) scale(.7);opacity:0}.van-dialog-bounce-leave-active{-webkit-transform:translate3d(-50%,-50%,0) scale(.9);transform:translate3d(-50%,-50%,0) scale(.9);opacity:0} @import '../common/index.wxss';.van-dialog{top:45%!important;overflow:hidden;width:320px;width:var(--dialog-width,320px);font-size:16px;font-size:var(--dialog-font-size,16px);border-radius:16px;border-radius:var(--dialog-border-radius,16px);background-color:#fff;background-color:var(--dialog-background-color,#fff)}@media (max-width:321px){.van-dialog{width:90%;width:var(--dialog-small-screen-width,90%)}}.van-dialog__header{text-align:center;padding-top:24px;padding-top:var(--dialog-header-padding-top,24px);font-weight:500;font-weight:var(--dialog-header-font-weight,500);line-height:24px;line-height:var(--dialog-header-line-height,24px)}.van-dialog__header--isolated{padding:24px 0;padding:var(--dialog-header-isolated-padding,24px 0)}.van-dialog__message{overflow-y:auto;text-align:center;-webkit-overflow-scrolling:touch;font-size:14px;font-size:var(--dialog-message-font-size,14px);line-height:20px;line-height:var(--dialog-message-line-height,20px);max-height:60vh;max-height:var(--dialog-message-max-height,60vh);padding:24px;padding:var(--dialog-message-padding,24px)}.van-dialog__message-text{word-wrap:break-word}.van-dialog__message--hasTitle{padding-top:8px;padding-top:var(--dialog-has-title-message-padding-top,8px);color:#646566;color:var(--dialog-has-title-message-text-color,#646566)}.van-dialog__message--round-button{padding-bottom:16px;color:#323233}.van-dialog__message--left{text-align:left}.van-dialog__message--right{text-align:right}.van-dialog__footer{display:-webkit-flex;display:flex}.van-dialog__footer--round-button{position:relative!important;padding:8px 24px 16px!important}.van-dialog__button{-webkit-flex:1;flex:1}.van-dialog__cancel,.van-dialog__confirm{border:0!important}.van-dialog-bounce-enter{-webkit-transform:translate3d(-50%,-50%,0) scale(.7);transform:translate3d(-50%,-50%,0) scale(.7);opacity:0}.van-dialog-bounce-leave-active{-webkit-transform:translate3d(-50%,-50%,0) scale(.9);transform:translate3d(-50%,-50%,0) scale(.9);opacity:0}
\ No newline at end of file \ No newline at end of file
...@@ -3,31 +3,31 @@ VantComponent({ ...@@ -3,31 +3,31 @@ VantComponent({
props: { props: {
dashed: { dashed: {
type: Boolean, type: Boolean,
value: false value: false,
}, },
hairline: { hairline: {
type: Boolean, type: Boolean,
value: false value: false,
}, },
contentPosition: { contentPosition: {
type: String, type: String,
value: '' value: '',
}, },
fontSize: { fontSize: {
type: Number, type: Number,
value: '' value: '',
}, },
borderColor: { borderColor: {
type: String, type: String,
value: '' value: '',
}, },
textColor: { textColor: {
type: String, type: String,
value: '' value: '',
}, },
customStyle: { customStyle: {
type: String, type: String,
value: '' value: '',
} },
} },
}); });
...@@ -7,34 +7,34 @@ VantComponent({ ...@@ -7,34 +7,34 @@ VantComponent({
current: 'dropdown-item', current: 'dropdown-item',
linked() { linked() {
this.updateDataFromParent(); this.updateDataFromParent();
} },
}, },
props: { props: {
value: { value: {
type: null, type: null,
observer: 'rerender' observer: 'rerender',
}, },
title: { title: {
type: String, type: String,
observer: 'rerender' observer: 'rerender',
}, },
disabled: Boolean, disabled: Boolean,
titleClass: { titleClass: {
type: String, type: String,
observer: 'rerender' observer: 'rerender',
}, },
options: { options: {
type: Array, type: Array,
value: [], value: [],
observer: 'rerender' observer: 'rerender',
}, },
popupStyle: String popupStyle: String,
}, },
data: { data: {
transition: true, transition: true,
showPopup: false, showPopup: false,
showWrapper: false, showWrapper: false,
displayTitle: '' displayTitle: '',
}, },
methods: { methods: {
rerender() { rerender() {
...@@ -44,13 +44,19 @@ VantComponent({ ...@@ -44,13 +44,19 @@ VantComponent({
}, },
updateDataFromParent() { updateDataFromParent() {
if (this.parent) { if (this.parent) {
const { overlay, duration, activeColor, closeOnClickOverlay, direction } = this.parent.data; const {
overlay,
duration,
activeColor,
closeOnClickOverlay,
direction,
} = this.parent.data;
this.setData({ this.setData({
overlay, overlay,
duration, duration,
activeColor, activeColor,
closeOnClickOverlay, closeOnClickOverlay,
direction direction,
}); });
} }
}, },
...@@ -95,10 +101,9 @@ VantComponent({ ...@@ -95,10 +101,9 @@ VantComponent({
this.setData({ wrapperStyle, showWrapper: true }); this.setData({ wrapperStyle, showWrapper: true });
this.rerender(); this.rerender();
}); });
} } else {
else {
this.rerender(); this.rerender();
} }
} },
} },
}); });
@import '../common/index.wxss';.van-dropdown-item{position:fixed;right:0;left:0;overflow:hidden}.van-dropdown-item__option{text-align:left}.van-dropdown-item__option--active .van-dropdown-item__icon,.van-dropdown-item__option--active .van-dropdown-item__title{color:#1989fa;color:var(--dropdown-menu-option-active-color,#1989fa)}.van-dropdown-item--up{top:0}.van-dropdown-item--down{bottom:0}.van-dropdown-item__icon{display:block;line-height:inherit} @import '../common/index.wxss';.van-dropdown-item{position:fixed;right:0;left:0;overflow:hidden}.van-dropdown-item__option{text-align:left}.van-dropdown-item__option--active .van-dropdown-item__icon,.van-dropdown-item__option--active .van-dropdown-item__title{color:#ee0a24;color:var(--dropdown-menu-option-active-color,#ee0a24)}.van-dropdown-item--up{top:0}.van-dropdown-item--down{bottom:0}.van-dropdown-item__icon{display:block;line-height:inherit}
\ No newline at end of file \ No newline at end of file
export interface Option {
text: string;
value: string | number;
icon: string;
}
import { VantComponent } from '../common/component'; import { VantComponent } from '../common/component';
import { addUnit } from '../common/utils'; import { addUnit, getRect, getSystemInfoSync } from '../common/utils';
let ARRAY = []; let ARRAY = [];
VantComponent({ VantComponent({
field: true, field: true,
...@@ -12,57 +12,57 @@ VantComponent({ ...@@ -12,57 +12,57 @@ VantComponent({
}, },
unlinked() { unlinked() {
this.updateItemListData(); this.updateItemListData();
} },
}, },
props: { props: {
activeColor: { activeColor: {
type: String, type: String,
observer: 'updateChildrenData' observer: 'updateChildrenData',
}, },
overlay: { overlay: {
type: Boolean, type: Boolean,
value: true, value: true,
observer: 'updateChildrenData' observer: 'updateChildrenData',
}, },
zIndex: { zIndex: {
type: Number, type: Number,
value: 10 value: 10,
}, },
duration: { duration: {
type: Number, type: Number,
value: 200, value: 200,
observer: 'updateChildrenData' observer: 'updateChildrenData',
}, },
direction: { direction: {
type: String, type: String,
value: 'down', value: 'down',
observer: 'updateChildrenData' observer: 'updateChildrenData',
}, },
closeOnClickOverlay: { closeOnClickOverlay: {
type: Boolean, type: Boolean,
value: true, value: true,
observer: 'updateChildrenData' observer: 'updateChildrenData',
}, },
closeOnClickOutside: { closeOnClickOutside: {
type: Boolean, type: Boolean,
value: true value: true,
} },
}, },
data: { data: {
itemListData: [] itemListData: [],
}, },
beforeCreate() { beforeCreate() {
const { windowHeight } = wx.getSystemInfoSync(); const { windowHeight } = getSystemInfoSync();
this.windowHeight = windowHeight; this.windowHeight = windowHeight;
ARRAY.push(this); ARRAY.push(this);
}, },
destroyed() { destroyed() {
ARRAY = ARRAY.filter(item => item !== this); ARRAY = ARRAY.filter((item) => item !== this);
}, },
methods: { methods: {
updateItemListData() { updateItemListData() {
this.setData({ this.setData({
itemListData: this.children.map((child) => child.data) itemListData: this.children.map((child) => child.data),
}); });
}, },
updateChildrenData() { updateChildrenData() {
...@@ -75,8 +75,7 @@ VantComponent({ ...@@ -75,8 +75,7 @@ VantComponent({
const { showPopup } = item.data; const { showPopup } = item.data;
if (index === active) { if (index === active) {
item.toggle(); item.toggle();
} } else if (showPopup) {
else if (showPopup) {
item.toggle(false, { immediate: true }); item.toggle(false, { immediate: true });
} }
}); });
...@@ -88,14 +87,13 @@ VantComponent({ ...@@ -88,14 +87,13 @@ VantComponent({
}, },
getChildWrapperStyle() { getChildWrapperStyle() {
const { zIndex, direction } = this.data; const { zIndex, direction } = this.data;
return this.getRect('.van-dropdown-menu').then((rect) => { return getRect(this, '.van-dropdown-menu').then((rect) => {
const { top = 0, bottom = 0 } = rect; const { top = 0, bottom = 0 } = rect;
const offset = direction === 'down' ? bottom : this.windowHeight - top; const offset = direction === 'down' ? bottom : this.windowHeight - top;
let wrapperStyle = `z-index: ${zIndex};`; let wrapperStyle = `z-index: ${zIndex};`;
if (direction === 'down') { if (direction === 'down') {
wrapperStyle += `top: ${addUnit(offset)};`; wrapperStyle += `top: ${addUnit(offset)};`;
} } else {
else {
wrapperStyle += `bottom: ${addUnit(offset)};`; wrapperStyle += `bottom: ${addUnit(offset)};`;
} }
return wrapperStyle; return wrapperStyle;
...@@ -105,15 +103,17 @@ VantComponent({ ...@@ -105,15 +103,17 @@ VantComponent({
const { index } = event.currentTarget.dataset; const { index } = event.currentTarget.dataset;
const child = this.children[index]; const child = this.children[index];
if (!child.data.disabled) { if (!child.data.disabled) {
ARRAY.forEach(menuItem => { ARRAY.forEach((menuItem) => {
if (menuItem && if (
menuItem &&
menuItem.data.closeOnClickOutside && menuItem.data.closeOnClickOutside &&
menuItem !== this) { menuItem !== this
) {
menuItem.close(); menuItem.close();
} }
}); });
this.toggleItem(index); this.toggleItem(index);
} }
} },
} },
}); });
@import '../common/index.wxss';.van-dropdown-menu{display:-webkit-flex;display:flex;-webkit-user-select:none;user-select:none;height:50px;height:var(--dropdown-menu-height,50px);background-color:#fff;background-color:var(--dropdown-menu-background-color,#fff)}.van-dropdown-menu__item{display:-webkit-flex;display:flex;-webkit-flex:1;flex:1;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;min-width:0}.van-dropdown-menu__item:active{opacity:.7}.van-dropdown-menu__item--disabled:active{opacity:1}.van-dropdown-menu__item--disabled .van-dropdown-menu__title{color:#969799;color:var(--dropdown-menu-title-disabled-text-color,#969799)}.van-dropdown-menu__title{position:relative;box-sizing:border-box;max-width:100%;padding:0 8px;padding:var(--dropdown-menu-title-padding,0 8px);color:#323233;color:var(--dropdown-menu-title-text-color,#323233);font-size:15px;font-size:var(--dropdown-menu-title-font-size,15px);line-height:18px;line-height:var(--dropdown-menu-title-line-height,18px)}.van-dropdown-menu__title:after{position:absolute;top:50%;right:-4px;margin-top:-5px;border-color:transparent transparent currentcolor currentcolor;border-style:solid;border-width:3px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:.8;content:""}.van-dropdown-menu__title--active{color:#1989fa;color:var(--dropdown-menu-title-active-text-color,#1989fa)}.van-dropdown-menu__title--down:after{margin-top:-1px;-webkit-transform:rotate(135deg);transform:rotate(135deg)} @import '../common/index.wxss';.van-dropdown-menu{display:-webkit-flex;display:flex;box-shadow:0 2px 12px rgba(100,101,102,.12);-webkit-user-select:none;user-select:none;height:50px;height:var(--dropdown-menu-height,50px);background-color:#fff;background-color:var(--dropdown-menu-background-color,#fff)}.van-dropdown-menu__item{display:-webkit-flex;display:flex;-webkit-flex:1;flex:1;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;min-width:0}.van-dropdown-menu__item:active{opacity:.7}.van-dropdown-menu__item--disabled:active{opacity:1}.van-dropdown-menu__item--disabled .van-dropdown-menu__title{color:#969799;color:var(--dropdown-menu-title-disabled-text-color,#969799)}.van-dropdown-menu__title{position:relative;box-sizing:border-box;max-width:100%;padding:0 8px;padding:var(--dropdown-menu-title-padding,0 8px);color:#323233;color:var(--dropdown-menu-title-text-color,#323233);font-size:15px;font-size:var(--dropdown-menu-title-font-size,15px);line-height:18px;line-height:var(--dropdown-menu-title-line-height,18px)}.van-dropdown-menu__title:after{position:absolute;top:50%;right:-4px;margin-top:-5px;border-color:transparent transparent currentcolor currentcolor;border-style:solid;border-width:3px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:.8;content:""}.van-dropdown-menu__title--active{color:#ee0a24;color:var(--dropdown-menu-title-active-text-color,#ee0a24)}.van-dropdown-menu__title--down:after{margin-top:-1px;-webkit-transform:rotate(135deg);transform:rotate(135deg)}
\ No newline at end of file \ No newline at end of file
import { VantComponent } from '../common/component';
const PRESETS = ['error', 'search', 'default', 'network'];
VantComponent({
props: {
description: String,
image: {
type: String,
value: 'default',
},
},
created() {
if (PRESETS.indexOf(this.data.image) !== -1) {
this.setData({
imageUrl: `https://img.yzcdn.cn/vant/empty-image-${this.data.image}.png`,
});
} else {
this.setData({ imageUrl: this.data.image });
}
},
});
{
"component": true,
"usingComponents": {}
}
\ No newline at end of file
<wxs src="../wxs/utils.wxs" module="utils" />
<view class="custom-class van-empty">
<view class="van-empty__image">
<slot name="image"></slot>
</view>
<view class="van-empty__image">
<image wx:if="{{ imageUrl }}" class="van-empty__image__img" src="{{ imageUrl }}" />
</view>
<view class="van-empty__description">
<slot name="description"></slot>
</view>
<view class="van-empty__description">
{{ description }}
</view>
<view class="van-empty__bottom">
<slot></slot>
</view>
</view>
@import '../common/index.wxss';.van-empty{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;padding:32px 0}.van-empty__image{width:160px;height:160px}.van-empty__image:empty{display:none}.van-empty__image__img{width:100%;height:100%}.van-empty__image:not(:empty)+.van-empty__image{display:none}.van-empty__description{margin-top:16px;padding:0 60px;color:#969799;font-size:14px;line-height:20px}.van-empty__description:empty,.van-empty__description:not(:empty)+.van-empty__description{display:none}.van-empty__bottom{margin-top:24px}
\ No newline at end of file
import { VantComponent } from '../common/component'; import { VantComponent } from '../common/component';
import { getSystemInfoSync } from '../common/utils'; import { commonProps, inputProps, textareaProps } from './props';
VantComponent({ VantComponent({
field: true, field: true,
classes: ['input-class', 'right-icon-class'], classes: ['input-class', 'right-icon-class', 'label-class'],
props: { props: Object.assign(
Object.assign(
Object.assign(Object.assign({}, commonProps), inputProps),
textareaProps
),
{
size: String, size: String,
icon: String, icon: String,
label: String, label: String,
error: Boolean, error: Boolean,
fixed: Boolean,
focus: Boolean,
center: Boolean, center: Boolean,
isLink: Boolean, isLink: Boolean,
leftIcon: String, leftIcon: String,
rightIcon: String, rightIcon: String,
disabled: Boolean, autosize: [Boolean, Object],
autosize: Boolean,
readonly: Boolean,
required: Boolean, required: Boolean,
password: Boolean,
iconClass: String, iconClass: String,
clearable: Boolean,
clickable: Boolean, clickable: Boolean,
inputAlign: String, inputAlign: String,
placeholder: String,
customStyle: String, customStyle: String,
confirmType: String,
confirmHold: Boolean,
holdKeyboard: Boolean,
errorMessage: String, errorMessage: String,
arrowDirection: String, arrowDirection: String,
placeholderStyle: String, showWordLimit: Boolean,
errorMessageAlign: String, errorMessageAlign: String,
selectionEnd: { readonly: {
type: Number,
value: -1
},
selectionStart: {
type: Number,
value: -1
},
showConfirmBar: {
type: Boolean, type: Boolean,
value: true observer: 'setShowClear',
}, },
adjustPosition: { clearable: {
type: Boolean, type: Boolean,
value: true observer: 'setShowClear',
},
cursorSpacing: {
type: Number,
value: 50
},
maxlength: {
type: Number,
value: -1
},
type: {
type: String,
value: 'text'
}, },
border: { border: {
type: Boolean, type: Boolean,
value: true value: true,
}, },
titleWidth: { titleWidth: {
type: String, type: String,
value: '90px' value: '6.2em',
}
}, },
}
),
data: { data: {
focused: false, focused: false,
system: getSystemInfoSync().system.split(' ').shift().toLowerCase() innerValue: '',
showClear: false,
},
created() {
this.value = this.data.value;
this.setData({ innerValue: this.value });
}, },
methods: { methods: {
onInput(event) { onInput(event) {
const { value = '' } = event.detail || {}; const { value = '' } = event.detail || {};
this.setData({ value }); this.value = value;
wx.nextTick(() => { this.setShowClear();
this.emitChange(value); this.emitChange();
});
}, },
onFocus(event) { onFocus(event) {
this.setData({ focused: true }); this.focused = true;
this.setShowClear();
this.$emit('focus', event.detail); this.$emit('focus', event.detail);
}, },
onBlur(event) { onBlur(event) {
this.setData({ focused: false }); this.focused = false;
this.setShowClear();
this.$emit('blur', event.detail); this.$emit('blur', event.detail);
}, },
onClickIcon() { onClickIcon() {
this.$emit('click-icon'); this.$emit('click-icon');
}, },
onClear() { onClear() {
this.setData({ value: '' }); this.setData({ innerValue: '' });
this.value = '';
this.setShowClear();
wx.nextTick(() => { wx.nextTick(() => {
this.emitChange(''); this.emitChange();
this.$emit('clear', ''); this.$emit('clear', '');
}); });
}, },
onConfirm() { onConfirm(event) {
this.$emit('confirm', this.data.value); const { value = '' } = event.detail || {};
this.value = value;
this.setShowClear();
this.$emit('confirm', value);
},
setValue(value) {
this.value = value;
this.setShowClear();
if (value === '') {
this.setData({ innerValue: '' });
}
this.emitChange();
}, },
emitChange(value) { onLineChange(event) {
this.$emit('input', value); this.$emit('linechange', event.detail);
this.$emit('change', value); },
onKeyboardHeightChange(event) {
this.$emit('keyboardheightchange', event.detail);
},
emitChange() {
this.setData({ value: this.value });
wx.nextTick(() => {
this.$emit('input', this.value);
this.$emit('change', this.value);
});
},
setShowClear() {
const { clearable, readonly } = this.data;
const { focused, value } = this;
this.setData({
showClear: !!clearable && !!focused && !!value && !readonly,
});
},
noop() {},
}, },
noop() { }
}
}); });
<wxs src="../wxs/utils.wxs" module="utils" /> <wxs src="../wxs/utils.wxs" module="utils" />
<wxs src="./index.wxs" module="computed" />
<van-cell <van-cell
size="{{ size }}" size="{{ size }}"
icon="{{ leftIcon }}" icon="{{ leftIcon }}"
title="{{ label }}"
center="{{ center }}" center="{{ center }}"
border="{{ border }}" border="{{ border }}"
is-link="{{ isLink }}" is-link="{{ isLink }}"
required="{{ required }}" required="{{ required }}"
clickable="{{ clickable }}" clickable="{{ clickable }}"
title-width="{{ titleWidth }}" title-width="{{ titleWidth }}"
title-style="margin-right: 12px;"
custom-style="{{ customStyle }}" custom-style="{{ customStyle }}"
arrow-direction="{{ arrowDirection }}" arrow-direction="{{ arrowDirection }}"
custom-class="van-field" custom-class="van-field"
> >
<slot name="left-icon" slot="icon" /> <slot name="left-icon" slot="icon" />
<slot name="label" slot="title" /> <view wx:if="{{ label }}" class="label-class {{ utils.bem('field__label', { disabled }) }}" slot="title">
<view class="{{ utils.bem('field__body', [type, system]) }}"> {{ label }}
</view>
<slot wx:else name="label" slot="title" />
<view class="{{ utils.bem('field__body', [type]) }}">
<textarea <textarea
wx:if="{{ type === 'textarea' }}" wx:if="{{ type === 'textarea' }}"
class="input-class {{ utils.bem('field__input', [inputAlign, type, { disabled, error }]) }}" class="input-class {{ utils.bem('field__input', [inputAlign, type, { disabled, error }]) }}"
fixed="{{ fixed }}" fixed="{{ fixed }}"
focus="{{ focus }}" focus="{{ focus }}"
value="{{ value }}" cursor="{{ cursor }}"
value="{{ innerValue }}"
auto-focus="{{ autoFocus }}"
disabled="{{ disabled || readonly }}" disabled="{{ disabled || readonly }}"
maxlength="{{ maxlength }}" maxlength="{{ maxlength }}"
placeholder="{{ placeholder }}" placeholder="{{ placeholder }}"
placeholder-style="{{ placeholderStyle }}" placeholder-style="{{ placeholderStyle }}"
placeholder-class="{{ utils.bem('field__placeholder', { error }) }}" placeholder-class="{{ utils.bem('field__placeholder', { error, disabled }) }}"
auto-height="{{ autosize }}" auto-height="{{ !!autosize }}"
style="{{ computed.inputStyle(autosize) }}"
cursor-spacing="{{ cursorSpacing }}" cursor-spacing="{{ cursorSpacing }}"
adjust-position="{{ adjustPosition }}" adjust-position="{{ adjustPosition }}"
show-confirm-bar="{{ showConfirmBar }}" show-confirm-bar="{{ showConfirmBar }}"
hold-keyboard="{{ holdKeyboard }}" hold-keyboard="{{ holdKeyboard }}"
selection-end="{{ selectionEnd }}" selection-end="{{ selectionEnd }}"
selection-start="{{ selectionStart }}" selection-start="{{ selectionStart }}"
disable-default-padding="{{ disableDefaultPadding }}"
bindinput="onInput" bindinput="onInput"
bind:blur="onBlur" bindblur="onBlur"
bind:focus="onFocus" bindfocus="onFocus"
bind:confirm="onConfirm" bindconfirm="onConfirm"
bindlinechange="onLineChange"
bindkeyboardheightchange="onKeyboardHeightChange"
> >
</textarea> </textarea>
<input <input
...@@ -46,7 +56,9 @@ ...@@ -46,7 +56,9 @@
class="input-class {{ utils.bem('field__input', [inputAlign, { disabled, error }]) }}" class="input-class {{ utils.bem('field__input', [inputAlign, { disabled, error }]) }}"
type="{{ type }}" type="{{ type }}"
focus="{{ focus }}" focus="{{ focus }}"
value="{{ value }}" cursor="{{ cursor }}"
value="{{ innerValue }}"
auto-focus="{{ autoFocus }}"
disabled="{{ disabled || readonly }}" disabled="{{ disabled || readonly }}"
maxlength="{{ maxlength }}" maxlength="{{ maxlength }}"
placeholder="{{ placeholder }}" placeholder="{{ placeholder }}"
...@@ -61,13 +73,13 @@ ...@@ -61,13 +73,13 @@
selection-start="{{ selectionStart }}" selection-start="{{ selectionStart }}"
password="{{ password || type === 'password' }}" password="{{ password || type === 'password' }}"
bindinput="onInput" bindinput="onInput"
bind:blur="onBlur" bindblur="onBlur"
bind:focus="onFocus" bindfocus="onFocus"
bind:confirm="onConfirm" bindconfirm="onConfirm"
bindkeyboardheightchange="onKeyboardHeightChange"
/> />
<van-icon <van-icon
wx:if="{{ clearable && focused && value && !readonly }}" wx:if="{{ showClear }}"
size="16px"
name="clear" name="clear"
class="van-field__clear-root van-field__icon-root" class="van-field__clear-root van-field__icon-root"
catch:touchstart="onClear" catch:touchstart="onClear"
...@@ -75,7 +87,6 @@ ...@@ -75,7 +87,6 @@
<view class="van-field__icon-container" bind:tap="onClickIcon"> <view class="van-field__icon-container" bind:tap="onClickIcon">
<van-icon <van-icon
wx:if="{{ rightIcon || icon }}" wx:if="{{ rightIcon || icon }}"
size="16px"
name="{{ rightIcon || icon }}" name="{{ rightIcon || icon }}"
class="van-field__icon-root {{ iconClass }}" class="van-field__icon-root {{ iconClass }}"
custom-class="right-icon-class" custom-class="right-icon-class"
...@@ -87,7 +98,10 @@ ...@@ -87,7 +98,10 @@
<slot name="button" /> <slot name="button" />
</view> </view>
</view> </view>
<view wx:if="{{ errorMessage }}" class="van-field__error-message {{ utils.bem('field__error', [errorMessageAlign, { disabled, error }]) }}"> <view wx:if="{{ showWordLimit && maxlength }}" class="van-field__word-limit">
<view class="{{ utils.bem('field__word-num', { full: value.length >= maxlength }) }}">{{ value.length >= maxlength ? maxlength : value.length }}</view>/{{ maxlength }}
</view>
<view wx:if="{{ errorMessage }}" class="{{ utils.bem('field__error-message', [errorMessageAlign, { disabled, error }]) }}">
{{ errorMessage }} {{ errorMessage }}
</view> </view>
</van-cell> </van-cell>
/* eslint-disable */
var utils = require('../wxs/utils.wxs');
function inputStyle(autosize) {
if (autosize && autosize.constructor === 'Object') {
var style = '';
if (autosize.minHeight) {
style += 'min-height:' + utils.addUnit(autosize.minHeight) + ';';
}
if (autosize.maxHeight) {
style += 'max-height:' + utils.addUnit(autosize.maxHeight) + ';';
}
return style;
}
return '';
}
module.exports = {
inputStyle: inputStyle
};
@import '../common/index.wxss';.van-field__body{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center}.van-field__body--textarea{line-height:1.2em;min-height:24px;min-height:var(--cell-line-height,24px)}.van-field__body--textarea.van-field__body--ios{margin-top:-4.5px}.van-field__input{position:relative;display:block;box-sizing:border-box;width:100%;margin:0;padding:0;line-height:inherit;text-align:left;background-color:initial;border:0;resize:none;color:#323233;color:var(--field-input-text-color,#323233);height:24px;height:var(--cell-line-height,24px);min-height:24px;min-height:var(--cell-line-height,24px)}.van-field__input--textarea{height:18px;height:var(--field-text-area-min-height,18px);min-height:18px;min-height:var(--field-text-area-min-height,18px)}.van-field__input--error{color:#ee0a24;color:var(--field-input-error-text-color,#ee0a24)}.van-field__input--disabled{background-color:initial;opacity:1;color:#969799;color:var(--field-input-disabled-text-color,#969799)}.van-field__input--center{text-align:center}.van-field__input--right{text-align:right}.van-field__placeholder{position:absolute;top:0;right:0;left:0;pointer-events:none;color:#969799;color:var(--field-placeholder-text-color,#969799)}.van-field__placeholder--error{color:#ee0a24;color:var(--field-error-message-color,#ee0a24)}.van-field__icon-root{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;min-height:24px;min-height:var(--cell-line-height,24px)}.van-field__clear-root,.van-field__icon-container{line-height:inherit;vertical-align:middle;padding:0 8px;padding:0 var(--padding-xs,8px);margin-right:-8px;margin-right:-var(--padding-xs,8px)}.van-field__button,.van-field__clear-root,.van-field__icon-container{-webkit-flex-shrink:0;flex-shrink:0}.van-field__clear-root{color:#c8c9cc;color:var(--field-clear-icon-color,#c8c9cc)}.van-field__icon-container{color:#969799;color:var(--field-icon-container-color,#969799)}.van-field__icon-container:empty{display:none}.van-field__button{padding-left:8px;padding-left:var(--padding-xs,8px)}.van-field__button:empty{display:none}.van-field__error-message{text-align:left;font-size:12px;font-size:var(--field-error-message-text-font-size,12px);color:#ee0a24;color:var(--field-error-message-color,#ee0a24)}.van-field__error-message--center{text-align:center}.van-field__error-message--right{text-align:right} @import '../common/index.wxss';.van-field{--cell-icon-size:16px;--cell-icon-size:var(--field-icon-size,16px)}.van-field__label{color:#646566;color:var(--field-label-color,#646566)}.van-field__label--disabled{color:#c8c9cc;color:var(--field-disabled-text-color,#c8c9cc)}.van-field__body{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center}.van-field__body--textarea{padding:3.6px 0;line-height:1.2em}.van-field__body--textarea,.van-field__input{box-sizing:border-box;min-height:24px;min-height:var(--cell-line-height,24px)}.van-field__input{position:relative;display:block;width:100%;margin:0;padding:0;line-height:inherit;text-align:left;background-color:initial;border:0;resize:none;color:#323233;color:var(--field-input-text-color,#323233);height:24px;height:var(--cell-line-height,24px)}.van-field__input--textarea{height:18px;height:var(--field-text-area-min-height,18px);min-height:18px;min-height:var(--field-text-area-min-height,18px)}.van-field__input--error{color:#ee0a24;color:var(--field-input-error-text-color,#ee0a24)}.van-field__input--disabled{background-color:initial;opacity:1;color:#c8c9cc;color:var(--field-input-disabled-text-color,#c8c9cc)}.van-field__input--center{text-align:center}.van-field__input--right{text-align:right}.van-field__placeholder{position:absolute;top:0;right:0;left:0;pointer-events:none;color:#c8c9cc;color:var(--field-placeholder-text-color,#c8c9cc)}.van-field__placeholder--error{color:#ee0a24;color:var(--field-error-message-color,#ee0a24)}.van-field__icon-root{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;min-height:24px;min-height:var(--cell-line-height,24px)}.van-field__clear-root,.van-field__icon-container{line-height:inherit;vertical-align:middle;padding:0 8px;padding:0 var(--padding-xs,8px);margin-right:-8px;margin-right:-var(--padding-xs,8px)}.van-field__button,.van-field__clear-root,.van-field__icon-container{-webkit-flex-shrink:0;flex-shrink:0}.van-field__clear-root{font-size:16px;font-size:var(--field-clear-icon-size,16px);color:#c8c9cc;color:var(--field-clear-icon-color,#c8c9cc)}.van-field__icon-container{font-size:16px;font-size:var(--field-icon-size,16px);color:#969799;color:var(--field-icon-container-color,#969799)}.van-field__icon-container:empty{display:none}.van-field__button{padding-left:8px;padding-left:var(--padding-xs,8px)}.van-field__button:empty{display:none}.van-field__error-message{text-align:left;font-size:12px;font-size:var(--field-error-message-text-font-size,12px);color:#ee0a24;color:var(--field-error-message-color,#ee0a24)}.van-field__error-message--center{text-align:center}.van-field__error-message--right{text-align:right}.van-field__word-limit{text-align:right;margin-top:4px;margin-top:var(--padding-base,4px);color:#646566;color:var(--field-word-limit-color,#646566);font-size:12px;font-size:var(--field-word-limit-font-size,12px);line-height:16px;line-height:var(--field-word-limit-line-height,16px)}.van-field__word-num{display:inline}.van-field__word-num--full{color:#ee0a24;color:var(--field-word-num-full-color,#ee0a24)}
\ No newline at end of file \ No newline at end of file
/// <reference types="miniprogram-api-typings" />
export declare const commonProps: {
value: {
type: StringConstructor;
observer(
this: WechatMiniprogram.Component.TrivialInstance,
value: string
): void;
};
placeholder: StringConstructor;
placeholderStyle: StringConstructor;
placeholderClass: StringConstructor;
disabled: BooleanConstructor;
maxlength: {
type: NumberConstructor;
value: number;
};
cursorSpacing: {
type: NumberConstructor;
value: number;
};
autoFocus: BooleanConstructor;
focus: BooleanConstructor;
cursor: {
type: NumberConstructor;
value: number;
};
selectionStart: {
type: NumberConstructor;
value: number;
};
selectionEnd: {
type: NumberConstructor;
value: number;
};
adjustPosition: {
type: BooleanConstructor;
value: boolean;
};
holdKeyboard: BooleanConstructor;
};
export declare const inputProps: {
type: {
type: StringConstructor;
value: string;
};
password: BooleanConstructor;
confirmType: StringConstructor;
confirmHold: BooleanConstructor;
};
export declare const textareaProps: {
autoHeight: BooleanConstructor;
fixed: BooleanConstructor;
showConfirmBar: {
type: BooleanConstructor;
value: boolean;
};
disableDefaultPadding: {
type: BooleanConstructor;
value: boolean;
};
};
export const commonProps = {
value: {
type: String,
observer(value) {
if (value !== this.value) {
this.setData({ innerValue: value });
this.value = value;
}
},
},
placeholder: String,
placeholderStyle: String,
placeholderClass: String,
disabled: Boolean,
maxlength: {
type: Number,
value: -1,
},
cursorSpacing: {
type: Number,
value: 50,
},
autoFocus: Boolean,
focus: Boolean,
cursor: {
type: Number,
value: -1,
},
selectionStart: {
type: Number,
value: -1,
},
selectionEnd: {
type: Number,
value: -1,
},
adjustPosition: {
type: Boolean,
value: true,
},
holdKeyboard: Boolean,
};
export const inputProps = {
type: {
type: String,
value: 'text',
},
password: Boolean,
confirmType: String,
confirmHold: Boolean,
};
export const textareaProps = {
autoHeight: Boolean,
fixed: Boolean,
showConfirmBar: {
type: Boolean,
value: true,
},
disableDefaultPadding: {
type: Boolean,
value: true,
},
};
...@@ -17,11 +17,8 @@ VantComponent({ ...@@ -17,11 +17,8 @@ VantComponent({
plain: Boolean, plain: Boolean,
type: { type: {
type: String, type: String,
value: 'danger' value: 'danger',
}
}, },
mounted() {
this.updateStyle();
}, },
methods: { methods: {
onClick(event) { onClick(event) {
...@@ -29,13 +26,16 @@ VantComponent({ ...@@ -29,13 +26,16 @@ VantComponent({
this.jumpLink(); this.jumpLink();
}, },
updateStyle() { updateStyle() {
if (this.parent == null) {
return;
}
const { children = [] } = this.parent; const { children = [] } = this.parent;
const { length } = children; const { length } = children;
const index = children.indexOf(this); const index = children.indexOf(this);
this.setData({ this.setData({
isFirst: index === 0, isFirst: index === 0,
isLast: index === length - 1 isLast: index === length - 1,
}); });
} },
} },
}); });
@import '../common/index.wxss';:host{-webkit-flex:1;flex:1}.van-goods-action-button{--button-warning-background-color:linear-gradient(90deg,#ffd01e,#ff8917);--button-warning-background-color:var(--goods-action-button-warning-color,linear-gradient(90deg,#ffd01e,#ff8917));--button-danger-background-color:linear-gradient(90deg,#ff6034,#ee0a24);--button-danger-background-color:var(--goods-action-button-danger-color,linear-gradient(90deg,#ff6034,#ee0a24));--button-default-height:40px;--button-default-height:var(--goods-action-button-height,40px);--button-line-height:40px;--button-line-height:var(--goods-action-button-height,40px);--button-plain-background-color:#fff;--button-plain-background-color:var(--goods-action-button-plain-color,#fff);display:block;--button-border-width:0}.van-goods-action-button--first{margin-left:5px;--button-border-radius:20px 0 0 20px;--button-border-radius:var(--goods-action-button-border-radius,20px) 0 0 var(--goods-action-button-border-radius,20px)}.van-goods-action-button--last{margin-right:5px;--button-border-radius:0 20px 20px 0;--button-border-radius:0 var(--goods-action-button-border-radius,20px) var(--goods-action-button-border-radius,20px) 0}.van-goods-action-button--first.van-goods-action-button--last{--button-border-radius:20px;--button-border-radius:var(--goods-action-button-border-radius,20px)}.van-goods-action-button--plain{--button-border-width:1px}.van-goods-action-button__inner{width:100%;font-weight:500!important;font-weight:var(--font-weight-bold,500)!important}@media (max-width:321px){.van-goods-action-button{font-size:13px}} @import '../common/index.wxss';:host{-webkit-flex:1;flex:1}.van-goods-action-button{--button-warning-background-color:linear-gradient(90deg,#ffd01e,#ff8917);--button-warning-background-color:var(--goods-action-button-warning-color,linear-gradient(90deg,#ffd01e,#ff8917));--button-danger-background-color:linear-gradient(90deg,#ff6034,#ee0a24);--button-danger-background-color:var(--goods-action-button-danger-color,linear-gradient(90deg,#ff6034,#ee0a24));--button-default-height:40px;--button-default-height:var(--goods-action-button-height,40px);--button-line-height:20px;--button-line-height:var(--goods-action-button-line-height,20px);--button-plain-background-color:#fff;--button-plain-background-color:var(--goods-action-button-plain-color,#fff);display:block;--button-border-width:0}.van-goods-action-button--first{margin-left:5px;--button-border-radius:20px 0 0 20px;--button-border-radius:var(--goods-action-button-border-radius,20px) 0 0 var(--goods-action-button-border-radius,20px)}.van-goods-action-button--last{margin-right:5px;--button-border-radius:0 20px 20px 0;--button-border-radius:0 var(--goods-action-button-border-radius,20px) var(--goods-action-button-border-radius,20px) 0}.van-goods-action-button--first.van-goods-action-button--last{--button-border-radius:20px;--button-border-radius:var(--goods-action-button-border-radius,20px)}.van-goods-action-button--plain{--button-border-width:1px}.van-goods-action-button__inner{width:100%;font-weight:500!important;font-weight:var(--font-weight-bold,500)!important}@media (max-width:321px){.van-goods-action-button{font-size:13px}}
\ No newline at end of file \ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment