mirror of
https://github.com/flarum/framework.git
synced 2025-01-20 18:27:47 +08:00
[A11Y] Accessibility improvements for the Search component (#3017)
* Remove deprecated code * Accessibility improvements for Search component
This commit is contained in:
parent
0fea85d37c
commit
b099a3843d
|
@ -103,14 +103,18 @@ export default class Search<T extends SearchAttrs = SearchAttrs> extends Compone
|
|||
|
||||
const searchLabel = extractText(app.translator.trans('core.forum.header.search_placeholder'));
|
||||
|
||||
const isActive = !!currentSearch;
|
||||
const shouldShowResults = !!(!this.loadingSources && this.state.getValue() && this.hasFocus);
|
||||
const shouldShowClearButton = !!(!this.loadingSources && this.state.getValue());
|
||||
|
||||
return (
|
||||
<div
|
||||
role="search"
|
||||
className={classList({
|
||||
Search: true,
|
||||
aria-label={app.translator.trans('core.forum.header.search_role_label')}
|
||||
className={classList('Search', {
|
||||
open: this.state.getValue() && this.hasFocus,
|
||||
focused: this.hasFocus,
|
||||
active: !!currentSearch,
|
||||
active: isActive,
|
||||
loading: !!this.loadingSources,
|
||||
})}
|
||||
>
|
||||
|
@ -125,18 +129,23 @@ export default class Search<T extends SearchAttrs = SearchAttrs> extends Compone
|
|||
onfocus={() => (this.hasFocus = true)}
|
||||
onblur={() => (this.hasFocus = false)}
|
||||
/>
|
||||
{this.loadingSources ? (
|
||||
<LoadingIndicator size="small" display="inline" containerClassName="Button Button--icon Button--link" />
|
||||
) : currentSearch ? (
|
||||
<button className="Search-clear Button Button--icon Button--link" onclick={this.clear.bind(this)}>
|
||||
{!!this.loadingSources && <LoadingIndicator size="small" display="inline" containerClassName="Button Button--icon Button--link" />}
|
||||
{shouldShowClearButton && (
|
||||
<button
|
||||
className="Search-clear Button Button--icon Button--link"
|
||||
onclick={this.clear.bind(this)}
|
||||
aria-label={app.translator.trans('core.forum.header.search_clear_button_accessible_label')}
|
||||
>
|
||||
{icon('fas fa-times-circle')}
|
||||
</button>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</div>
|
||||
<ul className="Dropdown-menu Search-results">
|
||||
{this.state.getValue() && this.hasFocus ? this.sources.map((source) => source.view(this.state.getValue())) : ''}
|
||||
<ul
|
||||
className="Dropdown-menu Search-results"
|
||||
aria-hidden={!shouldShowResults || undefined}
|
||||
aria-live={shouldShowResults ? 'polite' : undefined}
|
||||
>
|
||||
{shouldShowResults && this.sources.map((source) => source.view(this.state.getValue()))}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
|
@ -174,7 +183,7 @@ export default class Search<T extends SearchAttrs = SearchAttrs> extends Compone
|
|||
|
||||
this.$('.Search-results')
|
||||
.on('mousedown', (e) => e.preventDefault())
|
||||
.on('click', () => this.$('input').blur())
|
||||
.on('click', () => this.$('input').trigger('blur'))
|
||||
|
||||
// Whenever the mouse is hovered over a search result, highlight it.
|
||||
.on('mouseenter', '> li:not(.Dropdown-header)', function () {
|
||||
|
@ -223,7 +232,7 @@ export default class Search<T extends SearchAttrs = SearchAttrs> extends Compone
|
|||
.on('focus', function () {
|
||||
$(this)
|
||||
.one('mouseup', (e) => e.preventDefault())
|
||||
.select();
|
||||
.trigger('select');
|
||||
});
|
||||
|
||||
this.updateMaxHeightHandler = this.updateMaxHeight.bind(this);
|
||||
|
|
|
@ -1,5 +1,16 @@
|
|||
.Search {
|
||||
position: relative;
|
||||
|
||||
&-clear {
|
||||
// It looks very weird due to the padding given to the button..
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
// ...so we display the ring around the icon inside the button, with an offset
|
||||
.add-keyboard-focus-ring-nearby("> *");
|
||||
.add-keyboard-focus-ring-nearby-offset("> *", 4px);
|
||||
}
|
||||
}
|
||||
@media @tablet-up {
|
||||
.Search {
|
||||
|
|
|
@ -130,3 +130,39 @@
|
|||
.offset();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This mixin allows support for a custom element nearby the focused one
|
||||
* to have a focus style applied to it
|
||||
*
|
||||
* For example...
|
||||
*
|
||||
*? button { .add-keyboard-focus-ring-nearby("+ .myOtherElement") }
|
||||
* becomes
|
||||
*? button:-moz-focusring + .myOtherElement { <styles> }
|
||||
*? button:focus-within + .myOtherElement { <styles> }
|
||||
*/
|
||||
.add-keyboard-focus-ring-nearby-offset(@nearbySelector, @offset) {
|
||||
@realNearbySelector: ~"@{nearbySelector}";
|
||||
|
||||
.offset() {
|
||||
outline-offset: @offset;
|
||||
}
|
||||
|
||||
// We need to declare these separately, otherwise
|
||||
// browsers will ignore `:focus-visible` as they
|
||||
// don't understand `:-moz-focusring`
|
||||
|
||||
// These are the keyboard-only versions of :focus
|
||||
&:-moz-focusring {
|
||||
@{realNearbySelector} {
|
||||
.offset();
|
||||
}
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
@{realNearbySelector} {
|
||||
.offset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -348,7 +348,9 @@ core:
|
|||
log_in_link: => core.ref.log_in
|
||||
log_out_button: => core.ref.log_out
|
||||
profile_button: Profile
|
||||
search_clear_button_accessible_label: Clear search query
|
||||
search_placeholder: Search Forum
|
||||
search_role_label: Search Forum
|
||||
session_dropdown_accessible_label: Toggle session options dropdown menu
|
||||
settings_button: => core.ref.settings
|
||||
sign_up_link: => core.ref.sign_up
|
||||
|
|
Loading…
Reference in New Issue
Block a user