From 41c2302432a95cb567508203d5dc3aa362fc01f4 Mon Sep 17 00:00:00 2001
From: Zheng Song <szhsin9@gmail.com>
Date: Sat, 20 Jul 2024 17:21:04 +1000
Subject: [PATCH] Remove optional-chaining transform (#47)

---
 babel.config.js                            |  6 +--
 dist/cjs/index.js                          | 47 +++++++++-------------
 dist/esm/features/atom/autocompleteLite.js | 15 ++++---
 dist/esm/features/atom/dropdownToggle.js   |  8 +---
 dist/esm/features/atom/multiInput.js       |  2 +-
 dist/esm/hooks/useAutocomplete.js          |  2 +-
 dist/esm/hooks/useCombobox.js              |  4 +-
 dist/esm/hooks/useFocusCapture.js          |  8 +---
 dist/esm/hooks/useMultiSelect.js           |  8 ++--
 package.json                               |  2 +-
 src/features/atom/autocompleteLite.ts      |  2 +-
 src/hooks/useMultiSelect.ts                |  8 ++--
 src/types.ts                               |  2 +-
 types/hooks/useMultiSelect.d.ts            |  2 +-
 types/types.d.ts                           |  2 +-
 15 files changed, 48 insertions(+), 70 deletions(-)

diff --git a/babel.config.js b/babel.config.js
index 8a3ea20..c8cabf9 100644
--- a/babel.config.js
+++ b/babel.config.js
@@ -21,11 +21,7 @@ module.exports = {
       '@babel/preset-env',
       {
         bugfixes: true,
-        include: [
-          '@babel/plugin-proposal-optional-chaining',
-          '@babel/plugin-proposal-nullish-coalescing-operator',
-          '@babel/plugin-proposal-optional-catch-binding'
-        ],
+        include: ['@babel/plugin-transform-optional-catch-binding'],
         exclude: ['@babel/plugin-transform-typeof-symbol']
       }
     ],
diff --git a/dist/cjs/index.js b/dist/cjs/index.js
index d9b514d..3e47e51 100644
--- a/dist/cjs/index.js
+++ b/dist/cjs/index.js
@@ -41,7 +41,7 @@ const useAutocomplete = ({
     id: useId(),
     tmpValue,
     setTmpValue,
-    onChange: newValue => passthrough.value != newValue && (onChange == null ? void 0 : onChange(newValue)),
+    onChange: newValue => passthrough.value != newValue && onChange?.(newValue),
     ...passthrough,
     ...state
   });
@@ -68,9 +68,9 @@ const useCombobox = ({
     getSelectedValue: () => getItemValue(selected),
     onSelectChange: newItem => {
       if (!isEqual(newItem, selected)) {
-        onSelectChange == null || onSelectChange(newItem);
+        onSelectChange?.(newItem);
       } else if (flipOnSelect) {
-        onSelectChange == null || onSelectChange();
+        onSelectChange?.();
       }
     }
   });
@@ -80,16 +80,16 @@ const useMultiSelect = ({
   isEqual = defaultEqual,
   getItemValue,
   selected,
-  onSelectChange: _onSelectChange = () => {},
+  onSelectChange,
   flipOnSelect,
   ...passthrough
 }) => {
-  const removeItem = itemToRemove => _onSelectChange(selected.filter(item => !isEqual(itemToRemove, item)));
+  const removeItem = itemToRemove => onSelectChange?.(selected.filter(item => !isEqual(itemToRemove, item)));
   const removeSelect = item => {
     if (item) {
       removeItem(item);
     } else {
-      selected.length && _onSelectChange(selected.slice(0, selected.length - 1));
+      selected.length && onSelectChange?.(selected.slice(0, selected.length - 1));
     }
   };
   return {
@@ -102,7 +102,7 @@ const useMultiSelect = ({
       onSelectChange: newItem => {
         if (!newItem) return;
         if (selected.findIndex(item => isEqual(item, newItem)) < 0) {
-          _onSelectChange([...selected, newItem]);
+          onSelectChange?.([...selected, newItem]);
         } else if (flipOnSelect) {
           removeItem(newItem);
         }
@@ -154,18 +154,14 @@ const useFocusCapture = focusRef => {
     if (document.activeElement === focusRef.current) mutable.a = 1;
   }, () => {
     if (mutable.a) {
-      var _focusRef$current;
       mutable.a = 0;
-      (_focusRef$current = focusRef.current) == null || _focusRef$current.focus();
+      focusRef.current?.focus();
       return true;
     }
-  }, () => {
-    var _focusRef$current2;
-    return (_focusRef$current2 = focusRef.current) == null ? void 0 : _focusRef$current2.focus();
-  }];
+  }, () => focusRef.current?.focus()];
 };
 
-const scrollIntoView = element => element == null ? void 0 : element.scrollIntoView({
+const scrollIntoView = element => element?.scrollIntoView({
   block: 'nearest'
 });
 const autocompleteLite = ({
@@ -196,18 +192,17 @@ const autocompleteLite = ({
   items,
   id
 }) => {
-  var _ref;
   const [startCapture, inCapture, stopCapture] = useFocusCapture(inputRef);
-  const inputValue = (_ref = tmpValue || value) != null ? _ref : getSelectedValue();
+  const inputValue = (tmpValue || value) ?? getSelectedValue();
   const selectItemOrAction = (item, noAction) => {
-    if (isItemAction != null && isItemAction(item)) {
-      !noAction && (onAction == null ? void 0 : onAction(item));
+    if (isItemAction?.(item)) {
+      !noAction && onAction?.(item);
       return true;
     }
     const itemValue = getItemValue(item);
     if (!select) onChange(itemValue);
     const endIndex = itemValue.length;
-    inputRef.current.setSelectionRange(endIndex, endIndex);
+    inputRef.current?.setSelectionRange(endIndex, endIndex);
     onSelectChange(item);
   };
   const resetState = shouldClose => {
@@ -231,7 +226,7 @@ const autocompleteLite = ({
         if (--nextIndex < baseIndex) nextIndex = itemLength - 1;
       }
       newItem = items[nextIndex];
-      if (!newItem || !(isItemDisabled != null && isItemDisabled(newItem))) break;
+      if (!newItem || !isItemDisabled?.(newItem)) break;
       if (++itemCounter >= itemLength) return;
     }
     setFocusItem(newItem);
@@ -272,7 +267,7 @@ const autocompleteLite = ({
       'aria-selected': select ? isItemSelected(item) : isEqual(item, focusItem),
       ref: isEqual(item, focusItem) ? scrollIntoView : null,
       onClick: () => {
-        if (!(isItemDisabled != null && isItemDisabled(item))) {
+        if (!isItemDisabled?.(item)) {
           resetState(selectItemOrAction(item));
         }
       }
@@ -454,13 +449,9 @@ const dropdownToggle = ({
   const toggleRef = React.useRef(null);
   const inputValue = tmpValue || value || '';
   React.useEffect(() => {
-    var _inputRef$current;
-    if (open) (_inputRef$current = inputRef.current) == null || _inputRef$current.focus();
+    if (open) inputRef.current?.focus();
   }, [open, inputRef]);
-  const focusToggle = () => setTimeout(() => {
-    var _toggleRef$current;
-    return (_toggleRef$current = toggleRef.current) == null ? void 0 : _toggleRef$current.focus();
-  }, 0);
+  const focusToggle = () => setTimeout(() => toggleRef.current?.focus(), 0);
   return {
     isInputEmpty: !inputValue,
     getToggleProps: () => ({
@@ -523,7 +514,7 @@ const multiInput = () => ({
     }),
     getInputProps: () => ({
       onBlur: inCapture,
-      onKeyDown: e => !e.target.value && e.key === 'Backspace' && (removeSelect == null ? void 0 : removeSelect())
+      onKeyDown: e => !e.target.value && e.key === 'Backspace' && removeSelect?.()
     })
   };
 };
diff --git a/dist/esm/features/atom/autocompleteLite.js b/dist/esm/features/atom/autocompleteLite.js
index 5759761..ad818f6 100644
--- a/dist/esm/features/atom/autocompleteLite.js
+++ b/dist/esm/features/atom/autocompleteLite.js
@@ -1,7 +1,7 @@
 import { ButtonProps, getId } from '../../common.js';
 import { useFocusCapture } from '../../hooks/useFocusCapture.js';
 
-const scrollIntoView = element => element == null ? void 0 : element.scrollIntoView({
+const scrollIntoView = element => element?.scrollIntoView({
   block: 'nearest'
 });
 const autocompleteLite = ({
@@ -32,18 +32,17 @@ const autocompleteLite = ({
   items,
   id
 }) => {
-  var _ref;
   const [startCapture, inCapture, stopCapture] = useFocusCapture(inputRef);
-  const inputValue = (_ref = tmpValue || value) != null ? _ref : getSelectedValue();
+  const inputValue = (tmpValue || value) ?? getSelectedValue();
   const selectItemOrAction = (item, noAction) => {
-    if (isItemAction != null && isItemAction(item)) {
-      !noAction && (onAction == null ? void 0 : onAction(item));
+    if (isItemAction?.(item)) {
+      !noAction && onAction?.(item);
       return true;
     }
     const itemValue = getItemValue(item);
     if (!select) onChange(itemValue);
     const endIndex = itemValue.length;
-    inputRef.current.setSelectionRange(endIndex, endIndex);
+    inputRef.current?.setSelectionRange(endIndex, endIndex);
     onSelectChange(item);
   };
   const resetState = shouldClose => {
@@ -67,7 +66,7 @@ const autocompleteLite = ({
         if (--nextIndex < baseIndex) nextIndex = itemLength - 1;
       }
       newItem = items[nextIndex];
-      if (!newItem || !(isItemDisabled != null && isItemDisabled(newItem))) break;
+      if (!newItem || !isItemDisabled?.(newItem)) break;
       if (++itemCounter >= itemLength) return;
     }
     setFocusItem(newItem);
@@ -108,7 +107,7 @@ const autocompleteLite = ({
       'aria-selected': select ? isItemSelected(item) : isEqual(item, focusItem),
       ref: isEqual(item, focusItem) ? scrollIntoView : null,
       onClick: () => {
-        if (!(isItemDisabled != null && isItemDisabled(item))) {
+        if (!isItemDisabled?.(item)) {
           resetState(selectItemOrAction(item));
         }
       }
diff --git a/dist/esm/features/atom/dropdownToggle.js b/dist/esm/features/atom/dropdownToggle.js
index c6956a0..88e4eb3 100644
--- a/dist/esm/features/atom/dropdownToggle.js
+++ b/dist/esm/features/atom/dropdownToggle.js
@@ -15,13 +15,9 @@ const dropdownToggle = ({
   const toggleRef = useRef(null);
   const inputValue = tmpValue || value || '';
   useEffect(() => {
-    var _inputRef$current;
-    if (open) (_inputRef$current = inputRef.current) == null || _inputRef$current.focus();
+    if (open) inputRef.current?.focus();
   }, [open, inputRef]);
-  const focusToggle = () => setTimeout(() => {
-    var _toggleRef$current;
-    return (_toggleRef$current = toggleRef.current) == null ? void 0 : _toggleRef$current.focus();
-  }, 0);
+  const focusToggle = () => setTimeout(() => toggleRef.current?.focus(), 0);
   return {
     isInputEmpty: !inputValue,
     getToggleProps: () => ({
diff --git a/dist/esm/features/atom/multiInput.js b/dist/esm/features/atom/multiInput.js
index cfb7ec2..ede64ab 100644
--- a/dist/esm/features/atom/multiInput.js
+++ b/dist/esm/features/atom/multiInput.js
@@ -12,7 +12,7 @@ const multiInput = () => ({
     }),
     getInputProps: () => ({
       onBlur: inCapture,
-      onKeyDown: e => !e.target.value && e.key === 'Backspace' && (removeSelect == null ? void 0 : removeSelect())
+      onKeyDown: e => !e.target.value && e.key === 'Backspace' && removeSelect?.()
     })
   };
 };
diff --git a/dist/esm/hooks/useAutocomplete.js b/dist/esm/hooks/useAutocomplete.js
index 5bd0831..3b7cab6 100644
--- a/dist/esm/hooks/useAutocomplete.js
+++ b/dist/esm/hooks/useAutocomplete.js
@@ -23,7 +23,7 @@ const useAutocomplete = ({
     id: useId(),
     tmpValue,
     setTmpValue,
-    onChange: newValue => passthrough.value != newValue && (onChange == null ? void 0 : onChange(newValue)),
+    onChange: newValue => passthrough.value != newValue && onChange?.(newValue),
     ...passthrough,
     ...state
   });
diff --git a/dist/esm/hooks/useCombobox.js b/dist/esm/hooks/useCombobox.js
index e0bb031..4d7127b 100644
--- a/dist/esm/hooks/useCombobox.js
+++ b/dist/esm/hooks/useCombobox.js
@@ -19,9 +19,9 @@ const useCombobox = ({
     getSelectedValue: () => getItemValue(selected),
     onSelectChange: newItem => {
       if (!isEqual(newItem, selected)) {
-        onSelectChange == null || onSelectChange(newItem);
+        onSelectChange?.(newItem);
       } else if (flipOnSelect) {
-        onSelectChange == null || onSelectChange();
+        onSelectChange?.();
       }
     }
   });
diff --git a/dist/esm/hooks/useFocusCapture.js b/dist/esm/hooks/useFocusCapture.js
index 420870f..b0c3707 100644
--- a/dist/esm/hooks/useFocusCapture.js
+++ b/dist/esm/hooks/useFocusCapture.js
@@ -6,15 +6,11 @@ const useFocusCapture = focusRef => {
     if (document.activeElement === focusRef.current) mutable.a = 1;
   }, () => {
     if (mutable.a) {
-      var _focusRef$current;
       mutable.a = 0;
-      (_focusRef$current = focusRef.current) == null || _focusRef$current.focus();
+      focusRef.current?.focus();
       return true;
     }
-  }, () => {
-    var _focusRef$current2;
-    return (_focusRef$current2 = focusRef.current) == null ? void 0 : _focusRef$current2.focus();
-  }];
+  }, () => focusRef.current?.focus()];
 };
 
 export { useFocusCapture };
diff --git a/dist/esm/hooks/useMultiSelect.js b/dist/esm/hooks/useMultiSelect.js
index d7b8c9d..83790ab 100644
--- a/dist/esm/hooks/useMultiSelect.js
+++ b/dist/esm/hooks/useMultiSelect.js
@@ -6,16 +6,16 @@ const useMultiSelect = ({
   isEqual = defaultEqual,
   getItemValue,
   selected,
-  onSelectChange: _onSelectChange = () => {},
+  onSelectChange,
   flipOnSelect,
   ...passthrough
 }) => {
-  const removeItem = itemToRemove => _onSelectChange(selected.filter(item => !isEqual(itemToRemove, item)));
+  const removeItem = itemToRemove => onSelectChange?.(selected.filter(item => !isEqual(itemToRemove, item)));
   const removeSelect = item => {
     if (item) {
       removeItem(item);
     } else {
-      selected.length && _onSelectChange(selected.slice(0, selected.length - 1));
+      selected.length && onSelectChange?.(selected.slice(0, selected.length - 1));
     }
   };
   return {
@@ -28,7 +28,7 @@ const useMultiSelect = ({
       onSelectChange: newItem => {
         if (!newItem) return;
         if (selected.findIndex(item => isEqual(item, newItem)) < 0) {
-          _onSelectChange([...selected, newItem]);
+          onSelectChange?.([...selected, newItem]);
         } else if (flipOnSelect) {
           removeItem(newItem);
         }
diff --git a/package.json b/package.json
index d2e183e..30ab3fd 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@szhsin/react-autocomplete",
-  "version": "0.9.5",
+  "version": "0.9.6",
   "description": "",
   "author": "Zheng Song",
   "license": "MIT",
diff --git a/src/features/atom/autocompleteLite.ts b/src/features/atom/autocompleteLite.ts
index 2ca0e15..78a5b98 100644
--- a/src/features/atom/autocompleteLite.ts
+++ b/src/features/atom/autocompleteLite.ts
@@ -61,7 +61,7 @@ const autocompleteLite =
       const itemValue = getItemValue(item);
       if (!select) onChange(itemValue);
       const endIndex = itemValue.length;
-      inputRef.current!.setSelectionRange(endIndex, endIndex);
+      inputRef.current?.setSelectionRange(endIndex, endIndex);
       // We place onSelectChange after onChange to give user an opportunity
       // to manipulate the `value` state
       onSelectChange(item);
diff --git a/src/hooks/useMultiSelect.ts b/src/hooks/useMultiSelect.ts
index 81cc2e9..ac4ef57 100644
--- a/src/hooks/useMultiSelect.ts
+++ b/src/hooks/useMultiSelect.ts
@@ -7,18 +7,18 @@ const useMultiSelect = <T, FeatureYield extends object>({
   isEqual = defaultEqual,
   getItemValue,
   selected,
-  onSelectChange: _onSelectChange = () => {},
+  onSelectChange,
   flipOnSelect,
   ...passthrough
 }: MultiSelectProps<T, FeatureYield>) => {
   const removeItem = (itemToRemove: T) =>
-    _onSelectChange(selected.filter((item) => !isEqual(itemToRemove, item)));
+    onSelectChange?.(selected.filter((item) => !isEqual(itemToRemove, item)));
 
   const removeSelect: AdapterProps<T>['removeSelect'] = (item) => {
     if (item) {
       removeItem(item);
     } else {
-      selected.length && _onSelectChange(selected.slice(0, selected.length - 1));
+      selected.length && onSelectChange?.(selected.slice(0, selected.length - 1));
     }
   };
 
@@ -33,7 +33,7 @@ const useMultiSelect = <T, FeatureYield extends object>({
         if (!newItem) return;
 
         if (selected.findIndex((item) => isEqual(item, newItem)) < 0) {
-          _onSelectChange([...selected, newItem]);
+          onSelectChange?.([...selected, newItem]);
         } else if (flipOnSelect) {
           removeItem(newItem);
         }
diff --git a/src/types.ts b/src/types.ts
index 852b7eb..547435e 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -45,7 +45,7 @@ export interface PassthroughProps<T> {
   isItemDisabled?: (item: T) => boolean;
   isItemAction?: (item: T) => boolean;
   onAction?: (item: T) => void;
-  value?: string | undefined;
+  value: string | undefined;
   onChange: (value?: string | undefined) => void;
   items: T[];
 }
diff --git a/types/hooks/useMultiSelect.d.ts b/types/hooks/useMultiSelect.d.ts
index 8ec4dc4..ee690a8 100644
--- a/types/hooks/useMultiSelect.d.ts
+++ b/types/hooks/useMultiSelect.d.ts
@@ -1,6 +1,6 @@
 /// <reference types="react" />
 import type { MultiSelectProps } from '../types';
-declare const useMultiSelect: <T, FeatureYield extends object>({ isEqual, getItemValue, selected, onSelectChange: _onSelectChange, flipOnSelect, ...passthrough }: MultiSelectProps<T, FeatureYield>) => {
+declare const useMultiSelect: <T, FeatureYield extends object>({ isEqual, getItemValue, selected, onSelectChange, flipOnSelect, ...passthrough }: MultiSelectProps<T, FeatureYield>) => {
     inputRef: import("react").RefObject<HTMLInputElement>;
     focusItem: T | undefined;
     setFocusItem: (item?: T | undefined) => void;
diff --git a/types/types.d.ts b/types/types.d.ts
index a49a7b3..31a5a20 100644
--- a/types/types.d.ts
+++ b/types/types.d.ts
@@ -34,7 +34,7 @@ export interface PassthroughProps<T> {
     isItemDisabled?: (item: T) => boolean;
     isItemAction?: (item: T) => boolean;
     onAction?: (item: T) => void;
-    value?: string | undefined;
+    value: string | undefined;
     onChange: (value?: string | undefined) => void;
     items: T[];
 }