create-instantsearch-app 7.0.2 → 7.2.0
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/README.md +0 -1
- package/package.json +5 -5
- package/src/cli/__tests__/postProcessAnswers.js +56 -0
- package/src/cli/index.js +85 -0
- package/src/cli/postProcessAnswers.js +3 -0
- package/src/templates/Angular InstantSearch/angular.json +3 -11
- package/src/templates/Angular InstantSearch/karma.conf.js +5 -8
- package/src/templates/Angular InstantSearch/src/app/app.component.ts +2 -5
- package/src/templates/Angular InstantSearch/src/app/app.module.ts +4 -9
- package/src/templates/Angular InstantSearch/src/environments/environment.prod.ts +1 -1
- package/src/templates/Angular InstantSearch/src/environments/environment.ts +1 -1
- package/src/templates/Angular InstantSearch/src/index.html +15 -12
- package/src/templates/Angular InstantSearch/src/main.ts +3 -2
- package/src/templates/Angular InstantSearch/src/polyfills.ts +1 -2
- package/src/templates/Angular InstantSearch/src/test.ts +7 -3
- package/src/templates/InstantSearch iOS/App/Assets.xcassets/AppIcon.appiconset/Contents.json +29 -29
- package/src/templates/InstantSearch.js/.template.js +1 -0
- package/src/templates/InstantSearch.js/index.html.hbs +8 -0
- package/src/templates/InstantSearch.js/{package.json → package.json.hbs} +5 -0
- package/src/templates/InstantSearch.js/src/app.js.hbs +95 -0
- package/src/templates/InstantSearch.js/src/global.d.ts.hbs +16 -0
- package/src/templates/InstantSearch.js widget/config/api-extractor.json +1 -1
- package/src/templates/InstantSearch.js widget/example/index.css +1 -1
- package/src/templates/InstantSearch.js widget/example/index.html +17 -14
- package/src/templates/React InstantSearch/index.html +1 -1
- package/src/templates/React InstantSearch Native/babel.config.js +1 -1
- package/src/templates/React InstantSearch Native/src/InfiniteHits.tsx +3 -3
- package/src/templates/Vue InstantSearch/public/index.html +13 -7
- package/src/templates/Vue InstantSearch/src/main.js +1 -1
- package/src/templates/Vue InstantSearch with Vue 3/index.html +5 -2
- /package/src/templates/JavaScript Client/{package.json → package.json.hbs} +0 -0
- /package/src/templates/React InstantSearch Native/{package.json → package.json.hbs} +0 -0
package/README.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-instantsearch-app",
|
|
3
|
-
"version": "7.0
|
|
3
|
+
"version": "7.2.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "⚡️ Build InstantSearch apps at the speed of thought",
|
|
6
6
|
"keywords": [
|
|
@@ -38,20 +38,20 @@
|
|
|
38
38
|
"algoliasearch": "4",
|
|
39
39
|
"chalk": "3.0.0",
|
|
40
40
|
"commander": "4.1.1",
|
|
41
|
-
"inquirer": "8.
|
|
41
|
+
"inquirer": "8.2.0",
|
|
42
42
|
"jstransformer-handlebars": "1.1.0",
|
|
43
43
|
"load-json-file": "6.2.0",
|
|
44
44
|
"lodash.camelcase": "4.3.0",
|
|
45
45
|
"metalsmith": "2.5.1",
|
|
46
46
|
"metalsmith-rename": "1.0.0",
|
|
47
|
-
"prettier": "
|
|
47
|
+
"prettier": "^2.4.1",
|
|
48
48
|
"semver": "6.1.1",
|
|
49
49
|
"validate-npm-package-name": "3.0.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@instantsearch/testutils": "1.
|
|
52
|
+
"@instantsearch/testutils": "1.15.0",
|
|
53
53
|
"jest-image-snapshot": "2.12.0",
|
|
54
54
|
"walk-sync": "2.0.2"
|
|
55
55
|
},
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "c59c53cab5f6caddf44fca51e32063d737a96bce"
|
|
57
57
|
}
|
|
@@ -185,4 +185,60 @@ describe('flags', () => {
|
|
|
185
185
|
).toEqual(expect.objectContaining({ insights: false }));
|
|
186
186
|
});
|
|
187
187
|
});
|
|
188
|
+
|
|
189
|
+
describe('autocomplete', () => {
|
|
190
|
+
test('with usage of autocomplete in searchInputType', async () => {
|
|
191
|
+
expect(
|
|
192
|
+
await postProcessAnswers({
|
|
193
|
+
configuration: {},
|
|
194
|
+
templateConfig: {
|
|
195
|
+
libraryName: 'instantsearch.js',
|
|
196
|
+
flags: {
|
|
197
|
+
autocomplete: '>= 4.52',
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
optionsFromArguments: {},
|
|
201
|
+
answers: { searchInputType: 'autocomplete' },
|
|
202
|
+
})
|
|
203
|
+
).toEqual(
|
|
204
|
+
expect.objectContaining({
|
|
205
|
+
searchInputType: 'autocomplete',
|
|
206
|
+
flags: expect.objectContaining({ autocomplete: true }),
|
|
207
|
+
})
|
|
208
|
+
);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
test('without usage of autocomplete in searchInputType', async () => {
|
|
212
|
+
expect(
|
|
213
|
+
await postProcessAnswers({
|
|
214
|
+
configuration: {},
|
|
215
|
+
templateConfig: {
|
|
216
|
+
libraryName: 'instantsearch.js',
|
|
217
|
+
flags: {
|
|
218
|
+
autocomplete: '>= 4.52',
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
optionsFromArguments: {},
|
|
222
|
+
answers: { searchInputType: 'searchbox' },
|
|
223
|
+
})
|
|
224
|
+
).toEqual(
|
|
225
|
+
expect.objectContaining({
|
|
226
|
+
searchInputType: 'searchbox',
|
|
227
|
+
flags: expect.objectContaining({ autocomplete: false }),
|
|
228
|
+
})
|
|
229
|
+
);
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
test('without config', async () => {
|
|
233
|
+
expect(
|
|
234
|
+
(
|
|
235
|
+
await postProcessAnswers({
|
|
236
|
+
configuration: {},
|
|
237
|
+
templateConfig: {},
|
|
238
|
+
optionsFromArguments: {},
|
|
239
|
+
})
|
|
240
|
+
).flags
|
|
241
|
+
).toEqual(expect.objectContaining({ autocomplete: false }));
|
|
242
|
+
});
|
|
243
|
+
});
|
|
188
244
|
});
|
package/src/cli/index.js
CHANGED
|
@@ -201,6 +201,91 @@ const getQuestions = ({ appName }) => ({
|
|
|
201
201
|
when: ({ appId, apiKey, indexName }) =>
|
|
202
202
|
attributesForFaceting.length === 0 && appId && apiKey && indexName,
|
|
203
203
|
},
|
|
204
|
+
{
|
|
205
|
+
type: 'list',
|
|
206
|
+
name: 'searchInputType',
|
|
207
|
+
message: 'Type of search input',
|
|
208
|
+
choices: [
|
|
209
|
+
{
|
|
210
|
+
name: 'Autocomplete with suggested and recent searches',
|
|
211
|
+
value: 'autocomplete',
|
|
212
|
+
},
|
|
213
|
+
{ name: 'Regular search box', value: 'searchbox' },
|
|
214
|
+
],
|
|
215
|
+
default: 'autocomplete',
|
|
216
|
+
when: ({ libraryVersion, template }) => {
|
|
217
|
+
const templatePath = getTemplatePath(template);
|
|
218
|
+
const templateConfig = getAppTemplateConfig(templatePath);
|
|
219
|
+
|
|
220
|
+
const selectedLibraryVersion = libraryVersion;
|
|
221
|
+
const requiredLibraryVersion =
|
|
222
|
+
templateConfig.flags && templateConfig.flags.autocomplete;
|
|
223
|
+
const supportsAutocomplete =
|
|
224
|
+
selectedLibraryVersion &&
|
|
225
|
+
requiredLibraryVersion &&
|
|
226
|
+
semver.satisfies(selectedLibraryVersion, requiredLibraryVersion, {
|
|
227
|
+
includePrerelease: true,
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
return supportsAutocomplete;
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
type: 'input',
|
|
235
|
+
name: 'querySuggestionsIndexName',
|
|
236
|
+
message: 'Index name for suggested searches',
|
|
237
|
+
suffix: `\n ${chalk.gray('This must be a Query Suggestions index')}`,
|
|
238
|
+
default: 'instant_search_demo_query_suggestions',
|
|
239
|
+
when: ({ searchInputType }) => searchInputType === 'autocomplete',
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
type: 'list',
|
|
243
|
+
name: 'autocompleteLibraryVersion',
|
|
244
|
+
message: () => `Autocomplete version`,
|
|
245
|
+
choices: async () => {
|
|
246
|
+
const libraryName = '@algolia/autocomplete-js';
|
|
247
|
+
|
|
248
|
+
try {
|
|
249
|
+
const versions = await fetchLibraryVersions(libraryName);
|
|
250
|
+
const latestStableVersion = semver.maxSatisfying(versions, '1', {
|
|
251
|
+
includePrerelease: false,
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
if (!latestStableVersion) {
|
|
255
|
+
return versions;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return [
|
|
259
|
+
new inquirer.Separator('Latest stable version (recommended)'),
|
|
260
|
+
latestStableVersion,
|
|
261
|
+
new inquirer.Separator('All versions'),
|
|
262
|
+
...versions,
|
|
263
|
+
];
|
|
264
|
+
} catch (err) {
|
|
265
|
+
const fallbackLibraryVersion = '1.11.0';
|
|
266
|
+
|
|
267
|
+
console.log();
|
|
268
|
+
console.error(
|
|
269
|
+
chalk.red(
|
|
270
|
+
`Cannot fetch versions for library "${chalk.cyan(libraryName)}".`
|
|
271
|
+
)
|
|
272
|
+
);
|
|
273
|
+
console.log();
|
|
274
|
+
console.log(
|
|
275
|
+
`Fallback to ${chalk.cyan(
|
|
276
|
+
fallbackLibraryVersion
|
|
277
|
+
)}, please upgrade the dependency after generating the app.`
|
|
278
|
+
);
|
|
279
|
+
console.log();
|
|
280
|
+
|
|
281
|
+
return [
|
|
282
|
+
new inquirer.Separator('Available versions'),
|
|
283
|
+
fallbackLibraryVersion,
|
|
284
|
+
];
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
when: ({ searchInputType }) => searchInputType === 'autocomplete',
|
|
288
|
+
},
|
|
204
289
|
],
|
|
205
290
|
widget: [
|
|
206
291
|
{
|
|
@@ -77,6 +77,9 @@ async function postProcessAnswers({
|
|
|
77
77
|
insights:
|
|
78
78
|
Boolean(templateConfig.flags && templateConfig.flags.insights) &&
|
|
79
79
|
semver.satisfies(libraryVersion, templateConfig.flags.insights),
|
|
80
|
+
autocomplete:
|
|
81
|
+
Boolean(templateConfig.flags && templateConfig.flags.autocomplete) &&
|
|
82
|
+
combinedAnswers.searchInputType === 'autocomplete',
|
|
80
83
|
},
|
|
81
84
|
};
|
|
82
85
|
}
|
|
@@ -22,13 +22,8 @@
|
|
|
22
22
|
"main": "src/main.ts",
|
|
23
23
|
"polyfills": "src/polyfills.ts",
|
|
24
24
|
"tsConfig": "tsconfig.app.json",
|
|
25
|
-
"assets": [
|
|
26
|
-
|
|
27
|
-
"src/assets"
|
|
28
|
-
],
|
|
29
|
-
"styles": [
|
|
30
|
-
"src/styles.css"
|
|
31
|
-
],
|
|
25
|
+
"assets": ["src/favicon.ico", "src/assets"],
|
|
26
|
+
"styles": ["src/styles.css"],
|
|
32
27
|
"scripts": []
|
|
33
28
|
},
|
|
34
29
|
"configurations": {
|
|
@@ -89,10 +84,7 @@
|
|
|
89
84
|
"polyfills": "src/polyfills.ts",
|
|
90
85
|
"tsConfig": "tsconfig.spec.json",
|
|
91
86
|
"karmaConfig": "karma.conf.js",
|
|
92
|
-
"assets": [
|
|
93
|
-
"src/favicon.ico",
|
|
94
|
-
"src/assets"
|
|
95
|
-
],
|
|
87
|
+
"assets": ["src/favicon.ico", "src/assets"],
|
|
96
88
|
"styles": [
|
|
97
89
|
"node_modules/instantsearch.css/themes/satellite.css",
|
|
98
90
|
"src/styles.css"
|
|
@@ -10,7 +10,7 @@ module.exports = function (config) {
|
|
|
10
10
|
require('karma-chrome-launcher'),
|
|
11
11
|
require('karma-jasmine-html-reporter'),
|
|
12
12
|
require('karma-coverage'),
|
|
13
|
-
require('@angular-devkit/build-angular/plugins/karma')
|
|
13
|
+
require('@angular-devkit/build-angular/plugins/karma'),
|
|
14
14
|
],
|
|
15
15
|
client: {
|
|
16
16
|
jasmine: {
|
|
@@ -19,18 +19,15 @@ module.exports = function (config) {
|
|
|
19
19
|
// for example, you can disable the random execution with `random: false`
|
|
20
20
|
// or set a specific seed with `seed: 4321`
|
|
21
21
|
},
|
|
22
|
-
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
|
22
|
+
clearContext: false, // leave Jasmine Spec Runner output visible in browser
|
|
23
23
|
},
|
|
24
24
|
jasmineHtmlReporter: {
|
|
25
|
-
suppressAll: true // removes the duplicated traces
|
|
25
|
+
suppressAll: true, // removes the duplicated traces
|
|
26
26
|
},
|
|
27
27
|
coverageReporter: {
|
|
28
28
|
dir: require('path').join(__dirname, './coverage/{{name}}'),
|
|
29
29
|
subdir: '.',
|
|
30
|
-
reporters: [
|
|
31
|
-
{ type: 'html' },
|
|
32
|
-
{ type: 'text-summary' }
|
|
33
|
-
]
|
|
30
|
+
reporters: [{ type: 'html' }, { type: 'text-summary' }],
|
|
34
31
|
},
|
|
35
32
|
reporters: ['progress', 'kjhtml'],
|
|
36
33
|
port: 9876,
|
|
@@ -39,6 +36,6 @@ module.exports = function (config) {
|
|
|
39
36
|
autoWatch: true,
|
|
40
37
|
browsers: ['Chrome'],
|
|
41
38
|
singleRun: false,
|
|
42
|
-
restartOnFileChange: true
|
|
39
|
+
restartOnFileChange: true,
|
|
43
40
|
});
|
|
44
41
|
};
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import { Component } from '@angular/core';
|
|
2
2
|
import algoliasearch from 'algoliasearch/lite';
|
|
3
3
|
|
|
4
|
-
const searchClient = algoliasearch(
|
|
5
|
-
'{{appId}}',
|
|
6
|
-
'{{apiKey}}'
|
|
7
|
-
);
|
|
4
|
+
const searchClient = algoliasearch('{{appId}}', '{{apiKey}}');
|
|
8
5
|
|
|
9
6
|
@Component({
|
|
10
7
|
selector: 'app-root',
|
|
11
8
|
templateUrl: './app.component.html',
|
|
12
|
-
styleUrls: ['./app.component.css']
|
|
9
|
+
styleUrls: ['./app.component.css'],
|
|
13
10
|
})
|
|
14
11
|
export class AppComponent {
|
|
15
12
|
config = {
|
|
@@ -5,14 +5,9 @@ import { NgAisModule } from 'angular-instantsearch';
|
|
|
5
5
|
import { AppComponent } from './app.component';
|
|
6
6
|
|
|
7
7
|
@NgModule({
|
|
8
|
-
declarations: [
|
|
9
|
-
|
|
10
|
-
],
|
|
11
|
-
imports: [
|
|
12
|
-
NgAisModule.forRoot(),
|
|
13
|
-
BrowserModule
|
|
14
|
-
],
|
|
8
|
+
declarations: [AppComponent],
|
|
9
|
+
imports: [NgAisModule.forRoot(), BrowserModule],
|
|
15
10
|
providers: [],
|
|
16
|
-
bootstrap: [AppComponent]
|
|
11
|
+
bootstrap: [AppComponent],
|
|
17
12
|
})
|
|
18
|
-
export class AppModule {
|
|
13
|
+
export class AppModule {}
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
<!
|
|
1
|
+
<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
</
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<title>{{name}}</title>
|
|
6
|
+
<base href="/" />
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
8
|
+
<link rel="icon" type="image/x-icon" href="favicon.ico" />
|
|
9
|
+
<link
|
|
10
|
+
href="https://cdn.jsdelivr.net/npm/instantsearch.css@7/themes/satellite.css"
|
|
11
|
+
rel="stylesheet"
|
|
12
|
+
/>
|
|
13
|
+
</head>
|
|
14
|
+
<body>
|
|
15
|
+
<app-root></app-root>
|
|
16
|
+
</body>
|
|
14
17
|
</html>
|
|
@@ -57,8 +57,7 @@
|
|
|
57
57
|
/***************************************************************************************************
|
|
58
58
|
* Zone JS is required by default for Angular itself.
|
|
59
59
|
*/
|
|
60
|
-
import 'zone.js';
|
|
61
|
-
|
|
60
|
+
import 'zone.js'; // Included with Angular CLI.
|
|
62
61
|
|
|
63
62
|
/***************************************************************************************************
|
|
64
63
|
* APPLICATION IMPORTS
|
|
@@ -4,11 +4,15 @@ import 'zone.js/testing';
|
|
|
4
4
|
import { getTestBed } from '@angular/core/testing';
|
|
5
5
|
import {
|
|
6
6
|
BrowserDynamicTestingModule,
|
|
7
|
-
platformBrowserDynamicTesting
|
|
7
|
+
platformBrowserDynamicTesting,
|
|
8
8
|
} from '@angular/platform-browser-dynamic/testing';
|
|
9
9
|
|
|
10
10
|
declare const require: {
|
|
11
|
-
context(
|
|
11
|
+
context(
|
|
12
|
+
path: string,
|
|
13
|
+
deep?: boolean,
|
|
14
|
+
filter?: RegExp
|
|
15
|
+
): {
|
|
12
16
|
keys(): string[];
|
|
13
17
|
<T>(id: string): T;
|
|
14
18
|
};
|
|
@@ -18,7 +22,7 @@ declare const require: {
|
|
|
18
22
|
getTestBed().initTestEnvironment(
|
|
19
23
|
BrowserDynamicTestingModule,
|
|
20
24
|
platformBrowserDynamicTesting(),
|
|
21
|
-
{ teardown: { destroyAfterEach: true }}
|
|
25
|
+
{ teardown: { destroyAfterEach: true } }
|
|
22
26
|
);
|
|
23
27
|
|
|
24
28
|
// Then we find all the tests.
|
package/src/templates/InstantSearch iOS/App/Assets.xcassets/AppIcon.appiconset/Contents.json
CHANGED
|
@@ -1,48 +1,48 @@
|
|
|
1
1
|
{
|
|
2
|
-
"images"
|
|
2
|
+
"images": [
|
|
3
3
|
{
|
|
4
|
-
"idiom"
|
|
5
|
-
"size"
|
|
6
|
-
"scale"
|
|
4
|
+
"idiom": "iphone",
|
|
5
|
+
"size": "20x20",
|
|
6
|
+
"scale": "2x"
|
|
7
7
|
},
|
|
8
8
|
{
|
|
9
|
-
"idiom"
|
|
10
|
-
"size"
|
|
11
|
-
"scale"
|
|
9
|
+
"idiom": "iphone",
|
|
10
|
+
"size": "20x20",
|
|
11
|
+
"scale": "3x"
|
|
12
12
|
},
|
|
13
13
|
{
|
|
14
|
-
"idiom"
|
|
15
|
-
"size"
|
|
16
|
-
"scale"
|
|
14
|
+
"idiom": "iphone",
|
|
15
|
+
"size": "29x29",
|
|
16
|
+
"scale": "2x"
|
|
17
17
|
},
|
|
18
18
|
{
|
|
19
|
-
"idiom"
|
|
20
|
-
"size"
|
|
21
|
-
"scale"
|
|
19
|
+
"idiom": "iphone",
|
|
20
|
+
"size": "29x29",
|
|
21
|
+
"scale": "3x"
|
|
22
22
|
},
|
|
23
23
|
{
|
|
24
|
-
"idiom"
|
|
25
|
-
"size"
|
|
26
|
-
"scale"
|
|
24
|
+
"idiom": "iphone",
|
|
25
|
+
"size": "40x40",
|
|
26
|
+
"scale": "2x"
|
|
27
27
|
},
|
|
28
28
|
{
|
|
29
|
-
"idiom"
|
|
30
|
-
"size"
|
|
31
|
-
"scale"
|
|
29
|
+
"idiom": "iphone",
|
|
30
|
+
"size": "40x40",
|
|
31
|
+
"scale": "3x"
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
|
-
"idiom"
|
|
35
|
-
"size"
|
|
36
|
-
"scale"
|
|
34
|
+
"idiom": "iphone",
|
|
35
|
+
"size": "60x60",
|
|
36
|
+
"scale": "2x"
|
|
37
37
|
},
|
|
38
38
|
{
|
|
39
|
-
"idiom"
|
|
40
|
-
"size"
|
|
41
|
-
"scale"
|
|
39
|
+
"idiom": "iphone",
|
|
40
|
+
"size": "60x60",
|
|
41
|
+
"scale": "3x"
|
|
42
42
|
}
|
|
43
43
|
],
|
|
44
|
-
"info"
|
|
45
|
-
"version"
|
|
46
|
-
"author"
|
|
44
|
+
"info": {
|
|
45
|
+
"version": 1,
|
|
46
|
+
"author": "xcode"
|
|
47
47
|
}
|
|
48
|
-
}
|
|
48
|
+
}
|
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
<link rel="shortcut icon" href="./favicon.png">
|
|
10
10
|
|
|
11
11
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/instantsearch.css@7/themes/satellite-min.css">
|
|
12
|
+
{{#if flags.autocomplete}}
|
|
13
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@algolia/autocomplete-theme-classic@1.11.0/dist/theme.min.css">
|
|
14
|
+
{{/if}}
|
|
12
15
|
<link rel="stylesheet" href="./src/index.css">
|
|
13
16
|
<link rel="stylesheet" href="./src/app.css">
|
|
14
17
|
|
|
@@ -50,6 +53,11 @@
|
|
|
50
53
|
|
|
51
54
|
<script src="https://cdn.jsdelivr.net/npm/algoliasearch@4.10.5/dist/algoliasearch-lite.umd.js"></script>
|
|
52
55
|
<script src="https://cdn.jsdelivr.net/npm/instantsearch.js@{{libraryVersion}}"></script>
|
|
56
|
+
{{#if flags.autocomplete}}
|
|
57
|
+
<script src="https://cdn.jsdelivr.net/npm/@algolia/autocomplete-js@{{autocompleteLibraryVersion}}/dist/umd/index.production.min.js"></script>
|
|
58
|
+
<script src="https://cdn.jsdelivr.net/npm/@algolia/autocomplete-plugin-query-suggestions@{{autocompleteLibraryVersion}}/dist/umd/index.production.min.js"></script>
|
|
59
|
+
<script src="https://cdn.jsdelivr.net/npm/@algolia/autocomplete-plugin-recent-searches@{{autocompleteLibraryVersion}}/dist/umd/index.production.min.js"></script>
|
|
60
|
+
{{/if}}
|
|
53
61
|
<script src="./src/app.js"></script>
|
|
54
62
|
</body>
|
|
55
63
|
|
|
@@ -14,6 +14,11 @@
|
|
|
14
14
|
"prettier": "2.6.2"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
+
{{#if flags.autocomplete}}
|
|
18
|
+
"@algolia/autocomplete-js": "{{autocompleteLibraryVersion}}",
|
|
19
|
+
"@algolia/autocomplete-plugin-recent-searches": "{{autocompleteLibraryVersion}}",
|
|
20
|
+
"@algolia/autocomplete-plugin-query-suggestions": "{{autocompleteLibraryVersion}}",
|
|
21
|
+
{{/if}}
|
|
17
22
|
"algoliasearch": "4",
|
|
18
23
|
"instantsearch.js": "{{libraryVersion}}"
|
|
19
24
|
}
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
const { algoliasearch, instantsearch } = window;
|
|
2
|
+
{{#if flags.autocomplete}}
|
|
3
|
+
const { autocomplete } = window['@algolia/autocomplete-js'];
|
|
4
|
+
const { createLocalStorageRecentSearchesPlugin } = window[
|
|
5
|
+
'@algolia/autocomplete-plugin-recent-searches'
|
|
6
|
+
];
|
|
7
|
+
const { createQuerySuggestionsPlugin } = window[
|
|
8
|
+
'@algolia/autocomplete-plugin-query-suggestions'
|
|
9
|
+
];
|
|
10
|
+
{{/if}}
|
|
2
11
|
|
|
3
12
|
const searchClient = algoliasearch('{{appId}}', '{{apiKey}}');
|
|
4
13
|
|
|
@@ -8,13 +17,21 @@ const search = instantsearch({
|
|
|
8
17
|
{{#if flags.insights}}insights: true,{{/if}}
|
|
9
18
|
});
|
|
10
19
|
|
|
20
|
+
{{#if flags.autocomplete}}
|
|
21
|
+
const virtualSearchBox = instantsearch.connectors.connectSearchBox(() => {});
|
|
22
|
+
{{/if}}
|
|
23
|
+
|
|
11
24
|
search.addWidgets([
|
|
25
|
+
{{#unless flags.autocomplete}}
|
|
12
26
|
instantsearch.widgets.searchBox({
|
|
13
27
|
container: '#searchbox',
|
|
14
28
|
{{#if searchPlaceholder}}
|
|
15
29
|
placeholder: '{{searchPlaceholder}}',
|
|
16
30
|
{{/if}}
|
|
17
31
|
}),
|
|
32
|
+
{{else}}
|
|
33
|
+
virtualSearchBox({}),
|
|
34
|
+
{{/unless}}
|
|
18
35
|
instantsearch.widgets.hits({
|
|
19
36
|
container: '#hits',
|
|
20
37
|
{{#if attributesToDisplay}}
|
|
@@ -74,3 +91,81 @@ search.addWidgets([
|
|
|
74
91
|
]);
|
|
75
92
|
|
|
76
93
|
search.start();
|
|
94
|
+
|
|
95
|
+
{{#if flags.autocomplete}}
|
|
96
|
+
const recentSearchesPlugin = createLocalStorageRecentSearchesPlugin({
|
|
97
|
+
key: 'instantsearch',
|
|
98
|
+
limit: 3,
|
|
99
|
+
transformSource({ source }) {
|
|
100
|
+
return {
|
|
101
|
+
...source,
|
|
102
|
+
onSelect({ setIsOpen, setQuery, item, event }) {
|
|
103
|
+
onSelect({ setQuery, setIsOpen, event, query: item.label });
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
const querySuggestionsPlugin = createQuerySuggestionsPlugin({
|
|
110
|
+
searchClient,
|
|
111
|
+
indexName: '{{querySuggestionsIndexName}}',
|
|
112
|
+
getSearchParams() {
|
|
113
|
+
return recentSearchesPlugin.data.getAlgoliaSearchParams({ hitsPerPage: 6 });
|
|
114
|
+
},
|
|
115
|
+
transformSource({ source }) {
|
|
116
|
+
return {
|
|
117
|
+
...source,
|
|
118
|
+
sourceId: 'querySuggestionsPlugin',
|
|
119
|
+
onSelect({ setIsOpen, setQuery, event, item }) {
|
|
120
|
+
onSelect({ setQuery, setIsOpen, event, query: item.query });
|
|
121
|
+
},
|
|
122
|
+
getItems(params) {
|
|
123
|
+
if (!params.state.query) {
|
|
124
|
+
return [];
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return source.getItems(params);
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
autocomplete({
|
|
134
|
+
container: '#searchbox',
|
|
135
|
+
{{#if searchPlaceholder}}
|
|
136
|
+
placeholder: '{{searchPlaceholder}}',
|
|
137
|
+
{{/if}}
|
|
138
|
+
openOnFocus: true,
|
|
139
|
+
detachedMediaQuery: 'none',
|
|
140
|
+
onSubmit({ state }) {
|
|
141
|
+
setInstantSearchUiState({ query: state.query });
|
|
142
|
+
},
|
|
143
|
+
plugins: [recentSearchesPlugin, querySuggestionsPlugin],
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
function setInstantSearchUiState(indexUiState) {
|
|
147
|
+
search.mainIndex.setIndexUiState({ page: 1, ...indexUiState });
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function onSelect({ setIsOpen, setQuery, event, query }) {
|
|
151
|
+
if (isModifierEvent(event)) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
setQuery(query);
|
|
156
|
+
setIsOpen(false);
|
|
157
|
+
setInstantSearchUiState({ query });
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function isModifierEvent(event) {
|
|
161
|
+
const isMiddleClick = event.button === 1;
|
|
162
|
+
|
|
163
|
+
return (
|
|
164
|
+
isMiddleClick ||
|
|
165
|
+
event.altKey ||
|
|
166
|
+
event.ctrlKey ||
|
|
167
|
+
event.metaKey ||
|
|
168
|
+
event.shiftKey
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
{{/if}}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
{{#if flags.autocomplete}}
|
|
2
|
+
import { autocomplete } from '@algolia/autocomplete-js';
|
|
3
|
+
import { createLocalStorageRecentSearchesPlugin } from '@algolia/autocomplete-plugin-recent-searches';
|
|
4
|
+
import { createQuerySuggestionsPlugin } from '@algolia/autocomplete-plugin-query-suggestions';
|
|
5
|
+
{{/if}}
|
|
1
6
|
import algoliasearch from 'algoliasearch/lite';
|
|
2
7
|
import instantsearch from 'instantsearch.js/dist/instantsearch.production.min';
|
|
3
8
|
|
|
@@ -5,5 +10,16 @@ declare global {
|
|
|
5
10
|
interface Window {
|
|
6
11
|
algoliasearch: typeof algoliasearch;
|
|
7
12
|
instantsearch: typeof instantsearch;
|
|
13
|
+
{{#if flags.autocomplete}}
|
|
14
|
+
'@algolia/autocomplete-js': {
|
|
15
|
+
autocomplete: typeof autocomplete;
|
|
16
|
+
};
|
|
17
|
+
'@algolia/autocomplete-plugin-recent-searches': {
|
|
18
|
+
createLocalStorageRecentSearchesPlugin: typeof createLocalStorageRecentSearchesPlugin;
|
|
19
|
+
};
|
|
20
|
+
'@algolia/autocomplete-plugin-query-suggestions': {
|
|
21
|
+
createQuerySuggestionsPlugin: typeof createQuerySuggestionsPlugin;
|
|
22
|
+
};
|
|
23
|
+
{{/if}}
|
|
8
24
|
}
|
|
9
25
|
}
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<link
|
|
8
|
+
rel="stylesheet"
|
|
9
|
+
href="https://cdn.jsdelivr.net/npm/instantsearch.css@7/themes/algolia-min.css"
|
|
10
|
+
/>
|
|
11
|
+
<link rel="stylesheet" href="style.css" />
|
|
12
|
+
<title>{{ name }} example</title>
|
|
13
|
+
</head>
|
|
14
|
+
<body>
|
|
15
|
+
<div id="search-box"></div>
|
|
16
|
+
<div id="example"></div>
|
|
17
|
+
<div id="hits"></div>
|
|
18
|
+
<script src="index.ts"></script>
|
|
19
|
+
</body>
|
|
17
20
|
</html>
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
content="width=device-width, initial-scale=1, shrink-to-fit=no"
|
|
8
8
|
/>
|
|
9
9
|
|
|
10
|
-
<link rel="shortcut icon" href="favicon.png"
|
|
10
|
+
<link rel="shortcut icon" href="favicon.png" />
|
|
11
11
|
|
|
12
12
|
<!--
|
|
13
13
|
Do not use @7 in production, use a complete version like x.x.x, see website for latest version:
|
|
@@ -20,8 +20,8 @@ export const InfiniteHits = forwardRef(
|
|
|
20
20
|
return (
|
|
21
21
|
<FlatList
|
|
22
22
|
ref={ref}
|
|
23
|
-
data={
|
|
24
|
-
keyExtractor={item => item.objectID}
|
|
23
|
+
data={hits as unknown as THit[]}
|
|
24
|
+
keyExtractor={(item) => item.objectID}
|
|
25
25
|
ItemSeparatorComponent={() => <View style={styles.separator} />}
|
|
26
26
|
onEndReached={() => {
|
|
27
27
|
if (!isLastPage) {
|
|
@@ -30,7 +30,7 @@ export const InfiniteHits = forwardRef(
|
|
|
30
30
|
}}
|
|
31
31
|
renderItem={({ item }) => (
|
|
32
32
|
<View style={styles.item}>
|
|
33
|
-
<Hit hit={
|
|
33
|
+
<Hit hit={item as unknown as THit} />
|
|
34
34
|
</View>
|
|
35
35
|
)}
|
|
36
36
|
/>
|
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
|
-
<meta charset="utf-8"
|
|
5
|
-
<meta http-equiv="X-UA-Compatible" content="IE=edge"
|
|
6
|
-
<meta name="viewport" content="width=device-width,initial-scale=1.0"
|
|
7
|
-
<link rel="icon" href="<%= BASE_URL %>favicon.png"
|
|
8
|
-
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
6
|
+
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
|
7
|
+
<link rel="icon" href="<%= BASE_URL %>favicon.png" />
|
|
8
|
+
<!--
|
|
9
9
|
Do not use @7 in production, use a complete version like x.x.x, see website for latest version:
|
|
10
10
|
https://www.algolia.com/doc/guides/building-search-ui/installation/react/#load-the-style
|
|
11
11
|
-->
|
|
12
|
-
<link
|
|
12
|
+
<link
|
|
13
|
+
rel="stylesheet"
|
|
14
|
+
href="https://cdn.jsdelivr.net/npm/instantsearch.css@7/themes/satellite-min.css"
|
|
15
|
+
/>
|
|
13
16
|
<title>{{name}}</title>
|
|
14
17
|
</head>
|
|
15
18
|
<body>
|
|
16
19
|
<noscript>
|
|
17
|
-
<strong
|
|
20
|
+
<strong
|
|
21
|
+
>We're sorry but {{name}} doesn't work properly without JavaScript
|
|
22
|
+
enabled. Please enable it to continue.</strong
|
|
23
|
+
>
|
|
18
24
|
</noscript>
|
|
19
25
|
<div id="app"></div>
|
|
20
26
|
<!-- built files will be auto injected -->
|
|
@@ -2,14 +2,17 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
|
-
<meta http-equiv="X-UA-Compatible" content="ie=edge"
|
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<link rel="icon" href="/favicon.png" />
|
|
8
8
|
<!--
|
|
9
9
|
Do not use @7 in production, use a complete version like x.x.x, see website for latest version:
|
|
10
10
|
https://www.algolia.com/doc/guides/building-search-ui/installation/react/#load-the-style
|
|
11
11
|
-->
|
|
12
|
-
<link
|
|
12
|
+
<link
|
|
13
|
+
rel="stylesheet"
|
|
14
|
+
href="https://cdn.jsdelivr.net/npm/instantsearch.css@7/themes/satellite-min.css"
|
|
15
|
+
/>
|
|
13
16
|
<title>{{name}}</title>
|
|
14
17
|
</head>
|
|
15
18
|
<body>
|
|
File without changes
|
|
File without changes
|