Skip to content

Commit

Permalink
feat: add retainFocus config parameter (#83)
Browse files Browse the repository at this point in the history
* feat: add retainFocus config parameter
  • Loading branch information
rambah authored Jul 23, 2024
1 parent b41bec4 commit b1a9bb0
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ You can pass the following config options to `typeahead-standalone`:
|`display(selectedItem, event?) => string`|This callback is executed when the user selects an item from the suggestions. The current suggestion/item is passed as a parameter and it **must return a string** which is set as the input's value. The 2nd *optional* parameter `event` is a Mouse/Keyboard event which can be used to track user interaction or for analytics. It defaults to `null`. |Returns the string representation of the selected item|
|`tokenizer?: (words: string) => string[]`|The tokenizer function is used to split the search query and the search data by a given character(s). This function is useful when you wish to search hypenated-words or words with a certain prefix/suffix |words are split by space characters (new line, tab, spaces)|
|`listScrollOptions?: ScrollIntoViewOptions`| Allows fine control over the scroll behaviour for a large list of suggestions that needs scrolling. These options are passed to the `scrollIntoView()` function. [MDN Ref](https://developer.mozilla.org/docs/Web/API/Element/scrollIntoView) | `{ block: "nearest", inline: "nearest", behaviour: "auto"}`|
|`retainFocus`| Prevents the default tab key behavior when the list of suggestions is open. Disable this if you want to allow the default tab action to occur, for example, if you want to apply the suggestion and immediately move the focus to the next element on the page afterwards without having to press the tab key again. | `true`|

---

Expand Down
1 change: 1 addition & 0 deletions demo/dev.umd.html
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ <h4>Dummy input to test keyboard nav</h4>
className: 'typeahead-example',
minLength: 1,
limit: 10,
retainFocus: true,
templates: {
suggestion: (item) => {
const date = item.release_date
Expand Down
4 changes: 3 additions & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ <h5 class="center">
<li><a href="#config?id=classnames" title="classNames config param - typeahead-standalone.js"
class="section-link">classNames</a></li>
<li><a href="#config?id=tokenizer" title="tokenizer config param - typeahead-standalone.js" class="section-link">tokenizer</a></li>
<li><a href="#config?id=scrolloptions" title="tokenizer config param - typeahead-standalone.js" class="section-link">listScrollOptions</a></li>
<li><a href="#config?id=scrolloptions" title="listScrollOptions config param - typeahead-standalone.js" class="section-link">listScrollOptions</a></li>
<li><a href="#config?id=retainFocus" title="retainFocus config param - typeahead-standalone.js" class="section-link">retainFocus</a></li>
<li><a href="#config?id=templates" title="templates config param - typeahead-standalone.js" class="section-link">templates</a></li>
</ol>
</li>
Expand Down Expand Up @@ -189,6 +190,7 @@ <h5 class="center">
class="section-link">classNames</a></li>
<li><a href="#config?id=tokenizer" title="tokenizer config param - typeahead-standalone.js" class="section-link">tokenizer</a></li>
<li><a href="#config?id=scrolloptions" title="tokenizer config param - typeahead-standalone.js" class="section-link">listScrollOptions</a></li>
<li><a href="#config?id=retainFocus" title="retainFocus config param - typeahead-standalone.js" class="section-link">retainFocus</a></li>
<li><a href="#config?id=templates" title="templates config param - typeahead-standalone.js" class="section-link">templates</a></li>
</ol>
</li>
Expand Down
10 changes: 10 additions & 0 deletions docs/pages/config.html
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,16 @@ <h4><a href="#config?id=scrolloptions" id="scrolloptions" title="listScrollOptio
<code>{ block: 'nearest', inline: 'nearest', behaviour: 'auto' }</code>
</p>

<hr>
<h4><a href="#config?id=retainFocus" id="retainFocus" title="retainFocus config param - typeahead-standalone.js" class="submenu-link section-link">15. 🪙 retainFocus</h4></a>

<p>
The <code>retainFocus</code> config option is used to prevent the default action of the <kbd>Tab</kbd> key when the list of suggestions is open.
By default, when the list of suggestions is open, pressing the <kbd>Tab</kbd> key will select the first suggestion and stay in the input field. By pressing the <kbd>Tab</kbd> key again, the focus will move to the next element on the page.
When this option is set to <code>false</code>, pressing the <kbd>Tab</kbd> key will select the first suggestion and immediately move the focus to the next element on the page.
This option is set to <code>true</code> by default.
</p>

<hr>
<h4><a href="#config?id=templates" id="templates" title="templates config param - typeahead-standalone.js" class="submenu-link section-link">15. 🎨 templates</h4></a>

Expand Down
5 changes: 5 additions & 0 deletions src/common.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,11 @@ export interface typeaheadConfig<T extends Dictionary> {
* when the list of suggestions contains many items that require scrolling. It defaults to { inline: 'nearest', block: 'nearest' }
*/
listScrollOptions?: ScrollIntoViewOptions;
/**
* Prevents the default tab action when the list of suggestions is open. Disable this if you want to allow the default tab action to occur.
* It defaults to true.
*/
retainFocus?: boolean;
}

export interface ResultSet<T extends Dictionary> {
Expand Down
5 changes: 4 additions & 1 deletion src/typeahead-standalone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ const typeahead = <T extends Dictionary>(config: typeaheadConfig<T>): typeaheadR
...(config.classNames || {}),
};
const listScrollOptions: ScrollIntoViewOptions = { block: 'nearest', ...(config.listScrollOptions || {}) };
const retainFocus = config.retainFocus === false ? false : true;

// validate presence of atleast one data-source
if (!local && !prefetch && !remote) throw new Error('e02');
Expand Down Expand Up @@ -487,7 +488,9 @@ const typeahead = <T extends Dictionary>(config: typeaheadConfig<T>): typeaheadR
}

if (ev.key === 'Tab' && isListOpen()) {
ev.preventDefault();
if (retainFocus) {
ev.preventDefault();
}
useSelectedValue(true);
}
};
Expand Down

0 comments on commit b1a9bb0

Please sign in to comment.