roose 5 years ago
parent
commit
b6958a1d8b
100 changed files with 2722 additions and 5 deletions
  1. 7 5
      app.js
  2. 57 0
      miniprogram_npm/vant-weapp/calendar/calendar.wxml
  3. 1 0
      miniprogram_npm/vant-weapp/calendar/components/header/index.d.ts
  4. 16 0
      miniprogram_npm/vant-weapp/calendar/components/header/index.js
  5. 3 0
      miniprogram_npm/vant-weapp/calendar/components/header/index.json
  6. 16 0
      miniprogram_npm/vant-weapp/calendar/components/header/index.wxml
  7. 1 0
      miniprogram_npm/vant-weapp/calendar/components/header/index.wxss
  8. 1 0
      miniprogram_npm/vant-weapp/calendar/components/month/index.d.ts
  9. 157 0
      miniprogram_npm/vant-weapp/calendar/components/month/index.js
  10. 3 0
      miniprogram_npm/vant-weapp/calendar/components/month/index.json
  11. 39 0
      miniprogram_npm/vant-weapp/calendar/components/month/index.wxml
  12. 67 0
      miniprogram_npm/vant-weapp/calendar/components/month/index.wxs
  13. 1 0
      miniprogram_npm/vant-weapp/calendar/components/month/index.wxss
  14. 1 0
      miniprogram_npm/vant-weapp/calendar/index.d.ts
  15. 290 0
      miniprogram_npm/vant-weapp/calendar/index.js
  16. 9 0
      miniprogram_npm/vant-weapp/calendar/index.json
  17. 31 0
      miniprogram_npm/vant-weapp/calendar/index.wxml
  18. 37 0
      miniprogram_npm/vant-weapp/calendar/index.wxs
  19. 1 0
      miniprogram_npm/vant-weapp/calendar/index.wxss
  20. 17 0
      miniprogram_npm/vant-weapp/calendar/utils.d.ts
  21. 78 0
      miniprogram_npm/vant-weapp/calendar/utils.js
  22. 25 0
      miniprogram_npm/vant-weapp/calendar/utils.wxs
  23. 20 0
      miniprogram_npm/vant-weapp/checkbox/index.wxs
  24. 6 0
      miniprogram_npm/vant-weapp/circle/canvas.d.ts
  25. 43 0
      miniprogram_npm/vant-weapp/circle/canvas.js
  26. 1 0
      miniprogram_npm/vant-weapp/circle/index.d.ts
  27. 176 0
      miniprogram_npm/vant-weapp/circle/index.js
  28. 3 0
      miniprogram_npm/vant-weapp/circle/index.json
  29. 9 0
      miniprogram_npm/vant-weapp/circle/index.wxml
  30. 1 0
      miniprogram_npm/vant-weapp/circle/index.wxss
  31. 0 0
      miniprogram_npm/vant-weapp/common/style/theme.wxss
  32. 2 0
      miniprogram_npm/vant-weapp/common/version.d.ts
  33. 31 0
      miniprogram_npm/vant-weapp/common/version.js
  34. 1 0
      miniprogram_npm/vant-weapp/count-down/index.d.ts
  35. 99 0
      miniprogram_npm/vant-weapp/count-down/index.js
  36. 3 0
      miniprogram_npm/vant-weapp/count-down/index.json
  37. 4 0
      miniprogram_npm/vant-weapp/count-down/index.wxml
  38. 1 0
      miniprogram_npm/vant-weapp/count-down/index.wxss
  39. 10 0
      miniprogram_npm/vant-weapp/count-down/utils.d.ts
  40. 53 0
      miniprogram_npm/vant-weapp/count-down/utils.js
  41. 1 0
      miniprogram_npm/vant-weapp/divider/index.d.ts
  42. 1 0
      miniprogram_npm/vant-weapp/dropdown-item/index.d.ts
  43. 109 0
      miniprogram_npm/vant-weapp/dropdown-item/index.js
  44. 8 0
      miniprogram_npm/vant-weapp/dropdown-item/index.json
  45. 48 0
      miniprogram_npm/vant-weapp/dropdown-item/index.wxml
  46. 1 0
      miniprogram_npm/vant-weapp/dropdown-item/index.wxss
  47. 1 0
      miniprogram_npm/vant-weapp/dropdown-menu/index.d.ts
  48. 119 0
      miniprogram_npm/vant-weapp/dropdown-menu/index.js
  49. 3 0
      miniprogram_npm/vant-weapp/dropdown-menu/index.json
  50. 23 0
      miniprogram_npm/vant-weapp/dropdown-menu/index.wxml
  51. 16 0
      miniprogram_npm/vant-weapp/dropdown-menu/index.wxs
  52. 1 0
      miniprogram_npm/vant-weapp/dropdown-menu/index.wxss
  53. 21 0
      miniprogram_npm/vant-weapp/field/index.wxs
  54. 58 0
      miniprogram_npm/vant-weapp/field/props.d.ts
  55. 63 0
      miniprogram_npm/vant-weapp/field/props.js
  56. 1 0
      miniprogram_npm/vant-weapp/grid-item/index.d.ts
  57. 82 0
      miniprogram_npm/vant-weapp/grid-item/index.js
  58. 6 0
      miniprogram_npm/vant-weapp/grid-item/index.json
  59. 22 0
      miniprogram_npm/vant-weapp/grid-item/index.wxml
  60. 1 0
      miniprogram_npm/vant-weapp/grid-item/index.wxss
  61. 1 0
      miniprogram_npm/vant-weapp/grid/index.d.ts
  62. 65 0
      miniprogram_npm/vant-weapp/grid/index.js
  63. 3 0
      miniprogram_npm/vant-weapp/grid/index.json
  64. 3 0
      miniprogram_npm/vant-weapp/grid/index.wxml
  65. 1 0
      miniprogram_npm/vant-weapp/grid/index.wxss
  66. 1 0
      miniprogram_npm/vant-weapp/image/index.d.ts
  67. 101 0
      miniprogram_npm/vant-weapp/image/index.js
  68. 7 0
      miniprogram_npm/vant-weapp/image/index.json
  69. 33 0
      miniprogram_npm/vant-weapp/image/index.wxml
  70. 1 0
      miniprogram_npm/vant-weapp/image/index.wxss
  71. 1 0
      miniprogram_npm/vant-weapp/index-anchor/index.d.ts
  72. 30 0
      miniprogram_npm/vant-weapp/index-anchor/index.js
  73. 3 0
      miniprogram_npm/vant-weapp/index-anchor/index.json
  74. 14 0
      miniprogram_npm/vant-weapp/index-anchor/index.wxml
  75. 1 0
      miniprogram_npm/vant-weapp/index-anchor/index.wxss
  76. 1 0
      miniprogram_npm/vant-weapp/index-bar/index.d.ts
  77. 250 0
      miniprogram_npm/vant-weapp/index-bar/index.js
  78. 3 0
      miniprogram_npm/vant-weapp/index-bar/index.json
  79. 22 0
      miniprogram_npm/vant-weapp/index-bar/index.wxml
  80. 1 0
      miniprogram_npm/vant-weapp/index-bar/index.wxss
  81. 5 0
      miniprogram_npm/vant-weapp/mixins/page-scroll.d.ts
  82. 33 0
      miniprogram_npm/vant-weapp/mixins/page-scroll.js
  83. 28 0
      miniprogram_npm/vant-weapp/picker/toolbar.wxml
  84. 1 0
      miniprogram_npm/vant-weapp/sidebar-item/index.d.ts
  85. 31 0
      miniprogram_npm/vant-weapp/sidebar-item/index.js
  86. 6 0
      miniprogram_npm/vant-weapp/sidebar-item/index.json
  87. 19 0
      miniprogram_npm/vant-weapp/sidebar-item/index.wxml
  88. 1 0
      miniprogram_npm/vant-weapp/sidebar-item/index.wxss
  89. 1 0
      miniprogram_npm/vant-weapp/sidebar/index.d.ts
  90. 41 0
      miniprogram_npm/vant-weapp/sidebar/index.js
  91. 3 0
      miniprogram_npm/vant-weapp/sidebar/index.json
  92. 3 0
      miniprogram_npm/vant-weapp/sidebar/index.wxml
  93. 1 0
      miniprogram_npm/vant-weapp/sidebar/index.wxss
  94. 1 0
      miniprogram_npm/vant-weapp/skeleton/index.d.ts
  95. 46 0
      miniprogram_npm/vant-weapp/skeleton/index.js
  96. 4 0
      miniprogram_npm/vant-weapp/skeleton/index.json
  97. 29 0
      miniprogram_npm/vant-weapp/skeleton/index.wxml
  98. 1 0
      miniprogram_npm/vant-weapp/skeleton/index.wxss
  99. 20 0
      miniprogram_npm/vant-weapp/slider/index.wxs
  100. 0 0
      miniprogram_npm/vant-weapp/sticky/index.d.ts

+ 7 - 5
app.js

@@ -16,11 +16,13 @@ App({
     //     this.globalData.height = res.statusBarHeight
     //   }
     // })
-    if (wx.cloud) {
-      wx.cloud.init({
-        traceUser: true
-      })
-    }
+
+    // 云服务的开启
+    // if (wx.cloud) {
+    //   wx.cloud.init({
+    //     traceUser: true
+    //   })
+    // }
     wx.getSystemInfo({
       success: e => {
         this.globalData.StatusBar = e.statusBarHeight;

+ 57 - 0
miniprogram_npm/vant-weapp/calendar/calendar.wxml

@@ -0,0 +1,57 @@
+<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>

+ 1 - 0
miniprogram_npm/vant-weapp/calendar/components/header/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 16 - 0
miniprogram_npm/vant-weapp/calendar/components/header/index.js

@@ -0,0 +1,16 @@
+import { VantComponent } from '../../../common/component';
+VantComponent({
+  props: {
+    title: {
+      type: String,
+      value: '日期选择',
+    },
+    subtitle: String,
+    showTitle: Boolean,
+    showSubtitle: Boolean,
+  },
+  data: {
+    weekdays: ['日', '一', '二', '三', '四', '五', '六'],
+  },
+  methods: {},
+});

+ 3 - 0
miniprogram_npm/vant-weapp/calendar/components/header/index.json

@@ -0,0 +1,3 @@
+{
+  "component": true
+}

+ 16 - 0
miniprogram_npm/vant-weapp/calendar/components/header/index.wxml

@@ -0,0 +1,16 @@
+<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>

File diff suppressed because it is too large
+ 1 - 0
miniprogram_npm/vant-weapp/calendar/components/header/index.wxss


+ 1 - 0
miniprogram_npm/vant-weapp/calendar/components/month/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 157 - 0
miniprogram_npm/vant-weapp/calendar/components/month/index.js

@@ -0,0 +1,157 @@
+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 '开始/结束';
+        }
+      }
+    },
+  },
+});

+ 3 - 0
miniprogram_npm/vant-weapp/calendar/components/month/index.json

@@ -0,0 +1,3 @@
+{
+  "component": true
+}

+ 39 - 0
miniprogram_npm/vant-weapp/calendar/components/month/index.wxml

@@ -0,0 +1,39 @@
+<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>

+ 67 - 0
miniprogram_npm/vant-weapp/calendar/components/month/index.wxs

@@ -0,0 +1,67 @@
+/* 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
+};

File diff suppressed because it is too large
+ 1 - 0
miniprogram_npm/vant-weapp/calendar/components/month/index.wxss


+ 1 - 0
miniprogram_npm/vant-weapp/calendar/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 290 - 0
miniprogram_npm/vant-weapp/calendar/index.js

@@ -0,0 +1,290 @@
+import { VantComponent } from '../common/component';
+import {
+  ROW_HEIGHT,
+  getNextDay,
+  compareDay,
+  copyDates,
+  calcDateNum,
+  formatMonthTitle,
+  compareMonth,
+  getMonths,
+  getDayByOffset,
+} from './utils';
+import Toast from '../toast/toast';
+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() {
+      setTimeout(() => {
+        const {
+          currentDate,
+          type,
+          show,
+          poppable,
+          minDate,
+          maxDate,
+        } = this.data;
+        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;
+        });
+      }, 100);
+    },
+    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') {
+        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;
+        const selected = currentDate.some((dateItem, index) => {
+          const equal = compareDay(dateItem, date) === 0;
+          if (equal) {
+            selectedIndex = index;
+          }
+          return equal;
+        });
+        if (selected) {
+          const cancelDate = currentDate.splice(selectedIndex, 1);
+          this.setData({ currentDate });
+          this.unselect(cancelDate);
+        } else {
+          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(() => {
+        this.$emit('confirm', copyDates(this.data.currentDate));
+      });
+    },
+  },
+});

+ 9 - 0
miniprogram_npm/vant-weapp/calendar/index.json

@@ -0,0 +1,9 @@
+{
+  "component": true,
+  "usingComponents": {
+    "header": "./components/header/index",
+    "month": "./components/month/index",
+    "van-button": "../button/index",
+    "van-popup": "../popup/index"
+  }
+}

+ 31 - 0
miniprogram_npm/vant-weapp/calendar/index.wxml

@@ -0,0 +1,31 @@
+<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" />

+ 37 - 0
miniprogram_npm/vant-weapp/calendar/index.wxs

@@ -0,0 +1,37 @@
+/* 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
+};

File diff suppressed because it is too large
+ 1 - 0
miniprogram_npm/vant-weapp/calendar/index.wxss


+ 17 - 0
miniprogram_npm/vant-weapp/calendar/utils.d.ts

@@ -0,0 +1,17 @@
+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): any[];

+ 78 - 0
miniprogram_npm/vant-weapp/calendar/utils.js

@@ -0,0 +1,78 @@
+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;
+}

+ 25 - 0
miniprogram_npm/vant-weapp/calendar/utils.wxs

@@ -0,0 +1,25 @@
+/* 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
+};

+ 20 - 0
miniprogram_npm/vant-weapp/checkbox/index.wxs

@@ -0,0 +1,20 @@
+/* eslint-disable */
+var utils = require('../wxs/utils.wxs');
+
+function iconStyle(checkedColor, value, disabled, parentDisabled, iconSize) {
+  var styles = [['font-size', utils.addUnit(iconSize)]];
+  if (checkedColor && value && !disabled && !parentDisabled) {
+    styles.push(['border-color', checkedColor]);
+    styles.push(['background-color', checkedColor]);
+  }
+
+  return styles
+    .map(function(item) {
+      return item.join(':');
+    })
+    .join(';');
+}
+
+module.exports = {
+  iconStyle: iconStyle
+};

+ 6 - 0
miniprogram_npm/vant-weapp/circle/canvas.d.ts

@@ -0,0 +1,6 @@
+/// <reference types="miniprogram-api-typings" />
+declare type CanvasContext = WechatMiniprogram.CanvasContext;
+export declare function adaptor(
+  ctx: CanvasRenderingContext2D
+): CanvasContext & CanvasRenderingContext2D;
+export {};

+ 43 - 0
miniprogram_npm/vant-weapp/circle/canvas.js

@@ -0,0 +1,43 @@
+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() {},
+  });
+}

+ 1 - 0
miniprogram_npm/vant-weapp/circle/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 176 - 0
miniprogram_npm/vant-weapp/circle/index.js

@@ -0,0 +1,176 @@
+import { VantComponent } from '../common/component';
+import { isObj } from '../common/utils';
+import { BLUE, WHITE } from '../common/color';
+import { adaptor } from './canvas';
+function format(rate) {
+  return Math.min(Math.max(rate, 0), 100);
+}
+const PERIMETER = 2 * Math.PI;
+const BEGIN_ANGLE = -Math.PI / 2;
+const STEP = 1;
+VantComponent({
+  props: {
+    text: String,
+    lineCap: {
+      type: String,
+      value: 'round',
+    },
+    value: {
+      type: Number,
+      value: 0,
+      observer: 'reRender',
+    },
+    speed: {
+      type: Number,
+      value: 50,
+    },
+    size: {
+      type: Number,
+      value: 100,
+      observer() {
+        this.drawCircle(this.currentValue);
+      },
+    },
+    fill: String,
+    layerColor: {
+      type: String,
+      value: WHITE,
+    },
+    color: {
+      type: [String, Object],
+      value: BLUE,
+      observer: 'setHoverColor',
+    },
+    type: {
+      type: String,
+      value: '',
+    },
+    strokeWidth: {
+      type: Number,
+      value: 4,
+    },
+    clockwise: {
+      type: Boolean,
+      value: true,
+    },
+  },
+  data: {
+    hoverColor: BLUE,
+  },
+  methods: {
+    getContext() {
+      const { type } = this.data;
+      if (type === '') {
+        const ctx = wx.createCanvasContext('van-circle', this);
+        return Promise.resolve(ctx);
+      }
+      const dpr = wx.getSystemInfoSync().pixelRatio;
+      return new Promise((resolve) => {
+        wx.createSelectorQuery()
+          .in(this)
+          .select('#van-circle')
+          .fields({ node: true, size: true })
+          .exec((res) => {
+            const canvas = res[0].node;
+            const ctx = canvas.getContext(type);
+            canvas.width = res[0].width * dpr;
+            canvas.height = res[0].height * dpr;
+            ctx.scale(dpr, dpr);
+            resolve(adaptor(ctx));
+          });
+      });
+    },
+    setHoverColor() {
+      const { color, size } = this.data;
+      let hoverColor = color;
+      this.getContext().then((context) => {
+        if (isObj(color)) {
+          const LinearColor = context.createLinearGradient(size, 0, 0, 0);
+          Object.keys(color)
+            .sort((a, b) => parseFloat(a) - parseFloat(b))
+            .map((key) =>
+              LinearColor.addColorStop(parseFloat(key) / 100, color[key])
+            );
+          hoverColor = LinearColor;
+        }
+        this.setData({ hoverColor });
+      });
+    },
+    presetCanvas(context, strokeStyle, beginAngle, endAngle, fill) {
+      const { strokeWidth, lineCap, clockwise, size, type } = this.data;
+      const position = size / 2;
+      const radius = position - strokeWidth / 2;
+      context.setStrokeStyle(strokeStyle);
+      context.setLineWidth(strokeWidth);
+      context.setLineCap(lineCap);
+      context.beginPath();
+      context.arc(position, position, radius, beginAngle, endAngle, !clockwise);
+      context.stroke();
+      if (fill) {
+        context.setFillStyle(fill);
+        context.fill();
+      }
+    },
+    renderLayerCircle(context) {
+      const { layerColor, fill } = this.data;
+      this.presetCanvas(context, layerColor, 0, PERIMETER, fill);
+    },
+    renderHoverCircle(context, formatValue) {
+      const { clockwise, hoverColor } = this.data;
+      // 结束角度
+      const progress = PERIMETER * (formatValue / 100);
+      const endAngle = clockwise
+        ? BEGIN_ANGLE + progress
+        : 3 * Math.PI - (BEGIN_ANGLE + progress);
+      this.presetCanvas(context, hoverColor, BEGIN_ANGLE, endAngle);
+    },
+    drawCircle(currentValue) {
+      const { size } = this.data;
+      this.getContext().then((context) => {
+        context.clearRect(0, 0, size, size);
+        this.renderLayerCircle(context);
+        const formatValue = format(currentValue);
+        if (formatValue !== 0) {
+          this.renderHoverCircle(context, formatValue);
+        }
+        context.draw();
+      });
+    },
+    reRender() {
+      // tofector 动画暂时没有想到好的解决方案
+      const { value, speed } = this.data;
+      if (speed <= 0 || speed > 1000) {
+        this.drawCircle(value);
+        return;
+      }
+      this.clearInterval();
+      this.currentValue = this.currentValue || 0;
+      this.interval = setInterval(() => {
+        if (this.currentValue !== value) {
+          if (this.currentValue < value) {
+            this.currentValue += STEP;
+          } else {
+            this.currentValue -= STEP;
+          }
+          this.drawCircle(this.currentValue);
+        } else {
+          this.clearInterval();
+        }
+      }, 1000 / speed);
+    },
+    clearInterval() {
+      if (this.interval) {
+        clearInterval(this.interval);
+        this.interval = null;
+      }
+    },
+  },
+  created() {
+    const { value } = this.data;
+    this.currentValue = value;
+    this.drawCircle(value);
+  },
+  destroyed() {
+    this.clearInterval();
+  },
+});

+ 3 - 0
miniprogram_npm/vant-weapp/circle/index.json

@@ -0,0 +1,3 @@
+{
+  "component": true
+}

+ 9 - 0
miniprogram_npm/vant-weapp/circle/index.wxml

@@ -0,0 +1,9 @@
+<wxs src="../wxs/utils.wxs" module="utils" />
+
+<view class="van-circle">
+  <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">
+    <slot></slot>
+  </view>
+  <cover-view wx:else class="van-circle__text">{{ text }}</cover-view>
+</view>

+ 1 - 0
miniprogram_npm/vant-weapp/circle/index.wxss

@@ -0,0 +1 @@
+@import '../common/index.wxss';.van-circle{position:relative;display:inline-block;text-align:center}.van-circle__text{position:absolute;top:50%;left:0;width:100%;-webkit-transform:translateY(-50%);transform:translateY(-50%);color:#323233;color:var(--circle-text-color,#323233)}

+ 0 - 0
miniprogram_npm/vant-weapp/common/style/theme.wxss


+ 2 - 0
miniprogram_npm/vant-weapp/common/version.d.ts

@@ -0,0 +1,2 @@
+export declare function canIUseModel(): boolean;
+export declare function canIUseFormFieldButton(): boolean;

+ 31 - 0
miniprogram_npm/vant-weapp/common/version.js

@@ -0,0 +1,31 @@
+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;
+}

+ 1 - 0
miniprogram_npm/vant-weapp/count-down/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 99 - 0
miniprogram_npm/vant-weapp/count-down/index.js

@@ -0,0 +1,99 @@
+import { VantComponent } from '../common/component';
+import { isSameSecond, parseFormat, parseTimeData } from './utils';
+function simpleTick(fn) {
+  return setTimeout(fn, 30);
+}
+VantComponent({
+  props: {
+    useSlot: Boolean,
+    millisecond: Boolean,
+    time: {
+      type: Number,
+      observer: 'reset',
+    },
+    format: {
+      type: String,
+      value: 'HH:mm:ss',
+    },
+    autoStart: {
+      type: Boolean,
+      value: true,
+    },
+  },
+  data: {
+    timeData: parseTimeData(0),
+    formattedTime: '0',
+  },
+  destroyed() {
+    clearTimeout(this.tid);
+    this.tid = null;
+  },
+  methods: {
+    // 开始
+    start() {
+      if (this.counting) {
+        return;
+      }
+      this.counting = true;
+      this.endTime = Date.now() + this.remain;
+      this.tick();
+    },
+    // 暂停
+    pause() {
+      this.counting = false;
+      clearTimeout(this.tid);
+    },
+    // 重置
+    reset() {
+      this.pause();
+      this.remain = this.data.time;
+      this.setRemain(this.remain);
+      if (this.data.autoStart) {
+        this.start();
+      }
+    },
+    tick() {
+      if (this.data.millisecond) {
+        this.microTick();
+      } else {
+        this.macroTick();
+      }
+    },
+    microTick() {
+      this.tid = simpleTick(() => {
+        this.setRemain(this.getRemain());
+        if (this.remain !== 0) {
+          this.microTick();
+        }
+      });
+    },
+    macroTick() {
+      this.tid = simpleTick(() => {
+        const remain = this.getRemain();
+        if (!isSameSecond(remain, this.remain) || remain === 0) {
+          this.setRemain(remain);
+        }
+        if (this.remain !== 0) {
+          this.macroTick();
+        }
+      });
+    },
+    getRemain() {
+      return Math.max(this.endTime - Date.now(), 0);
+    },
+    setRemain(remain) {
+      this.remain = remain;
+      const timeData = parseTimeData(remain);
+      if (this.data.useSlot) {
+        this.$emit('change', timeData);
+      }
+      this.setData({
+        formattedTime: parseFormat(this.data.format, timeData),
+      });
+      if (remain === 0) {
+        this.pause();
+        this.$emit('finish');
+      }
+    },
+  },
+});

+ 3 - 0
miniprogram_npm/vant-weapp/count-down/index.json

@@ -0,0 +1,3 @@
+{
+  "component": true
+}

+ 4 - 0
miniprogram_npm/vant-weapp/count-down/index.wxml

@@ -0,0 +1,4 @@
+<view class="van-count-down">
+  <slot wx:if="{{ useSlot }}"/>
+  <block wx:else>{{ formattedTime }}</block>
+</view>

+ 1 - 0
miniprogram_npm/vant-weapp/count-down/index.wxss

@@ -0,0 +1 @@
+@import '../common/index.wxss';.van-count-down{color:#323233;color:var(--count-down-text-color,#323233);font-size:14px;font-size:var(--count-down-font-size,14px);line-height:20px;line-height:var(--count-down-line-height,20px)}

+ 10 - 0
miniprogram_npm/vant-weapp/count-down/utils.d.ts

@@ -0,0 +1,10 @@
+export declare type TimeData = {
+    days: number;
+    hours: number;
+    minutes: number;
+    seconds: number;
+    milliseconds: number;
+};
+export declare function parseTimeData(time: number): TimeData;
+export declare function parseFormat(format: string, timeData: TimeData): string;
+export declare function isSameSecond(time1: number, time2: number): boolean;

+ 53 - 0
miniprogram_npm/vant-weapp/count-down/utils.js

@@ -0,0 +1,53 @@
+function padZero(num, targetLength = 2) {
+  let str = num + '';
+  while (str.length < targetLength) {
+    str = '0' + str;
+  }
+  return str;
+}
+const SECOND = 1000;
+const MINUTE = 60 * SECOND;
+const HOUR = 60 * MINUTE;
+const DAY = 24 * HOUR;
+export function parseTimeData(time) {
+  const days = Math.floor(time / DAY);
+  const hours = Math.floor((time % DAY) / HOUR);
+  const minutes = Math.floor((time % HOUR) / MINUTE);
+  const seconds = Math.floor((time % MINUTE) / SECOND);
+  const milliseconds = Math.floor(time % SECOND);
+  return {
+    days,
+    hours,
+    minutes,
+    seconds,
+    milliseconds,
+  };
+}
+export function parseFormat(format, timeData) {
+  const { days } = timeData;
+  let { hours, minutes, seconds, milliseconds } = timeData;
+  if (format.indexOf('DD') === -1) {
+    hours += days * 24;
+  } else {
+    format = format.replace('DD', padZero(days));
+  }
+  if (format.indexOf('HH') === -1) {
+    minutes += hours * 60;
+  } else {
+    format = format.replace('HH', padZero(hours));
+  }
+  if (format.indexOf('mm') === -1) {
+    seconds += minutes * 60;
+  } else {
+    format = format.replace('mm', padZero(minutes));
+  }
+  if (format.indexOf('ss') === -1) {
+    milliseconds += seconds * 1000;
+  } else {
+    format = format.replace('ss', padZero(seconds));
+  }
+  return format.replace('SSS', padZero(milliseconds, 3));
+}
+export function isSameSecond(time1, time2) {
+  return Math.floor(time1 / 1000) === Math.floor(time2 / 1000);
+}

+ 1 - 0
miniprogram_npm/vant-weapp/divider/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 1 - 0
miniprogram_npm/vant-weapp/dropdown-item/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 109 - 0
miniprogram_npm/vant-weapp/dropdown-item/index.js

@@ -0,0 +1,109 @@
+import { VantComponent } from '../common/component';
+VantComponent({
+  field: true,
+  relation: {
+    name: 'dropdown-menu',
+    type: 'ancestor',
+    current: 'dropdown-item',
+    linked() {
+      this.updateDataFromParent();
+    },
+  },
+  props: {
+    value: {
+      type: null,
+      observer: 'rerender',
+    },
+    title: {
+      type: String,
+      observer: 'rerender',
+    },
+    disabled: Boolean,
+    titleClass: {
+      type: String,
+      observer: 'rerender',
+    },
+    options: {
+      type: Array,
+      value: [],
+      observer: 'rerender',
+    },
+    popupStyle: String,
+  },
+  data: {
+    transition: true,
+    showPopup: false,
+    showWrapper: false,
+    displayTitle: '',
+  },
+  methods: {
+    rerender() {
+      wx.nextTick(() => {
+        this.parent && this.parent.updateItemListData();
+      });
+    },
+    updateDataFromParent() {
+      if (this.parent) {
+        const {
+          overlay,
+          duration,
+          activeColor,
+          closeOnClickOverlay,
+          direction,
+        } = this.parent.data;
+        this.setData({
+          overlay,
+          duration,
+          activeColor,
+          closeOnClickOverlay,
+          direction,
+        });
+      }
+    },
+    onOpen() {
+      this.$emit('open');
+    },
+    onOpened() {
+      this.$emit('opened');
+    },
+    onClose() {
+      this.$emit('close');
+    },
+    onClosed() {
+      this.$emit('closed');
+      this.setData({ showWrapper: false });
+    },
+    onOptionTap(event) {
+      const { option } = event.currentTarget.dataset;
+      const { value } = option;
+      const shouldEmitChange = this.data.value !== value;
+      this.setData({ showPopup: false, value });
+      this.$emit('close');
+      this.rerender();
+      if (shouldEmitChange) {
+        this.$emit('change', value);
+      }
+    },
+    toggle(show, options = {}) {
+      const { showPopup } = this.data;
+      if (typeof show !== 'boolean') {
+        show = !showPopup;
+      }
+      if (show === showPopup) {
+        return;
+      }
+      this.setData({
+        transition: !options.immediate,
+        showPopup: show,
+      });
+      if (show) {
+        this.parent.getChildWrapperStyle().then((wrapperStyle) => {
+          this.setData({ wrapperStyle, showWrapper: true });
+          this.rerender();
+        });
+      } else {
+        this.rerender();
+      }
+    },
+  },
+});

+ 8 - 0
miniprogram_npm/vant-weapp/dropdown-item/index.json

@@ -0,0 +1,8 @@
+{
+  "component": true,
+  "usingComponents": {
+    "van-popup": "../popup/index",
+    "van-cell": "../cell/index",
+    "van-icon": "../icon/index"
+  }
+}

+ 48 - 0
miniprogram_npm/vant-weapp/dropdown-item/index.wxml

@@ -0,0 +1,48 @@
+<wxs src="../wxs/utils.wxs" module="utils" />
+
+<view
+  wx:if="{{ showWrapper }}"
+  class="{{ utils.bem('dropdown-item', direction) }}"
+  style="{{ wrapperStyle }}"
+>
+  <van-popup
+    show="{{ showPopup }}"
+    custom-style="position: absolute;{{ popupStyle }}"
+    overlay-style="position: absolute;"
+    overlay="{{ overlay }}"
+    position="{{ direction === 'down' ? 'top' : 'bottom' }}"
+    duration="{{ transition ? duration : 0 }}"
+    close-on-click-overlay="{{ closeOnClickOverlay }}"
+    bind:enter="onOpen"
+    bind:leave="onClose"
+    bind:close="toggle"
+    bind:after-enter="onOpened"
+    bind:after-leave="onClosed"
+  >
+    <van-cell
+      wx:for="{{ options }}"
+      wx:key="value"
+      data-option="{{ item }}"
+      class="{{ utils.bem('dropdown-item__option', { active: item.value === value } ) }}"
+      clickable
+      icon="{{ item.icon }}"
+      bind:tap="onOptionTap"
+    >
+      <view
+        slot="title"
+        class="van-dropdown-item__title"
+        style="{{ item.value === value  ? 'color:' + activeColor : '' }}"
+      >
+        {{ item.text }}
+      </view>
+      <van-icon
+        wx:if="{{ item.value === value }}"
+        name="success"
+        class="van-dropdown-item__icon"
+        color="{{ activeColor }}"
+      />
+    </van-cell>
+
+    <slot />
+  </van-popup>
+</view>

+ 1 - 0
miniprogram_npm/vant-weapp/dropdown-item/index.wxss

@@ -0,0 +1 @@
+@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}

+ 1 - 0
miniprogram_npm/vant-weapp/dropdown-menu/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 119 - 0
miniprogram_npm/vant-weapp/dropdown-menu/index.js

@@ -0,0 +1,119 @@
+import { VantComponent } from '../common/component';
+import { addUnit } from '../common/utils';
+let ARRAY = [];
+VantComponent({
+  field: true,
+  relation: {
+    name: 'dropdown-item',
+    type: 'descendant',
+    current: 'dropdown-menu',
+    linked() {
+      this.updateItemListData();
+    },
+    unlinked() {
+      this.updateItemListData();
+    },
+  },
+  props: {
+    activeColor: {
+      type: String,
+      observer: 'updateChildrenData',
+    },
+    overlay: {
+      type: Boolean,
+      value: true,
+      observer: 'updateChildrenData',
+    },
+    zIndex: {
+      type: Number,
+      value: 10,
+    },
+    duration: {
+      type: Number,
+      value: 200,
+      observer: 'updateChildrenData',
+    },
+    direction: {
+      type: String,
+      value: 'down',
+      observer: 'updateChildrenData',
+    },
+    closeOnClickOverlay: {
+      type: Boolean,
+      value: true,
+      observer: 'updateChildrenData',
+    },
+    closeOnClickOutside: {
+      type: Boolean,
+      value: true,
+    },
+  },
+  data: {
+    itemListData: [],
+  },
+  beforeCreate() {
+    const { windowHeight } = wx.getSystemInfoSync();
+    this.windowHeight = windowHeight;
+    ARRAY.push(this);
+  },
+  destroyed() {
+    ARRAY = ARRAY.filter((item) => item !== this);
+  },
+  methods: {
+    updateItemListData() {
+      this.setData({
+        itemListData: this.children.map((child) => child.data),
+      });
+    },
+    updateChildrenData() {
+      this.children.forEach((child) => {
+        child.updateDataFromParent();
+      });
+    },
+    toggleItem(active) {
+      this.children.forEach((item, index) => {
+        const { showPopup } = item.data;
+        if (index === active) {
+          item.toggle();
+        } else if (showPopup) {
+          item.toggle(false, { immediate: true });
+        }
+      });
+    },
+    close() {
+      this.children.forEach((child) => {
+        child.toggle(false, { immediate: true });
+      });
+    },
+    getChildWrapperStyle() {
+      const { zIndex, direction } = this.data;
+      return this.getRect('.van-dropdown-menu').then((rect) => {
+        const { top = 0, bottom = 0 } = rect;
+        const offset = direction === 'down' ? bottom : this.windowHeight - top;
+        let wrapperStyle = `z-index: ${zIndex};`;
+        if (direction === 'down') {
+          wrapperStyle += `top: ${addUnit(offset)};`;
+        } else {
+          wrapperStyle += `bottom: ${addUnit(offset)};`;
+        }
+        return wrapperStyle;
+      });
+    },
+    onTitleTap(event) {
+      const { index } = event.currentTarget.dataset;
+      const child = this.children[index];
+      if (!child.data.disabled) {
+        ARRAY.forEach((menuItem) => {
+          if (
+            menuItem &&
+            menuItem.data.closeOnClickOutside &&
+            menuItem !== this
+          ) {
+            menuItem.close();
+          }
+        });
+        this.toggleItem(index);
+      }
+    },
+  },
+});

+ 3 - 0
miniprogram_npm/vant-weapp/dropdown-menu/index.json

@@ -0,0 +1,3 @@
+{
+  "component": true
+}

+ 23 - 0
miniprogram_npm/vant-weapp/dropdown-menu/index.wxml

@@ -0,0 +1,23 @@
+<wxs src="../wxs/utils.wxs" module="utils" />
+<wxs src="./index.wxs" module="computed" />
+
+<view class="van-dropdown-menu van-dropdown-menu--top-bottom">
+  <view
+    wx:for="{{ itemListData }}"
+    wx:key="index"
+    data-index="{{ index }}"
+    class="{{ utils.bem('dropdown-menu__item', { disabled: item.disabled }) }}"
+    bind:tap="onTitleTap"
+  >
+    <view
+      class="{{ item.titleClass }} {{ utils.bem('dropdown-menu__title', { active: item.showPopup, down: item.showPopup === (direction === 'down') }) }}"
+      style="{{ item.showPopup ? 'color:' + activeColor : '' }}"
+    >
+      <view class="van-ellipsis">
+        {{ computed.displayTitle(item) }}
+      </view>
+    </view>
+  </view>
+
+  <slot />
+</view>

+ 16 - 0
miniprogram_npm/vant-weapp/dropdown-menu/index.wxs

@@ -0,0 +1,16 @@
+/* eslint-disable */
+function displayTitle(item) {
+  if (item.title) {
+    return item.title;
+  }
+
+  var match = item.options.filter(function(option) {
+    return option.value === item.value;
+  });
+  var displayTitle = match.length ? match[0].text : '';
+  return displayTitle;
+}
+
+module.exports = {
+  displayTitle: displayTitle
+};

File diff suppressed because it is too large
+ 1 - 0
miniprogram_npm/vant-weapp/dropdown-menu/index.wxss


+ 21 - 0
miniprogram_npm/vant-weapp/field/index.wxs

@@ -0,0 +1,21 @@
+/* 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
+};

+ 58 - 0
miniprogram_npm/vant-weapp/field/props.d.ts

@@ -0,0 +1,58 @@
+export declare const commonProps: {
+    value: {
+        type: StringConstructor;
+        observer(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;
+    };
+};

+ 63 - 0
miniprogram_npm/vant-weapp/field/props.js

@@ -0,0 +1,63 @@
+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,
+  },
+};

+ 1 - 0
miniprogram_npm/vant-weapp/grid-item/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 82 - 0
miniprogram_npm/vant-weapp/grid-item/index.js

@@ -0,0 +1,82 @@
+import { link } from '../mixins/link';
+import { VantComponent } from '../common/component';
+import { addUnit } from '../common/utils';
+VantComponent({
+  relation: {
+    name: 'grid',
+    type: 'ancestor',
+    current: 'grid-item',
+  },
+  classes: ['content-class', 'icon-class', 'text-class'],
+  mixins: [link],
+  props: {
+    icon: String,
+    dot: Boolean,
+    info: null,
+    badge: null,
+    text: String,
+    useSlot: Boolean,
+  },
+  data: {
+    viewStyle: '',
+  },
+  mounted() {
+    this.updateStyle();
+  },
+  methods: {
+    updateStyle() {
+      if (!this.parent) {
+        return;
+      }
+      const { data, children } = this.parent;
+      const {
+        columnNum,
+        border,
+        square,
+        gutter,
+        clickable,
+        center,
+        direction,
+        iconSize,
+      } = data;
+      const width = `${100 / columnNum}%`;
+      const styleWrapper = [];
+      styleWrapper.push(`width: ${width}`);
+      if (square) {
+        styleWrapper.push(`padding-top: ${width}`);
+      }
+      if (gutter) {
+        const gutterValue = addUnit(gutter);
+        styleWrapper.push(`padding-right: ${gutterValue}`);
+        const index = children.indexOf(this);
+        if (index >= columnNum && !square) {
+          styleWrapper.push(`margin-top: ${gutterValue}`);
+        }
+      }
+      let contentStyle = '';
+      if (square && gutter) {
+        const gutterValue = addUnit(gutter);
+        contentStyle = `
+          right: ${gutterValue};
+          bottom: ${gutterValue};
+          height: auto;
+        `;
+      }
+      this.setData({
+        viewStyle: styleWrapper.join('; '),
+        contentStyle,
+        center,
+        border,
+        square,
+        gutter,
+        clickable,
+        direction,
+        iconSize,
+      });
+    },
+    onClick() {
+      this.$emit('click');
+      this.jumpLink();
+    },
+  },
+});

+ 6 - 0
miniprogram_npm/vant-weapp/grid-item/index.json

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

+ 22 - 0
miniprogram_npm/vant-weapp/grid-item/index.wxml

@@ -0,0 +1,22 @@
+<wxs src="../wxs/utils.wxs" module="utils" />
+
+<view class="custom-class {{ utils.bem('grid-item', { square }) }}" style="{{ viewStyle }}" bindtap="onClick">
+  <view
+    class="content-class {{ utils.bem('grid-item__content', [direction, { center, square, clickable, surround: border && gutter }]) }} {{ border ? 'van-hairline--surround' : '' }}"
+    style="{{ contentStyle }}"
+  >
+    <block wx:if="{{ useSlot }}">
+      <slot />
+    </block>
+    <block wx:else>
+      <view class="van-grid-item__icon icon-class">
+        <van-icon wx:if="{{ icon }}" name="{{ icon }}" dot="{{ dot }}" info="{{ badge || info }}" size="{{ iconSize }}" />
+        <slot wx:else name="icon"></slot>
+      </view>
+      <view class="van-grid-item__text text-class">
+        <text wx:if="{{ text }}">{{ text }}</text>
+        <slot wx:else name="text"></slot>
+      </view>
+    </block>
+  </view>
+</view>

File diff suppressed because it is too large
+ 1 - 0
miniprogram_npm/vant-weapp/grid-item/index.wxss


+ 1 - 0
miniprogram_npm/vant-weapp/grid/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 65 - 0
miniprogram_npm/vant-weapp/grid/index.js

@@ -0,0 +1,65 @@
+import { VantComponent } from '../common/component';
+import { addUnit } from '../common/utils';
+VantComponent({
+  relation: {
+    name: 'grid-item',
+    type: 'descendant',
+    current: 'grid',
+  },
+  props: {
+    square: {
+      type: Boolean,
+      observer: 'updateChildren',
+    },
+    gutter: {
+      type: [Number, String],
+      value: 0,
+      observer: 'updateChildren',
+    },
+    clickable: {
+      type: Boolean,
+      observer: 'updateChildren',
+    },
+    columnNum: {
+      type: Number,
+      value: 4,
+      observer: 'updateChildren',
+    },
+    center: {
+      type: Boolean,
+      value: true,
+      observer: 'updateChildren',
+    },
+    border: {
+      type: Boolean,
+      value: true,
+      observer: 'updateChildren',
+    },
+    direction: {
+      type: String,
+      observer: 'updateChildren',
+    },
+    iconSize: {
+      type: String,
+      observer: 'updateChildren',
+    },
+  },
+  data: {
+    viewStyle: '',
+  },
+  created() {
+    const { gutter } = this.data;
+    if (gutter) {
+      this.setData({
+        viewStyle: `padding-left: ${addUnit(gutter)}`,
+      });
+    }
+  },
+  methods: {
+    updateChildren() {
+      this.children.forEach((child) => {
+        child.updateStyle();
+      });
+    },
+  },
+});

+ 3 - 0
miniprogram_npm/vant-weapp/grid/index.json

@@ -0,0 +1,3 @@
+{
+  "component": true
+}

+ 3 - 0
miniprogram_npm/vant-weapp/grid/index.wxml

@@ -0,0 +1,3 @@
+<view class="van-grid custom-class {{ border && !gutter ? 'van-hairline--top' : '' }}" style="{{ viewStyle }}">
+  <slot />
+</view>

+ 1 - 0
miniprogram_npm/vant-weapp/grid/index.wxss

@@ -0,0 +1 @@
+@import '../common/index.wxss';.van-grid{position:relative;box-sizing:border-box;overflow:hidden}

+ 1 - 0
miniprogram_npm/vant-weapp/image/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 101 - 0
miniprogram_npm/vant-weapp/image/index.js

@@ -0,0 +1,101 @@
+import { addUnit, isDef } from '../common/utils';
+import { VantComponent } from '../common/component';
+import { button } from '../mixins/button';
+import { openType } from '../mixins/open-type';
+const FIT_MODE_MAP = {
+  none: 'center',
+  fill: 'scaleToFill',
+  cover: 'aspectFill',
+  contain: 'aspectFit',
+  widthFix: 'widthFix',
+  heightFix: 'heightFix',
+};
+VantComponent({
+  mixins: [button, openType],
+  classes: ['custom-class', 'loading-class', 'error-class', 'image-class'],
+  props: {
+    src: {
+      type: String,
+      observer() {
+        this.setData({
+          error: false,
+          loading: true,
+        });
+      },
+    },
+    round: Boolean,
+    width: {
+      type: null,
+      observer: 'setStyle',
+    },
+    height: {
+      type: null,
+      observer: 'setStyle',
+    },
+    radius: null,
+    lazyLoad: Boolean,
+    useErrorSlot: Boolean,
+    useLoadingSlot: Boolean,
+    showMenuByLongpress: Boolean,
+    fit: {
+      type: String,
+      value: 'fill',
+      observer: 'setMode',
+    },
+    showError: {
+      type: Boolean,
+      value: true,
+    },
+    showLoading: {
+      type: Boolean,
+      value: true,
+    },
+  },
+  data: {
+    error: false,
+    loading: true,
+    viewStyle: '',
+  },
+  mounted() {
+    this.setMode();
+    this.setStyle();
+  },
+  methods: {
+    setMode() {
+      this.setData({
+        mode: FIT_MODE_MAP[this.data.fit],
+      });
+    },
+    setStyle() {
+      const { width, height, radius } = this.data;
+      let style = '';
+      if (isDef(width)) {
+        style += `width: ${addUnit(width)};`;
+      }
+      if (isDef(height)) {
+        style += `height: ${addUnit(height)};`;
+      }
+      if (isDef(radius)) {
+        style += 'overflow: hidden;';
+        style += `border-radius: ${addUnit(radius)};`;
+      }
+      this.setData({ viewStyle: style });
+    },
+    onLoad(event) {
+      this.setData({
+        loading: false,
+      });
+      this.$emit('load', event.detail);
+    },
+    onError(event) {
+      this.setData({
+        loading: false,
+        error: true,
+      });
+      this.$emit('error', event.detail);
+    },
+    onClick(event) {
+      this.$emit('click', event.detail);
+    },
+  },
+});

+ 7 - 0
miniprogram_npm/vant-weapp/image/index.json

@@ -0,0 +1,7 @@
+{
+  "component": true,
+  "usingComponents": {
+    "van-icon": "../icon/index",
+    "van-loading": "../loading/index"
+  }
+}

+ 33 - 0
miniprogram_npm/vant-weapp/image/index.wxml

@@ -0,0 +1,33 @@
+<wxs src="../wxs/utils.wxs" module="utils" />
+
+<view
+  style="{{ viewStyle }}"
+  class="custom-class {{ utils.bem('image', { round })}}"
+  bind:tap="onClick"
+>
+  <image
+    wx:if="{{ !error }}"
+    src="{{ src }}"
+    mode="{{ mode }}"
+    lazy-load="{{ lazyLoad }}"
+    class="image-class van-image__img"
+    show-menu-by-longpress="{{ showMenuByLongpress }}"
+    bind:load="onLoad"
+    bind:error="onError"
+  />
+
+  <view
+    wx:if="{{ loading && showLoading }}"
+    class="loading-class van-image__loading"
+  >
+    <slot wx:if="{{ useLoadingSlot }}" name="loading" />
+    <van-icon wx:else name="photo-o" size="22" />
+  </view>
+  <view
+    wx:if="{{ error && showError }}"
+    class="error-class van-image__error"
+  >
+    <slot wx:if="{{ useErrorSlot }}" name="error" />
+    <van-icon wx:else name="warning-o" size="22" />
+  </view>
+</view>

File diff suppressed because it is too large
+ 1 - 0
miniprogram_npm/vant-weapp/image/index.wxss


+ 1 - 0
miniprogram_npm/vant-weapp/index-anchor/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 30 - 0
miniprogram_npm/vant-weapp/index-anchor/index.js

@@ -0,0 +1,30 @@
+import { VantComponent } from '../common/component';
+VantComponent({
+  relation: {
+    name: 'index-bar',
+    type: 'ancestor',
+    current: 'index-anchor',
+  },
+  props: {
+    useSlot: Boolean,
+    index: null,
+  },
+  data: {
+    active: false,
+    wrapperStyle: '',
+    anchorStyle: '',
+  },
+  methods: {
+    scrollIntoView(scrollTop) {
+      this.getBoundingClientRect().then((rect) => {
+        wx.pageScrollTo({
+          duration: 0,
+          scrollTop: scrollTop + rect.top - this.parent.data.stickyOffsetTop,
+        });
+      });
+    },
+    getBoundingClientRect() {
+      return this.getRect('.van-index-anchor-wrapper');
+    },
+  },
+});

+ 3 - 0
miniprogram_npm/vant-weapp/index-anchor/index.json

@@ -0,0 +1,3 @@
+{
+  "component": true
+}

+ 14 - 0
miniprogram_npm/vant-weapp/index-anchor/index.wxml

@@ -0,0 +1,14 @@
+<view
+  class="van-index-anchor-wrapper"
+  style="{{ wrapperStyle }}"
+>
+  <view
+    class="van-index-anchor {{ active ? 'van-index-anchor--active van-hairline--bottom' : '' }}"
+    style="{{ anchorStyle }}"
+  >
+    <slot wx:if="{{ useSlot }}"/>
+    <block wx:else>
+      <text>{{ index }}</text>
+    </block>
+  </view>
+</view>

File diff suppressed because it is too large
+ 1 - 0
miniprogram_npm/vant-weapp/index-anchor/index.wxss


+ 1 - 0
miniprogram_npm/vant-weapp/index-bar/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 250 - 0
miniprogram_npm/vant-weapp/index-bar/index.js

@@ -0,0 +1,250 @@
+import { VantComponent } from '../common/component';
+import { GREEN } from '../common/color';
+import { pageScrollMixin } from '../mixins/page-scroll';
+const indexList = () => {
+  const indexList = [];
+  const charCodeOfA = 'A'.charCodeAt(0);
+  for (let i = 0; i < 26; i++) {
+    indexList.push(String.fromCharCode(charCodeOfA + i));
+  }
+  return indexList;
+};
+VantComponent({
+  relation: {
+    name: 'index-anchor',
+    type: 'descendant',
+    current: 'index-bar',
+    linked() {
+      this.updateData();
+    },
+    unlinked() {
+      this.updateData();
+    },
+  },
+  props: {
+    sticky: {
+      type: Boolean,
+      value: true,
+    },
+    zIndex: {
+      type: Number,
+      value: 1,
+    },
+    highlightColor: {
+      type: String,
+      value: GREEN,
+    },
+    stickyOffsetTop: {
+      type: Number,
+      value: 0,
+    },
+    indexList: {
+      type: Array,
+      value: indexList(),
+    },
+  },
+  mixins: [
+    pageScrollMixin(function (event) {
+      this.scrollTop = event.scrollTop || 0;
+      this.onScroll();
+    }),
+  ],
+  data: {
+    activeAnchorIndex: null,
+    showSidebar: false,
+  },
+  created() {
+    this.scrollTop = 0;
+  },
+  methods: {
+    updateData() {
+      wx.nextTick(() => {
+        if (this.timer != null) {
+          clearTimeout(this.timer);
+        }
+        this.timer = setTimeout(() => {
+          this.setData({
+            showSidebar: !!this.children.length,
+          });
+          this.setRect().then(() => {
+            this.onScroll();
+          });
+        }, 0);
+      });
+    },
+    setRect() {
+      return Promise.all([
+        this.setAnchorsRect(),
+        this.setListRect(),
+        this.setSiderbarRect(),
+      ]);
+    },
+    setAnchorsRect() {
+      return Promise.all(
+        this.children.map((anchor) =>
+          anchor.getRect('.van-index-anchor-wrapper').then((rect) => {
+            Object.assign(anchor, {
+              height: rect.height,
+              top: rect.top + this.scrollTop,
+            });
+          })
+        )
+      );
+    },
+    setListRect() {
+      return this.getRect('.van-index-bar').then((rect) => {
+        Object.assign(this, {
+          height: rect.height,
+          top: rect.top + this.scrollTop,
+        });
+      });
+    },
+    setSiderbarRect() {
+      return this.getRect('.van-index-bar__sidebar').then((res) => {
+        this.sidebar = {
+          height: res.height,
+          top: res.top,
+        };
+      });
+    },
+    setDiffData({ target, data }) {
+      const diffData = {};
+      Object.keys(data).forEach((key) => {
+        if (target.data[key] !== data[key]) {
+          diffData[key] = data[key];
+        }
+      });
+      if (Object.keys(diffData).length) {
+        target.setData(diffData);
+      }
+    },
+    getAnchorRect(anchor) {
+      return anchor.getRect('.van-index-anchor-wrapper').then((rect) => ({
+        height: rect.height,
+        top: rect.top,
+      }));
+    },
+    getActiveAnchorIndex() {
+      const { children, scrollTop } = this;
+      const { sticky, stickyOffsetTop } = this.data;
+      for (let i = this.children.length - 1; i >= 0; i--) {
+        const preAnchorHeight = i > 0 ? children[i - 1].height : 0;
+        const reachTop = sticky ? preAnchorHeight + stickyOffsetTop : 0;
+        if (reachTop + scrollTop >= children[i].top) {
+          return i;
+        }
+      }
+      return -1;
+    },
+    onScroll() {
+      const { children = [], scrollTop } = this;
+      if (!children.length) {
+        return;
+      }
+      const { sticky, stickyOffsetTop, zIndex, highlightColor } = this.data;
+      const active = this.getActiveAnchorIndex();
+      this.setDiffData({
+        target: this,
+        data: {
+          activeAnchorIndex: active,
+        },
+      });
+      if (sticky) {
+        let isActiveAnchorSticky = false;
+        if (active !== -1) {
+          isActiveAnchorSticky =
+            children[active].top <= stickyOffsetTop + scrollTop;
+        }
+        children.forEach((item, index) => {
+          if (index === active) {
+            let wrapperStyle = '';
+            let anchorStyle = `
+              color: ${highlightColor};
+            `;
+            if (isActiveAnchorSticky) {
+              wrapperStyle = `
+                height: ${children[index].height}px;
+              `;
+              anchorStyle = `
+                position: fixed;
+                top: ${stickyOffsetTop}px;
+                z-index: ${zIndex};
+                color: ${highlightColor};
+              `;
+            }
+            this.setDiffData({
+              target: item,
+              data: {
+                active: true,
+                anchorStyle,
+                wrapperStyle,
+              },
+            });
+          } else if (index === active - 1) {
+            const currentAnchor = children[index];
+            const currentOffsetTop = currentAnchor.top;
+            const targetOffsetTop =
+              index === children.length - 1
+                ? this.top
+                : children[index + 1].top;
+            const parentOffsetHeight = targetOffsetTop - currentOffsetTop;
+            const translateY = parentOffsetHeight - currentAnchor.height;
+            const anchorStyle = `
+              position: relative;
+              transform: translate3d(0, ${translateY}px, 0);
+              z-index: ${zIndex};
+              color: ${highlightColor};
+            `;
+            this.setDiffData({
+              target: item,
+              data: {
+                active: true,
+                anchorStyle,
+              },
+            });
+          } else {
+            this.setDiffData({
+              target: item,
+              data: {
+                active: false,
+                anchorStyle: '',
+                wrapperStyle: '',
+              },
+            });
+          }
+        });
+      }
+    },
+    onClick(event) {
+      this.scrollToAnchor(event.target.dataset.index);
+    },
+    onTouchMove(event) {
+      const sidebarLength = this.children.length;
+      const touch = event.touches[0];
+      const itemHeight = this.sidebar.height / sidebarLength;
+      let index = Math.floor((touch.clientY - this.sidebar.top) / itemHeight);
+      if (index < 0) {
+        index = 0;
+      } else if (index > sidebarLength - 1) {
+        index = sidebarLength - 1;
+      }
+      this.scrollToAnchor(index);
+    },
+    onTouchStop() {
+      this.scrollToAnchorIndex = null;
+    },
+    scrollToAnchor(index) {
+      if (typeof index !== 'number' || this.scrollToAnchorIndex === index) {
+        return;
+      }
+      this.scrollToAnchorIndex = index;
+      const anchor = this.children.find(
+        (item) => item.data.index === this.data.indexList[index]
+      );
+      if (anchor) {
+        anchor.scrollIntoView(this.scrollTop);
+        this.$emit('select', anchor.data.index);
+      }
+    },
+  },
+});

+ 3 - 0
miniprogram_npm/vant-weapp/index-bar/index.json

@@ -0,0 +1,3 @@
+{
+  "component": true
+}

+ 22 - 0
miniprogram_npm/vant-weapp/index-bar/index.wxml

@@ -0,0 +1,22 @@
+<view class="van-index-bar">
+  <slot />
+
+  <view
+    wx:if="{{ showSidebar }}"
+    class="van-index-bar__sidebar"
+    catch:tap="onClick"
+    catch:touchmove="onTouchMove"
+    catch:touchend="onTouchStop"
+    catch:touchcancel="onTouchStop"
+  >
+    <view
+      wx:for="{{ indexList }}"
+      wx:key="index"
+      class="van-index-bar__index"
+      style="z-index: {{ zIndex + 1 }}; color: {{ activeAnchorIndex === index ? highlightColor : '' }}"
+      data-index="{{ index }}"
+    >
+      {{ item }}
+    </view>
+  </view>
+</view>

File diff suppressed because it is too large
+ 1 - 0
miniprogram_npm/vant-weapp/index-bar/index.wxss


+ 5 - 0
miniprogram_npm/vant-weapp/mixins/page-scroll.d.ts

@@ -0,0 +1,5 @@
+/// <reference types="miniprogram-api-typings" />
+declare type IPageScrollOption = WechatMiniprogram.Page.IPageScrollOption;
+declare type Scroller = (event: IPageScrollOption) => void;
+export declare const pageScrollMixin: (scroller: Scroller) => string;
+export {};

+ 33 - 0
miniprogram_npm/vant-weapp/mixins/page-scroll.js

@@ -0,0 +1,33 @@
+function getCurrentPage() {
+  const pages = getCurrentPages();
+  return pages[pages.length - 1] || {};
+}
+function onPageScroll(event) {
+  const { vanPageScroller = [] } = getCurrentPage();
+  vanPageScroller.forEach((scroller) => {
+    if (typeof scroller === 'function') {
+      scroller(event);
+    }
+  });
+}
+export const pageScrollMixin = (scroller) =>
+  Behavior({
+    attached() {
+      const page = getCurrentPage();
+      if (Array.isArray(page.vanPageScroller)) {
+        page.vanPageScroller.push(scroller.bind(this));
+      } else {
+        page.vanPageScroller =
+          typeof page.onPageScroll === 'function'
+            ? [page.onPageScroll.bind(page), scroller.bind(this)]
+            : [scroller.bind(this)];
+      }
+      page.onPageScroll = onPageScroll;
+    },
+    detached() {
+      const page = getCurrentPage();
+      page.vanPageScroller = (page.vanPageScroller || []).filter(
+        (item) => item !== scroller
+      );
+    },
+  });

+ 28 - 0
miniprogram_npm/vant-weapp/picker/toolbar.wxml

@@ -0,0 +1,28 @@
+<template name="toolbar">
+  <view
+    wx:if="{{ showToolbar }}"
+    class="van-picker__toolbar van-hairline--top-bottom toolbar-class"
+  >
+    <view
+      class="van-picker__cancel"
+      hover-class="van-picker__cancel--hover"
+      hover-stay-time="70"
+      data-type="cancel"
+      bindtap="emit"
+    >
+      {{ cancelButtonText }}
+    </view>
+    <view wx:if="{{ title }}" class="van-picker__title van-ellipsis">{{
+      title
+    }}</view>
+    <view
+      class="van-picker__confirm"
+      hover-class="van-picker__confirm--hover"
+      hover-stay-time="70"
+      data-type="confirm"
+      bindtap="emit"
+    >
+      {{ confirmButtonText }}
+    </view>
+  </view>
+</template>

+ 1 - 0
miniprogram_npm/vant-weapp/sidebar-item/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 31 - 0
miniprogram_npm/vant-weapp/sidebar-item/index.js

@@ -0,0 +1,31 @@
+import { VantComponent } from '../common/component';
+VantComponent({
+  classes: ['active-class', 'disabled-class'],
+  relation: {
+    type: 'ancestor',
+    name: 'sidebar',
+    current: 'sidebar-item',
+  },
+  props: {
+    dot: Boolean,
+    info: null,
+    title: String,
+    disabled: Boolean,
+  },
+  methods: {
+    onClick() {
+      const { parent } = this;
+      if (!parent || this.data.disabled) {
+        return;
+      }
+      const index = parent.children.indexOf(this);
+      parent.setActive(index).then(() => {
+        this.$emit('click', index);
+        parent.$emit('change', index);
+      });
+    },
+    setActive(selected) {
+      return this.setData({ selected });
+    },
+  },
+});

+ 6 - 0
miniprogram_npm/vant-weapp/sidebar-item/index.json

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

+ 19 - 0
miniprogram_npm/vant-weapp/sidebar-item/index.wxml

@@ -0,0 +1,19 @@
+<wxs src="../wxs/utils.wxs" module="utils" />
+
+<view
+  class="{{ utils.bem('sidebar-item', { selected, disabled }) }} {{ selected ? 'active-class' : '' }} {{ disabled ? 'disabled-class' : '' }} custom-class"
+  hover-class="van-sidebar-item--hover"
+  hover-stay-time="70"
+  bind:tap="onClick"
+>
+  <view class="van-sidebar-item__text">
+    <van-info
+      wx:if="{{ info !== null || dot }}"
+      dot="{{ dot }}"
+      info="{{ info }}"
+      custom-style="right: 4px"
+    />
+    <view wx:if="{{ title }}">{{ title }}</view>
+    <slot wx:else name="title" />
+  </view>
+</view>

File diff suppressed because it is too large
+ 1 - 0
miniprogram_npm/vant-weapp/sidebar-item/index.wxss


+ 1 - 0
miniprogram_npm/vant-weapp/sidebar/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 41 - 0
miniprogram_npm/vant-weapp/sidebar/index.js

@@ -0,0 +1,41 @@
+import { VantComponent } from '../common/component';
+VantComponent({
+  relation: {
+    name: 'sidebar-item',
+    type: 'descendant',
+    current: 'sidebar',
+    linked() {
+      this.setActive(this.data.activeKey);
+    },
+    unlinked() {
+      this.setActive(this.data.activeKey);
+    },
+  },
+  props: {
+    activeKey: {
+      type: Number,
+      value: 0,
+      observer: 'setActive',
+    },
+  },
+  beforeCreate() {
+    this.currentActive = -1;
+  },
+  methods: {
+    setActive(activeKey) {
+      const { children, currentActive } = this;
+      if (!children.length) {
+        return Promise.resolve();
+      }
+      this.currentActive = activeKey;
+      const stack = [];
+      if (currentActive !== activeKey && children[currentActive]) {
+        stack.push(children[currentActive].setActive(false));
+      }
+      if (children[activeKey]) {
+        stack.push(children[activeKey].setActive(true));
+      }
+      return Promise.all(stack);
+    },
+  },
+});

+ 3 - 0
miniprogram_npm/vant-weapp/sidebar/index.json

@@ -0,0 +1,3 @@
+{
+  "component": true
+}

+ 3 - 0
miniprogram_npm/vant-weapp/sidebar/index.wxml

@@ -0,0 +1,3 @@
+<view class="van-sidebar custom-class">
+  <slot />
+</view>

+ 1 - 0
miniprogram_npm/vant-weapp/sidebar/index.wxss

@@ -0,0 +1 @@
+@import '../common/index.wxss';.van-sidebar{width:85px;width:var(--sidebar-width,85px)}

+ 1 - 0
miniprogram_npm/vant-weapp/skeleton/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 46 - 0
miniprogram_npm/vant-weapp/skeleton/index.js

@@ -0,0 +1,46 @@
+import { VantComponent } from '../common/component';
+VantComponent({
+  classes: ['avatar-class', 'title-class', 'row-class'],
+  props: {
+    row: {
+      type: Number,
+      value: 0,
+      observer(value) {
+        this.setData({ rowArray: Array.from({ length: value }) });
+      },
+    },
+    title: Boolean,
+    avatar: Boolean,
+    loading: {
+      type: Boolean,
+      value: true,
+    },
+    animate: {
+      type: Boolean,
+      value: true,
+    },
+    avatarSize: {
+      type: String,
+      value: '32px',
+    },
+    avatarShape: {
+      type: String,
+      value: 'round',
+    },
+    titleWidth: {
+      type: String,
+      value: '40%',
+    },
+    rowWidth: {
+      type: null,
+      value: '100%',
+      observer(val) {
+        this.setData({ isArray: val instanceof Array });
+      },
+    },
+  },
+  data: {
+    isArray: false,
+    rowArray: [],
+  },
+});

+ 4 - 0
miniprogram_npm/vant-weapp/skeleton/index.json

@@ -0,0 +1,4 @@
+{
+  "component": true,
+  "usingComponents": {}
+}

+ 29 - 0
miniprogram_npm/vant-weapp/skeleton/index.wxml

@@ -0,0 +1,29 @@
+<wxs src="../wxs/utils.wxs" module="utils" />
+
+<view
+  wx:if="{{ loading }}"
+  class="custom-class {{ utils.bem('skeleton', [{animate}]) }}"
+>
+  <view
+    wx:if="{{ avatar }}"
+    class="avatar-class {{ utils.bem('skeleton__avatar', [avatarShape])}}"
+    style="{{ 'width:' + avatarSize + ';height:' + avatarSize }}"
+  />
+  <view class="{{ utils.bem('skeleton__content')}}">
+    <view
+      wx:if="{{ title }}"
+      class="title-class {{ utils.bem('skeleton__title') }}"
+      style="{{ 'width:' + titleWidth }}"
+    />
+    <view
+      wx:for="{{ rowArray }}"
+      wx:key="index"
+      wx:for-index="index"
+      class="row-class {{ utils.bem('skeleton__row') }}"
+      style="{{ 'width:' + (isArray ? rowWidth[index] : rowWidth) }}"
+    />
+  </view>
+</view>
+<view wx:else class="{{ utils.bem('skeleton__content')}}">
+  <slot />
+</view>

File diff suppressed because it is too large
+ 1 - 0
miniprogram_npm/vant-weapp/skeleton/index.wxss


+ 20 - 0
miniprogram_npm/vant-weapp/slider/index.wxs

@@ -0,0 +1,20 @@
+/* eslint-disable */
+var utils = require('../wxs/utils.wxs');
+
+function barStyle(barHeight, activeColor) {
+  var styles = [['height', utils.addUnit(barHeight)]];
+
+  if (activeColor) {
+    styles.push(['background', activeColor]);
+  }
+
+  return styles
+    .map(function (item) {
+      return item.join(':');
+    })
+    .join(';');
+}
+
+module.exports = {
+  barStyle: barStyle,
+};

+ 0 - 0
miniprogram_npm/vant-weapp/sticky/index.d.ts


Some files were not shown because too many files changed in this diff