import React, { forwardRef, useEffect } from 'react'
import type { SelectProps } from 'antd'
import { Select } from 'antd'
import { useControllableValue } from 'ahooks'
import { BaseOptionType, DefaultOptionType } from 'rc-select/lib/Select'
import { BaseSelectRef } from 'rc-select'
export interface EnhancedSelectProps<
ValueType = any,
OptionType extends BaseOptionType = DefaultOptionType,
> extends SelectProps<ValueType, OptionType> {
beforeChange?: () => Promise<void>
autoSelectFirst?: boolean
}
const EnhancedSelect = forwardRef<any, EnhancedSelectProps>((props, ref) => {
const { onChange, options, beforeChange, autoSelectFirst = false, ...restProps } = props
const [value, setValue] = useControllableValue<EnhancedSelectProps['value']>(props)
useEffect(() => {
if (
!autoSelectFirst ||
!options?.length ||
options.some(opt => opt.value === value && !opt.disabled)
) {
return
}
const firstAvailableOption = options.find(opt => !opt.disabled)
if (firstAvailableOption) {
setValue(firstAvailableOption.value)
}
}, [options, autoSelectFirst, value])
async function handleChange(ev) {
let shouldTrigger = true
if (beforeChange) {
try {
await beforeChange()
} catch (e) {
shouldTrigger = false
}
}
if (shouldTrigger) {
setValue(ev)
}
}
return <Select ref={ref} {...restProps} value={value} options={options} onChange={handleChange} />
})
declare const MySelect: (<
ValueType = any,
OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,
>(
props: EnhancedSelectProps<ValueType, OptionType> & {
children?: React.ReactNode
} & { ref?: React.Ref<BaseSelectRef> },
) => React.ReactElement) & {
SECRET_COMBOBOX_MODE_DO_NOT_USE: typeof Select['SECRET_COMBOBOX_MODE_DO_NOT_USE']
Option: typeof Select['Option']
OptGroup: typeof Select['OptGroup']
}
export default {
...Select,
...EnhancedSelect,
} as unknown as typeof MySelect