diff --git a/packages/element-plus/index.ts b/packages/element-plus/index.ts
index 2976341d0f..08179a551a 100644
--- a/packages/element-plus/index.ts
+++ b/packages/element-plus/index.ts
@@ -3,11 +3,18 @@ import ElButton from '@element-plus/button'
import ElBadge from '@element-plus/badge'
import ElCard from '@element-plus/card'
import ElTag from '@element-plus/tag'
+import ElLayout from '@element-plus/layout'
import ElDivider from '@element-plus/divider'
import ElTimeLine from '@element-plus/time-line'
export {
- ElButton, ElBadge, ElCard, ElDivider, ElTag, ElTimeLine,
+ ElLayout,
+ ElButton,
+ ElBadge,
+ ElCard,
+ ElDivider,
+ ElTag,
+ ElTimeLine,
}
export default function install(app: App): void {
@@ -15,6 +22,7 @@ export default function install(app: App): void {
ElBadge(app)
ElCard(app)
ElTag(app)
+ ElLayout(app)
ElDivider(app)
ElTimeLine(app)
}
diff --git a/packages/element-plus/package.json b/packages/element-plus/package.json
index b7d5be193e..268a2646f8 100644
--- a/packages/element-plus/package.json
+++ b/packages/element-plus/package.json
@@ -16,6 +16,7 @@
"dependencies": {
"@element-plus/badge": "^0.0.0",
"@element-plus/button": "^0.0.0",
+ "@element-plus/layout": "^0.0.0",
"@element-plus/card": "^0.0.0",
"@element-plus/tag": "^0.0.0",
"@element-plus/time-line": "^0.0.0",
diff --git a/packages/layout/__tests__/layout.spec.ts b/packages/layout/__tests__/layout.spec.ts
new file mode 100644
index 0000000000..ba1672bcb1
--- /dev/null
+++ b/packages/layout/__tests__/layout.spec.ts
@@ -0,0 +1,102 @@
+import { mount } from '@vue/test-utils'
+import Col from '../src/col'
+import Row from '../src/row'
+
+describe('Col', () => {
+ it('create', () => {
+ const wrapper = mount(Col)
+ expect(wrapper.classes()).toContain('el-col')
+ })
+
+ it('span', () => {
+ const wrapper = mount(Col, {
+ props: { span: 12 },
+ })
+ expect(wrapper.classes()).toContain('el-col-12')
+ })
+
+ it('pull', () => {
+ const wrapper = mount(Col, {
+ props: { span: 12, pull: 3 },
+ })
+ expect(wrapper.classes()).toContain('el-col-pull-3')
+ })
+
+ it('push', () => {
+ const wrapper = mount(Col, {
+ props: { span: 12, push: 3 },
+ })
+ expect(wrapper.classes()).toContain('el-col-push-3')
+ })
+
+ it('gutter', () => {
+ const TestComponent = {
+ template: `
+
+ `,
+ components: {
+ 'el-col': Col,
+ 'el-row':Row,
+ },
+ }
+ const wrapper = mount(TestComponent)
+ const colElm = wrapper.findComponent({ ref: 'col' }).element as HTMLElement
+ expect(colElm.style.paddingLeft === '10px').toBe(true)
+ expect(colElm.style.paddingRight === '10px').toBe(true)
+ })
+ it('responsive', () => {
+ const TestComponent = {
+ template: `
+
+
+ `,
+ components: {
+ 'el-col': Col,
+ 'el-row':Row,
+ },
+ }
+ const wrapper = mount(TestComponent)
+ const colElmClass = wrapper.findComponent({ ref: 'col' }).classes()
+ expect(colElmClass.includes('el-col-sm-4')).toBe(true)
+ expect(colElmClass.includes('el-col-sm-4')).toBe(true)
+ expect(colElmClass.includes('el-col-sm-offset-2')).toBe(true)
+ expect(colElmClass.includes('el-col-lg-6')).toBe(true)
+ expect(colElmClass.includes('el-col-lg-offset-3')).toBe(true)
+ expect(colElmClass.includes('el-col-md-8')).toBe(true)
+ })
+})
+
+describe('Row', () => {
+ test('create', () => {
+ const wrapper = mount(Row)
+ expect(wrapper.classes()).toContain('el-row')
+ })
+
+ test('gutter', () => {
+ const wrapper = mount(Row, {
+ props: { gutter: 20 },
+ })
+ const rowElm = wrapper.element as HTMLElement
+ expect(rowElm.style.marginLeft).toEqual('-10px')
+ expect(rowElm.style.marginRight).toEqual('-10px')
+ })
+ test('type', () => {
+ const wrapper = mount(Row, {
+ props: { type: 'flex' },
+ })
+ expect(wrapper.classes()).toContain('el-row--flex')
+ })
+ test('justify', () => {
+ const wrapper = mount(Row, {
+ props: { justify: 'end' },
+ })
+ expect(wrapper.classes()).toContain('is-justify-end')
+ })
+ test('align', () => {
+ const wrapper = mount(Row, {
+ props: { align: 'bottom' },
+ })
+ expect(wrapper.classes()).toContain('is-align-bottom')
+ })
+})
+
diff --git a/packages/layout/doc/basic.vue b/packages/layout/doc/basic.vue
new file mode 100644
index 0000000000..5a31a69cdc
--- /dev/null
+++ b/packages/layout/doc/basic.vue
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/layout/doc/index.stories.ts b/packages/layout/doc/index.stories.ts
new file mode 100644
index 0000000000..a5e472687e
--- /dev/null
+++ b/packages/layout/doc/index.stories.ts
@@ -0,0 +1,6 @@
+export { default as BasicUsage } from './basic.vue'
+
+export default {
+ title: 'Layout',
+}
+
diff --git a/packages/layout/index.ts b/packages/layout/index.ts
new file mode 100644
index 0000000000..570d70f3fe
--- /dev/null
+++ b/packages/layout/index.ts
@@ -0,0 +1,7 @@
+import { App } from 'vue'
+import Row from './src/row'
+import Col from './src/col'
+export default (app: App) => {
+ app.component(Row.name, Row)
+ app.component(Col.name, Col)
+}
diff --git a/packages/layout/package.json b/packages/layout/package.json
new file mode 100644
index 0000000000..2f9e2928c3
--- /dev/null
+++ b/packages/layout/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "@element-plus/layout",
+ "version": "0.0.0",
+ "main": "dist/index.js",
+ "license": "MIT",
+ "peerDependencies": {
+ "vue": "^3.0.0-rc.1"
+ },
+ "devDependencies": {
+ "@vue/test-utils": "^2.0.0-beta.0"
+ }
+}
diff --git a/packages/layout/src/col.ts b/packages/layout/src/col.ts
new file mode 100644
index 0000000000..82ffb538c1
--- /dev/null
+++ b/packages/layout/src/col.ts
@@ -0,0 +1,67 @@
+import { defineComponent, computed, inject, h } from 'vue'
+
+const ElCol = defineComponent({
+ name: 'ElCol',
+ props: {
+ span: {
+ type: Number,
+ default: 24,
+ },
+ offset: Number,
+ pull: Number,
+ push: Number,
+ xs: [Number, Object],
+ sm: [Number, Object],
+ md: [Number, Object],
+ lg: [Number, Object],
+ xl: [Number, Object],
+ },
+ setup(props, { slots }) {
+ const gutter = inject('ElRow', 0)
+
+ const style = computed(() => {
+ if (gutter) {
+ return {
+ paddingLeft: gutter / 2 + 'px',
+ paddingRight: gutter / 2 + 'px',
+ }
+ }
+ return {}
+ })
+ const classList = computed(() => {
+ const ret: string[] = []
+ const pos: ['span', 'offset', 'pull', 'push'] = ['span', 'offset', 'pull', 'push']
+ pos.forEach(prop => {
+ const size = props[prop]
+ if (typeof size === 'number' && size >= 0) {
+ ret.push(prop !== 'span' ? `el-col-${prop}-${props[prop]}` : `el-col-${props[prop]}`)
+ }
+ })
+ const sizes: ['xs', 'sm', 'md', 'lg', 'xl'] = ['xs', 'sm', 'md', 'lg', 'xl']
+ sizes.forEach(size => {
+ if (typeof props[size] === 'number') {
+ ret.push(`el-col-${size}-${props[size]}`)
+ } else if (typeof props[size] === 'object') {
+ const sizeProps = props[size]
+ Object.keys(sizeProps).forEach(prop => {
+ ret.push(
+ prop !== 'span' ? `el-col-${size}-${prop}-${sizeProps[prop]}` : `el-col-${size}-${sizeProps[prop]}`,
+ )
+ })
+ }
+ })
+ return ret
+ })
+
+ return () =>h(
+ 'div',
+ {
+ class: ['el-col', classList.value],
+ style: style.value,
+ },
+ slots.default?.(),
+ )
+ },
+})
+
+export default ElCol
diff --git a/packages/layout/src/row.ts b/packages/layout/src/row.ts
new file mode 100644
index 0000000000..8068b40056
--- /dev/null
+++ b/packages/layout/src/row.ts
@@ -0,0 +1,47 @@
+import { defineComponent, computed, h, provide } from 'vue'
+export default defineComponent({
+ name: 'ElRow',
+ props: {
+ tag: {
+ type: String,
+ default: 'div',
+ },
+ gutter: Number,
+ type: String,
+ justify: {
+ type: String,
+ default: 'start',
+ },
+ align: {
+ type: String,
+ default: 'top',
+ },
+ },
+ setup(props, { slots }) {
+ provide('ElRow', props.gutter)
+
+ const style = computed(() => {
+ const ret = { marginLeft: '', marginRight: '' }
+ if (props.gutter) {
+ ret.marginLeft = `-${props.gutter / 2}px`
+ ret.marginRight = ret.marginLeft
+ }
+ return ret
+ })
+
+ return () =>
+ h(
+ props.tag,
+ {
+ class: [
+ 'el-row',
+ props.justify !== 'start' ? `is-justify-${props.justify}` : '',
+ props.align !== 'top' ? `is-align-${props.align}` : '',
+ props.type === 'flex' ? 'el-row--flex' : '',
+ ],
+ style: style.value,
+ },
+ slots.default?.(),
+ )
+ },
+})
diff --git a/src/router.ts b/src/router.ts
deleted file mode 100644
index 73c64d52e0..0000000000
--- a/src/router.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { RouteRecordRaw, createRouter, createWebHistory } from 'vue-router'
-import Button from '@element-plus/button/doc/index.vue'
-import Tag from '@element-plus/tag/doc/index.vue'
-
-const routes: Array = [
- {
- path: '/button',
- component: Button,
- },
- {
- path: '/tag',
- component: Tag,
- },
-]
-
-const router = createRouter({
- history: createWebHistory(process.env.BASE_URL),
- routes,
-})
-
-export default router