diff --git a/examples/routers/radio.vue b/examples/routers/radio.vue index 69fd7b8..1fda34a 100644 --- a/examples/routers/radio.vue +++ b/examples/routers/radio.vue @@ -50,5 +50,5 @@ methods: { } - } + }; </script> diff --git a/src/components/radio/radio-group.vue b/src/components/radio/radio-group.vue index 4e6715e..6cd4ffe 100644 --- a/src/components/radio/radio-group.vue +++ b/src/components/radio/radio-group.vue @@ -1,11 +1,5 @@ <template> - <div - :class="classes" tabindex="0" - @keydown.left="onLeft" - @keydown.right="onRight" - @keydown.up="onUp" - @keydown.down="onDown" - @keydown.tab="onTab"> + <div :class="classes" :name="name"> <slot></slot> </div> </template> @@ -15,6 +9,10 @@ const prefixCls = 'ivu-radio-group'; + let seed = 0; + const now = Date.now(); + const getUuid = () => `ivuRadioGroup_${now}_${seed++}`; + export default { name: 'RadioGroup', mixins: [ Emitter ], @@ -36,13 +34,16 @@ vertical: { type: Boolean, default: false + }, + name: { + type: String, + default: getUuid } }, data () { return { currentValue: this.value, - childrens: [], - preventDefaultTab: true + childrens: [] }; }, computed: { @@ -63,12 +64,10 @@ }, methods: { updateValue () { - const value = this.value; this.childrens = findComponentsDownward(this, 'Radio'); - if (this.childrens) { this.childrens.forEach(child => { - child.currentValue = value === child.label; + child.currentValue = this.value === child.label; child.group = true; }); } @@ -79,55 +78,11 @@ this.$emit('input', data.value); this.$emit('on-change', data.value); this.dispatch('FormItem', 'on-form-change', data.value); - }, - findRadio(value) { - return this.childrens && this.childrens.length ? this.childrens.find((child) => child.value === value) : undefined; - }, - findIndexRadio(value) { - return this.childrens && this.childrens.length ? this.childrens.findIndex((child) => child.value === value) : -1; - }, - includesRadio(value) { - return this.childrens && this.childrens.length ? this.childrens.includes((child) => child.value === value) : false; - }, - nextRadio() { - if (this.includesRadio(this.currentValue)) { - console.log('get next'); - } else { - return this.childrens && this.childrens.length ? this.childrens[0] : undefined; - } - }, - onLeft() { - console.log('left', this.currentValue); - }, - onRight() { - console.log('right', this.currentValue); - }, - onUp() { - console.log('up', this.currentValue); - }, - onDown() { - console.log('down', this.currentValue); - }, - onTab(event) { - if (!this.preventDefaultTab) { - return; - } - - event.preventDefault(); - this.preventDefaultTab = false; - this.currentValue = this.nextRadio(); - if (this.currentValue) { - this.change({ - value: this.currentValue.label - }); - } - - console.log('tab', this); - - }, + } }, watch: { value () { + this.currentValue = this.value; this.updateValue(); } } diff --git a/src/components/radio/radio.vue b/src/components/radio/radio.vue index 7be686f..7d78d1c 100644 --- a/src/components/radio/radio.vue +++ b/src/components/radio/radio.vue @@ -1,20 +1,18 @@ <template> - <label - :class="wrapClasses" - :tabindex="disabled || group ? -1 : 0"> + <label :class="wrapClasses" ref="label"> <span :class="radioClasses"> - <span :class="innerClasses"></span> + <span :class="innerClasses" ref="inner"></span> <input type="radio" - tabindex="-1" :class="inputClasses" :disabled="disabled" :checked="currentValue" - :name="name" + :name="groupName" @change="change" - @focus="$el.focus()" - > - </span><slot>{{ label }}</slot> + @focus="onFocus" + @blur="onBlur"> + </span> + <slot>{{ label }}</slot> </label> </template> <script> @@ -59,7 +57,10 @@ return { currentValue: this.value, group: false, - parent: findComponentUpward(this, 'RadioGroup') + groupName: this.name, + parent: findComponentUpward(this, 'RadioGroup'), + focusWrapper: false, + focusInner: false }; }, computed: { @@ -70,7 +71,8 @@ [`${prefixCls}-group-item`]: this.group, [`${prefixCls}-wrapper-checked`]: this.currentValue, [`${prefixCls}-wrapper-disabled`]: this.disabled, - [`${prefixCls}-${this.size}`]: !!this.size + [`${prefixCls}-${this.size}`]: !!this.size, + [`${prefixCls}-focus`]: this.focusWrapper } ]; }, @@ -84,18 +86,33 @@ ]; }, innerClasses () { - return `${prefixCls}-inner`; + return [ + `${prefixCls}-inner`, + { + [`${prefixCls}-focus`]: this.focusInner + } + ]; }, inputClasses () { return `${prefixCls}-input`; } }, mounted () { - if (this.parent) this.group = true; - if (!this.group) { - this.updateValue(); - } else { + if (this.parent) { + this.group = true; + if (this.name && this.name !== this.parent.name) { + if (console.warn) { + console.warn('[iview] Name does not match Radio Group name.'); + } + } else { + this.groupName = this.parent.name; + } + } + + if (this.group) { this.parent.updateValue(); + } else { + this.updateValue(); } }, methods: { @@ -107,30 +124,43 @@ const checked = event.target.checked; this.currentValue = checked; - let value = checked ? this.trueValue : this.falseValue; + const value = checked ? this.trueValue : this.falseValue; this.$emit('input', value); - if (this.group && this.label !== undefined) { - this.parent.change({ - value: this.label, - checked: this.value - }); - } - if (!this.group) { + if (this.group) { + if (this.label !== undefined) { + this.parent.change({ + value: this.label, + checked: this.value + }); + } + } else { this.$emit('on-change', value); this.dispatch('FormItem', 'on-form-change', value); } }, updateValue () { this.currentValue = this.value === this.trueValue; + }, + onBlur () { + this.focusWrapper = false; + this.focusInner = false; + }, + onFocus () { + if (this.group && this.parent.type === 'button') { + this.focusWrapper = true; + } else { + this.focusInner = true; + } } }, watch: { value (val) { - if (val !== this.trueValue && val !== this.falseValue) { + if (val === this.trueValue || val === this.falseValue) { + this.updateValue(); + } else { throw 'Value should be trueValue or falseValue.'; } - this.updateValue(); } } }; diff --git a/src/styles/components/radio.less b/src/styles/components/radio.less index de53295..5149844 100644 --- a/src/styles/components/radio.less +++ b/src/styles/components/radio.less @@ -3,11 +3,16 @@ @radio-inner-prefix-cls: ~"@{radio-prefix-cls}-inner"; @radio-group-button-prefix-cls: ~"@{radio-group-prefix-cls}-button"; +.@{radio-prefix-cls}-focus { + box-shadow: 0 0 0 2px fade(@primary-color, 20%); + z-index: 1; +} + .@{radio-group-prefix-cls} { display: inline-block; font-size: @font-size-small; vertical-align: middle; - //outline: 0; + //outline: none; &-vertical{ .@{radio-prefix-cls}-wrapper { display: block; @@ -29,20 +34,14 @@ &-disabled{ cursor: @cursor-disabled; } - outline: 0; - &:focus { - & .@{radio-inner-prefix-cls} { - box-shadow: 0 0 0 2px fade(@primary-color, 20%); - z-index: 1; - } - } + //outline: none; } .@{radio-prefix-cls} { display: inline-block; margin-right: 4px; white-space: nowrap; - outline: none; + //outline: none; position: relative; line-height: 1; vertical-align: middle; @@ -227,11 +226,6 @@ span.@{radio-prefix-cls} + * { } } - &:focus { - box-shadow: 0 0 0 2px fade(@primary-color, 20%); - z-index: 1; - } - .@{radio-prefix-cls}-inner, input { opacity: 0; @@ -247,7 +241,7 @@ span.@{radio-prefix-cls} + * { &:first-child { border-color: @primary-color; - box-shadow: none!important; + //box-shadow: none!important; } &:hover { @@ -256,10 +250,6 @@ span.@{radio-prefix-cls} + * { color: tint(@primary-color, 20%); } - &:focus { - box-shadow: 0 0 0 2px fade(@primary-color, 20%)!important; - } - &:active { border-color: shade(@primary-color, 5%); //box-shadow: -1px 0 0 0 shade(@primary-color, 5%); -- libgit2 0.21.4