packages/antd/src/array-cards/index.tsx (148 lines of code) (raw):
import React from 'react'
import { Card, Empty } from 'antd'
import { CardProps } from 'antd/lib/card'
import { ArrayField } from '@formily/core'
import {
useField,
observer,
useFieldSchema,
RecursionField,
} from '@formily/react'
import cls from 'classnames'
import { ISchema } from '@formily/json-schema'
import { usePrefixCls } from '../__builtins__'
import { ArrayBase, ArrayBaseMixins, IArrayBaseProps } from '../array-base'
type ComposedArrayCards = React.FC<
React.PropsWithChildren<CardProps & IArrayBaseProps>
> &
ArrayBaseMixins
const isAdditionComponent = (schema: ISchema) => {
return schema['x-component']?.indexOf('Addition') > -1
}
const isIndexComponent = (schema: ISchema) => {
return schema['x-component']?.indexOf?.('Index') > -1
}
const isRemoveComponent = (schema: ISchema) => {
return schema['x-component']?.indexOf?.('Remove') > -1
}
const isCopyComponent = (schema: ISchema) => {
return schema['x-component']?.indexOf?.('Copy') > -1
}
const isMoveUpComponent = (schema: ISchema) => {
return schema['x-component']?.indexOf?.('MoveUp') > -1
}
const isMoveDownComponent = (schema: ISchema) => {
return schema['x-component']?.indexOf?.('MoveDown') > -1
}
const isOperationComponent = (schema: ISchema) => {
return (
isAdditionComponent(schema) ||
isRemoveComponent(schema) ||
isCopyComponent(schema) ||
isMoveDownComponent(schema) ||
isMoveUpComponent(schema)
)
}
export const ArrayCards: ComposedArrayCards = observer((props) => {
const field = useField<ArrayField>()
const schema = useFieldSchema()
const dataSource = Array.isArray(field.value) ? field.value : []
const prefixCls = usePrefixCls('formily-array-cards', props)
const { onAdd, onCopy, onRemove, onMoveDown, onMoveUp } = props
if (!schema) throw new Error('can not found schema object')
const renderItems = () => {
return dataSource?.map((item, index) => {
const items = Array.isArray(schema.items)
? schema.items[index] || schema.items[0]
: schema.items
const title = (
<span>
<RecursionField
schema={items}
name={index}
filterProperties={(schema) => {
if (!isIndexComponent(schema)) return false
return true
}}
onlyRenderProperties
/>
{props.title || field.title}
</span>
)
const extra = (
<span>
<RecursionField
schema={items}
name={index}
filterProperties={(schema) => {
if (!isOperationComponent(schema)) return false
return true
}}
onlyRenderProperties
/>
{props.extra}
</span>
)
const content = (
<RecursionField
schema={items}
name={index}
filterProperties={(schema) => {
if (isIndexComponent(schema)) return false
if (isOperationComponent(schema)) return false
return true
}}
/>
)
return (
<ArrayBase.Item
key={index}
index={index}
record={() => field.value?.[index]}
>
<Card
{...props}
onChange={() => {}}
className={cls(`${prefixCls}-item`, props.className)}
title={title}
extra={extra}
>
{content}
</Card>
</ArrayBase.Item>
)
})
}
const renderAddition = () => {
return schema.reduceProperties((addition, schema, key) => {
if (isAdditionComponent(schema)) {
return <RecursionField schema={schema} name={key} />
}
return addition
}, null)
}
const renderEmpty = () => {
if (dataSource?.length) return
return (
<Card
{...props}
onChange={() => {}}
className={cls(`${prefixCls}-item`, props.className)}
title={props.title || field.title}
>
<Empty />
</Card>
)
}
return (
<ArrayBase
onAdd={onAdd}
onCopy={onCopy}
onRemove={onRemove}
onMoveUp={onMoveUp}
onMoveDown={onMoveDown}
>
{renderEmpty()}
{renderItems()}
{renderAddition()}
</ArrayBase>
)
})
ArrayCards.displayName = 'ArrayCards'
ArrayBase.mixin(ArrayCards)
export default ArrayCards