A11y: Review of #6173, ensure checkboxes are labelled

This specifically alters the checkbox label implementation to use the
existing checkbox label instead of always adding an extra label to the
custom checkbox element itself, unless they diverge (like for permission
checkboxes).
This commit is contained in:
Dan Brown
2026-09-15 19:20:14 +01:00
parent aa44f3508d
commit 82b9472554
5 changed files with 21 additions and 12 deletions
@@ -20,6 +20,9 @@ export class CustomCheckbox extends Component {
}
toggle() {
if (this.checkbox.disabled) {
return;
}
this.checkbox.checked = !this.checkbox.checked;
this.checkbox.dispatchEvent(new Event('change'));
this.stateChange();
+11 -6
View File
@@ -1,15 +1,20 @@
{{--
$name
$value
$checked
$label
$name - string
$value - string
$checked - boolean
$disabled - boolean
$label - string
$ariaLabel? (optional, falls back to $label)
--}}
<label component="custom-checkbox" class="toggle-switch @if($errors->has($name)) text-neg @endif">
<label component="custom-checkbox" id="custom-checkbox-label-{{ $name }}" class="toggle-switch @if($errors->has($name)) text-neg @endif">
<input type="checkbox" name="{{$name}}" value="{{ $value }}" @if($checked) checked="checked" @endif @if($disabled ?? false) disabled="disabled" @endif>
<span tabindex="0" role="checkbox"
aria-checked="{{ $checked ? 'true' : 'false' }}"
aria-label="{{ $ariaLabel ?? $label }}"
@if(isset($ariaLabel))
aria-label="{{ $ariaLabel }}"
@else
aria-labelledby="custom-checkbox-label-{{ $name }}"
@endif
class="custom-checkbox text-primary">@icon('check')</span>
<span class="label">{{$label}}</span>
</label>
+4 -3
View File
@@ -1,9 +1,10 @@
<label components="custom-checkbox toggle-switch" class="toggle-switch">
<label components="custom-checkbox toggle-switch" id="toggle-switch-label-{{ $name }}" class="toggle-switch">
<input type="hidden" name="{{$name}}" value="{{$value?'true':'false'}}"/>
<input type="checkbox" @if($value) checked="checked" @endif>
<span tabindex="0" role="checkbox"
<span tabindex="0"
role="checkbox"
aria-labelledby="toggle-switch-label-{{ $name }}"
aria-checked="{{ $value ? 'true' : 'false' }}"
aria-label="{{ $label }}"
class="custom-checkbox text-primary">@icon('check')</span>
<span class="label">{{ $label }}</span>
</label>
@@ -38,7 +38,7 @@
<div class="toggle-switch-list">
@include('form.custom-checkbox', [
'name' => 'events[]',
'name' => 'events[all]',
'value' => 'all',
'label' => trans('settings.webhooks_events_all'),
'checked' => old('events') ? in_array('all', old('events')) : (isset($webhook) ? $webhook->tracksEvent('all') : false),
@@ -51,7 +51,7 @@
@foreach(\BookStack\Activity\ActivityType::all() as $activityType)
<div>
@include('form.custom-checkbox', [
'name' => 'events[]',
'name' => 'events[' . $activityType . ']',
'value' => $activityType,
'label' => $activityType,
'checked' => old('events') ? in_array($activityType, old('events')) : (isset($webhook) ? $webhook->tracksEvent($activityType) : false),
+1 -1
View File
@@ -72,7 +72,7 @@ class WebhookManagementTest extends TestCase
$resp->assertSee('Edit Webhook');
$this->withHtml($resp)->assertElementContains('form[action="' . $webhook->getUrl() . '"] button', 'Save Webhook');
$this->withHtml($resp)->assertElementContains('a[href="' . $webhook->getUrl('/delete') . '"]', 'Delete Webhook');
$this->withHtml($resp)->assertElementExists('input[type="checkbox"][value="all"][name="events[]"]');
$this->withHtml($resp)->assertElementExists('input[type="checkbox"][name="events[all]"][value="all"]');
}
public function test_update()