diff --git a/changes/changelog.d/1121.enhancement b/changes/changelog.d/1121.enhancement new file mode 100644 index 0000000000000000000000000000000000000000..188865c94c8486d59970809e3728d6fe0d878e41 --- /dev/null +++ b/changes/changelog.d/1121.enhancement @@ -0,0 +1 @@ +Use semantic headers for accessibility (#1121) \ No newline at end of file diff --git a/front/package.json b/front/package.json index 4a85f6469ebb2d6ab2898f7586f6eb9b7d5b30b1..86540e14969a2f9d4e9ef7954d50423071c093af 100644 --- a/front/package.json +++ b/front/package.json @@ -20,6 +20,7 @@ "core-js": "^3.6.4", "diff": "^4.0.1", "django-channels": "^1.1.6", + "focus-trap": "^5.1.0", "fomantic-ui-css": "^2.8.3", "howler": "^2.0.14", "js-logger": "^1.4.1", diff --git a/front/src/components/Queue.vue b/front/src/components/Queue.vue index 4becb11f3cb1fda84053d458f5015389935fb43b..0813291af5e89ed1325a4d3713765ca76045efa8 100644 --- a/front/src/components/Queue.vue +++ b/front/src/components/Queue.vue @@ -209,7 +209,7 @@ import $ from 'jquery' import moment from "moment" import lodash from '@/lodash' import time from "@/utils/time" - +import createFocusTrap from 'focus-trap' import store from "@/store" export default { @@ -224,11 +224,14 @@ export default { showVolume: false, isShuffling: false, tracksChangeBuffer: null, + focusTrap: null, time } }, mounted () { let self = this + this.focusTrap = createFocusTrap(this.$el, {allowOutsideClick: () => { return true }}) + this.focusTrap.activate() this.$nextTick(() => { setTimeout(() => { this.scrollToCurrent() diff --git a/front/src/components/SetInstanceModal.vue b/front/src/components/SetInstanceModal.vue index 618a16a20df016ae33facfa4074fe9e4c1ba26b9..2e5c24bc2acf72eaeec2cb1a6ad2dd5a0c2b8ffb 100644 --- a/front/src/components/SetInstanceModal.vue +++ b/front/src/components/SetInstanceModal.vue @@ -35,7 +35,7 @@ </form> </div> <div class="actions"> - <div class="ui basic cancel button"><translate translate-context="*/*/Button.Label/Verb">Cancel</translate></div> + <button class="ui basic cancel button"><translate translate-context="*/*/Button.Label/Verb">Cancel</translate></button> </div> </modal> </template> diff --git a/front/src/components/ShortcutsModal.vue b/front/src/components/ShortcutsModal.vue index 017cdc977f7a790c5e687bede808f4860f2b67d4..c88bfb71591053623ae7038d6ff55f68a7bd9a86 100644 --- a/front/src/components/ShortcutsModal.vue +++ b/front/src/components/ShortcutsModal.vue @@ -36,7 +36,7 @@ </div> </section> <footer class="actions"> - <div class="ui basic cancel button"><translate translate-context="*/*/Button.Label/Verb">Close</translate></div> + <button class="ui basic cancel button"><translate translate-context="*/*/Button.Label/Verb">Close</translate></button> </footer> </modal> </template> diff --git a/front/src/components/auth/LoginForm.vue b/front/src/components/auth/LoginForm.vue index 3b18fbc290ed34427e3a523b4705870e6f6f78b1..f0591a5385d36c59dd64fc556c5e5fe6ccb03abe 100644 --- a/front/src/components/auth/LoginForm.vue +++ b/front/src/components/auth/LoginForm.vue @@ -25,7 +25,6 @@ </label> <input ref="username" - tabindex="1" required name="username" type="text" @@ -50,7 +49,7 @@ <translate translate-context="Contant/Auth/Paragraph" :translate-params="{domain: $store.getters['instance/domain']}">You will be redirected to %{ domain } to authenticate.</translate> </p> </template> - <button tabindex="3" :class="['ui', {'loading': isLoading}, 'right', 'floated', buttonClasses, 'button']" type="submit"> + <button :class="['ui', {'loading': isLoading}, 'right', 'floated', buttonClasses, 'button']" type="submit"> <translate translate-context="*/Login/*/Verb">Login</translate> </button> </form> diff --git a/front/src/components/common/DangerousButton.vue b/front/src/components/common/DangerousButton.vue index 353c8ecf339fb96f943dc75ff2b11d6e61ed8b03..763f3fa98bcdd10160f7499266b03addcffdf871 100644 --- a/front/src/components/common/DangerousButton.vue +++ b/front/src/components/common/DangerousButton.vue @@ -14,14 +14,14 @@ </div> </div> <div class="actions"> - <div class="ui basic cancel button"> + <button class="ui basic cancel button"> <translate translate-context="*/*/Button.Label/Verb">Cancel</translate> - </div> - <div :class="['ui', 'confirm', confirmButtonColor, 'button']" @click="confirm"> + </button> + <button :class="['ui', 'confirm', confirmButtonColor, 'button']" @click="confirm"> <slot name="modal-confirm"> <translate translate-context="Modal/*/Button.Label/Short, Verb">Confirm</translate> </slot> - </div> + </button> </div> </modal> </div> diff --git a/front/src/components/moderation/FilterModal.vue b/front/src/components/moderation/FilterModal.vue index 2c650014c8b71049b7e99b84f7a2a701f7a0fd8f..f83e69741bd325d17ba095313634bc78788cf87d 100644 --- a/front/src/components/moderation/FilterModal.vue +++ b/front/src/components/moderation/FilterModal.vue @@ -37,8 +37,8 @@ </div> </div> <div class="actions"> - <div class="ui basic cancel button"><translate translate-context="*/*/Button.Label/Verb">Cancel</translate></div> - <div :class="['ui', 'success', {loading: isLoading}, 'button']" @click="hide"><translate translate-context="Popup/*/Button.Label">Hide content</translate></div> + <button class="ui basic cancel button"><translate translate-context="*/*/Button.Label/Verb">Cancel</translate></button> + <button :class="['ui', 'success', {loading: isLoading}, 'button']" @click="hide"><translate translate-context="Popup/*/Button.Label">Hide content</translate></button> </div> </modal> </template> diff --git a/front/src/components/moderation/ReportModal.vue b/front/src/components/moderation/ReportModal.vue index db37960a27970ea52c2f9d90f301e579a8be615a..f32f7b6f6f0aa52c3e7527372524be1654d9a5de 100644 --- a/front/src/components/moderation/ReportModal.vue +++ b/front/src/components/moderation/ReportModal.vue @@ -71,7 +71,7 @@ </div> </div> <div class="actions"> - <div class="ui basic cancel button"><translate translate-context="*/*/Button.Label/Verb">Cancel</translate></div> + <button class="ui basic cancel button"><translate translate-context="*/*/Button.Label/Verb">Cancel</translate></button> <button v-if="canSubmit" :class="['ui', 'success', {loading: isLoading}, 'button']" diff --git a/front/src/components/semantic/Modal.vue b/front/src/components/semantic/Modal.vue index 78f9534213eddd6d55adbbb89030ac896b640e63..0a93a053ed3f34652ed9092639f58713e3358e13 100644 --- a/front/src/components/semantic/Modal.vue +++ b/front/src/components/semantic/Modal.vue @@ -9,6 +9,7 @@ <script> import $ from 'jquery' +import createFocusTrap from 'focus-trap' export default { props: { @@ -17,9 +18,13 @@ export default { }, data () { return { - control: null + control: null, + focusTrap: null, } }, + mounted () { + this.focusTrap = createFocusTrap(this.$el) + }, beforeDestroy () { if (this.control) { $(this.$el).modal('hide') @@ -38,6 +43,11 @@ export default { }.bind(this), onHidden: function () { this.$emit('update:show', false) + this.focusTrap.pause() + }.bind(this), + onVisible: function () { + this.focusTrap.activate() + this.focusTrap.unpause() }.bind(this) }) } diff --git a/front/yarn.lock b/front/yarn.lock index 40aa5b9d00c10356d2c6ba8622a62a0fd9f5a1f8..4cab2dee136f89a7c816672ee6587db121c84fd1 100644 --- a/front/yarn.lock +++ b/front/yarn.lock @@ -4375,6 +4375,14 @@ flush-write-stream@^1.0.0: inherits "^2.0.3" readable-stream "^2.3.6" +focus-trap@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-5.1.0.tgz#64a0bfabd95c382103397dbc96bfef3a3cf8e5ad" + integrity sha512-CkB/nrO55069QAUjWFBpX6oc+9V90Qhgpe6fBWApzruMq5gnlh90Oo7iSSDK7pKiV5ugG6OY2AXM5mxcmL3lwQ== + dependencies: + tabbable "^4.0.0" + xtend "^4.0.1" + follow-redirects@1.5.10: version "1.5.10" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" @@ -9206,6 +9214,11 @@ symbol-tree@^3.2.2: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== +tabbable@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-4.0.0.tgz#5bff1d1135df1482cf0f0206434f15eadbeb9261" + integrity sha512-H1XoH1URcBOa/rZZWxLxHCtOdVUEev+9vo5YdYhC9tCY4wnybX+VQrCYuy9ubkg69fCBxCONJOSLGfw0DWMffQ== + table@^5.2.3: version "5.4.6" resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e"