export function createPolyInput()

in packages/react-settings-form/src/components/PolyInput/index.tsx [55:132]


export function createPolyInput(polyTypes: PolyTypes = []): React.FC<IInput> {
  return ({
    className,
    style,
    value,
    onChange,
    exclude,
    include,
    ...props
  }) => {
    const prefix = usePrefix('poly-input')
    const types = createTypes(polyTypes, exclude, include)
    const [current, setCurrent] = useState(types[0]?.type)
    const type = types?.find(({ type }) => type === current)
    const component = type?.component
    const typesValue = useRef({})
    useEffect(() => {
      types?.forEach(({ checker, type }) => {
        if (checker(value)) {
          setCurrent(type)
        }
      })
    }, [value])

    const getNextType = () => {
      const currentIndex = types?.findIndex(({ type }) => type === current)
      const nextIndex =
        currentIndex + 1 > types?.length - 1 ? 0 : currentIndex + 1
      return types[nextIndex]
    }

    const transformOnChangeValue = (value: any, type: IPolyType) => {
      return type?.toChangeValue ? type?.toChangeValue(value) : value
    }

    return (
      <div className={cls(prefix, className)} style={style}>
        {component && (
          <div className={prefix + '-content'}>
            {React.createElement(component, {
              ...props,
              value: type?.toInputValue ? type?.toInputValue(value) : value,
              onChange: (event: any) => {
                const value = getEventValue(event)
                typesValue.current[type?.type] = value
                onChange?.(transformOnChangeValue(value, type))
              },
            })}
          </div>
        )}
        <Button
          className={prefix + '-controller'}
          style={{
            width: !component ? '100%' : 'auto',
          }}
          block
          onClick={() => {
            const nextType = getNextType()
            if (nextType === type) return
            setCurrent(nextType?.type)
            onChange?.(
              transformOnChangeValue(
                typesValue.current[nextType?.type],
                nextType
              )
            )
          }}
        >
          {type?.icon ? (
            <IconWidget infer={type.icon} />
          ) : (
            type?.title || type?.type
          )}
        </Button>
      </div>
    )
  }
}