# MagicBox Decorator - 魔方装修工具

MagicBox（魔方） 是装修工具的名称，也是核心组件的名称。

## 1.Usage

    yarn add @whalecloud/magic-box

- 设计态使用 Designer 组件
- 预览态使用 Previewer 组件

Designer & Previewer 是两个巨型 React 组件，所有功能都封装在组件内部，所有必备的参数和定制都通过 props 传递进来。


<img src="./src/assets/imgs/designer.png">


<img src="./src/assets/imgs/previewer.png">

## 2. Screen Shots


## 3. Architecture

### 3.1 Grid Layout

<img src="./src/assets/imgs/bootstrap.png">

设计器整体采用行列布局，也就是 Row（ MRow 类） 和 Column（ MCol 类） 模型，此设计参考了 Bootstrap 的栅格布局模型。

MRow 表示一行，MCol 表示一列，MRow 中只能放置 MCol。虽然组件没有约束一行中最多放多少列，但是建议参考 Bootstrap 的思路，最多放 12 列。

MCol 内部可以放真正的业务组件，也可以继续放置 MRow，可以形成无限嵌套。

### 3.2 Data Driven & UI isolation

Designer 和 Renderer 都基于数据驱动模式工作，整体是一份巨大的 JSON 数据。

数据中只记录组件类型和数据，不记录组件具体的展示逻辑，UI 展示逻辑由不同类型的 Render 具体负责，在对页面布局要求不高的场景下，PC、手机端、Pad 可以共用一份数据。

数据格式示例：

``` json
{
    index: 0,
    id: 'df019a54-e3fb-40f8-b916-d2cde8325475',
    pid: -1,
    childNodes: [
        {
            type: 'MRow',
            id: '9c40cfe6-c6ff-418f-8ae6-5e1818189172',
            title: 'MRow',
            pid: 'df019a54-e3fb-40f8-b916-d2cde8325475',
            index: 0,
            childNodes: [
                {
                    type: 'MCol',
                    id: '9d027c88-ad6d-43c3-850e-ab8bae6b8ab4',
                    title: 'MCol',
                    pid: '9c40cfe6-c6ff-418f-8ae6-5e1818189172',
                    index: 0,
                    childNodes: [
                        {
                            type: 'GalaryTemplate4',
                            id: '80c970f7-5f30-4f72-b6a9-455399ac2aea',
                            title: '4 Images',
                            pid: '9d027c88-ad6d-43c3-850e-ab8bae6b8ab4',
                            index: 0,
                        },
                    ],
                },
            ],
        }
...
```

### 3.3. Directory Structure

```

document updating...

```

### 3.4. Core Components

核心组件只有2个：

- MagicBox: 是整个设计器和渲染器的核心，MagicBox 在逻辑上可以看成超级 DIV，它在 DIV 的基础上增加了拖拽布局和渲染功能。**重要：因为 react-dnd 目前只能支持函数式组件，所以这里只能写成函数形式。**MagicBox 在 designer 模式和 renderer 模式下具有不同的外观和功能。MagicBox 切分成2个内部组件分别实现设计器和渲染器功能 DesignerBox 和 RendererBox。在 designer 模式下，具有拖拽布局功能。在 renderer 模式下纯展现，其功能退化成一层空的容器 div，不再具有拖拽交互功能。
- DropZone: 封装放置区域逻辑，当把对象拖动到 DropZone 并放开鼠标时，会触发 drop 动作。
MagicBox 和 DropZone 基于 react-dnd 进行了再次封装，它们是内部核心机制，设计器的外部调用方不需要关心这两个类的实现细节，只要关注暴露的参数即可，下是 MagicBox 的核心参数：

``` javascript
id,
pid,
index,
nodeData,
children,
onHover,
onDrop,
componentMap,
acceptTypes = ['MagicBox', 'MRow'], //盒子内部可以接受的类型只有 MagicBox 和 MRow，MagicBox 默认可以接受自己，形成无限嵌套。
isValidDest = false,
canDrag = true,
isLeaf = false,
isSelected = false,
innerDirection = 'vertical',
```
