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