packages/element/src/array-items/index.ts (170 lines of code) (raw):
import { ArrayField } from '@formily/core'
import { ISchema } from '@formily/json-schema'
import { observer } from '@formily/reactive-vue'
import { h, RecursionField, useField, useFieldSchema } from '@formily/vue'
import { defineComponent } from 'vue-demi'
import { SlickItem, SlickList } from 'vue-slicksort'
import { ArrayBase } from '../array-base'
import { stylePrefix } from '../__builtins__/configs'
import { composeExport } from '../__builtins__/shared'
const isAdditionComponent = (schema: ISchema) => {
return schema['x-component']?.indexOf('Addition') > -1
}
export interface IArrayItemsItemProps {
type?: 'card' | 'divide'
}
const ArrayItemsInner = observer(
defineComponent({
name: 'FArrayItems',
setup() {
const fieldRef = useField<ArrayField>()
const schemaRef = useFieldSchema()
const prefixCls = `${stylePrefix}-array-items`
const { getKey, keyMap } = ArrayBase.useKey(schemaRef.value)
return () => {
const field = fieldRef.value
const schema = schemaRef.value
const dataSource = Array.isArray(field.value) ? field.value.slice() : []
const renderItems = () => {
const items = dataSource?.map((item, index) => {
const items = Array.isArray(schema.items)
? schema.items[index] || schema.items[0]
: schema.items
const key = getKey(item, index)
return h(
ArrayBase.Item,
{
key,
props: {
index,
record: item,
},
},
{
default: () =>
h(
SlickItem,
{
class: [`${prefixCls}-item-inner`],
props: {
index,
},
key,
},
{
default: () =>
h(
RecursionField,
{
props: {
schema: items,
name: index,
},
},
{}
),
}
),
}
)
})
return h(
SlickList,
{
class: [`${prefixCls}-list`],
props: {
useDragHandle: true,
lockAxis: 'y',
helperClass: `${prefixCls}-sort-helper`,
value: [],
},
on: {
'sort-end': ({ oldIndex, newIndex }) => {
if (Array.isArray(keyMap)) {
keyMap.splice(newIndex, 0, keyMap.splice(oldIndex, 1)[0])
}
field.move(oldIndex, newIndex)
},
},
},
{ default: () => items }
)
}
const renderAddition = () => {
return schema.reduceProperties((addition, schema) => {
if (isAdditionComponent(schema)) {
return h(
RecursionField,
{
props: {
schema,
name: 'addition',
},
},
{}
)
}
return addition
}, null)
}
return h(
ArrayBase,
{
props: {
keyMap,
},
},
{
default: () =>
h(
'div',
{
class: [prefixCls],
on: {
change: () => {},
},
},
{
default: () => [renderItems(), renderAddition()],
}
),
}
)
}
},
})
)
const ArrayItemsItem = defineComponent<IArrayItemsItemProps>({
name: 'FArrayItemsItem',
props: ['type'],
setup(props, { attrs, slots }) {
const prefixCls = `${stylePrefix}-array-items`
return () =>
h(
'div',
{
class: [`${prefixCls}-${props.type || 'card'}`],
attrs: {
...attrs,
},
on: {
change: () => {},
},
},
slots
)
},
})
export const ArrayItems = composeExport(ArrayItemsInner, {
Item: ArrayItemsItem,
Index: ArrayBase.Index,
SortHandle: ArrayBase.SortHandle,
Addition: ArrayBase.Addition,
Remove: ArrayBase.Remove,
MoveDown: ArrayBase.MoveDown,
MoveUp: ArrayBase.MoveUp,
useArray: ArrayBase.useArray,
useIndex: ArrayBase.useIndex,
useRecord: ArrayBase.useRecord,
})
export default ArrayItems