@codecademy/gamut

72.2.272.2.3-alpha.f0a032.0
dist/Form/SelectDropdown/hooks/useSelectHandlers.js
+dist/Form/SelectDropdown/hooks/useSelectHandlers.jsNew file
+62
Index: package/dist/Form/SelectDropdown/hooks/useSelectHandlers.js
===================================================================
--- package/dist/Form/SelectDropdown/hooks/useSelectHandlers.js
+++ package/dist/Form/SelectDropdown/hooks/useSelectHandlers.js
@@ -0,0 +1,62 @@
+import { useCallback, useEffect, useState } from 'react';
+import { ON_CHANGE_ACTION } from '../core/constants';
+import { filterValueFromOptions, getCreatedOptionValue, isMultipleSelectProps, isOptionsGrouped, isSingleSelectProps, removeValueFromSelectedOptions } from '../core/utils';
+export const useSelectHandlers = ({
+  onChange,
+  multiple,
+  onCreateOption,
+  selectOptions,
+  value,
+  currentFocusedValue,
+  removeAllButtonRef
+}) => {
+  const [activated, setActivated] = useState(false);
+  const [multiValues, setMultiValues] = useState(multiple ? filterValueFromOptions(selectOptions, value, isOptionsGrouped(selectOptions)) : false);
+
+  // Sync multi-select value from props when controlled (`value` is a string[]).
+  // Uncontrolled multi (`value` undefined or '') keeps selection in local state.
+  useEffect(() => {
+    if (!multiple || !Array.isArray(value)) return;
+    const newMultiValues = filterValueFromOptions(selectOptions, value, isOptionsGrouped(selectOptions));
+    if (newMultiValues !== multiValues) setMultiValues(newMultiValues);
+
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+  }, [selectOptions, value, multiple]);
+  const changeHandler = useCallback((optionEvent, actionMeta) => {
+    setActivated(true);
+    if (actionMeta.action === 'create-option') {
+      const createdValue = getCreatedOptionValue(optionEvent, actionMeta, multiple);
+      if (createdValue) onCreateOption?.(createdValue);
+    }
+    const onChangeProps = {
+      onChange,
+      multiple
+    };
+    const forwardedMeta = actionMeta.action === 'create-option' ? actionMeta : {
+      action: ON_CHANGE_ACTION,
+      option: isMultipleSelectProps(onChangeProps) ? undefined : optionEvent
+    };
+    if (isSingleSelectProps(onChangeProps)) {
+      onChangeProps.onChange?.(optionEvent, forwardedMeta);
+    }
+    if (isMultipleSelectProps(onChangeProps)) {
+      setMultiValues(optionEvent);
+      onChangeProps.onChange?.(optionEvent, forwardedMeta);
+    }
+  }, [onChange, multiple, onCreateOption]);
+  const keyPressHandler = e => {
+    if (multiple && e.key === 'Enter' && currentFocusedValue && multiValues) {
+      const newMultiValues = removeValueFromSelectedOptions(multiValues, currentFocusedValue);
+      if (newMultiValues !== multiValues) setMultiValues(newMultiValues);
+    }
+    if (removeAllButtonRef.current !== null && e.key === 'ArrowRight' && multiValues && currentFocusedValue === multiValues[multiValues.length - 1].value) {
+      removeAllButtonRef.current.focus();
+    }
+  };
+  return {
+    activated,
+    multiValues,
+    changeHandler,
+    keyPressHandler
+  };
+};
\ No newline at end of file