Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add query parameter to custom suggestionTemplate function #1516

Merged
merged 2 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 61 additions & 1 deletion components/o-autocomplete/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
- [JavaScript](#javascript)
- [dynamic suggestions function](#dynamic-suggestions-function)
- [mapOptionToSuggestedValue](#mapoptiontosuggestedvalue)
- [onConfirm](#onconfirm)

Check warning on line 14 in components/o-autocomplete/README.md

View workflow job for this annotation

GitHub Actions / test (components/o-autocomplete)

The table of contents top-level contain a link to every h2 in the document, and sub-levels should contain a link to every h3 in their section. Missing item for "onConfirm"

Check warning on line 14 in components/o-autocomplete/README.md

View workflow job for this annotation

GitHub Actions / test (components/o-autocomplete)

The table of contents top-level contain a link to every h2 in the document, and sub-levels should contain a link to every h3 in their section. Missing item for "suggestionTemplate"
- [Keyboard Support](#keyboard-support)
- [When focus is within the text input](#when-focus-is-within-the-text-input)
- [When focus is within the suggestions menu](#when-focus-is-within-the-suggestions-menu)
Expand Down Expand Up @@ -236,10 +236,14 @@

It is typically used when wanting to provide additional context or styling for each suggestion item.

The `query` value (text which was typed into the autocomplete text input field by the user) is provided so that it can be used as a basis for highlighting the `option` value (or one of its values if it is an object).

:warning: **Caution:** because this function allows you to output arbitrary HTML, you should [make sure it's trusted](https://en.wikipedia.org/wiki/Cross-site_scripting), and accessible. The HTML will be output within listbox options, so [ensure all descendants are presentational](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/option_role#all_descendants_are_presentational).

#### Example

Providing additional context by displaying multiple `option` properties:

```js
import oAutocomplete from 'o-autocomplete';

Expand All @@ -250,6 +254,7 @@

/**
* @param {{"name": string, "role": string}} option - The option to transform into a suggestion
* @param {string} [query] - Text which was typed into the autocomplete text input field by the user
* @returns {string} The HTML to render in the suggestion list*/
function suggestionTemplate(option) {
return `
Expand All @@ -267,14 +272,69 @@
});
```

Using the `query` value to apply highlighting to one of the `option` properties:

```js
import oAutocomplete from 'o-autocomplete';

async function customSuggestions(query, populateOptions) {
const suggestions = await getSuggestions(query);
populateOptions(suggestions);
}

function highlightSuggestion(suggestion, query) {
const result = suggestion.split('');

const matchIndex = suggestion.toLocaleLowerCase().indexOf(query.toLocaleLowerCase());
return result.map(function(character, index) {
let shouldHighlight = true;
const hasMatched = matchIndex > -1;
const characterIsWithinMatch = index >= matchIndex && index <= matchIndex + query.length - 1;
if (hasMatched && characterIsWithinMatch) {
shouldHighlight = false;
}
return [character, shouldHighlight];
});
}

/**
* @param {{"name": string, "role": string}} option - The option to transform into a suggestion
* @param {string} [query] - Text which was typed into the autocomplete text input field by the user
* @returns {string} The HTML to render in the suggestion list*/
function suggestionTemplate(option, query) {
const characters = highlightSuggestion(option.name, query || option.name);

let output = '';
for (const [character, shoudHighlight] of characters) {
if (shoudHighlight) {
output += `<span class="o-autocomplete__option--highlight">${character}</span>`;
} else {
output += `${character}`;
}
}
output += ` (${option.role})`;
const span = document.createElement('span');
span.setAttribute('aria-label', option.name);
span.innerHTML = output;
return span.outerHTML;
}

const oAutocompleteElement = document.getElementById('my-o-autocomplete-element');
new oAutocomplete(oAutocompleteElement, {
suggestionTemplate,
source: customSuggestions,
});
```

<a name="SuggestionTemplate"></a>

#### SuggestionTemplate ⇒ <code>string</code>
**Returns**: <code>string</code> - The HTML string to render as the suggestion for this option

| Param | Type | Description |
| --- | --- | --- |
| option | <code>\*</code> | The option to transform into a suggestio |
| option | <code>\*</code> | The option to transform into a suggestion |
| query | <code>string</code> | Text which was typed into the autocomplete text input field by the user |

### onConfirm

Expand Down
Loading
Loading