From c43c7a502c4f11a603afbcc047935dfe758642ce Mon Sep 17 00:00:00 2001 From: neverland Date: Wed, 5 Sep 2018 18:00:46 +0800 Subject: [PATCH] [new feature] add Dialog component (#504) --- dist/button/index.js | 30 ++++-------- dist/button/index.wxml | 2 +- dist/button/index.wxss | 2 +- dist/dialog/dialog.js | 66 +++++++++++++++++++++++++++ dist/dialog/index.js | 81 +++++++++++++++++++++++++++++++++ dist/dialog/index.json | 7 +++ dist/dialog/index.wxml | 36 +++++++++++++++ dist/dialog/index.wxss | 1 + dist/tabs/index.wxss | 2 +- example/pages/dialog/index.js | 47 ++++++++++++++++++- example/pages/dialog/index.json | 1 + example/pages/dialog/index.wxml | 34 ++++++++++++++ packages/dialog/dialog.js | 66 +++++++++++++++++++++++++++ packages/dialog/index.js | 81 +++++++++++++++++++++++++++++++++ packages/dialog/index.json | 7 +++ packages/dialog/index.pcss | 61 +++++++++++++++++++++++++ packages/dialog/index.wxml | 36 +++++++++++++++ 17 files changed, 536 insertions(+), 24 deletions(-) create mode 100644 dist/dialog/dialog.js create mode 100644 dist/dialog/index.js create mode 100644 dist/dialog/index.json create mode 100644 dist/dialog/index.wxml create mode 100644 dist/dialog/index.wxss diff --git a/dist/button/index.js b/dist/button/index.js index 2247c09f..98d38b8f 100644 --- a/dist/button/index.js +++ b/dist/button/index.js @@ -1,6 +1,11 @@ import buttonBehaviors from '../behaviors/button'; import classnames from '../common/classnames'; +const booleanProp = { + type: Boolean, + observer: 'setClasses' +}; + Component({ options: { addGlobalClass: true @@ -21,26 +26,11 @@ Component({ value: 'normal', observer: 'setClasses' }, - plain: { - type: Boolean, - observer: 'setClasses' - }, - disabled: { - type: Boolean, - observer: 'setClasses' - }, - loading: { - type: Boolean, - observer: 'setClasses' - }, - block: { - type: Boolean, - observer: 'setClasses' - }, - square: { - type: Boolean, - observer: 'setClasses' - } + plain: booleanProp, + block: booleanProp, + square: booleanProp, + loading: booleanProp, + disabled: booleanProp }, attached() { diff --git a/dist/button/index.wxml b/dist/button/index.wxml index 7f6a2e0c..8d1be79a 100644 --- a/dist/button/index.wxml +++ b/dist/button/index.wxml @@ -26,5 +26,5 @@ custom-class="loading-class" color="{{ type === 'default' ? '#c9c9c9' : '#fff' }}" /> - + diff --git a/dist/button/index.wxss b/dist/button/index.wxss index f84b5d1e..ac06007d 100644 --- a/dist/button/index.wxss +++ b/dist/button/index.wxss @@ -1 +1 @@ -.van-button{position:relative;padding:0;display:inline-block;height:44px;line-height:42px;border-radius:3px;box-sizing:border-box;font-size:16px;text-align:center;vertical-align:middle;-webkit-appearance:none;-webkit-text-size-adjust:100%}.van-button::after{content:" ";position:absolute;top:50%;left:50%;opacity:0;width:100%;height:100%;border:inherit;border-color:#000;background-color:#000;border-radius:inherit;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.van-button:active::after{opacity:.3}.van-button--unclickable::after{display:none}.van-button--default{color:#333;background-color:#fff;border:1px solid #e5e5e5}.van-button--primary{color:#fff;background-color:#4b0;border:1px solid #4b0}.van-button--danger{color:#fff;background-color:#f44;border:1px solid #f44}.van-button--warning{color:#fff;background-color:#f85;border:1px solid #f85}.van-button--plain{background-color:#fff}.van-button--plain.van-button--primary{color:#4b0}.van-button--plain.van-button--danger{color:#f44}.van-button--plain.van-button--warning{color:#f85}.van-button--large{width:100%;height:50px;line-height:48px}.van-button--normal{padding:0 15px;font-size:14px}.van-button--small{height:30px;padding:0 8px;min-width:60px;font-size:12px;line-height:28px}.van-button--loading .van-loading{display:inline-block}.van-button--loading .van-button__text{display:none}.van-button--mini{display:inline-block;width:50px;height:22px;line-height:20px;font-size:10px}.van-button--mini+.van-button--mini{margin-left:5px}.van-button--block{width:100%;display:block}.van-button--square{border-radius:0}.van-button--disabled{color:#999;background-color:#e8e8e8;border:1px solid #e5e5e5} \ No newline at end of file +.van-button{position:relative;padding:0;display:inline-block;height:44px;line-height:42px;border-radius:3px;box-sizing:border-box;font-size:16px;text-align:center;vertical-align:middle;-webkit-appearance:none;-webkit-text-size-adjust:100%}.van-button::after{content:" ";position:absolute;top:50%;left:50%;opacity:0;width:100%;height:100%;border:inherit;border-color:#000;background-color:#000;border-radius:inherit;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.van-button:active::after{opacity:.3}.van-button--unclickable::after{display:none}.van-button--default{color:#333;background-color:#fff;border:1px solid #e5e5e5}.van-button--primary{color:#fff;background-color:#4b0;border:1px solid #4b0}.van-button--danger{color:#fff;background-color:#f44;border:1px solid #f44}.van-button--warning{color:#fff;background-color:#f85;border:1px solid #f85}.van-button--plain{background-color:#fff}.van-button--plain.van-button--primary{color:#4b0}.van-button--plain.van-button--danger{color:#f44}.van-button--plain.van-button--warning{color:#f85}.van-button--large{width:100%;height:50px;line-height:48px}.van-button--normal{padding:0 15px;font-size:14px}.van-button--small{height:30px;padding:0 8px;min-width:60px;font-size:12px;line-height:28px}.van-button--mini{display:inline-block;width:50px;height:22px;line-height:20px;font-size:10px}.van-button--mini+.van-button--mini{margin-left:5px}.van-button--block{width:100%;display:block}.van-button--square{border-radius:0}.van-button--disabled{color:#999;background-color:#e8e8e8;border:1px solid #e5e5e5} \ No newline at end of file diff --git a/dist/dialog/dialog.js b/dist/dialog/dialog.js new file mode 100644 index 00000000..6148ab00 --- /dev/null +++ b/dist/dialog/dialog.js @@ -0,0 +1,66 @@ +let queue = []; + +const Dialog = options => { + return new Promise((resolve, reject) => { + const pages = getCurrentPages(); + const ctx = pages[pages.length - 1]; + + const dialog = ctx.selectComponent(options.selector); + delete options.selector; + + if (dialog) { + dialog.setData({ + onCancel: reject, + onConfirm: resolve, + ...options + }); + queue.push(dialog); + } + }); +}; + +Dialog.defaultOptions = { + show: true, + title: '', + message: '', + overlay: true, + selector: '#van-dialog', + beforeClose: null, + confirmButtonText: '确认', + cancelButtonText: '取消', + showConfirmButton: true, + showCancelButton: false, + closeOnClickOverlay: false +}; + +Dialog.alert = options => + Dialog({ + ...Dialog.currentOptions, + ...options + }); + +Dialog.confirm = options => + Dialog({ + ...Dialog.currentOptions, + showCancelButton: true, + ...options + }); + +Dialog.close = () => { + queue.forEach(dialog => { + dialog.close(); + }); + queue = []; +}; + +Dialog.setDefaultOptions = options => { + Object.assign(Dialog.currentOptions, options); +}; + +Dialog.resetDefaultOptions = () => { + Dialog.currentOptions = { ...Dialog.defaultOptions }; +}; + +Dialog.resetDefaultOptions(); + +export default Dialog; diff --git a/dist/dialog/index.js b/dist/dialog/index.js new file mode 100644 index 00000000..be129287 --- /dev/null +++ b/dist/dialog/index.js @@ -0,0 +1,81 @@ +Component({ + options: { + addGlobalClass: true + }, + + properties: { + title: String, + message: String, + useSlot: Boolean, + asyncClose: Boolean, + showCancelButton: Boolean, + show: { + type: Boolean, + observer(show) { + if (!show) { + this.setData({ + loading: { + confirm: false, + cancel: false + } + }); + } + } + }, + confirmButtonText: { + type: String, + value: '确认' + }, + cancelButtonText: { + type: String, + value: '取消' + }, + showConfirmButton: { + type: Boolean, + value: true + }, + overlay: { + type: Boolean, + value: true + }, + closeOnClickOverlay: { + type: Boolean, + value: false + } + }, + + data: { + loading: { + confirm: false, + cancel: false + } + }, + + methods: { + onConfirm() { + this.handleAction('confirm'); + }, + + onCancel() { + this.handleAction('cancel'); + }, + + handleAction(action) { + if (this.data.asyncClose) { + this.setData({ + [`loading.${action}`]: true + }); + } + + this.onClose(action); + }, + + onClose(action) { + if (!this.data.asyncClose) { + this.setData({ show: false }); + } + this.triggerEvent('close', action); + this.triggerEvent(action); + } + } +}); diff --git a/dist/dialog/index.json b/dist/dialog/index.json new file mode 100644 index 00000000..e2ee09ae --- /dev/null +++ b/dist/dialog/index.json @@ -0,0 +1,7 @@ +{ + "component": true, + "usingComponents": { + "van-popup": "../popup/index", + "van-button": "../button/index" + } +} diff --git a/dist/dialog/index.wxml b/dist/dialog/index.wxml new file mode 100644 index 00000000..7176e4e3 --- /dev/null +++ b/dist/dialog/index.wxml @@ -0,0 +1,36 @@ + + + {{ title }} + + + + + {{ message }} + + + + + + {{ cancelButtonText }} + + + + + {{ confirmButtonText }} + + + + diff --git a/dist/dialog/index.wxss b/dist/dialog/index.wxss new file mode 100644 index 00000000..3979491e --- /dev/null +++ b/dist/dialog/index.wxss @@ -0,0 +1 @@ +.van-hairline,.van-hairline--bottom,.van-hairline--left,.van-hairline--right,.van-hairline--surround,.van-hairline--top,.van-hairline--top-bottom{position:relative}.van-hairline--bottom::after,.van-hairline--left::after,.van-hairline--right::after,.van-hairline--surround::after,.van-hairline--top-bottom::after,.van-hairline--top::after,.van-hairline::after{content:'';position:absolute;top:0;left:0;width:200%;height:200%;-webkit-transform:scale(.5);transform:scale(.5);-webkit-transform-origin:0 0;transform-origin:0 0;pointer-events:none;box-sizing:border-box;border:0 solid #e5e5e5}.van-hairline--top::after{border-top-width:1px}.van-hairline--left::after{border-left-width:1px}.van-hairline--right::after{border-right-width:1px}.van-hairline--bottom::after{border-bottom-width:1px}.van-hairline--top-bottom::after{border-width:1px 0}.van-hairline--surround::after{border-width:1px}.van-dialog{width:85%;font-size:16px;overflow:hidden;border-radius:4px;background-color:#fff}.van-dialog__header{padding:15px 0 0;text-align:center}.van-dialog__header--isolated{padding:25px 0}.van-dialog__message{line-height:1.5;padding:15px 20px}.van-dialog__message--has-title{color:#999;font-size:14px}.van-dialog__footer{display:-webkit-box;display:-webkit-flex;display:flex;overflow:hidden;-webkit-user-select:none;user-select:none}.van-dialog__button{-webkit-box-flex:1;-webkit-flex:1;flex:1}.van-dialog__cancel,.van-dialog__confirm{border:0!important}.van-dialog__confirm,.van-dialog__confirm:active{color:#00c000!important}.van-dialog-bounce-enter{opacity:0;-webkit-transform:translate3d(-50%,-50%,0) scale(.7);transform:translate3d(-50%,-50%,0) scale(.7)}.van-dialog-bounce-leave-active{opacity:0;-webkit-transform:translate3d(-50%,-50%,0) scale(.9);transform:translate3d(-50%,-50%,0) scale(.9)} \ No newline at end of file diff --git a/dist/tabs/index.wxss b/dist/tabs/index.wxss index 10ca63cb..f7592c1f 100644 --- a/dist/tabs/index.wxss +++ b/dist/tabs/index.wxss @@ -1 +1 @@ -.van-tabs{position:relative;-webkit-tap-highlight-color:transparent}.van-tabs__wrap{top:0;left:0;right:0;z-index:99;position:absolute}.van-tabs__wrap--page-top{position:fixed}.van-tabs__wrap--content-bottom{top:auto;bottom:0}.van-tabs__wrap--scrollable .van-tab{-webkit-box-flex:0;-webkit-flex:0 0 22%;flex:0 0 22%}.van-tabs__nav{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-user-select:none;user-select:none;position:relative;background-color:#fff}.van-tabs__nav--line{height:100%}.van-tabs__nav--card{margin:0 15px;border-radius:2px;box-sizing:border-box;border:1px solid #f44;height:30px}.van-tabs__nav--card .van-tab{color:#f44;border-right:1px solid #f44;line-height:28px}.van-tabs__nav--card .van-tab:last-child{border-right:none}.van-tabs__nav--card .van-tab.van-tab--active{color:#fff;background-color:#f44}.van-tabs__line{z-index:1;left:0;bottom:0;height:2px;position:absolute;background-color:#f44}.van-tabs--line{padding-top:44px}.van-tabs--line .van-tabs__wrap{height:44px}.van-tabs--card{padding-top:30px}.van-tabs--card .van-tabs__wrap{height:30px}.van-tab{-webkit-box-flex:1;-webkit-flex:1;flex:1;cursor:pointer;padding:0 5px;font-size:14px;position:relative;color:#333;line-height:44px;text-align:center;box-sizing:border-box;background-color:#fff;min-width:0}.van-tab span{display:block}.van-tab:active{background-color:#e8e8e8}.van-tab--active{color:#f44}.van-tab--disabled{color:#c9c9c9}.van-tab--disabled:active{background-color:#fff} \ No newline at end of file +.van-hairline,.van-hairline--bottom,.van-hairline--left,.van-hairline--right,.van-hairline--surround,.van-hairline--top,.van-hairline--top-bottom{position:relative}.van-hairline--bottom::after,.van-hairline--left::after,.van-hairline--right::after,.van-hairline--surround::after,.van-hairline--top-bottom::after,.van-hairline--top::after,.van-hairline::after{content:'';position:absolute;top:0;left:0;width:200%;height:200%;-webkit-transform:scale(.5);transform:scale(.5);-webkit-transform-origin:0 0;transform-origin:0 0;pointer-events:none;box-sizing:border-box;border:0 solid #e5e5e5}.van-hairline--top::after{border-top-width:1px}.van-hairline--left::after{border-left-width:1px}.van-hairline--right::after{border-right-width:1px}.van-hairline--bottom::after{border-bottom-width:1px}.van-hairline--top-bottom::after{border-width:1px 0}.van-hairline--surround::after{border-width:1px}.van-tabs{position:relative;-webkit-tap-highlight-color:transparent}.van-tabs__wrap{top:0;left:0;right:0;z-index:99;position:absolute}.van-tabs__wrap--page-top{position:fixed}.van-tabs__wrap--content-bottom{top:auto;bottom:0}.van-tabs__wrap--scrollable .van-tab{-webkit-box-flex:0;-webkit-flex:0 0 22%;flex:0 0 22%}.van-tabs__nav{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-user-select:none;user-select:none;position:relative;background-color:#fff}.van-tabs__nav--line{height:100%}.van-tabs__nav--card{margin:0 15px;border-radius:2px;box-sizing:border-box;border:1px solid #f44;height:30px}.van-tabs__nav--card .van-tab{color:#f44;border-right:1px solid #f44;line-height:28px}.van-tabs__nav--card .van-tab:last-child{border-right:none}.van-tabs__nav--card .van-tab.van-tab--active{color:#fff;background-color:#f44}.van-tabs__line{z-index:1;left:0;bottom:0;height:2px;position:absolute;background-color:#f44}.van-tabs--line{padding-top:44px}.van-tabs--line .van-tabs__wrap{height:44px}.van-tabs--card{padding-top:30px}.van-tabs--card .van-tabs__wrap{height:30px}.van-tab{-webkit-box-flex:1;-webkit-flex:1;flex:1;cursor:pointer;padding:0 5px;font-size:14px;position:relative;color:#333;line-height:44px;text-align:center;box-sizing:border-box;background-color:#fff;min-width:0}.van-tab span{display:block}.van-tab:active{background-color:#e8e8e8}.van-tab--active{color:#f44}.van-tab--disabled{color:#c9c9c9}.van-tab--disabled:active{background-color:#fff} \ No newline at end of file diff --git a/example/pages/dialog/index.js b/example/pages/dialog/index.js index cc11dfda..b5bbe1bf 100644 --- a/example/pages/dialog/index.js +++ b/example/pages/dialog/index.js @@ -1,3 +1,48 @@ import Page from '../../common/page'; +import Dialog from '../../dist/dialog/dialog'; -Page(); +Page({ + data: { + show: false, + username: '', + password: '' + }, + + showCustomDialog() { + this.setData({ show: true }); + }, + + onClickAlert() { + Dialog.alert({ + title: '标题', + message: '内容' + }); + }, + + onClickAlert2() { + Dialog.alert({ + message: '内容' + }); + }, + + onClickConfirm() { + Dialog.confirm({ + title: '标题', + message: '内容' + }); + }, + + onClose(event) { + if (event.detail === 'confirm') { + setTimeout(() => { + this.setData({ + show: false + }); + }, 1000); + } else { + this.setData({ + show: false + }); + } + } +}); diff --git a/example/pages/dialog/index.json b/example/pages/dialog/index.json index 0df4617d..cc5b26e6 100644 --- a/example/pages/dialog/index.json +++ b/example/pages/dialog/index.json @@ -2,6 +2,7 @@ "navigationBarTitleText": "Dialog 弹出框", "usingComponents": { "demo-block": "../../components/demo-block/index", + "van-field": "../../dist/field/index", "van-button": "../../dist/button/index", "van-dialog": "../../dist/dialog/index" } diff --git a/example/pages/dialog/index.wxml b/example/pages/dialog/index.wxml index e69de29b..73caac87 100644 --- a/example/pages/dialog/index.wxml +++ b/example/pages/dialog/index.wxml @@ -0,0 +1,34 @@ + + Alert + 无标题 Alert + + + + Confirm + + + + 高级用法 + + + + + + + diff --git a/packages/dialog/dialog.js b/packages/dialog/dialog.js index e69de29b..6148ab00 100644 --- a/packages/dialog/dialog.js +++ b/packages/dialog/dialog.js @@ -0,0 +1,66 @@ +let queue = []; + +const Dialog = options => { + return new Promise((resolve, reject) => { + const pages = getCurrentPages(); + const ctx = pages[pages.length - 1]; + + const dialog = ctx.selectComponent(options.selector); + delete options.selector; + + if (dialog) { + dialog.setData({ + onCancel: reject, + onConfirm: resolve, + ...options + }); + queue.push(dialog); + } + }); +}; + +Dialog.defaultOptions = { + show: true, + title: '', + message: '', + overlay: true, + selector: '#van-dialog', + beforeClose: null, + confirmButtonText: '确认', + cancelButtonText: '取消', + showConfirmButton: true, + showCancelButton: false, + closeOnClickOverlay: false +}; + +Dialog.alert = options => + Dialog({ + ...Dialog.currentOptions, + ...options + }); + +Dialog.confirm = options => + Dialog({ + ...Dialog.currentOptions, + showCancelButton: true, + ...options + }); + +Dialog.close = () => { + queue.forEach(dialog => { + dialog.close(); + }); + queue = []; +}; + +Dialog.setDefaultOptions = options => { + Object.assign(Dialog.currentOptions, options); +}; + +Dialog.resetDefaultOptions = () => { + Dialog.currentOptions = { ...Dialog.defaultOptions }; +}; + +Dialog.resetDefaultOptions(); + +export default Dialog; diff --git a/packages/dialog/index.js b/packages/dialog/index.js index e69de29b..be129287 100644 --- a/packages/dialog/index.js +++ b/packages/dialog/index.js @@ -0,0 +1,81 @@ +Component({ + options: { + addGlobalClass: true + }, + + properties: { + title: String, + message: String, + useSlot: Boolean, + asyncClose: Boolean, + showCancelButton: Boolean, + show: { + type: Boolean, + observer(show) { + if (!show) { + this.setData({ + loading: { + confirm: false, + cancel: false + } + }); + } + } + }, + confirmButtonText: { + type: String, + value: '确认' + }, + cancelButtonText: { + type: String, + value: '取消' + }, + showConfirmButton: { + type: Boolean, + value: true + }, + overlay: { + type: Boolean, + value: true + }, + closeOnClickOverlay: { + type: Boolean, + value: false + } + }, + + data: { + loading: { + confirm: false, + cancel: false + } + }, + + methods: { + onConfirm() { + this.handleAction('confirm'); + }, + + onCancel() { + this.handleAction('cancel'); + }, + + handleAction(action) { + if (this.data.asyncClose) { + this.setData({ + [`loading.${action}`]: true + }); + } + + this.onClose(action); + }, + + onClose(action) { + if (!this.data.asyncClose) { + this.setData({ show: false }); + } + this.triggerEvent('close', action); + this.triggerEvent(action); + } + } +}); diff --git a/packages/dialog/index.json b/packages/dialog/index.json index e69de29b..e2ee09ae 100644 --- a/packages/dialog/index.json +++ b/packages/dialog/index.json @@ -0,0 +1,7 @@ +{ + "component": true, + "usingComponents": { + "van-popup": "../popup/index", + "van-button": "../button/index" + } +} diff --git a/packages/dialog/index.pcss b/packages/dialog/index.pcss index e69de29b..e200ce14 100644 --- a/packages/dialog/index.pcss +++ b/packages/dialog/index.pcss @@ -0,0 +1,61 @@ +@import '../common/style/var.pcss'; +@import '../common/style/hairline.pcss'; + +.van-dialog { + width: 85%; + font-size: 16px; + overflow: hidden; + border-radius: 4px; + background-color: $white; + + &__header { + padding: 15px 0 0; + text-align: center; + + &--isolated { + padding: 25px 0; + } + } + + &__message { + line-height: 1.5; + padding: 15px 20px; + + &--has-title { + color: $gray-dark; + font-size: 14px; + } + } + + &__footer { + display: flex; + overflow: hidden; + user-select: none; + } + + &__button { + flex: 1; + } + + &__confirm, + &__cancel { + border: 0 !important; + } + + &__confirm { + &, + &:active { + color: #00c000 !important; + } + } + + &-bounce-enter { + opacity: 0; + transform: translate3d(-50%, -50%, 0) scale(0.7); + } + + &-bounce-leave-active { + opacity: 0; + transform: translate3d(-50%, -50%, 0) scale(0.9); + } +} diff --git a/packages/dialog/index.wxml b/packages/dialog/index.wxml index e69de29b..7176e4e3 100644 --- a/packages/dialog/index.wxml +++ b/packages/dialog/index.wxml @@ -0,0 +1,36 @@ + + + {{ title }} + + + + + {{ message }} + + + + + + {{ cancelButtonText }} + + + + + {{ confirmButtonText }} + + + +