diff --git a/.babelrc b/.babelrc index 73ec7b8a50..828d18b3c3 100644 --- a/.babelrc +++ b/.babelrc @@ -1,30 +1,54 @@ { "env": { - "test": { + "development": { "presets": [ - ["env", {"targets": { "node": "current" }}], + [ + "env", + { + "targets": { + "browsers": ["last 2 versions", "ie >= 9"] + } + } + ], "react", "stage-2" ], "plugins": [ - "babel-plugin-rewire", - ["module-resolver", { - "alias": { - "preact-compat": "react" - } - }] + "transform-react-remove-prop-types", + "transform-react-constant-elements", + "transform-react-pure-class-to-function" ] }, - "development": { + "production": { "presets": [ - ["env", { "targets": { "browsers": ["last 2 versions", "ie >= 10"] } }], + [ + "env", + { + "targets": { + "browsers": ["last 2 versions", "ie >= 9"] + } + } + ], "react", "stage-2" + ], + "plugins": [ + "transform-react-remove-prop-types", + "transform-react-constant-elements", + "transform-react-pure-class-to-function" ] }, - "production": { + "umd": { "presets": [ - ["env", { "targets": { "browsers": ["last 2 versions", "ie >= 10"] } }], + [ + "env", + { + "modules": false, + "targets": { + "browsers": ["last 2 versions", "ie >= 9"] + } + } + ], "react", "stage-2" ], @@ -34,16 +58,86 @@ "transform-react-pure-class-to-function" ] }, - "production-es6": { + "cjs": { "presets": [ - ["env", { "modules": false, "targets": { "browsers": ["last 2 versions", "ie >= 10"] } }], + [ + "env", + { + "targets": { + "browsers": ["last 2 versions", "ie >= 9"] + } + } + ], "react", "stage-2" ], "plugins": [ "transform-react-remove-prop-types", "transform-react-constant-elements", - "transform-react-pure-class-to-function" + "transform-react-pure-class-to-function", + [ + "inline-replace-variables", + { + "__DEV__": { + "type": "node", + "replacement": "process.env.NODE_ENV === 'development'" + } + } + ] + ] + }, + "es": { + "presets": [ + [ + "env", + { + "modules": false, + "targets": { + "browsers": ["last 2 versions", "ie >= 9"] + } + } + ], + "react", + "stage-2" + ], + "plugins": [ + "transform-react-remove-prop-types", + "transform-react-constant-elements", + "transform-react-pure-class-to-function", + [ + "inline-replace-variables", + { + "__DEV__": { + "type": "node", + "replacement": "process.env.NODE_ENV === 'development'" + } + } + ] + ] + }, + "test": { + "presets": [ + [ + "env", + { + "targets": { + "node": "current" + } + } + ], + "react", + "stage-2" + ], + "plugins": [ + "rewire", + [ + "module-resolver", + { + "alias": { + "preact-compat": "react" + } + } + ] ] } } diff --git a/.eslintignore b/.eslintignore index 58076091b2..63f778131d 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,7 +1,7 @@ -dist/ -dist-es5-module/ +/dist +/cjs +/es +/docgen docs/ docs.old/ -docgen/ node_modules/ -es/ diff --git a/.eslintrc.js b/.eslintrc.js index 732d0fe599..bdf9cfa2d3 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,8 +1,11 @@ module.exports = { extends: ['algolia', 'algolia/jest', 'algolia/react'], rules: { - "no-param-reassign": 0, - "import/no-extraneous-dependencies": 0, - "react/no-string-refs": 1 - } -} + 'no-param-reassign': 0, + 'import/no-extraneous-dependencies': 0, + 'react/no-string-refs': 1, + }, + globals: { + __DEV__: false, + }, +}; diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 7ae2e61533..6dabbe5551 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -17,11 +17,11 @@ Demonstrate the code is solid. Example: The exact commands you ran and their output, screenshots / videos if the pull request changes UI. - + You will be able to test out these changes on the deploy - preview (address will be commented by a bot): - + preview (address will be commented by a bot): + 1. the documentation site (/) - 2. a widget playground (/dev-novel) + 2. a widget playground (/stories) --> diff --git a/.gitignore b/.gitignore index 1eaafa8fc3..57db9c8fb8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,17 @@ node_modules/ -dist/ -dist-es5-module/ +!scripts/docs/ npm-debug.log +yarn-error.log .DS_Store -docs/ -!scripts/docs/ -# Ignore staging build files -dev/dist/* +# Bundle build files +/dist +/cjs +/es -# Ignore Argos CI screenshots. -functional-tests/screenshots/ +# Generated files +/docs +/storybook/dist/* -# Ignore ES6 build files -es/ - -yarn-error.log +# Argos CI screenshots +/functional-tests/screenshots/ diff --git a/.npmignore b/.npmignore deleted file mode 100644 index fb55ddc16f..0000000000 --- a/.npmignore +++ /dev/null @@ -1,6 +0,0 @@ -# we do not want to lock down dependencies when used as an npm dependency, -# only when we build -docs/ -dev/ -scripts/ -**/__tests__/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9cfe01e40f..cc89dd10c8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -25,7 +25,7 @@ don't hesitate to leave a message on the [community forum](https://discourse.alg - [Folders of the project](#folders-of-the-project) - [The source folder](#the-source-folder) - [The documentation source](#the-documentation-source) - - [The dev app](#the-dev-app) + - [The storybook source](#the-storybook-source) - [Tests](#tests) - [Unit tests](#unit-tests) - [Functional tests](#functional-tests) @@ -71,9 +71,9 @@ On it you can find: 1. The generated documentation: https://**deploy-url-netlify**/ - for example: https://deploy-preview-2383--algolia-instantsearch.netlify.com/ - source: https://github.com/algolia/instantsearch.js/tree/develop/docgen -2. A playground for the widgets: https://**deploy-url-netlify**/v2/dev-novel - - for example: https://deploy-preview-3102--algolia-instantsearch.netlify.com/v2/dev-novel - - source: https://github.com/algolia/instantsearch.js/tree/develop/dev +2. A playground for the widgets: https://**deploy-url-netlify**/stories + - for example: https://deploy-preview-3102--algolia-instantsearch.netlify.com/stories + - source: https://github.com/algolia/instantsearch.js/tree/develop/storybook ## Commit conventions @@ -157,15 +157,13 @@ And also relaunch the dev environement afterwards. Here are the main files and folders of the project. ``` -▸ dev/ << the dev app source ▸ docgen/ << the documentation source ▸ functional-tests/ << the functional tests ▸ scripts/ << the scripts for maintaining the project ▸ src/ << the source of the library +▸ storybook/ << the storybook source CHANGELOG.md << the autogenerated changelog (based on commits) CONTRIBUTING.md << this file - index.es6.js << the root js file for the ES6 module - index.js << the root js file for the bundle package.json << the definition of the project README.md << the introduction of the project ``` @@ -177,9 +175,9 @@ Here are the main files and folders of the project. ▸ components/ << The pReact components for the UI of our widgets (UI) ▸ connectors/ << The source of all the connectors (UX without UI) ▸ css/ << The source of the themes (reset / algolia theme) - ▸ decorators/ << Preact HoC that factorize some behaviour of the widgets ▸ lib/ << The core of the library, instantsearch, url ▸ widgets/ << The source of the widgets (UX + UI) + ▸ helpers/ << The source of the method helpers ``` ### The documentation source @@ -206,18 +204,15 @@ Here are the main files and folders of the project. webpack.config.start.babel.js << dev webpack config ``` -### The dev app +### The storybook source ``` -▾ dev/ +▾ storybook/ ▾ app/ << the source of the dev app - ▸ custom-widgets/ << the source of the custom widgets to validate the connector API - ▸ templates/ << templates used for the common widgets + ▸ builtin/ << templates used for built-in widgets + ▸ utils/ << utility functions to build stories index.js << main script of the dev app - init-builtin-widgets.js << initialization of the IS.js app with built-in widgets - init-jquery-widgets.js << initialization of the IS.js app with custom widget / jQuery - init-vanilla-widgets.js << initialization of the IS.js app with other custom widgets - wrap-with-hits.js << utility source that adds a hits and searchbox for each story + init-unmount-widgets.js << initialization of the IS.js app with unmountable widgets style.css template.html webpack.config.js @@ -292,8 +287,8 @@ Update the config of the dev server (instantsearch.js/scripts/dev.sh) so that yo the test page with your VM. **Do not commit this change** ```diff -- webpack-dev-server --config dev/webpack.dev.config.babel.js --hot --inline --no-info & -+ webpack-dev-server --config dev/webpack.dev.config.babel.js --hot --inline --no-info --public [your_ip] & +- webpack-dev-server --config storybook/webpack.dev.config.babel.js --hot --inline --no-info & ++ webpack-dev-server --config storybook/webpack.dev.config.babel.js --hot --inline --no-info --public [your_ip] & ``` Then you should be able debug using the dev setup: `yarn run dev` and the virtual machine. You can also @@ -312,7 +307,7 @@ yarn lint ``` The JS files are validated using a combination of prettier (strict syntax form) and eslint rules (for -common mistakes and patterns). The scss linter uses sass-lint. +common mistakes and patterns). ## Release @@ -330,7 +325,7 @@ npm run release For the maintenance version, go on maintenance (`git checkout maintenance`) and use: ```sh -npm run release-maintenance +npm run release:maintenance ``` **Be sure to use `$ npm run` instead of `$ yarn run` to avoid issues** diff --git a/README.md b/README.md index 39f70e5740..8809de1bae 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@

- InstantSearch.js is a library for building blazing fast search-as-you-type search UIs with Algolia. + InstantSearch.js is a JavaScript library for building performant and instant search experiences with Algolia.

@@ -25,6 +25,7 @@ InstantSearch.js is a vanilla JavaScript library that lets you create an instant - [Why](#why) - [Getting started](#getting-started) +- [Installation](#installation) - [Documentation](#documentation) - [Demos](#demos) - [Playground](#playground) @@ -51,15 +52,14 @@ Using InstantSearch.js is as simple as adding this JavaScript code to your page: ```javascript // 1. Instantiate the search const search = instantsearch({ - appId: 'latency', - apiKey: '6be0576ff61c053d5f9a3225e2a90f76', indexName: 'instant_search', + searchClient: algoliasearch('latency', '6be0576ff61c053d5f9a3225e2a90f76'), }); // 2. Create an interactive search box search.addWidget( instantsearch.widgets.searchBox({ - container: document.querySelector('#searchBox'), + container: '#searchbox', placeholder: 'Search for products', }) ); @@ -67,9 +67,9 @@ search.addWidget( // 3. Plug the search results into the product container search.addWidget( instantsearch.widgets.hits({ - container: document.querySelector('#products'), + container: '#products', templates: { - item: '{{{_highlightResult.name.value}}}', + item: '{{#helpers.highlight}}{ "attribute": "name" }{{/helpers.highlight}}', }, }) ); @@ -77,8 +77,8 @@ search.addWidget( // 4. Make the brands refinable search.addWidget( instantsearch.widgets.refinementList({ - container: document.querySelector('#brand'), - attributeName: 'brand', + container: '#brand', + attribute: 'brand', }) ); @@ -96,6 +96,14 @@ search.start(); To learn more about the library, follow the [getting started](https://community.algolia.com/instantsearch.js/v2/getting-started.html) guide or check how to [add it to your own project](https://community.algolia.com/instantsearch.js/v2/guides/usage.html). +## Installation + +```sh +npm install instantsearch.js algoliasearch +# or +yarn add instantsearch.js algoliasearch +``` + ## Documentation The documentation is available at [community.algolia.com/instantsearch.js](https://community.algolia.com/instantsearch.js). @@ -135,7 +143,7 @@ To start contributing to code, you need to: 1. [Clone the repository](https://help.github.com/articles/cloning-a-repository/) 1. Install the dependencies: `yarn` 1. Run the development mode: `yarn run dev` -1. [Open dev-novel](http://localhost:8080) +1. [Open the stories](http://localhost:8080) Please read [our contribution process](CONTRIBUTING.md) to learn more. @@ -154,7 +162,7 @@ InstantSearch.js is [MIT licensed][license-url]. -[algolia-website]: https://algolia.com +[algolia-website]: https://www.algolia.com/?utm_source=instantsearch.js&utm_campaign=repository [react-instantsearch-github]: https://github.com/algolia/react-instantsearch/ [vue-instantsearch-github]: https://github.com/algolia/vue-instantsearch [instantsearch-android-github]: https://github.com/algolia/instantsearch-android diff --git a/dev/app/builtin/stories/clear-all.stories.js b/dev/app/builtin/stories/clear-all.stories.js deleted file mode 100644 index 9beda8e203..0000000000 --- a/dev/app/builtin/stories/clear-all.stories.js +++ /dev/null @@ -1,64 +0,0 @@ -/* eslint-disable import/default */ - -import { storiesOf } from 'dev-novel'; -import instantsearch from '../../../../index'; -import { wrapWithHits } from '../../utils/wrap-with-hits.js'; - -const stories = storiesOf('ClearAll'); - -export default () => { - stories - .add( - 'default', - wrapWithHits( - container => { - window.search.addWidget( - instantsearch.widgets.clearAll({ - container, - autoHideContainer: false, - }) - ); - }, - { - searchParameters: { - disjunctiveFacetsRefinements: { brand: ['Apple'] }, - disjunctiveFacets: ['brand'], - }, - } - ) - ) - .add( - 'with nothing to clear', - wrapWithHits(container => { - window.search.addWidget( - instantsearch.widgets.clearAll({ - container, - autoHideContainer: false, - }) - ); - }) - ) - .add( - 'with clear refinements and query', - wrapWithHits( - container => { - window.search.addWidget( - instantsearch.widgets.clearAll({ - container, - autoHideContainer: false, - clearsQuery: true, - templates: { - link: 'Clear refinements and query', - }, - }) - ); - }, - { - searchParameters: { - disjunctiveFacetsRefinements: { brand: ['Apple'] }, - disjunctiveFacets: ['brand'], - }, - } - ) - ); -}; diff --git a/dev/app/builtin/stories/current-refined-values.stories.js b/dev/app/builtin/stories/current-refined-values.stories.js deleted file mode 100644 index 8f84521ddd..0000000000 --- a/dev/app/builtin/stories/current-refined-values.stories.js +++ /dev/null @@ -1,139 +0,0 @@ -/* eslint-disable import/default */ - -import { storiesOf } from 'dev-novel'; -import instantsearch from '../../../../index'; -import { wrapWithHits } from '../../utils/wrap-with-hits.js'; - -const stories = storiesOf('CurrentRefinedValues'); - -export default () => { - stories - .add( - 'default', - wrapWithHits( - container => { - window.search.addWidget( - instantsearch.widgets.currentRefinedValues({ container }) - ); - }, - { - searchParameters: { - disjunctiveFacetsRefinements: { brand: ['Apple', 'Samsung'] }, - disjunctiveFacets: ['brand'], - numericRefinements: { price: { '>=': [100] } }, - }, - } - ) - ) - .add( - 'with header', - wrapWithHits( - container => { - window.search.addWidget( - instantsearch.widgets.currentRefinedValues({ - container, - templates: { - header: 'Current refinements', - }, - }) - ); - }, - { - searchParameters: { - disjunctiveFacetsRefinements: { brand: ['Apple', 'Samsung'] }, - disjunctiveFacets: ['brand'], - numericRefinements: { price: { '>=': [100] } }, - }, - } - ) - ) - .add( - 'with header but no refinements', - wrapWithHits(container => { - window.search.addWidget( - instantsearch.widgets.currentRefinedValues({ - container, - autoHideContainer: false, - templates: { - header: 'Current refinements', - }, - }) - ); - }) - ) - .add( - 'with clearsQuery', - wrapWithHits( - container => { - window.search.addWidget( - instantsearch.widgets.currentRefinedValues({ - container, - clearsQuery: true, - }) - ); - }, - { - searchParameters: { - disjunctiveFacetsRefinements: { brand: ['Apple', 'Samsung'] }, - disjunctiveFacets: ['brand'], - numericRefinements: { price: { '>=': [100] } }, - }, - } - ) - ) - .add( - 'with transformed items', - wrapWithHits( - container => { - window.search.addWidget( - instantsearch.widgets.currentRefinedValues({ - container, - clearsQuery: true, - transformItems: items => - items.map(item => ({ - ...item, - name: `${item.name} (transformed)`, - })), - }) - ); - }, - { - searchParameters: { - disjunctiveFacetsRefinements: { brand: ['Apple', 'Samsung'] }, - disjunctiveFacets: ['brand'], - numericRefinements: { price: { '>=': [100] } }, - }, - } - ) - ) - .add( - 'with onlyListedAttributes', - wrapWithHits( - container => { - window.search.addWidget( - instantsearch.widgets.currentRefinedValues({ - container, - onlyListedAttributes: true, - clearsQuery: true, - attributes: [ - { - name: 'brand', - label: 'Brand', - }, - { - name: 'query', - }, - ], - }) - ); - }, - { - searchParameters: { - disjunctiveFacetsRefinements: { brand: ['Apple', 'Samsung'] }, - disjunctiveFacets: ['brand'], - numericRefinements: { price: { '>=': [100] } }, - }, - } - ) - ); -}; diff --git a/dev/app/builtin/stories/hits.stories.js b/dev/app/builtin/stories/hits.stories.js deleted file mode 100644 index 435c3090bc..0000000000 --- a/dev/app/builtin/stories/hits.stories.js +++ /dev/null @@ -1,74 +0,0 @@ -/* eslint-disable import/default */ - -import { storiesOf } from 'dev-novel'; -import instantsearch from '../../../../index'; -import { wrapWithHits } from '../../utils/wrap-with-hits.js'; - -const stories = storiesOf('Hits'); - -export default () => { - stories - .add( - 'default', - wrapWithHits(container => { - window.search.addWidget(instantsearch.widgets.hits({ container })); - }) - ) - .add( - 'with transformed items', - wrapWithHits(container => { - window.search.addWidget( - instantsearch.widgets.hits({ - container, - transformItems: items => - items.map(item => ({ - ...item, - name: `${item.name} (transformed)`, - })), - }) - ); - }) - ) - .add( - 'with highlighted array', - wrapWithHits( - container => { - window.search.addWidget( - instantsearch.widgets.hits({ - container, - escapeHits: true, - templates: { - item: ` -
-
-
- {{{_highlightResult.name.value}}} - \${{price}} - {{rating}} stars -
-
- {{{_highlightResult.type.value}}} -
-
- {{{_highlightResult.description.value}}} -
-
- {{#_highlightResult.tags}} - {{{value}}} - {{/_highlightResult.tags}} -
-
-
- `, - }, - }) - ); - }, - { - appId: 'KY4PR9ORUL', - apiKey: 'a5ca312adab3b79e14054154efa00b37', - indexName: 'highlight_array', - } - ) - ); -}; diff --git a/dev/app/builtin/stories/numeric-refinement-list.stories.js b/dev/app/builtin/stories/numeric-refinement-list.stories.js deleted file mode 100644 index 40bc747bf0..0000000000 --- a/dev/app/builtin/stories/numeric-refinement-list.stories.js +++ /dev/null @@ -1,72 +0,0 @@ -/* eslint-disable import/default */ - -import { storiesOf } from 'dev-novel'; -import instantsearch from '../../../../index'; -import { wrapWithHits } from '../../utils/wrap-with-hits.js'; - -const stories = storiesOf('NumericRefinementList'); - -export default () => { - stories - .add( - 'default', - wrapWithHits(container => { - window.search.addWidget( - instantsearch.widgets.numericRefinementList({ - container, - attributeName: 'price', - operator: 'or', - options: [ - { name: 'All' }, - { end: 4, name: 'less than 4' }, - { start: 4, end: 4, name: '4' }, - { start: 5, end: 10, name: 'between 5 and 10' }, - { start: 10, name: 'more than 10' }, - ], - cssClasses: { - header: 'facet-title', - link: 'facet-value', - count: 'facet-count pull-right', - active: 'facet-active', - }, - templates: { - header: 'Numeric refinement list (price)', - }, - }) - ); - }) - ) - .add( - 'with transformed hits', - wrapWithHits(container => { - window.search.addWidget( - instantsearch.widgets.numericRefinementList({ - container, - attributeName: 'price', - operator: 'or', - options: [ - { name: 'All' }, - { end: 4, name: 'less than 4' }, - { start: 4, end: 4, name: '4' }, - { start: 5, end: 10, name: 'between 5 and 10' }, - { start: 10, name: 'more than 10' }, - ], - cssClasses: { - header: 'facet-title', - link: 'facet-value', - count: 'facet-count pull-right', - active: 'facet-active', - }, - templates: { - header: 'Numeric refinement list (price)', - }, - transformItems: items => - items.map(item => ({ - ...item, - label: `${item.label} (transformed)`, - })), - }) - ); - }) - ); -}; diff --git a/dev/app/builtin/stories/numeric-selector.stories.js b/dev/app/builtin/stories/numeric-selector.stories.js deleted file mode 100644 index ad9ad21f36..0000000000 --- a/dev/app/builtin/stories/numeric-selector.stories.js +++ /dev/null @@ -1,73 +0,0 @@ -/* eslint-disable import/default */ - -import { storiesOf } from 'dev-novel'; -import instantsearch from '../../../../index'; -import { wrapWithHits } from '../../utils/wrap-with-hits.js'; - -const stories = storiesOf('NumericSelector'); - -export default () => { - stories.add( - 'default', - wrapWithHits(container => { - window.search.addWidget( - instantsearch.widgets.numericSelector({ - container, - operator: '>=', - attributeName: 'popularity', - options: [ - { label: 'Default', value: 0 }, - { label: 'Top 10', value: 21459 }, - { label: 'Top 100', value: 21369 }, - { label: 'Top 500', value: 20969 }, - ], - }) - ); - }) - ); - stories.add( - 'with default value', - wrapWithHits(container => { - window.search.addWidget( - instantsearch.widgets.numericSelector({ - container, - operator: '=', - attributeName: 'rating', - options: [ - { label: 'No rating selected', value: undefined }, - { label: 'Rating: 5', value: 5 }, - { label: 'Rating: 4', value: 4 }, - { label: 'Rating: 3', value: 3 }, - { label: 'Rating: 2', value: 2 }, - { label: 'Rating: 1', value: 1 }, - ], - }) - ); - }) - ); - stories.add( - 'with transformed items', - wrapWithHits(container => { - window.search.addWidget( - instantsearch.widgets.numericSelector({ - container, - operator: '=', - attributeName: 'rating', - options: [ - { label: 'No rating selected', value: undefined }, - { label: 'Rating: 5', value: 5 }, - { label: 'Rating: 4', value: 4 }, - { label: 'Rating: 3', value: 3 }, - { label: 'Rating: 2', value: 2 }, - { label: 'Rating: 1', value: 1 }, - ], - transformItems: items => - items.map(item => ({ - ...item, - label: `${item.label} (transformed)`, - })), - }) - ); - }) - ); -}; diff --git a/dev/app/builtin/stories/pagination.stories.js b/dev/app/builtin/stories/pagination.stories.js deleted file mode 100644 index 8acbf96ff5..0000000000 --- a/dev/app/builtin/stories/pagination.stories.js +++ /dev/null @@ -1,44 +0,0 @@ -/* eslint-disable import/default */ - -import { storiesOf } from 'dev-novel'; -import instantsearch from '../../../../index'; -import { wrapWithHits } from '../../utils/wrap-with-hits.js'; - -const stories = storiesOf('Pagination'); - -export default () => { - stories - .add( - 'default', - wrapWithHits(container => { - window.search.addWidget( - instantsearch.widgets.pagination({ - container, - maxPages: 20, - }) - ); - }) - ) - .add( - 'with padding', - wrapWithHits(container => { - window.search.addWidget( - instantsearch.widgets.pagination({ - container, - padding: 6, - }) - ); - }) - ) - .add( - 'without autoHideContainer', - wrapWithHits(container => { - window.search.addWidget( - instantsearch.widgets.pagination({ - container, - autoHideContainer: false, - }) - ); - }) - ); -}; diff --git a/dev/app/builtin/stories/price-ranges.stories.js b/dev/app/builtin/stories/price-ranges.stories.js deleted file mode 100644 index 2cbbf7b4fb..0000000000 --- a/dev/app/builtin/stories/price-ranges.stories.js +++ /dev/null @@ -1,24 +0,0 @@ -/* eslint-disable import/default */ - -import { storiesOf } from 'dev-novel'; -import instantsearch from '../../../../index'; -import { wrapWithHits } from '../../utils/wrap-with-hits.js'; - -const stories = storiesOf('PriceRanges'); - -export default () => { - stories.add( - 'default', - wrapWithHits(container => { - window.search.addWidget( - instantsearch.widgets.priceRanges({ - container, - attributeName: 'price', - templates: { - header: 'Price ranges', - }, - }) - ); - }) - ); -}; diff --git a/dev/app/builtin/stories/sort-by-selector.stories.js b/dev/app/builtin/stories/sort-by-selector.stories.js deleted file mode 100644 index cbdc3df1a3..0000000000 --- a/dev/app/builtin/stories/sort-by-selector.stories.js +++ /dev/null @@ -1,46 +0,0 @@ -/* eslint-disable import/default */ - -import { storiesOf } from 'dev-novel'; -import instantsearch from '../../../../index'; -import { wrapWithHits } from '../../utils/wrap-with-hits.js'; - -const stories = storiesOf('SortBySelector'); - -export default () => { - stories - .add( - 'default', - wrapWithHits(container => { - window.search.addWidget( - instantsearch.widgets.sortBySelector({ - container, - indices: [ - { name: 'instant_search', label: 'Most relevant' }, - { name: 'instant_search_price_asc', label: 'Lowest price' }, - { name: 'instant_search_price_desc', label: 'Highest price' }, - ], - }) - ); - }) - ) - .add( - 'with transformed items', - wrapWithHits(container => { - window.search.addWidget( - instantsearch.widgets.sortBySelector({ - container, - indices: [ - { name: 'instant_search', label: 'Most relevant' }, - { name: 'instant_search_price_asc', label: 'Lowest price' }, - { name: 'instant_search_price_desc', label: 'Highest price' }, - ], - transformItems: items => - items.map(item => ({ - ...item, - label: `${item.label} (transformed)`, - })), - }) - ); - }) - ); -}; diff --git a/dev/app/builtin/stories/star-rating.stories.js b/dev/app/builtin/stories/star-rating.stories.js deleted file mode 100644 index 6f779e8847..0000000000 --- a/dev/app/builtin/stories/star-rating.stories.js +++ /dev/null @@ -1,28 +0,0 @@ -/* eslint-disable import/default */ - -import { storiesOf } from 'dev-novel'; -import instantsearch from '../../../../index'; -import { wrapWithHits } from '../../utils/wrap-with-hits.js'; - -const stories = storiesOf('StarRating'); - -export default () => { - stories.add( - 'default', - wrapWithHits(container => { - window.search.addWidget( - instantsearch.widgets.starRating({ - container, - attributeName: 'rating', - max: 5, - labels: { - andUp: '& Up', - }, - templates: { - header: 'Rating', - }, - }) - ); - }) - ); -}; diff --git a/dev/app/builtin/stories/toggle.stories.js b/dev/app/builtin/stories/toggle.stories.js deleted file mode 100644 index efa19a6fab..0000000000 --- a/dev/app/builtin/stories/toggle.stories.js +++ /dev/null @@ -1,45 +0,0 @@ -/* eslint-disable import/default */ - -import { storiesOf } from 'dev-novel'; -import instantsearch from '../../../../index'; -import { wrapWithHits } from '../../utils/wrap-with-hits.js'; - -const stories = storiesOf('Toggle'); - -export default () => { - stories - .add( - 'default', - wrapWithHits(container => { - window.search.addWidget( - instantsearch.widgets.toggle({ - container, - attributeName: 'free_shipping', - label: 'Free Shipping (toggle single value)', - templates: { - header: 'Shipping', - }, - }) - ); - }) - ) - .add( - 'with on & off values', - wrapWithHits(container => { - window.search.addWidget( - instantsearch.widgets.toggle({ - container, - attributeName: 'brand', - label: 'Canon (not checked) or sony (checked)', - values: { - on: 'Sony', - off: 'Canon', - }, - templates: { - header: 'Google or amazon (toggle two values)', - }, - }) - ); - }) - ); -}; diff --git a/dev/app/jquery/init-stories.js b/dev/app/jquery/init-stories.js deleted file mode 100644 index 617c243bad..0000000000 --- a/dev/app/jquery/init-stories.js +++ /dev/null @@ -1,39 +0,0 @@ -import initClearAllStories from './stories/clear-all.stories'; -import initCurrentRefinedValuesStories from './stories/current-refined-values.stories'; -import initHierarchicalMenuStories from './stories/hierarchical-menu.stories'; -import initHitsStories from './stories/hits.stories'; -import initHitsPerPageSelectorStories from './stories/hits-per-page-selector.stories'; -import initInfiniteHitsStories from './stories/infinite-hits.stories'; -import initMenuStories from './stories/menu.stories'; -import initNumericRefinementListStories from './stories/numeric-refinement-list.stories'; -import initNumericSelectorStories from './stories/numeric-selector.stories'; -import initPaginationStories from './stories/pagination.stories'; -import initPriceRangesStories from './stories/price-ranges.stories'; -import initRefinementListStories from './stories/refinement-list.stories'; -import initSearchBoxStories from './stories/search-box.stories'; -import initSortBySelectorStories from './stories/sort-by-selector.stories'; -import initStarRatingStories from './stories/star-rating.stories'; -import initStatsStories from './stories/stats.stories'; -import initToggleStories from './stories/toggle.stories'; -import initAutcompleteStories from './stories/autocomplete.stories'; - -export default () => { - initClearAllStories(); - initCurrentRefinedValuesStories(); - initHierarchicalMenuStories(); - initHitsStories(); - initHitsPerPageSelectorStories(); - initInfiniteHitsStories(); - initMenuStories(); - initNumericRefinementListStories(); - initNumericSelectorStories(); - initPaginationStories(); - initPriceRangesStories(); - initRefinementListStories(); - initSearchBoxStories(); - initSortBySelectorStories(); - initStarRatingStories(); - initStatsStories(); - initToggleStories(); - initAutcompleteStories(); -}; diff --git a/dev/app/jquery/stories/autocomplete.stories.js b/dev/app/jquery/stories/autocomplete.stories.js deleted file mode 100644 index a50b80f007..0000000000 --- a/dev/app/jquery/stories/autocomplete.stories.js +++ /dev/null @@ -1,208 +0,0 @@ -/* eslint-disable import/default */ - -import { action, storiesOf } from 'dev-novel'; - -import instantsearch from '../../../../index.js'; -import { wrapWithHitsAndJquery } from '../../utils/wrap-with-hits.js'; - -const stories = storiesOf('Autocomplete'); - -// Widget to search into brands, select one and set it as query -const autocompleteBrands = instantsearch.connectors.connectAutocomplete( - ({ indices, refine, widgetParams: { containerNode } }, isFirstRendering) => { - if (isFirstRendering) { - containerNode.html(` - Search for a brand: - - `); - - containerNode.find('select').selectize({ - options: [], - - valueField: 'brand', - labelField: 'brand', - searchField: 'brand', - - highlight: false, - - onType: refine, - - onChange: refine, - }); - } - - if (!isFirstRendering && indices[0].results) { - const autocompleteInstance = containerNode.find('select')[0].selectize; - - indices[0].results.hits.forEach(h => autocompleteInstance.addOption(h)); - autocompleteInstance.refreshOptions(autocompleteInstance.isOpen); - } - } -); - -// widget to search into hits, select a choice open a new page (event example) -const autocompleteAndSelect = instantsearch.connectors.connectAutocomplete( - ({ indices, refine, widgetParams: { containerNode } }, isFirstRendering) => { - const onItemSelected = objectID => { - const item = indices.reduce((match, index) => { - if (match) return match; - return index.hits.find(obj => obj.objectID === objectID); - }, null); - - action('item:selected')(item); - }; - - if (isFirstRendering) { - containerNode.html(` - Search for anything: - - `); - - containerNode.find('select').selectize({ - options: [], - - valueField: 'objectID', - labelField: 'name', - searchField: ['name', 'brand', 'categories', 'description'], - - render: { - option: item => ` -
-
- -
- -
-
- ${item._highlightResult.name.value} - ${item.price_formatted} - ${item.rating} stars -
- -
- ${item._highlightResult.type.value} -
- -
- ${item._highlightResult.description.value} -
-
-
- `, - }, - - highlight: false, - onType: refine, - - onChange: onItemSelected, - }); - - // HACK: bind `autocompleteInstance.search` with an empty query so it returns - // all the hits sent by Algolia - const autocompleteInstance = containerNode.find('select')[0].selectize; - autocompleteInstance.search.bind(autocompleteInstance, ''); - } - - if (!isFirstRendering && indices[0].results) { - const autocompleteInstance = containerNode.find('select')[0].selectize; - - // first clear options - autocompleteInstance.clearOptions(); - // add new ones - indices[0].results.hits.forEach(h => autocompleteInstance.addOption(h)); - // refresh the view - autocompleteInstance.refreshOptions(autocompleteInstance.isOpen); - } - } -); - -const multiIndex = instantsearch.connectors.connectAutocomplete( - ( - { indices, currentRefinement, widgetParams: { containerNode } }, - isFirstRendering - ) => { - if (isFirstRendering) { - containerNode.append(` -
-
-
- -
-
- -
-
- `); - } - - // display hits - indices.forEach(({ hits }, index) => { - const hitsHTML = - hits.length === 0 - ? `No results for query ${currentRefinement}` - : hits.map( - hit => ` -
-
- -
- -
-
- ${hit._highlightResult.name.value} -
- -
- ${hit._highlightResult.type.value} -
-
-
- ` - ); - - containerNode.find(`#hits${index}`).html(hitsHTML); - }); - } -); - -export default () => { - stories - .add( - 'default', - wrapWithHitsAndJquery(containerNode => { - window.search.addWidget(autocompleteBrands({ containerNode })); - }) - ) - .add( - 'Autcomplete into hits', - wrapWithHitsAndJquery(containerNode => - window.search.addWidget(autocompleteAndSelect({ containerNode })) - ) - ) - .add( - 'Multi index', - wrapWithHitsAndJquery(containerNode => { - containerNode.append(''); - window.search.addWidget( - instantsearch.widgets.searchBox({ - container: '#multi-index-search-box', - placeholder: 'Search into the two indices', - poweredBy: false, - autofocus: false, - }) - ); - window.search.addWidget( - multiIndex({ - containerNode, - indices: [{ label: 'instant_search', value: 'instant_search' }], - }) - ); - }) - ); -}; diff --git a/dev/app/jquery/stories/clear-all.stories.js b/dev/app/jquery/stories/clear-all.stories.js deleted file mode 100644 index a7f287a518..0000000000 --- a/dev/app/jquery/stories/clear-all.stories.js +++ /dev/null @@ -1,14 +0,0 @@ -import { storiesOf } from 'dev-novel'; -import { wrapWithHitsAndJquery } from '../../utils/wrap-with-hits.js'; -import * as widgets from '../widgets/index.js'; - -const stories = storiesOf('ClearAll'); - -export default () => { - stories.add( - 'default', - wrapWithHitsAndJquery(containerNode => { - window.search.addWidget(widgets.clearAll({ containerNode })); - }) - ); -}; diff --git a/dev/app/jquery/stories/current-refined-values.stories.js b/dev/app/jquery/stories/current-refined-values.stories.js deleted file mode 100644 index c8288c79a6..0000000000 --- a/dev/app/jquery/stories/current-refined-values.stories.js +++ /dev/null @@ -1,14 +0,0 @@ -import { storiesOf } from 'dev-novel'; -import { wrapWithHitsAndJquery } from '../../utils/wrap-with-hits.js'; -import * as widgets from '../widgets/index.js'; - -const stories = storiesOf('CurrentRefinedValues'); - -export default () => { - stories.add( - 'default', - wrapWithHitsAndJquery(containerNode => { - window.search.addWidget(widgets.currentRefinedValues({ containerNode })); - }) - ); -}; diff --git a/dev/app/jquery/stories/hierarchical-menu.stories.js b/dev/app/jquery/stories/hierarchical-menu.stories.js deleted file mode 100644 index c5d31cc142..0000000000 --- a/dev/app/jquery/stories/hierarchical-menu.stories.js +++ /dev/null @@ -1,23 +0,0 @@ -import { storiesOf } from 'dev-novel'; -import { wrapWithHitsAndJquery } from '../../utils/wrap-with-hits.js'; -import * as widgets from '../widgets/index.js'; - -const stories = storiesOf('HierarchicalMenu'); - -export default () => { - stories.add( - 'default', - wrapWithHitsAndJquery(containerNode => { - window.search.addWidget( - widgets.hierarchicalMenu({ - containerNode, - attributes: [ - 'hierarchicalCategories.lvl0', - 'hierarchicalCategories.lvl1', - 'hierarchicalCategories.lvl2', - ], - }) - ); - }) - ); -}; diff --git a/dev/app/jquery/stories/hits-per-page-selector.stories.js b/dev/app/jquery/stories/hits-per-page-selector.stories.js deleted file mode 100644 index 03d9d5dd7b..0000000000 --- a/dev/app/jquery/stories/hits-per-page-selector.stories.js +++ /dev/null @@ -1,23 +0,0 @@ -import { storiesOf } from 'dev-novel'; -import { wrapWithHitsAndJquery } from '../../utils/wrap-with-hits.js'; -import * as widgets from '../widgets/index.js'; - -const stories = storiesOf('HitsPerPageSelector'); - -export default () => { - stories.add( - 'default', - wrapWithHitsAndJquery(containerNode => { - window.search.addWidget( - widgets.hitsPerPageSelector({ - containerNode, - items: [ - { value: 3, label: '3 per page' }, - { value: 5, label: '5 per page' }, - { value: 10, label: '10 per page' }, - ], - }) - ); - }) - ); -}; diff --git a/dev/app/jquery/stories/hits.stories.js b/dev/app/jquery/stories/hits.stories.js deleted file mode 100644 index ca28484484..0000000000 --- a/dev/app/jquery/stories/hits.stories.js +++ /dev/null @@ -1,14 +0,0 @@ -import { storiesOf } from 'dev-novel'; -import { wrapWithHitsAndJquery } from '../../utils/wrap-with-hits.js'; -import * as widgets from '../widgets/index.js'; - -const stories = storiesOf('Hits'); - -export default () => { - stories.add( - 'default', - wrapWithHitsAndJquery(containerNode => { - window.search.addWidget(widgets.hits({ containerNode })); - }) - ); -}; diff --git a/dev/app/jquery/stories/infinite-hits.stories.js b/dev/app/jquery/stories/infinite-hits.stories.js deleted file mode 100644 index 2c74770b82..0000000000 --- a/dev/app/jquery/stories/infinite-hits.stories.js +++ /dev/null @@ -1,14 +0,0 @@ -import { storiesOf } from 'dev-novel'; -import { wrapWithHitsAndJquery } from '../../utils/wrap-with-hits.js'; -import * as widgets from '../widgets/index.js'; - -const stories = storiesOf('InfiniteHits'); - -export default () => { - stories.add( - 'default', - wrapWithHitsAndJquery(containerNode => { - window.search.addWidget(widgets.infiniteHits({ containerNode })); - }) - ); -}; diff --git a/dev/app/jquery/stories/menu.stories.js b/dev/app/jquery/stories/menu.stories.js deleted file mode 100644 index 4e73b49be9..0000000000 --- a/dev/app/jquery/stories/menu.stories.js +++ /dev/null @@ -1,34 +0,0 @@ -import { storiesOf } from 'dev-novel'; -import { wrapWithHitsAndJquery } from '../../utils/wrap-with-hits.js'; -import * as widgets from '../widgets/index.js'; - -const stories = storiesOf('Menu'); - -export default () => { - stories - .add( - 'default', - wrapWithHitsAndJquery(containerNode => { - window.search.addWidget( - widgets.menu({ - containerNode, - attributeName: 'categories', - limit: 3, - }) - ); - }) - ) - .add( - 'with show more', - wrapWithHitsAndJquery(containerNode => { - window.search.addWidget( - widgets.showMoreMenu({ - containerNode, - attributeName: 'categories', - limit: 3, - showMoreLimit: 10, - }) - ); - }) - ); -}; diff --git a/dev/app/jquery/stories/numeric-refinement-list.stories.js b/dev/app/jquery/stories/numeric-refinement-list.stories.js deleted file mode 100644 index 3698e56559..0000000000 --- a/dev/app/jquery/stories/numeric-refinement-list.stories.js +++ /dev/null @@ -1,27 +0,0 @@ -import { storiesOf } from 'dev-novel'; -import { wrapWithHitsAndJquery } from '../../utils/wrap-with-hits.js'; -import * as widgets from '../widgets/index.js'; - -const stories = storiesOf('NumericRefinementList'); - -export default () => { - stories.add( - 'default', - wrapWithHitsAndJquery(containerNode => { - window.search.addWidget( - widgets.numericRefinementList({ - containerNode, - attributeName: 'price', - operator: 'or', - options: [ - { name: 'All' }, - { end: 4, name: 'less than 4' }, - { start: 4, end: 4, name: '4' }, - { start: 5, end: 10, name: 'between 5 and 10' }, - { start: 10, name: 'more than 10' }, - ], - }) - ); - }) - ); -}; diff --git a/dev/app/jquery/stories/numeric-selector.stories.js b/dev/app/jquery/stories/numeric-selector.stories.js deleted file mode 100644 index 89145836f9..0000000000 --- a/dev/app/jquery/stories/numeric-selector.stories.js +++ /dev/null @@ -1,26 +0,0 @@ -import { storiesOf } from 'dev-novel'; -import { wrapWithHitsAndJquery } from '../../utils/wrap-with-hits.js'; -import * as widgets from '../widgets/index.js'; - -const stories = storiesOf('NumericSelector'); - -export default () => { - stories.add( - 'default', - wrapWithHitsAndJquery(containerNode => { - window.search.addWidget( - widgets.numericSelector({ - containerNode, - operator: '>=', - attributeName: 'popularity', - options: [ - { label: 'Default', value: 0 }, - { label: 'Top 10', value: 9991 }, - { label: 'Top 100', value: 9901 }, - { label: 'Top 500', value: 9501 }, - ], - }) - ); - }) - ); -}; diff --git a/dev/app/jquery/stories/pagination.stories.js b/dev/app/jquery/stories/pagination.stories.js deleted file mode 100644 index 8f59102c7b..0000000000 --- a/dev/app/jquery/stories/pagination.stories.js +++ /dev/null @@ -1,19 +0,0 @@ -import { storiesOf } from 'dev-novel'; -import { wrapWithHitsAndJquery } from '../../utils/wrap-with-hits.js'; -import * as widgets from '../widgets/index.js'; - -const stories = storiesOf('Pagination'); - -export default () => { - stories.add( - 'default', - wrapWithHitsAndJquery(containerNode => { - window.search.addWidget( - widgets.pagination({ - containerNode, - maxPages: 20, - }) - ); - }) - ); -}; diff --git a/dev/app/jquery/stories/price-ranges.stories.js b/dev/app/jquery/stories/price-ranges.stories.js deleted file mode 100644 index bb78d233b1..0000000000 --- a/dev/app/jquery/stories/price-ranges.stories.js +++ /dev/null @@ -1,19 +0,0 @@ -import { storiesOf } from 'dev-novel'; -import { wrapWithHitsAndJquery } from '../../utils/wrap-with-hits.js'; -import * as widgets from '../widgets/index.js'; - -const stories = storiesOf('PriceRanges'); - -export default () => { - stories.add( - 'default', - wrapWithHitsAndJquery(containerNode => { - window.search.addWidget( - widgets.priceRanges({ - containerNode, - attributeName: 'price', - }) - ); - }) - ); -}; diff --git a/dev/app/jquery/stories/refinement-list.stories.js b/dev/app/jquery/stories/refinement-list.stories.js deleted file mode 100644 index 14dc8dddff..0000000000 --- a/dev/app/jquery/stories/refinement-list.stories.js +++ /dev/null @@ -1,22 +0,0 @@ -import { storiesOf } from 'dev-novel'; -import { wrapWithHitsAndJquery } from '../../utils/wrap-with-hits.js'; -import * as widgets from '../widgets/index.js'; - -const stories = storiesOf('RefinementList'); - -export default () => { - stories.add( - 'default', - wrapWithHitsAndJquery(containerNode => { - window.search.addWidget( - widgets.refinementList({ - containerNode, - attributeName: 'brand', - operator: 'or', - limit: 10, - title: 'Brands', - }) - ); - }) - ); -}; diff --git a/dev/app/jquery/stories/search-box.stories.js b/dev/app/jquery/stories/search-box.stories.js deleted file mode 100644 index 32a0e2441a..0000000000 --- a/dev/app/jquery/stories/search-box.stories.js +++ /dev/null @@ -1,18 +0,0 @@ -import { storiesOf } from 'dev-novel'; -import { wrapWithHitsAndJquery } from '../../utils/wrap-with-hits.js'; -import * as widgets from '../widgets/index.js'; - -const stories = storiesOf('SearchBox'); - -export default () => { - stories.add( - 'default', - wrapWithHitsAndJquery(containerNode => { - const inputNode = document.createElement('input'); - containerNode.append(inputNode); - window.search.addWidget( - widgets.searchBox({ inputNode: window.$(inputNode) }) - ); - }) - ); -}; diff --git a/dev/app/jquery/stories/sort-by-selector.stories.js b/dev/app/jquery/stories/sort-by-selector.stories.js deleted file mode 100644 index e6eb2cc0e5..0000000000 --- a/dev/app/jquery/stories/sort-by-selector.stories.js +++ /dev/null @@ -1,23 +0,0 @@ -import { storiesOf } from 'dev-novel'; -import { wrapWithHitsAndJquery } from '../../utils/wrap-with-hits.js'; -import * as widgets from '../widgets/index.js'; - -const stories = storiesOf('SortBySelector'); - -export default () => { - stories.add( - 'default', - wrapWithHitsAndJquery(containerNode => { - window.search.addWidget( - widgets.sortBySelector({ - containerNode, - indices: [ - { name: 'instant_search', label: 'Most relevant' }, - { name: 'instant_search_price_asc', label: 'Lowest price' }, - { name: 'instant_search_price_desc', label: 'Highest price' }, - ], - }) - ); - }) - ); -}; diff --git a/dev/app/jquery/stories/star-rating.stories.js b/dev/app/jquery/stories/star-rating.stories.js deleted file mode 100644 index 4930a171e4..0000000000 --- a/dev/app/jquery/stories/star-rating.stories.js +++ /dev/null @@ -1,20 +0,0 @@ -import { storiesOf } from 'dev-novel'; -import { wrapWithHitsAndJquery } from '../../utils/wrap-with-hits.js'; -import * as widgets from '../widgets/index.js'; - -const stories = storiesOf('StarRating'); - -export default () => { - stories.add( - 'default', - wrapWithHitsAndJquery(containerNode => { - window.search.addWidget( - widgets.starRating({ - containerNode, - attributeName: 'rating', - max: 5, - }) - ); - }) - ); -}; diff --git a/dev/app/jquery/stories/stats.stories.js b/dev/app/jquery/stories/stats.stories.js deleted file mode 100644 index 21f728c207..0000000000 --- a/dev/app/jquery/stories/stats.stories.js +++ /dev/null @@ -1,14 +0,0 @@ -import { storiesOf } from 'dev-novel'; -import { wrapWithHitsAndJquery } from '../../utils/wrap-with-hits.js'; -import * as widgets from '../widgets/index.js'; - -const stories = storiesOf('Stats'); - -export default () => { - stories.add( - 'default', - wrapWithHitsAndJquery(containerNode => { - window.search.addWidget(widgets.stats({ containerNode })); - }) - ); -}; diff --git a/dev/app/jquery/stories/toggle.stories.js b/dev/app/jquery/stories/toggle.stories.js deleted file mode 100644 index d90184aae9..0000000000 --- a/dev/app/jquery/stories/toggle.stories.js +++ /dev/null @@ -1,21 +0,0 @@ -import { storiesOf } from 'dev-novel'; -import { wrapWithHitsAndJquery } from '../../utils/wrap-with-hits.js'; -import * as widgets from '../widgets/index.js'; - -const stories = storiesOf('Toggle'); - -export default () => { - stories.add( - 'default', - wrapWithHitsAndJquery(containerNode => { - window.search.addWidget( - widgets.toggle({ - containerNode, - attributeName: 'free_shipping', - label: 'Free Shipping (toggle single value)', - title: 'Free Shipping', - }) - ); - }) - ); -}; diff --git a/dev/app/jquery/widgets/clearAll.js b/dev/app/jquery/widgets/clearAll.js deleted file mode 100644 index 86bc9b0d49..0000000000 --- a/dev/app/jquery/widgets/clearAll.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable import/default */ -import instantsearch from '../../../../index.js'; - -const renderFn = ( - { refine, hasRefinements, widgetParams: { containerNode } }, - isFirstRendering -) => { - if (isFirstRendering) { - const markup = window.$(''); - containerNode.append(markup); - - markup.on('click', e => { - e.preventDefault(); - refine(); - }); - } - const clearAllCTA = containerNode.find('#custom-clear-all'); - - // disable button - clearAllCTA.attr('disabled', !hasRefinements); -}; - -export default instantsearch.connectors.connectClearAll(renderFn); diff --git a/dev/app/jquery/widgets/currentRefinedValues.js b/dev/app/jquery/widgets/currentRefinedValues.js deleted file mode 100644 index ec6f04e634..0000000000 --- a/dev/app/jquery/widgets/currentRefinedValues.js +++ /dev/null @@ -1,114 +0,0 @@ -/* eslint-disable import/default */ -import instantsearch from '../../../../index.js'; - -const renderFn = ( - { - clearAllClick, - clearAllURL, - createURL, - refine, - refinements, - widgetParams: { containerNode }, - }, - isFirstRendering -) => { - // append initial markup on first rendering - // ---------------------------------------- - if (isFirstRendering) { - const markup = window.$(` -
Custom current refinements
-
- - `); - containerNode.append(markup); - } - - if (refinements && refinements.length > 0) { - // append clear all link - // --------------------- - containerNode.find('#custom-crv-clear-all-container').html(` - - Clear all - - `); - - containerNode - .find('#custom-crv-clear-all-container > a') - .off('click') - .on('click', e => { - e.preventDefault(); - clearAllClick(); - }); - - // show current refined values - // --------------------------- - const list = refinements - .map(value => { - const { computedLabel, count } = value; - - const afterCount = count - ? `${count}` - : ''; - - switch (true) { - case value.attributeName === 'price_range': - return `Price range: ${computedLabel.replace( - /(\d+)/g, - '$$$1' - )} ${afterCount}`; - - case value.attributeName === 'price': - return `Price: ${computedLabel.replace(/(\d+)/g, '$$$1')}`; - - case value.attributeName === 'free_shipping': - return computedLabel === 'true' - ? `Free shipping ${afterCount}` - : ''; - - default: - return `${computedLabel} ${afterCount}`; - } - }) - .map( - (content, index) => ` -
  • - - ${content} - -
  • - ` - ); - - containerNode.find('ul').html(list.join('')); - - // bind click events on links - // -------------------------- - containerNode.find('li > a').each(function(index) { - window - .$(this) - .off('click') - .on('click', e => { - e.preventDefault(); - refine(refinements[index]); - }); - }); - - // show container - // -------------- - containerNode.find('#custom-current-refined-values').show(); - } else { - // remove refinements list and clear all button, hide the container - // ---------------------------------------------------------------- - containerNode.find('ul').html(''); - containerNode.find('#custom-crv-clear-all-container').html(''); - containerNode.find('#custom-current-refined-values').hide(); - } -}; - -export default instantsearch.connectors.connectCurrentRefinedValues(renderFn); diff --git a/dev/app/jquery/widgets/hierarchicalMenu.js b/dev/app/jquery/widgets/hierarchicalMenu.js deleted file mode 100644 index 133cdba685..0000000000 --- a/dev/app/jquery/widgets/hierarchicalMenu.js +++ /dev/null @@ -1,81 +0,0 @@ -/* eslint-disable import/default */ -import instantsearch from '../../../../index.js'; - -const formatMenuEntry = (createURL, lvl = 0) => item => { - const countHTML = ` - - ${item.count} - - `; - - if ( - item.isRefined === true && - Array.isArray(item.data) && - item.data.length > 0 - ) { - return ` -
    - - ${item.label} ${countHTML} - -
    - ${item.data.map(formatMenuEntry(createURL, lvl + 1)).join('')} -
    -
    - `; - } - - return ` -
    - - ${ - item.isRefined ? `${item.label}` : item.label - } ${countHTML} - -
    - `; -}; - -const renderFn = ( - { createURL, items, refine, widgetParams: { containerNode } }, - isFirstRendering -) => { - if (isFirstRendering) { - const markup = window.$(` -
    Custom hierarchical
    -
    - `); - containerNode.append(markup); - } - - // remove event listeners before replacing markup - containerNode.find('a[data-refine-value]').each(function() { - window.$(this).off('click'); - }); - - if (items && items.length > 0) { - // replace markup with items - const menuItems = items.map(formatMenuEntry(createURL)).join(''); - - containerNode.find('#custom-hierarchical-menu__container').html(menuItems); - - // bind links with `data-refine-value` - containerNode.find('a[data-refine-value]').each(function() { - window.$(this).on('click', e => { - e.preventDefault(); - refine(window.$(this).data('refine-value')); - }); - }); - } -}; - -export default instantsearch.connectors.connectHierarchicalMenu(renderFn); diff --git a/dev/app/jquery/widgets/hits.js b/dev/app/jquery/widgets/hits.js deleted file mode 100644 index a369ae55f9..0000000000 --- a/dev/app/jquery/widgets/hits.js +++ /dev/null @@ -1,38 +0,0 @@ -/* eslint-disable import/default */ -import instantsearch from '../../../../index.js'; - -const renderFn = ({ hits, widgetParams: { containerNode } }) => { - containerNode.html( - hits.map( - hit => ` -
    -
    - - - - -
    -

    $${hit.price}

    -

    ${hit._highlightResult.name.value}

    -

    ${hit._highlightResult.description.value}

    - - ${ - hit.free_shipping - ? 'Free shipping' - : '' - } -
    -
    -
    - ` - ) - ); -}; - -export default instantsearch.connectors.connectHits(renderFn); diff --git a/dev/app/jquery/widgets/hitsPerPageSelector.js b/dev/app/jquery/widgets/hitsPerPageSelector.js deleted file mode 100644 index e5c6672367..0000000000 --- a/dev/app/jquery/widgets/hitsPerPageSelector.js +++ /dev/null @@ -1,34 +0,0 @@ -/* eslint-disable import/default */ -import instantsearch from '../../../../index.js'; - -const renderFn = ( - { items, refine, widgetParams: { containerNode } }, - isFirstRendering -) => { - if (isFirstRendering) { - const markup = ''; - containerNode.append(markup); - } - - const itemsHTML = items.map( - ({ value, label, isRefined }) => ` - - ` - ); - - containerNode.find('select').html(itemsHTML); - - containerNode - .find('select') - .off('change') - .on('change', e => { - refine(e.target.value); - }); -}; - -export default instantsearch.connectors.connectHitsPerPage(renderFn); diff --git a/dev/app/jquery/widgets/index.js b/dev/app/jquery/widgets/index.js deleted file mode 100644 index 0e4430c12e..0000000000 --- a/dev/app/jquery/widgets/index.js +++ /dev/null @@ -1,18 +0,0 @@ -export { default as clearAll } from './clearAll'; -export { default as currentRefinedValues } from './currentRefinedValues'; -export { default as hierarchicalMenu } from './hierarchicalMenu'; -export { default as menu } from './menu'; -export { default as pagination } from './pagination'; -export { default as hitsPerPageSelector } from './hitsPerPageSelector'; -export { default as hits } from './hits'; -export { default as refinementList } from './refinementList'; -export { default as numericSelector } from './numericSelector'; -export { default as numericRefinementList } from './numericRefinementList'; -export { default as priceRanges } from './priceRanges'; -export { default as searchBox } from './searchBox'; -export { default as sortBySelector } from './sortBySelector'; -export { default as starRating } from './starRating'; -export { default as stats } from './stats'; -export { default as toggle } from './toggle'; -export { default as infiniteHits } from './infiniteHits'; -export { default as showMoreMenu } from './showMoreMenu'; diff --git a/dev/app/jquery/widgets/infiniteHits.js b/dev/app/jquery/widgets/infiniteHits.js deleted file mode 100644 index cd5b5ed12c..0000000000 --- a/dev/app/jquery/widgets/infiniteHits.js +++ /dev/null @@ -1,57 +0,0 @@ -/* eslint-disable import/default */ -import instantsearch from '../../../../index.js'; - -const renderFn = ({ - hits, - showMore, - isLastPage, - widgetParams: { containerNode }, -}) => { - const hitsHTML = hits.map( - hit => ` -
    -
    - - - - -
    -

    $${hit.price}

    -

    ${hit._highlightResult.name.value}

    -

    ${hit._highlightResult.description.value}

    - - ${ - hit.free_shipping - ? 'Free shipping' - : '' - } -
    -
    -
    - ` - ); - - containerNode.find('button[data-show-more]').off('click'); - containerNode.html(hitsHTML); - - if (!isLastPage) { - containerNode.append(` - - `); - - containerNode.find('button[data-show-more]').on('click', e => { - e.preventDefault(); - showMore(); - }); - } -}; - -export default instantsearch.connectors.connectInfiniteHits(renderFn); diff --git a/dev/app/jquery/widgets/menu.js b/dev/app/jquery/widgets/menu.js deleted file mode 100644 index ba8744ceb6..0000000000 --- a/dev/app/jquery/widgets/menu.js +++ /dev/null @@ -1,48 +0,0 @@ -/* eslint-disable import/default */ -/* global $ */ -import instantsearch from '../../../../index.js'; - -export default instantsearch.connectors.connectMenu(customMenuRendering); -function customMenuRendering(opts, isFirstRendering) { - const container = opts.widgetParams.containerNode; - - let input; - if (isFirstRendering) { - input = $(''); - input.refine = opts.refine; - input.on('change', e => { - input.refine(e.target.value); - }); - container - .html( - '
    Custom categories
    ' - ) - .append(input); - } else { - input = container.find('select'); - } - - input.refine = opts.refine; - - const facetValues = opts.items.slice(0, opts.widgetParams.limit || 10); - const facetOptions = facetValues.map( - f => - f.isRefined - ? $(``) - : $(``) - ); - const isValueSelected = facetValues.find(f => f.isRefined); - - const noValue = $( - `` - ); - - input.html(''); - - input.append(noValue); - if (facetOptions.length > 0) { - facetOptions.forEach(o => { - input.append(o); - }); - } -} diff --git a/dev/app/jquery/widgets/numericRefinementList.js b/dev/app/jquery/widgets/numericRefinementList.js deleted file mode 100644 index 92fce31cf5..0000000000 --- a/dev/app/jquery/widgets/numericRefinementList.js +++ /dev/null @@ -1,62 +0,0 @@ -/* eslint-disable import/default */ -import instantsearch from '../../../../index.js'; - -const renderFn = ( - { - items, - refine, - widgetParams: { - containerNode, - attributeName, - title = 'Numeric refinement list', - }, - }, - isFirstRendering -) => { - if (isFirstRendering) { - const markup = ` -
    ${title}
    - - `; - containerNode.append(markup); - } - - // remove event listeners if any before attachign new ones - containerNode.find('li[data-refine-value]').each(function() { - window.$(this).off(); - }); - - const list = items.map( - item => ` -
  • - -
  • - ` - ); - - containerNode.find('ul').html(list); - - containerNode.find('li[data-refine-value]').each(function() { - window.$(this).on('click', e => { - e.preventDefault(); - e.stopPropagation(); - - refine(window.$(this).data('refine-value')); - }); - }); -}; - -export default instantsearch.connectors.connectNumericRefinementList(renderFn); diff --git a/dev/app/jquery/widgets/numericSelector.js b/dev/app/jquery/widgets/numericSelector.js deleted file mode 100644 index 6b0775e7bb..0000000000 --- a/dev/app/jquery/widgets/numericSelector.js +++ /dev/null @@ -1,34 +0,0 @@ -/* eslint-disable import/default */ -import instantsearch from '../../../../index.js'; - -const renderFn = ( - { currentRefinement, options, refine, widgetParams: { containerNode } }, - isFirstRendering -) => { - if (isFirstRendering) { - const markup = ''; - containerNode.append(markup); - } - - const optionsHTML = options.map( - ({ value, label }) => ` - - ` - ); - - containerNode.find('select').html(optionsHTML); - - containerNode - .find('select') - .off('change') - .on('change', e => { - refine(e.target.value); - }); -}; - -export default instantsearch.connectors.connectNumericSelector(renderFn); diff --git a/dev/app/jquery/widgets/pagination.js b/dev/app/jquery/widgets/pagination.js deleted file mode 100644 index d13b9ca770..0000000000 --- a/dev/app/jquery/widgets/pagination.js +++ /dev/null @@ -1,55 +0,0 @@ -/* eslint-disable import/default */ -import instantsearch from '../../../../index.js'; - -const renderFn = ( - { - nbPages, - pages, - createURL, - refine, - currentRefinement, - widgetParams: { containerNode }, - }, - isFirstRendering -) => { - if (isFirstRendering) { - const markup = ` -
    Custom pagination
    - - `; - containerNode.append(markup); - } - - // remove event listeners before replacing markup - containerNode.find('a[data-page]').each(function() { - window.$(this).off('click'); - }); - - if (nbPages > 0) { - containerNode.find('ul.pagination').html( - pages - .map( - page => ` -
  • - - ${page + 1} - -
  • - ` - ) - .join('') - ); - - containerNode.find('a[data-page]').each(function() { - window.$(this).on('click', e => { - e.preventDefault(); - refine(window.$(this).data('page')); - }); - }); - } -}; - -export default instantsearch.connectors.connectPagination(renderFn); diff --git a/dev/app/jquery/widgets/priceRanges.js b/dev/app/jquery/widgets/priceRanges.js deleted file mode 100644 index 2a91b1d572..0000000000 --- a/dev/app/jquery/widgets/priceRanges.js +++ /dev/null @@ -1,119 +0,0 @@ -/* eslint-disable import/default */ -import instantsearch from '../../../../index.js'; - -const getLabel = ({ from, to } = {}) => { - if (to === undefined) return `≥ $${from}`; - if (from === undefined) return `≤ $${to}`; - return `$${from} - $${to}`; -}; - -// Available price ranges for results -// ---------------------------------- -const renderList = ({ containerNode, items, refine }) => { - containerNode.find('ul > li').each(function() { - window.$(this).off(); - }); - - const list = items.map( - item => ` -
  • - - ${getLabel(item)} - -
  • - ` - ); - - containerNode.find('ul').html(list); - - containerNode.find('ul > li').each(function(index) { - window.$(this).on('click', e => { - e.preventDefault(); - e.stopPropagation(); - - const { from, to } = items[index]; - refine({ from, to }); - }); - }); -}; - -// Custom values form -// ------------------ -const renderForm = ({ containerNode, currentRefinement }) => { - const { from, to } = currentRefinement || {}; - containerNode.find('form').html(` - - - to - - - - - `); -}; - -const handleFormSubmit = ({ refine, containerNode }) => e => { - e.preventDefault(); - - const [ - { value: fromInputValue }, - { value: toInputValue }, - ] = containerNode.find('input[type="number"]'); - - const from = !isNaN(parseFloat(fromInputValue)) - ? parseFloat(fromInputValue) - : undefined; - const to = !isNaN(parseFloat(toInputValue)) - ? parseFloat(toInputValue) - : undefined; - - if (from || to) refine({ from, to }); -}; - -const renderFn = ( - { - items, - refine, - currentRefinement, - widgetParams: { containerNode, title = 'Price ranges' }, - }, - isFirstRendering -) => { - if (isFirstRendering) { - const markup = ` -
    ${title}
    - -
    - `; - containerNode.append(markup); - - // bind form action on first render - containerNode - .find('form') - .on('submit', handleFormSubmit({ refine, containerNode })); - } - - renderList({ containerNode, items, refine }); - renderForm({ containerNode, currentRefinement, refine }); -}; - -export default instantsearch.connectors.connectPriceRanges(renderFn); diff --git a/dev/app/jquery/widgets/refinementList.js b/dev/app/jquery/widgets/refinementList.js deleted file mode 100644 index a8a6266672..0000000000 --- a/dev/app/jquery/widgets/refinementList.js +++ /dev/null @@ -1,70 +0,0 @@ -/* eslint-disable import/default */ -import instantsearch from '../../../../index.js'; - -const renderFn = ( - { - items, - refine, - canRefine, - createURL, - widgetParams: { containerNode, title }, - }, - isFirstRendering -) => { - if (isFirstRendering) { - const markup = ` -
    ${title}
    - - `; - - containerNode.append(markup); - } - - // remove event listeners if any before attaching new ones - window.$('li[data-refine-value]').each(function() { - window.$(this).off(); - }); - - if (canRefine) { - const list = items.map( - item => ` -
  • - -
  • - ` - ); - - containerNode.find('ul').html(list.join('')); - - containerNode.find('li[data-refine-value]').each(function() { - window.$(this).on('click', e => { - e.preventDefault(); - e.stopPropagation(); - - refine(window.$(this).data('refine-value')); - }); - }); - } -}; - -export default instantsearch.connectors.connectRefinementList(renderFn); diff --git a/dev/app/jquery/widgets/searchBox.js b/dev/app/jquery/widgets/searchBox.js deleted file mode 100644 index c1bfb8f3e2..0000000000 --- a/dev/app/jquery/widgets/searchBox.js +++ /dev/null @@ -1,14 +0,0 @@ -/* eslint-disable import/default */ -import instantsearch from '../../../../index.js'; - -const renderFn = ( - { query, refine, widgetParams: { inputNode } }, - isFirstRendering -) => { - if (isFirstRendering) { - inputNode.on('keyup', () => refine(inputNode.val())); - inputNode.val(query); - } -}; - -export default instantsearch.connectors.connectSearchBox(renderFn); diff --git a/dev/app/jquery/widgets/showMoreMenu.js b/dev/app/jquery/widgets/showMoreMenu.js deleted file mode 100644 index 9da63f81cc..0000000000 --- a/dev/app/jquery/widgets/showMoreMenu.js +++ /dev/null @@ -1,56 +0,0 @@ -/* eslint-disable import/default */ -import instantsearch from '../../../../index.js'; - -const renderFn = ( - { - items, - refine, - createURL, - isShowingMore, - toggleShowMore, - widgetParams: { containerNode }, - }, - isFirstRendering -) => { - if (isFirstRendering) { - containerNode.html(` -
    Categories (menu with showmore)
    -