Skip to content

Commit db7f461

Browse files
committed
feat: update checkbox
1 parent 05f7f69 commit db7f461

File tree

8 files changed

+170
-90
lines changed

8 files changed

+170
-90
lines changed

Diff for: .vscode/settings.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"editor.codeActionsOnSave": {
3+
"source.organizeImports": false
4+
}
5+
}

Diff for: demo/components/checkbox/checkbox.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ export default {
44
checked: false,
55
indeterminate_: false,
66
disabled: false,
7-
7+
checkedSolo: false,
88
ids: [],
99
};
1010
},

Diff for: demo/components/checkbox/demo.vue

+49-23
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
<template>
22
<div class="my-demo">
3-
<div class="mcw-demo--container">
4-
<mcw-checkbox
5-
v-model="checked"
6-
v-model:indeterminate="indeterminate"
7-
:disabled="disabled"
8-
:label="checked ? 'Checked' : 'Unchecked'"
9-
/>
10-
11-
<div>
3+
<div class="mcw-demo--wrapper">
4+
<div class="mcw-demo--container">
5+
<mcw-checkbox
6+
v-model="checked"
7+
v-model:indeterminate="indeterminate"
8+
:disabled="disabled"
9+
:label="checked ? 'Checked' : 'Unchecked'"
10+
/>
11+
</div>
12+
<div class="mcw-demo--wrapper-actions">
1213
<mcw-button outlined @click="onIndeterminate"
1314
>make indeterminate</mcw-button
1415
>
@@ -18,22 +19,32 @@
1819
</div>
1920
</div>
2021

21-
<div class="mcw-demo--container">
22+
<div class="mcw-demo--wrapper">
2223
<div>Array selection</div>
23-
<mcw-checkbox
24-
value="abc"
25-
label="one"
26-
:model-value="ids"
27-
@update:modelValue="onIds"
28-
/>
29-
<mcw-checkbox
30-
value="xyz"
31-
label="two"
32-
:model-value="ids"
33-
@update:modelValue="onIds"
34-
/>
24+
<div class="mcw-demo--container">
25+
<mcw-checkbox
26+
value="abc"
27+
label="one"
28+
:model-value="ids"
29+
@update:modelValue="onIds"
30+
/>
31+
<mcw-checkbox
32+
value="xyz"
33+
label="two"
34+
:model-value="ids"
35+
@update:modelValue="onIds"
36+
/>
37+
</div>
38+
<div class="mcw-demo--wrapper-label">Selected IDs: {{ ids }}</div>
39+
</div>
40+
<div class="mcw-demo--wrapper">
41+
<div>Without label</div>
42+
<div class="mcw-demo--container">
43+
<mcw-checkbox v-model="checkedSolo" />
44+
</div>
45+
46+
<div class="mcw-demo--wrapper-label">checked: {{ checkedSolo }}</div>
3547
</div>
36-
<div>Selected IDs: {{ ids }}</div>
3748
</div>
3849
</template>
3950

@@ -47,4 +58,19 @@
4758
margin-bottom: 1em;
4859
background-color: #f2f2f2;
4960
}
61+
62+
.mcw-demo--wrapper {
63+
margin-bottom: 1em;
64+
background-color: #f2f2f2;
65+
}
66+
67+
.mcw-demo--wrapper-actions {
68+
display: flex;
69+
justify-content: center;
70+
margin-top: -2em;
71+
}
72+
73+
.mcw-demo--wrapper .mcw-demo--wrapper-label {
74+
margin-top: -1em;
75+
}
5076
</style>

Diff for: package-lock.json

+20-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: package.json

+7-5
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@
141141
"postcss-loader": "^6.2.1",
142142
"postcss-preset-env": "^7.4.3",
143143
"prettier": "^2.6.1",
144+
"prettier-plugin-organize-imports": "^2.3.4",
144145
"regenerator-runtime": "^0.13.9",
145146
"rollup": "^2.70.1",
146147
"rollup-plugin-cleaner": "^1.0.0",
@@ -199,15 +200,16 @@
199200
"browser": true
200201
},
201202
"rules": {
202-
"vue/no-v-model-argument": "off",
203-
"no-unused-vars": "error",
204203
"no-else-return": 1,
205204
"prefer-const": "error",
206205
"no-var": "error",
207-
"no-nested-ternary": "off",
208-
"unicorn/no-array-reduce": [
209-
"off"
206+
"no-unused-vars": [
207+
"error",
208+
{
209+
"ignoreRestSiblings": true
210+
}
210211
],
212+
"no-nested-ternary": "off",
211213
"unicorn/no-nested-ternary": [
212214
"off"
213215
],

Diff for: src/checkbox/checkbox-content.js

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { MDCFormFieldFoundation } from '@material/form-field/foundation.js';
2+
import { computed, h, onBeforeUnmount, onMounted, ref } from 'vue';
3+
4+
export default {
5+
props: {
6+
activate: Function,
7+
deactivate: Function,
8+
alignEnd: Boolean,
9+
checkboxId: String,
10+
},
11+
inheritAttrs: false,
12+
setup(props, { slots }) {
13+
const labelElement = ref();
14+
15+
let formField;
16+
17+
const hasLabel = !!slots.label;
18+
19+
const formFieldClasses = computed(() => {
20+
return {
21+
'mdc-form-field': hasLabel,
22+
'mdc-form-field--align-end': hasLabel && props.alignEnd,
23+
};
24+
});
25+
26+
onMounted(() => {
27+
if (props.hasLabel) {
28+
formField = new MDCFormFieldFoundation({
29+
registerInteractionHandler: (type, handler) => {
30+
labelElement.value.addEventListener(type, handler);
31+
},
32+
deregisterInteractionHandler: (type, handler) => {
33+
labelElement.value.removeEventListener(type, handler);
34+
},
35+
activateInputRipple: () => {
36+
props?.activate();
37+
},
38+
deactivateInputRipple: () => {
39+
props?.deactivate();
40+
},
41+
});
42+
formField.init();
43+
}
44+
});
45+
46+
onBeforeUnmount(() => {
47+
formField?.destroy();
48+
});
49+
50+
return () => {
51+
if (hasLabel) {
52+
return h(
53+
'div',
54+
{ class: { 'mdc-checkbox-wrapper': 1, ...formFieldClasses.value } },
55+
[
56+
slots.default?.(),
57+
h(
58+
'label',
59+
{
60+
for: props.checkboxId,
61+
ref: labelElement,
62+
},
63+
[slots.label?.()],
64+
),
65+
],
66+
);
67+
}
68+
69+
return slots.default();
70+
};
71+
},
72+
};

Diff for: src/checkbox/checkbox.js

+6-32
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { getCorrectEventName } from '@material/animation/index.js';
22
import { MDCCheckboxFoundation } from '@material/checkbox/foundation.js';
33
import { applyPassive } from '@material/dom/events.js';
44
import { matches } from '@material/dom/ponyfill.js';
5-
import { MDCFormFieldFoundation } from '@material/form-field/foundation.js';
65
import {
76
computed,
87
onBeforeUnmount,
@@ -14,6 +13,7 @@ import {
1413
} from 'vue';
1514
import { emitCustomEvent } from '../base/custom-event.js';
1615
import { useRipplePlugin } from '../ripple/ripple-plugin.js';
16+
import checkboxContent from './checkbox-content.js';
1717

1818
const CB_PROTO_PROPS = ['checked', 'indeterminate'];
1919
let checkboxId_ = 0;
@@ -43,7 +43,6 @@ export default {
4343
});
4444

4545
let foundation;
46-
let formField;
4746
const checkboxId = `__mcw-checkbox-${checkboxId_++}`;
4847

4948
const {
@@ -71,16 +70,8 @@ export default {
7170
return { ...rippleClasses.value, ...uiState.classes };
7271
});
7372

74-
const hasLabel = computed(() => {
75-
return props.label ?? slots.default;
76-
});
73+
const hasLabel = computed(() => !!(props.label || slots.default));
7774

78-
const formFieldClasses = computed(() => {
79-
return {
80-
'mdc-form-field': hasLabel.value,
81-
'mdc-form-field--align-end': hasLabel.value && props.alignEnd,
82-
};
83-
});
8475
const onChange = ({ target: { indeterminate, checked } }) => {
8576
// note indeterminate will not currently work with the array model
8677
emit('update:indeterminate', indeterminate);
@@ -116,7 +107,6 @@ export default {
116107
isChecked: () => uiState.control.checked,
117108
isIndeterminate: () => uiState.control.indeterminate,
118109
removeClass: className => {
119-
// eslint-disable-next-line no-unused-vars
120110
const { [className]: removed, ...rest } = uiState.classes;
121111
uiState.classes = rest;
122112
},
@@ -217,23 +207,6 @@ export default {
217207
);
218208

219209
installPropertyChangeHooks_();
220-
if (hasLabel.value) {
221-
formField = new MDCFormFieldFoundation({
222-
registerInteractionHandler: (type, handler) => {
223-
uiState.labelEl.addEventListener(type, handler);
224-
},
225-
deregisterInteractionHandler: (type, handler) => {
226-
uiState.labelEl.removeEventListener(type, handler);
227-
},
228-
activateInputRipple: () => {
229-
activate();
230-
},
231-
deactivateInputRipple: () => {
232-
deactivate();
233-
},
234-
});
235-
formField.init();
236-
}
237210

238211
foundation.init();
239212

@@ -248,25 +221,26 @@ export default {
248221
handleAnimationEnd,
249222
);
250223

251-
formField?.destroy();
252-
253224
uninstallPropertyChangeHooks_();
254225
foundation.destroy();
255226
});
256227

257228
return {
258229
...toRefs(uiState),
259230
rootClasses,
260-
formFieldClasses,
261231
onChange,
262232
styles,
263233
hasLabel,
264234
setChecked,
265235
setIndeterminate,
266236
isChecked,
267237
checkboxId,
238+
activate,
239+
deactivate,
268240
};
269241
},
242+
243+
components: { checkboxContent },
270244
};
271245

272246
// ===

0 commit comments

Comments
 (0)