feat(radio): add native element to support native keyboard events

This commit is contained in:
07akioni 2020-02-14 14:57:08 +08:00
parent 96f3d41824
commit 5166526a60
4 changed files with 75 additions and 22 deletions

View File

@ -4,12 +4,22 @@
:class="{
'n-radio--disabled': syntheticDisabled,
'n-radio--checked': syntheticChecked,
'n-radio--focus': focus,
[`n-${syntheticTheme}-theme`]: syntheticTheme
}"
:tabindex="syntheticDisabled ? -1 : 0"
@keyup.enter="handleKeyUpEnter"
@click="handleClick"
>
<input
ref="input"
type="radio"
class="n-radio__radio-input"
:checked="syntheticChecked"
:disabled="syntheticDisabled"
@change="handleRadioInputChange"
@focus="handleRadioInputFocus"
@blur="handleRadioInputBlur"
>
<div
class="n-radio__control"
:class="{
@ -26,10 +36,11 @@
import asformitem from '../../_mixins/asformitem'
import withapp from '../../_mixins/withapp'
import themeable from '../../_mixins/themeable'
import radioMixin from './radioMixin'
export default {
name: 'NRadio',
mixins: [ withapp, themeable, asformitem() ],
mixins: [ withapp, themeable, asformitem(), radioMixin ],
model: {
prop: 'checkedValue',
event: 'change'
@ -75,12 +86,6 @@ export default {
this.$emit('click', e)
this.toggle()
},
toggle () {
if (this.syntheticDisabled) return
if (this.checkedValue !== this.value) {
this.emitChangeEvent()
}
},
emitChangeEvent () {
if (this.NRadioGroup) {
this.NRadioGroup.$emit('change', this.value)

View File

@ -3,20 +3,33 @@
class="n-radio-button"
:class="{
'n-radio-button--disabled': syntheticDisabled,
'n-radio-button--checked': syntheticChecked
'n-radio-button--checked': syntheticChecked,
'n-radio-button--focus': focus
}"
:tabindex="syntheticDisabled ? -1 : 0"
@keyup.enter="handleKeyUpEnter"
@click="handleClick"
>
<input
ref="input"
type="radio"
class="n-radio-button__radio-input"
:checked="syntheticChecked"
:disabled="syntheticDisabled"
@change="handleRadioInputChange"
@focus="handleRadioInputFocus"
@blur="handleRadioInputBlur"
>
<div class="n-radio-button__border-mask" />
<slot />
</div>
</template>
<script>
import radioMixin from './radioMixin'
export default {
name: 'NRadioButton',
mixins: [radioMixin],
model: {
prop: 'checkedValue',
event: 'change'
@ -67,12 +80,6 @@ export default {
handleClick () {
this.toggle()
},
toggle () {
if (this.syntheticDisabled) return
if (this.checkedValue !== this.value) {
this.emitChangeEvent()
}
},
emitChangeEvent () {
if (this.NRadioGroup) {
this.NRadioGroup.$emit('change', this.value)

View File

@ -0,0 +1,25 @@
export default {
data () {
return {
focus: false
}
},
methods: {
toggle () {
if (this.syntheticDisabled) return
this.$refs.input.focus()
if (this.checkedValue !== this.value) {
this.emitChangeEvent()
}
},
handleRadioInputChange () {
this.toggle()
},
handleRadioInputBlur () {
this.focus = false
},
handleRadioInputFocus () {
this.focus = true
}
}
}

View File

@ -25,6 +25,12 @@
vertical-align: middle;
align-items: center;
margin-right: 18px;
@include e(radio-input) {
width: 0;
height: 0;
opacity: 0;
margin: 0;
}
}
@include e(control) {
box-shadow: map-get($--radio-box-shadow, 'default');
@ -69,9 +75,11 @@
transition: box-shadow .3s $--n-ease-in-out-cubic-bezier;
}
}
&:focus:not(:active) {
@include e(control) {
box-shadow: map-get($--radio-box-shadow, 'focus');
@include m(focus) {
&:not(:active) {
@include e(control) {
box-shadow: map-get($--radio-box-shadow, 'focus');
}
}
}
}
@ -128,6 +136,12 @@
padding-right: 14px;
white-space: nowrap;
transition: background-color .3s $--n-ease-in-out-cubic-bezier, opacity .3s $--n-ease-in-out-cubic-bezier, border-color .3s $--n-ease-in-out-cubic-bezier, color .3s $--n-ease-in-out-cubic-bezier;
@include e(radio-input) {
width: 0;
height: 0;
opacity: 0;
margin: 0;
}
@include e(border-mask) {
pointer-events: none;
position: absolute;
@ -180,9 +194,11 @@
color: map-get($--radio-button-label-color, 'hover');
}
}
&:focus:not(:active) {
@include e(border-mask) {
box-shadow: map-get($--radio-button-box-shadow, 'focus')
@include m(focus) {
&:not(:active) {
@include e(border-mask) {
box-shadow: map-get($--radio-button-box-shadow, 'focus')
}
}
}
}