Pārlūkot izejas kodu

add layout (#6600)

* add layout

* add docs

* add en docs

* fix test
杨奕 8 gadi atpakaļ
vecāks
revīzija
bf6661266a

+ 1 - 1
build/bin/build-entry.js

@@ -8,7 +8,7 @@ var endOfLine = require('os').EOL;
 var OUTPUT_PATH = path.join(__dirname, '../../src/index.js');
 var IMPORT_TEMPLATE = 'import {{name}} from \'../packages/{{package}}/index.js\';';
 var INSTALL_COMPONENT_TEMPLATE = '  {{name}}';
-var MAIN_TEMPLATE = `/* Automatic generated by './build/bin/build-entry.js' */
+var MAIN_TEMPLATE = `/* Automatically generated by './build/bin/build-entry.js' */
 
 {{include}}
 import locale from 'element-ui/src/locale';

+ 6 - 1
components.json

@@ -62,5 +62,10 @@
   "collapse-item": "./packages/collapse-item/index.js",
   "cascader": "./packages/cascader/index.js",
   "color-picker": "./packages/color-picker/index.js",
-  "transfer": "./packages/transfer/index.js"
+  "transfer": "./packages/transfer/index.js",
+  "container": "./packages/container/index.js",
+  "header": "./packages/header/index.js",
+  "aside": "./packages/aside/index.js",
+  "main": "./packages/main/index.js",
+  "footer": "./packages/footer/index.js"
 }

+ 297 - 0
examples/docs/en-US/container.md

@@ -0,0 +1,297 @@
+<style>
+  .el-header, .el-footer {
+    background-color: #1f2d3d;
+    color: #fff;
+    line-height: 60px;
+  }
+  
+  .el-aside {
+    color: #fff;
+  }
+  
+  #common-layouts + .demo-container {
+    .el-header, .el-footer {
+      text-align: center;
+    }
+    
+    .el-aside {
+      background-color: #8492a6;
+      text-align: center;
+      line-height: 200px;
+    }
+    
+    .el-main {
+      background-color: #d3dce6;
+      color: #5e6d82;
+      text-align: center;
+      line-height: 160px;
+    }
+    
+    & > .source > .el-container {
+      margin-bottom: 40px;
+    
+      &:nth-child(5) .el-aside,
+      &:nth-child(6) .el-aside {
+        line-height: 260px;
+      }
+    
+     &:nth-child(7) .el-aside {
+       line-height: 320px;
+      }
+    }
+  }
+</style>
+
+<script>
+  export default {
+    data() {
+      const item = {
+        date: '2016-05-02',
+        name: 'Tom',
+        address: 'No. 189, Grove St, Los Angeles'
+      };
+      return {
+        tableData: Array(20).fill(item)
+      }
+    }
+  };
+</script>
+
+## Container
+Container components for scaffolding basic structure of the page:
+
+`<el-container>`: wrapper container. When nested with a `<el-header>` or `<el-footer>`, all its child elements will be vertically arranged. Otherwise horizontally.
+
+`<el-header>`: container for headers.
+
+`<el-aside>`: container for side sections (usually a side nav).
+
+`<el-main>`: container for main sections.
+
+`<el-footer>`: container for footers.
+
+:::tip
+These components use flex for layout, so please make sure your browser supports it. Besides, `<el-container>`'s direct child elements have to be one or more of the latter four components. And father element of the latter four components must be a `<el-container>`.
+:::
+
+### Common layouts
+
+::: demo
+```html
+<el-container>
+  <el-header>Header</el-header>
+  <el-main>Main</el-main>
+</el-container>
+
+<el-container>
+  <el-header>Header</el-header>
+  <el-main>Main</el-main>
+  <el-footer>Footer</el-footer>
+</el-container>
+
+<el-container>
+  <el-aside width="200px">Aside</el-aside>
+  <el-main>Main</el-main>
+</el-container>
+
+<el-container>
+  <el-header>Header</el-header>
+  <el-container>
+    <el-aside width="200px">Aside</el-aside>
+    <el-main>Main</el-main>
+  </el-container>
+</el-container>
+
+<el-container>
+  <el-header>Header</el-header>
+  <el-container>
+    <el-aside width="200px">Aside</el-aside>
+    <el-container>
+      <el-main>Main</el-main>
+      <el-footer>Footer</el-footer>
+    </el-container>
+  </el-container>
+</el-container>
+
+<el-container>
+  <el-aside width="200px">Aside</el-aside>
+  <el-container>
+    <el-header>Header</el-header>
+    <el-main>Main</el-main>
+  </el-container>
+</el-container>
+
+<el-container>
+  <el-aside width="200px">Aside</el-aside>
+  <el-container>
+    <el-header>Header</el-header>
+    <el-main>Main</el-main>
+    <el-footer>Footer</el-footer>
+  </el-container>
+</el-container>
+
+<style>
+  .el-header, .el-footer {
+    background-color: #1f2d3d;
+    color: #fff;
+    text-align: center;
+    line-height: 60px;
+  }
+  
+  .el-aside {
+    background-color: #8492a6;
+    color: #fff;
+    text-align: center;
+    line-height: 200px;
+  }
+  
+  .el-main {
+    background-color: #d3dce6;
+    color: #5e6d82;
+    text-align: center;
+    line-height: 160px;
+  }
+  
+  body > .el-container {
+    margin-bottom: 40px;
+  }
+  
+  .el-container:nth-child(5) .el-aside,
+  .el-container:nth-child(6) .el-aside {
+    line-height: 260px;
+  }
+  
+  .el-container:nth-child(7) .el-aside {
+    line-height: 320px;
+  }
+</style>
+```
+:::
+
+### Example
+
+::: demo
+```html
+<el-container style="height: 500px; border: 1px solid #eee">
+  <el-aside width="200px" style="background-color: rgb(238, 241, 246)">
+    <el-menu :default-openeds="['1', '3']">
+      <el-submenu index="1">
+        <template slot="title"><i class="el-icon-message"></i>Navigator One</template>
+        <el-menu-item-group>
+          <template slot="title">Group 1</template>
+          <el-menu-item index="1-1">Option 1</el-menu-item>
+          <el-menu-item index="1-2">Option 2</el-menu-item>
+        </el-menu-item-group>
+        <el-menu-item-group title="Group 2">
+          <el-menu-item index="1-3">Option 3</el-menu-item>
+        </el-menu-item-group>
+        <el-submenu index="1-4">
+          <template slot="title">Option4</template>
+          <el-menu-item index="1-4-1">Option 4-1</el-menu-item>
+        </el-submenu>
+      </el-submenu>
+      <el-submenu index="2">
+        <template slot="title"><i class="el-icon-menu"></i>Navigator Two</template>
+        <el-menu-item-group>
+          <template slot="title">Group 1</template>
+          <el-menu-item index="2-1">Option 1</el-menu-item>
+          <el-menu-item index="2-2">Option 2</el-menu-item>
+        </el-menu-item-group>
+        <el-menu-item-group title="Group 2">
+          <el-menu-item index="2-3">Option 3</el-menu-item>
+        </el-menu-item-group>
+        <el-submenu index="2-4">
+          <template slot="title">Option 4</template>
+          <el-menu-item index="2-4-1">Option 4-1</el-menu-item>
+        </el-submenu>
+      </el-submenu>
+      <el-submenu index="3">
+        <template slot="title"><i class="el-icon-setting"></i>Navigator Three</template>
+        <el-menu-item-group>
+          <template slot="title">Group 1</template>
+          <el-menu-item index="3-1">Option 1</el-menu-item>
+          <el-menu-item index="3-2">Option 2</el-menu-item>
+        </el-menu-item-group>
+        <el-menu-item-group title="Group 2">
+          <el-menu-item index="3-3">Option 3</el-menu-item>
+        </el-menu-item-group>
+        <el-submenu index="3-4">
+          <template slot="title">Option 4</template>
+          <el-menu-item index="3-4-1">Option 4-1</el-menu-item>
+        </el-submenu>
+      </el-submenu>
+    </el-menu>
+  </el-aside>
+  <el-container>
+    <el-header style="text-align: right; font-size: 12px">
+      <el-dropdown>
+        <i class="el-icon-setting" style="margin-right: 15px"></i>
+        <el-dropdown-menu slot="dropdown">
+          <el-dropdown-item>View</el-dropdown-item>
+          <el-dropdown-item>Add</el-dropdown-item>
+          <el-dropdown-item>Delete</el-dropdown-item>
+        </el-dropdown-menu>
+      </el-dropdown>
+      <span>Tom</span>
+    </el-header>
+    <el-main>
+      <el-table :data="tableData">
+        <el-table-column prop="date" label="Date" width="140">
+        </el-table-column>
+        <el-table-column prop="name" label="Name" width="120">
+        </el-table-column>
+        <el-table-column prop="address" label="Address">
+        </el-table-column>
+      </el-table>
+    </el-main>
+  </el-container>
+</el-container>
+
+<style>
+  .el-header {
+    background-color: #1f2d3d;
+    color: #fff;
+    line-height: 60px;
+  }
+  
+  .el-aside {
+    color: #fff;
+  }
+</style>
+
+<script>
+  export default {
+    data() {
+      const item = {
+        date: '2016-05-02',
+        name: 'Tom',
+        address: 'No. 189, Grove St, Los Angeles'
+      };
+      return {
+        tableData: Array(20).fill(item)
+      }
+    }
+  };
+</script>
+```
+:::
+
+### Container Attributes
+| Attribute      | Description          | Type      | Accepted Values       | Default  |
+|---------- |-------------- |---------- |--------------------------------  |-------- |
+| direction | layout direction for child elements | string | horizontal / vertical | vertical when nested with `el-header` or `el-footer`; horizontal otherwise |
+
+### Header Attributes
+| Attribute      | Description          | Type      | Accepted Values       | Default  |
+|---------- |-------------- |---------- |--------------------------------  |-------- |
+| height | height of the header | string | — | 60px |
+
+### Aside Attributes
+| Attribute      | Description          | Type      | Accepted Values       | Default  |
+|---------- |-------------- |---------- |--------------------------------  |-------- |
+| width | width of the side section | string | — | 300px |
+
+### Footer Attributes
+| Attribute      | Description          | Type      | Accepted Values       | Default  |
+|---------- |-------------- |---------- |--------------------------------  |-------- |
+| height | height of the footer | string | — | 60px |

+ 297 - 0
examples/docs/zh-CN/container.md

@@ -0,0 +1,297 @@
+<style>
+  .el-header, .el-footer {
+    background-color: #1f2d3d;
+    color: #fff;
+    line-height: 60px;
+  }
+  
+  .el-aside {
+    color: #fff;
+  }
+  
+  #chang-jian-ye-mian-bu-ju + .demo-container {
+    .el-header, .el-footer {
+      text-align: center;
+    }
+  
+    .el-aside {
+      background-color: #8492a6;
+      text-align: center;
+      line-height: 200px;
+    }
+  
+    .el-main {
+      background-color: #d3dce6;
+      color: #5e6d82;
+      text-align: center;
+      line-height: 160px;
+    }
+    
+    & > .source > .el-container {
+      margin-bottom: 40px;
+    
+      &:nth-child(5) .el-aside,
+      &:nth-child(6) .el-aside {
+        line-height: 260px;
+      }
+
+      &:nth-child(7) .el-aside {
+        line-height: 320px;
+      }
+    }
+  }
+</style>
+
+<script>
+  export default {
+    data() {
+      const item = {
+        date: '2016-05-02',
+        name: '王小虎',
+        address: '上海市普陀区金沙江路 1518 弄'
+      };
+      return {
+        tableData: Array(20).fill(item)
+      }
+    }
+  };
+</script>
+
+## Container 布局容器
+用于布局的容器组件,方便快速搭建页面的基本结构:
+
+`<el-container>`:外层容器。当子元素中包含 `<el-header>` 或 `<el-footer>` 时,全部子元素会垂直上下排列,否则会水平左右排列。
+
+`<el-header>`:顶栏容器。
+
+`<el-aside>`:侧边栏容器。
+
+`<el-main>`:主要区域容器。
+
+`<el-footer>`:底栏容器。
+
+:::tip
+以上组件采用了 flex 布局,使用前请确定目标浏览器是否兼容。此外,`<el-container>` 的子元素只能是后四者,后四者的父元素也只能是 `<el-container>`。
+:::
+
+### 常见页面布局
+
+::: demo
+```html
+<el-container>
+  <el-header>Header</el-header>
+  <el-main>Main</el-main>
+</el-container>
+
+<el-container>
+  <el-header>Header</el-header>
+  <el-main>Main</el-main>
+  <el-footer>Footer</el-footer>
+</el-container>
+
+<el-container>
+  <el-aside width="200px">Aside</el-aside>
+  <el-main>Main</el-main>
+</el-container>
+
+<el-container>
+  <el-header>Header</el-header>
+  <el-container>
+    <el-aside width="200px">Aside</el-aside>
+    <el-main>Main</el-main>
+  </el-container>
+</el-container>
+
+<el-container>
+  <el-header>Header</el-header>
+  <el-container>
+    <el-aside width="200px">Aside</el-aside>
+    <el-container>
+      <el-main>Main</el-main>
+      <el-footer>Footer</el-footer>
+    </el-container>
+  </el-container>
+</el-container>
+
+<el-container>
+  <el-aside width="200px">Aside</el-aside>
+  <el-container>
+    <el-header>Header</el-header>
+    <el-main>Main</el-main>
+  </el-container>
+</el-container>
+
+<el-container>
+  <el-aside width="200px">Aside</el-aside>
+  <el-container>
+    <el-header>Header</el-header>
+    <el-main>Main</el-main>
+    <el-footer>Footer</el-footer>
+  </el-container>
+</el-container>
+
+<style>
+  .el-header, .el-footer {
+    background-color: #1f2d3d;
+    color: #fff;
+    text-align: center;
+    line-height: 60px;
+  }
+  
+  .el-aside {
+    background-color: #8492a6;
+    color: #fff;
+    text-align: center;
+    line-height: 200px;
+  }
+  
+  .el-main {
+    background-color: #d3dce6;
+    color: #5e6d82;
+    text-align: center;
+    line-height: 160px;
+  }
+  
+  body > .el-container {
+    margin-bottom: 40px;
+  }
+  
+  .el-container:nth-child(5) .el-aside,
+  .el-container:nth-child(6) .el-aside {
+    line-height: 260px;
+  }
+  
+  .el-container:nth-child(7) .el-aside {
+    line-height: 320px;
+  }
+</style>
+```
+:::
+
+### 实例
+
+::: demo
+```html
+<el-container style="height: 500px; border: 1px solid #eee">
+  <el-aside width="200px" style="background-color: rgb(238, 241, 246)">
+    <el-menu :default-openeds="['1', '3']">
+      <el-submenu index="1">
+        <template slot="title"><i class="el-icon-message"></i>导航一</template>
+        <el-menu-item-group>
+          <template slot="title">分组一</template>
+          <el-menu-item index="1-1">选项1</el-menu-item>
+          <el-menu-item index="1-2">选项2</el-menu-item>
+        </el-menu-item-group>
+        <el-menu-item-group title="分组2">
+          <el-menu-item index="1-3">选项3</el-menu-item>
+        </el-menu-item-group>
+        <el-submenu index="1-4">
+          <template slot="title">选项4</template>
+          <el-menu-item index="1-4-1">选项4-1</el-menu-item>
+        </el-submenu>
+      </el-submenu>
+      <el-submenu index="2">
+        <template slot="title"><i class="el-icon-menu"></i>导航二</template>
+        <el-menu-item-group>
+          <template slot="title">分组一</template>
+          <el-menu-item index="2-1">选项1</el-menu-item>
+          <el-menu-item index="2-2">选项2</el-menu-item>
+        </el-menu-item-group>
+        <el-menu-item-group title="分组2">
+          <el-menu-item index="2-3">选项3</el-menu-item>
+        </el-menu-item-group>
+        <el-submenu index="2-4">
+          <template slot="title">选项4</template>
+          <el-menu-item index="2-4-1">选项4-1</el-menu-item>
+        </el-submenu>
+      </el-submenu>
+      <el-submenu index="3">
+        <template slot="title"><i class="el-icon-setting"></i>导航三</template>
+        <el-menu-item-group>
+          <template slot="title">分组一</template>
+          <el-menu-item index="3-1">选项1</el-menu-item>
+          <el-menu-item index="3-2">选项2</el-menu-item>
+        </el-menu-item-group>
+        <el-menu-item-group title="分组2">
+          <el-menu-item index="3-3">选项3</el-menu-item>
+        </el-menu-item-group>
+        <el-submenu index="3-4">
+          <template slot="title">选项4</template>
+          <el-menu-item index="3-4-1">选项4-1</el-menu-item>
+        </el-submenu>
+      </el-submenu>
+    </el-menu>
+  </el-aside>
+  <el-container>
+    <el-header style="text-align: right; font-size: 12px">
+      <el-dropdown>
+        <i class="el-icon-setting" style="margin-right: 15px"></i>
+        <el-dropdown-menu slot="dropdown">
+          <el-dropdown-item>查看</el-dropdown-item>
+          <el-dropdown-item>新增</el-dropdown-item>
+          <el-dropdown-item>删除</el-dropdown-item>
+        </el-dropdown-menu>
+      </el-dropdown>
+      <span>王小虎</span>
+    </el-header>
+    <el-main>
+      <el-table :data="tableData">
+        <el-table-column prop="date" label="日期" width="140">
+        </el-table-column>
+        <el-table-column prop="name" label="姓名" width="120">
+        </el-table-column>
+        <el-table-column prop="address" label="地址">
+        </el-table-column>
+      </el-table>
+    </el-main>
+  </el-container>
+</el-container>
+
+<style>
+  .el-header {
+    background-color: #1f2d3d;
+    color: #fff;
+    line-height: 60px;
+  }
+  
+  .el-aside {
+    color: #fff;
+  }
+</style>
+
+<script>
+  export default {
+    data() {
+      const item = {
+        date: '2016-05-02',
+        name: '王小虎',
+        address: '上海市普陀区金沙江路 1518 弄'
+      };
+      return {
+        tableData: Array(20).fill(item)
+      }
+    }
+  };
+</script>
+```
+:::
+
+### Container Attributes
+| 参数    | 说明     | 类型    | 可选值      | 默认值 |
+|---------|----------|---------|-------------|--------|
+| direction | 子元素的排列方向 | string | horizontal / vertical | 子元素中有 `el-header` 或 `el-footer` 时为 vertical,否则为 horizontal |
+
+### Header Attributes
+| 参数    | 说明     | 类型    | 可选值      | 默认值 |
+|---------|----------|---------|-------------|--------|
+| height | 顶栏高度 | string | — | 60px |
+
+### Aside Attributes
+| 参数    | 说明     | 类型    | 可选值      | 默认值 |
+|---------|----------|---------|-------------|--------|
+| width | 侧边栏宽度 | string | — | 300px |
+
+### Footer Attributes
+| 参数    | 说明     | 类型    | 可选值      | 默认值 |
+|---------|----------|---------|-------------|--------|
+| height | 底栏高度 | string | — | 60px |

+ 8 - 0
examples/nav.config.json

@@ -43,6 +43,10 @@
               "path": "/layout",
               "title": "Layout 布局"
             },
+            {
+              "path": "/container",
+              "title": "Container 布局容器"
+            },
             {
               "path": "/color",
               "title": "Color 色彩"
@@ -285,6 +289,10 @@
               "path": "/layout",
               "title": "Layout"
             },
+            {
+              "path": "/container",
+              "title": "Layout Container"
+            },
             {
               "path": "/color",
               "title": "Color"

+ 8 - 0
packages/aside/index.js

@@ -0,0 +1,8 @@
+import Aside from './src/main';
+
+/* istanbul ignore next */
+Aside.install = function(Vue) {
+  Vue.component(Aside.name, Aside);
+};
+
+export default Aside;

+ 20 - 0
packages/aside/src/main.vue

@@ -0,0 +1,20 @@
+<template>
+  <aside class="el-aside" :style="{ width }">
+    <slot></slot>
+  </aside>
+</template>
+
+<script>
+  export default {
+    name: 'ElAside',
+
+    componentName: 'ElAside',
+
+    props: {
+      width: {
+        type: String,
+        default: '300px'
+      }
+    }
+  };
+</script>

+ 8 - 0
packages/container/index.js

@@ -0,0 +1,8 @@
+import Container from './src/main';
+
+/* istanbul ignore next */
+Container.install = function(Vue) {
+  Vue.component(Container.name, Container);
+};
+
+export default Container;

+ 33 - 0
packages/container/src/main.vue

@@ -0,0 +1,33 @@
+<template>
+  <section class="el-container" :class="{ 'is-vertical': isVertical }">
+    <slot></slot>
+  </section>
+</template>
+
+<script>
+  export default {
+    name: 'ElContainer',
+
+    componentName: 'ElContainer',
+
+    props: {
+      direction: String
+    },
+
+    computed: {
+      isVertical() {
+        if (this.direction === 'vertical') {
+          return true;
+        } else if (this.direction === 'horizontal') {
+          return false;
+        }
+        return this.$slots && this.$slots.default
+          ? this.$slots.default.some(vnode => {
+            const tag = vnode.componentOptions && vnode.componentOptions.tag;
+            return tag === 'el-header' || tag === 'el-footer';
+          })
+          : false;
+      }
+    }
+  };
+</script>

+ 8 - 0
packages/footer/index.js

@@ -0,0 +1,8 @@
+import Footer from './src/main';
+
+/* istanbul ignore next */
+Footer.install = function(Vue) {
+  Vue.component(Footer.name, Footer);
+};
+
+export default Footer;

+ 20 - 0
packages/footer/src/main.vue

@@ -0,0 +1,20 @@
+<template>
+  <footer class="el-footer" :style="{ height }">
+    <slot></slot>
+  </footer>
+</template>
+
+<script>
+  export default {
+    name: 'ElFooter',
+
+    componentName: 'ElFooter',
+
+    props: {
+      height: {
+        type: String,
+        default: '60px'
+      }
+    }
+  };
+</script>

+ 8 - 0
packages/header/index.js

@@ -0,0 +1,8 @@
+import Header from './src/main';
+
+/* istanbul ignore next */
+Header.install = function(Vue) {
+  Vue.component(Header.name, Header);
+};
+
+export default Header;

+ 20 - 0
packages/header/src/main.vue

@@ -0,0 +1,20 @@
+<template>
+  <header class="el-header" :style="{ height }">
+    <slot></slot>
+  </header>
+</template>
+
+<script>
+  export default {
+    name: 'ElHeader',
+
+    componentName: 'ElHeader',
+
+    props: {
+      height: {
+        type: String,
+        default: '60px'
+      }
+    }
+  };
+</script>

+ 8 - 0
packages/main/index.js

@@ -0,0 +1,8 @@
+import Main from './src/main';
+
+/* istanbul ignore next */
+Main.install = function(Vue) {
+  Vue.component(Main.name, Main);
+};
+
+export default Main;

+ 12 - 0
packages/main/src/main.vue

@@ -0,0 +1,12 @@
+<template>
+  <main class="el-main">
+    <slot></slot>
+  </main>
+</template>
+
+<script>
+  export default {
+    name: 'ElMain',
+    componentName: 'ElMain'
+  };
+</script>

+ 8 - 0
packages/theme-default/src/aside.css

@@ -0,0 +1,8 @@
+@charset "UTF-8";
+
+@component-namespace el {
+  @b aside {
+    overflow: auto;
+    box-sizing: border-box;
+  }
+}

+ 12 - 0
packages/theme-default/src/common/var.css

@@ -599,4 +599,16 @@
   --transfer-item-height: 32px;
   --transfer-item-hover-background: var(--color-light-gray);
   --transfer-filter-height: 22px;
+
+  /* Header
+  --------------------------*/
+  --header-padding: 0 20px;
+
+  /* Footer
+  --------------------------*/
+  --footer-padding: 0 20px;
+
+  /* Main
+  --------------------------*/
+  --main-padding: 20px;
 }

+ 14 - 0
packages/theme-default/src/container.css

@@ -0,0 +1,14 @@
+@charset "UTF-8";
+
+@component-namespace el {
+  @b container {
+    display: flex;
+    flex-direction: row;
+    flex: 1;
+    box-sizing: border-box;
+
+    @when vertical {
+      flex-direction: column;
+    }
+  }
+}

+ 9 - 0
packages/theme-default/src/footer.css

@@ -0,0 +1,9 @@
+@charset "UTF-8";
+@import "./common/var.css";
+
+@component-namespace el {
+  @b footer {
+    padding: var(--footer-padding);
+    box-sizing: border-box;
+  }
+}

+ 9 - 0
packages/theme-default/src/header.css

@@ -0,0 +1,9 @@
+@charset "UTF-8";
+@import "./common/var.css";
+
+@component-namespace el {
+  @b header {
+    padding: var(--header-padding);
+    box-sizing: border-box;
+  }
+}

+ 5 - 0
packages/theme-default/src/index.css

@@ -60,3 +60,8 @@
 @import "./cascader.css";
 @import "./color-picker.css";
 @import "./transfer.css";
+@import "./container.css";
+@import "./header.css";
+@import "./aside.css";
+@import "./main.css";
+@import "./footer.css";

+ 11 - 0
packages/theme-default/src/main.css

@@ -0,0 +1,11 @@
+@charset "UTF-8";
+@import "./common/var.css";
+
+@component-namespace el {
+  @b main {
+    flex: 1;
+    overflow: auto;
+    box-sizing: border-box;
+    padding: var(--main-padding);
+  }
+}

+ 17 - 2
src/index.js

@@ -1,4 +1,4 @@
-/* Automatic generated by './build/bin/build-entry.js' */
+/* Automatically generated by './build/bin/build-entry.js' */
 
 import Pagination from '../packages/pagination/index.js';
 import Dialog from '../packages/dialog/index.js';
@@ -64,6 +64,11 @@ import CollapseItem from '../packages/collapse-item/index.js';
 import Cascader from '../packages/cascader/index.js';
 import ColorPicker from '../packages/color-picker/index.js';
 import Transfer from '../packages/transfer/index.js';
+import Container from '../packages/container/index.js';
+import Header from '../packages/header/index.js';
+import Aside from '../packages/aside/index.js';
+import Main from '../packages/main/index.js';
+import Footer from '../packages/footer/index.js';
 import locale from 'element-ui/src/locale';
 import CollapseTransition from 'element-ui/src/transitions/collapse-transition';
 
@@ -128,6 +133,11 @@ const components = [
   Cascader,
   ColorPicker,
   Transfer,
+  Container,
+  Header,
+  Aside,
+  Main,
+  Footer,
   CollapseTransition
 ];
 
@@ -226,5 +236,10 @@ module.exports = {
   CollapseItem,
   Cascader,
   ColorPicker,
-  Transfer
+  Transfer,
+  Container,
+  Header,
+  Aside,
+  Main,
+  Footer
 };

+ 106 - 0
test/unit/specs/container.spec.js

@@ -0,0 +1,106 @@
+import { createTest, createVue, destroyVM } from '../util';
+import Container from 'packages/container';
+import Header from 'packages/header';
+import Main from 'packages/main';
+import Aside from 'packages/aside';
+import Footer from 'packages/footer';
+
+describe('Container', () => {
+  let vm;
+  afterEach(() => {
+    destroyVM(vm);
+  });
+
+  it('create', () => {
+    vm = createTest(Container, true);
+    expect(vm.$el).to.exist;
+  });
+
+  it('vertical', () => {
+    vm = createVue({
+      template: `
+        <el-container>
+          <el-header></el-header>
+          <el-main></el-main>
+        </el-container>
+      `
+    }, true);
+    expect(vm.$children[0].$el.classList.contains('is-vertical')).to.true;
+  });
+});
+
+describe('Header', () => {
+  let vm;
+  afterEach(() => {
+    destroyVM(vm);
+  });
+
+  it('create', () => {
+    vm = createTest(Header, true);
+    expect(vm.$el).to.exist;
+  });
+
+  it('height', () => {
+    vm = createVue({
+      template: `
+        <el-header height="100px"></el-header>
+      `
+    }, true);
+    expect(vm.$children[0].$el.style.height).to.equal('100px');
+  });
+});
+
+describe('Aside', () => {
+  let vm;
+  afterEach(() => {
+    destroyVM(vm);
+  });
+
+  it('create', () => {
+    vm = createTest(Aside, true);
+    expect(vm.$el).to.exist;
+  });
+
+  it('width', () => {
+    vm = createVue({
+      template: `
+        <el-aside width="200px"></el-aside>
+      `
+    }, true);
+    expect(vm.$children[0].$el.style.width).to.equal('200px');
+  });
+});
+
+describe('Main', () => {
+  let vm;
+  afterEach(() => {
+    destroyVM(vm);
+  });
+
+  it('create', () => {
+    vm = createTest(Main, true);
+    expect(vm.$el).to.exist;
+  });
+});
+
+describe('Footer', () => {
+  let vm;
+  afterEach(() => {
+    destroyVM(vm);
+  });
+
+  it('create', () => {
+    vm = createTest(Footer, true);
+    expect(vm.$el).to.exist;
+  });
+
+  it('height', () => {
+    vm = createVue({
+      template: `
+        <el-footer height="100px"></el-footer>
+      `
+    }, true);
+    expect(vm.$children[0].$el.style.height).to.equal('100px');
+  });
+});
+