Commit 342390e691f0a67379663cc315e882aef68c54a3

Authored by Aresn
Committed by GitHub
2 parents 105af4ee a646fc36

Merge pull request #2882 from iview/pr/2867

Pr/2867
examples/routers/radio.vue
... ... @@ -43,12 +43,12 @@
43 43 data () {
44 44 return {
45 45 single: true,
46   - phone: 'apple',
  46 + phone: '',
47 47 button2: '北京',
48   - }
  48 + };
49 49 },
50 50 methods: {
51 51  
52 52 }
53   - }
  53 + };
54 54 </script>
... ...
src/components/radio/radio-group.vue
1 1 <template>
2   - <div :class="classes">
  2 + <div :class="classes" :name="name">
3 3 <slot></slot>
4 4 </div>
5 5 </template>
... ... @@ -9,6 +9,10 @@
9 9  
10 10 const prefixCls = 'ivu-radio-group';
11 11  
  12 + let seed = 0;
  13 + const now = Date.now();
  14 + const getUuid = () => `ivuRadioGroup_${now}_${seed++}`;
  15 +
12 16 export default {
13 17 name: 'RadioGroup',
14 18 mixins: [ Emitter ],
... ... @@ -30,6 +34,10 @@
30 34 vertical: {
31 35 type: Boolean,
32 36 default: false
  37 + },
  38 + name: {
  39 + type: String,
  40 + default: getUuid
33 41 }
34 42 },
35 43 data () {
... ... @@ -56,12 +64,10 @@
56 64 },
57 65 methods: {
58 66 updateValue () {
59   - const value = this.value;
60 67 this.childrens = findComponentsDownward(this, 'Radio');
61   -
62 68 if (this.childrens) {
63 69 this.childrens.forEach(child => {
64   - child.currentValue = value == child.label;
  70 + child.currentValue = this.value === child.label;
65 71 child.group = true;
66 72 });
67 73 }
... ... @@ -76,6 +82,7 @@
76 82 },
77 83 watch: {
78 84 value () {
  85 + this.currentValue = this.value;
79 86 this.updateValue();
80 87 }
81 88 }
... ...
src/components/radio/radio.vue
1 1 <template>
2   - <label
3   - :class="wrapClasses"
4   - :tabindex="disabled ? -1 : 0"
5   - @keyup.space="change">
  2 + <label :class="wrapClasses">
6 3 <span :class="radioClasses">
7 4 <span :class="innerClasses"></span>
8 5 <input
9 6 type="radio"
10   - tabindex="-1"
11 7 :class="inputClasses"
12 8 :disabled="disabled"
13 9 :checked="currentValue"
14   - :name="name"
  10 + :name="groupName"
15 11 @change="change"
16   - >
17   - </span><slot>{{ label }}</slot>
  12 + @focus="onFocus"
  13 + @blur="onBlur">
  14 + </span>
  15 + <slot>{{ label }}</slot>
18 16 </label>
19 17 </template>
20 18 <script>
... ... @@ -59,7 +57,10 @@
59 57 return {
60 58 currentValue: this.value,
61 59 group: false,
62   - parent: findComponentUpward(this, 'RadioGroup')
  60 + groupName: this.name,
  61 + parent: findComponentUpward(this, 'RadioGroup'),
  62 + focusWrapper: false,
  63 + focusInner: false
63 64 };
64 65 },
65 66 computed: {
... ... @@ -70,7 +71,8 @@
70 71 [`${prefixCls}-group-item`]: this.group,
71 72 [`${prefixCls}-wrapper-checked`]: this.currentValue,
72 73 [`${prefixCls}-wrapper-disabled`]: this.disabled,
73   - [`${prefixCls}-${this.size}`]: !!this.size
  74 + [`${prefixCls}-${this.size}`]: !!this.size,
  75 + [`${prefixCls}-focus`]: this.focusWrapper
74 76 }
75 77 ];
76 78 },
... ... @@ -84,18 +86,35 @@
84 86 ];
85 87 },
86 88 innerClasses () {
87   - return `${prefixCls}-inner`;
  89 + return [
  90 + `${prefixCls}-inner`,
  91 + {
  92 + [`${prefixCls}-focus`]: this.focusInner
  93 + }
  94 + ];
88 95 },
89 96 inputClasses () {
90 97 return `${prefixCls}-input`;
91 98 }
92 99 },
93 100 mounted () {
94   - if (this.parent) this.group = true;
95   - if (!this.group) {
96   - this.updateValue();
97   - } else {
  101 + if (this.parent) {
  102 + this.group = true;
  103 + if (this.name && this.name !== this.parent.name) {
  104 + /* eslint-disable no-console */
  105 + if (console.warn) {
  106 + console.warn('[iview] Name does not match Radio Group name.');
  107 + }
  108 + /* eslint-enable no-console */
  109 + } else {
  110 + this.groupName = this.parent.name;
  111 + }
  112 + }
  113 +
  114 + if (this.group) {
98 115 this.parent.updateValue();
  116 + } else {
  117 + this.updateValue();
99 118 }
100 119 },
101 120 methods: {
... ... @@ -107,30 +126,43 @@
107 126 const checked = event.target.checked;
108 127 this.currentValue = checked;
109 128  
110   - let value = checked ? this.trueValue : this.falseValue;
  129 + const value = checked ? this.trueValue : this.falseValue;
111 130 this.$emit('input', value);
112 131  
113   - if (this.group && this.label !== undefined) {
114   - this.parent.change({
115   - value: this.label,
116   - checked: this.value
117   - });
118   - }
119   - if (!this.group) {
  132 + if (this.group) {
  133 + if (this.label !== undefined) {
  134 + this.parent.change({
  135 + value: this.label,
  136 + checked: this.value
  137 + });
  138 + }
  139 + } else {
120 140 this.$emit('on-change', value);
121 141 this.dispatch('FormItem', 'on-form-change', value);
122 142 }
123 143 },
124 144 updateValue () {
125 145 this.currentValue = this.value === this.trueValue;
  146 + },
  147 + onBlur () {
  148 + this.focusWrapper = false;
  149 + this.focusInner = false;
  150 + },
  151 + onFocus () {
  152 + if (this.group && this.parent.type === 'button') {
  153 + this.focusWrapper = true;
  154 + } else {
  155 + this.focusInner = true;
  156 + }
126 157 }
127 158 },
128 159 watch: {
129 160 value (val) {
130   - if (val !== this.trueValue && val !== this.falseValue) {
  161 + if (val === this.trueValue || val === this.falseValue) {
  162 + this.updateValue();
  163 + } else {
131 164 throw 'Value should be trueValue or falseValue.';
132 165 }
133   - this.updateValue();
134 166 }
135 167 }
136 168 };
... ...
src/styles/components/radio.less
... ... @@ -3,10 +3,16 @@
3 3 @radio-inner-prefix-cls: ~"@{radio-prefix-cls}-inner";
4 4 @radio-group-button-prefix-cls: ~"@{radio-group-prefix-cls}-button";
5 5  
  6 +.@{radio-prefix-cls}-focus {
  7 + box-shadow: 0 0 0 2px fade(@primary-color, 20%);
  8 + z-index: 1;
  9 +}
  10 +
6 11 .@{radio-group-prefix-cls} {
7 12 display: inline-block;
8 13 font-size: @font-size-small;
9 14 vertical-align: middle;
  15 + //outline: none;
10 16 &-vertical{
11 17 .@{radio-prefix-cls}-wrapper {
12 18 display: block;
... ... @@ -28,19 +34,14 @@
28 34 &-disabled{
29 35 cursor: @cursor-disabled;
30 36 }
31   - outline: 0;
32   - &:focus {
33   - & .@{radio-inner-prefix-cls} {
34   - box-shadow: 0 0 0 2px fade(@primary-color, 20%);
35   - }
36   - }
  37 + //outline: none;
37 38 }
38 39  
39 40 .@{radio-prefix-cls} {
40 41 display: inline-block;
41 42 margin-right: 4px;
42 43 white-space: nowrap;
43   - outline: none;
  44 + //outline: none;
44 45 position: relative;
45 46 line-height: 1;
46 47 vertical-align: middle;
... ... @@ -177,7 +178,7 @@ span.@{radio-prefix-cls} + * {
177 178 height: @btn-circle-size;
178 179 line-height: @btn-circle-size - 2px;
179 180 margin: 0;
180   - padding: 0 16px;
  181 + padding: 0 16px - 1px;
181 182 font-size: @font-size-small;
182 183 color: @btn-default-color;
183 184 transition: all @transition-time ease-in-out;
... ... @@ -185,26 +186,37 @@ span.@{radio-prefix-cls} + * {
185 186 border: 1px solid @border-color-base;
186 187 border-left: 0;
187 188 background: #fff;
  189 + position: relative;
188 190  
189 191 > span {
190 192 margin-left: 0;
191 193 }
192 194  
193   - &:before {
  195 + &:before, &:after {
194 196 content: '';
  197 + display: block;
195 198 position: absolute;
196 199 width: 1px;
197 200 height: 100%;
198 201 left: -1px;
  202 + top: 0;
199 203 background: @border-color-base;
200   - visibility: hidden;
  204 + //visibility: hidden;
201 205 transition: all @transition-time ease-in-out;
202 206 }
203 207  
  208 + &:after{
  209 + height: @btn-circle-size + 4px;
  210 + left: -1px;
  211 + top: -3px;
  212 + background: fade(@primary-color, 20%);
  213 + opacity: 0;
  214 + }
  215 +
204 216 &:first-child {
205 217 border-radius: @btn-border-radius 0 0 @btn-border-radius;
206 218 border-left: 1px solid @border-color-base;
207   - &:before {
  219 + &:before, &:after {
208 220 display: none;
209 221 }
210 222 }
... ... @@ -225,10 +237,6 @@ span.@{radio-prefix-cls} + * {
225 237 }
226 238 }
227 239  
228   - &:focus {
229   - box-shadow: 0 0 0 2px fade(@primary-color, 20%);
230   - }
231   -
232 240 .@{radio-prefix-cls}-inner,
233 241 input {
234 242 opacity: 0;
... ... @@ -241,25 +249,41 @@ span.@{radio-prefix-cls} + * {
241 249 border-color: @primary-color;
242 250 color: @primary-color;
243 251 box-shadow: -1px 0 0 0 @primary-color;
  252 + z-index: 1;
  253 +
  254 + &:before{
  255 + background: @primary-color;
  256 + opacity: 0.1;
  257 + }
  258 +
  259 + &.@{radio-prefix-cls}-focus{
  260 + box-shadow: -1px 0 0 0 @primary-color, 0 0 0 2px fade(@primary-color, 20%);
  261 + transition: all @transition-time ease-in-out;
  262 + &:after{
  263 + left: -3px;
  264 + top: -3px;
  265 + opacity: 1;
  266 + background: fade(@primary-color, 20%);
  267 + }
  268 + &:first-child{
  269 + box-shadow: 0 0 0 2px fade(@primary-color, 20%);
  270 + }
  271 + }
244 272  
245 273 &:first-child {
246 274 border-color: @primary-color;
247   - box-shadow: none!important;
  275 + box-shadow: none;
248 276 }
249 277  
250 278 &:hover {
251 279 border-color: tint(@primary-color, 20%);
252   - box-shadow: -1px 0 0 0 tint(@primary-color, 20%);
  280 + //box-shadow: -1px 0 0 0 tint(@primary-color, 20%);
253 281 color: tint(@primary-color, 20%);
254 282 }
255 283  
256   - &:focus {
257   - box-shadow: 0 0 0 2px fade(@primary-color, 20%)!important;
258   - }
259   -
260 284 &:active {
261 285 border-color: shade(@primary-color, 5%);
262   - box-shadow: -1px 0 0 0 shade(@primary-color, 5%);
  286 + //box-shadow: -1px 0 0 0 shade(@primary-color, 5%);
263 287 color: shade(@primary-color, 5%);
264 288 }
265 289 }
... ... @@ -294,6 +318,9 @@ span.@{radio-prefix-cls} + * {
294 318 height: @btn-circle-size-large;
295 319 line-height: @btn-circle-size-large - 2px;
296 320 font-size: @font-size-base;
  321 + &:after{
  322 + height: @btn-circle-size-large + 4px;
  323 + }
297 324 }
298 325  
299 326 .@{radio-group-button-prefix-cls}.@{radio-group-prefix-cls}-small .@{radio-prefix-cls}-wrapper{
... ... @@ -301,6 +328,11 @@ span.@{radio-prefix-cls} + * {
301 328 line-height: @btn-circle-size-small - 2px;
302 329 padding: 0 12px;
303 330 font-size: @font-size-small;
  331 +
  332 + &:after{
  333 + height: @btn-circle-size-small + 4px;
  334 + }
  335 +
304 336 &:first-child {
305 337 border-radius: @btn-border-radius-small 0 0 @btn-border-radius-small;
306 338 }
... ...