Skip to content

Commit afb9039

Browse files
authored
feat(drawer): add showAnimation prop (#193)
* feat(drawer): add showAnimation prop * fix(drawer): fix question of type checking
1 parent e82c96f commit afb9039

File tree

8 files changed

+121
-68
lines changed

8 files changed

+121
-68
lines changed

packages/devui-vue/devui/drawer/src/components/drawer-body.tsx

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { defineComponent, inject, computed } from 'vue'
1+
import { defineComponent, inject, computed, Transition } from 'vue'
22

33
import './drawer-body.scss'
44

@@ -14,6 +14,7 @@ export default defineComponent({
1414
const visible: boolean = inject('visible')
1515
const backdropCloseable: any = inject('backdropCloseable')
1616
const destroyOnHide: any = inject('destroyOnHide')
17+
const showAnimation: any = inject('showAnimation')
1718

1819
const navRight = computed(() => position.value === 'right' ? { 'right': 0 } : { 'left': 0 })
1920
const navWidth = computed(() => isFullScreen.value ? '100vw' : width.value)
@@ -34,6 +35,8 @@ export default defineComponent({
3435
navRight,
3536
navWidth,
3637
visible,
38+
position,
39+
showAnimation,
3740
clickContent,
3841
handleDrawerClose,
3942
destroyOnHide,
@@ -42,25 +45,27 @@ export default defineComponent({
4245

4346
render() {
4447
const {
45-
zindex, slots, isCover, navRight, navWidth,
46-
visible, handleDrawerClose, destroyOnHide } = this
48+
zindex, slots, isCover, navRight, navWidth, showAnimation,
49+
visible, handleDrawerClose, destroyOnHide, position } = this
4750

4851
if (destroyOnHide.value && !visible) {
4952
return null
5053
}
5154

52-
const visibleVal = visible ? 'visible' : 'hidden'
55+
const transitionName = showAnimation ? position : 'none'
5356

5457
return (
55-
<div class="devui-drawer" style={{ zIndex: zindex, visibility : visibleVal }} onClick={handleDrawerClose} >
58+
<div class="devui-drawer" style={{ zIndex: zindex }} onClick={handleDrawerClose} >
5659
{isCover ? <div class="devui-overlay-backdrop" /> : null}
57-
<div class="devui-overlay-wrapper">
58-
<div class="devui-drawer-nav" style={{ 'width': navWidth, ...navRight }}>
59-
<div class="devui-drawer-content" onClick={this.clickContent}>
60-
{slots.default ? slots.default() : null}
60+
<Transition name={'devui-drawer-' + transitionName}>
61+
<div class="devui-overlay-wrapper" v-show={ visible }>
62+
<div class="devui-drawer-nav" style={{ 'width': navWidth, ...navRight }}>
63+
<div class="devui-drawer-content" onClick={this.clickContent}>
64+
{slots.default ? slots.default() : null}
65+
</div>
6166
</div>
6267
</div>
63-
</div>
68+
</Transition>
6469
</div>
6570
)
6671
}

packages/devui-vue/devui/drawer/src/components/drawer-container.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ export default defineComponent({
1313
if (destroyOnHide.value && !visible) {
1414
return null
1515
}
16-
const visibleVal = this.visible ? 'visible' : 'hidden'
17-
return <div style={{ visibility : visibleVal }}>内容区域</div>
16+
return <div>内容区域</div>
1817
}
1918
})

packages/devui-vue/devui/drawer/src/components/drawer-header.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,17 @@ export default defineComponent({
2626
return { fullScreenClassName, visible, handleFullScreen, handleDrawerClose, destroyOnHide }
2727
},
2828
render() {
29-
const {
30-
handleFullScreen, handleDrawerClose, visible,
31-
fullScreenClassName, destroyOnHide
29+
const {
30+
handleFullScreen, handleDrawerClose, visible,
31+
fullScreenClassName, destroyOnHide
3232
} = this
3333

3434
if (destroyOnHide.value && !visible) {
3535
return null
3636
}
3737

38-
const visibleVal = visible ? 'visible' : 'hidden'
39-
4038
return (
41-
<div class="devui-drawer-header" style= {{ visibility : visibleVal }}>
39+
<div class="devui-drawer-header">
4240
<div class="devui-drawer-header-item">
4341
<span class="devui-drawer-header-item icon icon-more-operate" />
4442
</div>

packages/devui-vue/devui/drawer/src/drawer-service.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { createApp } from 'vue'
22
import { DrawerProps } from './drawer-types'
33

44
import DDrawer from './drawer'
5+
import { omit } from 'lodash-es'
56

67
interface drawerInstance {
78
hide(): void
@@ -13,8 +14,12 @@ function createDrawerApp(props: DrawerProps, drawer: drawerInstance, el: HTMLEle
1314
if (drawer) {
1415
return drawer
1516
}
17+
const restProps = omit(props, ['header', 'content', 'visible'])
18+
1619
const res = createApp(
17-
<DDrawer v-model:visible={props.visible}>{{ header: props.header, content: props.content }}</DDrawer>
20+
// BUG: this function generates a new app, v-model instructor of template is like not working
21+
// TODO: could be fixed by using self-defined header slot
22+
<DDrawer v-model={[props.visible, 'visible']} {...restProps}>{{ header: props.header, content: props.content }}</DDrawer>
1823
)
1924
res.mount(el)
2025
return res

packages/devui-vue/devui/drawer/src/drawer-types.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,18 @@ export const drawerProps = {
3333
type: Boolean,
3434
default: false,
3535
},
36+
showAnimation: { // 是否启用动效
37+
type: Boolean,
38+
default: true,
39+
},
3640
beforeHidden: { // 关闭前的回调
3741
type: [Promise, Function] as PropType<Promise<boolean> | (() => boolean | Promise<boolean>)>,
3842
},
3943
content: { // 默认内容插槽
40-
type: [Object, Function],
44+
type: Object,
4145
},
4246
header: { // 头部内容插槽
43-
type: [Object, Function],
47+
type: Object,
4448
},
4549
} as const
4650

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,41 @@
1+
.devui-drawer{
2+
&-left-enter-active {
3+
animation: left-inout 0.3s;
4+
}
15

6+
&-left-leave-active {
7+
animation: left-inout 0.3s reverse;
8+
}
9+
10+
&-right-enter-active {
11+
animation: right-inout 0.3s;
12+
}
13+
14+
&-right-leave-active {
15+
animation: right-inout 0.3s reverse;
16+
}
17+
}
18+
19+
@keyframes right-inout {
20+
0% {
21+
transform: translateX(100px);
22+
opacity: 0;
23+
}
24+
25+
100% {
26+
transform: translateX(0);
27+
opacity: 1;
28+
}
29+
}
30+
31+
@keyframes left-inout {
32+
0% {
33+
transform: translateX(-100px);
34+
opacity: 0;
35+
}
36+
37+
100% {
38+
transform: translateX(0);
39+
opacity: 1;
40+
}
41+
}

packages/devui-vue/devui/drawer/src/drawer.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,19 @@ import DrawerHeader from './components/drawer-header'
55
import DrawerContainer from './components/drawer-container'
66
import DrawerBody from './components/drawer-body'
77

8+
import './drawer.scss'
9+
810
export default defineComponent({
911
name: 'DDrawer',
1012
props: drawerProps,
1113
emits: ['close', 'update:visible', 'afterOpened'],
1214
setup(props: DrawerProps, { emit, slots }) {
1315
const {
1416
width, visible, zIndex, isCover, escKeyCloseable, position,
15-
backdropCloseable, destroyOnHide
17+
backdropCloseable, destroyOnHide, showAnimation
1618
} = toRefs(props)
1719
const isFullScreen = ref(false)
18-
20+
1921
const fullscreen = () => {
2022
isFullScreen.value = !isFullScreen.value
2123
}
@@ -66,6 +68,7 @@ export default defineComponent({
6668
provide('isFullScreen', isFullScreen)
6769
provide('backdropCloseable', backdropCloseable)
6870
provide('destroyOnHide', destroyOnHide)
71+
provide('showAnimation', showAnimation)
6972

7073
onUnmounted(() => {
7174
document.removeEventListener('keyup', escCloseDrawer)
@@ -81,16 +84,15 @@ export default defineComponent({
8184
},
8285
render() {
8386
const { fullscreen, closeDrawer, visible, destroyOnHide } = this;
87+
8488
if (destroyOnHide.value && !visible) {
8589
return null
8690
}
8791

88-
const visibleVal = visible ? 'visible' : 'hidden'
8992
return (
9093
<Teleport to="body">
91-
<DrawerBody style= {{ visibility : visibleVal }}>
92-
{/* BUG: 已使用作用域插槽解决 此处对应的 DEMO 使用了 **双向绑定** 导致可以关闭【一种关闭了的'假象'】。*/}
93-
{this.slots.header ? this.slots.header({fullscreen, closeDrawer}) :
94+
<DrawerBody v-show={ visible }>
95+
{this.slots.header ? this.slots.header({fullscreen, closeDrawer}) :
9496
<DrawerHeader onToggleFullScreen={fullscreen} onClose={closeDrawer} />
9597
}
9698
{this.slots.content ? this.slots.content() : <DrawerContainer />}

0 commit comments

Comments
 (0)