import { createContext, forwardRef, useContext } from 'react'; import ReactSelect from 'react-select'; import { useDisclosure } from '@chakra-ui/react'; import { useColorMode } from '~/context'; import { Option } from './option'; import { useRSTheme, useMenuStyle, useMenuPortal, useOptionStyle, useControlStyle, useMenuListStyle, useMultiValueStyle, usePlaceholderStyle, useSingleValueStyle, useMultiValueLabelStyle, useMultiValueRemoveStyle, useIndicatorSeparatorStyle, } from './styles'; import { isSingleValue } from './types'; import type { Props as ReactSelectProps, MultiValue, OnChangeValue, SelectInstance, } from 'react-select'; import type { SingleOption } from '~/types'; import type { TSelectBase, TSelectContext } from './types'; const SelectContext = createContext({} as TSelectContext); export const useSelectContext = (): TSelectContext => useContext(SelectContext); export const Select = forwardRef( ( props: TSelectBase, ref: React.Ref>, ): JSX.Element => { const { options, isMulti, onSelect, isError = false, components, ...rest } = props; const { isOpen, onOpen, onClose } = useDisclosure(); const { colorMode } = useColorMode(); const defaultOnChange: ReactSelectProps['onChange'] = changed => { if (isSingleValue(changed)) { changed = [changed] as unknown as OnChangeValue; } if (typeof onSelect === 'function') { onSelect(changed as MultiValue); } }; const menu = useMenuStyle({ colorMode }); const menuList = useMenuListStyle({ colorMode }); const control = useControlStyle({ colorMode }); const option = useOptionStyle({ colorMode }); const singleValue = useSingleValueStyle({ colorMode }); const multiValue = useMultiValueStyle({ colorMode }); const multiValueLabel = useMultiValueLabelStyle({ colorMode }); const multiValueRemove = useMultiValueRemoveStyle({ colorMode }); const menuPortal = useMenuPortal(); const placeholder = usePlaceholderStyle({ colorMode }); const indicatorSeparator = useIndicatorSeparatorStyle({ colorMode }); const rsTheme = useRSTheme(); return ( onChange={defaultOnChange} onMenuClose={onClose} onMenuOpen={onOpen} isClearable={true} options={options} isMulti={isMulti} theme={rsTheme} components={{ Option, ...components }} ref={ref} styles={{ menu, option, control, menuList, menuPortal, multiValue, singleValue, placeholder, multiValueLabel, multiValueRemove, indicatorSeparator, }} {...rest} /> ); }, );