mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
72 lines
2.4 KiB
TypeScript
72 lines
2.4 KiB
TypeScript
import { FormControl, useToken, useColorMode } from '@chakra-ui/react';
|
|
import type { CSSObjectWithLabel, GroupBase, SingleValue, MultiValue, AsyncProps, Props as SelectProps } from 'chakra-react-select';
|
|
import { Select, AsyncSelect } from 'chakra-react-select';
|
|
import React from 'react';
|
|
import type { FieldError, FieldErrorsImpl, Merge } from 'react-hook-form';
|
|
|
|
import type { Option } from './types';
|
|
|
|
import { getChakraStyles } from 'ui/shared/FancySelect/utils';
|
|
import InputPlaceholder from 'ui/shared/InputPlaceholder';
|
|
|
|
interface CommonProps {
|
|
error?: Merge<FieldError, FieldErrorsImpl<Option>> | undefined;
|
|
placeholderIcon?: React.ReactNode;
|
|
}
|
|
|
|
interface RegularSelectProps extends SelectProps<Option, boolean, GroupBase<Option>>, CommonProps {
|
|
isAsync?: false;
|
|
onChange: (newValue: SingleValue<Option> | MultiValue<Option>) => void;
|
|
}
|
|
|
|
interface AsyncSelectProps extends AsyncProps<Option, boolean, GroupBase<Option>>, CommonProps {
|
|
isAsync: true;
|
|
onChange: (newValue: SingleValue<Option> | MultiValue<Option>) => void;
|
|
}
|
|
|
|
type Props = RegularSelectProps | AsyncSelectProps;
|
|
|
|
const FancySelect = (props: Props, ref: React.LegacyRef<HTMLDivElement>) => {
|
|
const menuZIndex = useToken('zIndices', 'dropdown');
|
|
const { colorMode } = useColorMode();
|
|
|
|
const styles = React.useMemo(() => ({
|
|
menuPortal: (provided: CSSObjectWithLabel) => ({ ...provided, zIndex: menuZIndex }),
|
|
}), [ menuZIndex ]);
|
|
|
|
const chakraStyles = React.useMemo(() => getChakraStyles(colorMode), [ colorMode ]);
|
|
|
|
const SelectComponent = props.isAsync ? AsyncSelect : Select;
|
|
|
|
return (
|
|
<FormControl
|
|
variant="floating"
|
|
size={ props.size || 'md' }
|
|
isRequired={ props.isRequired }
|
|
ref={ ref }
|
|
{ ...(props.error ? { 'aria-invalid': true } : {}) }
|
|
{ ...(props.isDisabled ? { 'aria-disabled': true } : {}) }
|
|
{ ...(props.value ? { 'data-active': true } : {}) }
|
|
>
|
|
<SelectComponent
|
|
{ ...props }
|
|
size={ props.size || 'md' }
|
|
menuPortalTarget={ window.document.body }
|
|
placeholder=""
|
|
styles={ styles }
|
|
chakraStyles={ chakraStyles }
|
|
isInvalid={ Boolean(props.error) }
|
|
useBasicStyles
|
|
/>
|
|
<InputPlaceholder
|
|
text={ typeof props.placeholder === 'string' ? props.placeholder : '' }
|
|
icon={ props.placeholderIcon }
|
|
error={ props.error }
|
|
isFancy
|
|
/>
|
|
</FormControl>
|
|
);
|
|
};
|
|
|
|
export default React.memo(React.forwardRef(FancySelect));
|