setup()

in packages/element/src/array-collapse/index.ts [93:364]


    setup(props, { attrs }) {
      const fieldRef = useField<ArrayField>()
      const schemaRef = useFieldSchema()

      const prefixCls = `${stylePrefix}-array-collapse`
      const activeKeys: Ref<number[] | number> = ref([])

      watchEffect(() => {
        const field = fieldRef.value
        const dataSource = Array.isArray(field.value) ? field.value.slice() : []
        if (!field.modified && dataSource.length) {
          activeKeys.value = takeDefaultActiveKeys(
            dataSource.length,
            props.defaultOpenPanelCount,
            attrs.accordion as boolean
          )
        }
      })

      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() : []
        if (!schema) throw new Error('can not found schema object')

        const renderItems = () => {
          if (!dataSource.length) {
            return null
          }

          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)
            const panelProps = field
              .query(`${field.address}.${index}`)
              .get('componentProps')
            const props: CollapseItemProps = items['x-component-props']
            const headerTitle = panelProps?.title || props.title || field.title
            const path = field.address.concat(index)
            const errors = field.form.queryFeedbacks({
              type: 'error',
              address: `${path}.**`,
            })

            const title = h(
              ArrayBase.Item,
              {
                props: {
                  index,
                  record: item,
                },
              },
              {
                default: () => [
                  h(
                    RecursionField,
                    {
                      props: {
                        schema: items,
                        name: index,
                        filterProperties: (schema) => {
                          if (!isIndexComponent(schema)) return false
                          return true
                        },
                        onlyRenderProperties: true,
                      },
                    },
                    {}
                  ),
                  errors.length
                    ? h(
                        Badge,
                        {
                          class: [`${prefixCls}-errors-badge`],
                          props: {
                            value: errors.length,
                          },
                        },
                        { default: () => headerTitle }
                      )
                    : headerTitle,
                ],
              }
            )
            const extra = h(
              ArrayBase.Item,
              {
                props: {
                  index,
                  record: item,
                },
              },
              {
                default: () => [
                  h(
                    RecursionField,
                    {
                      props: {
                        schema: items,
                        name: index,
                        filterProperties: (schema) => {
                          if (!isOperationComponent(schema)) return false
                          return true
                        },
                        onlyRenderProperties: true,
                      },
                    },
                    {}
                  ),
                ],
              }
            )
            const content = h(
              RecursionField,
              {
                props: {
                  schema: items,
                  name: index,
                  filterProperties: (schema) => {
                    if (isIndexComponent(schema)) return false
                    if (isOperationComponent(schema)) return false
                    return true
                  },
                },
              },
              {}
            )

            return h(
              CollapseItem,
              {
                attrs: {
                  ...props,
                  ...panelProps,
                  name: index,
                },
                key,
              },
              {
                default: () => [
                  h(
                    ArrayBase.Item,
                    {
                      props: {
                        index,
                        record: item,
                      },
                    },
                    {
                      default: () => [content],
                    }
                  ),
                ],
                title: () =>
                  h(
                    Row,
                    {
                      style: { flex: 1 },
                      props: {
                        type: 'flex',
                        justify: 'space-between',
                      },
                    },
                    {
                      default: () => [
                        h('span', {}, { default: () => title }),
                        h('span', {}, { default: () => extra }),
                      ],
                    }
                  ),
              }
            )
          })

          return h(
            Collapse,
            {
              class: [`${prefixCls}-item`],
              attrs: {
                ...attrs,
                value: activeKeys.value,
              },
              on: {
                change: (keys: number[] | number) => {
                  activeKeys.value = keys
                },
              },
            },
            {
              default: () => [items],
            }
          )
        }
        const renderAddition = () => {
          return schema.reduceProperties((addition, schema) => {
            if (isAdditionComponent(schema)) {
              return h(
                RecursionField,
                {
                  props: {
                    schema,
                    name: 'addition',
                  },
                },
                {}
              )
            }
            return addition
          }, null)
        }
        const renderEmpty = () => {
          if (dataSource?.length) return
          return h(
            Card,
            {
              class: [`${prefixCls}-item`],
              attrs: {
                shadow: 'never',
                ...attrs,
                header: attrs.title || field.title,
              },
            },
            {
              default: () =>
                h(
                  Empty,
                  { props: { description: 'No Data', imageSize: 100 } },
                  {}
                ),
            }
          )
        }

        return h(
          'div',
          {
            class: [prefixCls],
          },
          {
            default: () =>
              h(
                ArrayBase,
                {
                  props: {
                    keyMap,
                  },
                  on: {
                    add: (index: number) => {
                      activeKeys.value = insertActiveKeys(
                        activeKeys.value,
                        index,
                        attrs.accordion as boolean
                      )
                    },
                  },
                },
                {
                  default: () => [
                    renderEmpty(),
                    renderItems(),
                    renderAddition(),
                  ],
                }
              ),
          }
        )
      }
    },