diff --git a/examples/wxcomponents-template/App.vue b/examples/wxcomponents-template/App.vue index 4e598e3afda9a38c176fae66aeaf9470c683dd06..c44f2a168a1861d16c464c4376bf19283f088f6a 100644 --- a/examples/wxcomponents-template/App.vue +++ b/examples/wxcomponents-template/App.vue @@ -14,13 +14,12 @@ diff --git a/examples/wxcomponents-template/pages.json b/examples/wxcomponents-template/pages.json index bf32f65d10af8aa94e12fdb94145c43d20ce7feb..9714c6100dbd4bb114b5bfc71799aab6d3a745e0 100644 --- a/examples/wxcomponents-template/pages.json +++ b/examples/wxcomponents-template/pages.json @@ -3,13 +3,34 @@ { "path": "pages/index/index", "style": { - "navigationBarTitleText": "uni-app" + "navigationBarTitleText": "小程序组件示例" + } + }, + { + "path": "pages/vant/vant", + "style": { + "navigationBarTitleText": "vant组件示例", + "usingComponents": { + "van-nav-bar": "/wxcomponents/vant-weapp/dist/nav-bar/index", + "van-icon": "/wxcomponents/vant-weapp/dist/icon/index" + } + } + }, + { + "path": "pages/wux/wux", + "style": { + "navigationBarTitleText": "wux组件示例", + "usingComponents": { + "wux-calendar": "/wxcomponents/wux-weapp/dist/calendar/index", + "wux-cell-group": "/wxcomponents/wux-weapp/dist/cell-group/index", + "wux-cell": "/wxcomponents/wux-weapp/dist/cell/index" + } } } ], "globalStyle": { "navigationBarTextStyle": "black", - "navigationBarTitleText": "uni-app", + "navigationBarTitleText": "小程序组件示例", "navigationBarBackgroundColor": "#F8F8F8", "backgroundColor": "#F8F8F8" } diff --git a/examples/wxcomponents-template/pages/index/index.vue b/examples/wxcomponents-template/pages/index/index.vue index 78b92e81a40c5ee5376ea6e1ff1991c3d47f20a0..ac3d2ce424e8a75e86e7bb95d36e40a6e12ddd7a 100644 --- a/examples/wxcomponents-template/pages/index/index.vue +++ b/examples/wxcomponents-template/pages/index/index.vue @@ -1,26 +1,22 @@ diff --git a/examples/wxcomponents-template/pages/vant/vant.vue b/examples/wxcomponents-template/pages/vant/vant.vue new file mode 100644 index 0000000000000000000000000000000000000000..2773013779445e89b5cfca958f9de2d2ec42b88e --- /dev/null +++ b/examples/wxcomponents-template/pages/vant/vant.vue @@ -0,0 +1,32 @@ + + + + + diff --git a/examples/wxcomponents-template/pages/wux/wux.vue b/examples/wxcomponents-template/pages/wux/wux.vue new file mode 100644 index 0000000000000000000000000000000000000000..7ca6c7e5f594d597e8334dc32adc9678e8b42b85 --- /dev/null +++ b/examples/wxcomponents-template/pages/wux/wux.vue @@ -0,0 +1,80 @@ + + + + + diff --git a/examples/wxcomponents-template/static/.gitkeep b/examples/wxcomponents-template/static/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/icon/index.js b/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/icon/index.js new file mode 100644 index 0000000000000000000000000000000000000000..ba24cbba877d8d9cf18656717dd589bdaa800347 --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/icon/index.js @@ -0,0 +1,20 @@ +import { create } from '../common/create'; + +create({ + props: { + info: null, + name: String, + size: String, + color: String, + classPrefix: { + type: String, + value: 'van-icon' + } + }, + + methods: { + onClick() { + this.$emit('click'); + } + } +}); diff --git a/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/icon/index.json b/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/icon/index.json new file mode 100644 index 0000000000000000000000000000000000000000..467ce2945f917ae0035594117b51f5304cdcdfa6 --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/icon/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} diff --git a/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/icon/index.wxml b/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/icon/index.wxml new file mode 100644 index 0000000000000000000000000000000000000000..2ea3e9fbacd16c3f6c524195dc001575090314a4 --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/icon/index.wxml @@ -0,0 +1,7 @@ + + {{ info }} + diff --git a/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/icon/index.wxss b/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/icon/index.wxss new file mode 100644 index 0000000000000000000000000000000000000000..59f39c5e71fb7223f9b7624105518d8a772fa658 --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/icon/index.wxss @@ -0,0 +1 @@ +@font-face{font-style:normal;font-weight:400;font-family:vant-icon;src:url(https://img.yzcdn.cn/vant/vant-icon-76f274.ttf) format('truetype')}.van-icon{position:relative;display:inline-block;font:normal normal normal 14px/1 vant-icon;font-size:inherit;text-rendering:auto}.van-icon__info{color:#fff;left:100%;top:-.5em;font-size:.5em;padding:0 .3em;text-align:center;min-width:1.2em;line-height:1.2;position:absolute;border-radius:.6em;box-sizing:border-box;background-color:#f44;-webkit-transform:translateX(-50%);transform:translateX(-50%);font-family:PingFang SC,Helvetica Neue,Arial,sans-serif}.van-icon::before{display:inline-block}.van-icon-add-o::before{content:"\F000"}.van-icon-add::before{content:"\F001"}.van-icon-add2::before{content:"\F002"}.van-icon-after-sale::before{content:"\F003"}.van-icon-aim::before{content:"\F004"}.van-icon-alipay::before{content:"\F005"}.van-icon-arrow-left::before{content:"\F006"}.van-icon-arrow::before{content:"\F007"}.van-icon-balance-pay::before{content:"\F008"}.van-icon-browsing-history::before{content:"\F009"}.van-icon-card::before{content:"\F00A"}.van-icon-cart::before{content:"\F00B"}.van-icon-cash-back-record::before{content:"\F00C"}.van-icon-cash-on-deliver::before{content:"\F00D"}.van-icon-certificate::before{content:"\F00E"}.van-icon-chat::before{content:"\F00F"}.van-icon-check::before{content:"\F010"}.van-icon-checked::before{content:"\F011"}.van-icon-clear::before{content:"\F012"}.van-icon-clock::before{content:"\F013"}.van-icon-close::before{content:"\F014"}.van-icon-completed::before{content:"\F015"}.van-icon-contact::before{content:"\F016"}.van-icon-coupon::before{content:"\F017"}.van-icon-credit-pay::before{content:"\F018"}.van-icon-debit-pay::before{content:"\F019"}.van-icon-delete::before{content:"\F01A"}.van-icon-description::before{content:"\F01B"}.van-icon-discount::before{content:"\F01C"}.van-icon-ecard-pay::before{content:"\F01D"}.van-icon-edit-data::before{content:"\F01E"}.van-icon-edit::before{content:"\F01F"}.van-icon-exchange-record::before{content:"\F020"}.van-icon-exchange::before{content:"\F021"}.van-icon-fail::before{content:"\F022"}.van-icon-free-postage::before{content:"\F023"}.van-icon-gift-card-pay::before{content:"\F024"}.van-icon-gift-card::before{content:"\F025"}.van-icon-gift::before{content:"\F026"}.van-icon-gold-coin::before{content:"\F027"}.van-icon-goods-collect::before{content:"\F028"}.van-icon-home::before{content:"\F029"}.van-icon-hot-sale::before{content:"\F02A"}.van-icon-hot::before{content:"\F02B"}.van-icon-idcard::before{content:"\F02C"}.van-icon-info-o::before{content:"\F02D"}.van-icon-like-o::before{content:"\F02E"}.van-icon-like::before{content:"\F02F"}.van-icon-location::before{content:"\F030"}.van-icon-logistics::before{content:"\F031"}.van-icon-more-o::before{content:"\F032"}.van-icon-more::before{content:"\F033"}.van-icon-new-arrival::before{content:"\F034"}.van-icon-new::before{content:"\F035"}.van-icon-other-pay::before{content:"\F036"}.van-icon-passed::before{content:"\F037"}.van-icon-password-not-view::before{content:"\F038"}.van-icon-password-view::before{content:"\F039"}.van-icon-pause::before{content:"\F03A"}.van-icon-peer-pay::before{content:"\F03B"}.van-icon-pending-deliver::before{content:"\F03C"}.van-icon-pending-evaluate::before{content:"\F03D"}.van-icon-pending-orders::before{content:"\F03E"}.van-icon-pending-payment::before{content:"\F03F"}.van-icon-phone::before{content:"\F040"}.van-icon-photo::before{content:"\F041"}.van-icon-photograph::before{content:"\F042"}.van-icon-play::before{content:"\F043"}.van-icon-point-gift::before{content:"\F044"}.van-icon-points-mall::before{content:"\F045"}.van-icon-points::before{content:"\F046"}.van-icon-qr-invalid::before{content:"\F047"}.van-icon-qr::before{content:"\F048"}.van-icon-question::before{content:"\F049"}.van-icon-receive-gift::before{content:"\F04A"}.van-icon-records::before{content:"\F04B"}.van-icon-search::before{content:"\F04C"}.van-icon-send-gift::before{content:"\F04D"}.van-icon-setting::before{content:"\F04E"}.van-icon-share::before{content:"\F04F"}.van-icon-shop-collect::before{content:"\F050"}.van-icon-shop::before{content:"\F051"}.van-icon-shopping-cart::before{content:"\F052"}.van-icon-sign::before{content:"\F053"}.van-icon-stop::before{content:"\F054"}.van-icon-success::before{content:"\F055"}.van-icon-tosend::before{content:"\F056"}.van-icon-underway::before{content:"\F057"}.van-icon-upgrade::before{content:"\F058"}.van-icon-value-card::before{content:"\F059"}.van-icon-wap-home::before{content:"\F05A"}.van-icon-wap-nav::before{content:"\F05B"}.van-icon-warn::before{content:"\F05C"}.van-icon-wechat::before{content:"\F05D"} \ No newline at end of file diff --git a/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/nav-bar/index.js b/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/nav-bar/index.js new file mode 100644 index 0000000000000000000000000000000000000000..db96154662642ed1b5b8407b1c184e6075c2d5eb --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/nav-bar/index.js @@ -0,0 +1,27 @@ +import { create } from '../common/create'; + +create({ + classes: ['title-class'], + + props: { + title: String, + leftText: String, + rightText: String, + leftArrow: Boolean, + fixed: Boolean, + zIndex: { + type: Number, + value: 1 + } + }, + + methods: { + onClickLeft() { + this.$emit('clickLeft'); + }, + + onClickRight() { + this.$emit('clickRight'); + } + } +}); diff --git a/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/nav-bar/index.json b/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/nav-bar/index.json new file mode 100644 index 0000000000000000000000000000000000000000..0a336c083ec7c8f87af66097dd241c13b3f6dc2e --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/nav-bar/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "van-icon": "../icon/index" + } +} diff --git a/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/nav-bar/index.wxml b/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/nav-bar/index.wxml new file mode 100644 index 0000000000000000000000000000000000000000..e53a5918020a2fe7ead6bfe3bc8dc4a954c58b07 --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/nav-bar/index.wxml @@ -0,0 +1,24 @@ + + + + + {{ leftText }} + + + + + {{ title }} + + + + {{ rightText }} + + + diff --git a/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/nav-bar/index.wxss b/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/nav-bar/index.wxss new file mode 100644 index 0000000000000000000000000000000000000000..c21c6b735d20200a55b57adf4d0752a6a222ccd3 --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/vant-weapp/dist/nav-bar/index.wxss @@ -0,0 +1 @@ +.van-nav-bar{height:46px;position:relative;-webkit-user-select:none;user-select:none;text-align:center;line-height:46px;background-color:#fff}.van-nav-bar__arrow{color:#38f;vertical-align:middle;-webkit-transform:rotate(180deg);transform:rotate(180deg)}.van-nav-bar__arrow+.van-nav-bar__text{margin-left:-20px;padding-left:25px}.van-nav-bar--fixed{top:0;left:0;width:100%;position:fixed}.van-nav-bar__title{margin:0 auto;max-width:60%;font-size:16px}.van-nav-bar__left,.van-nav-bar__right{bottom:0;font-size:14px;position:absolute}.van-nav-bar__left{left:15px}.van-nav-bar__right{right:15px}.van-nav-bar__text{color:#38f;margin:0 -15px;padding:0 15px;display:inline-block;vertical-align:middle}.van-nav-bar__text:active{background-color:#e8e8e8} \ No newline at end of file diff --git a/examples/wxcomponents-template/wxcomponents/wux-weapp/.babelrc b/examples/wxcomponents-template/wxcomponents/wux-weapp/.babelrc new file mode 100644 index 0000000000000000000000000000000000000000..69f50d59a72b7a0efbf1799206b22e36be57dcc1 --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/wux-weapp/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["env"] +} \ No newline at end of file diff --git a/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/calendar/index.js b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/calendar/index.js new file mode 100644 index 0000000000000000000000000000000000000000..a50d2a43124974b1d27c8289b13926bdb9119401 --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/calendar/index.js @@ -0,0 +1,717 @@ +import baseBehavior from '../helpers/baseBehavior' +import mergeOptionsToData from '../helpers/mergeOptionsToData' +import { $wuxBackdrop } from '../index' + +const defaults = { + monthNames: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'], + monthNamesShort: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'], + dayNames: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'], + dayNamesShort: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'], + firstDay: 1, // First day of the week, Monday + weekendDays: [0, 6], // Sunday and Saturday + multiple: false, + dateFormat: 'yyyy-mm-dd', + direction: 'horizontal', // or 'vertical' + minDate: null, + maxDate: null, + touchMove: true, + animate: true, + closeOnSelect: true, + weekHeader: true, + toolbar: true, + value: [], + onMonthAdd() {}, + onChange() {}, + onOpen() {}, + onClose() {}, + onDayClick() {}, + onMonthYearChangeStart() {}, + onMonthYearChangeEnd() {}, +} + +// 获取手指触摸点坐标 +const getTouchPosition = (e) => { + const touches = e.touches[0] || e.changedTouches[0] + return { + x: touches.pageX, + y: touches.pageY, + } +} + +// 获取元素旋转属性 +const getTransform = (translate, isH) => `transform: translate3d(${isH ? translate : 0}%, ${isH ? 0 : translate}%, 0)` + +// 判断两个日期是否在同一天 +const isSameDate = (a, b) => { + const prev = new Date(a) + const next = new Date(b) + return prev.getFullYear() === next.getFullYear() && prev.getMonth() === next.getMonth() && prev.getDate() === next.getDate() +} + +Component({ + behaviors: [baseBehavior], + externalClasses: ['wux-class'], + data: mergeOptionsToData(defaults), + methods: { + /** + * 打开日历 + * @param {Object} opts + */ + open(opts = {}) { + const options = this.$$mergeOptionsAndBindMethods(Object.assign({}, defaults, opts)) + + this.monthsTranslate = 0 + this.isH = options.direction === 'horizontal' + + this.$$setData({ in: true, ...options }) + .then(() => { + const weeks = this.setWeekHeader() + const months = this.setMonthsHTML() + const monthsTranslate = this.setMonthsTranslate() + + if (typeof this.fns.onMonthAdd === 'function') { + months.forEach((month) => { + this.fns.onMonthAdd.call(this, month) + }) + } + + return this.$$setData({ weeks, months, monthsTranslate, wrapperTranslate: '' }) + }) + .then(() => this.$$setData({...this.updateCurrentMonthYear() })) + + this.setValue(options.value) + this.$wuxBackdrop.retain() + + if (typeof this.fns.onOpen === 'function') { + this.fns.onOpen.call(this) + } + }, + /** + * 关闭日历 + */ + close() { + this.$$setData({ in: false }) + this.$wuxBackdrop.release() + + if (typeof this.fns.onClose === 'function') { + this.fns.onClose.call(this) + } + }, + /** + * 设置月份的位置信息 + * @param {Number} translate + */ + setMonthsTranslate(translate = this.monthsTranslate) { + const prevMonthTranslate = -(translate + 1) * 100 + const currentMonthTranslate = -translate * 100 + const nextMonthTranslate = -(translate - 1) * 100 + + return [ + getTransform(prevMonthTranslate, this.isH), + getTransform(currentMonthTranslate, this.isH), + getTransform(nextMonthTranslate, this.isH), + ] + }, + /** + * 更新当前年月 + * @param {String} dir 方向 + */ + updateCurrentMonthYear(dir) { + const { months, monthNames } = this.data + + if (typeof dir === 'undefined') { + const currentMonth = parseInt(months[1].month, 10) + const currentYear = parseInt(months[1].year, 10) + const currentMonthName = monthNames[currentMonth] + + return { + currentMonth, + currentYear, + currentMonthName, + } + } + + const currentMonth = parseInt(months[dir === 'next' ? (months.length - 1) : 0].month, 10) + const currentYear = parseInt(months[dir === 'next' ? (months.length - 1) : 0].year, 10) + const currentMonthName = monthNames[currentMonth] + + return { + currentMonth, + currentYear, + currentMonthName, + } + }, + /** + * 手指触摸动作开始 + * @param {Object} e 事件对象 + */ + onTouchStart(e) { + if (!this.data.touchMove || this.isMoved || this.isRendered) { + return false + } + + this.start = getTouchPosition(e) + this.move = {} + this.touchesDiff = 0 + this.allowItemClick = true + this.isMoved = false + }, + /** + * 手指触摸后移动 + * @param {Object} e 事件对象 + */ + onTouchMove(e) { + if (!this.data.touchMove || this.isRendered) { + return false + } + + this.allowItemClick = false + + if (!this.isMoved) { + this.isMoved = true + } + + const query = wx.createSelectorQuery().in(this) + query.select('.wux-calendar__months-content').boundingClientRect((rect) => { + if (!rect) { + return false + } + + this.move = getTouchPosition(e) + this.touchesDiff = this.isH ? this.move.x - this.start.x : this.move.y - this.start.y + + const { width, height } = rect + const percentage = this.touchesDiff / (this.isH ? width : height) + const currentTranslate = (this.monthsTranslate + percentage) * 100 + const transform = getTransform(currentTranslate, this.isH) + + this.$$setData({ + wrapperTranslate: `transition-duration: 0s; ${transform}`, + }) + }) + query.exec() + }, + /** + * 手指触摸动作结束 + */ + onTouchEnd() { + if (!this.data.touchMove || !this.isMoved || this.isRendered) { + return false + } + + this.isMoved = false + + if (Math.abs(this.touchesDiff) < 30) { + this.resetMonth() + } else if (this.touchesDiff >= 30) { + this.prevMonth() + } else { + this.nextMonth() + } + + // Allow click + setTimeout(() => (this.allowItemClick = true), 100) + }, + /** + * 日期的点击事件 + * @param {Object} e 事件对象 + */ + onDayClick(e) { + if (this.allowItemClick) { + const dataset = e.currentTarget.dataset + const dateYear = dataset.year + const dateMonth = dataset.month + const dateDay = dataset.day + const dateType = dataset.type + + if (dateType.selected && !this.data.multiple) return false + if (dateType.disabled) return false + if (dateType.next) this.nextMonth() + if (dateType.prev) this.prevMonth() + + if (typeof this.fns.onDayClick === 'function') { + this.fns.onDayClick.call(this, dateYear, dateMonth, dateDay) + } + + this.addValue(new Date(dateYear, dateMonth, dateDay).getTime()) + + if (this.data.closeOnSelect && !this.data.multiple) { + this.close() + } + } + }, + /** + * 重置月份的位置信息 + */ + resetMonth() { + const translate = this.monthsTranslate * 100 + const transform = getTransform(translate, this.isH) + + this.$$setData({ + wrapperTranslate: `transition-duration: 0s; ${transform}`, + }) + }, + /** + * 设置年月 + * @param {String} year 年份 + * @param {String} month 月份 + */ + setYearMonth(year = this.data.currentYear, month = this.data.currentMonth) { + const { months, monthsTranslate, maxDate, minDate, currentYear, currentMonth } = this.data + const targetDate = year < currentYear ? new Date(year, month + 1, -1).getTime() : new Date(year, month).getTime() + + // 判断是否存在最大日期 + if (maxDate && targetDate > new Date(maxDate).getTime()) { + return false + } + + // 判断是否存在最小日期 + if (minDate && targetDate < new Date(minDate).getTime()) { + return false + } + + const currentDate = new Date(currentYear, currentMonth).getTime() + const dir = targetDate > currentDate ? 'next' : 'prev' + const newMonthHTML = this.monthHTML(new Date(year, month)) + + const prevTranslate = this.monthsTranslate = this.monthsTranslate || 0 + + if (targetDate > currentDate) { + this.monthsTranslate = this.monthsTranslate - 1 + + const translate = -(prevTranslate - 1) * 100 + const nextMonthTranslate = getTransform(translate, this.isH) + + this.$$setData({ + months: [months[1], months[2], newMonthHTML], + monthsTranslate: [monthsTranslate[1], monthsTranslate[2], nextMonthTranslate], + }) + } else { + this.monthsTranslate = this.monthsTranslate + 1 + + const translate = -(prevTranslate + 1) * 100 + const prevMonthTranslate = getTransform(translate, this.isH) + + this.$$setData({ + months: [newMonthHTML, months[0], months[1]], + monthsTranslate: [prevMonthTranslate, monthsTranslate[0], monthsTranslate[1]], + }) + } + + this.onMonthChangeStart(dir) + + const transform = getTransform(this.monthsTranslate * 100, this.isH) + const duration = this.data.animate ? .3 : 0 + const wrapperTranslate = `transition-duration: ${duration}s; ${transform}` + + this.$$setData({ + wrapperTranslate, + }) + + setTimeout(() => this.onMonthChangeEnd(dir, true), duration) + }, + /** + * 下一年 + */ + nextYear() { + this.setYearMonth(this.data.currentYear + 1) + }, + /** + * 上一年 + */ + prevYear() { + this.setYearMonth(this.data.currentYear - 1) + }, + /** + * 下一月 + */ + nextMonth() { + const { months, monthsTranslate, maxDate, currentMonth } = this.data + const nextMonth = parseInt(months[months.length - 1].month, 10) + const nextYear = parseInt(months[months.length - 1].year, 10) + const nextDate = new Date(nextYear, nextMonth) + const nextDateTime = nextDate.getTime() + + // 判断是否存在最大日期 + if (maxDate && nextDateTime > new Date(maxDate).getTime()) { + return this.resetMonth() + } + + this.monthsTranslate = this.monthsTranslate - 1 + + if (nextMonth === currentMonth) { + const translate = -(this.monthsTranslate) * 100 + const nextMonthHTML = this.monthHTML(nextDateTime, 'next') + const nextMonthTranslate = getTransform(translate, this.isH) + const months = [this.data.months[1], this.data.months[2], nextMonthHTML] + + this.$$setData({ + months, + monthsTranslate: [monthsTranslate[1], monthsTranslate[2], nextMonthTranslate], + }) + + if (typeof this.fns.onMonthAdd === 'function') { + this.fns.onMonthAdd.call(this, months[months.length - 1]) + } + } + + this.onMonthChangeStart('next') + + const transform = getTransform(this.monthsTranslate * 100, this.isH) + const duration = this.data.animate ? .3 : 0 + const wrapperTranslate = `transition-duration: ${duration}s; ${transform}` + + this.$$setData({ + wrapperTranslate, + }) + + setTimeout(() => this.onMonthChangeEnd('next'), duration) + }, + /** + * 上一月 + */ + prevMonth() { + const { months, monthsTranslate, minDate, currentMonth } = this.data + const prevMonth = parseInt(months[0].month, 10) + const prevYear = parseInt(months[0].year, 10) + const prevDate = new Date(prevYear, prevMonth + 1, -1) + const prevDateTime = prevDate.getTime() + + // 判断是否存在最小日期 + if (minDate && prevDateTime < new Date(minDate).getTime()) { + return this.resetMonth() + } + + this.monthsTranslate = this.monthsTranslate + 1 + + if (prevMonth === currentMonth) { + const translate = -(this.monthsTranslate) * 100 + const prevMonthHTML = this.monthHTML(prevDateTime, 'prev') + const prevMonthTranslate = getTransform(translate, this.isH) + const months = [prevMonthHTML, this.data.months[0], this.data.months[1]] + + this.$$setData({ + months, + monthsTranslate: [prevMonthTranslate, monthsTranslate[0], monthsTranslate[1]], + }) + + if (typeof this.fns.onMonthAdd === 'function') { + this.fns.onMonthAdd.call(this, months[0]) + } + } + + this.onMonthChangeStart('prev') + + const transform = getTransform(this.monthsTranslate * 100, this.isH) + const duration = this.data.animate ? .3 : 0 + const wrapperTranslate = `transition-duration: ${duration}s; ${transform}` + + this.$$setData({ + wrapperTranslate, + }) + + setTimeout(() => this.onMonthChangeEnd('prev'), duration) + }, + /** + * 月份变化开始时的回调函数 + * @param {String} dir 方向 + */ + onMonthChangeStart(dir) { + const params = this.updateCurrentMonthYear(dir) + + this.$$setData(params) + + if (typeof this.fns.onMonthYearChangeStart === 'function') { + this.fns.onMonthYearChangeStart.call(this, params.currentYear, params.currentMonth) + } + }, + /** + * 月份变化完成时的回调函数 + * @param {String} dir 方向 + * @param {Boolean} rebuildBoth 重置 + */ + onMonthChangeEnd(dir = 'next', rebuildBoth = false) { + const { currentYear, currentMonth } = this.data + let nextMonthHTML, prevMonthHTML, newMonthHTML, months = [...this.data.months] + + if (!rebuildBoth) { + newMonthHTML = this.monthHTML(new Date(currentYear, currentMonth), dir) + if (dir === 'next') { + months = [months[1], months[2], newMonthHTML] + } else if (dir === 'prev') { + months = [newMonthHTML, months[0], months[1]] + } + } else { + prevMonthHTML = this.monthHTML(new Date(currentYear, currentMonth), 'prev') + nextMonthHTML = this.monthHTML(new Date(currentYear, currentMonth), 'next') + months = [prevMonthHTML, months[dir === 'next' ? months.length - 1 : 0], nextMonthHTML] + } + + const monthsTranslate = this.setMonthsTranslate(this.monthsTranslate) + + this.isRendered = true + this.$$setData({ months, monthsTranslate }).then(() => (this.isRendered = false)) + + if (typeof this.fns.onMonthAdd === 'function') { + this.fns.onMonthAdd.call(this, dir === 'next' ? months[months.length - 1] : months[0]) + } + + if (typeof this.fns.onMonthYearChangeEnd === 'function') { + this.fns.onMonthYearChangeEnd.call(this, currentYear, currentMonth) + } + }, + /** + * 设置星期 + */ + setWeekHeader() { + const { weekHeader, firstDay, dayNamesShort, weekendDays } = this.data + const weeks = [] + + if (weekHeader) { + for (let i = 0; i < 7; i++) { + const weekDayIndex = (i + firstDay > 6) ? (i - 7 + firstDay) : (i + firstDay) + const dayName = dayNamesShort[weekDayIndex] + const weekend = weekendDays.indexOf(weekDayIndex) >= 0 + + weeks.push({ + weekend, + dayName, + }) + } + } + + return weeks + }, + /** + * 判断日期是否存在 + */ + daysInMonth(date) { + const d = new Date(date) + return new Date(d.getFullYear(), d.getMonth() + 1, 0).getDate() + }, + /** + * 设置月份数据 + */ + monthHTML(date, offset) { + date = new Date(date) + let year = date.getFullYear(), + month = date.getMonth(), + time = date.getTime() + + const monthHTML = { + year, + month, + time, + items: [], + } + + if (offset === `next`) { + if (month === 11) date = new Date(year + 1, 0) + else date = new Date(year, month + 1, 1) + } + + if (offset === `prev`) { + if (month === 0) date = new Date(year - 1, 11) + else date = new Date(year, month - 1, 1) + } + + if (offset === `next` || offset === `prev`) { + month = date.getMonth() + year = date.getFullYear() + time = date.getTime() + } + + let daysInPrevMonth = this.daysInMonth(new Date(date.getFullYear(), date.getMonth()).getTime() - 10 * 24 * 60 * 60 * 1000), + daysInMonth = this.daysInMonth(date), + firstDayOfMonthIndex = new Date(date.getFullYear(), date.getMonth()).getDay() + if (firstDayOfMonthIndex === 0) firstDayOfMonthIndex = 7 + + let dayDate, currentValues = [], + i, j, + rows = 6, + cols = 7, + dayIndex = 0 + (this.data.firstDay - 1), + today = new Date().setHours(0, 0, 0, 0), + minDate = this.data.minDate ? new Date(this.data.minDate).getTime() : null, + maxDate = this.data.maxDate ? new Date(this.data.maxDate).getTime() : null + + if (this.data.value && this.data.value.length) { + for (let i = 0; i < this.data.value.length; i++) { + currentValues.push(new Date(this.data.value[i]).setHours(0, 0, 0, 0)) + } + } + + for (let i = 1; i <= rows; i++) { + let rowHTML = [] + let row = i + + for (let j = 1; j <= cols; j++) { + let col = j + dayIndex++ + let dayNumber = dayIndex - firstDayOfMonthIndex + let type = {} + + if (dayNumber < 0) { + dayNumber = daysInPrevMonth + dayNumber + 1 + type.prev = true + dayDate = new Date(month - 1 < 0 ? year - 1 : year, month - 1 < 0 ? 11 : month - 1, dayNumber).getTime() + } else { + dayNumber = dayNumber + 1 + if (dayNumber > daysInMonth) { + dayNumber = dayNumber - daysInMonth + type.next = true + dayDate = new Date(month + 1 > 11 ? year + 1 : year, month + 1 > 11 ? 0 : month + 1, dayNumber).getTime() + } else { + dayDate = new Date(year, month, dayNumber).getTime() + } + } + + // Today + if (dayDate === today) type.today = true + + // Selected + if (currentValues.indexOf(dayDate) >= 0) type.selected = true + + // Weekend + if (this.data.weekendDays.indexOf(col - 1) >= 0) { + type.weekend = true + } + + // Disabled + if ((minDate && dayDate < minDate) || (maxDate && dayDate > maxDate)) { + type.disabled = true + } + + dayDate = new Date(dayDate) + const dayYear = dayDate.getFullYear() + const dayMonth = dayDate.getMonth() + + rowHTML.push({ + type, + year: dayYear, + month: dayMonth, + day: dayNumber, + date: `${dayYear}-${dayMonth + 1}-${dayNumber}`, + }) + } + + monthHTML.year = year + monthHTML.month = month + monthHTML.time = time + + monthHTML.items.push(rowHTML) + } + + return monthHTML + }, + /** + * 设置月份 + */ + setMonthsHTML() { + const layoutDate = this.data.value && this.data.value.length ? this.data.value[0] : new Date().setHours(0, 0, 0, 0) + const prevMonthHTML = this.monthHTML(layoutDate, `prev`) + const currentMonthHTML = this.monthHTML(layoutDate) + const nextMonthHTML = this.monthHTML(layoutDate, `next`) + + return [prevMonthHTML, currentMonthHTML, nextMonthHTML] + }, + /** + * 格式化日期 + */ + formatDate(date) { + date = new Date(date) + const year = date.getFullYear() + const month = date.getMonth() + const month1 = month + 1 + const day = date.getDate() + const weekDay = date.getDay() + + return this.data.dateFormat + .replace(/yyyy/g, year) + .replace(/yy/g, (year + '').substring(2)) + .replace(/mm/g, month1 < 10 ? '0' + month1 : month1) + .replace(/m/g, month1) + .replace(/MM/g, this.data.monthNames[month]) + .replace(/M/g, this.data.monthNamesShort[month]) + .replace(/dd/g, day < 10 ? '0' + day : day) + .replace(/d/g, day) + .replace(/DD/g, this.data.dayNames[weekDay]) + .replace(/D/g, this.data.dayNamesShort[weekDay]) + }, + /** + * 添加选中值 + */ + addValue(value) { + if (this.data.multiple) { + let arrValues = this.data.value || [] + let inValuesIndex = -1 + + for (let i = 0; i < arrValues.length; i++) { + if (isSameDate(value, arrValues[i])) { + inValuesIndex = i + } + } + + if (inValuesIndex === -1) { + arrValues.push(value) + } else { + arrValues.splice(inValuesIndex, 1) + } + + this.setValue(arrValues) + } else { + this.setValue([value]) + } + }, + /** + * 设置选择值 + */ + setValue(value) { + this.$$setData({ value }).then(() => this.updateValue()) + }, + /** + * 更新日历 + */ + updateValue() { + const changedPath = {} + + this.data.months.forEach((n, i) => { + n.items.forEach((v, k) => { + v.forEach((p, j) => { + if (p.type.selected) { + changedPath[`months[${i}].items[${k}][${j}].type.selected`] = false + } + }) + }) + }) + + for (let ii = 0; ii < this.data.value.length; ii++) { + const valueDate = new Date(this.data.value[ii]) + const valueYear = valueDate.getFullYear() + const valueMonth = valueDate.getMonth() + const valueDay = valueDate.getDate() + + this.data.months.forEach((n, i) => { + if (n.year === valueYear && n.month === valueMonth) { + n.items.forEach((v, k) => { + v.forEach((p, j) => { + if (p.year === valueYear && p.month === valueMonth && p.day === valueDay) { + changedPath[`months[${i}].items[${k}][${j}].type.selected`] = true + } + }) + }) + } + }) + } + + this.$$setData(changedPath) + + if (typeof this.fns.onChange === 'function') { + this.fns.onChange.call(this, this.data.value, this.data.value.map((n) => this.formatDate(n))) + } + }, + }, + created() { + this.$wuxBackdrop = $wuxBackdrop('#wux-backdrop', this) + }, +}) \ No newline at end of file diff --git a/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/calendar/index.json b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/calendar/index.json new file mode 100644 index 0000000000000000000000000000000000000000..34b34c1642644e429486f5716710b7de06b6652b --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/calendar/index.json @@ -0,0 +1,7 @@ +{ + "component": true, + "usingComponents": { + "wux-animation-group": "../animation-group/index", + "wux-backdrop": "../backdrop/index" + } +} \ No newline at end of file diff --git a/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/calendar/index.wxml b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/calendar/index.wxml new file mode 100644 index 0000000000000000000000000000000000000000..8ffb7760df4be0b9b5f16ff735218ca725fc9875 --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/calendar/index.wxml @@ -0,0 +1,53 @@ + + + + + + + + + + {{ currentMonthName }} + + + + + + + + + {{ currentYear }} + + + + + + + + + + + {{ item.dayName }} + + + + + + + + + + + + {{ col.day }} + + + + + + + + + + + \ No newline at end of file diff --git a/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/calendar/index.wxss b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/calendar/index.wxss new file mode 100644 index 0000000000000000000000000000000000000000..c635ea4c77d4e3a029861a612bc3edbf35f98388 --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/calendar/index.wxss @@ -0,0 +1,322 @@ +.wux-calendar { + position: fixed; + left: 0; + bottom: 0; + height: 13rem; + z-index: 1500; + background: #cfd5da; + background: #fff; + height: 600rpx; + width: 100%; + overflow: hidden; +} +.wux-calendar__content { + position: relative; + width: 100%; + height: 100%; + -webkit-transition: -webkit-transform .3s; + transition: -webkit-transform .3s; + transition: transform .3s; + transition: transform .3s, -webkit-transform .3s; +} +.wux-calendar__bd { + height: 100%; + position: relative; + overflow: hidden; +} +.wux-calendar__hd { + position: relative; + width: 100%; +} +.wux-calendar__hd:before { + content: ''; + position: absolute; + left: 0; + top: 0; + bottom: auto; + right: auto; + height: 2rpx; + width: 100%; + background-color: #999999; + display: block; + z-index: 15; + -webkit-transform-origin: 50% 0%; + transform-origin: 50% 0%; +} +.wux-calendar__hd + .wux-calendar__bd { + height: calc(97.8%); +} +@media only screen and (-webkit-min-device-pixel-ratio: 2) { + .wux-calendar__hd:before { + -webkit-transform: scaleY(0.5); + transform: scaleY(0.5); + } +} +@media only screen and (-webkit-min-device-pixel-ratio: 3) { + .wux-calendar__hd:before { + -webkit-transform: scaleY(0.33); + transform: scaleY(0.33); + } +} +.wux-calendar--inline { + display: block; + position: relative; + z-index: inherit; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +.wux-calendar--inline .wux-calendar__hd:before { + display: none; +} +.wux-calendar--inline .wux-calendar__hd:after { + content: ''; + position: absolute; + left: 0; + bottom: 0; + right: auto; + top: auto; + height: 2rpx; + width: 100%; + background-color: #999999; + display: block; + z-index: 15; + -webkit-transform-origin: 50% 100%; + transform-origin: 50% 100%; +} +@media only screen and (-webkit-min-device-pixel-ratio: 2) { + .wux-calendar--inline .wux-calendar__hd:after { + -webkit-transform: scaleY(0.5); + transform: scaleY(0.5); + } +} +@media only screen and (-webkit-min-device-pixel-ratio: 3) { + .wux-calendar--inline .wux-calendar__hd:after { + -webkit-transform: scaleY(0.33); + transform: scaleY(0.33); + } +} +@media (orientation: landscape) and (max-height: 830rpx) { + .wux-calendar:not(.wux-calendar--inline) { + height: 440rpx; + } +} +.wux-calendar__toolbar { + height: 2.2rem; + display: -webkit-box; + display: -webkit-flex; + display: flex; + text-align: center; +} +.wux-calendar__picker { + display: -webkit-box; + display: -webkit-flex; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + align-items: center; + -webkit-box-pack: justify; + -webkit-justify-content: space-between; + justify-content: space-between; + width: 50%; + max-width: 400rpx; + -webkit-flex-shrink: 10; + flex-shrink: 10; + display: block; + line-height: 2.2rem; +} +.wux-calendar__link { + float: left; + width: 25%; + height: 2.2rem; + line-height: 2rem; + min-width: 72rpx; +} +.wux-calendar__icon { + display: inline-block; + vertical-align: middle; + background-size: 100% auto; + background-position: center; +} +.wux-calendar__icon--next, +.wux-calendar__icon--prev { + width: 0.75rem; + height: 0.75rem; +} +.wux-calendar__icon--next { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2015%2015'%3E%3Cg%3E%3Cpath%20fill%3D'%23007aff'%20d%3D'M1%2C1.6l11.8%2C5.8L1%2C13.4V1.6%20M0%2C0v15l15-7.6L0%2C0L0%2C0z'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); +} +.wux-calendar__icon--prev { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2015%2015'%3E%3Cg%3E%3Cpath%20fill%3D'%23007aff'%20d%3D'M14%2C1.6v11.8L2.2%2C7.6L14%2C1.6%20M15%2C0L0%2C7.6L15%2C15V0L15%2C0z'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); +} +.wux-calendar__value { + -webkit-flex-shrink: 1; + flex-shrink: 1; + position: relative; + overflow: hidden; + text-overflow: ellipsis; + float: left; + width: 50%; + height: 2.2rem; +} +.wux-calendar__weekdays { + height: 36rpx; + background: #f7f7f8; + display: -webkit-box; + display: -webkit-flex; + display: flex; + font-size: 22rpx; + box-sizing: border-box; + position: relative; +} +.wux-calendar__weekdays:after { + content: ''; + position: absolute; + left: 0; + bottom: 0; + right: auto; + top: auto; + height: 2rpx; + width: 100%; + background-color: #c4c4c4; + display: block; + z-index: 15; + -webkit-transform-origin: 50% 100%; + transform-origin: 50% 100%; +} +.wux-calendar__weekdays + .wux-calendar__months { + height: calc(82%); +} +@media only screen and (-webkit-min-device-pixel-ratio: 2) { + .wux-calendar__weekdays:after { + -webkit-transform: scaleY(0.5); + transform: scaleY(0.5); + } +} +@media only screen and (-webkit-min-device-pixel-ratio: 3) { + .wux-calendar__weekdays:after { + -webkit-transform: scaleY(0.33); + transform: scaleY(0.33); + } +} +.wux-calendar__weekday { + -webkit-flex-shrink: 1; + flex-shrink: 1; + width: 14.28571429%; + width: calc(14.28571429%); + line-height: 34rpx; + text-align: center; +} +.wux-calendar__months { + width: 100%; + height: 100%; + overflow: hidden; + position: relative; +} +.wux-calendar__months-content { + width: 100%; + height: 100%; + display: -webkit-box; + display: -webkit-flex; + display: flex; + position: relative; + -webkit-backface-visibility: hidden; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +.wux-calendar__month { + display: -webkit-box; + display: -webkit-flex; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + flex-direction: column; + width: 100%; + height: 100%; + position: absolute; + left: 0; + top: 0; +} +.wux-calendar__days { + height: 16.66666667%; + height: calc(16.66666667%); + display: -webkit-box; + display: -webkit-flex; + display: flex; + -webkit-flex-shrink: 1; + flex-shrink: 1; + width: 100%; + position: relative; +} +.wux-calendar__days:after { + content: ''; + position: absolute; + left: 0; + bottom: 0; + right: auto; + top: auto; + height: 2rpx; + width: 100%; + background-color: #cccccc; + display: block; + z-index: 15; + -webkit-transform-origin: 50% 100%; + transform-origin: 50% 100%; +} +.wux-calendar__days:last-child:after { + display: none; +} +@media only screen and (-webkit-min-device-pixel-ratio: 2) { + .wux-calendar__days:after { + -webkit-transform: scaleY(0.5); + transform: scaleY(0.5); + } +} +@media only screen and (-webkit-min-device-pixel-ratio: 3) { + .wux-calendar__days:after { + -webkit-transform: scaleY(0.33); + transform: scaleY(0.33); + } +} +.wux-calendar__day { + -webkit-flex-shrink: 1; + flex-shrink: 1; + display: -webkit-box; + display: -webkit-flex; + display: flex; + -webkit-box-pack: center; + -webkit-justify-content: center; + justify-content: center; + -webkit-box-align: center; + -webkit-align-items: center; + align-items: center; + box-sizing: border-box; + width: 14.28571429%; + width: calc(14.28571429%); + text-align: center; + color: #3d4145; + font-size: 30rpx; + cursor: pointer; +} +.wux-calendar__day--prev, +.wux-calendar__day--next { + color: #cccccc; +} +.wux-calendar__day--disabled { + color: #d4d4d4; + cursor: auto; +} +.wux-calendar__day--today .wux-calendar__text { + background: #e3e3e3; +} +.wux-calendar__day--selected .wux-calendar__text { + background: #0894ec; + color: #fff; +} +.wux-calendar__text { + display: inline-block; + border-radius: 100%; + width: 60rpx; + height: 60rpx; + line-height: 60rpx; +} diff --git a/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell-group/index.js b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell-group/index.js new file mode 100644 index 0000000000000000000000000000000000000000..1fc9cce32c7b3a12bcced952c8cf6cb131bfe336 --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell-group/index.js @@ -0,0 +1,38 @@ +Component({ + externalClasses: ['wux-class'], + relations: { + '../cell/index': { + type: 'child', + linked() { + this.updateIsLastElement('../cell/index') + }, + linkChanged() { + this.updateIsLastElement('../cell/index') + }, + unlinked() { + this.updateIsLastElement('../cell/index') + }, + }, + }, + properties: { + title: { + type: String, + value: '', + }, + label: { + type: String, + value: '', + }, + }, + methods: { + updateIsLastElement() { + const elements = this.getRelationNodes('../cell/index') + if (elements.length > 0) { + const lastIndex = elements.length - 1 + elements.forEach((element, index) => { + element.updateIsLastElement(index === lastIndex) + }) + } + }, + }, +}) \ No newline at end of file diff --git a/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell-group/index.json b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell-group/index.json new file mode 100644 index 0000000000000000000000000000000000000000..fba482a42bfc985e328144eb7f5cc005680b7c57 --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell-group/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} \ No newline at end of file diff --git a/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell-group/index.wxml b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell-group/index.wxml new file mode 100644 index 0000000000000000000000000000000000000000..3fa656dbd47d8b791f2052224f979dca6ac2bbbe --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell-group/index.wxml @@ -0,0 +1,7 @@ + + {{ title }} + + + + {{ label }} + \ No newline at end of file diff --git a/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell-group/index.wxss b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell-group/index.wxss new file mode 100644 index 0000000000000000000000000000000000000000..44d9831ff296d5e7e2f8c70d52cc99b5901a74c0 --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell-group/index.wxss @@ -0,0 +1,33 @@ +.wux-cell-group__hd { + padding: 30rpx 30rpx 18rpx; + font-size: 28rpx; + color: #888; + width: 100%; + box-sizing: border-box; +} +.wux-cell-group__bd { + position: relative; + background-color: #fff; +} +.wux-cell-group__bd:after { + content: " "; + position: absolute; + top: 0; + left: 0; + width: 200%; + height: 200%; + -webkit-transform: scale(0.5); + transform: scale(0.5); + -webkit-transform-origin: 0 0; + transform-origin: 0 0; + pointer-events: none; + box-sizing: border-box; + border: 0 solid #D9D9D9; + border-top-width: 2rpx; + border-bottom-width: 2rpx; +} +.wux-cell-group__ft { + padding: 18rpx 30rpx 30rpx; + font-size: 28rpx; + color: #888; +} diff --git a/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell/index.js b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell/index.js new file mode 100644 index 0000000000000000000000000000000000000000..15cafabd671aa50afe65cda5a311f01673b0d0ce --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell/index.js @@ -0,0 +1,79 @@ +Component({ + externalClasses: ['wux-class'], + options: { + multipleSlots: true, + }, + relations: { + '../cell-group/index': { + type: 'parent', + }, + }, + data: { + isLast: false, + }, + properties: { + hoverClass: { + type: String, + value: 'wux-cell--hover', + }, + thumb: { + type: String, + value: '', + }, + title: { + type: String, + value: '', + }, + label: { + type: String, + value: '', + }, + extra: { + type: String, + value: '', + }, + isLink: { + type: Boolean, + value: false, + }, + openType: { + type: String, + value: 'navigateTo', + }, + url: { + type: String, + value: '', + }, + delta: { + type: Number, + value: 1, + }, + }, + methods: { + onTap() { + const { url, isLink, openType, delta } = this.data + const navigate = [ + 'navigateTo', + 'redirectTo', + 'switchTab', + 'navigateBack', + 'reLaunch', + ] + + this.triggerEvent('click') + + if (!isLink || !url) { + return false + } else if (!navigate.includes(openType)) { + return console.warn('openType 属性可选值为 navigateTo、redirectTo、switchTab、navigateBack、reLaunch', openType) + } else if (openType === 'navigateBack') { + return wx[openType].call(wx, { delta }) + } else { + return wx[openType].call(wx, { url }) + } + }, + updateIsLastElement(isLast) { + this.setData({ isLast }) + }, + }, +}) \ No newline at end of file diff --git a/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell/index.json b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell/index.json new file mode 100644 index 0000000000000000000000000000000000000000..fba482a42bfc985e328144eb7f5cc005680b7c57 --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} \ No newline at end of file diff --git a/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell/index.wxml b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell/index.wxml new file mode 100644 index 0000000000000000000000000000000000000000..1437d3daa4a54d4c937d949f3ad0b6d5c4a8f6a0 --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell/index.wxml @@ -0,0 +1,21 @@ + + + + + + + + + + + {{ title }} + {{ label }} + + + + {{ extra }} + + + + + \ No newline at end of file diff --git a/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell/index.wxss b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell/index.wxss new file mode 100644 index 0000000000000000000000000000000000000000..488b886fdee04a323b5b79d8b1eec9c01a1fceef --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/cell/index.wxss @@ -0,0 +1,77 @@ +.wux-cell { + padding: 20rpx 30rpx; + position: relative; + display: -webkit-box; + display: -webkit-flex; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + align-items: center; + background: #fff; +} +.wux-cell:after { + content: " "; + position: absolute; + left: 0; + bottom: 0; + right: 0; + height: 2rpx; + border-bottom: 2rpx solid #D9D9D9; + color: #D9D9D9; + -webkit-transform-origin: 0 100%; + transform-origin: 0 100%; + -webkit-transform: scaleY(0.5); + transform: scaleY(0.5); + left: 30rpx; +} +.wux-cell--last:after { + display: none; +} +.wux-cell--hover { + background-color: #ECECEC; +} +.wux-cell__thumb { + display: block; + width: 40rpx; + height: 40rpx; + margin-right: 10rpx; +} +.wux-cell__bd { + -webkit-box-flex: 1; + -webkit-flex: 1; + flex: 1; +} +.wux-cell__text { + text-align: left; +} +.wux-cell__desc { + text-align: left; + line-height: 1.2; + font-size: 24rpx; + color: #808080; +} +.wux-cell__ft { + text-align: right; + color: #808080; +} +.wux-cell--access .wux-cell__ft { + padding-right: 26rpx; + position: relative; +} +.wux-cell--access .wux-cell__ft:after { + content: " "; + display: inline-block; + height: 12rpx; + width: 12rpx; + border-width: 4rpx 4rpx 0 0; + border-color: #C8C8CD; + border-style: solid; + -webkit-transform: matrix(0.71, 0.71, -0.71, 0.71, 0, 0); + transform: matrix(0.71, 0.71, -0.71, 0.71, 0, 0); + position: relative; + top: -4rpx; + position: absolute; + top: 50%; + margin-top: -8rpx; + right: 4rpx; +} diff --git a/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/countdown/index.js b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/countdown/index.js new file mode 100644 index 0000000000000000000000000000000000000000..59ca76deb912faad252923725915628d87225ffc --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/countdown/index.js @@ -0,0 +1,176 @@ +class Countdown { + constructor(options = {}, page = getCurrentPages()[getCurrentPages().length - 1]) { + Object.assign(this, { + page, + options, + }) + this.__init() + } + + /** + * 初始化 + */ + __init() { + this.setData = this.page.setData.bind(this.page) + this.restart(this.options) + } + + /** + * 默认参数 + */ + setDefaults() { + return { + date: `June 7, 2087 15:03:25`, + refresh: 1000, + offset: 0, + onEnd() {}, + render(date) {}, + } + } + + /** + * 合并参数 + */ + mergeOptions(options) { + const defaultOptions = this.setDefaults() + + for (let i in defaultOptions) { + if (defaultOptions.hasOwnProperty(i)) { + this.options[i] = typeof options[i] !== `undefined` ? options[i] : defaultOptions[i] + + if (i === `date` && typeof this.options.date !== `object`) { + this.options.date = new Date(this.options.date) + } + + if (typeof this.options[i] === `function`) { + this.options[i] = this.options[i].bind(this) + } + } + } + + if (typeof this.options.date !== `object`) { + this.options.date = new Date(this.options.date) + } + } + + /** + * 计算日期差 + */ + getDiffDate() { + let diff = (this.options.date.getTime() - Date.now() + this.options.offset) / 1000 + + let dateData = { + years: 0, + days: 0, + hours: 0, + min: 0, + sec: 0, + millisec: 0, + } + + if (diff <= 0) { + if (this.interval) { + this.stop() + this.options.onEnd() + } + return dateData + } + + if (diff >= (365.25 * 86400)) { + dateData.years = Math.floor(diff / (365.25 * 86400)) + diff -= dateData.years * 365.25 * 86400 + } + + if (diff >= 86400) { + dateData.days = Math.floor(diff / 86400) + diff -= dateData.days * 86400 + } + + if (diff >= 3600) { + dateData.hours = Math.floor(diff / 3600) + diff -= dateData.hours * 3600 + } + + if (diff >= 60) { + dateData.min = Math.floor(diff / 60) + diff -= dateData.min * 60 + } + + dateData.sec = Math.round(diff) + + dateData.millisec = diff % 1 * 1000 + + return dateData + } + + /** + * 补零 + */ + leadingZeros(num, length = 2) { + num = String(num) + if (num.length > length) return num + return (Array(length + 1).join(`0`) + num).substr(-length) + } + + /** + * 更新组件 + */ + update(newDate) { + this.options.date = typeof newDate !== `object` ? new Date(newDate) : newDate + this.render() + return this + } + + /** + * 停止倒计时 + */ + stop() { + if (this.interval) { + clearInterval(this.interval) + this.interval = !1 + } + return this + } + + /** + * 渲染组件 + */ + render() { + this.options.render(this.getDiffDate()) + return this + } + + /** + * 启动倒计时 + */ + start() { + if (this.interval) return !1 + this.render() + if (this.options.refresh) { + this.interval = setInterval(() => { + this.render() + }, this.options.refresh) + } + return this + } + + /** + * 更新offset + */ + updateOffset(offset) { + this.options.offset = offset + return this + } + + /** + * 重启倒计时 + */ + restart(options = {}) { + this.mergeOptions(options) + this.interval = !1 + this.start() + return this + } +} + +export default Countdown \ No newline at end of file diff --git a/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/countup/index.js b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/countup/index.js new file mode 100644 index 0000000000000000000000000000000000000000..7b8894ebf7c6ce17885e479c29ad98714089c85b --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/countup/index.js @@ -0,0 +1,220 @@ +class CountUp { + constructor(startVal, endVal, decimals, duration, options = {}, page = getCurrentPages()[getCurrentPages().length - 1]) { + Object.assign(this, { + page, + startVal, + endVal, + decimals, + duration, + options, + }) + this.__init() + } + + /** + * 初始化 + */ + __init() { + this.setData = this.page.setData.bind(this.page) + + this.lastTime = 0 + + // merge options + this.mergeOptions(this.options) + + this.startVal = Number(this.startVal) + this.cacheVal = this.startVal + this.endVal = Number(this.endVal) + this.countDown = (this.startVal > this.endVal) + this.frameVal = this.startVal + this.decimals = Math.max(0, this.decimals || 0) + this.dec = Math.pow(10, this.decimals) + this.duration = Number(this.duration) * 1000 || 2000 + + // format startVal on initialization + this.printValue(this.formattingFn(this.startVal)) + } + + /** + * 默认参数 + */ + setDefaultOptions() { + return { + useEasing: true, // toggle easing + useGrouping: true, // 1,000,000 vs 1000000 + separator: `,`, // character to use as a separator + decimal: `.`, // character to use as a decimal + easingFn: null, // optional custom easing closure function, default is Robert Penner's easeOutExpo + formattingFn: null, // optional custom formatting function, default is this.formatNumber below + printValue(value) {}, // printValue + } + } + + /** + * 合并参数 + */ + mergeOptions(options) { + const defaultOptions = this.setDefaultOptions() + + // extend default options with passed options object + for (let key in defaultOptions) { + if (defaultOptions.hasOwnProperty(key)) { + this.options[key] = typeof options[key] !== `undefined` ? options[key] : defaultOptions[key] + if (typeof this.options[key] === `function`) { + this.options[key] = this.options[key].bind(this) + } + } + } + + if (this.options.separator === ``) { this.options.useGrouping = !1 } + if (!this.options.prefix) this.options.prefix = `` + if (!this.options.suffix) this.options.suffix = `` + + this.easingFn = this.options.easingFn ? this.options.easingFn : this.easeOutExpo + this.formattingFn = this.options.formattingFn ? this.options.formattingFn : this.formatNumber + this.printValue = this.options.printValue ? this.options.printValue : function() {} + } + + /** + * 创建定时器 + */ + requestAnimationFrame(callback) { + let currTime = new Date().getTime() + let timeToCall = Math.max(0, 16 - (currTime - this.lastTime)) + let timeout = setTimeout(() => { + callback.bind(this)(currTime + timeToCall) + }, timeToCall) + this.lastTime = currTime + timeToCall + return timeout + } + + /** + * 清空定时器 + */ + cancelAnimationFrame(timeout) { + clearTimeout(timeout) + } + + /** + * 格式化数字 + */ + formatNumber(nStr) { + nStr = nStr.toFixed(this.decimals) + nStr += `` + let x, x1, x2, rgx + x = nStr.split(`.`) + x1 = x[0] + x2 = x.length > 1 ? this.options.decimal + x[1] : `` + rgx = /(\d+)(\d{3})/ + if (this.options.useGrouping) { + while (rgx.test(x1)) { + x1 = x1.replace(rgx, `$1` + this.options.separator + `$2`) + } + } + return this.options.prefix + x1 + x2 + this.options.suffix + } + + /** + * 过渡效果 + */ + easeOutExpo(t, b, c, d) { + return c * (-Math.pow(2, -10 * t / d) + 1) * 1024 / 1023 + b + } + + /** + * 计数函数 + */ + count(timestamp) { + if (!this.startTime) { this.startTime = timestamp } + + this.timestamp = timestamp + const progress = timestamp - this.startTime + this.remaining = this.duration - progress + + // to ease or not to ease + if (this.options.useEasing) { + if (this.countDown) { + this.frameVal = this.startVal - this.easingFn(progress, 0, this.startVal - this.endVal, this.duration) + } else { + this.frameVal = this.easingFn(progress, this.startVal, this.endVal - this.startVal, this.duration) + } + } else { + if (this.countDown) { + this.frameVal = this.startVal - ((this.startVal - this.endVal) * (progress / this.duration)) + } else { + this.frameVal = this.startVal + (this.endVal - this.startVal) * (progress / this.duration) + } + } + + // don't go past endVal since progress can exceed duration in the last frame + if (this.countDown) { + this.frameVal = (this.frameVal < this.endVal) ? this.endVal : this.frameVal + } else { + this.frameVal = (this.frameVal > this.endVal) ? this.endVal : this.frameVal + } + + // decimal + this.frameVal = Math.round(this.frameVal * this.dec) / this.dec + + // format and print value + this.printValue(this.formattingFn(this.frameVal)) + + // whether to continue + if (progress < this.duration) { + this.rAF = this.requestAnimationFrame(this.count) + } else { + if (this.callback) { this.callback() } + } + } + + /** + * 启动计数器 + */ + start(callback) { + this.callback = callback + this.rAF = this.requestAnimationFrame(this.count) + return !1 + } + + /** + * 停止计数器 + */ + pauseResume() { + if (!this.paused) { + this.paused = !0 + this.cancelAnimationFrame(this.rAF) + } else { + this.paused = !1 + delete this.startTime + this.duration = this.remaining + this.startVal = this.frameVal + this.requestAnimationFrame(this.count) + } + } + + /** + * 重置计数器 + */ + reset() { + this.paused = !1 + delete this.startTime + this.startVal = this.cacheVal + this.cancelAnimationFrame(this.rAF) + this.printValue(this.formattingFn(this.startVal)) + } + + /** + * 更新计数器 + */ + update(newEndVal) { + this.cancelAnimationFrame(this.rAF) + this.paused = !1 + delete this.startTime + this.startVal = this.frameVal + this.endVal = Number(newEndVal) + this.countDown = (this.startVal > this.endVal) + this.rAF = this.requestAnimationFrame(this.count) + } +} + +export default CountUp \ No newline at end of file diff --git a/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/index.js b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/index.js new file mode 100644 index 0000000000000000000000000000000000000000..a0422d68d3cb6fd06fec81f478b5b3a7f913d0b4 --- /dev/null +++ b/examples/wxcomponents-template/wxcomponents/wux-weapp/dist/index.js @@ -0,0 +1,47 @@ +import $wuxCountDown from './countdown/index' +import $wuxCountUp from './countup/index' + +/** + * 使用选择器选择组件实例节点,返回匹配到的第一个组件实例对象 + * @param {String} selector 节点选择器 + * @param {Object} ctx 页面栈或组件的实例,默认为当前页面栈实例 + */ +const getCtx = (selector, ctx = getCurrentPages()[getCurrentPages().length - 1]) => { + const componentCtx = ctx.selectComponent(selector) + + if (!componentCtx) { + throw new Error('无法找到对应的组件,请按文档说明使用组件') + } + + return componentCtx +} + +const $wuxActionSheet = (selector = '#wux-actionsheet', ctx) => getCtx(selector, ctx) +const $wuxBackdrop = (selector = '#wux-backdrop', ctx) => getCtx(selector, ctx) +const $wuxToast = (selector = '#wux-toast', ctx) => getCtx(selector, ctx) +const $wuxLoading = (selector = '#wux-loading', ctx) => getCtx(selector, ctx) +const $wuxDialog = (selector = '#wux-dialog', ctx) => getCtx(selector, ctx) +const $wuxToptips = (selector = '#wux-toptips', ctx) => getCtx(selector, ctx) +const $wuxGallery = (selector = '#wux-gallery', ctx) => getCtx(selector, ctx) +const $wuxNotification = (selector = '#wux-notification', ctx) => getCtx(selector, ctx) +const $wuxKeyBoard = (selector = '#wux-keyboard', ctx) => getCtx(selector, ctx) +const $wuxSelect = (selector = '#wux-select', ctx) => getCtx(selector, ctx) +const $wuxCalendar = (selector = '#wux-calendar', ctx) => getCtx(selector, ctx) +const $stopWuxRefresher = (selector = '#wux-refresher', ctx) => getCtx(selector, ctx).finishPullToRefresh() + +export { + $wuxActionSheet, + $wuxBackdrop, + $wuxToast, + $wuxLoading, + $wuxDialog, + $wuxToptips, + $wuxGallery, + $wuxNotification, + $wuxKeyBoard, + $wuxSelect, + $wuxCalendar, + $stopWuxRefresher, + $wuxCountDown, + $wuxCountUp, +} \ No newline at end of file