packages/antd/src/array-items/index.tsx (125 lines of code) (raw):

import React, { useRef } from 'react' 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, SortableContainer, SortableElement, } from '../__builtins__' import { ArrayBase, ArrayBaseMixins, IArrayBaseProps } from '../array-base' type ComposedArrayItems = React.FC< React.PropsWithChildren< React.HTMLAttributes<HTMLDivElement> & IArrayBaseProps > > & ArrayBaseMixins & { Item?: React.FC< React.HTMLAttributes<HTMLDivElement> & { type?: 'card' | 'divide' } > } const SortableItem = SortableElement( (props: React.PropsWithChildren<React.HTMLAttributes<HTMLDivElement>>) => { const prefixCls = usePrefixCls('formily-array-items') return ( <div {...props} className={cls(`${prefixCls}-item`, props.className)}> {props.children} </div> ) } ) const SortableList = SortableContainer( (props: React.PropsWithChildren<React.HTMLAttributes<HTMLDivElement>>) => { const prefixCls = usePrefixCls('formily-array-items') return ( <div {...props} className={cls(`${prefixCls}-list`, props.className)}> {props.children} </div> ) } ) const isAdditionComponent = (schema: ISchema) => { return schema['x-component']?.indexOf('Addition') > -1 } const useAddition = () => { const schema = useFieldSchema() return schema.reduceProperties((addition, schema, key) => { if (isAdditionComponent(schema)) { return <RecursionField schema={schema} name={key} /> } return addition }, null) } export const ArrayItems: ComposedArrayItems = observer((props) => { const field = useField<ArrayField>() const prefixCls = usePrefixCls('formily-array-items') const ref = useRef<HTMLDivElement>(null) const schema = useFieldSchema() const addition = useAddition() const dataSource = Array.isArray(field.value) ? field.value : [] const { onAdd, onCopy, onRemove, onMoveDown, onMoveUp } = props if (!schema) throw new Error('can not found schema object') return ( <ArrayBase onAdd={onAdd} onCopy={onCopy} onRemove={onRemove} onMoveUp={onMoveUp} onMoveDown={onMoveDown} > <div {...props} ref={ref} onChange={() => {}} className={cls(prefixCls, props.className)} > <SortableList list={dataSource.slice()} className={`${prefixCls}-sort-helper`} onSortEnd={({ oldIndex, newIndex }) => { field.move(oldIndex, newIndex) }} > {dataSource?.map((item, index) => { const items = Array.isArray(schema.items) ? schema.items[index] || schema.items[0] : schema.items return ( <ArrayBase.Item key={index} index={index} record={() => field.value?.[index]} > <SortableItem key={`item-${index}`} lockAxis="y" index={index}> <div className={`${prefixCls}-item-inner`}> <RecursionField schema={items} name={index} /> </div> </SortableItem> </ArrayBase.Item> ) })} </SortableList> {addition} </div> </ArrayBase> ) }) ArrayItems.displayName = 'ArrayItems' ArrayItems.Item = (props) => { const prefixCls = usePrefixCls('formily-array-items') return ( <div {...props} onChange={() => {}} className={cls(`${prefixCls}-${props.type || 'card'}`, props.className)} > {props.children} </div> ) } ArrayBase.mixin(ArrayItems) export default ArrayItems