Skip to content

Commit 824e696

Browse files
committed
Accessibility fix, readme update and cleanups.
1 parent 711ac72 commit 824e696

File tree

10 files changed

+249
-136
lines changed

10 files changed

+249
-136
lines changed

README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ vue-toggle-component makes an ease to use, lightweight and highly customizable t
99
![Light theme](https://user-images.githubusercontent.com/25898715/116152862-c273f400-a6e6-11eb-8b4d-1017b92d14a5.gif)
1010
![Dark theme](https://user-images.githubusercontent.com/25898715/116152879-c7d13e80-a6e6-11eb-87b3-9b606184ba1e.gif)
1111

12+
## Features
13+
14+
- **🍞 Easy:** Easy use with minimal required properties.
15+
- **🍤 Tiny:** Small footprint < 4kb which makes your apps faster to load.
16+
- **✅ Accessible:** ARIA attributes in the component which makes it very accessible.
17+
1218
## Getting Started
1319
### Installation
1420
#### Installing the package
@@ -51,6 +57,30 @@ export default {
5157
| fontWeight | `Boolean` | `normal` || Sets the font weight of the text next to the toggle. |
5258
| toggled | `Boolean` | `true` || Sets the default value for the toggler. |
5359

60+
#### Events
61+
When you toggle the component the component emits the `toggle` event. You can use the event using the example below. The value in the event is the whether the toggler is toggled or not.
62+
```html
63+
<template>
64+
<VueToggle title="Toggle me" name="VueToggle" @toggle="doSomething"/>
65+
</template>
66+
67+
<script>
68+
import VueToggle from "vue-toggle-component";
69+
70+
export default {
71+
name: 'App',
72+
components: {
73+
VueToggle
74+
},
75+
methods: {
76+
doSomething(value) {
77+
// value = true || false.
78+
}
79+
},
80+
}
81+
</script>
82+
```
83+
5484
### Vue version support
5585
The main v1 version supports Vue 3.x only, for previous versions of Vue, check the following the table.
5686

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vue-toggle-component",
3-
"version": "1.0.14",
3+
"version": "1.0.15",
44
"main": "dist/vue-toggle-component.common.js",
55
"files": [
66
"dist/*"

src/App.vue

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,12 @@ import VueToggle from "./components/VueToggle";
77
88
export default {
99
name: 'App',
10-
components: {
11-
VueToggle
12-
}
10+
components: { VueToggle }
1311
}
1412
</script>
1513
<style>
1614
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@500&display=swap');
15+
1716
* {
1817
font-family: 'Roboto', sans-serif;
1918
}

src/components/VueToggle.vue

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
<template>
22
<section
3-
:class="{'dark': darkTheme, disabled}"
3+
:class="{
4+
'is-dark': darkTheme,
5+
'is-disabled': disabled,
6+
}"
47
class="m-toggle"
58
>
69
<input
@@ -14,17 +17,22 @@
1417
<span
1518
:aria-checked="toggleState"
1619
:aria-disabled="disabled"
20+
:aria-labelledby="`${id}-label`"
1721
:aria-readonly="disabled"
18-
:aria-labelledby="labelId"
19-
:style="toggleState && {background: activeColor}"
22+
:style="toggleState && {
23+
'background-color': activeColor
24+
}"
2025
class="m-toggle__content"
2126
role="checkbox"
2227
@click="toggle"
2328
/>
2429
<label
25-
:id="labelId"
30+
:id="`${id}-label`"
2631
:for="id"
27-
:style="[{fontSize: `${fontSize}px`, fontWeight}]"
32+
:style="{
33+
'font-size': fontSize,
34+
'font-weight': fontWeight,
35+
}"
2836
class="m-toggle__label"
2937
>
3038
{{ title }}
@@ -40,33 +48,29 @@ export default {
4048
activeColor: { type: String, default: '#9FD6AE' },
4149
darkTheme: { type: Boolean, default: false },
4250
disabled: { type: Boolean, default: false },
43-
fontSize: { type: Number, default: 16 },
51+
fontSize: { type: String, default: '16px' },
4452
fontWeight: { type: String, default: 'normal' },
4553
name: { type: String, required: true },
4654
title: { type: String, required: true },
4755
toggled: { type: Boolean, default: false },
4856
},
4957
5058
data() {
51-
return {
52-
toggleState: this.toggled
53-
}
59+
return { toggleState: this.toggled }
5460
},
5561
5662
methods: {
5763
toggle() {
5864
if (this.disabled) return;
59-
this.toggleState = !this.toggleState
65+
this.toggleState = !this.toggleState;
66+
this.$emit('toggle', this.toggleState);
6067
}
6168
},
6269
6370
computed: {
6471
id() {
6572
return this.name.replace(/ /g, '').toLowerCase();
6673
},
67-
labelId() {
68-
return `${this.id}-label`
69-
},
7074
},
7175
}
7276
</script>
@@ -75,8 +79,8 @@ export default {
7579
.m-toggle {
7680
$self: &;
7781
$toggle-spacing: 2px;
78-
display: flex;
7982
align-items: center;
83+
display: flex;
8084
margin: 0 -5px;
8185
8286
> * {
@@ -87,11 +91,11 @@ export default {
8791
&__label {
8892
user-select: none;
8993
90-
.disabled & {
94+
.is-disabled & {
9195
cursor: not-allowed;
9296
}
9397
94-
.dark & {
98+
.is-dark & {
9599
color: white;
96100
}
97101
}
@@ -109,19 +113,21 @@ export default {
109113
}
110114
111115
&__content {
112-
box-sizing: border-box;
113116
background: #F0F0F0;
114117
border-radius: 2em;
118+
box-sizing: border-box;
115119
height: 2em;
116120
outline: 0;
121+
overflow: hidden;
117122
padding: $toggle-spacing;
118-
transition: background .4s ease;
123+
transition: background-color .4s ease;
119124
width: 4em;
120-
will-change: background;
125+
will-change: background-color;
121126
122127
&:after {
123128
background: white;
124129
border-radius: 50%;
130+
box-shadow: 0 0 5px 0 rgba(0, 0, 0, .05);
125131
content: '';
126132
display: block;
127133
height: 100%;
@@ -132,12 +138,12 @@ export default {
132138
will-change: left;
133139
}
134140
135-
.disabled & {
136-
opacity: 50%;
141+
.is-disabled & {
137142
cursor: not-allowed;
143+
opacity: 50%;
138144
}
139145
140-
.dark & {
146+
.is-dark & {
141147
background: #374151;
142148
}
143149
}

vue-toggle-component/README.md

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ vue-toggle-component makes an ease to use, lightweight and highly customizable t
99
![Light theme](https://user-images.githubusercontent.com/25898715/116152862-c273f400-a6e6-11eb-8b4d-1017b92d14a5.gif)
1010
![Dark theme](https://user-images.githubusercontent.com/25898715/116152879-c7d13e80-a6e6-11eb-87b3-9b606184ba1e.gif)
1111

12+
## Features
13+
14+
- **🍞 Easy:** Easy use with minimal required properties.
15+
- **🍤 Tiny:** Small footprint < 4kb which makes your apps faster to load.
16+
- **✅ Accessible:** ARIA attributes in the component which makes it very accessible.
17+
1218
## Getting Started
1319
### Installation
1420
#### Installing the package
@@ -48,9 +54,33 @@ export default {
4854
| darkTheme | `Boolean` | `false` || Set's dark mode to active. (note that this will not change the background like in the preview GIF) |
4955
| disabled | `Number` | `false` || Disables the toggler. |
5056
| fontSize | `String` | `16` || Sets the font size of the text next to the toggle |
51-
| fontWeight | `Boolean` | `bold` || Sets the font weight of the text next to the toggle. |
57+
| fontWeight | `Boolean` | `normal` || Sets the font weight of the text next to the toggle. |
5258
| toggled | `Boolean` | `true` || Sets the default value for the toggler. |
5359

60+
#### Events
61+
When you toggle the component the component emits the `toggle` event. You can use the event using the example below. The value in the event is the whether the toggler is toggled or not.
62+
```html
63+
<template>
64+
<VueToggle title="Toggle me" name="VueToggle" @toggle="doSomething"/>
65+
</template>
66+
67+
<script>
68+
import VueToggle from "vue-toggle-component";
69+
70+
export default {
71+
name: 'App',
72+
components: {
73+
VueToggle
74+
},
75+
methods: {
76+
doSomething(value) {
77+
// value = true || false.
78+
}
79+
},
80+
}
81+
</script>
82+
```
83+
5484
### Vue version support
5585
The main v1 version supports Vue 3.x only, for previous versions of Vue, check the following the table.
5686

vue-toggle-component/dist/vue-toggle-component.esm.js

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ var script = {
1515
type: Boolean,
1616
default: false
1717
},
18+
fontSize: {
19+
type: String,
20+
default: '16px'
21+
},
22+
fontWeight: {
23+
type: String,
24+
default: 'normal'
25+
},
1826
name: {
1927
type: String,
2028
required: true
@@ -39,38 +47,53 @@ var script = {
3947
toggle() {
4048
if (this.disabled) return;
4149
this.toggleState = !this.toggleState;
50+
this.$emit('toggle', this.toggleState);
51+
}
52+
53+
},
54+
computed: {
55+
id() {
56+
return this.name.replace(/ /g, '').toLowerCase();
4257
}
4358

4459
}
4560
};
4661

47-
const _withId = /*#__PURE__*/withScopeId("data-v-84279cda");
62+
const _withId = /*#__PURE__*/withScopeId("data-v-576222af");
4863

4964
const render = /*#__PURE__*/_withId((_ctx, _cache, $props, $setup, $data, $options) => {
5065
return openBlock(), createBlock("section", {
5166
class: [{
52-
'dark': $props.darkTheme,
53-
'disabled': $props.disabled
54-
}, "wrapper"],
55-
title: $props.title
67+
'is-dark': $props.darkTheme,
68+
'is-disabled': $props.disabled
69+
}, "m-toggle"]
5670
}, [withDirectives(createVNode("input", {
57-
id: `_${$props.name}`,
71+
id: $options.id,
5872
"onUpdate:modelValue": _cache[1] || (_cache[1] = $event => $data.toggleState = $event),
5973
disabled: $props.disabled,
6074
name: $props.name,
61-
class: "toggle",
75+
class: "m-toggle__input",
6276
type: "checkbox"
63-
}, null, 8, ["id", "disabled", "name"]), [[vModelCheckbox, $data.toggleState]]), createVNode("label", {
64-
for: $props.name,
65-
style: [$data.toggleState && {
66-
'background': $props.activeColor
67-
}],
68-
class: "toggler",
77+
}, null, 8, ["id", "disabled", "name"]), [[vModelCheckbox, $data.toggleState]]), createVNode("span", {
78+
"aria-checked": $data.toggleState,
79+
"aria-disabled": $props.disabled,
80+
"aria-labelledby": `${$options.id}-label`,
81+
"aria-readonly": $props.disabled,
82+
style: $data.toggleState && {
83+
'background-color': $props.activeColor
84+
},
85+
class: "m-toggle__content",
86+
role: "checkbox",
6987
onClick: _cache[2] || (_cache[2] = (...args) => $options.toggle && $options.toggle(...args))
70-
}, null, 12, ["for"]), createVNode("span", {
71-
class: "title",
72-
onClick: _cache[3] || (_cache[3] = (...args) => $options.toggle && $options.toggle(...args))
73-
}, toDisplayString($props.title), 1)], 10, ["title"]);
88+
}, null, 12, ["aria-checked", "aria-disabled", "aria-labelledby", "aria-readonly"]), createVNode("label", {
89+
id: `${$options.id}-label`,
90+
for: $options.id,
91+
style: {
92+
'font-size': $props.fontSize,
93+
'font-weight': $props.fontWeight
94+
},
95+
class: "m-toggle__label"
96+
}, toDisplayString($props.title), 13, ["id", "for"])], 2);
7497
});
7598

7699
function styleInject(css, ref) {
@@ -100,11 +123,11 @@ function styleInject(css, ref) {
100123
}
101124
}
102125

103-
var css_248z = "\n.wrapper[data-v-84279cda] {\n display: flex;\n flex-wrap: wrap;\n padding: 5px;\n}\n.wrapper > *[data-v-84279cda] {\n cursor: pointer;\n margin: 0 5px;\n}\n.title[data-v-84279cda] {\n display: inline-block;\n font-weight: 700;\n line-height: 2em;\n vertical-align: middle;\n}\n.title[data-v-84279cda]::selection {\n background: none;\n}\n.disabled .title[data-v-84279cda]:hover {\n cursor: not-allowed;\n}\n.dark .title[data-v-84279cda] {\n color: white;\n}\n.toggle[data-v-84279cda] {\n display: none;\n}\n.toggle[data-v-84279cda]:after, .toggle + .toggler[data-v-84279cda] {\n box-sizing: border-box;\n}\n.toggle[data-v-84279cda]:after::selection, .toggle + .toggler[data-v-84279cda]::selection {\n background: none;\n}\n.toggle + .toggler[data-v-84279cda] {\n background: #f0f0f0;\n border-radius: 2em;\n display: block;\n height: 2em;\n outline: 0;\n padding: 2px;\n position: relative;\n transition: background 0.4s ease;\n user-select: none;\n width: 4em;\n will-change: background;\n}\n.toggle + .toggler[data-v-84279cda]:after {\n background: white;\n border-radius: 50%;\n content: \"\";\n display: block;\n height: 100%;\n left: 0;\n position: relative;\n transition: left 0.2s ease;\n width: 50%;\n will-change: left;\n}\n.disabled .toggle + .toggler[data-v-84279cda] {\n opacity: 50%;\n}\n.disabled .toggle + .toggler[data-v-84279cda]:hover {\n cursor: not-allowed;\n}\n.dark .toggle + .toggler[data-v-84279cda] {\n background: #374151;\n}\n.toggle:checked + .toggler[data-v-84279cda]:after {\n left: 50%;\n}\n\n";
126+
var css_248z = "\n.m-toggle[data-v-576222af] {\n align-items: center;\n display: flex;\n margin: 0 -5px;\n}\n.m-toggle > *[data-v-576222af] {\n cursor: pointer;\n margin: 0 5px;\n}\n.m-toggle__label[data-v-576222af] {\n user-select: none;\n}\n.is-disabled .m-toggle__label[data-v-576222af] {\n cursor: not-allowed;\n}\n.is-dark .m-toggle__label[data-v-576222af] {\n color: white;\n}\n.m-toggle__input[data-v-576222af] {\n display: none;\n}\n.m-toggle__input:checked + .m-toggle__content[data-v-576222af]:after {\n left: calc(50% + 2px);\n}\n.m-toggle__content[data-v-576222af] {\n background: #F0F0F0;\n border-radius: 2em;\n box-sizing: border-box;\n height: 2em;\n outline: 0;\n overflow: hidden;\n padding: 2px;\n transition: background-color 0.4s ease;\n width: 4em;\n will-change: background-color;\n}\n.m-toggle__content[data-v-576222af]:after {\n background: white;\n border-radius: 50%;\n box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.05);\n content: '';\n display: block;\n height: 100%;\n left: 0;\n position: relative;\n transition: left 0.2s ease;\n width: calc(50% - 2px);\n will-change: left;\n}\n.is-disabled .m-toggle__content[data-v-576222af] {\n cursor: not-allowed;\n opacity: 50%;\n}\n.is-dark .m-toggle__content[data-v-576222af] {\n background: #374151;\n}\n\n";
104127
styleInject(css_248z);
105128

106129
script.render = render;
107-
script.__scopeId = "data-v-84279cda";
130+
script.__scopeId = "data-v-576222af";
108131

109132
// Import vue component
110133
// IIFE injects install function into component, allowing component

0 commit comments

Comments
 (0)