Skip to content

Commit

Permalink
Merge pull request hug-sun#164 from wxy0902/master
Browse files Browse the repository at this point in the history
refactor: drawer component and add test
  • Loading branch information
motao314 authored Sep 3, 2020
2 parents 79855da + 531fc4e commit 4f28645
Show file tree
Hide file tree
Showing 6 changed files with 509 additions and 212 deletions.
3 changes: 2 additions & 1 deletion build/bin/build-entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ ComponentNames.forEach((name) => {
'message',
'input-number',
'step',
'steps'
'steps',
'drawer'
].indexOf(name) > -1
) {
// 白名单 挨个替换
Expand Down
12 changes: 6 additions & 6 deletions examples/docs/zh-CN/drawer.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

<el-drawer
title="我是标题"
:visible.sync="drawer"
v-model:visible="drawer"
:direction="direction"
:before-close="handleClose">
<span>我来啦!</span>
Expand Down Expand Up @@ -63,7 +63,7 @@

<el-drawer
title="我是标题"
:visible.sync="drawer"
v-model:visible="drawer"
:with-header="false">
<span>我来啦!</span>
</el-drawer>
Expand Down Expand Up @@ -92,7 +92,7 @@
<el-button type="text" @click="dialog = true">打开嵌套 Form 的 Drawer</el-button>
<el-drawer
title="我嵌套了表格!"
:visible.sync="table"
v-model:visible="table"
direction="rtl"
size="50%">
<el-table :data="gridData">
Expand All @@ -105,7 +105,7 @@
<el-drawer
title="我嵌套了 Form !"
:before-close="handleClose"
:visible.sync="dialog"
v-model:visible="dialog"
direction="ltr"
custom-class="demo-drawer"
ref="drawer"
Expand Down Expand Up @@ -210,15 +210,15 @@ export default {

<el-drawer
title="我是外面的 Drawer"
:visible.sync="drawer"
v-model:visible="drawer"
size="50%">
<div>
<el-button @click="innerDrawer = true">打开里面的!</el-button>
<el-drawer
title="我是里面的"
:append-to-body="true"
:before-close="handleClose"
:visible.sync="innerDrawer">
v-model:visible="innerDrawer">
<p>_(:зゝ∠)_</p>
</el-drawer>
</div>
Expand Down
246 changes: 246 additions & 0 deletions packages/drawer/Drawer.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
<template>
<transition name="el-drawer-fade" @after-enter="afterEnter" @after-leave="afterLeave">
<div class="el-drawer__wrapper" tabindex="-1" v-show="visible">
<div
class="el-drawer__container"
:class="visible && 'el-drawer__open'"
@click.self="handleWrapperClick"
role="document"
tabindex="-1"
>
<div
aria-modal="true"
aria-labelledby="el-drawer__title"
:aria-label="title"
class="el-drawer"
:class="[direction, customClass]"
:style="isHorizontal ? `width: ${size}` : `height: ${size}`"
ref="drawer"
role="dialog"
tabindex="-1"
>
<header class="el-drawer__header" id="el-drawer__title" v-if="withHeader">
<slot name="title">
<span role="heading" tabindex="0" :title="title">
{{
title
}}
</span>
</slot>
<button
:aria-label="`close ${title || 'drawer'}`"
class="el-drawer__close-btn"
type="button"
v-if="showClose"
@click="closeDrawer"
>
<i class="el-dialog__close el-icon el-icon-close"></i>
</button>
</header>
<section class="el-drawer__body" v-if="rendered">
<slot></slot>
</section>
</div>
</div>
</div>
</transition>
</template>

<script>
import {
toRefs,
computed,
ref,
watch,
getCurrentInstance,
nextTick,
onMounted,
onUnmounted
} from 'vue'
import { popupProps, usePopup } from 'element-ui/src/use/popup'
import Utils from 'element-ui/src/utils/aria-utils'
export default {
name: 'ElDrawer',
props: {
...popupProps,
appendToBody: {
type: Boolean,
default: false
},
beforeClose: {
type: Function
},
customClass: {
type: String,
default: ''
},
closeOnPressEscape: {
type: Boolean,
default: true
},
destroyOnClose: {
type: Boolean,
default: false
},
modal: {
type: Boolean,
default: true
},
direction: {
type: String,
default: 'rtl',
validator(val) {
return ['ltr', 'rtl', 'ttb', 'btt'].indexOf(val) !== -1
}
},
modalAppendToBody: {
type: Boolean,
default: true
},
showClose: {
type: Boolean,
default: true
},
size: {
type: String,
default: '30%'
},
title: {
type: String,
default: ''
},
visible: {
type: Boolean
},
wrapperClosable: {
type: Boolean,
default: true
},
withHeader: {
type: Boolean,
default: true
}
},
emits: ['update:visible', 'close', 'opened', 'open', 'closed'],
setup(props, { emit }) {
const { rendered, open } = usePopup(props)
const {
appendToBody,
beforeClose,
customClass,
destroyOnClose,
direction,
showClose,
size,
title,
visible,
wrapperClosable,
withHeader
} = toRefs(props)
const closed = ref(false)
const prevActiveElement = ref(null)
const drawer = ref(null)
const self = getCurrentInstance().proxy
const isHorizontal = computed(() => {
return direction.value === 'rtl' || direction.value === 'ltr'
})
watch(visible, val => {
const el = self.$el
if (val) {
closed.value = false
emit('open')
if (appendToBody.value) {
document.body.appendChild(el)
}
prevActiveElement.value = document.activeElement
nextTick(() => {
Utils.focusFirstDescendant(drawer.value)
})
} else {
if (!closed.value) emit('close')
nextTick(() => {
if (prevActiveElement.value) {
prevActiveElement.value.focus()
}
})
}
})
const afterEnter = () => {
emit('opened')
}
const afterLeave = () => {
emit('closed')
}
const handleWrapperClick = () => {
if (wrapperClosable.value) {
closeDrawer()
}
}
const closeDrawer = () => {
if (beforeClose && typeof beforeClose.value === 'function') {
beforeClose.value(hide)
} else {
hide()
}
}
const hide = cancel => {
if (cancel !== false) {
emit('update:visible', false)
emit('close')
if (destroyOnClose.value === true) {
rendered.value = false
}
closed.value = true
}
}
// todo: ESC 退出模态框,暂时无调用,lint过不去先在return调用
const handleClose = () => {
// This method here will be called by PopupManger, when the `closeOnPressEscape` was set to true
// pressing `ESC` will call this method, and also close the drawer.
// This method also calls `beforeClose` if there was one.
closeDrawer()
}
onMounted(() => {
if (visible.value) {
rendered.value = true
open()
}
})
onUnmounted(() => {
// if appendToBody is true, remove DOM node after destroy
if (appendToBody.value && self.$el && self.$el.parentNode) {
self.$el.parentNode.removeChild(self.$el)
}
})
return {
customClass,
direction,
showClose,
size,
title,
withHeader,
isHorizontal,
drawer,
rendered,
afterEnter,
afterLeave,
handleWrapperClick,
closeDrawer,
handleClose
}
}
}
</script>
Loading

0 comments on commit 4f28645

Please sign in to comment.