diff --git a/src/platforms/app-plus-nvue/runtime/components/radio-group.js b/src/platforms/app-plus-nvue/runtime/components/radio-group.js new file mode 100644 index 0000000000000000000000000000000000000000..da3164eeb7e84a52d16ac5abc7a3ed337dca9631 --- /dev/null +++ b/src/platforms/app-plus-nvue/runtime/components/radio-group.js @@ -0,0 +1,103 @@ +import { + emitter, + listeners +} from '../mixins' + +function getRadioGroup (weex) { + return { + name: 'RadioGroup', + mixins: [emitter, listeners], + props: { + name: { + type: String, + default: '' + } + }, + data: function data () { + return { + radioList: [] + } + }, + listeners: { + '@radio-change': '_changeHandler', + '@radio-group-update': '_radioGroupUpdateHandler' + }, + mounted () { + this._resetRadioGroupValue(this.radioList.length - 1) + }, + created () { + this.$dispatch('Form', 'uni-form-group-update', { + type: 'add', + vm: this + }) + }, + beforeDestroy () { + this.$dispatch('Form', 'uni-form-group-update', { + type: 'remove', + vm: this + }) + }, + methods: { + _changeHandler ($event, vm) { + const index = this.radioList.indexOf(vm) + this._resetRadioGroupValue(index, true) + this.$trigger('change', { + value: vm.radioValue + }) + }, + _radioGroupUpdateHandler ($event) { + if ($event.type === 'add') { + this.radioList.push($event.vm) + } + else { + const index = this.radioList.indexOf($event.vm) + this.radioList.splice(index, 1) + } + }, + _resetRadioGroupValue (key, change) { + const _this = this + + this.radioList.forEach(function (value, index) { + if (index === key) { + return + } + if (change) { + _this.radioList[index].radioChecked = false + } + else { + _this.radioList.forEach(function (v, i) { + if (index >= i) { + return + } + if (_this.radioList[i].radioChecked) { + _this.radioList[index].radioChecked = false + } + }) + } + }) + }, + _getFormData () { + const data = {} + if (this.name !== '') { + let value = '' + this.radioList.forEach(function (vm) { + if (vm.radioChecked) { + value = vm.value + } + }) + data['value'] = value + data['key'] = this.name + } + return data + } + }, + render (createElement) { + const _vm = this + return createElement('div', _vm._g({}, _vm.$listeners), [_vm._t('default')], 2) + } + } +} + +export default function init (Vue, weex) { + Vue.component('radio-group', getRadioGroup(weex)) +} diff --git a/src/platforms/app-plus-nvue/runtime/components/radio.js b/src/platforms/app-plus-nvue/runtime/components/radio.js new file mode 100644 index 0000000000000000000000000000000000000000..12899a4393d44f4c258f64bcda791f59af9ac981 --- /dev/null +++ b/src/platforms/app-plus-nvue/runtime/components/radio.js @@ -0,0 +1,148 @@ +import { + emitter, + listeners +} from '../mixins' + +function getRadio (weex) { + return { + name: 'Radio', + mixins: [emitter, listeners], + props: { + checked: { + type: [Boolean, String], + default: false + }, + id: { + type: String, + default: '' + }, + disabled: { + type: [Boolean, String], + default: false + }, + color: { + type: String, + default: '#007AFF' + }, + value: { + type: String, + default: '' + } + }, + data: function data () { + return { + radioChecked: this.checked, + radioValue: this.value + } + }, + listeners: { + 'label-click': '_onClick', + '@label-click': '_onClick' + }, + computed: { + checkedStyle: function checkedStyle () { + return { + backgroundColor: this.color, + borderColor: this.color + } + }, + uncheckedStyle () { + return { + borderColor: '#d1d1d1' + } + } + }, + watch: { + checked: function checked (val) { + this.radioChecked = val + }, + value: function value (val) { + this.radioValue = val + } + }, + beforeCreate () { + }, + created () { + this.$dispatch('RadioGroup', 'uni-radio-group-update', { + type: 'add', + vm: this + }) + this.$dispatch('Form', 'uni-form-group-update', { + type: 'add', + vm: this + }) + }, + beforeDestroy () { + this.$dispatch('RadioGroup', 'uni-radio-group-update', { + type: 'remove', + vm: this + }) + this.$dispatch('Form', 'uni-form-group-update', { + type: 'remove', + vm: this + }) + }, + methods: { + _onClick ($event) { + if (this.disabled || this.radioChecked) { + return + } + this.radioChecked = true + this.$dispatch('RadioGroup', 'uni-radio-change', $event, this) + }, + _resetFormData () { + this.radioChecked = false + } + }, + render (createElement) { + const _vm = this + return createElement('div', _vm._g({ + staticClass: ['uni-radio'], + on: { + 'click': _vm._onClick + } + }, _vm.$listeners), [createElement('div', { + staticClass: ['uni-radio-input'], + style: _vm.radioChecked ? _vm.checkedStyle : _vm.uncheckedStyle + }, [(_vm.radioChecked) ? createElement('u-text', { + staticClass: ['uni-radio-input-icon'] + }, [_vm._v(_vm._s('\uEA08'))]) : _vm._e()], 1), createElement('u-text', { + staticClass: ['uni-text'] + }, [_vm._t('default')], 2)], 1) + }, + style: { + 'uni-radio': { + 'alignItems': 'center', + 'flexDirection': 'row' + }, + 'uni-radio-input': { + 'position': 'relative', + 'alignItems': 'center', + 'justifyContent': 'center', + 'marginRight': '5', + 'backgroundColor': '#ffffff', + 'borderStyle': 'solid', + 'borderWidth': '1', + 'borderColor': '#d1d1d1', + 'borderRadius': 50, + 'width': '22', + 'height': '22', + 'outline': 0 + }, + 'uni-radio-input-icon': { + 'fontFamily': 'unincomponents', + 'fontSize': '14', + 'color': '#ffffff' + }, + 'uni-radio-input-disabled': { + 'backgroundColor': '#e1e1e1', + 'borderColor': '#d1d1d1', + 'color': '#adadad' + } + } + } +} + +export default function init (Vue, weex) { + Vue.component('radio', getRadio(weex)) +} diff --git a/src/platforms/app-plus-nvue/runtime/components/rich-text.js b/src/platforms/app-plus-nvue/runtime/components/rich-text.js new file mode 100644 index 0000000000000000000000000000000000000000..043a150cb9bc64ea41a3d34eb275bea643092d49 --- /dev/null +++ b/src/platforms/app-plus-nvue/runtime/components/rich-text.js @@ -0,0 +1,180 @@ +import { + cached, + normalizeUnit +} from '../helpers/index' + +const parseStyleText = cached(function (cssText) { + const res = {} + const listDelimiter = /;(?![^(]*\))/g + const propertyDelimiter = /:(.+)/ + cssText.split(listDelimiter).forEach(function (item) { + if (item) { + const tmp = item.split(propertyDelimiter) + tmp.length > 1 && (res[tmp[0].trim()] = tmp[1].trim()) + } + }) + return res +}) + +function parseStyle (node, ctx) { + const styles = Object.create(null) + + if (!node.attrs) { + return styles + } + + const classList = (node.attrs.class || '').split(' ') + + const cssMap = ctx.$options.style || {} + + classList.forEach(name => { + if (name && cssMap[name]) { + Object.assign(styles, cssMap[name]) + } + }) + + Object.assign(styles, parseStyleText(node.attrs.style || '')) + + return styles +} + +const TAGS = ['span', 'a', 'image', 'img'] + +function block (node) { + node.attr.value = (node.attr.value || '') + '\n' + return node +} + +function heading (node, em, options) { + !node.style.fontSize && (node.style.fontSize = options.defaultFontSize * em) + return block(bold(node)) +} + +function createHeading (em) { + return function (node, options) { + return heading(node, em, options) + } +} + +function bold (node) { + !node.style.fontWeight && (node.style.fontWeight = 'bold') + return node +} + +const strategies = { + 'blockquote': block, + 'br': block, + 'div': block, + 'dl': block, + 'h1': createHeading(2), + 'h2': createHeading(1.5), + 'h3': createHeading(1.17), + 'h4': createHeading(1), + 'h5': createHeading(0.83), + 'h6': createHeading(0.67), + 'hr': block, + 'ol': block, + 'p': block, + 'strong': bold, + 'table': block, + 'tbody': block, + 'tfoot': block, + 'thead': block, + 'ul': block +} + +const HTML_RE = /&(amp|gt|lt|nbsp|quot|apos);/g + +const CHARS = { + 'amp': '&', + 'gt': '>', + 'lt': '<', + 'nbsp': ' ', + 'quot': '"', + 'apos': "'" +} + +function normalizeText (str) { + return str.replace(HTML_RE, function (match, entity) { + return CHARS[entity] + }) +} + +function normalizeNode (node, ctx, options) { + let type = (node.name || '').toLowerCase() + + const strategy = strategies[type] + + if (TAGS.indexOf(type) === -1) { + type = 'span' + } + if (type === 'img') { + type = 'image' + } + const nvueNode = { + type, + attr: Object.create(null) + } + + if (node.type === 'text' || node.text) { + nvueNode.attr.value = normalizeText((node.text || '').trim()) + } + + if (node.attrs) { + Object.keys(node.attrs).forEach(name => { + if (name !== 'class' && name !== 'style') { + nvueNode.attr[name] = node.attrs[name] + } + }) + } + + nvueNode.style = normalizeUnit(parseStyle(node, ctx)) + + if (strategy) { + strategy(nvueNode, options) + } + + nvueNode.children = normalizeNodes(node.children, ctx, options) + + return nvueNode +} + +function normalizeNodes (nodes, ctx, options) { + if (Array.isArray(nodes)) { + return nodes.map(node => normalizeNode(node, ctx, options)) + } + return [] +} + +function getRichText (weex) { + const { + scale, + deviceWidth + } = weex.config.env + const defaultFontSize = deviceWidth / scale / 20 + return { + props: { + nodes: { + type: [Array, String], + default: function () { + return [] + } + } + }, + render (createElement) { + // TODO 待处理 String 类型 + const nodes = normalizeNodes(this.nodes || [], this.$vnode.context, { + defaultFontSize + }) + return createElement('u-rich-text', this._g({ + attrs: { + value: nodes + } + }, this.$listeners)) + } + } +} + +export default function init (Vue, weex) { + Vue.component('rich-text', getRichText(weex)) +} diff --git a/src/platforms/app-plus-nvue/runtime/components/slider.js b/src/platforms/app-plus-nvue/runtime/components/slider.js new file mode 100644 index 0000000000000000000000000000000000000000..739d3d8d276d657a75cef8e7eca37d716dfe093b --- /dev/null +++ b/src/platforms/app-plus-nvue/runtime/components/slider.js @@ -0,0 +1,332 @@ +import { + emitter, + listeners +} from '../mixins' + +function getSlider (weex) { + return { + name: 'U-Slider', + mixins: [emitter, listeners], + props: { + name: { + type: String, + default: '' + }, + min: { + type: [Number, String], + default: 0 + }, + max: { + type: [Number, String], + default: 100 + }, + value: { + type: [Number, String], + default: 0 + }, + step: { + type: [Number, String], + default: 1 + }, + disabled: { + type: [Boolean, String], + default: false + }, + color: { + type: String, + default: '#e9e9e9' + }, + backgroundColor: { + type: String, + default: '#e9e9e9' + }, + activeColor: { + type: String, + default: '#007aff' + }, + selectedColor: { + type: String, + default: '#007aff' + }, + blockColor: { + type: String, + default: '#ffffff' + }, + blockSize: { + type: [Number, String], + default: 28 + }, + showValue: { + type: [Boolean, String], + default: false + } + }, + data () { + return { + left: 0, + width: 0, + sliderValue: Number(this.value), + sliderThumbValue: 0 + } + }, + computed: { + trackStyle () { + return { + backgroundColor: this._getBgColor() + } + }, + trackActiveStyle () { + return { + backgroundColor: this._getActiveColor(), + width: this.thumbValue + 'px' + } + }, + thumbStyle () { + return { + width: this.blockSize + 'px', + height: this.blockSize + 'px', + marginTop: -this.blockSize / 2 + 'px', + left: this.thumbValue + 'px', + backgroundColor: this.blockColor + } + }, + thumbValue () { + return (this.sliderValue - Number(this.min)) / (Number(this.max) - Number(this.min)) * this.width + } + }, + watch: { + value (val) { + this.sliderValue = Number(val) + } + }, + mounted () { + this._x0 = 0 + this._x1 = 0 + this.$eventOld = null + setTimeout(() => { + const dom = weex.requireModule('dom') + dom.getComponentRect(this.$refs['slider-track'], res => { + this.left = res.size.left + this.width = res.size.width + }) + }, 50) + }, + created () { + this.$dispatch('Form', 'uni-form-group-update', { + type: 'add', + vm: this + }) + }, + beforeDestroy () { + this.$dispatch('Form', 'uni-form-group-update', { + type: 'remove', + vm: this + }) + }, + methods: { + _handleStart (e) { + if (e.changedTouches.length === 1 && !this._$eventOld) { + this._$eventOld = e + const px = e.changedTouches[0].pageX + this._x0 = this._x1 = px + this._onTrack('start', px) + } + }, + _handleMove (e) { + if (e.changedTouches.length === 1 && this._$eventOld) { + const px = e.changedTouches[0].pageX + this._onTrack('move', px) + this._x1 = px + } + }, + _handleEnd (e) { + if (e.changedTouches.length === 1 && this._$eventOld) { + const px = e.changedTouches[0].pageX + this._$eventOld = null + this._onTrack('end', px) + } + }, + _onTrack: function (state, x) { + if (!this.disabled) { + if (state === 'move') { + this._onUserChangedValue({ + x: x + }) + this.$trigger('changing', { + value: this.sliderValue + }) + } + else if (state === 'end') { + this._onUserChangedValue({ + x: x + }) + this.$trigger('change', { + value: this.sliderValue + }) + } + } + }, + _onUserChangedValue (e) { + let x = e.x + if (x < 0) { + x = 0 + } + if (x > this.width) { + x = this.width + } + this.sliderValue = this._filterValue(x) + }, + _filterValue (x) { + let value = (x / this.width) * (Number(this.max) - Number(this.min)) + const step = Number(this.step) + if (step > 0 && value > step && (value % step) / step !== 0) { + value -= value % step + } + return parseInt(value + Number(this.min)) + }, + _getBgColor () { + return this.backgroundColor !== '#e9e9e9' + ? this.backgroundColor + : this.color !== '#007aff' + ? this.color + : '#007aff' + }, + _getActiveColor () { + return this.activeColor !== '#007aff' + ? this.activeColor + : this.selectedColor !== '#e9e9e9' + ? this.selectedColor + : '#e9e9e9' + }, + _resetFormData () { + this.sliderValue = this.min + }, + _getFormData () { + const data = {} + if (this.name !== '') { + data['value'] = this.sliderValue + data['key'] = this.name + } + return data + } + }, + render (createElement) { + const _vm = this + return createElement('div', _vm._g({ + staticClass: ['uni-slider'] + }, _vm.$listeners), [createElement('div', { + staticClass: ['uni-slider-wrapper'] + }, [createElement('div', { + staticClass: ['uni-slider-tap-area'], + on: { + 'touchstart': _vm._handleStart, + 'touchmove': _vm._handleMove, + 'touchend': _vm._handleEnd + } + }, [createElement('div', { + ref: 'slider-track', + staticClass: ['uni-slider-handle-wrapper'], + style: _vm.trackStyle + }, [createElement('div', { + staticClass: ['uni-slider-track'], + style: _vm.trackActiveStyle + })]), createElement('div', { + ref: 'uni-slider-handle', + staticClass: ['uni-slider-thumb'], + style: _vm.thumbStyle + })]), (_vm.showValue) ? createElement('u-text', { + staticClass: ['uni-slider-value'] + }, [_vm._v(_vm._s(_vm.sliderValue))]) : _vm._e()])]) + }, + style: { + 'uni-slider': { + 'marginTop': '12', + 'marginRight': 0, + 'marginBottom': '12', + 'marginLeft': 0, + 'paddingTop': 0, + 'paddingRight': 0, + 'paddingBottom': 0, + 'paddingLeft': 0 + }, + 'uni-slider-wrapper': { + 'flexDirection': 'row', + 'alignItems': 'center', + 'minHeight': '30' + }, + 'uni-slider-tap-area': { + 'position': 'relative', + 'flex': 1, + 'paddingTop': '15', + 'paddingRight': 0, + 'paddingBottom': '15', + 'paddingLeft': 0 + }, + 'uni-slider-handle-wrapper': { + 'position': 'relative', + 'marginTop': 0, + 'marginRight': '18', + 'marginBottom': 0, + 'marginLeft': '18', + 'height': '2', + 'borderRadius': '5', + 'backgroundColor': '#e9e9e9', + 'transitionProperty': 'backgroundColor', + 'transitionDuration': 300, + 'transitionTimingFunction': 'ease' + }, + '@TRANSITION': { + 'uni-slider-handle-wrapper': { + 'property': 'backgroundColor', + 'duration': 300, + 'timingFunction': 'ease' + }, + 'uni-slider-track': { + 'property': 'backgroundColor', + 'duration': 300, + 'timingFunction': 'ease' + }, + 'uni-slider-thumb': { + 'property': 'borderColor', + 'duration': 300, + 'timingFunction': 'ease' + } + }, + 'uni-slider-track': { + 'flex': 1, + 'height': '2', + 'borderRadius': '6', + 'backgroundColor': '#007aff', + 'transitionProperty': 'backgroundColor', + 'transitionDuration': 300, + 'transitionTimingFunction': 'ease' + }, + 'uni-slider-thumb': { + 'position': 'absolute', + 'width': '28', + 'height': '28', + 'borderRadius': 50, + 'boxShadow': '0 0 4px #ebebeb', + 'transitionProperty': 'borderColor', + 'transitionDuration': 300, + 'transitionTimingFunction': 'ease' + }, + 'uni-slider-step': { + 'position': 'absolute', + 'width': 100, + 'height': '2', + 'background': 'transparent', + 'zIndex': 1 + }, + 'uni-slider-value': { + 'color': '#888888', + 'fontSize': '14', + 'marginRight': '14' + } + } + } +} + +export default function init (Vue, weex) { + Vue.component('u-slider', getSlider(weex)) +} diff --git a/src/platforms/app-plus-nvue/runtime/components/swiper-item.js b/src/platforms/app-plus-nvue/runtime/components/swiper-item.js new file mode 100644 index 0000000000000000000000000000000000000000..57d0ea3e659ab05db25bec8a9af97a97c9f93e77 --- /dev/null +++ b/src/platforms/app-plus-nvue/runtime/components/swiper-item.js @@ -0,0 +1,28 @@ +function getSwiperItem (weex) { + return { + name: 'SwiperItem', + props: { + itemId: { + type: String, + default: '' + } + }, + render (createElement) { + return createElement('div', this._g({ + staticClass: ['uni-swiper-item'], + staticStyle: { + position: 'absolute', + left: 0, + top: 0, + right: 0, + bottom: 0, + overflow: 'hidden' + } + }, this.$listeners), this._t('default'), 2) + } + } +} + +export default function init (Vue, weex) { + Vue.component('swiper-item', getSwiperItem(weex)) +} diff --git a/src/platforms/app-plus-nvue/runtime/components/swiper.js b/src/platforms/app-plus-nvue/runtime/components/swiper.js new file mode 100644 index 0000000000000000000000000000000000000000..de367704a74dbf86d269c4bf18d0829b0fc4b7f5 --- /dev/null +++ b/src/platforms/app-plus-nvue/runtime/components/swiper.js @@ -0,0 +1,222 @@ +import { + emitter +} from '../mixins' + +function getSwiper (weex) { + return { + name: 'Swiper', + mixins: [emitter], + props: { + indicatorDots: { + type: [Boolean, String], + default: false + }, + vertical: { + type: [Boolean, String], + default: false + }, + autoplay: { + type: [Boolean, String], + default: false + }, + circular: { + type: [Boolean, String], + default: false + }, + interval: { + type: [Number, String], + default: 5e3 + }, + duration: { + type: [Number, String], + default: 500 + }, + current: { + type: [Number, String], + default: 0 + }, + indicatorColor: { + type: String, + default: 'rgba(0,0,0,.3)' + }, + indicatorActiveColor: { + type: String, + default: '#000000' + }, + previousMargin: { + type: String, + default: '' + }, + nextMargin: { + type: String, + default: '' + }, + currentItemId: { + type: String, + default: '' + }, + skipHiddenItemLayout: { + type: [Boolean, String], + default: false + }, + displayMultipleItems: { + type: [Number, String], + default: 1 + } + }, + data () { + return { + currentSync: this.current, + currentChangeSource: 'autoplay', + touching: false, + touchendTime: 0 + } + }, + watch: { + current () { + this._currentCheck() + }, + currentItemId () { + this._currentCheck() + }, + currentSync () { + const source = this.touching && this.currentChangeSource ? 'touch' : this.currentChangeSource + if (source) { + this.$trigger('change', this._getDetail()) + } + else { + this.currentChangeSource = 'autoplay' + } + } + }, + methods: { + onChange (event) { + this.currentSync = event.detail.index + }, + onScroll (event) { + const offsetXRatio = event.detail.offsetXRatio + if (!this.touching && Math.abs(offsetXRatio) === 0) { + const detail = this._getDetail() + if (Date.now() - this.touchendTime < this.interval - 1) { + detail.source = 'touch' + } + this.$trigger('animationfinish', detail) + } + }, + onTouchmove () { + this.touching = true + }, + onTouchend () { + this.touching = false + this.touchendTime = Date.now() + }, + _getDetail () { + const current = this.currentSync + const currentItem = this.items[current] || {} + const currentItemId = (currentItem.componentInstance && currentItem.componentInstance.itemId) || '' + const source = this.touching && this.currentChangeSource ? 'touch' : this.currentChangeSource + return { + current, + currentItemId, + source + } + }, + _currentCheck () { + let current = -1 + if (this.currentItemId) { + for (let i = 0, items = this.items; i < items.length; i++) { + const componentInstance = items[i].componentInstance + if (componentInstance && componentInstance.itemId === this.currentItemId) { + current = i + break + } + } + } + if (current < 0) { + current = Math.round(this.current) || 0 + } + current = current < 0 ? 0 : current + if (this.currentSync !== current) { + this.currentChangeSource = '' + this.currentSync = current + } + } + }, + created () { + this.items = [] + }, + mounted () { + this._currentCheck() + }, + render (createElement) { + const swiperItems = [] + const slots = Array.isArray(this.$slots.default) ? this.$slots.default : [] + + slots.forEach(vnode => { + if (vnode.componentOptions && vnode.componentOptions.tag === 'swiper-item') { + swiperItems.push(vnode) + } + }) + this.items = swiperItems + const event = {} + const $listeners = this.$listeners + if ($listeners.change || $listeners.animationfinish) { + event.panmove = this.onTouchmove + event.panend = this.onTouchend + } + if ($listeners.change) { + event.change = this.onChange + } + if ($listeners.animationfinish) { + event.scroll = this.onScroll + } + return createElement('div', this._g({ + staticClass: ['uni-swiper'] + }, $listeners), [createElement('slider', { + staticClass: ['uni-swiper-slider'], + attrs: { + autoPlay: this.autoplay, + interval: this.interval, + index: this.currentSync, + showIndicators: this.indicatorDots, + infinite: this.circular, + vertical: this.vertical + }, + on: event + }, [...swiperItems, createElement('indicator', { + staticClass: ['uni-swiper-dots'], + style: { + itemColor: this.indicatorColor, + itemSelectedColor: this.indicatorActiveColor, + itemSize: 8, + // 动态创建 indicator 在安卓上有问题,改成透明度控制显示和隐藏 + opacity: this.indicatorDots ? 1 : 0 + } + })], 2)]) + }, + style: { + 'uni-swiper': { + position: 'relative', + height: '150px' + }, + 'uni-swiper-slider': { + position: 'absolute', + left: 0, + top: 0, + right: 0, + bottom: 0 + }, + 'uni-swiper-dots': { + position: 'absolute', + left: 0, + right: 0, + bottom: '10', + height: '10' + } + } + } +} + +export default function init (Vue, weex) { + Vue.component('swiper', getSwiper(weex)) +} diff --git a/src/platforms/app-plus-nvue/runtime/components/switch.js b/src/platforms/app-plus-nvue/runtime/components/switch.js new file mode 100644 index 0000000000000000000000000000000000000000..5fdfc45b68504eefb3105929d98f8bc42ae49246 --- /dev/null +++ b/src/platforms/app-plus-nvue/runtime/components/switch.js @@ -0,0 +1,193 @@ +import { + emitter, + listeners +} from '../mixins' + +function getSwitch (weex) { + return { + name: 'Switch', + mixins: [emitter, listeners], + props: { + name: { + type: String, + default: '' + }, + id: { + type: String, + default: '' + }, + type: { + type: String, + default: 'switch' + }, + checked: { + type: [Boolean, String], + default: false + }, + disabled: { + type: [Boolean, String], + default: false + }, + color: { + type: String, + default: '#007aff' + } + }, + data () { + return { + switchChecked: this.checked + } + }, + computed: { + switchStyle () { + return { + backgroundColor: this.color + } + } + }, + watch: { + checked (value) { + this.switchChecked = value + } + }, + created () { + this.$dispatch('Form', 'uni-form-group-update', { + type: 'add', + vm: this + }) + }, + beforeDestroy () { + this.$dispatch('Form', 'uni-form-group-update', { + type: 'remove', + vm: this + }) + }, + methods: { + _onClick ($event) { + if (this.disabled) { + return + } + this.switchChecked = !this.switchChecked + this.$trigger('change', { + value: this.switchChecked + }) + }, + _resetFormData () { + this.switchChecked = false + }, + _getFormData () { + const data = {} + if (this.name !== '') { + data['value'] = this.switchChecked + data['key'] = this.name + } + return data + } + }, + render (createElement) { + const _vm = this + return createElement('div', _vm._g({ + staticClass: ['uni-switch'], + on: { + 'click': _vm._onClick + } + }, _vm.$listeners), [(_vm.type === 'switch') ? createElement('div', { + staticClass: ['uni-switch-input'], + style: { + backgroundColor: _vm.switchChecked ? _vm.color : '#DFDFDF' + } + }, [ + createElement('div', { + staticClass: ['uni-switch-input-bg'], + style: { + backgroundColor: _vm.switchChecked ? _vm.color : '#FFFFFF' + } + }), + createElement('div', { + staticClass: ['uni-switch-input-check'], + class: [_vm.switchChecked ? 'uni-switch-input-check-checked' : ''] + }) + ]) : _vm._e(), (_vm.type === 'checkbox') ? createElement('div', { + staticClass: ['uni-checkbox-input'], + class: [_vm.switchChecked ? 'uni-checkbox-input-checked' : ''] + }, [(_vm.switchChecked) ? createElement('u-text', { + staticClass: ['uni-icon', 'uni-checkbox-input-icon'] + }, [_vm._v(_vm._s('\uEA08'))]) : _vm._e()]) : _vm._e()]) + }, + style: { + 'uni-switch': { + 'position': 'relative' + }, + 'uni-switch-input': { + 'position': 'relative', + 'width': '52', + 'height': '32', + 'borderRadius': '16', + 'backgroundColor': '#dfdfdf', + 'transitionDuration': 200, + 'transitionProperty': 'backgroundColor' + }, + 'uni-switch-input-disabled': { + 'backgroundColor': '#e1e1e1' + }, + 'uni-switch-input-bg': { + 'position': 'absolute', + 'left': 1, + 'top': 1, + 'width': '50', + 'height': '30', + 'borderRadius': '15', + 'backgroundColor': '#ffffff', + 'transitionDuration': 200, + 'transitionProperty': 'backgroundColor' + }, + 'uni-switch-input-check': { + 'pointerEvents': 'none', + 'position': 'absolute', + 'left': 1, + 'top': 1, + 'width': '30', + 'height': '30', + 'borderRadius': 50, + 'backgroundColor': '#ffffff', + 'boxShadow': '0 1px 3px #e0e0e0', + 'transitionDuration': 200, + 'transitionProperty': 'transform,backgroundColor', + 'transform': 'translateX(0)' + }, + 'uni-switch-input-check-checked': { + 'background': '#ffffff', + 'borderColor': '#ffffff', + 'transform': 'translateX(20px)' + }, + 'uni-checkbox-input': { + 'position': 'relative', + 'appearance': 'none', + 'marginRight': '5', + 'backgroundColor': '#ffffff', + 'borderStyle': 'solid', + 'borderWidth': '1', + 'borderColor': '#d1d1d1', + 'borderRadius': '3', + 'width': '22', + 'height': '22', + 'outline': 0 + }, + 'uni-checkbox-input-disabled': { + 'backgroundColor': '#e1e1e1', + 'color': '#adadad' + }, + 'uni-icon': { + 'fontFamily': 'unincomponents', + 'fontSize': '16', + 'marginLeft': '2', + 'marginTop': '2', + 'color': '#007aff' + } + } + } +} + +export default function init (Vue, weex) { + Vue.component('switch', getSwitch(weex)) +}