@algolia/autocomplete-js 1.6.2 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -78,10 +78,7 @@ export function createAutocompleteDom(_ref) {
78
78
  getInputProps: propGetters.getInputProps,
79
79
  getInputPropsCore: autocomplete.getInputProps,
80
80
  autocompleteScopeApi: autocompleteScopeApi,
81
- onDetachedEscape: isDetached ? function () {
82
- autocomplete.setIsOpen(false);
83
- setIsModalOpen(false);
84
- } : undefined
81
+ isDetached: isDetached
85
82
  });
86
83
  var inputWrapperPrefix = createDomElement('div', {
87
84
  class: classNames.inputWrapperPrefix,
@@ -6,7 +6,7 @@ declare type InputProps = {
6
6
  environment: AutocompleteEnvironment;
7
7
  getInputProps: AutocompletePropGetters<any>['getInputProps'];
8
8
  getInputPropsCore: AutocompleteCoreApi<any>['getInputProps'];
9
- onDetachedEscape?(): void;
9
+ isDetached: boolean;
10
10
  state: AutocompleteState<any>;
11
11
  };
12
12
  export declare const Input: AutocompleteElement<InputProps, HTMLInputElement>;
@@ -1,4 +1,4 @@
1
- var _excluded = ["autocompleteScopeApi", "environment", "classNames", "getInputProps", "getInputPropsCore", "onDetachedEscape", "state"];
1
+ var _excluded = ["autocompleteScopeApi", "environment", "classNames", "getInputProps", "getInputPropsCore", "isDetached", "state"];
2
2
 
3
3
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
4
4
 
@@ -18,7 +18,7 @@ export var Input = function Input(_ref) {
18
18
  classNames = _ref.classNames,
19
19
  getInputProps = _ref.getInputProps,
20
20
  getInputPropsCore = _ref.getInputPropsCore,
21
- onDetachedEscape = _ref.onDetachedEscape,
21
+ isDetached = _ref.isDetached,
22
22
  state = _ref.state,
23
23
  props = _objectWithoutProperties(_ref, _excluded);
24
24
 
@@ -33,9 +33,8 @@ export var Input = function Input(_ref) {
33
33
  }, autocompleteScopeApi));
34
34
  setProperties(element, _objectSpread(_objectSpread({}, inputProps), {}, {
35
35
  onKeyDown: function onKeyDown(event) {
36
- if (onDetachedEscape && event.key === 'Escape') {
37
- event.preventDefault();
38
- onDetachedEscape();
36
+ // In detached mode we don't want to close the panel when hittin `Tab`.
37
+ if (isDetached && event.key === 'Tab') {
39
38
  return;
40
39
  }
41
40
 
@@ -9,12 +9,14 @@ export declare function getDefaultOptions<TItem extends BaseItem>(options: Autoc
9
9
  props: {
10
10
  onTouchStart(event: TouchEvent): void;
11
11
  onTouchMove(event: TouchEvent): void;
12
+ onMouseDown(event: MouseEvent): void;
12
13
  };
13
14
  } & {
14
15
  state: import("./types").AutocompleteState<TItem>;
15
16
  } & import("@algolia/autocomplete-core").AutocompleteScopeApi<TItem>) => {
16
17
  onTouchStart(event: TouchEvent): void;
17
18
  onTouchMove(event: TouchEvent): void;
19
+ onMouseDown(event: MouseEvent): void;
18
20
  };
19
21
  getFormProps: (params: {
20
22
  props: {
@@ -83,7 +83,7 @@ export function getDefaultOptions(options) {
83
83
 
84
84
  var containerElement = getHTMLElement(environment, container);
85
85
  invariant(containerElement.tagName !== 'INPUT', 'The `container` option does not support `input` elements. You need to change the container to a `div`.');
86
- process.env.NODE_ENV !== 'production' ? warn(!(render && renderer && !(renderer !== null && renderer !== void 0 && renderer.render)), "You provided the `render` option but did not provide a `renderer.render`. Since v1.6.0, you can provide a `render` function directly in `renderer`." + "\nTo get rid of this warning, do any of the following depending on your use case." + "\n- If you are using the `render` option only to override Autocomplete's default `render` function, pass the `render` function into `renderer` and remove the `render` option." + '\n- If you are using the `render` option to customize the layout, pass your `render` function into `renderer` and use it from the provided parameters of the `render` option.' + '\nSee https://www.algolia.com/doc/ui-libraries/autocomplete/api-reference/autocomplete-js/autocomplete/#param-render') : void 0;
86
+ process.env.NODE_ENV !== 'production' ? warn(!(render && renderer && !(renderer !== null && renderer !== void 0 && renderer.render)), "You provided the `render` option but did not provide a `renderer.render`. Since v1.6.0, you can provide a `render` function directly in `renderer`." + "\nTo get rid of this warning, do any of the following depending on your use case." + "\n- If you are using the `render` option only to override Autocomplete's default `render` function, pass the `render` function into `renderer` and remove the `render` option." + '\n- If you are using the `render` option to customize the layout, pass your `render` function into `renderer` and use it from the provided parameters of the `render` option.' + '\n- If you are using the `render` option to work with React 18, pass an empty `render` function into `renderer`.' + '\nSee https://www.algolia.com/doc/ui-libraries/autocomplete/api-reference/autocomplete-js/autocomplete/#param-render') : void 0;
87
87
  process.env.NODE_ENV !== 'production' ? warn(!renderer || render || renderer.Fragment && renderer.createElement && renderer.render, "You provided an incomplete `renderer` (missing: ".concat([!(renderer !== null && renderer !== void 0 && renderer.createElement) && '`renderer.createElement`', !(renderer !== null && renderer !== void 0 && renderer.Fragment) && '`renderer.Fragment`', !(renderer !== null && renderer !== void 0 && renderer.render) && '`renderer.render`'].filter(Boolean).join(', '), "). This can cause rendering issues.") + '\nSee https://www.algolia.com/doc/ui-libraries/autocomplete/api-reference/autocomplete-js/autocomplete/#param-renderer') : void 0;
88
88
 
89
89
  var defaultedRenderer = _objectSpread(_objectSpread({}, defaultRenderer), renderer);
@@ -1,13 +1,13 @@
1
1
  /// <reference types="react" />
2
2
  export declare type Pragma = (type: any, props: Record<string, any> | null, ...children: ComponentChildren[]) => JSX.Element;
3
3
  export declare type PragmaFrag = any;
4
- declare type ComponentChild = VNode<any> | object | string | number | boolean | null | undefined;
4
+ declare type ComponentChild = VNode<any> | string | number | boolean | null | undefined;
5
5
  declare type ComponentChildren = ComponentChild[] | ComponentChild;
6
- export declare type VNode<TProps = any> = {
6
+ export declare type VNode<TProps = {}> = {
7
7
  type: any;
8
+ key: string | number | any;
8
9
  props: TProps & {
9
10
  children: ComponentChildren;
10
- key?: any;
11
11
  };
12
12
  };
13
13
  export declare type Render = (vnode: ComponentChild, parent: Element | Document | ShadowRoot | DocumentFragment, replaceNode?: Element | Text | undefined) => void;
@@ -1,4 +1,4 @@
1
- /*! @algolia/autocomplete-js 1.6.2 | MIT License | © Algolia, Inc. and contributors | https://github.com/algolia/autocomplete */
1
+ /*! @algolia/autocomplete-js 1.7.1 | MIT License | © Algolia, Inc. and contributors | https://github.com/algolia/autocomplete */
2
2
  (function (global, factory) {
3
3
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
4
4
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
@@ -353,7 +353,7 @@
353
353
 
354
354
  var noop = function noop() {};
355
355
 
356
- var version = '1.6.2';
356
+ var version = '1.7.1';
357
357
 
358
358
  var userAgents$1 = [{
359
359
  segment: 'autocomplete-core',
@@ -1751,6 +1751,13 @@
1751
1751
  // pending and could reopen the panel once they resolve, because that would
1752
1752
  // result in an unsolicited UI behavior.
1753
1753
 
1754
+ store.pendingRequests.cancelAll();
1755
+ } else if (event.key === 'Tab') {
1756
+ store.dispatch('blur', null); // Hitting the `Escape` key signals the end of a user interaction with the
1757
+ // autocomplete. At this point, we should ignore any requests that are still
1758
+ // pending and could reopen the panel once they resolve, because that would
1759
+ // result in an unsolicited UI behavior.
1760
+
1754
1761
  store.pendingRequests.cancelAll();
1755
1762
  } else if (event.key === 'Enter') {
1756
1763
  // No active item, so we let the browser handle the native `onSubmit` form
@@ -1758,6 +1765,14 @@
1758
1765
  if (store.getState().activeItemId === null || store.getState().collections.every(function (collection) {
1759
1766
  return collection.items.length === 0;
1760
1767
  })) {
1768
+ // If requests are still pending when the panel closes, they could reopen
1769
+ // the panel once they resolve.
1770
+ // We want to prevent any subsequent query from reopening the panel
1771
+ // because it would result in an unsolicited UI behavior.
1772
+ if (!props.debug) {
1773
+ store.pendingRequests.cancelAll();
1774
+ }
1775
+
1761
1776
  return;
1762
1777
  } // This prevents the `onSubmit` event to be sent because an item is
1763
1778
  // highlighted.
@@ -1942,42 +1957,49 @@
1942
1957
  panelElement = providedProps.panelElement,
1943
1958
  rest = _objectWithoutProperties$1(providedProps, _excluded2);
1944
1959
 
1945
- return _objectSpread$6({
1946
- // On touch devices, we do not rely on the native `blur` event of the
1947
- // input to close the panel, but rather on a custom `touchstart` event
1948
- // outside of the autocomplete elements.
1949
- // This ensures a working experience on mobile because we blur the input
1950
- // on touch devices when the user starts scrolling (`touchmove`).
1951
- // @TODO: support cases where there are multiple Autocomplete instances.
1960
+ function onMouseDownOrTouchStart(event) {
1961
+ // The `onTouchStart`/`onMouseDown` events shouldn't trigger the `blur`
1962
+ // handler when it's not an interaction with Autocomplete.
1963
+ // We detect it with the following heuristics:
1964
+ // - the panel is closed AND there are no pending requests
1965
+ // (no interaction with the autocomplete, no future state updates)
1966
+ // - OR the touched target is the input element (should open the panel)
1967
+ var isAutocompleteInteraction = store.getState().isOpen || !store.pendingRequests.isEmpty();
1968
+
1969
+ if (!isAutocompleteInteraction || event.target === inputElement) {
1970
+ return;
1971
+ } // @TODO: support cases where there are multiple Autocomplete instances.
1952
1972
  // Right now, a second instance makes this computation return false.
1953
- onTouchStart: function onTouchStart(event) {
1954
- // The `onTouchStart` event shouldn't trigger the `blur` handler when
1955
- // it's not an interaction with Autocomplete. We detect it with the
1956
- // following heuristics:
1957
- // - the panel is closed AND there are no pending requests
1958
- // (no interaction with the autocomplete, no future state updates)
1959
- // - OR the touched target is the input element (should open the panel)
1960
- var isAutocompleteInteraction = store.getState().isOpen || !store.pendingRequests.isEmpty();
1961
-
1962
- if (!isAutocompleteInteraction || event.target === inputElement) {
1963
- return;
1964
- }
1965
1973
 
1966
- var isTargetWithinAutocomplete = [formElement, panelElement].some(function (contextNode) {
1967
- return isOrContainsNode(contextNode, event.target);
1968
- });
1969
1974
 
1970
- if (isTargetWithinAutocomplete === false) {
1971
- store.dispatch('blur', null); // If requests are still pending when the user closes the panel, they
1972
- // could reopen the panel once they resolve.
1973
- // We want to prevent any subsequent query from reopening the panel
1974
- // because it would result in an unsolicited UI behavior.
1975
+ var isTargetWithinAutocomplete = [formElement, panelElement].some(function (contextNode) {
1976
+ return isOrContainsNode(contextNode, event.target);
1977
+ });
1978
+
1979
+ if (isTargetWithinAutocomplete === false) {
1980
+ store.dispatch('blur', null); // If requests are still pending when the user closes the panel, they
1981
+ // could reopen the panel once they resolve.
1982
+ // We want to prevent any subsequent query from reopening the panel
1983
+ // because it would result in an unsolicited UI behavior.
1975
1984
 
1976
- if (!props.debug) {
1977
- store.pendingRequests.cancelAll();
1978
- }
1985
+ if (!props.debug) {
1986
+ store.pendingRequests.cancelAll();
1979
1987
  }
1980
- },
1988
+ }
1989
+ }
1990
+
1991
+ return _objectSpread$6({
1992
+ // We do not rely on the native `blur` event of the input to close the
1993
+ // panel, but rather on a custom `touchstart`/`mousedown` event outside
1994
+ // of the autocomplete elements.
1995
+ // This ensures we don't mistakenly interpret interactions within the
1996
+ // autocomplete (but outside of the input) as a signal to close the panel.
1997
+ // For example, clicking reset button causes an input blur, but if
1998
+ // `openOnFocus=true`, it shouldn't close the panel.
1999
+ // On touch devices, scrolling results (`touchmove`) causes an input blur
2000
+ // but shouldn't close the panel.
2001
+ onTouchStart: onMouseDownOrTouchStart,
2002
+ onMouseDown: onMouseDownOrTouchStart,
1981
2003
  // When scrolling on touch devices (mobiles, tablets, etc.), we want to
1982
2004
  // mimic the native platform behavior where the input is blurred to
1983
2005
  // hide the virtual keyboard. This gives more vertical space to
@@ -2056,8 +2078,6 @@
2056
2078
  store.dispatch('focus', null);
2057
2079
  }
2058
2080
 
2059
- var isTouchDevice = ('ontouchstart' in props.environment);
2060
-
2061
2081
  var _ref2 = providedProps || {};
2062
2082
  _ref2.inputElement;
2063
2083
  var _ref2$maxLength = _ref2.maxLength,
@@ -2065,7 +2085,7 @@
2065
2085
  rest = _objectWithoutProperties$1(_ref2, _excluded4);
2066
2086
 
2067
2087
  var activeItem = getActiveItem(store.getState());
2068
- var userAgent = (_props$environment$na = props.environment.navigator) === null || _props$environment$na === void 0 ? void 0 : _props$environment$na.userAgent;
2088
+ var userAgent = ((_props$environment$na = props.environment.navigator) === null || _props$environment$na === void 0 ? void 0 : _props$environment$na.userAgent) || '';
2069
2089
  var shouldFallbackKeyHint = isSamsung(userAgent);
2070
2090
  var enterKeyHint = activeItem !== null && activeItem !== void 0 && activeItem.itemUrl && !shouldFallbackKeyHint ? 'go' : 'search';
2071
2091
  return _objectSpread$6({
@@ -2102,20 +2122,10 @@
2102
2122
  }, setters));
2103
2123
  },
2104
2124
  onFocus: onFocus,
2105
- onBlur: function onBlur() {
2106
- // We do rely on the `blur` event on touch devices.
2107
- // See explanation in `onTouchStart`.
2108
- if (!isTouchDevice) {
2109
- store.dispatch('blur', null); // If requests are still pending when the user closes the panel, they
2110
- // could reopen the panel once they resolve.
2111
- // We want to prevent any subsequent query from reopening the panel
2112
- // because it would result in an unsolicited UI behavior.
2113
-
2114
- if (!props.debug) {
2115
- store.pendingRequests.cancelAll();
2116
- }
2117
- }
2118
- },
2125
+ // We don't rely on the `blur` event.
2126
+ // See explanation in `onTouchStart`/`onMouseDown`.
2127
+ // @MAJOR See if we need to keep this handler.
2128
+ onBlur: noop,
2119
2129
  onClick: function onClick(event) {
2120
2130
  // When the panel is closed and you click on the input while
2121
2131
  // the input is focused, the `onFocus` event is not triggered
@@ -2311,11 +2321,11 @@
2311
2321
  };
2312
2322
  }
2313
2323
  function injectMetadata(_ref3) {
2314
- var _environment$navigato;
2324
+ var _environment$navigato, _environment$navigato2;
2315
2325
 
2316
2326
  var metadata = _ref3.metadata,
2317
2327
  environment = _ref3.environment;
2318
- var isMetadataEnabled = (_environment$navigato = environment.navigator) === null || _environment$navigato === void 0 ? void 0 : _environment$navigato.userAgent.includes('Algolia Crawler');
2328
+ var isMetadataEnabled = (_environment$navigato = environment.navigator) === null || _environment$navigato === void 0 ? void 0 : (_environment$navigato2 = _environment$navigato.userAgent) === null || _environment$navigato2 === void 0 ? void 0 : _environment$navigato2.includes('Algolia Crawler');
2319
2329
 
2320
2330
  if (isMetadataEnabled) {
2321
2331
  var metadataContainer = environment.document.createElement('meta');
@@ -2851,14 +2861,14 @@
2851
2861
  };
2852
2862
  }
2853
2863
 
2854
- var _excluded$3 = ["autocompleteScopeApi", "environment", "classNames", "getInputProps", "getInputPropsCore", "onDetachedEscape", "state"];
2864
+ var _excluded$3 = ["autocompleteScopeApi", "environment", "classNames", "getInputProps", "getInputPropsCore", "isDetached", "state"];
2855
2865
  var Input = function Input(_ref) {
2856
2866
  var autocompleteScopeApi = _ref.autocompleteScopeApi,
2857
2867
  environment = _ref.environment;
2858
2868
  _ref.classNames;
2859
2869
  var getInputProps = _ref.getInputProps,
2860
2870
  getInputPropsCore = _ref.getInputPropsCore,
2861
- onDetachedEscape = _ref.onDetachedEscape,
2871
+ isDetached = _ref.isDetached,
2862
2872
  state = _ref.state,
2863
2873
  props = _objectWithoutProperties$4(_ref, _excluded$3);
2864
2874
 
@@ -2873,9 +2883,8 @@
2873
2883
  }, autocompleteScopeApi));
2874
2884
  setProperties(element, _objectSpread2(_objectSpread2({}, inputProps), {}, {
2875
2885
  onKeyDown: function onKeyDown(event) {
2876
- if (onDetachedEscape && event.key === 'Escape') {
2877
- event.preventDefault();
2878
- onDetachedEscape();
2886
+ // In detached mode we don't want to close the panel when hittin `Tab`.
2887
+ if (isDetached && event.key === 'Tab') {
2879
2888
  return;
2880
2889
  }
2881
2890
 
@@ -2981,10 +2990,7 @@
2981
2990
  getInputProps: propGetters.getInputProps,
2982
2991
  getInputPropsCore: autocomplete.getInputProps,
2983
2992
  autocompleteScopeApi: autocompleteScopeApi,
2984
- onDetachedEscape: isDetached ? function () {
2985
- autocomplete.setIsOpen(false);
2986
- setIsModalOpen(false);
2987
- } : undefined
2993
+ isDetached: isDetached
2988
2994
  });
2989
2995
  var inputWrapperPrefix = createDomElement('div', {
2990
2996
  class: classNames.inputWrapperPrefix,
@@ -3773,7 +3779,7 @@
3773
3779
 
3774
3780
  var containerElement = getHTMLElement(environment, container);
3775
3781
  invariant(containerElement.tagName !== 'INPUT', 'The `container` option does not support `input` elements. You need to change the container to a `div`.');
3776
- "development" !== 'production' ? warn(!(render && renderer && !(renderer !== null && renderer !== void 0 && renderer.render)), "You provided the `render` option but did not provide a `renderer.render`. Since v1.6.0, you can provide a `render` function directly in `renderer`." + "\nTo get rid of this warning, do any of the following depending on your use case." + "\n- If you are using the `render` option only to override Autocomplete's default `render` function, pass the `render` function into `renderer` and remove the `render` option." + '\n- If you are using the `render` option to customize the layout, pass your `render` function into `renderer` and use it from the provided parameters of the `render` option.' + '\nSee https://www.algolia.com/doc/ui-libraries/autocomplete/api-reference/autocomplete-js/autocomplete/#param-render') : void 0;
3782
+ "development" !== 'production' ? warn(!(render && renderer && !(renderer !== null && renderer !== void 0 && renderer.render)), "You provided the `render` option but did not provide a `renderer.render`. Since v1.6.0, you can provide a `render` function directly in `renderer`." + "\nTo get rid of this warning, do any of the following depending on your use case." + "\n- If you are using the `render` option only to override Autocomplete's default `render` function, pass the `render` function into `renderer` and remove the `render` option." + '\n- If you are using the `render` option to customize the layout, pass your `render` function into `renderer` and use it from the provided parameters of the `render` option.' + '\n- If you are using the `render` option to work with React 18, pass an empty `render` function into `renderer`.' + '\nSee https://www.algolia.com/doc/ui-libraries/autocomplete/api-reference/autocomplete-js/autocomplete/#param-render') : void 0;
3777
3783
  "development" !== 'production' ? warn(!renderer || render || renderer.Fragment && renderer.createElement && renderer.render, "You provided an incomplete `renderer` (missing: ".concat([!(renderer !== null && renderer !== void 0 && renderer.createElement) && '`renderer.createElement`', !(renderer !== null && renderer !== void 0 && renderer.Fragment) && '`renderer.Fragment`', !(renderer !== null && renderer !== void 0 && renderer.render) && '`renderer.render`'].filter(Boolean).join(', '), "). This can cause rendering issues.") + '\nSee https://www.algolia.com/doc/ui-libraries/autocomplete/api-reference/autocomplete-js/autocomplete/#param-renderer') : void 0;
3778
3784
 
3779
3785
  var defaultedRenderer = _objectSpread2(_objectSpread2({}, defaultRenderer), renderer);