diff --git a/app.json b/app.json index e6ddd47..34e5891 100644 --- a/app.json +++ b/app.json @@ -23,7 +23,8 @@ "pages/billboards/park/park-detail/index", "pages/weChatAuth/index", "pages/user/myWhistle/index", - "pages/user/myWhistle/whistleDetail/index" + "pages/user/myWhistle/whistleDetail/index", + "pages/user/myWhistle/evaluate/index" ], "window": { "backgroundTextStyle": "light", diff --git a/components/vant/action-sheet/index.d.ts b/components/vant/action-sheet/index.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/components/vant/action-sheet/index.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/components/vant/action-sheet/index.js b/components/vant/action-sheet/index.js new file mode 100644 index 0000000..3044481 --- /dev/null +++ b/components/vant/action-sheet/index.js @@ -0,0 +1,62 @@ +import { VantComponent } from '../common/component'; +import { button } from '../mixins/button'; +import { openType } from '../mixins/open-type'; +VantComponent({ + mixins: [button, openType], + props: { + show: Boolean, + title: String, + cancelText: String, + description: String, + round: { + type: Boolean, + value: true + }, + zIndex: { + type: Number, + value: 100 + }, + actions: { + type: Array, + value: [] + }, + overlay: { + type: Boolean, + value: true + }, + closeOnClickOverlay: { + type: Boolean, + value: true + }, + closeOnClickAction: { + type: Boolean, + value: true + }, + safeAreaInsetBottom: { + type: Boolean, + value: true + } + }, + methods: { + onSelect(event) { + const { index } = event.currentTarget.dataset; + const item = this.data.actions[index]; + if (item && !item.disabled && !item.loading) { + this.$emit('select', item); + if (this.data.closeOnClickAction) { + this.onClose(); + } + } + }, + onCancel() { + this.$emit('cancel'); + }, + onClose() { + this.$emit('close'); + }, + onClickOverlay() { + this.$emit('click-overlay'); + this.onClose(); + } + } +}); diff --git a/components/vant/action-sheet/index.json b/components/vant/action-sheet/index.json new file mode 100644 index 0000000..19bf989 --- /dev/null +++ b/components/vant/action-sheet/index.json @@ -0,0 +1,8 @@ +{ + "component": true, + "usingComponents": { + "van-icon": "../icon/index", + "van-popup": "../popup/index", + "van-loading": "../loading/index" + } +} diff --git a/components/vant/action-sheet/index.wxml b/components/vant/action-sheet/index.wxml new file mode 100644 index 0000000..7ed2819 --- /dev/null +++ b/components/vant/action-sheet/index.wxml @@ -0,0 +1,67 @@ + + + + + {{ title }} + + + + {{ description }} + + + + + + + + {{ cancelText }} + + diff --git a/components/vant/action-sheet/index.wxss b/components/vant/action-sheet/index.wxss new file mode 100644 index 0000000..dc54840 --- /dev/null +++ b/components/vant/action-sheet/index.wxss @@ -0,0 +1 @@ +@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)} \ No newline at end of file diff --git a/components/vant/area/index.d.ts b/components/vant/area/index.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/components/vant/area/index.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/components/vant/area/index.js b/components/vant/area/index.js new file mode 100644 index 0000000..e17234c --- /dev/null +++ b/components/vant/area/index.js @@ -0,0 +1,210 @@ +import { VantComponent } from '../common/component'; +import { pickerProps } from '../picker/shared'; +const COLUMNSPLACEHOLDERCODE = '000000'; +VantComponent({ + classes: ['active-class', 'toolbar-class', 'column-class'], + props: Object.assign(Object.assign({}, pickerProps), { value: { + type: String, + observer(value) { + this.code = value; + this.setValues(); + }, + }, areaList: { + type: Object, + value: {}, + observer: 'setValues' + }, columnsNum: { + type: null, + value: 3, + observer(value) { + this.setData({ + displayColumns: this.data.columns.slice(0, +value) + }); + } + }, columnsPlaceholder: { + type: Array, + observer(val) { + this.setData({ + typeToColumnsPlaceholder: { + province: val[0] || '', + city: val[1] || '', + county: val[2] || '', + } + }); + } + } }), + data: { + columns: [{ values: [] }, { values: [] }, { values: [] }], + displayColumns: [{ values: [] }, { values: [] }, { values: [] }], + typeToColumnsPlaceholder: {} + }, + mounted() { + setTimeout(() => { + this.setValues(); + }, 0); + }, + methods: { + getPicker() { + if (this.picker == null) { + this.picker = this.selectComponent('.van-area__picker'); + } + return this.picker; + }, + onCancel(event) { + this.emit('cancel', event.detail); + }, + onConfirm(event) { + const { index } = event.detail; + let { value } = event.detail; + value = this.parseOutputValues(value); + this.emit('confirm', { value, index }); + }, + emit(type, detail) { + detail.values = detail.value; + delete detail.value; + this.$emit(type, detail); + }, + // parse output columns data + parseOutputValues(values) { + const { columnsPlaceholder } = this.data; + return values.map((value, index) => { + // save undefined value + if (!value) + return value; + value = JSON.parse(JSON.stringify(value)); + if (!value.code || value.name === columnsPlaceholder[index]) { + value.code = ''; + value.name = ''; + } + return value; + }); + }, + onChange(event) { + const { index, picker, value } = event.detail; + this.code = value[index].code; + this.setValues().then(() => { + this.$emit('change', { + picker, + values: this.parseOutputValues(picker.getValues()), + index + }); + }); + }, + getConfig(type) { + const { areaList } = this.data; + return (areaList && areaList[`${type}_list`]) || {}; + }, + getList(type, code) { + const { typeToColumnsPlaceholder } = this.data; + let result = []; + if (type !== 'province' && !code) { + return result; + } + const list = this.getConfig(type); + result = Object.keys(list).map(code => ({ + code, + name: list[code] + })); + if (code) { + // oversea code + if (code[0] === '9' && type === 'city') { + code = '9'; + } + result = result.filter(item => item.code.indexOf(code) === 0); + } + if (typeToColumnsPlaceholder[type] && result.length) { + // set columns placeholder + const codeFill = type === 'province' ? '' : type === 'city' ? COLUMNSPLACEHOLDERCODE.slice(2, 4) : COLUMNSPLACEHOLDERCODE.slice(4, 6); + result.unshift({ + code: `${code}${codeFill}`, + name: typeToColumnsPlaceholder[type] + }); + } + return result; + }, + getIndex(type, code) { + let compareNum = type === 'province' ? 2 : type === 'city' ? 4 : 6; + const list = this.getList(type, code.slice(0, compareNum - 2)); + // oversea code + if (code[0] === '9' && type === 'province') { + compareNum = 1; + } + code = code.slice(0, compareNum); + for (let i = 0; i < list.length; i++) { + if (list[i].code.slice(0, compareNum) === code) { + return i; + } + } + return 0; + }, + 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(); + if (!picker) { + return; + } + const stack = []; + stack.push(picker.setColumnValues(0, province, false)); + stack.push(picker.setColumnValues(1, city, false)); + if (city.length && code.slice(2, 4) === '00') { + [{ code }] = city; + } + stack.push(picker.setColumnValues(2, this.getList('county', code.slice(0, 4)), false)); + return Promise.all(stack) + .catch(() => { }) + .then(() => picker.setIndexes([ + this.getIndex('province', code), + this.getIndex('city', code), + this.getIndex('county', code) + ])) + .catch(() => { }); + }, + getValues() { + const picker = this.getPicker(); + return picker ? picker.getValues().filter(value => !!value) : []; + }, + getDetail() { + const values = this.getValues(); + const area = { + code: '', + country: '', + province: '', + city: '', + county: '' + }; + if (!values.length) { + return area; + } + const names = values.map((item) => item.name); + area.code = values[values.length - 1].code; + if (area.code[0] === '9') { + area.country = names[1] || ''; + area.province = names[2] || ''; + } + else { + area.province = names[0] || ''; + area.city = names[1] || ''; + area.county = names[2] || ''; + } + return area; + }, + reset(code) { + this.code = code || ''; + return this.setValues(); + } + } +}); diff --git a/components/vant/area/index.json b/components/vant/area/index.json new file mode 100644 index 0000000..a778e91 --- /dev/null +++ b/components/vant/area/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "van-picker": "../picker/index" + } +} diff --git a/components/vant/area/index.wxml b/components/vant/area/index.wxml new file mode 100644 index 0000000..6075794 --- /dev/null +++ b/components/vant/area/index.wxml @@ -0,0 +1,18 @@ + diff --git a/components/vant/area/index.wxss b/components/vant/area/index.wxss new file mode 100644 index 0000000..99694d6 --- /dev/null +++ b/components/vant/area/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss'; \ No newline at end of file diff --git a/components/vant/button/index.d.ts b/components/vant/button/index.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/components/vant/button/index.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/components/vant/button/index.js b/components/vant/button/index.js new file mode 100644 index 0000000..599aa98 --- /dev/null +++ b/components/vant/button/index.js @@ -0,0 +1,69 @@ +import { VantComponent } from '../common/component'; +import { button } from '../mixins/button'; +import { openType } from '../mixins/open-type'; +VantComponent({ + mixins: [button, openType], + classes: ['hover-class', 'loading-class'], + data: { + baseStyle: '' + }, + props: { + icon: String, + plain: Boolean, + block: Boolean, + round: Boolean, + square: Boolean, + loading: Boolean, + hairline: Boolean, + disabled: Boolean, + loadingText: String, + customStyle: String, + loadingType: { + type: String, + value: 'circular' + }, + type: { + type: String, + value: 'default' + }, + size: { + type: String, + value: 'normal' + }, + loadingSize: { + type: String, + value: '20px' + }, + color: { + 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: { + onClick() { + if (!this.data.loading) { + this.$emit('click'); + } + }, + noop() { } + } +}); diff --git a/components/vant/button/index.json b/components/vant/button/index.json new file mode 100644 index 0000000..e00a588 --- /dev/null +++ b/components/vant/button/index.json @@ -0,0 +1,7 @@ +{ + "component": true, + "usingComponents": { + "van-icon": "../icon/index", + "van-loading": "../loading/index" + } +} diff --git a/components/vant/button/index.wxml b/components/vant/button/index.wxml new file mode 100644 index 0000000..09bef32 --- /dev/null +++ b/components/vant/button/index.wxml @@ -0,0 +1,68 @@ + + + + + + +function get(type, color,plain) { + if(plain) { + return color ? color: '#c9c9c9'; + } + + if(type === 'default') { + return '#c9c9c9'; + } + return 'white'; +} + +module.exports = get; + diff --git a/components/vant/button/index.wxss b/components/vant/button/index.wxss new file mode 100644 index 0000000..5a591fb --- /dev/null +++ b/components/vant/button/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-button{position:relative;display:-webkit-inline-flex;display:inline-flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;padding:0;text-align:center;vertical-align:middle;-webkit-appearance:none;-webkit-text-size-adjust:100%;height:44px;height:var(--button-default-height,44px);line-height:20px;line-height:var(--button-line-height,20px);font-size:16px;font-size:var(--button-default-font-size,16px);transition:opacity .2s;transition:opacity var(--animation-duration-fast,.2s);border-radius:2px;border-radius:var(--button-border-radius,2px)}.van-button:before{position:absolute;top:50%;left:50%;width:100%;height:100%;border:inherit;border-radius:inherit;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);opacity:0;content:" ";background-color:#000;background-color:var(--black,#000);border-color:#000;border-color:var(--black,#000)}.van-button:after{border-width:0}.van-button--active:before{opacity:.15}.van-button--unclickable:after{display:none}.van-button--default{color:#323233;color:var(--button-default-color,#323233);background:#fff;background:var(--button-default-background-color,#fff);border:1px solid #ebedf0;border:var(--button-border-width,1px) solid var(--button-default-border-color,#ebedf0)}.van-button--primary{color:#fff;color:var(--button-primary-color,#fff);background:#07c160;background:var(--button-primary-background-color,#07c160);border:1px solid #07c160;border:var(--button-border-width,1px) solid var(--button-primary-border-color,#07c160)}.van-button--info{color:#fff;color:var(--button-info-color,#fff);background:#1989fa;background:var(--button-info-background-color,#1989fa);border:1px solid #1989fa;border:var(--button-border-width,1px) solid var(--button-info-border-color,#1989fa)}.van-button--danger{color:#fff;color:var(--button-danger-color,#fff);background:#ee0a24;background:var(--button-danger-background-color,#ee0a24);border:1px solid #ee0a24;border:var(--button-border-width,1px) solid var(--button-danger-border-color,#ee0a24)}.van-button--warning{color:#fff;color:var(--button-warning-color,#fff);background:#ff976a;background:var(--button-warning-background-color,#ff976a);border:1px solid #ff976a;border:var(--button-border-width,1px) solid var(--button-warning-border-color,#ff976a)}.van-button--plain{background:#fff;background:var(--button-plain-background-color,#fff)}.van-button--plain.van-button--primary{color:#07c160;color:var(--button-primary-background-color,#07c160)}.van-button--plain.van-button--info{color:#1989fa;color:var(--button-info-background-color,#1989fa)}.van-button--plain.van-button--danger{color:#ee0a24;color:var(--button-danger-background-color,#ee0a24)}.van-button--plain.van-button--warning{color:#ff976a;color:var(--button-warning-background-color,#ff976a)}.van-button--large{width:100%;height:50px;height:var(--button-large-height,50px)}.van-button--normal{padding:0 15px;font-size:14px;font-size:var(--button-normal-font-size,14px)}.van-button--small{min-width:60px;min-width:var(--button-small-min-width,60px);height:30px;height:var(--button-small-height,30px);padding:0 8px;padding:0 var(--padding-xs,8px);font-size:12px;font-size:var(--button-small-font-size,12px)}.van-button--mini{display:inline-block;min-width:50px;min-width:var(--button-mini-min-width,50px);height:22px;height:var(--button-mini-height,22px);font-size:10px;font-size:var(--button-mini-font-size,10px)}.van-button--mini+.van-button--mini{margin-left:5px}.van-button--block{display:-webkit-flex;display:flex;width:100%}.van-button--round{border-radius:999px;border-radius:var(--button-round-border-radius,999px)}.van-button--square{border-radius:0}.van-button--disabled{opacity:.5;opacity:var(--button-disabled-opacity,.5)}.van-button__text{display:inline}.van-button__icon+.van-button__text:not(:empty),.van-button__loading-text{margin-left:4px}.van-button__icon{min-width:1em;line-height:inherit!important;vertical-align:top}.van-button--hairline{padding-top:1px;border-width:0}.van-button--hairline:after{border-color:inherit;border-width:1px;border-radius:4px;border-radius:calc(var(--button-border-radius, 2px)*2)}.van-button--hairline.van-button--round:after{border-radius:999px;border-radius:var(--button-round-border-radius,999px)}.van-button--hairline.van-button--square:after{border-radius:0} \ No newline at end of file diff --git a/components/vant/calendar/calendar.wxml b/components/vant/calendar/calendar.wxml new file mode 100644 index 0000000..09a60b3 --- /dev/null +++ b/components/vant/calendar/calendar.wxml @@ -0,0 +1,57 @@ + + + diff --git a/components/vant/calendar/components/header/index.d.ts b/components/vant/calendar/components/header/index.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/components/vant/calendar/components/header/index.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/components/vant/calendar/components/header/index.js b/components/vant/calendar/components/header/index.js new file mode 100644 index 0000000..74d4327 --- /dev/null +++ b/components/vant/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: {} +}); diff --git a/components/vant/calendar/components/header/index.json b/components/vant/calendar/components/header/index.json new file mode 100644 index 0000000..467ce29 --- /dev/null +++ b/components/vant/calendar/components/header/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} diff --git a/components/vant/calendar/components/header/index.wxml b/components/vant/calendar/components/header/index.wxml new file mode 100644 index 0000000..eb8e4b4 --- /dev/null +++ b/components/vant/calendar/components/header/index.wxml @@ -0,0 +1,16 @@ + + + + {{ title }} + + + + {{ subtitle }} + + + + + {{ item }} + + + diff --git a/components/vant/calendar/components/header/index.wxss b/components/vant/calendar/components/header/index.wxss new file mode 100644 index 0000000..4075e48 --- /dev/null +++ b/components/vant/calendar/components/header/index.wxss @@ -0,0 +1 @@ +@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 diff --git a/components/vant/calendar/components/month/index.d.ts b/components/vant/calendar/components/month/index.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/components/vant/calendar/components/month/index.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/components/vant/calendar/components/month/index.js b/components/vant/calendar/components/month/index.js new file mode 100644 index 0000000..0c88643 --- /dev/null +++ b/components/vant/calendar/components/month/index.js @@ -0,0 +1,148 @@ +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 '开始/结束'; + } + } + } + } +}); diff --git a/components/vant/calendar/components/month/index.json b/components/vant/calendar/components/month/index.json new file mode 100644 index 0000000..467ce29 --- /dev/null +++ b/components/vant/calendar/components/month/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} diff --git a/components/vant/calendar/components/month/index.wxml b/components/vant/calendar/components/month/index.wxml new file mode 100644 index 0000000..55bab83 --- /dev/null +++ b/components/vant/calendar/components/month/index.wxml @@ -0,0 +1,39 @@ + + + + + + {{ computed.formatMonthTitle(date) }} + + + + + {{ computed.getMark(date) }} + + + + + {{ item.topInfo }} + {{ item.text }} + + {{ item.bottomInfo }} + + + + + {{ item.topInfo }} + {{ item.text }} + + {{ item.bottomInfo }} + + + + + diff --git a/components/vant/calendar/components/month/index.wxs b/components/vant/calendar/components/month/index.wxs new file mode 100644 index 0000000..a057079 --- /dev/null +++ b/components/vant/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 +}; diff --git a/components/vant/calendar/components/month/index.wxss b/components/vant/calendar/components/month/index.wxss new file mode 100644 index 0000000..17c12f4 --- /dev/null +++ b/components/vant/calendar/components/month/index.wxss @@ -0,0 +1 @@ +@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 diff --git a/components/vant/calendar/index.d.ts b/components/vant/calendar/index.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/components/vant/calendar/index.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/components/vant/calendar/index.js b/components/vant/calendar/index.js new file mode 100644 index 0000000..e9a4614 --- /dev/null +++ b/components/vant/calendar/index.js @@ -0,0 +1,250 @@ +import { VantComponent } from '../common/component'; +import { ROW_HEIGHT, getNextDay, compareDay, copyDates, calcDateNum, formatMonthTitle, compareMonth, getMonths } 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) { + currentDate.splice(selectedIndex, 1); + this.setData({ currentDate }); + } + else { + this.select([...currentDate, date]); + } + } + else { + this.select(date, true); + } + }, + select(date, complete) { + 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)); + if (complete && this.data.type === 'range') { + const valid = this.checkRange(); + if (!valid) { + return; + } + } + if (complete && !this.data.showConfirm) { + this.onConfirm(); + } + }, + checkRange() { + const { maxRange, currentDate, rangePrompt } = this.data; + if (maxRange && calcDateNum(currentDate) > maxRange) { + Toast(rangePrompt || `选择天数不能超过 ${maxRange} 天`); + return false; + } + return true; + }, + onConfirm() { + if (this.data.type === 'range' && !this.checkRange()) { + return; + } + wx.nextTick(() => { + this.$emit('confirm', copyDates(this.data.currentDate)); + }); + } + } +}); diff --git a/components/vant/calendar/index.json b/components/vant/calendar/index.json new file mode 100644 index 0000000..61dec08 --- /dev/null +++ b/components/vant/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" + } +} diff --git a/components/vant/calendar/index.wxml b/components/vant/calendar/index.wxml new file mode 100644 index 0000000..1a4f59c --- /dev/null +++ b/components/vant/calendar/index.wxml @@ -0,0 +1,29 @@ + + + + + +