create-instantsearch-app 5.2.1 → 6.1.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/package.json +4 -5
- package/src/api/__tests__/__snapshots__/index.test.js.snap +4 -4
- package/src/templates/Angular InstantSearch/src/app/app.component.html.hbs +4 -1
- package/src/templates/InstantSearch.js/index.html.hbs +2 -4
- package/src/templates/InstantSearch.js/package.json +5 -11
- package/src/templates/InstantSearch.js/src/app.js.hbs +12 -6
- package/src/templates/React InstantSearch/public/index.html +1 -1
- package/src/templates/React InstantSearch/src/App.js.hbs +10 -4
- package/src/templates/React InstantSearch Hooks/.editorconfig +8 -0
- package/src/templates/React InstantSearch Hooks/.gitignore.template +23 -0
- package/src/templates/React InstantSearch Hooks/.prettierrc +5 -0
- package/src/templates/React InstantSearch Hooks/.template.js +24 -0
- package/src/templates/React InstantSearch Hooks/README.md +19 -0
- package/src/templates/React InstantSearch Hooks/favicon.png +0 -0
- package/src/templates/React InstantSearch Hooks/index.html +31 -0
- package/src/templates/React InstantSearch Hooks/package.json +20 -0
- package/src/templates/React InstantSearch Hooks/src/App.css +71 -0
- package/src/templates/React InstantSearch Hooks/src/App.tsx.hbs +110 -0
- package/src/templates/React InstantSearch Hooks/src/Panel.tsx +14 -0
- package/src/templates/React InstantSearch Hooks/src/index.tsx +5 -0
- package/src/templates/React InstantSearch widget/README.md +1 -1
- package/src/templates/React InstantSearch widget/package.json.hbs +2 -1
- package/src/templates/React InstantSearch widget/src/lib/connector.ts.hbs +6 -3
- package/src/templates/React InstantSearch widget/src/lib/widget.tsx.hbs +4 -4
- package/src/templates/React InstantSearch widget/src/types/connector.ts +17 -0
- package/src/templates/Vue InstantSearch/package.json +15 -14
- package/src/templates/Vue InstantSearch/public/index.html +1 -1
- package/src/templates/Vue InstantSearch/src/App.vue +18 -6
- package/src/templates/Vue InstantSearch 2/package.json +15 -14
- package/src/templates/Vue InstantSearch with Vue 3/README.md +2 -2
- package/src/templates/Vue InstantSearch with Vue 3/index.html +1 -1
- package/src/templates/Vue InstantSearch with Vue 3/package.json +1 -0
- package/src/templates/Vue InstantSearch with Vue 3/src/App.vue +9 -2
- package/src/utils/__tests__/__snapshots__/index.test.js.snap +1 -1
- package/src/utils/__tests__/index.test.js +2 -2
- package/CHANGELOG.md +0 -518
- package/src/templates/InstantSearch.js/manifest.webmanifest +0 -15
- package/src/templates/React InstantSearch widget/.gitignore +0 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-instantsearch-app",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.1.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "⚡️ Build InstantSearch apps at the speed of thought",
|
|
6
6
|
"keywords": [
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"scripts": {
|
|
17
17
|
"start": "node src/cli/index.js",
|
|
18
|
-
"test": "jest src",
|
|
18
|
+
"test": "jest --no-color src",
|
|
19
19
|
"test:e2e:templates": "jest e2e/templates.test.js",
|
|
20
20
|
"test:e2e:installs": "jest e2e/installs.test.js",
|
|
21
21
|
"test:e2e": "yarn run test:e2e:templates && yarn run test:e2e:installs",
|
|
@@ -25,8 +25,7 @@
|
|
|
25
25
|
"doctoc": "doctoc --maxlevel 3 README.md CONTRIBUTING.md docs/",
|
|
26
26
|
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
|
|
27
27
|
"release-templates": "node ./scripts/release-templates",
|
|
28
|
-
"release": "
|
|
29
|
-
"release:beta": "release-it --preRelease=beta"
|
|
28
|
+
"release": "shipjs prepare"
|
|
30
29
|
},
|
|
31
30
|
"files": [
|
|
32
31
|
"index.js",
|
|
@@ -67,7 +66,7 @@
|
|
|
67
66
|
"eslint-plugin-prettier": "3.1.2",
|
|
68
67
|
"jest": "25.1.0",
|
|
69
68
|
"jest-image-snapshot": "2.12.0",
|
|
70
|
-
"
|
|
69
|
+
"shipjs": "0.24.4",
|
|
71
70
|
"walk-sync": "2.0.2"
|
|
72
71
|
}
|
|
73
72
|
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
3
|
exports[`Options with invalid name throws 1`] = `
|
|
4
|
-
"Could not create a project called \\"
|
|
4
|
+
"Could not create a project called \\"./WrongNpmName\\" because of npm naming restrictions.
|
|
5
5
|
- name cannot start with a period
|
|
6
6
|
- name can only contain URL-friendly characters"
|
|
7
7
|
`;
|
|
8
8
|
|
|
9
|
-
exports[`Options with unknown template throws 1`] = `"The template directory must contain a configuration file \`.template.js\` or must be one of those: Angular InstantSearch, Autocomplete, Autocomplete.js 0, InstantSearch Android, InstantSearch iOS, InstantSearch.js, InstantSearch.js 2, InstantSearch.js widget, JavaScript Client, JavaScript Helper, JavaScript Helper 2, React InstantSearch, React InstantSearch Hooks Native, React InstantSearch Native, React InstantSearch widget, Vue InstantSearch, Vue InstantSearch 1, Vue InstantSearch 2, Vue InstantSearch with Vue 3"`;
|
|
9
|
+
exports[`Options with unknown template throws 1`] = `"The template directory must contain a configuration file \`.template.js\` or must be one of those: Angular InstantSearch, Autocomplete, Autocomplete.js 0, InstantSearch Android, InstantSearch iOS, InstantSearch.js, InstantSearch.js 2, InstantSearch.js widget, JavaScript Client, JavaScript Helper, JavaScript Helper 2, React InstantSearch, React InstantSearch Hooks, React InstantSearch Hooks Native, React InstantSearch Native, React InstantSearch widget, Vue InstantSearch, Vue InstantSearch 1, Vue InstantSearch 2, Vue InstantSearch with Vue 3"`;
|
|
10
10
|
|
|
11
|
-
exports[`Options with wrong template path throws 1`] = `"The template directory must contain a configuration file \`.template.js\` or must be one of those: Angular InstantSearch, Autocomplete, Autocomplete.js 0, InstantSearch Android, InstantSearch iOS, InstantSearch.js, InstantSearch.js 2, InstantSearch.js widget, JavaScript Client, JavaScript Helper, JavaScript Helper 2, React InstantSearch, React InstantSearch Hooks Native, React InstantSearch Native, React InstantSearch widget, Vue InstantSearch, Vue InstantSearch 1, Vue InstantSearch 2, Vue InstantSearch with Vue 3"`;
|
|
11
|
+
exports[`Options with wrong template path throws 1`] = `"The template directory must contain a configuration file \`.template.js\` or must be one of those: Angular InstantSearch, Autocomplete, Autocomplete.js 0, InstantSearch Android, InstantSearch iOS, InstantSearch.js, InstantSearch.js 2, InstantSearch.js widget, JavaScript Client, JavaScript Helper, JavaScript Helper 2, React InstantSearch, React InstantSearch Hooks, React InstantSearch Hooks Native, React InstantSearch Native, React InstantSearch widget, Vue InstantSearch, Vue InstantSearch 1, Vue InstantSearch 2, Vue InstantSearch with Vue 3"`;
|
|
12
12
|
|
|
13
13
|
exports[`Options without path throws 1`] = `"The option \`path\` is required."`;
|
|
14
14
|
|
|
15
|
-
exports[`Options without template throws 1`] = `"The template directory must contain a configuration file \`.template.js\` or must be one of those: Angular InstantSearch, Autocomplete, Autocomplete.js 0, InstantSearch Android, InstantSearch iOS, InstantSearch.js, InstantSearch.js 2, InstantSearch.js widget, JavaScript Client, JavaScript Helper, JavaScript Helper 2, React InstantSearch, React InstantSearch Hooks Native, React InstantSearch Native, React InstantSearch widget, Vue InstantSearch, Vue InstantSearch 1, Vue InstantSearch 2, Vue InstantSearch with Vue 3"`;
|
|
15
|
+
exports[`Options without template throws 1`] = `"The template directory must contain a configuration file \`.template.js\` or must be one of those: Angular InstantSearch, Autocomplete, Autocomplete.js 0, InstantSearch Android, InstantSearch iOS, InstantSearch.js, InstantSearch.js 2, InstantSearch.js widget, JavaScript Client, JavaScript Helper, JavaScript Helper 2, React InstantSearch, React InstantSearch Hooks, React InstantSearch Hooks Native, React InstantSearch Native, React InstantSearch widget, Vue InstantSearch, Vue InstantSearch 1, Vue InstantSearch 2, Vue InstantSearch with Vue 3"`;
|
|
@@ -12,11 +12,14 @@
|
|
|
12
12
|
|
|
13
13
|
<div class="container">
|
|
14
14
|
<ais-instantsearch [config]="config">
|
|
15
|
+
<ais-configure [searchParameters]="{ hitsPerPage: 8 }"></ais-configure>
|
|
15
16
|
<div class="search-panel">
|
|
16
17
|
{{#if attributesForFaceting}}
|
|
17
18
|
<div class="search-panel__filters">
|
|
18
19
|
{{#each attributesForFaceting}}
|
|
19
|
-
<ais-
|
|
20
|
+
<ais-panel header="{{this}}">
|
|
21
|
+
<ais-refinement-list attribute="{{this}}"></ais-refinement-list>
|
|
22
|
+
</ais-panel>
|
|
20
23
|
{{/each}}
|
|
21
24
|
</div>
|
|
22
25
|
|
|
@@ -6,10 +6,9 @@
|
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
|
7
7
|
<meta name="theme-color" content="#000000">
|
|
8
8
|
|
|
9
|
-
<link rel="manifest" href="./manifest.webmanifest">
|
|
10
9
|
<link rel="shortcut icon" href="./favicon.png">
|
|
11
10
|
|
|
12
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/instantsearch.css@7/themes/
|
|
11
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/instantsearch.css@7/themes/satellite-min.css">
|
|
13
12
|
<link rel="stylesheet" href="./src/index.css">
|
|
14
13
|
<link rel="stylesheet" href="./src/app.css">
|
|
15
14
|
|
|
@@ -44,10 +43,9 @@
|
|
|
44
43
|
<div class="search-panel__results">
|
|
45
44
|
<div id="searchbox"></div>
|
|
46
45
|
<div id="hits"></div>
|
|
46
|
+
<div id="pagination"></div>
|
|
47
47
|
</div>
|
|
48
48
|
</div>
|
|
49
|
-
|
|
50
|
-
<div id="pagination"></div>
|
|
51
49
|
</div>
|
|
52
50
|
|
|
53
51
|
<script src="https://cdn.jsdelivr.net/npm/algoliasearch@4.10.5/dist/algoliasearch-lite.umd.js"></script>
|
|
@@ -2,22 +2,16 @@
|
|
|
2
2
|
"name": "{{name}}",
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"private": true,
|
|
5
|
-
"main": "src/app.js",
|
|
6
5
|
"scripts": {
|
|
7
6
|
"start": "parcel index.html --port 3000",
|
|
8
7
|
"build": "parcel build index.html",
|
|
9
|
-
"lint": "eslint .",
|
|
10
|
-
"lint:fix": "
|
|
8
|
+
"lint": "eslint . && prettier --check .",
|
|
9
|
+
"lint:fix": "eslint . --fix && prettier --write ."
|
|
11
10
|
},
|
|
12
11
|
"devDependencies": {
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"eslint-config-prettier": "3.6.0",
|
|
17
|
-
"eslint-plugin-import": "2.19.1",
|
|
18
|
-
"eslint-plugin-prettier": "3.1.2",
|
|
19
|
-
"parcel-bundler": "1.12.5",
|
|
20
|
-
"prettier": "1.19.1"
|
|
12
|
+
"eslint": "8.15.0",
|
|
13
|
+
"parcel": "2.0.1",
|
|
14
|
+
"prettier": "2.6.2"
|
|
21
15
|
},
|
|
22
16
|
"dependencies": {
|
|
23
17
|
"algoliasearch": "4",
|
|
@@ -31,22 +31,26 @@ search.addWidgets([
|
|
|
31
31
|
},
|
|
32
32
|
{{/if}}
|
|
33
33
|
}),
|
|
34
|
-
{{#if flags.dynamicWidgets}}
|
|
35
34
|
instantsearch.widgets.configure({
|
|
36
|
-
|
|
37
|
-
maxValuesPerFacet: 20,
|
|
35
|
+
hitsPerPage: 8,
|
|
38
36
|
}),
|
|
37
|
+
{{#if flags.dynamicWidgets}}
|
|
39
38
|
instantsearch.widgets.dynamicWidgets({
|
|
40
39
|
container: '#dynamic-widgets',
|
|
41
40
|
fallbackWidget({ container, attribute }) {
|
|
42
|
-
return instantsearch.widgets.
|
|
41
|
+
return instantsearch.widgets.panel({ templates: { header: attribute } })(
|
|
42
|
+
instantsearch.widgets.refinementList
|
|
43
|
+
)({
|
|
43
44
|
container,
|
|
44
45
|
attribute,
|
|
45
46
|
});
|
|
46
47
|
},
|
|
47
48
|
widgets: [
|
|
48
49
|
{{#each attributesForFaceting}}
|
|
49
|
-
container =>
|
|
50
|
+
container =>
|
|
51
|
+
instantsearch.widgets.panel({
|
|
52
|
+
templates: { header: '{{this}}' },
|
|
53
|
+
})(instantsearch.widgets.refinementList)({
|
|
50
54
|
container,
|
|
51
55
|
attribute: '{{this}}',
|
|
52
56
|
}),
|
|
@@ -55,7 +59,9 @@ search.addWidgets([
|
|
|
55
59
|
}),
|
|
56
60
|
{{else}}
|
|
57
61
|
{{#each attributesForFaceting}}
|
|
58
|
-
instantsearch.widgets.
|
|
62
|
+
instantsearch.widgets.panel({
|
|
63
|
+
templates: { header: '{{this}}' },
|
|
64
|
+
})(instantsearch.widgets.refinementList)({
|
|
59
65
|
container: '#{{this}}-list',
|
|
60
66
|
attribute: '{{this}}',
|
|
61
67
|
}),
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
Do not use @7 in production, use a complete version like x.x.x, see website for latest version:
|
|
14
14
|
https://www.algolia.com/doc/guides/building-search-ui/installation/react/#load-the-style
|
|
15
15
|
-->
|
|
16
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/instantsearch.css@7/themes/
|
|
16
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/instantsearch.css@7/themes/satellite-min.css">
|
|
17
17
|
|
|
18
18
|
<title>{{name}}</title>
|
|
19
19
|
</head>
|
|
@@ -2,14 +2,16 @@ import React from 'react';
|
|
|
2
2
|
import algoliasearch from 'algoliasearch/lite';
|
|
3
3
|
import {
|
|
4
4
|
InstantSearch,
|
|
5
|
+
Configure,
|
|
5
6
|
Hits,
|
|
6
7
|
SearchBox,
|
|
7
8
|
{{#if flags.dynamicWidgets}}
|
|
8
|
-
Configure,
|
|
9
9
|
DynamicWidgets,
|
|
10
|
+
Panel,
|
|
10
11
|
RefinementList,
|
|
11
12
|
{{else}}
|
|
12
13
|
{{#if attributesForFaceting}}
|
|
14
|
+
Panel,
|
|
13
15
|
RefinementList,
|
|
14
16
|
{{/if}}
|
|
15
17
|
{{/if}}
|
|
@@ -40,18 +42,22 @@ function App() {
|
|
|
40
42
|
|
|
41
43
|
<div className="container">
|
|
42
44
|
<InstantSearch searchClient={searchClient} indexName="{{indexName}}">
|
|
45
|
+
<Configure hitsPerPage={8} />
|
|
43
46
|
<div className="search-panel">
|
|
44
47
|
<div className="search-panel__filters">
|
|
45
48
|
{{#if flags.dynamicWidgets}}
|
|
46
|
-
<Configure facets={['*']} maxValuesPerFacet={20} />
|
|
47
49
|
<DynamicWidgets fallbackWidget={RefinementList}>
|
|
48
50
|
{{#each attributesForFaceting}}
|
|
49
|
-
<
|
|
51
|
+
<Panel header="{{this}}">
|
|
52
|
+
<RefinementList attribute="{{this}}" />
|
|
53
|
+
</Panel>
|
|
50
54
|
{{/each}}
|
|
51
55
|
</DynamicWidgets>
|
|
52
56
|
{{else}}
|
|
53
57
|
{{#each attributesForFaceting}}
|
|
54
|
-
<
|
|
58
|
+
<Panel header="{{this}}">
|
|
59
|
+
<RefinementList attribute="{{this}}" />
|
|
60
|
+
</Panel>
|
|
55
61
|
{{/each}}
|
|
56
62
|
{{/if}}
|
|
57
63
|
</div>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Logs
|
|
2
|
+
logs
|
|
3
|
+
*.log
|
|
4
|
+
npm-debug.log*
|
|
5
|
+
yarn-debug.log*
|
|
6
|
+
yarn-error.log*
|
|
7
|
+
pnpm-debug.log*
|
|
8
|
+
lerna-debug.log*
|
|
9
|
+
|
|
10
|
+
node_modules
|
|
11
|
+
dist
|
|
12
|
+
.parcel-cache
|
|
13
|
+
*.local
|
|
14
|
+
|
|
15
|
+
# Editor directories and files
|
|
16
|
+
.vscode
|
|
17
|
+
.idea
|
|
18
|
+
.DS_Store
|
|
19
|
+
*.suo
|
|
20
|
+
*.ntvs*
|
|
21
|
+
*.njsproj
|
|
22
|
+
*.sln
|
|
23
|
+
*.sw?
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const install = require('../../tasks/node/install');
|
|
2
|
+
const teardown = require('../../tasks/node/teardown');
|
|
3
|
+
|
|
4
|
+
module.exports = {
|
|
5
|
+
category: 'Web',
|
|
6
|
+
libraryName: 'react-instantsearch-hooks-web',
|
|
7
|
+
supportedVersion: '>= 6.0.0 < 7.0.0',
|
|
8
|
+
flags: {
|
|
9
|
+
dynamicWidgets: '>=6.16',
|
|
10
|
+
},
|
|
11
|
+
templateName: 'react-instantsearch-hooks',
|
|
12
|
+
appName: 'react-instantsearch-hooks-app',
|
|
13
|
+
keywords: [
|
|
14
|
+
'algolia',
|
|
15
|
+
'InstantSearch',
|
|
16
|
+
'React',
|
|
17
|
+
'Hooks',
|
|
18
|
+
'react-instantsearch-hooks',
|
|
19
|
+
],
|
|
20
|
+
tasks: {
|
|
21
|
+
install,
|
|
22
|
+
teardown,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# {{name}}
|
|
2
|
+
|
|
3
|
+
_This project was generated with [create-instantsearch-app](https://github.com/algolia/create-instantsearch-app) by [Algolia](https://algolia.com)._
|
|
4
|
+
|
|
5
|
+
## Get started
|
|
6
|
+
|
|
7
|
+
To run this project locally, install the dependencies and run the local server:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm install
|
|
11
|
+
npm start
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Alternatively, you may use [Yarn](https://http://yarnpkg.com/):
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
yarn
|
|
18
|
+
yarn start
|
|
19
|
+
```
|
|
Binary file
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta
|
|
6
|
+
name="viewport"
|
|
7
|
+
content="width=device-width, initial-scale=1, shrink-to-fit=no"
|
|
8
|
+
/>
|
|
9
|
+
|
|
10
|
+
<link rel="shortcut icon" href="favicon.png">
|
|
11
|
+
|
|
12
|
+
<!--
|
|
13
|
+
Do not use @7 in production, use a complete version like x.x.x, see website for latest version:
|
|
14
|
+
https://www.algolia.com/doc/guides/building-search-ui/installation/react/#load-the-style
|
|
15
|
+
-->
|
|
16
|
+
<link
|
|
17
|
+
rel="stylesheet"
|
|
18
|
+
href="https://cdn.jsdelivr.net/npm/instantsearch.css@7/themes/satellite-min.css"
|
|
19
|
+
/>
|
|
20
|
+
|
|
21
|
+
<title>{{name}}</title>
|
|
22
|
+
</head>
|
|
23
|
+
|
|
24
|
+
<body>
|
|
25
|
+
<noscript> You need to enable JavaScript to run this app. </noscript>
|
|
26
|
+
|
|
27
|
+
<div id="root"></div>
|
|
28
|
+
|
|
29
|
+
<script type="module" src="src/index.tsx"></script>
|
|
30
|
+
</body>
|
|
31
|
+
</html>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{name}}",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "parcel build index.html",
|
|
7
|
+
"start": "parcel index.html"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"algoliasearch": "4",
|
|
11
|
+
"instantsearch.js": "4.40.5",
|
|
12
|
+
"react": "17.0.2",
|
|
13
|
+
"react-dom": "17.0.2",
|
|
14
|
+
"react-instantsearch-hooks-web": "{{libraryVersion}}"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@types/react": "17.0.45",
|
|
18
|
+
"parcel": "2.5.0"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
body,
|
|
2
|
+
h1 {
|
|
3
|
+
margin: 0;
|
|
4
|
+
padding: 0;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
body {
|
|
8
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica,
|
|
9
|
+
Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
em {
|
|
13
|
+
background: cyan;
|
|
14
|
+
font-style: normal;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.header {
|
|
18
|
+
display: flex;
|
|
19
|
+
align-items: center;
|
|
20
|
+
min-height: 50px;
|
|
21
|
+
padding: 0.5rem 1rem;
|
|
22
|
+
background-image: linear-gradient(to right, #8e43e7, #00aeff);
|
|
23
|
+
color: #fff;
|
|
24
|
+
margin-bottom: 1rem;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.header a {
|
|
28
|
+
color: #fff;
|
|
29
|
+
text-decoration: none;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.header-title {
|
|
33
|
+
font-size: 1.2rem;
|
|
34
|
+
font-weight: normal;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.header-title::after {
|
|
38
|
+
content: ' ▸ ';
|
|
39
|
+
padding: 0 0.5rem;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.header-subtitle {
|
|
43
|
+
font-size: 1.2rem;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.container {
|
|
47
|
+
max-width: 1200px;
|
|
48
|
+
margin: 0 auto;
|
|
49
|
+
padding: 1rem;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.search-panel {
|
|
53
|
+
display: flex;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.search-panel__filters {
|
|
57
|
+
flex: 1;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.search-panel__results {
|
|
61
|
+
flex: 3;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.searchbox {
|
|
65
|
+
margin-bottom: 2rem;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.pagination {
|
|
69
|
+
margin: 2rem auto;
|
|
70
|
+
text-align: center;
|
|
71
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import algoliasearch from 'algoliasearch/lite';
|
|
2
|
+
import {
|
|
3
|
+
Configure,
|
|
4
|
+
{{#if flags.dynamicWidgets}}
|
|
5
|
+
DynamicWidgets,
|
|
6
|
+
{{#unless attributesForFaceting}}
|
|
7
|
+
RefinementList,
|
|
8
|
+
{{/unless}}
|
|
9
|
+
{{/if}}
|
|
10
|
+
{{#if attributesToDisplay}}
|
|
11
|
+
Highlight,
|
|
12
|
+
{{/if}}
|
|
13
|
+
Hits,
|
|
14
|
+
InstantSearch,
|
|
15
|
+
Pagination,
|
|
16
|
+
{{#if attributesForFaceting}}
|
|
17
|
+
RefinementList,
|
|
18
|
+
{{/if}}
|
|
19
|
+
SearchBox,
|
|
20
|
+
} from 'react-instantsearch-hooks-web';
|
|
21
|
+
|
|
22
|
+
import { Panel } from './Panel';
|
|
23
|
+
|
|
24
|
+
import type { Hit } from 'instantsearch.js';
|
|
25
|
+
|
|
26
|
+
import './App.css';
|
|
27
|
+
|
|
28
|
+
const searchClient = algoliasearch(
|
|
29
|
+
'{{appId}}',
|
|
30
|
+
'{{apiKey}}'
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
export function App() {
|
|
34
|
+
return (
|
|
35
|
+
<div>
|
|
36
|
+
<header className="header">
|
|
37
|
+
<h1 className="header-title">
|
|
38
|
+
<a href="/">{{name}}</a>
|
|
39
|
+
</h1>
|
|
40
|
+
<p className="header-subtitle">
|
|
41
|
+
using{' '}
|
|
42
|
+
<a href="https://github.com/algolia/react-instantsearch">
|
|
43
|
+
React InstantSearch Hooks
|
|
44
|
+
</a>
|
|
45
|
+
</p>
|
|
46
|
+
</header>
|
|
47
|
+
|
|
48
|
+
<div className="container">
|
|
49
|
+
<InstantSearch searchClient={searchClient} indexName="{{indexName}}">
|
|
50
|
+
<Configure hitsPerPage={8} />
|
|
51
|
+
<div className="search-panel">
|
|
52
|
+
<div className="search-panel__filters">
|
|
53
|
+
{{#if flags.dynamicWidgets}}
|
|
54
|
+
<DynamicWidgets fallback={RefinementList}>
|
|
55
|
+
{{#each attributesForFaceting}}
|
|
56
|
+
<Panel header="{{this}}">
|
|
57
|
+
<RefinementList attribute="{{this}}" />
|
|
58
|
+
</Panel>
|
|
59
|
+
{{/each}}
|
|
60
|
+
</DynamicWidgets>
|
|
61
|
+
{{else}}
|
|
62
|
+
{{#each attributesForFaceting}}
|
|
63
|
+
<Panel header="{{this}}">
|
|
64
|
+
<RefinementList attribute="{{this}}" />
|
|
65
|
+
</Panel>
|
|
66
|
+
{{/each}}
|
|
67
|
+
{{/if}}
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
<div className="search-panel__results">
|
|
71
|
+
<SearchBox placeholder="{{searchPlaceholder}}" className="searchbox" />
|
|
72
|
+
<Hits hitComponent={Hit} />
|
|
73
|
+
|
|
74
|
+
<div className="pagination">
|
|
75
|
+
<Pagination />
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
</InstantSearch>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
type HitProps = {
|
|
86
|
+
hit: Hit;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
function Hit({ hit }: HitProps) {
|
|
90
|
+
return (
|
|
91
|
+
<article>
|
|
92
|
+
{{#if attributesToDisplay}}
|
|
93
|
+
<h1>
|
|
94
|
+
<Highlight attribute="{{attributesToDisplay.[0]}}" hit={hit} />
|
|
95
|
+
</h1>
|
|
96
|
+
{{#each attributesToDisplay}}
|
|
97
|
+
{{#unless @first}}
|
|
98
|
+
<p>
|
|
99
|
+
<Highlight attribute="{{this}}" hit={hit} />
|
|
100
|
+
</p>
|
|
101
|
+
{{/unless}}
|
|
102
|
+
{{/each}}
|
|
103
|
+
{{else}}
|
|
104
|
+
<p>
|
|
105
|
+
<code>{JSON.stringify(hit).slice(0, 100)}...</code>
|
|
106
|
+
</p>
|
|
107
|
+
{{/if}}
|
|
108
|
+
</article>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type PanelProps = React.PropsWithChildren<{
|
|
2
|
+
header: string;
|
|
3
|
+
}>;
|
|
4
|
+
|
|
5
|
+
export function Panel({ header, children }: PanelProps) {
|
|
6
|
+
return (
|
|
7
|
+
<div className="ais-Panel">
|
|
8
|
+
<div className="ais-Panel-header">
|
|
9
|
+
<span>{header}</span>
|
|
10
|
+
</div>
|
|
11
|
+
<div className="ais-Panel-body">{children}</div>
|
|
12
|
+
</div>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
@@ -19,8 +19,8 @@ yarn add {{ packageName }}
|
|
|
19
19
|
### Usage
|
|
20
20
|
|
|
21
21
|
```jsx
|
|
22
|
-
import instantsearch from 'instantsearch.js';
|
|
23
22
|
import algoliasearch from 'algoliasearch/lite';
|
|
23
|
+
import { InstantSearch } from 'react-instantsearch-dom';
|
|
24
24
|
import { {{ pascalCaseName }} } from '{{ packageName }}';
|
|
25
25
|
|
|
26
26
|
const searchClient = algoliasearch('appId', 'apiKey');
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"algoliasearch": "4",
|
|
43
43
|
"react": "^16.8.0",
|
|
44
44
|
"react-dom": "^16.8.0",
|
|
45
|
-
"react-instantsearch-dom": "^6.
|
|
45
|
+
"react-instantsearch-dom": "^6.26.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@babel/core": "7.14.3",
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
"@types/node": "15.3.0",
|
|
55
55
|
"@types/react": "17.0.0",
|
|
56
56
|
"@types/react-dom": "17.0.0",
|
|
57
|
+
"@types/react-instantsearch-core": "6.26.0",
|
|
57
58
|
"@types/react-instantsearch-dom": "6.10.0",
|
|
58
59
|
"@typescript-eslint/eslint-plugin": "4.24.0",
|
|
59
60
|
"@typescript-eslint/parser": "4.24.0",
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
+
import type { Connector } from '../types/connector';
|
|
2
|
+
|
|
1
3
|
import { createConnector } from 'react-instantsearch-dom';
|
|
2
4
|
|
|
3
5
|
export type ProvidedProps = {
|
|
4
6
|
// TODO: fill props that are returned by `getProvidedProps`
|
|
5
7
|
}
|
|
6
8
|
|
|
7
|
-
export const connect{{ pascalCaseName }} = createConnector({
|
|
9
|
+
export const connect{{ pascalCaseName }}: Connector<ProvidedProps> = createConnector<ProvidedProps>({
|
|
8
10
|
displayName: '{{ pascalCaseName }}',
|
|
11
|
+
$$type: '{{ widgetType }}',
|
|
9
12
|
|
|
10
|
-
getProvidedProps(props, searchState, searchResults)
|
|
13
|
+
getProvidedProps(props, searchState, searchResults) {
|
|
11
14
|
return {
|
|
12
15
|
// TODO: return a props for the component
|
|
13
16
|
};
|
|
@@ -19,7 +22,7 @@ export const connect{{ pascalCaseName }} = createConnector({
|
|
|
19
22
|
};
|
|
20
23
|
},
|
|
21
24
|
|
|
22
|
-
cleanUp(props, searchState
|
|
25
|
+
cleanUp(props, searchState) {
|
|
23
26
|
return {
|
|
24
27
|
// TODO: return a searchState where this widget is removed from the widget tree
|
|
25
28
|
};
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { {{ pascalCaseName }}Component } from './component';
|
|
2
2
|
import { connect{{ pascalCaseName }} } from './connector';
|
|
3
3
|
|
|
4
|
-
import type { ElementType } from 'react';
|
|
5
|
-
|
|
6
4
|
type WidgetParams = {
|
|
7
5
|
/**
|
|
8
6
|
* Placeholder text for input element.
|
|
@@ -10,5 +8,7 @@ type WidgetParams = {
|
|
|
10
8
|
placeholder?: string;
|
|
11
9
|
};
|
|
12
10
|
|
|
13
|
-
export const {{ pascalCaseName }}: ElementType<WidgetParams> =
|
|
14
|
-
|
|
11
|
+
export const {{ pascalCaseName }}: React.ElementType<WidgetParams> = connect{{ pascalCaseName }}(
|
|
12
|
+
{{ pascalCaseName }}Component,
|
|
13
|
+
{ $$widgetType: '{{ widgetType }}' }
|
|
14
|
+
);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ConnectedComponentClass,
|
|
3
|
+
ConnectorProvided,
|
|
4
|
+
} from 'react-instantsearch-core';
|
|
5
|
+
|
|
6
|
+
type AdditionalWidgetProperties = {
|
|
7
|
+
$$widgetType?: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type Connector<TProvided = {}, TExposed = {}> = ((
|
|
11
|
+
stateless: React.FunctionComponent<ConnectorProvided<TProvided>>,
|
|
12
|
+
additionalWidgetProperties: AdditionalWidgetProperties
|
|
13
|
+
) => React.ComponentClass<TExposed>) &
|
|
14
|
+
(<TProps extends Partial<ConnectorProvided<TProvided>>>(
|
|
15
|
+
Composed: React.ComponentType<TProps>,
|
|
16
|
+
additionalWidgetProperties: AdditionalWidgetProperties
|
|
17
|
+
) => ConnectedComponentClass<TProps, ConnectorProvided<TProvided>, TExposed>);
|