vue-instantsearch 4.8.10 → 4.10.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.
Files changed (44) hide show
  1. package/package.json +4 -4
  2. package/src/__tests__/common.test.js +161 -1
  3. package/src/components/Hits.vue +2 -0
  4. package/src/components/InfiniteHits.vue +2 -0
  5. package/src/components/InstantSearch.js +7 -0
  6. package/src/components/__tests__/Hits.js +1 -0
  7. package/src/components/__tests__/InfiniteHits.js +1 -0
  8. package/src/util/__tests__/createServerRootMixin.test.js +3 -18
  9. package/src/util/createInstantSearchComponent.js +1 -1
  10. package/src/util/vue-compat/index-vue3.js +24 -3
  11. package/vue2/cjs/index.js +1 -1
  12. package/vue2/cjs/index.js.map +1 -1
  13. package/vue2/es/package.json.js +1 -1
  14. package/vue2/es/src/components/Hits.vue.js +1 -1
  15. package/vue2/es/src/components/InfiniteHits.vue.js +1 -1
  16. package/vue2/es/src/components/InstantSearch.js +1 -1
  17. package/vue2/es/src/components/InstantSearch.js.map +1 -1
  18. package/vue2/es/src/util/createInstantSearchComponent.js +1 -1
  19. package/vue2/es/src/util/createInstantSearchComponent.js.map +1 -1
  20. package/vue2/umd/index.js +1 -1
  21. package/vue2/umd/index.js.map +1 -1
  22. package/vue3/cjs/index.js +1 -1
  23. package/vue3/cjs/index.js.map +1 -1
  24. package/vue3/es/package.json.js +1 -1
  25. package/vue3/es/src/components/Hits.vue.js +1 -1
  26. package/vue3/es/src/components/Hits.vue_vue&type=script&lang.js.map +1 -1
  27. package/vue3/es/src/components/Hits.vue_vue&type=template&id=19b8dc8f&lang.js +2 -0
  28. package/vue3/es/src/components/Hits.vue_vue&type=template&id=19b8dc8f&lang.js.map +1 -0
  29. package/vue3/es/src/components/InfiniteHits.vue.js +1 -1
  30. package/vue3/es/src/components/InfiniteHits.vue_vue&type=script&lang.js.map +1 -1
  31. package/vue3/es/src/components/InfiniteHits.vue_vue&type=template&id=09224cc0&lang.js +2 -0
  32. package/vue3/es/src/components/InfiniteHits.vue_vue&type=template&id=09224cc0&lang.js.map +1 -0
  33. package/vue3/es/src/components/InstantSearch.js +1 -1
  34. package/vue3/es/src/components/InstantSearch.js.map +1 -1
  35. package/vue3/es/src/util/createInstantSearchComponent.js +1 -1
  36. package/vue3/es/src/util/createInstantSearchComponent.js.map +1 -1
  37. package/vue3/es/src/util/vue-compat/index-vue3.js +1 -1
  38. package/vue3/es/src/util/vue-compat/index-vue3.js.map +1 -1
  39. package/vue3/umd/index.js +1 -1
  40. package/vue3/umd/index.js.map +1 -1
  41. package/vue3/es/src/components/Hits.vue_vue&type=template&id=5bc4cfef&lang.js +0 -2
  42. package/vue3/es/src/components/Hits.vue_vue&type=template&id=5bc4cfef&lang.js.map +0 -1
  43. package/vue3/es/src/components/InfiniteHits.vue_vue&type=template&id=0e2ba520&lang.js +0 -2
  44. package/vue3/es/src/components/InfiniteHits.vue_vue&type=template&id=0e2ba520&lang.js.map +0 -1
package/package.json CHANGED
@@ -16,7 +16,7 @@
16
16
  "autocomplete"
17
17
  ],
18
18
  "license": "MIT",
19
- "version": "4.8.10",
19
+ "version": "4.10.0",
20
20
  "files": [
21
21
  "vue2",
22
22
  "vue3",
@@ -35,7 +35,7 @@
35
35
  "test:exports:vue3": "node ./test/module/vue3/is-es-module.mjs && node ./test/module/vue3/is-cjs-module.cjs"
36
36
  },
37
37
  "dependencies": {
38
- "instantsearch.js": "4.54.1",
38
+ "instantsearch.js": "4.56.0",
39
39
  "mitt": "^2.1.0"
40
40
  },
41
41
  "peerDependencies": {
@@ -60,7 +60,7 @@
60
60
  "@vue/test-utils": "1.3.0",
61
61
  "@vue/test-utils2": "npm:@vue/test-utils@2.0.0-rc.11",
62
62
  "algoliasearch": "4.14.3",
63
- "algoliasearch-helper": "3.11.3",
63
+ "algoliasearch-helper": "3.13.0",
64
64
  "instantsearch.css": "8.0.0",
65
65
  "rollup": "1.32.1",
66
66
  "rollup-plugin-babel": "4.4.0",
@@ -85,5 +85,5 @@
85
85
  "vuex": "3.5.1",
86
86
  "vuex4": "npm:vuex@4.0.0"
87
87
  },
88
- "gitHead": "1f81b61cf0e78aeb7022d5e9eca0d49de727dc64"
88
+ "gitHead": "ea054eab1484a3d167db83bc768f6ea134add5f9"
89
89
  }
@@ -8,6 +8,8 @@ import {
8
8
  createMenuTests,
9
9
  createPaginationTests,
10
10
  createInfiniteHitsTests,
11
+ createHitsTests,
12
+ createRangeInputTests,
11
13
  } from '@instantsearch/tests';
12
14
 
13
15
  import { nextTick, mountApp } from '../../test/utils';
@@ -22,6 +24,9 @@ import {
22
24
  AisInfiniteHits,
23
25
  AisSearchBox,
24
26
  createWidgetMixin,
27
+ AisHits,
28
+ AisIndex,
29
+ AisRangeInput,
25
30
  } from '../instantsearch';
26
31
  jest.unmock('instantsearch.js/es');
27
32
 
@@ -128,7 +133,162 @@ createInfiniteHitsTests(async ({ instantSearchOptions, widgetParams }) => {
128
133
  render: renderCompat((h) =>
129
134
  h(AisInstantSearch, { props: instantSearchOptions }, [
130
135
  h(AisSearchBox),
131
- h(AisInfiniteHits, { props: widgetParams }),
136
+ h(AisInfiniteHits, {
137
+ attrs: { id: 'main-hits' },
138
+ props: widgetParams,
139
+ scopedSlots: {
140
+ item: ({ item: hit, sendEvent }) =>
141
+ h(
142
+ 'div',
143
+ {
144
+ attrs: {
145
+ 'data-testid': `main-hits-top-level-${hit.__position}`,
146
+ },
147
+ },
148
+ [
149
+ hit.objectID,
150
+ h('button', {
151
+ attrs: {
152
+ 'data-testid': `main-hits-convert-${hit.__position}`,
153
+ },
154
+ on: {
155
+ click: () => sendEvent('conversion', hit, 'Converted'),
156
+ },
157
+ }),
158
+ h('button', {
159
+ attrs: {
160
+ 'data-testid': `main-hits-click-${hit.__position}`,
161
+ },
162
+ on: {
163
+ click: () => sendEvent('click', hit, 'Clicked'),
164
+ },
165
+ }),
166
+ ]
167
+ ),
168
+ },
169
+ }),
170
+ h(AisIndex, { props: { indexName: 'nested' } }, [
171
+ h(AisInfiniteHits, {
172
+ attrs: { id: 'nested-hits' },
173
+ scopedSlots: {
174
+ item: ({ item: hit, sendEvent }) =>
175
+ h(
176
+ 'div',
177
+ {
178
+ attrs: {
179
+ 'data-testid': `nested-hits-top-level-${hit.__position}`,
180
+ },
181
+ },
182
+ [
183
+ hit.objectID,
184
+ h('button', {
185
+ attrs: {
186
+ 'data-testid': `nested-hits-click-${hit.__position}`,
187
+ },
188
+ on: {
189
+ click: () =>
190
+ sendEvent('click', hit, 'Clicked nested'),
191
+ },
192
+ }),
193
+ ]
194
+ ),
195
+ },
196
+ }),
197
+ ]),
198
+ h(GlobalErrorSwallower),
199
+ ])
200
+ ),
201
+ },
202
+ document.body.appendChild(document.createElement('div'))
203
+ );
204
+
205
+ await nextTick();
206
+ });
207
+
208
+ createHitsTests(async ({ instantSearchOptions, widgetParams }) => {
209
+ mountApp(
210
+ {
211
+ render: renderCompat((h) =>
212
+ h(AisInstantSearch, { props: instantSearchOptions }, [
213
+ h(AisSearchBox),
214
+ h(AisHits, {
215
+ attrs: { id: 'main-hits' },
216
+ props: widgetParams,
217
+ scopedSlots: {
218
+ item: ({ item: hit, sendEvent }) =>
219
+ h(
220
+ 'div',
221
+ {
222
+ attrs: {
223
+ 'data-testid': `main-hits-top-level-${hit.__position}`,
224
+ },
225
+ },
226
+ [
227
+ hit.objectID,
228
+ h('button', {
229
+ attrs: {
230
+ 'data-testid': `main-hits-convert-${hit.__position}`,
231
+ },
232
+ on: {
233
+ click: () => sendEvent('conversion', hit, 'Converted'),
234
+ },
235
+ }),
236
+ h('button', {
237
+ attrs: {
238
+ 'data-testid': `main-hits-click-${hit.__position}`,
239
+ },
240
+ on: {
241
+ click: () => sendEvent('click', hit, 'Clicked'),
242
+ },
243
+ }),
244
+ ]
245
+ ),
246
+ },
247
+ }),
248
+ h(AisIndex, { props: { indexName: 'nested' } }, [
249
+ h(AisHits, {
250
+ attrs: { id: 'nested-hits' },
251
+ scopedSlots: {
252
+ item: ({ item: hit, sendEvent }) =>
253
+ h(
254
+ 'div',
255
+ {
256
+ attrs: {
257
+ 'data-testid': `nested-hits-top-level-${hit.__position}`,
258
+ },
259
+ },
260
+ [
261
+ hit.objectID,
262
+ h('button', {
263
+ attrs: {
264
+ 'data-testid': `nested-hits-click-${hit.__position}`,
265
+ },
266
+ on: {
267
+ click: () =>
268
+ sendEvent('click', hit, 'Clicked nested'),
269
+ },
270
+ }),
271
+ ]
272
+ ),
273
+ },
274
+ }),
275
+ ]),
276
+ h(GlobalErrorSwallower),
277
+ ])
278
+ ),
279
+ },
280
+ document.body.appendChild(document.createElement('div'))
281
+ );
282
+
283
+ await nextTick();
284
+ });
285
+
286
+ createRangeInputTests(async ({ instantSearchOptions, widgetParams }) => {
287
+ mountApp(
288
+ {
289
+ render: renderCompat((h) =>
290
+ h(AisInstantSearch, { props: instantSearchOptions }, [
291
+ h(AisRangeInput, { props: widgetParams }),
132
292
  h(GlobalErrorSwallower),
133
293
  ])
134
294
  ),
@@ -10,12 +10,14 @@
10
10
  v-for="(item, itemIndex) in items"
11
11
  :key="item.objectID"
12
12
  :class="suit('item')"
13
+ @click="state.sendEvent('click:internal', item, 'Hit Clicked')"
13
14
  >
14
15
  <slot
15
16
  name="item"
16
17
  :item="item"
17
18
  :index="itemIndex"
18
19
  :insights="state.insights"
20
+ :send-event="state.sendEvent"
19
21
  >
20
22
  objectID: {{ item.objectID }}, index: {{ itemIndex }}
21
23
  </slot>
@@ -34,12 +34,14 @@
34
34
  v-for="(item, index) in items"
35
35
  :class="suit('item')"
36
36
  :key="item.objectID"
37
+ @click="state.sendEvent('click:internal', item, 'Hit Clicked')"
37
38
  >
38
39
  <slot
39
40
  name="item"
40
41
  :item="item"
41
42
  :index="index"
42
43
  :insights="state.insights"
44
+ :send-event="state.sendEvent"
43
45
  >
44
46
  objectID: {{ item.objectID }}, index: {{ index }}
45
47
  </slot>
@@ -38,6 +38,12 @@ export default createInstantSearchComponent({
38
38
  return true;
39
39
  },
40
40
  },
41
+ insights: {
42
+ default: undefined,
43
+ validator(value) {
44
+ return typeof value === 'boolean' || typeof value === 'object';
45
+ },
46
+ },
41
47
  stalledSearchDelay: {
42
48
  type: Number,
43
49
  default: undefined,
@@ -84,6 +90,7 @@ export default createInstantSearchComponent({
84
90
  instantSearchInstance: instantsearch({
85
91
  searchClient: this.searchClient,
86
92
  insightsClient: this.insightsClient,
93
+ insights: this.insights,
87
94
  indexName: this.indexName,
88
95
  routing: this.routing,
89
96
  stalledSearchDelay: this.stalledSearchDelay,
@@ -11,6 +11,7 @@ jest.mock('../../mixins/widget');
11
11
 
12
12
  const defaultState = {
13
13
  hits: [{ objectID: 'one' }, { objectID: 'two' }],
14
+ sendEvent: jest.fn(),
14
15
  };
15
16
 
16
17
  it('accepts an escapeHTML prop', () => {
@@ -15,6 +15,7 @@ const defaultState = {
15
15
  escapeHTML: true,
16
16
  transformItems: (items) => items,
17
17
  },
18
+ sendEvent: jest.fn(),
18
19
  hits: [
19
20
  {
20
21
  objectID: '00001',
@@ -66,23 +66,6 @@ describe('createServerRootMixin', () => {
66
66
  ).toThrowErrorMatchingInlineSnapshot(`
67
67
  "The \`searchClient\` option is required.
68
68
 
69
- See documentation: https://www.algolia.com/doc/api-reference/widgets/instantsearch/js/"
70
- `);
71
- });
72
-
73
- it('requires indexName', () => {
74
- expect(() =>
75
- createSSRApp({
76
- mixins: [
77
- createServerRootMixin({
78
- searchClient: createFakeClient(),
79
- indexName: undefined,
80
- }),
81
- ],
82
- })
83
- ).toThrowErrorMatchingInlineSnapshot(`
84
- "The \`indexName\` option is required.
85
-
86
69
  See documentation: https://www.algolia.com/doc/api-reference/widgets/instantsearch/js/"
87
70
  `);
88
71
  });
@@ -1133,7 +1116,9 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/instantsear
1133
1116
 
1134
1117
  const resultsState = createSerializedState();
1135
1118
  const state = new SearchParameters(resultsState.state);
1136
- const localState = new SearchParameters({ index: 'lol' });
1119
+ const localState = new SearchParameters({
1120
+ index: 'lol',
1121
+ });
1137
1122
  const results = new SearchResults(state, resultsState.results);
1138
1123
 
1139
1124
  instantSearchInstance.hydrate({
@@ -23,7 +23,7 @@ export const createInstantSearchComponent = (component) =>
23
23
  this.instantSearchInstance.helper.setClient(searchClient).search();
24
24
  },
25
25
  indexName(indexName) {
26
- this.instantSearchInstance.helper.setIndex(indexName).search();
26
+ this.instantSearchInstance.helper.setIndex(indexName || '').search();
27
27
  },
28
28
  stalledSearchDelay(stalledSearchDelay) {
29
29
  // private InstantSearch.js API:
@@ -9,13 +9,34 @@ export { Vue, Vue2, isVue2, isVue3 };
9
9
 
10
10
  export function renderCompat(fn) {
11
11
  function h(tag, props, children) {
12
- if (typeof props === 'object' && (props.attrs || props.props)) {
12
+ if (
13
+ typeof props === 'object' &&
14
+ (props.attrs || props.props || props.scopedSlots || props.on)
15
+ ) {
13
16
  // In vue 3, we no longer wrap with `attrs` or `props` key.
14
- const flatProps = Object.assign({}, props, props.attrs, props.props);
17
+ const flatProps = Object.assign(
18
+ {},
19
+ props,
20
+ props.attrs,
21
+ props.props,
22
+ Object.keys(props.on || {}).reduce((acc, key) => {
23
+ // eslint-disable-next-line no-param-reassign
24
+ acc[`on${key[0].toUpperCase()}${key.slice(1)}`] = props.on[key];
25
+ return acc;
26
+ }, {})
27
+ );
15
28
  delete flatProps.attrs;
16
29
  delete flatProps.props;
30
+ delete flatProps.scopedSlots;
31
+ delete flatProps.on;
17
32
 
18
- return Vue.h(tag, flatProps, children);
33
+ return Vue.h(
34
+ tag,
35
+ flatProps,
36
+ props.scopedSlots
37
+ ? Object.assign({ default: () => children }, props.scopedSlots)
38
+ : children
39
+ );
19
40
  }
20
41
 
21
42
  return Vue.h(tag, props, children);