# Component Specification

import TypesTable from '@site/src/components/TypesTable';

The material agreement defines the basic information of a component, including the name, properties, drag and drop rules, etc. The material agreement is an additional description file attached to the component, which will not invade your component code. Therefore, you can add a material agreement to the component without changing the component code.

## 组件原型 prototype

<TypesTable name="ComponentPrototypeType" />

## 组件属性 ComponentPropType

<TypesTable name="ComponentPropType" />

### 嵌套属性

当某个组件属性为嵌套属性时，例如 `<Table scroll={{ x: 800, y: 400 }} />`，此时可以描述如下：

```jsx
{
  name: 'Table',
  props: [
    {
      name: 'scroll',
      props: [
        {
          name: 'x',
          setter: 'numberSetter',
        },
        {
          name: 'y',
          setter: 'numberSetter',
        }
      ],
    }
  ],
}
```

### 属性的关联展示

当某个属性依赖某个特定的其他属性值时，可以借助 `getVisible` 实现关联展示控制：

```js
{
  name: 'Button',
  props: [
    {
      name: 'shape',
    },
    {
      name: 'buttonType',
      getVisible: (form) => {
        // 配置项 buttonType 仅在配置项 shape 的值为 button 时才展示
        return form.getValue('shape') === 'button';
      },
    },
  ];
}
```

### 动态属性设置

当组件需要依据某个属性值进行动态设置其他属性时，可以借助 `getProp` 实现控制：

```js
{
  name: 'FormItem',
  props: [
    {
      name: 'component',
      title: '控件类型',
    },
    {
      name: 'componentProps',
      title: '子组件属性',
      getProp(form) {
        const type = form.getValue('component');
        const proto = { ...componentMap[type] };
        const props = omitProps(proto.props, [
          'placeholder',
          'options',
          'onChange',
          'defaultValue',
          'value',
        ]);
        return {
          title: proto.title + '属性',
          props,
        };
      },
    }
  ],
}
```

### 属性的输入提示

当某个属性在输入时需要进行输入提示时，例如某个函数属性需要提示其签名的模版，则可以借助属性输入提示实现:

```js
{
  name: 'TableColumn',
  props: [
    {
      name: 'render',
      setter: 'expressionSetter',
      autoCompleteOptions: ['(value, record, index) => { return null; }'],
    }
  ],
}
```

![img](https://p5.music.126.net/obj/wonDlsKUwrLClGjCm8Kx/18917075100/9569/09fa/bc62/c418d3de8694ce93977450fb725bb524.gif)

## 组件拖拽规则 ComponentDndRulesType

<TypesTable name="ComponentDndRulesType" />

### canDrag/canDrop

在 onDragStart 的时候执行。

```js
export const Page = {
  name: 'Page',
  rules: {
    canDrag() {
      return false;
    },
  },
};
```

### canMoveIn/canMoveOut

在 onDragEnter 的时候执行。

```js
export const Modal = {
  name: 'Modal',
  rules: {
    canMoveIn(incomingName) {
      return !(incomingName === Modal.name);
    },
  },
};
```
