Skip to content

Commit a033969

Browse files
committed
添加drawer组件
1 parent 24356ae commit a033969

File tree

11 files changed

+305
-2
lines changed

11 files changed

+305
-2
lines changed

packages/drawer/index.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { App } from 'vue'
2+
import Component from './src/index.vue'
3+
export const install = function (app: App) {
4+
app.component(Component.name as string, Component)
5+
}
6+
7+
export default Component

packages/drawer/src/index.vue

+212
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
<template>
2+
<transition
3+
name="el-drawer-fade"
4+
@after-enter="afterEnter"
5+
@after-leave="afterLeave">
6+
<div
7+
class="el-drawer__wrapper"
8+
tabindex="-1"
9+
v-show="visible">
10+
<div
11+
class="el-drawer__container"
12+
:class="visible && 'el-drawer__open'"
13+
@click.self="handleWrapperClick"
14+
role="document"
15+
tabindex="-1">
16+
<div
17+
aria-modal="true"
18+
aria-labelledby="el-drawer__title"
19+
:aria-label="title"
20+
class="el-drawer"
21+
:class="[direction, customClass]"
22+
:style="isHorizontal ? `width: ${size}` : `height: ${size}`"
23+
ref="drawer"
24+
role="dialog"
25+
tabindex="-1"
26+
>
27+
<header class="el-drawer__header" id="el-drawer__title" v-if="withHeader">
28+
<slot name="title">
29+
<span role="heading" tabindex="0" :title="title">{{ title }}</span>
30+
</slot>
31+
<button
32+
:aria-label="`close ${title || 'drawer'}`"
33+
class="el-drawer__close-btn"
34+
type="button"
35+
v-if="showClose"
36+
@click="closeDrawer">
37+
<i class="el-dialog__close el-icon el-icon-close"></i>
38+
</button>
39+
</header>
40+
<section class="el-drawer__body" v-if="rendered">
41+
<slot></slot>
42+
</section>
43+
</div>
44+
</div>
45+
</div>
46+
</transition>
47+
</template>
48+
49+
<script lang="ts">
50+
// @ts-ignore
51+
import Popup from '@/utils/popup'
52+
// @ts-ignore
53+
import Utils from '@/utils/aria-utils'
54+
import { ComponentInternalInstance, computed, defineComponent, getCurrentInstance, nextTick, onMounted, onUnmounted, Prop, ref, watch } from 'vue'
55+
56+
export default defineComponent({
57+
name: 'ElDrawer',
58+
mixins: [Popup],
59+
emits: ['open', 'opened', 'close', 'closed', 'update:visible'],
60+
props: {
61+
appendToBody: {
62+
type: Boolean,
63+
default: false
64+
},
65+
beforeClose: {
66+
type: Function
67+
},
68+
customClass: {
69+
type: String,
70+
default: ''
71+
},
72+
closeOnPressEscape: {
73+
type: Boolean,
74+
default: true
75+
},
76+
destroyOnClose: {
77+
type: Boolean,
78+
default: false
79+
},
80+
modal: {
81+
type: Boolean,
82+
default: true
83+
},
84+
direction: {
85+
type: String,
86+
default: 'rtl',
87+
validator(val: string) {
88+
return ['ltr', 'rtl', 'ttb', 'btt'].indexOf(val) !== -1;
89+
}
90+
} as Prop<String>,
91+
modalAppendToBody: {
92+
type: Boolean,
93+
default: true
94+
},
95+
showClose: {
96+
type: Boolean,
97+
default: true
98+
},
99+
size: {
100+
type: String,
101+
default: '30%'
102+
},
103+
title: {
104+
type: String,
105+
default: ''
106+
},
107+
visible: {
108+
type: Boolean
109+
},
110+
wrapperClosable: {
111+
type: Boolean,
112+
default: true
113+
},
114+
withHeader: {
115+
type: Boolean,
116+
default: true
117+
}
118+
},
119+
120+
setup(props, { emit }) {
121+
const closed = ref(false)
122+
const prevActiveElement = ref(null as Element | HTMLElement | null)
123+
const rendered = ref(false)
124+
const isHorizontal = computed(() => {
125+
return props.direction === 'rtl' || props.direction === 'ltr'
126+
})
127+
const instance = getCurrentInstance() as ComponentInternalInstance
128+
watch(() => props.visible, (val) => {
129+
const el = instance.vnode.el as HTMLElement
130+
if (val) {
131+
closed.value = false
132+
emit('open')
133+
if (props.appendToBody) {
134+
document.body.appendChild(el)
135+
}
136+
prevActiveElement.value = document.activeElement
137+
nextTick(() => {
138+
Utils.focusFirstDescendant(instance.refs.drawer)
139+
})
140+
} else {
141+
if (!closed.value) emit('close')
142+
nextTick(() => {
143+
if (prevActiveElement.value) {
144+
(prevActiveElement.value as HTMLElement)?.focus()
145+
}
146+
})
147+
}
148+
})
149+
150+
const afterEnter = () => {
151+
emit('opened')
152+
}
153+
const afterLeave = () => {
154+
emit('closed')
155+
}
156+
const hide = (cancel?:boolean) => {
157+
if (cancel !== false) {
158+
emit('update:visible', false);
159+
emit('close');
160+
if (props.destroyOnClose === true) {
161+
rendered.value = false
162+
}
163+
closed.value = true;
164+
}
165+
}
166+
const handleWrapperClick = () => {
167+
if (props.wrapperClosable) {
168+
closeDrawer()
169+
}
170+
}
171+
const closeDrawer = () => {
172+
if (typeof props.beforeClose === 'function') {
173+
props.beforeClose(hide)
174+
} else {
175+
hide()
176+
}
177+
}
178+
const handleClose = () => {
179+
// This method here will be called by PopupManger, when the `closeOnPressEscape` was set to true
180+
// pressing `ESC` will call this method, and also close the drawer.
181+
// This method also calls `beforeClose` if there was one.
182+
closeDrawer()
183+
}
184+
onMounted(() => {
185+
if (props.visible) {
186+
rendered.value = true
187+
open()
188+
}
189+
})
190+
onUnmounted(() => {
191+
const el = instance.vnode.el
192+
if (props.appendToBody && el?.parentNode) {
193+
el.parentNode.removeChild(el)
194+
}
195+
})
196+
197+
return {
198+
rendered,
199+
isHorizontal,
200+
afterEnter,
201+
afterLeave,
202+
handleWrapperClick,
203+
closeDrawer,
204+
handleClose
205+
}
206+
}
207+
})
208+
</script>
209+
210+
<style lang="scss">
211+
@import 'theme/drawer.scss';
212+
</style>

packages/form-item/index.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { App } from 'vue'
2+
import Component from '../form/src/form-item.vue'
3+
export const install = function (app: App) {
4+
app.component(Component.name as string, Component)
5+
}
6+
7+
export default Component

packages/form/index.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { App } from 'vue'
2+
import Component from './src/index.vue'
3+
export const install = function (app: App) {
4+
app.component(Component.name as string, Component)
5+
}
6+
7+
export default Component

packages/form/src/form-item.vue

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<template>
2+
<div></div>
3+
</template>
4+
<script>
5+
import { defineComponent } from 'vue'
6+
export default defineComponent({
7+
name: 'ElFormItem'
8+
})
9+
</script>

packages/form/src/index.vue

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<template>
2+
<div>--form组件暂未开发--</div>
3+
</template>
4+
<script>
5+
import { defineComponent } from 'vue'
6+
export default defineComponent({
7+
name: 'ElForm'
8+
})
9+
</script>

packages/index.ts

+22-2
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@ import collapseItem from './collapse-item'
2929
import collapseTransition from './collapse-transition'
3030
import dialog from './dialog'
3131
import divider from './divider'
32+
import drawer from './drawer'
3233
import { ElementUIOptions } from './component'
3334
import footer from './footer'
35+
import form from './form'
36+
import formItem from './form-item'
3437
import header from './header'
3538
import icon from './icon'
3639
import input from './input'
@@ -46,6 +49,8 @@ import optionGroup from './option-group'
4649
import scrollbar from './scrollbar'
4750
import select from './select'
4851
import tag from './tag'
52+
import table from './table'
53+
import tableColumn from './table-column'
4954

5055
export const Alert = alert
5156
export const Aside = aside
@@ -73,7 +78,10 @@ export const Carousel = carousel
7378
export const CarouselItem = carouselItem
7479
export const Dialog = dialog
7580
export const Divider = divider
81+
export const Drawer = drawer
7682
export const Footer = footer
83+
export const Form = form
84+
export const FormItem = formItem
7785
export const Header = header
7886
export const Icon = icon
7987
export const Input = input
@@ -89,6 +97,8 @@ export const OptionGroup = optionGroup
8997
export const Scrollbar = scrollbar
9098
export const Select = select
9199
export const Tag = tag
100+
export const Table = table
101+
export const TableColumn = tableColumn
92102

93103
export const components = [
94104
Alert,
@@ -117,7 +127,10 @@ export const components = [
117127
Container,
118128
Dialog,
119129
Divider,
130+
Drawer,
120131
Footer,
132+
Form,
133+
FormItem,
121134
Header,
122135
Icon,
123136
Input,
@@ -132,7 +145,9 @@ export const components = [
132145
RadioGroup,
133146
Scrollbar,
134147
Select,
135-
Tag
148+
Tag,
149+
Table,
150+
TableColumn
136151
]
137152

138153
const install = function(app: App, opts = {}) {
@@ -182,7 +197,10 @@ export default {
182197
Container,
183198
Dialog,
184199
Divider,
200+
Drawer,
185201
Footer,
202+
Form,
203+
FormItem,
186204
Header,
187205
Icon,
188206
Input,
@@ -197,5 +215,7 @@ export default {
197215
RadioGroup,
198216
Scrollbar,
199217
Select,
200-
Tag
218+
Tag,
219+
Table,
220+
TableColumn
201221
}

packages/table-column/index.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { App } from 'vue'
2+
import Component from '../table/src/table-column.vue'
3+
export const install = function (app: App) {
4+
app.component(Component.name as string, Component)
5+
}
6+
7+
export default Component

packages/table/index.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { App } from 'vue'
2+
import Component from './src/index.vue'
3+
export const install = function (app: App) {
4+
app.component(Component.name as string, Component)
5+
}
6+
7+
export default Component

packages/table/src/index.vue

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<template>
2+
<div>--table组件暂未开发--</div>
3+
</template>
4+
<script>
5+
import { defineComponent } from 'vue'
6+
export default defineComponent({
7+
name: 'ElTable'
8+
})
9+
</script>

packages/table/src/table-column.vue

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<template>
2+
<div></div>
3+
</template>
4+
<script>
5+
import { defineComponent } from 'vue'
6+
export default defineComponent({
7+
name: 'ElTableColumn'
8+
})
9+
</script>

0 commit comments

Comments
 (0)