143 lines
3.3 KiB
TypeScript
143 lines
3.3 KiB
TypeScript
import React from 'react'
|
|
import { mapTextComponent, mapStyledProps, normalizeCol } from '@formily/antd'
|
|
import { Select as AntSelect } from 'antd'
|
|
import { SelectProps as AntSelectProps } from 'antd/lib/select'
|
|
import styled from 'styled-components'
|
|
import { isArr, FormPath } from '@formily/shared'
|
|
export * from '@formily/shared'
|
|
|
|
export const compose = (...args: any[]) => {
|
|
return (payload: any, ...extra: any[]) => {
|
|
return args.reduce((buf, fn) => {
|
|
return buf !== undefined ? fn(buf, ...extra) : fn(payload, ...extra)
|
|
}, payload)
|
|
}
|
|
}
|
|
|
|
interface SelectOption {
|
|
label: React.ReactText
|
|
value: any
|
|
[key: string]: any
|
|
}
|
|
|
|
type SelectProps = AntSelectProps & {
|
|
dataSource?: SelectOption[]
|
|
}
|
|
|
|
const createEnum = (enums: any) => {
|
|
if (isArr(enums)) {
|
|
return enums.map(item => {
|
|
if (typeof item === 'object') {
|
|
return {
|
|
...item
|
|
}
|
|
} else {
|
|
return {
|
|
label: item,
|
|
value: item
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
return []
|
|
}
|
|
|
|
export const Select: React.FC<SelectProps> = styled((props: SelectProps) => {
|
|
const { dataSource = [], onChange, ...others } = props
|
|
const children = createEnum(dataSource).map(item => {
|
|
const { label, value, children = [], ...others } = item
|
|
if (children.length) {
|
|
return (
|
|
<AntSelect.OptGroup label={label}>
|
|
{children.map(({value, label, ...others}: any) => (
|
|
<AntSelect.Option
|
|
key={value}
|
|
{...others}
|
|
title={label}
|
|
value={value}
|
|
>
|
|
{label}
|
|
</AntSelect.Option>
|
|
))}
|
|
</AntSelect.OptGroup>
|
|
);
|
|
}
|
|
return (
|
|
<AntSelect.Option
|
|
key={value}
|
|
{...others}
|
|
title={label as string}
|
|
value={value}
|
|
>
|
|
{label}
|
|
</AntSelect.Option>
|
|
)
|
|
})
|
|
return (
|
|
<AntSelect
|
|
className={props.className}
|
|
{...others}
|
|
onChange={(value: any, options: any) => {
|
|
onChange(
|
|
value,
|
|
isArr(options)
|
|
? options.map(item => ({
|
|
...item,
|
|
props: undefined
|
|
}))
|
|
: {
|
|
...options,
|
|
props: undefined //干掉循环引用
|
|
}
|
|
)
|
|
}}
|
|
>
|
|
{children}
|
|
</AntSelect>
|
|
)
|
|
})`
|
|
min-width: 100px;
|
|
width: 100%;
|
|
`
|
|
export const acceptEnum = (component: React.JSXElementConstructor<any>) => {
|
|
return ({ dataSource, ...others }) => {
|
|
if (dataSource) {
|
|
return React.createElement(Select, { dataSource, ...others })
|
|
} else {
|
|
return React.createElement(component, others)
|
|
}
|
|
}
|
|
}
|
|
|
|
export const transformDataSourceKey = (component, dataSourceKey) => {
|
|
return ({ dataSource, ...others }) => {
|
|
return React.createElement(component, {
|
|
[dataSourceKey]: dataSource,
|
|
...others
|
|
})
|
|
}
|
|
}
|
|
|
|
export const createMatchUpdate = (name: string, path: string) => (
|
|
targetName: string,
|
|
targetPath: string,
|
|
callback: () => void
|
|
) => {
|
|
if (targetName || targetPath) {
|
|
if (targetName) {
|
|
if (FormPath.parse(targetName).matchAliasGroup(name, path)) {
|
|
callback()
|
|
}
|
|
} else if (targetPath) {
|
|
if (FormPath.parse(targetPath).matchAliasGroup(name, path)) {
|
|
callback()
|
|
}
|
|
}
|
|
} else {
|
|
callback()
|
|
}
|
|
}
|
|
|
|
export { mapTextComponent, mapStyledProps, normalizeCol }
|