import React, { useEffect, useState, useRef } from 'react' import { Button } from 'antd' import { usePrefix, IconWidget } from '@pind/designable-react' import cls from 'classnames' import './styles.less' export interface IInput { style?: React.CSSProperties className?: string value: any onChange: (value: any) => void exclude?: string[] include?: string[] } export interface IPolyType { type: string title?: string icon?: string component?: any checker: (value: any) => boolean toInputValue?: (value: any) => any toChangeValue?: (value: any) => any } export type PolyTypes = IPolyType[] const isValid = (val: any) => val !== undefined && val !== null const getEventValue = (event: any) => { if (event?.target) { if (isValid(event.target.value)) return event.target.value if (isValid(event.target.checked)) return event.target.checked return } return event } const createTypes = ( types: PolyTypes, exclude?: string[], include?: string[] ) => { return types.filter(({ type }) => { if (Array.isArray(include) && include.length) { return include.includes(type) } if (Array.isArray(exclude) && exclude.length) { return !exclude.includes(type) } return true }) } export function createPolyInput(polyTypes: PolyTypes = []): React.FC { 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 (
{component && (
{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)) }, })}
)}
) } }