Skip to content
This repository has been archived by the owner on Jan 3, 2024. It is now read-only.

feat: improve switch UI and a11y #1421

Merged
merged 4 commits into from
Jun 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions changelog/unreleased/enhancement-switch-improvements
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Enhancement: Improve `OcSwitch` UI and accessibility

We've added round corners to the `OcSwitch` component so that it is more consistent with other elements in our UI.
We've also made the component accessible, added visible label and enabled toggling its state with the spacebar.

https://github.com/owncloud/owncloud-design-system/pull/1421
93 changes: 0 additions & 93 deletions src/components/OcSwitch.vue

This file was deleted.

23 changes: 23 additions & 0 deletions src/components/switch/OcSwitch.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { shallowMount } from "@vue/test-utils"

import Switch from "./OcSwitch.vue"

const defaultProps = {
label: "Test label",
}

describe("OcSwitch", () => {
it("can be toggled", async () => {
const wrapper = shallowMount(Switch, {
propsData: defaultProps,
})

await wrapper.find('[data-test-id="oc-switch-btn"]').trigger("click")

expect(wrapper.emitted().change[0][0]).toEqual(true)

await wrapper.find('[data-test-id="oc-switch-btn"]').trigger("click")

expect(wrapper.emitted().change[0][0]).toEqual(true)
})
})
142 changes: 142 additions & 0 deletions src/components/switch/OcSwitch.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
<template>
<span :key="`oc-switch-${checked.toString()}`" class="oc-switch">
<span :id="labelId" v-text="label" />
<button
data-test-id="oc-switch-btn"
class="oc-switch-btn"
role="switch"
:aria-checked="checked.toString()"
:aria-labelledby="labelId"
@click="toggle"
/>
</span>
</template>

<script>
import uniqueId from "../../utils/uniqueId"

/**
* The switch has two states between users can choose.
*/
export default {
name: "OcSwitch",
status: "review",
release: "1.0.0",
model: {
prop: "checked",
event: "change",
},
props: {
/**
* Value of the switch
*
* @model
**/
checked: {
type: Boolean,
required: false,
default: false,
},
/**
* Accessible name of the switch
**/
label: {
type: String,
required: true,
default: null,
},
/**
* ID of the label element
* If not set, unique ID is used instead with format `oc-switch-label-{number}`
*/
labelId: {
type: String,
required: false,
default: uniqueId("oc-switch-label-"),
},
},

methods: {
toggle() {
/**
* Change event
* @event change
* @type {boolean}
*/
this.$emit("change", !this.checked)
},
},
}
</script>

<style lang="scss">
.oc-switch {
align-items: center;
display: inline-flex;
gap: var(--oc-space-small);

&-btn {
border: 0;
border-radius: 20px;
cursor: pointer;
display: block;
height: $form-radio-size;
margin: 0;
padding: 0;
position: relative;
transition: background-color 0.25s;
width: $form-radio-size * 1.75;

&::before {
background-color: var(--oc-color-text-inverse);
border-radius: 50%;
content: "";
height: $form-radio-size - 4;
left: 1px;
position: absolute;
top: 2px;
transition: transform 0.25s;
width: $form-radio-size - 4;
}

&[aria-checked="false"] {
background-color: var(--oc-color-text-muted);

&::before {
transform: translateX(0);
}
}

&[aria-checked="true"] {
background-color: var(--oc-color-swatch-brand-default);

&::before {
transform: translateX(calc(100% + 1px));
}
}
}
}
</style>

<docs>
```vue
<template>
<section>
<h3>Switcher behavior</h3>
<oc-switch label="Darkmode" v-model="state" />
<p>
The switch is turned <strong v-if="state">on</strong><strong v-else="state">off</strong>.
</p>
</section>
</template>
<script>
export default {
data: () => {
return {
state: true
}
}
}
</script>
```
</docs>
1 change: 0 additions & 1 deletion src/styles/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
@import 'theme/oc-scroll';
@import 'theme/oc-spacing';
@import 'theme/oc-spinner';
@import 'theme/oc-switch';
@import 'theme/oc-tabbed';
@import 'theme/oc-text';
@import 'theme/oc-topbar';
Expand Down
42 changes: 0 additions & 42 deletions src/styles/theme/oc-switch.scss

This file was deleted.