This commit is contained in:
Ivan
2021-06-07 11:56:04 +08:00
commit c3c9fee2fb
1071 changed files with 195655 additions and 0 deletions

8
packages/radio/index.js Normal file
View File

@@ -0,0 +1,8 @@
import Radio from './src/radio';
/* istanbul ignore next */
Radio.install = function(Vue) {
Vue.component(Radio.name, Radio);
};
export default Radio;

View File

@@ -0,0 +1,114 @@
<template>
<label
class="el-radio-button"
:class="[
size ? 'el-radio-button--' + size : '',
{ 'is-active': value === label },
{ 'is-disabled': isDisabled },
{ 'is-focus': focus }
]"
role="radio"
:aria-checked="value === label"
:aria-disabled="isDisabled"
:tabindex="tabIndex"
@keydown.space.stop.prevent="value = isDisabled ? value : label"
>
<input
class="el-radio-button__orig-radio"
:value="label"
type="radio"
v-model="value"
:name="name"
@change="handleChange"
:disabled="isDisabled"
tabindex="-1"
@focus="focus = true"
@blur="focus = false"
>
<span
class="el-radio-button__inner"
:style="value === label ? activeStyle : null"
@keydown.stop>
<slot></slot>
<template v-if="!$slots.default">{{label}}</template>
</span>
</label>
</template>
<script>
import Emitter from 'element-ui/src/mixins/emitter';
export default {
name: 'ElRadioButton',
mixins: [Emitter],
inject: {
elForm: {
default: ''
},
elFormItem: {
default: ''
}
},
props: {
label: {},
disabled: Boolean,
name: String
},
data() {
return {
focus: false
};
},
computed: {
value: {
get() {
return this._radioGroup.value;
},
set(value) {
this._radioGroup.$emit('input', value);
}
},
_radioGroup() {
let parent = this.$parent;
while (parent) {
if (parent.$options.componentName !== 'ElRadioGroup') {
parent = parent.$parent;
} else {
return parent;
}
}
return false;
},
activeStyle() {
return {
backgroundColor: this._radioGroup.fill || '',
borderColor: this._radioGroup.fill || '',
boxShadow: this._radioGroup.fill ? `-1px 0 0 0 ${this._radioGroup.fill}` : '',
color: this._radioGroup.textColor || ''
};
},
_elFormItemSize() {
return (this.elFormItem || {}).elFormItemSize;
},
size() {
return this._radioGroup.radioGroupSize || this._elFormItemSize || (this.$ELEMENT || {}).size;
},
isDisabled() {
return this.disabled || this._radioGroup.disabled || (this.elForm || {}).disabled;
},
tabIndex() {
return (this.isDisabled || (this._radioGroup && this.value !== this.label)) ? -1 : 0;
}
},
methods: {
handleChange() {
this.$nextTick(() => {
this.dispatch('ElRadioGroup', 'handleChange', this.value);
});
}
}
};
</script>

View File

@@ -0,0 +1,111 @@
<template>
<component
:is="_elTag"
class="el-radio-group"
role="radiogroup"
@keydown="handleKeydown"
>
<slot></slot>
</component>
</template>
<script>
import Emitter from 'element-ui/src/mixins/emitter';
const keyCode = Object.freeze({
LEFT: 37,
UP: 38,
RIGHT: 39,
DOWN: 40
});
export default {
name: 'ElRadioGroup',
componentName: 'ElRadioGroup',
inject: {
elFormItem: {
default: ''
}
},
mixins: [Emitter],
props: {
value: {},
size: String,
fill: String,
textColor: String,
disabled: Boolean
},
computed: {
_elFormItemSize() {
return (this.elFormItem || {}).elFormItemSize;
},
_elTag() {
return (this.$vnode.data || {}).tag || 'div';
},
radioGroupSize() {
return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
}
},
created() {
this.$on('handleChange', value => {
this.$emit('change', value);
});
},
mounted() {
// 当radioGroup没有默认选项时第一个可以选中Tab导航
const radios = this.$el.querySelectorAll('[type=radio]');
const firstLabel = this.$el.querySelectorAll('[role=radio]')[0];
if (![].some.call(radios, radio => radio.checked) && firstLabel) {
firstLabel.tabIndex = 0;
}
},
methods: {
handleKeydown(e) { // 左右上下按键 可以在radio组内切换不同选项
const target = e.target;
const className = target.nodeName === 'INPUT' ? '[type=radio]' : '[role=radio]';
const radios = this.$el.querySelectorAll(className);
const length = radios.length;
const index = [].indexOf.call(radios, target);
const roleRadios = this.$el.querySelectorAll('[role=radio]');
switch (e.keyCode) {
case keyCode.LEFT:
case keyCode.UP:
e.stopPropagation();
e.preventDefault();
if (index === 0) {
roleRadios[length - 1].click();
roleRadios[length - 1].focus();
} else {
roleRadios[index - 1].click();
roleRadios[index - 1].focus();
}
break;
case keyCode.RIGHT:
case keyCode.DOWN:
if (index === (length - 1)) {
e.stopPropagation();
e.preventDefault();
roleRadios[0].click();
roleRadios[0].focus();
} else {
roleRadios[index + 1].click();
roleRadios[index + 1].focus();
}
break;
default:
break;
}
}
},
watch: {
value(value) {
this.dispatch('ElFormItem', 'el.form.change', [this.value]);
}
}
};
</script>

View File

@@ -0,0 +1,133 @@
<template>
<label
class="el-radio"
:class="[
border && radioSize ? 'el-radio--' + radioSize : '',
{ 'is-disabled': isDisabled },
{ 'is-focus': focus },
{ 'is-bordered': border },
{ 'is-checked': model === label }
]"
role="radio"
:aria-checked="model === label"
:aria-disabled="isDisabled"
:tabindex="tabIndex"
@keydown.space.stop.prevent="model = isDisabled ? model : label"
>
<span class="el-radio__input"
:class="{
'is-disabled': isDisabled,
'is-checked': model === label
}"
>
<span class="el-radio__inner"></span>
<input
ref="radio"
class="el-radio__original"
:value="label"
type="radio"
aria-hidden="true"
v-model="model"
@focus="focus = true"
@blur="focus = false"
@change="handleChange"
:name="name"
:disabled="isDisabled"
tabindex="-1"
>
</span>
<span class="el-radio__label" @keydown.stop>
<slot></slot>
<template v-if="!$slots.default">{{label}}</template>
</span>
</label>
</template>
<script>
import Emitter from 'element-ui/src/mixins/emitter';
export default {
name: 'ElRadio',
mixins: [Emitter],
inject: {
elForm: {
default: ''
},
elFormItem: {
default: ''
}
},
componentName: 'ElRadio',
props: {
value: {},
label: {},
disabled: Boolean,
name: String,
border: Boolean,
size: String
},
data() {
return {
focus: false
};
},
computed: {
isGroup() {
let parent = this.$parent;
while (parent) {
if (parent.$options.componentName !== 'ElRadioGroup') {
parent = parent.$parent;
} else {
this._radioGroup = parent;
return true;
}
}
return false;
},
model: {
get() {
return this.isGroup ? this._radioGroup.value : this.value;
},
set(val) {
if (this.isGroup) {
this.dispatch('ElRadioGroup', 'input', [val]);
} else {
this.$emit('input', val);
}
this.$refs.radio && (this.$refs.radio.checked = this.model === this.label);
}
},
_elFormItemSize() {
return (this.elFormItem || {}).elFormItemSize;
},
radioSize() {
const temRadioSize = this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
return this.isGroup
? this._radioGroup.radioGroupSize || temRadioSize
: temRadioSize;
},
isDisabled() {
return this.isGroup
? this._radioGroup.disabled || this.disabled || (this.elForm || {}).disabled
: this.disabled || (this.elForm || {}).disabled;
},
tabIndex() {
return (this.isDisabled || (this.isGroup && this.model !== this.label)) ? -1 : 0;
}
},
methods: {
handleChange() {
this.$nextTick(() => {
this.$emit('change', this.model);
this.isGroup && this.dispatch('ElRadioGroup', 'handleChange', this.model);
});
}
}
};
</script>