Skip to content

Commit

Permalink
Always show dropdown arrow when there are suggestions or the no resul…
Browse files Browse the repository at this point in the history
…ts dialog
  • Loading branch information
owenatgov committed Oct 8, 2024
1 parent c5847e1 commit 724eed2
Show file tree
Hide file tree
Showing 14 changed files with 90 additions and 40 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Fixes

- [Pull request #753: Add visual cue for when a dialog is available](https://github.com/alphagov/accessible-autocomplete/pull/753)

## 3.0.1 - 2024-09-12

### Fixes
Expand Down
2 changes: 1 addition & 1 deletion dist/accessible-autocomplete.min.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/accessible-autocomplete.min.css.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/accessible-autocomplete.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/accessible-autocomplete.min.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/lib/accessible-autocomplete.preact.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/lib/accessible-autocomplete.preact.min.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/lib/accessible-autocomplete.react.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/lib/accessible-autocomplete.react.min.js.map

Large diffs are not rendered by default.

6 changes: 1 addition & 5 deletions src/autocomplete.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,21 @@
.autocomplete__input {
background-color: transparent;
position: relative;
padding: 5px 35px 5px 5px; /* Space for arrow */
}

.autocomplete__hint {
color: #505a5f;
position: absolute;
}

.autocomplete__input--default {
padding: 5px;
}

.autocomplete__input--focused {
outline: 3px solid #fd0;
outline-offset: 0;
box-shadow: inset 0 0 0 2px;
}

.autocomplete__input--show-all-values {
padding: 5px 35px 5px 5px; /* Space for arrow. Other padding should match .autocomplete__input--default. */
cursor: pointer;
}

Expand Down
27 changes: 14 additions & 13 deletions src/autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -436,10 +436,12 @@ export default class Autocomplete extends Component {
const queryLongEnough = query.length >= minLength
const showNoOptionsFound = this.props.showNoOptionsFound &&
inputFocused && noOptionsAvailable && queryNotEmpty && queryLongEnough
const downArrowVisible = showAllValues || (menuOpen || showNoOptionsFound)

const wrapperClassName = `${cssNamespace}__wrapper`
const statusClassName = `${cssNamespace}__status`
const dropdownArrowClassName = `${cssNamespace}__dropdown-arrow-down`
const dropdownArrowWrapperClassName = `${cssNamespace}__dropdown-arrow-down-wrapper${downArrowVisible ? ` ${cssNamespace}__dropdown-arrow-down-wrapper--visible` : ''}`
const optionFocused = focused !== -1 && focused !== null

const optionClassName = `${cssNamespace}__option`
Expand All @@ -461,29 +463,28 @@ export default class Autocomplete extends Component {
'aria-autocomplete': (this.hasAutoselect()) ? 'both' : 'list'
}

let dropdownArrow

// we only need a dropdown arrow if showAllValues is set to a truthy value
if (showAllValues) {
dropdownArrow = dropdownArrowFactory({ className: dropdownArrowClassName })
let dropdownArrow = dropdownArrowFactory({
wrapperClassName: dropdownArrowWrapperClassName,
className: dropdownArrowClassName
})

// if the factory returns a string we'll render this as HTML (usage w/o (P)React)
if (typeof dropdownArrow === 'string') {
dropdownArrow = <div className={`${cssNamespace}__dropdown-arrow-down-wrapper`} dangerouslySetInnerHTML={{ __html: dropdownArrow }} />
}
// if the factory returns a string we'll render this as HTML (usage w/o (P)React)
if (typeof dropdownArrow === 'string') {
dropdownArrow = <div className={dropdownArrowWrapperClassName} dangerouslySetInnerHTML={{ __html: dropdownArrow }} />
}

const inputClassName = `${cssNamespace}__input`
const inputClassList = [
inputClassName,
this.props.showAllValues ? `${inputClassName}--show-all-values` : `${inputClassName}--default`
]
const inputClassList = [inputClassName]

const componentIsFocused = focused !== null
if (componentIsFocused) {
inputClassList.push(`${inputClassName}--focused`)
}

if (showAllValues) {
inputClassList.push(`${inputClassName}--show-all-values`)
}

if (inputClasses) {
inputClassList.push(inputClasses)
}
Expand Down
14 changes: 8 additions & 6 deletions src/dropdown-arrow-down.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { createElement } from 'preact' /** @jsx createElement */

const DropdownArrowDown = ({ className }) => (
<svg version='1.1' xmlns='http://www.w3.org/2000/svg' className={className} focusable='false'>
<g stroke='none' fill='none' fill-rule='evenodd'>
<polygon fill='#000000' points='0 0 22 0 11 17' />
</g>
</svg>
const DropdownArrowDown = ({ wrapperClassName, className }) => (
<div className={wrapperClassName} aria-hidden='true'>
<svg version='1.1' xmlns='http://www.w3.org/2000/svg' className={className} focusable='false'>
<g stroke='none' fill='none' fill-rule='evenodd'>
<polygon fill='#000000' points='0 0 22 0 11 17' />
</g>
</svg>
</div>
)

export default DropdownArrowDown
12 changes: 12 additions & 0 deletions test/functional/dropdown-arrow-down.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,24 @@ describe('DropdownArrowDown', () => {
expect(scratch.innerHTML).to.contain('svg')
})

it('renders a wrapping div', () => {
render(<DropdownArrowDown />, scratch)

expect(scratch.innerHTML).to.contain('div')
})

it('renders with a given custom class', () => {
render(<DropdownArrowDown className='foo' />, scratch)

expect(scratch.innerHTML).to.contain('class="foo"')
})

it('renders with a given custom wrapper class', () => {
render(<DropdownArrowDown wrapperClassName='foo' />, scratch)

expect(scratch.innerHTML).to.contain('class="foo"')
})

// IE issue so the dropdown svg is not focusable (tabindex won't work for this)
it('renders an svg where focusable attribute is false', () => {
render(<DropdownArrowDown />, scratch)
Expand Down
Loading

0 comments on commit 724eed2

Please sign in to comment.