]> BookStack Code Mirror - bookstack/commitdiff
Added focus and a11y attributes/functionality to custom checkboxes
authorDan Brown <redacted>
Tue, 4 Jun 2019 09:45:44 +0000 (10:45 +0100)
committerDan Brown <redacted>
Tue, 4 Jun 2019 09:47:09 +0000 (10:47 +0100)
Closes #1476

resources/assets/js/components/custom-checkbox.js [new file with mode: 0644]
resources/assets/js/components/index.js
resources/assets/js/components/toggle-switch.js
resources/views/auth/login.blade.php
resources/views/components/custom-checkbox.blade.php
resources/views/components/toggle-switch.blade.php

diff --git a/resources/assets/js/components/custom-checkbox.js b/resources/assets/js/components/custom-checkbox.js
new file mode 100644 (file)
index 0000000..65ce8c1
--- /dev/null
@@ -0,0 +1,34 @@
+
+class CustomCheckbox {
+
+    constructor(elem) {
+        this.elem = elem;
+        this.checkbox = elem.querySelector('input[type=checkbox]');
+        this.display = elem.querySelector('[role="checkbox"]');
+
+        this.checkbox.addEventListener('change', this.stateChange.bind(this));
+        this.elem.addEventListener('keydown', this.onKeyDown.bind(this));
+    }
+
+    onKeyDown(event) {
+        const isEnterOrPress = event.keyCode === 32 || event.keyCode === 13;
+        if (isEnterOrPress) {
+            event.preventDefault();
+            this.toggle();
+        }
+    }
+
+    toggle() {
+        this.checkbox.checked = !this.checkbox.checked;
+        this.checkbox.dispatchEvent(new Event('change'));
+        this.stateChange();
+    }
+
+    stateChange() {
+        const checked = this.checkbox.checked ? 'true' : 'false';
+        this.display.setAttribute('aria-checked', checked);
+    }
+
+}
+
+export default CustomCheckbox;
\ No newline at end of file
index 355b96473801f47a50d7d12f720c42fd706605b1..bd7432b8dc25c4f42ff6940435d69f15b8f7b2ef 100644 (file)
@@ -23,6 +23,7 @@ import listSortControl from "./list-sort-control";
 import triLayout from "./tri-layout";
 import breadcrumbListing from "./breadcrumb-listing";
 import permissionsTable from "./permissions-table";
+import customCheckbox from "./custom-checkbox";
 
 const componentMapping = {
     'dropdown': dropdown,
@@ -50,6 +51,7 @@ const componentMapping = {
     'tri-layout': triLayout,
     'breadcrumb-listing': breadcrumbListing,
     'permissions-table': permissionsTable,
+    'custom-checkbox': customCheckbox,
 };
 
 window.components = {};
index 3be67d5dc94afb0f0f10ec6788c6590541ab04f0..3dd1ce85ccb4bd3d94983e34605a2651d3d47be0 100644 (file)
@@ -6,12 +6,11 @@ class ToggleSwitch {
         this.input = elem.querySelector('input[type=hidden]');
         this.checkbox = elem.querySelector('input[type=checkbox]');
 
-        this.checkbox.addEventListener('change', this.onClick.bind(this));
+        this.checkbox.addEventListener('change', this.stateChange.bind(this));
     }
 
-    onClick(event) {
-        let checked = this.checkbox.checked;
-        this.input.value = checked ? 'true' : 'false';
+    stateChange() {
+        this.input.value = (this.checkbox.checked ? 'true' : 'false');
     }
 
 }
index 51b47f5c7b7aa44c45d54c6d9e7ea3c3a4346022..a0e5f716c37d85e8b9999719016ce8a1d9f6239b 100644 (file)
@@ -22,6 +22,7 @@
                             'name' => 'remember',
                             'checked' => false,
                             'value' => 'on',
+                            'tabindex' => 1,
                             'label' => trans('auth.remember_me'),
                         ])
                     </div>
index 73b7496f8d9e2b62130f4a9c97fbfc96c25edeb3..6ba2f457f88925f6b4dad718fbd176e6bdc9aed7 100644 (file)
@@ -3,9 +3,13 @@ $name
 $value
 $checked
 $label
+$tabindex
 --}}
-<label class="toggle-switch @if($errors->has($name)) text-neg @endif">
+<label custom-checkbox class="toggle-switch @if($errors->has($name)) text-neg @endif">
     <input type="checkbox" name="{{$name}}" value="{{ $value }}" @if($checked) checked="checked" @endif>
-    <span class="custom-checkbox text-primary">@icon('check')</span>
+    <span tabindex="{{ $tabindex ?? '0' }}"
+          role="checkbox"
+          aria-checked="{{ $checked ? 'true' : 'false' }}"
+          class="custom-checkbox text-primary">@icon('check')</span>
     <span class="label">{{$label}}</span>
 </label>
\ No newline at end of file
index 84a8a3083716972b1a1a53a6302aec62d3ed6256..f61c076707eb5f1277a8a7d725654e30c4a03816 100644 (file)
@@ -1,6 +1,9 @@
-<label toggle-switch="{{$name}}" class="toggle-switch">
+<label toggle-switch="{{$name}}" custom-checkbox class="toggle-switch">
     <input type="hidden" name="{{$name}}" value="{{$value?'true':'false'}}"/>
     <input type="checkbox" @if($value) checked="checked" @endif>
-    <span class="custom-checkbox text-primary">@icon('check')</span>
+    <span tabindex="{{ $tabindex ?? '0' }}"
+          role="checkbox"
+          aria-checked="{{ $value ? 'true' : 'false' }}"
+          class="custom-checkbox text-primary">@icon('check')</span>
     <span class="label">{{ $label }}</span>
 </label>
\ No newline at end of file