<commit_before>import React, { useCallback, useEffect, useRef, useState } from 'react';
import { startsWith } from 'lodash/fp';
import { GlobalListeners } from 'react-polymorph/lib/components/HOC/GlobalListeners';
import { MnemonicAutocompleteLayout } from './MnemonicAutocompleteLayout';

interface MnemonicsAutocompleteContainerProps {
  onChange: (value: string) => void;
  ordinalNumber: number;
  value: string;
  options: string[];
  maxVisibleOptions: number;
  disabled: boolean;
  error: boolean;
  reset: boolean;
  noResultsMessage: string;
}

const MnemonicsAutocompleteContainer = ({
  onChange,
  reset,
  ordinalNumber,
  value,
  options,
  maxVisibleOptions,
  disabled,
  error,
  noResultsMessage,
}: MnemonicsAutocompleteContainerProps) => {
  const [state, setState] = useState({
    inputValue: value,
    selectedOption: '',
    filteredOptions: options.slice(0, maxVisibleOptions - 1),
    isOpen: false,
    mouseIsOverOptions: false,
  });
  const rootRef = useRef();
  const inputRef = useRef();
  const optionsRef = useRef();
  const suggestionsRef = useRef();

  const toggleOpen = useCallback(() => {
    if (disabled) return;
    setState((prevState) => ({ ...prevState, isOpen: !prevState.isOpen }));
  }, []);

  const toggleMouseIsOverOptions = useCallback(() => {
    setState((prevState) => ({
      ...prevState,
      mouseIsOverOptions: !prevState.mouseIsOverOptions,
    }));
  }, []);

  const handleInputChange = useCallback(
    (inputValue) => {
      if (disabled) return;

      let selectedOption = '';

      if (options.includes(inputValue)) {
        selectedOption = inputValue;
      }

      setState((prevState) => ({
        ...prevState,
        isOpen: true,
        filteredOptions: options
          .filter(startsWith(inputValue))
          .slice(0, maxVisibleOptions - 1),
        inputValue,
        selectedOption,
      }));
    },
    [options]
  );

  const handleInputSelect = useCallback((inputValue) => {
    if (disabled) return;

    setState((prevState) => ({
      ...prevState,
      isOpen: false,
      filteredOptions: [inputValue],
      selectedOption: inputValue,
      inputValue,
    }));
  }, []);

  const [blurred, setBlurred] = useState(false);
  const handleBlur = useCallback(() => {
    if (disabled) return;

    setBlurred(true);
  }, [setBlurred]);

  useEffect(() => {
    onChange(state.selectedOption);
  }, [state.selectedOption]);

  useEffect(() => {
    if (reset) {
      setBlurred(false);
    }
  }, [reset]);

  useEffect(() => {
    if (value !== state.inputValue) {
      setState((prevState) => ({ ...prevState, inputValue: value }));
    }
  }, [value]);

  return (
    <GlobalListeners
      mouseIsOverOptions={state.mouseIsOverOptions}
      optionsIsOpen={state.isOpen}
      optionsRef={optionsRef}
      rootRef={rootRef}
      toggleOpen={toggleOpen}
    >
      {({ optionsMaxHeight, optionHeight = 50 }) => (
        <MnemonicAutocompleteLayout
          ordinalNumber={ordinalNumber}
          value={state.inputValue}
          isOpen={state.isOpen}
          options={state.filteredOptions}
          optionsMaxHeight={optionsMaxHeight}
          noResultsMessage={noResultsMessage}
          rootRef={rootRef}
          inputRef={inputRef}
          optionsRef={optionsRef}
          onChange={handleInputChange}
          onSelect={handleInputSelect}
          onClick={toggleOpen}
          onBlur={handleBlur}
          suggestionsRef={suggestionsRef}
          toggleMouseLocation={toggleMouseIsOverOptions}
          toggleOpen={toggleOpen}
          optionHeight={optionHeight}
          disabled={disabled}
          error={blurred && error}
        />
      )}
    </GlobalListeners>
  );
};

export { MnemonicsAutocompleteContainer };
<commit_msg>[DDW-409] Fix form reset + unify state<commit_after>import React, {
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
} from 'react';
import { startsWith } from 'lodash/fp';
import { GlobalListeners } from 'react-polymorph/lib/components/HOC/GlobalListeners';
import { MnemonicAutocompleteLayout } from './MnemonicAutocompleteLayout';

interface MnemonicsAutocompleteContainerProps {
  onChange: (value: string) => void;
  ordinalNumber: number;
  value: string;
  options: string[];
  maxVisibleOptions: number;
  disabled: boolean;
  error: boolean;
  reset: boolean;
  noResultsMessage: string;
}

const MnemonicsAutocompleteContainer = ({
  onChange,
  reset,
  ordinalNumber,
  value,
  options,
  maxVisibleOptions,
  disabled,
  error,
  noResultsMessage,
}: MnemonicsAutocompleteContainerProps) => {
  const initialState = useMemo(
    () => ({
      inputValue: value,
      selectedOption: '',
      filteredOptions: options.slice(0, maxVisibleOptions - 1),
      isOpen: false,
      mouseIsOverOptions: false,
      blurred: false,
    }),
    []
  );
  const [state, setState] = useState(initialState);
  const rootRef = useRef();
  const inputRef = useRef();
  const optionsRef = useRef();
  const suggestionsRef = useRef();

  const toggleOpen = useCallback(() => {
    if (disabled) return;
    setState((prevState) => ({ ...prevState, isOpen: !prevState.isOpen }));
  }, [disabled]);

  const toggleMouseIsOverOptions = useCallback(() => {
    setState((prevState) => ({
      ...prevState,
      mouseIsOverOptions: !prevState.mouseIsOverOptions,
    }));
  }, []);

  const handleInputChange = useCallback(
    (inputValue) => {
      if (disabled) return;
      let selectedOption = '';

      if (options.includes(inputValue)) {
        selectedOption = inputValue;
      }

      setState((prevState) => ({
        ...prevState,
        isOpen: true,
        filteredOptions: options
          .filter(startsWith(inputValue))
          .slice(0, maxVisibleOptions - 1),
        inputValue,
        selectedOption,
      }));
    },
    [options, disabled]
  );

  const handleInputSelect = useCallback(
    (inputValue) => {
      if (disabled) return;
      setState((prevState) => ({
        ...prevState,
        isOpen: false,
        filteredOptions: [inputValue],
        selectedOption: inputValue,
        inputValue,
      }));
    },
    [disabled]
  );

  const handleBlur = useCallback(() => {
    if (disabled) return;
    setState((prevState) => ({ ...prevState, blurred: true }));
  }, [disabled]);

  useEffect(() => {
    onChange(state.selectedOption);
  }, [state.selectedOption]);

  useEffect(() => {
    if (reset) {
      setState(initialState);
    }
  }, [reset]);

  return (
    <GlobalListeners
      mouseIsOverOptions={state.mouseIsOverOptions}
      optionsIsOpen={state.isOpen}
      optionsRef={optionsRef}
      rootRef={rootRef}
      toggleOpen={toggleOpen}
    >
      {({ optionsMaxHeight, optionHeight = 50 }) => (
        <MnemonicAutocompleteLayout
          ordinalNumber={ordinalNumber}
          value={state.inputValue}
          isOpen={state.isOpen}
          options={state.filteredOptions}
          optionsMaxHeight={optionsMaxHeight}
          noResultsMessage={noResultsMessage}
          rootRef={rootRef}
          inputRef={inputRef}
          optionsRef={optionsRef}
          onChange={handleInputChange}
          onSelect={handleInputSelect}
          onClick={toggleOpen}
          onBlur={handleBlur}
          suggestionsRef={suggestionsRef}
          toggleMouseLocation={toggleMouseIsOverOptions}
          toggleOpen={toggleOpen}
          optionHeight={optionHeight}
          disabled={disabled}
          error={state.blurred && error}
        />
      )}
    </GlobalListeners>
  );
};

export { MnemonicsAutocompleteContainer };

{'fraction_non_alphanumeric': 0.12864651773981603, 'fraction_numerical': 0.0019710906701708277, 'mean_word_length': 2.903076923076923, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5567504', 'n_tokens_mistral': 2241, 'n_tokens_neox': 2200, 'n_words': 409}