Skip to content

Commit

Permalink
v1.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
mynamesleon committed Mar 27, 2021
1 parent 525fbf9 commit 723fd7e
Show file tree
Hide file tree
Showing 13 changed files with 134 additions and 46 deletions.
16 changes: 13 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,23 @@

All notable changes to this project will be documented in this file.

## [1.3.2] - 2021-03-24
## [1.4.0] - 2021-03-27

### Added

- the ability to provide a function for the `confirmOnBlur` option that can return a string to compare against the search result labels.
- page up and page down key handling within the options list to move the current focus position up or down by 10 options.
- handling for disabled options, including ones based on disabled checkboxes and disabled select options.

### Changed

- adjusted the `confirmOnBlur` string matching behaviour to used the "cleaned" version of the search term and option label when blurring off of the field without a currently focused menu option.
- adjusted the `confirmOnBlur` string matching behaviour to use the "cleaned" version of the search term and option label when blurring off of the field without a currently focused menu option.
- defensive adjustment to setting the input value and moving focus to it after the component area is blurred.

### Fixed

- the `create` option when used as a function not being called with the API as context.

## [1.3.0] - 2021-03-07

### Added
Expand Down Expand Up @@ -104,7 +114,7 @@ All notable changes to this project will be documented in this file.
- Issue when clicking on a single-select autocomplete with minLength of 0 with a current selection, which was correctly searching with an empty string, but the polling method was then triggering a search with the value afterwards.
- Screen reader announcements for results ignoring the number of results rendered

[1.3.2]: https://github.com/mynamesleon/aria-autocomplete/compare/v1.3.0...v1.3.2
[1.4.0]: https://github.com/mynamesleon/aria-autocomplete/compare/v1.3.0...v1.4.0
[1.3.0]: https://github.com/mynamesleon/aria-autocomplete/compare/v1.2.3...v1.3.0
[1.2.3]: https://github.com/mynamesleon/aria-autocomplete/compare/v1.2.0...v1.2.3
[1.2.0]: https://github.com/mynamesleon/aria-autocomplete/compare/v1.1.4...v1.2.0
Expand Down
20 changes: 13 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@
[![npm version](https://img.shields.io/npm/v/aria-autocomplete.svg)](http://npm.im/aria-autocomplete)
[![gzip size](http://img.badgesize.io/https://unpkg.com/aria-autocomplete/dist/aria-autocomplete.min.js?compression=gzip)](https://unpkg.com/aria-autocomplete/dist/aria-autocomplete.min.js)

Accessible, extensible, plain JavaScript autocomplete with multi-select.
Fast, accessible, extensible, plain JavaScript autocomplete with multi-select.

[Try out the examples](https://mynamesleon.github.io/aria-autocomplete/).

Key design goals and features:

- **multiple selection**
- **support multiple selection**
- **extensible source options**: Array of Strings, Array of Objects, a Function, or an endpoint String
- **progressive enhancement**: Automatic source building through specifying a `<select>` as the element, or an element with child checkboxes.
- **accessibility**: Use of ARIA attributes, custom screen reader announcements, and testing with assistive technologies
- **compatibility**: Broad browser and device support (IE9+)
- **starting values**: Automatic selection based on starting values, including for checkboxes, `select` options, and for async handling.
- **small**: only 10 kB gzipped

Built from the ground up for the **accessibility**, **performance**, and **functionality** combination that I couldn't find in any other autocomplete plugins.

Expand Down Expand Up @@ -68,9 +69,9 @@ You can grab the minified JS from the `dist` directory, or straight from unpkg:

## Performance

I wrote this from the ground up largely because I needed an autocomplete with better performance than others I'd tried. I've optimised the JavaScript where I can, but in some browsers the list _rendering_ will still be a hit to performance. In my testing, modern browsers can render huge lists (1000+ items) just fine (on my laptop, averaging 40ms in Chrome, and under 20ms in Firefox).
While this was written from the ground up to have better performance than other autocompletes I've tested, in much older browser the _rendering_ of large lists will still be a hit to performance. In my testing, modern browsers can render even _huge_ lists (1000+ items) just fine (on my laptop, averaging <40ms in Chrome, and <20ms in Firefox).

As we all know however, Internet Explorer _sucks_. If you need to support Internet Explorer, I suggest using a sensible combination for the `delay`, `maxResults`, and possibly `minLength` options, to prevent the browser from freezing as your users type, and to reduce the rendering impact. Testing on my laptop, the list rendering in IE11 would take on average: 55ms for 250 items, 300ms for 650 items, and over 600ms for 1000 items.
As we all know however, Internet Explorer _sucks_. If you need to support Internet Explorer, I suggest using a sensible combination for the `delay`, `maxResults`, and possibly `minLength` options, to prevent the browser stuttering as your users type, and to reduce the rendering impact. Testing on my laptop, the list rendering in IE11 would take on average: 55ms for 250 items, 300ms for 650 items, and over 600ms for 1000 items.

## Options

Expand Down Expand Up @@ -135,10 +136,15 @@ The full list of options, and their defaults:
showAllControl: boolean = false;

/**
* Confirm currently active selection when blurring off of the control. If
* no active selection, will compare current input value against available labels
* Confirm currently active selection when blurring off of the control.
* If no active selection, will compare current input value against available labels.
* Can also be a function that receives the search term and results, which can
* return a string to be used in the comparison instead of the original search term.
* Note: the comparison will be done with "cleaned" versions of the value and labels
* (ignoring quotes, commas, colons, and hyphens, normalising "&" and "and",
* and removing duplicate whitespace)
*/
confirmOnBlur: boolean = true;
confirmOnBlur: boolean | ((value: string, options: any[]) => string | void) = true;

/**
* Allow multiple items to be selected
Expand Down
13 changes: 10 additions & 3 deletions dist/aria-autocomplete.css
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,20 @@
text-decoration: underline;
cursor: pointer;
}
.aria-autocomplete__option--no-results {
margin-top: 0 !important;
.aria-autocomplete__option:hover[aria-disabled='true'],
.aria-autocomplete__option--focused[aria-disabled='true'] {
background: #f5f5f5;
}
.aria-autocomplete__option--no-results,
.aria-autocomplete__option[aria-disabled='true'] {
opacity: 0.65 !important;
color: #434143 !important;
cursor: not-allowed !important;
text-decoration: none !important;
}
.aria-autocomplete__option--no-results {
margin-top: 0 !important;
background: transparent !important;
color: #434143 !important;
}
.aria-autocomplete__selected {
position: relative;
Expand Down
2 changes: 1 addition & 1 deletion dist/aria-autocomplete.min.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ export interface IAriaAutocompleteOptions {
source?: string | string[] | any[] | Function | Promise<any[]>;
sourceMapping?: any;
alsoSearchIn?: string[];
create?: boolean | ((value: string) => string | any);
create?: boolean | ((value: string) => string | any | void);
delay?: number;
minLength?: number;
maxResults?: number;
showAllControl?: boolean;
confirmOnBlur?: boolean;
confirmOnBlur?: boolean | ((value: string, results: any[]) => string | void);
multiple?: boolean;
autoGrow?: boolean;
maxItems?: number;
Expand Down
22 changes: 16 additions & 6 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<meta name="twitter:title" content="Aria-Autocomplete" />
<meta
name="twitter:description"
content="Accessible, extensible, plain JavaScript autocomplete with multi-select"
content="Fast, accessible, extensible, plain JavaScript autocomplete with multi-select"
/>
<link rel="stylesheet" href="dist/aria-autocomplete.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/styles/a11y-dark.min.css" />
Expand Down Expand Up @@ -449,7 +449,11 @@ <h3>Core options</h3>
</div>
<div>
<dt>create: <code>boolean | Function</code></dt>
<dd>If no exact match is found, create an entry in the results list for the current search text<br>Default: <code>false</code></dd>
<dd>
If no exact match is found, create an entry in the results list for the current search text.
Can use a function that receives the search term, and returns a string or an object (like a normal static source entry).
<br>Default: <code>false</code>
</dd>
<dt>delay: <code>number</code></dt>
<dd>input delay before running a search<br>Default: <code>100</code></dd>
<dt>minLength: <code>number</code></dt>
Expand All @@ -458,8 +462,12 @@ <h3>Core options</h3>
<dd>Maximum number of results to render<br>Default: <code>9999</code></dd>
<dt>showAllControl: <code>boolean</code></dt>
<dd>Render a button that triggers showing all options<br>Default: <code>false</code></dd>
<dt>confirmOnBlur: <code>boolean</code></dt>
<dd>Confirm current selection (from using arrow keys) when blurring off of the control. Will also check for an exact text match<br>Default: <code>true</code></dd>
<dt>confirmOnBlur: <code>boolean | Function</code></dt>
<dd>
Confirm current selection (from using arrow keys) when blurring off of the control. Will also check for a label match if there is no current selection.<br>
Can use a function which receives the search term and results, and returns a string to be used to compare against the result labels.<br>
Default: <code>true</code>
</dd>
</div>
<div>
<dt>multiple: <code>boolean</code></dt>
Expand Down Expand Up @@ -513,7 +521,8 @@ <h3>Screen reader enhancements</h3>
<dd>
Set the delay in milliseconds before screen reader announcements are made.<br>
Note: if this is too short, some default announcements may interrupt it.<br>
Default: <code>5000</code></dd>
Default: <code>5000</code>
</dd>
<dt>srAutoClear: <code>boolean | number</code></dt>
<dd>Automatically clear the screen reader announcement element after the specified delay. Number is in milliseconds.<br>Default: <code>10000</code></dd>
<dt>srDeleteText: <code>string</code></dt>
Expand All @@ -532,7 +541,8 @@ <h3>Screen reader enhancements</h3>
<dd>
Automatically remove the srAssistiveText once user input is detected, to reduce screen reader verbosity.<br>
The text is re-associated with the generated input if its value is emptied.<br>
Default: <code>5000</code></dd>
Default: <code>5000</code>
</dd>
<dt>srResultsText: <code>Function</code></dt>
<dd>Screen reader announcement after results are rendered<br>Default: <code>length => `${length} ${length === 1 ? 'result' : 'results'} available.`</code></dd>
</div>
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

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

7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "aria-autocomplete",
"version": "1.3.2",
"version": "1.4.0",
"description": "Accessible, extensible, JavaScript autocomplete with multi-select",
"main": "dist/aria-autocomplete.min.js",
"style": "dist/aria-autocomplete.css",
Expand All @@ -27,7 +27,10 @@
"select",
"combobox",
"multiselect",
"multiple selection"
"multiple selection",
"component",
"plugin",
"widget"
],
"browserslist": [
">0.1%",
Expand Down
4 changes: 2 additions & 2 deletions src/aria-autocomplete-types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ export interface IAriaAutocompleteOptions {
source?: string | string[] | any[] | Function | Promise<any[]>;
sourceMapping?: any;
alsoSearchIn?: string[];
create?: boolean | ((value: string) => string | any);
create?: boolean | ((value: string) => string | any | void);
delay?: number;
minLength?: number;
maxResults?: number;
showAllControl?: boolean;
confirmOnBlur?: boolean;
confirmOnBlur?: boolean | ((value: string, results: any[]) => string | void);
multiple?: boolean;
autoGrow?: boolean;
maxItems?: number;
Expand Down
14 changes: 11 additions & 3 deletions src/aria-autocomplete.less
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,23 @@
font-weight: normal;
text-decoration: underline;
cursor: pointer;

&[aria-disabled='true'] {
background: #f5f5f5;
}
}

&--no-results {
margin-top: 0 !important;
&--no-results,
&[aria-disabled='true'] {
opacity: 0.65 !important;
color: @near-black !important;
cursor: not-allowed !important;
text-decoration: none !important;
}

&--no-results {
margin-top: 0 !important;
background: transparent !important;
color: @near-black !important;
}
}

Expand Down
2 changes: 0 additions & 2 deletions src/autocomplete-constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ export const KEYCODES = {
PAGEDOWN: 34,
END: 35,
HOME: 36,
LEFT: 37,
UP: 38,
RIGHT: 39,
DOWN: 40,
DELETE: 46,
};
Expand Down
4 changes: 2 additions & 2 deletions src/autocomplete-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default class AutocompleteOptions {
* If no exact match is found,
* create an entry in the options list for the current search text
*/
create: boolean | ((value: string) => string | object) = false;
create: boolean | ((value: string) => string | any | void) = false;

/**
* Input delay after typing before running a search
Expand All @@ -61,7 +61,7 @@ export default class AutocompleteOptions {
* Confirm currently active selection when blurring off of the control. If
* no active selection, will compare current input value against available labels
*/
confirmOnBlur: boolean = true;
confirmOnBlur: boolean | ((value: string, options: any[]) => string | void) = true;

/**
* Allow multiple items to be selected
Expand Down
Loading

0 comments on commit 723fd7e

Please sign in to comment.