|
|
@ -24,6 +24,31 @@ import { getSelectStyles } from './getSelectStyles'; |
|
|
|
import { cleanValue } from './utils'; |
|
|
|
import { cleanValue } from './utils'; |
|
|
|
import { SelectBaseProps, SelectValue } from './types'; |
|
|
|
import { SelectBaseProps, SelectValue } from './types'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
interface ExtraValuesIndicatorProps { |
|
|
|
|
|
|
|
maxVisibleValues?: number | undefined; |
|
|
|
|
|
|
|
selectedValuesCount: number; |
|
|
|
|
|
|
|
menuIsOpen: boolean; |
|
|
|
|
|
|
|
showAllSelectedWhenOpen: boolean; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const renderExtraValuesIndicator = (props: ExtraValuesIndicatorProps) => { |
|
|
|
|
|
|
|
const { maxVisibleValues, selectedValuesCount, menuIsOpen, showAllSelectedWhenOpen } = props; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( |
|
|
|
|
|
|
|
maxVisibleValues !== undefined && |
|
|
|
|
|
|
|
selectedValuesCount > maxVisibleValues && |
|
|
|
|
|
|
|
!(showAllSelectedWhenOpen && menuIsOpen) |
|
|
|
|
|
|
|
) { |
|
|
|
|
|
|
|
return ( |
|
|
|
|
|
|
|
<span key="excess-values" id="excess-values"> |
|
|
|
|
|
|
|
(+{selectedValuesCount - maxVisibleValues}) |
|
|
|
|
|
|
|
</span> |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const CustomControl = (props: any) => { |
|
|
|
const CustomControl = (props: any) => { |
|
|
|
const { |
|
|
|
const { |
|
|
|
children, |
|
|
|
children, |
|
|
@ -66,6 +91,7 @@ export function SelectBase<T>({ |
|
|
|
allowCustomValue = false, |
|
|
|
allowCustomValue = false, |
|
|
|
autoFocus = false, |
|
|
|
autoFocus = false, |
|
|
|
backspaceRemovesValue = true, |
|
|
|
backspaceRemovesValue = true, |
|
|
|
|
|
|
|
closeMenuOnSelect = true, |
|
|
|
components, |
|
|
|
components, |
|
|
|
defaultOptions, |
|
|
|
defaultOptions, |
|
|
|
defaultValue, |
|
|
|
defaultValue, |
|
|
@ -83,6 +109,7 @@ export function SelectBase<T>({ |
|
|
|
loadOptions, |
|
|
|
loadOptions, |
|
|
|
loadingMessage = 'Loading options...', |
|
|
|
loadingMessage = 'Loading options...', |
|
|
|
maxMenuHeight = 300, |
|
|
|
maxMenuHeight = 300, |
|
|
|
|
|
|
|
maxVisibleValues, |
|
|
|
menuPosition, |
|
|
|
menuPosition, |
|
|
|
menuPlacement = 'auto', |
|
|
|
menuPlacement = 'auto', |
|
|
|
noOptionsMessage = 'No options found', |
|
|
|
noOptionsMessage = 'No options found', |
|
|
@ -98,6 +125,7 @@ export function SelectBase<T>({ |
|
|
|
placeholder = 'Choose', |
|
|
|
placeholder = 'Choose', |
|
|
|
prefix, |
|
|
|
prefix, |
|
|
|
renderControl, |
|
|
|
renderControl, |
|
|
|
|
|
|
|
showAllSelectedWhenOpen = true, |
|
|
|
tabSelectsValue = true, |
|
|
|
tabSelectsValue = true, |
|
|
|
className, |
|
|
|
className, |
|
|
|
value, |
|
|
|
value, |
|
|
@ -142,6 +170,7 @@ export function SelectBase<T>({ |
|
|
|
autoFocus, |
|
|
|
autoFocus, |
|
|
|
backspaceRemovesValue, |
|
|
|
backspaceRemovesValue, |
|
|
|
captureMenuScroll: false, |
|
|
|
captureMenuScroll: false, |
|
|
|
|
|
|
|
closeMenuOnSelect, |
|
|
|
defaultValue, |
|
|
|
defaultValue, |
|
|
|
// Also passing disabled, as this is the new Select API, and I want to use this prop instead of react-select's one
|
|
|
|
// Also passing disabled, as this is the new Select API, and I want to use this prop instead of react-select's one
|
|
|
|
disabled, |
|
|
|
disabled, |
|
|
@ -156,6 +185,7 @@ export function SelectBase<T>({ |
|
|
|
isMulti, |
|
|
|
isMulti, |
|
|
|
isSearchable, |
|
|
|
isSearchable, |
|
|
|
maxMenuHeight, |
|
|
|
maxMenuHeight, |
|
|
|
|
|
|
|
maxVisibleValues, |
|
|
|
menuIsOpen: isOpen, |
|
|
|
menuIsOpen: isOpen, |
|
|
|
menuPlacement, |
|
|
|
menuPlacement, |
|
|
|
menuPosition, |
|
|
|
menuPosition, |
|
|
@ -171,6 +201,7 @@ export function SelectBase<T>({ |
|
|
|
placeholder, |
|
|
|
placeholder, |
|
|
|
prefix, |
|
|
|
prefix, |
|
|
|
renderControl, |
|
|
|
renderControl, |
|
|
|
|
|
|
|
showAllSelectedWhenOpen, |
|
|
|
tabSelectsValue, |
|
|
|
tabSelectsValue, |
|
|
|
value: isMulti ? selectedValue : selectedValue[0], |
|
|
|
value: isMulti ? selectedValue : selectedValue[0], |
|
|
|
}; |
|
|
|
}; |
|
|
@ -196,7 +227,22 @@ export function SelectBase<T>({ |
|
|
|
components={{ |
|
|
|
components={{ |
|
|
|
MenuList: SelectMenu, |
|
|
|
MenuList: SelectMenu, |
|
|
|
Group: SelectOptionGroup, |
|
|
|
Group: SelectOptionGroup, |
|
|
|
ValueContainer: ValueContainer, |
|
|
|
ValueContainer: (props: any) => { |
|
|
|
|
|
|
|
const { menuIsOpen } = props.selectProps; |
|
|
|
|
|
|
|
if ( |
|
|
|
|
|
|
|
Array.isArray(props.children) && |
|
|
|
|
|
|
|
Array.isArray(props.children[0]) && |
|
|
|
|
|
|
|
maxVisibleValues !== undefined && |
|
|
|
|
|
|
|
!(showAllSelectedWhenOpen && menuIsOpen) |
|
|
|
|
|
|
|
) { |
|
|
|
|
|
|
|
const [valueChildren, ...otherChildren] = props.children; |
|
|
|
|
|
|
|
const truncatedValues = valueChildren.slice(0, maxVisibleValues); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return <ValueContainer {...props} children={[truncatedValues, ...otherChildren]} />; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return <ValueContainer {...props} />; |
|
|
|
|
|
|
|
}, |
|
|
|
Placeholder: (props: any) => ( |
|
|
|
Placeholder: (props: any) => ( |
|
|
|
<div |
|
|
|
<div |
|
|
|
{...props.innerProps} |
|
|
|
{...props.innerProps} |
|
|
@ -216,7 +262,28 @@ export function SelectBase<T>({ |
|
|
|
{props.children} |
|
|
|
{props.children} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
), |
|
|
|
), |
|
|
|
IndicatorsContainer: IndicatorsContainer, |
|
|
|
IndicatorsContainer: (props: any) => { |
|
|
|
|
|
|
|
const { selectProps } = props; |
|
|
|
|
|
|
|
const { value, showAllSelectedWhenOpen, maxVisibleValues, menuIsOpen } = selectProps; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (maxVisibleValues !== undefined) { |
|
|
|
|
|
|
|
const selectedValuesCount = value.length; |
|
|
|
|
|
|
|
const indicatorChildren = [...props.children]; |
|
|
|
|
|
|
|
indicatorChildren.splice( |
|
|
|
|
|
|
|
-1, |
|
|
|
|
|
|
|
0, |
|
|
|
|
|
|
|
renderExtraValuesIndicator({ |
|
|
|
|
|
|
|
maxVisibleValues, |
|
|
|
|
|
|
|
selectedValuesCount, |
|
|
|
|
|
|
|
showAllSelectedWhenOpen, |
|
|
|
|
|
|
|
menuIsOpen, |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
return <IndicatorsContainer {...props} children={indicatorChildren} />; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return <IndicatorsContainer {...props} />; |
|
|
|
|
|
|
|
}, |
|
|
|
IndicatorSeparator: () => <></>, |
|
|
|
IndicatorSeparator: () => <></>, |
|
|
|
Control: CustomControl, |
|
|
|
Control: CustomControl, |
|
|
|
Option: SelectMenuOptions, |
|
|
|
Option: SelectMenuOptions, |
|
|
|