@primer/components
Version:
Primer react components
123 lines (114 loc) • 2.85 kB
JavaScript
import React, { useCallback, useReducer, useRef } from 'react';
import { useSSRSafeId } from '@react-aria/ssr';
import { AutocompleteContext } from './AutocompleteContext';
import AutocompleteInput from './AutocompleteInput';
import AutocompleteMenu from './AutocompleteMenu';
import AutocompleteOverlay from './AutocompleteOverlay';
const initialState = {
inputValue: '',
showMenu: false,
isMenuDirectlyActivated: false,
autocompleteSuggestion: '',
selectedItemLength: 0
};
const reducer = (state, action) => {
const {
type,
payload
} = action;
switch (type) {
case 'inputValue':
return { ...state,
inputValue: payload
};
case 'showMenu':
return { ...state,
showMenu: payload
};
case 'isMenuDirectlyActivated':
return { ...state,
isMenuDirectlyActivated: payload
};
case 'autocompleteSuggestion':
return { ...state,
autocompleteSuggestion: payload
};
case 'selectedItemLength':
return { ...state,
selectedItemLength: payload
};
default:
return state;
}
};
const Autocomplete = ({
children,
id: idProp
}) => {
const activeDescendantRef = useRef(null);
const scrollContainerRef = useRef(null);
const inputRef = useRef(null);
const [state, dispatch] = useReducer(reducer, initialState);
const {
inputValue,
showMenu,
autocompleteSuggestion,
isMenuDirectlyActivated,
selectedItemLength
} = state;
const setInputValue = useCallback(value => {
dispatch({
type: 'inputValue',
payload: value
});
}, []);
const setShowMenu = useCallback(value => {
dispatch({
type: 'showMenu',
payload: value
});
}, []);
const setAutocompleteSuggestion = useCallback(value => {
dispatch({
type: 'autocompleteSuggestion',
payload: value
});
}, []);
const setIsMenuDirectlyActivated = useCallback(value => {
dispatch({
type: 'isMenuDirectlyActivated',
payload: value
});
}, []);
const setSelectedItemLength = useCallback(value => {
dispatch({
type: 'selectedItemLength',
payload: value
});
}, []);
const id = useSSRSafeId(idProp);
return /*#__PURE__*/React.createElement(AutocompleteContext.Provider, {
value: {
activeDescendantRef,
autocompleteSuggestion,
id,
inputRef,
inputValue,
isMenuDirectlyActivated,
scrollContainerRef,
selectedItemLength,
setAutocompleteSuggestion,
setInputValue,
setIsMenuDirectlyActivated,
setShowMenu,
setSelectedItemLength,
showMenu
}
}, children);
};
Autocomplete.displayName = "Autocomplete";
export default Object.assign(Autocomplete, {
Input: AutocompleteInput,
Menu: AutocompleteMenu,
Overlay: AutocompleteOverlay
});