Skip to content

Commit 0bf50bf

Browse files
mdarticLeopoldthecoder
authored andcommitted
Add button style to checkbox (ElemeFE#3697)
* Add button style to checkbox * Implement min/max for checkbox button group * Fixing a display bug when chekbox is ':checked' * Update docs to integrate example button+min/max option * Register correctly checkbox-button Last fixes after cherry pick and bad rebase...
1 parent 8e1d832 commit 0bf50bf

File tree

10 files changed

+591
-6
lines changed

10 files changed

+591
-6
lines changed

components.json

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"radio-group": "./packages/radio-group/index.js",
1616
"radio-button": "./packages/radio-button/index.js",
1717
"checkbox": "./packages/checkbox/index.js",
18+
"checkbox-button": "./packages/checkbox-button/index.js",
1819
"checkbox-group": "./packages/checkbox-group/index.js",
1920
"switch": "./packages/switch/index.js",
2021
"select": "./packages/select/index.js",

examples/docs/en-US/checkbox.md

+44-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
cities: cityOptions,
1414
checkedCities: ['Shanghai', 'Beijing'],
1515
checkedCities1: ['Shanghai', 'Beijing'],
16-
isIndeterminate: true
16+
isIndeterminate: true,
17+
checkboxGroup1: ['Shanghai'],
18+
checkboxGroup2: ['Beijing'],
19+
checkboxGroup3: ['Guangzhou']
1720
};
1821
},
1922
methods: {
@@ -154,7 +157,6 @@ The `indeterminate` property can help you to achieve a 'check all' effect.
154157
```
155158
:::
156159

157-
158160
### Minimum / Maximum items checked
159161

160162
The `min` and `max` properties can help you to limit the number of checked items.
@@ -184,6 +186,43 @@ The `min` and `max` properties can help you to limit the number of checked items
184186
```
185187
:::
186188

189+
### Button style
190+
191+
Checkbox with button styles.
192+
193+
:::demo You just need to change `<el-checkbox>` element into `<el-checkbox-button>` element. We also provide `size` attribute for these buttons: `large` and `small`.
194+
```html
195+
<template>
196+
<div style="margin: 15px 0;"></div>
197+
<el-checkbox-group v-model="checkboxGroup1">
198+
<el-checkbox-button v-for="city in cities" :label="city">{{city}}</el-checkbox-button>
199+
</el-checkbox-group>
200+
<div style="margin: 15px 0;"></div>
201+
<el-checkbox-group v-model="checkboxGroup2" size="small">
202+
<el-checkbox-button v-for="city in cities" :label="city" :disabled="city === 'Shenzhen'">{{city}}</el-checkbox-button>
203+
</el-checkbox-group>
204+
<div style="margin: 15px 0;"></div>
205+
<el-checkbox-group v-model="checkboxGroup3" size="large" fill="#324057" text-color="#a4aebd" :min="1" :max="3">
206+
<el-checkbox-button v-for="city in cities" :label="city">{{city}}</el-checkbox-button>
207+
</el-checkbox-group>
208+
</template>
209+
<script>
210+
const cityOptions = ['Shanghai', 'Beijing', 'Guangzhou', 'Shenzhen'];
211+
212+
export default {
213+
data () {
214+
return {
215+
checkboxGroup1: ['Shanghai'],
216+
checkboxGroup2: ['Beijing'],
217+
checkboxGroup3: ['Guangzhou'],
218+
cities: cityOptions
219+
};
220+
}
221+
}
222+
</script>
223+
```
224+
:::
225+
187226
### Checkbox Attributes
188227
| Attribute | Description | Type | Options | Default|
189228
|---------- |-------- |---------- |------------- |-------- |
@@ -198,6 +237,9 @@ The `min` and `max` properties can help you to limit the number of checked items
198237
### Checkbox-group Attributes
199238
| Attribute | Description | Type | Options | Default|
200239
|---------- |-------- |---------- |------------- |-------- |
240+
|size | the size of checkbox buttons | string | large/small | —
241+
|fill | border and background color when button is active | string || #20a0ff |
242+
|text-color | font color when button is active | string || #ffffff |
201243
| min | minimum number of checkbox checked | number |||
202244
| max | maximum number of checkbox checked | number |||
203245

examples/docs/zh-CN/checkbox.md

+48-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
cities: cityOptions,
1414
checkedCities: ['上海', '北京'],
1515
checkedCities1: ['上海', '北京'],
16-
isIndeterminate: true
16+
isIndeterminate: true,
17+
checkboxGroup1: ['上海'],
18+
checkboxGroup2: ['北京'],
19+
checkboxGroup3: ['广州']
1720
};
1821
},
1922
methods: {
@@ -191,7 +194,46 @@
191194
};
192195
</script>
193196
```
197+
194198
:::
199+
200+
### Button style (to be translated)
201+
202+
Checkbox with button styles.
203+
204+
:::demo 只需要把`el-checkbox`元素换成`el-checkbox-button`元素即可,此外,Element 还提供了`size`属性给按钮组,支持`large``small`两种(如果不设定为默认)
205+
```html
206+
<template>
207+
<div style="margin: 15px 0;"></div>
208+
<el-checkbox-group v-model="checkboxGroup1">
209+
<el-checkbox-button v-for="city in cities" :label="city">{{city}}</el-checkbox-button>
210+
</el-checkbox-group>
211+
<div style="margin: 15px 0;"></div>
212+
<el-checkbox-group v-model="checkboxGroup2" size="small">
213+
<el-checkbox-button v-for="city in cities" :label="city" :disabled="city === '深圳'">{{city}}</el-checkbox-button>
214+
</el-checkbox-group>
215+
<div style="margin: 15px 0;"></div>
216+
<el-checkbox-group v-model="checkboxGroup3" size="large" fill="#324057" text-color="#a4aebd" :min="1" :max="3">
217+
<el-checkbox-button v-for="city in cities" :label="city">{{city}}</el-checkbox-button>
218+
</el-checkbox-group>
219+
</template>
220+
<script>
221+
const cityOptions = ['上海', '北京', '广州', '深圳'];
222+
export default {
223+
data () {
224+
return {
225+
checkboxGroup1: ['上海'],
226+
checkboxGroup2: ['北京'],
227+
checkboxGroup3: ['广州'],
228+
cities: cityOptions
229+
};
230+
}
231+
}
232+
</script>
233+
```
234+
235+
:::
236+
195237
### Checkbox Attributes
196238
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
197239
|---------- |-------- |---------- |------------- |-------- |
@@ -203,9 +245,12 @@
203245
| checked | 当前是否勾选 | boolean || false |
204246
| indeterminate | 设置 indeterminate 状态,只负责样式控制 | boolean || false |
205247

206-
### Checkbox-group Attributes
207-
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
248+
### Checkbox-group Attributes (to be translated)
249+
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
208250
|---------- |-------- |---------- |------------- |-------- |
251+
| size | Checkbox 按钮组尺寸 | string | large, small ||
252+
| fill | 按钮激活时的填充色和边框色 | string || #20a0ff |
253+
| text-color | 按钮激活时的文本颜色 | string || #ffffff |
209254
| min | 可被勾选的 checkbox 的最大数量 | number |||
210255
| max | 可被勾选的 checkbox 的最小数量 | number |||
211256

packages/checkbox-button/index.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import ElCheckboxButton from '../checkbox/src/checkbox-button.vue';
2+
3+
/* istanbul ignore next */
4+
ElCheckboxButton.install = function(Vue) {
5+
Vue.component(ElCheckboxButton.name, ElCheckboxButton);
6+
};
7+
8+
export default ElCheckboxButton;
+161
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
<template>
2+
<label
3+
class="el-checkbox-button"
4+
:class="[
5+
size ? 'el-checkbox-button--' + size : '',
6+
{ 'is-disabled': disabled },
7+
{ 'is-checked': isChecked },
8+
{ 'is-focus': focus },
9+
]"
10+
>
11+
<input
12+
v-if="trueLabel || falseLabel"
13+
class="el-checkbox-button__original"
14+
type="checkbox"
15+
:name="name"
16+
:disabled="disabled"
17+
:true-value="trueLabel"
18+
:false-value="falseLabel"
19+
v-model="model"
20+
@change="handleChange"
21+
@focus="focus = true"
22+
@blur="focus = false">
23+
<input
24+
v-else
25+
class="el-checkbox-button__original"
26+
type="checkbox"
27+
:name="name"
28+
:disabled="disabled"
29+
:value="label"
30+
v-model="model"
31+
@change="handleChange"
32+
@focus="focus = true"
33+
@blur="focus = false">
34+
35+
<span class="el-checkbox-button__inner"
36+
v-if="$slots.default || label"
37+
:style="isChecked ? activeStyle : null">
38+
<slot>{{label}}</slot>
39+
</span>
40+
41+
</label>
42+
</template>
43+
<script>
44+
import Emitter from 'element-ui/src/mixins/emitter';
45+
46+
export default {
47+
name: 'ElCheckboxButton',
48+
49+
mixins: [Emitter],
50+
51+
data() {
52+
return {
53+
selfModel: false,
54+
focus: false
55+
};
56+
},
57+
58+
props: {
59+
value: {},
60+
label: {},
61+
disabled: Boolean,
62+
checked: Boolean,
63+
name: String,
64+
trueLabel: [String, Number],
65+
falseLabel: [String, Number]
66+
},
67+
computed: {
68+
model: {
69+
get() {
70+
return this._checkboxGroup
71+
? this.store : this.value !== undefined
72+
? this.value : this.selfModel;
73+
},
74+
75+
set(val) {
76+
if (this._checkboxGroup) {
77+
let isLimitExceeded = false;
78+
(this._checkboxGroup.min !== undefined &&
79+
val.length < this._checkboxGroup.min &&
80+
(isLimitExceeded = true));
81+
82+
(this._checkboxGroup.max !== undefined &&
83+
val.length > this._checkboxGroup.max &&
84+
(isLimitExceeded = true));
85+
86+
isLimitExceeded === false &&
87+
this.dispatch('ElCheckboxGroup', 'input', [val]);
88+
} else if (this.value !== undefined) {
89+
this.$emit('input', val);
90+
} else {
91+
this.selfModel = val;
92+
}
93+
}
94+
},
95+
96+
isChecked() {
97+
if ({}.toString.call(this.model) === '[object Boolean]') {
98+
return this.model;
99+
} else if (Array.isArray(this.model)) {
100+
return this.model.indexOf(this.label) > -1;
101+
} else if (this.model !== null && this.model !== undefined) {
102+
return this.model === this.trueLabel;
103+
}
104+
},
105+
106+
_checkboxGroup() {
107+
let parent = this.$parent;
108+
while (parent) {
109+
if (parent.$options.componentName !== 'ElCheckboxGroup') {
110+
parent = parent.$parent;
111+
} else {
112+
return parent;
113+
}
114+
}
115+
return false;
116+
},
117+
118+
store() {
119+
return this._checkboxGroup ? this._checkboxGroup.value : this.value;
120+
},
121+
122+
activeStyle() {
123+
return {
124+
backgroundColor: this._checkboxGroup.fill || '',
125+
borderColor: this._checkboxGroup.fill || '',
126+
color: this._checkboxGroup.textColor || '',
127+
'box-shadow': '-1px 0 0 0 ' + this._checkboxGroup.fill
128+
129+
};
130+
},
131+
132+
size() {
133+
return this._checkboxGroup.size;
134+
}
135+
},
136+
methods: {
137+
addToStore() {
138+
if (
139+
Array.isArray(this.model) &&
140+
this.model.indexOf(this.label) === -1
141+
) {
142+
this.model.push(this.label);
143+
} else {
144+
this.model = this.trueLabel || true;
145+
}
146+
},
147+
handleChange(ev) {
148+
this.$emit('change', ev);
149+
if (this._checkboxGroup) {
150+
this.$nextTick(_ => {
151+
this.dispatch('ElCheckboxGroup', 'change', [this._checkboxGroup.value]);
152+
});
153+
}
154+
}
155+
},
156+
157+
created() {
158+
this.checked && this.addToStore();
159+
}
160+
};
161+
</script>

packages/checkbox/src/checkbox-group.vue

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@
1111
props: {
1212
value: {},
1313
min: Number,
14-
max: Number
14+
max: Number,
15+
size: String,
16+
fill: String,
17+
textColor: String
1518
},
1619
1720
watch: {

0 commit comments

Comments
 (0)