@financial-times/o-autocomplete 1.7.4 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +85 -0
- package/demos/src/dynamic-custom-suggestion/data.js +2098 -0
- package/demos/src/dynamic-custom-suggestion/dynamic-custom-suggestion.js +83 -0
- package/demos/src/dynamic-custom-suggestion/dynamic-custom-suggestion.mustache +14 -0
- package/origami.json +8 -0
- package/package.json +2 -2
- package/src/js/autocomplete.js +16 -1
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import Autocomplete from '../../../main.js';
|
|
2
|
+
import {data} from './data.js';
|
|
3
|
+
import oForms from '@financial-times/o-forms';
|
|
4
|
+
oForms.init();
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {object} CustomOption
|
|
7
|
+
* @property {string} Continent_Code - 2 letter continent code
|
|
8
|
+
* @property {string} Continent_Name - name of continent
|
|
9
|
+
* @property {string} Country_Name - name of country
|
|
10
|
+
* @property {number} Country_Number - id of country
|
|
11
|
+
* @property {string} Three_Letter_Country_Code - three letter country code
|
|
12
|
+
* @property {string} Two_Letter_Country_Code - two letter country code
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param {CustomOption} option - The option to transform into a suggestion string
|
|
17
|
+
* @returns {string} The string to display in the suggestions dropdown for this option
|
|
18
|
+
*/
|
|
19
|
+
function mapOptionToSuggestedValue(option) {
|
|
20
|
+
if (typeof option !== 'object') {
|
|
21
|
+
throw new Error(`Could not map option to suggested value, unexpected type: ${typeof option}.`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (typeof option.Country_Name !== 'string') {
|
|
25
|
+
throw new Error(`Could not map option to suggested value, option.Country_Name is not a string`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return option.Country_Name;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* @param {CustomOption} option - The option to transform into a suggestion string
|
|
32
|
+
* @returns {string} The string to display in the suggestions dropdown for this option
|
|
33
|
+
*/
|
|
34
|
+
function suggestionTemplate(option) {
|
|
35
|
+
if(typeof option === 'string') return option;
|
|
36
|
+
return `<div>
|
|
37
|
+
<strong>${option.Country_Name}</strong>
|
|
38
|
+
<span> </span>
|
|
39
|
+
<em>${option.Continent_Name}</em>
|
|
40
|
+
</div>`
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @typedef {Function} PopulateOptions
|
|
45
|
+
* @property {Array<string>} options - The options which match the rext which was typed into the autocomplete by the user
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @param {string} query - Text which was typed into the autocomplete by the user
|
|
50
|
+
* @param {PopulateOptions} populateOptions - Function to call when ready to update the suggestions dropdown
|
|
51
|
+
* @returns {void}
|
|
52
|
+
*/
|
|
53
|
+
function customSuggestions(query, populateOptions) {
|
|
54
|
+
const suggestions = data;
|
|
55
|
+
|
|
56
|
+
if (!query) {
|
|
57
|
+
populateOptions([]);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
suggestions.sort(function(a,b) {
|
|
61
|
+
return a.Country_Name.localeCompare(b.Country_Name);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const filteredOptions = [];
|
|
65
|
+
for (const suggestion of suggestions) {
|
|
66
|
+
const lowercaseSuggestion = suggestion.Country_Name.toLocaleLowerCase();
|
|
67
|
+
if (lowercaseSuggestion.startsWith(query.toLocaleLowerCase())) {
|
|
68
|
+
filteredOptions.push(suggestion);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
populateOptions(filteredOptions);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
new Autocomplete(document.querySelector('[data-o-component="o-autocomplete"]'), {
|
|
75
|
+
source: customSuggestions,
|
|
76
|
+
suggestionTemplate,
|
|
77
|
+
mapOptionToSuggestedValue,
|
|
78
|
+
defaultValue: data.find((d) => d['Two_Letter_Country_Code'] === 'GB')?.Country_Name,
|
|
79
|
+
onConfirm: function (option) {
|
|
80
|
+
// eslint-disable-next-line no-console
|
|
81
|
+
console.log('You chose option', option);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<form data-o-component="o-forms">
|
|
2
|
+
<div class="o-forms-field">
|
|
3
|
+
<span class="o-forms-title">
|
|
4
|
+
<label for="my-autocomplete" class="o-forms-title__main">Select your country</label>
|
|
5
|
+
</span>
|
|
6
|
+
<span class="o-forms-input o-forms-input--text">
|
|
7
|
+
<span data-o-component="o-autocomplete" class="o-autocomplete">
|
|
8
|
+
<!-- If the JavaScript executes, then this input will be progressively enhanced to an autocomplete component -->
|
|
9
|
+
<input required type="text" name="text-example" id="my-autocomplete">
|
|
10
|
+
</span>
|
|
11
|
+
<span role="alert" class="o-forms-input__error">Please fill out this field</span>
|
|
12
|
+
</span>
|
|
13
|
+
</div>
|
|
14
|
+
</form>
|
package/origami.json
CHANGED
|
@@ -53,6 +53,14 @@
|
|
|
53
53
|
"js": "demos/src/dynamic-complex/dynamic-complex.js",
|
|
54
54
|
"hidden": true
|
|
55
55
|
},
|
|
56
|
+
{
|
|
57
|
+
"title": "Autocomplete with custom suggestion items",
|
|
58
|
+
"name": "dynamic-custom-suggestions",
|
|
59
|
+
"template": "demos/src/dynamic-custom-suggestion/dynamic-custom-suggestion.mustache",
|
|
60
|
+
"description": "The source function returns objects and the suggestionTemplate transforms the objects into custom HTML suggestions",
|
|
61
|
+
"js": "demos/src/dynamic-custom-suggestion/dynamic-custom-suggestion.js",
|
|
62
|
+
"hidden": true
|
|
63
|
+
},
|
|
56
64
|
{
|
|
57
65
|
"title": "Pa11y",
|
|
58
66
|
"name": "pa11y",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@financial-times/o-autocomplete",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.1",
|
|
4
4
|
"description": "An origami component for autocomplete inputs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"autocomplete",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"@financial-times/o-loading": "^5.0.0",
|
|
39
39
|
"@financial-times/o-normalise": "^3.3.0",
|
|
40
40
|
"@financial-times/o-spacing": "^3.0.0",
|
|
41
|
-
"@financial-times/o-typography": "^7.
|
|
41
|
+
"@financial-times/o-typography": "^7.4.1",
|
|
42
42
|
"@financial-times/o-visual-effects": "^4.0.1"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
package/src/js/autocomplete.js
CHANGED
|
@@ -171,12 +171,19 @@ function initClearButton(instance) {
|
|
|
171
171
|
* @returns {void}
|
|
172
172
|
*/
|
|
173
173
|
|
|
174
|
+
/**
|
|
175
|
+
* @callback SuggestionTemplate
|
|
176
|
+
* @param {*} option - The option to render
|
|
177
|
+
* @returns {string} The html string to render for this suggestion.
|
|
178
|
+
*/
|
|
179
|
+
|
|
174
180
|
/**
|
|
175
181
|
* @typedef {object} AutocompleteOptions
|
|
176
182
|
* @property {string} [defaultValue] - Specify a string to prefill the autocomplete with
|
|
177
183
|
* @property {Source} [source] - The function which retrieves the suggestions to display
|
|
178
|
-
* @property {MapOptionToSuggestedValue} [mapOptionToSuggestedValue] - Function which transforms a suggestion before rendering
|
|
184
|
+
* @property {MapOptionToSuggestedValue} [mapOptionToSuggestedValue] - Function which transforms a suggestion before rendering.
|
|
179
185
|
* @property {onConfirm} [onConfirm] - Function which is called when the user selects an option
|
|
186
|
+
* @property {SuggestionTemplate} [suggestionTemplate] - Function to override how a suggestion item is rendered.
|
|
180
187
|
*/
|
|
181
188
|
|
|
182
189
|
class Autocomplete {
|
|
@@ -201,6 +208,9 @@ class Autocomplete {
|
|
|
201
208
|
if (opts.onConfirm) {
|
|
202
209
|
this.options.onConfirm = opts.onConfirm;
|
|
203
210
|
}
|
|
211
|
+
if (opts.suggestionTemplate) {
|
|
212
|
+
this.options.suggestionTemplate = opts.suggestionTemplate;
|
|
213
|
+
}
|
|
204
214
|
|
|
205
215
|
const container = document.createElement('div');
|
|
206
216
|
container.classList.add('o-autocomplete__listbox-container');
|
|
@@ -279,6 +289,11 @@ class Autocomplete {
|
|
|
279
289
|
* @returns {string|undefined} HTML string to represent a single suggestion.
|
|
280
290
|
*/
|
|
281
291
|
suggestion: (option) => {
|
|
292
|
+
// If the suggestionTemplate override option is provided,
|
|
293
|
+
// use that to render the suggestion.
|
|
294
|
+
if(typeof this.options.suggestionTemplate === 'function') {
|
|
295
|
+
return this.options.suggestionTemplate(option);
|
|
296
|
+
}
|
|
282
297
|
if (typeof option === 'object') {
|
|
283
298
|
// If the `mapOptionToSuggestedValue` function is defined
|
|
284
299
|
// Apply the function to the option. This is a way for the
|