Merge pull request #281 from nolanlawson/nolan/issue-221

fix: improve search/clear a11y
release
Nolan Lawson 2019-03-12 08:08:32 -07:00 committed by GitHub
commit 445d2d4656
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 6 deletions

View File

@ -58,6 +58,7 @@ import { Picker } from 'emoji-mart'
#### I18n #### I18n
```js ```js
search: 'Search', search: 'Search',
clear: 'Clear', // Accessible label on "clear" button
notfound: 'No Emoji Found', notfound: 'No Emoji Found',
skintext: 'Choose your default skin tone', skintext: 'Choose your default skin tone',
categories: { categories: {

View File

@ -102,12 +102,22 @@
outline: 0; outline: 0;
} }
.emoji-mart-search input,
.emoji-mart-search input::-webkit-search-decoration,
.emoji-mart-search input::-webkit-search-cancel-button,
.emoji-mart-search input::-webkit-search-results-button,
.emoji-mart-search input::-webkit-search-results-decoration {
/* remove webkit/blink styles for <input type="search">
* via https://stackoverflow.com/a/9422689 */
-webkit-appearance: none;
}
.emoji-mart-search-icon { .emoji-mart-search-icon {
position: absolute; position: absolute;
top: 9px; top: 7px;
right: 16px; right: 11px;
z-index: 2; z-index: 2;
padding: 0; padding: 2px 5px 1px;
border: none; border: none;
background: none; background: none;
} }
@ -369,3 +379,17 @@
.emoji-mart-skin-tone-4 { background-color: #bf8f68 } .emoji-mart-skin-tone-4 { background-color: #bf8f68 }
.emoji-mart-skin-tone-5 { background-color: #9b643d } .emoji-mart-skin-tone-5 { background-color: #9b643d }
.emoji-mart-skin-tone-6 { background-color: #594539 } .emoji-mart-skin-tone-6 { background-color: #594539 }
/* For screenreaders only, via https://stackoverflow.com/a/19758620 */
.emoji-mart-sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}

View File

@ -18,6 +18,7 @@ import { PickerDefaultProps } from '../../utils/shared-default-props'
const I18N = { const I18N = {
search: 'Search', search: 'Search',
clear: 'Clear', // Accessible label on "clear" button
notfound: 'No Emoji Found', notfound: 'No Emoji Found',
skintext: 'Choose your default skin tone', skintext: 'Choose your default skin tone',
categories: { categories: {

View File

@ -4,12 +4,15 @@ import PropTypes from 'prop-types'
import { search as icons } from '../svgs' import { search as icons } from '../svgs'
import NimbleEmojiIndex from '../utils/emoji-index/nimble-emoji-index' import NimbleEmojiIndex from '../utils/emoji-index/nimble-emoji-index'
let id = 0
export default class Search extends React.PureComponent { export default class Search extends React.PureComponent {
constructor(props) { constructor(props) {
super(props) super(props)
this.state = { this.state = {
icon: icons.search, icon: icons.search,
isSearching: false, isSearching: false,
id: ++id,
} }
this.data = props.data this.data = props.data
@ -46,6 +49,7 @@ export default class Search extends React.PureComponent {
clear() { clear() {
if (this.input.value == '') return if (this.input.value == '') return
this.input.value = '' this.input.value = ''
this.input.focus()
this.search('') this.search('')
} }
@ -64,22 +68,32 @@ export default class Search extends React.PureComponent {
} }
render() { render() {
var { i18n, autoFocus } = this.props const { i18n, autoFocus } = this.props
var { icon, isSearching } = this.state const { icon, isSearching, id } = this.state
const inputId = `emoji-mart-search-${id}`
return ( return (
<div className="emoji-mart-search"> <div className="emoji-mart-search">
<input <input
id={inputId}
ref={this.setRef} ref={this.setRef}
type="text" type="search"
onChange={this.handleChange} onChange={this.handleChange}
placeholder={i18n.search} placeholder={i18n.search}
autoFocus={autoFocus} autoFocus={autoFocus}
/> />
{/*
* Use a <label> in addition to the placeholder for accessibility, but place it off-screen
* http://www.maxability.co.in/2016/01/placeholder-attribute-and-why-it-is-not-accessible/
*/}
<label className="emoji-mart-sr-only" htmlFor={inputId}>
{i18n.search}
</label>
<button <button
className="emoji-mart-search-icon" className="emoji-mart-search-icon"
onClick={this.clear} onClick={this.clear}
onKeyUp={this.handleKeyUp} onKeyUp={this.handleKeyUp}
aria-label={i18n.clear}
disabled={!isSearching} disabled={!isSearching}
> >
{icon()} {icon()}