mirror of https://github.com/ElemeFE/element
Drawer: bugfix/drawer-append-to-body-not-working (#16953)
- 修复了 AppendToBody API 不管用的问题. - 修复了展开动画会出现滚动条的问题 - 新增了一个新的 API `withHeader` 来控制是否显示 Header 栏 - 动画流畅度的一个小改动 - 对应文档的改动 - 对应单元测试的改动pull/17264/head^2
parent
7bf3924b29
commit
068b3ad1b0
|
@ -50,6 +50,36 @@ Callout a temporary drawer, from multiple direction
|
||||||
```
|
```
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
### No Title
|
||||||
|
|
||||||
|
When you no longer need a title, you can remove title from drawer.
|
||||||
|
|
||||||
|
:::demo Set the `withHeader` attribute to **false**, you can remove the title from drawer, thus your drawer can have more space on screen. If you want to be accessible, make sure to set the `title` attribute.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<el-button @click="drawer = true" type="primary" style="margin-left: 16px;">
|
||||||
|
open
|
||||||
|
</el-button>
|
||||||
|
|
||||||
|
<el-drawer
|
||||||
|
title="I am the title"
|
||||||
|
:visible.sync="drawer"
|
||||||
|
:with-header="false">
|
||||||
|
<span>Hi there!</span>
|
||||||
|
</el-drawer>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
drawer: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
### Customization Content
|
### Customization Content
|
||||||
|
|
||||||
Like `Dialog`, `Drawer` can do many diverse interaction as you wanted.
|
Like `Dialog`, `Drawer` can do many diverse interaction as you wanted.
|
||||||
|
@ -92,7 +122,7 @@ Like `Dialog`, `Drawer` can do many diverse interaction as you wanted.
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="demo-drawer__footer">
|
<div class="demo-drawer__footer">
|
||||||
<el-button @click="dialog = false">Cancel</el-button>
|
<el-button @click="cancelForm">Cancel</el-button>
|
||||||
<el-button type="primary" @click="$refs.drawer.closeDrawer()" :loading="loading">{{ loading ? 'Submitting ...' : 'Submit' }}</el-button>
|
<el-button type="primary" @click="$refs.drawer.closeDrawer()" :loading="loading">{{ loading ? 'Submitting ...' : 'Submit' }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -132,20 +162,32 @@ export default {
|
||||||
resource: '',
|
resource: '',
|
||||||
desc: ''
|
desc: ''
|
||||||
},
|
},
|
||||||
formLabelWidth: '80px'
|
formLabelWidth: '80px',
|
||||||
|
timer: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleClose(done) {
|
handleClose(done) {
|
||||||
|
if (this.loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.$confirm('Do you want to submit?')
|
this.$confirm('Do you want to submit?')
|
||||||
.then(_ => {
|
.then(_ => {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
setTimeout(() => {
|
this.timer = setTimeout(() => {
|
||||||
this.loading = false;
|
|
||||||
done();
|
done();
|
||||||
|
// animation takes time
|
||||||
|
setTimeout(() => {
|
||||||
|
this.loading = false;
|
||||||
|
}, 400);
|
||||||
}, 2000);
|
}, 2000);
|
||||||
})
|
})
|
||||||
.catch(_ => {});
|
.catch(_ => {});
|
||||||
|
},
|
||||||
|
cancelForm() {
|
||||||
|
this.loading = false;
|
||||||
|
this.dialog = false;
|
||||||
|
clearTimeout(this.timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,6 +280,7 @@ If the variable bound to `visible` is managed in Vuex store, the `.sync` can not
|
||||||
| title | Drawer's title, can also be set by named slot, detailed descriptions can be found in the slot form | string | — | — |
|
| title | Drawer's title, can also be set by named slot, detailed descriptions can be found in the slot form | string | — | — |
|
||||||
| visible | Should Drawer be displayed, also support the `.sync` notation | boolean | — | false |
|
| visible | Should Drawer be displayed, also support the `.sync` notation | boolean | — | false |
|
||||||
| wrapperClosable | Indicates whether user can close Drawer by clicking the shadowing layer. | boolean | - | true |
|
| wrapperClosable | Indicates whether user can close Drawer by clicking the shadowing layer. | boolean | - | true |
|
||||||
|
| withHeader | Flag that controls the header section's existance, default to true, when withHeader set to false, both `title attribute` and `title slot` won't work | boolean | - | true |
|
||||||
|
|
||||||
### Drawer Slot
|
### Drawer Slot
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,37 @@ Llamada de un drawer temporal, desde varias direcciones
|
||||||
```
|
```
|
||||||
:::
|
:::
|
||||||
|
|
||||||
### Personalizar el contenido
|
### No Title
|
||||||
|
|
||||||
|
When you no longer need a title, you can remove title from drawer.
|
||||||
|
|
||||||
|
:::demo Set the `withHeader` attribute to **false**, you can remove the title from drawer, thus your drawer can have more space on screen. If you want to be accessible, make sure to set the `title` attribute.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<el-button @click="drawer = true" type="primary" style="margin-left: 16px;">
|
||||||
|
open
|
||||||
|
</el-button>
|
||||||
|
|
||||||
|
<el-drawer
|
||||||
|
title="I am the title"
|
||||||
|
:visible.sync="drawer"
|
||||||
|
:with-header="false">
|
||||||
|
<span>Hi there!</span>
|
||||||
|
</el-drawer>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
drawer: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Personalizar el contenido
|
||||||
|
|
||||||
Al igual que `Dialog`, `Drawer` puede hacer muchas interacciones diversas.
|
Al igual que `Dialog`, `Drawer` puede hacer muchas interacciones diversas.
|
||||||
|
|
||||||
|
@ -92,7 +122,7 @@ Al igual que `Dialog`, `Drawer` puede hacer muchas interacciones diversas.
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="demo-drawer__footer">
|
<div class="demo-drawer__footer">
|
||||||
<el-button @click="dialog = false">Cancel</el-button>
|
<el-button @click="cancelForm">Cancel</el-button>
|
||||||
<el-button type="primary" @click="$refs.drawer.closeDrawer()" :loading="loading">{{ loading ? 'Submitting ...' : 'Submit' }}</el-button>
|
<el-button type="primary" @click="$refs.drawer.closeDrawer()" :loading="loading">{{ loading ? 'Submitting ...' : 'Submit' }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -132,20 +162,32 @@ export default {
|
||||||
resource: '',
|
resource: '',
|
||||||
desc: ''
|
desc: ''
|
||||||
},
|
},
|
||||||
formLabelWidth: '80px'
|
formLabelWidth: '80px',
|
||||||
|
timer: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleClose(done) {
|
handleClose(done) {
|
||||||
|
if (this.loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.$confirm('Do you want to submit?')
|
this.$confirm('Do you want to submit?')
|
||||||
.then(_ => {
|
.then(_ => {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
setTimeout(() => {
|
this.timer = setTimeout(() => {
|
||||||
this.loading = false;
|
|
||||||
done();
|
done();
|
||||||
|
// animation takes time
|
||||||
|
setTimeout(() => {
|
||||||
|
this.loading = false;
|
||||||
|
}, 400);
|
||||||
}, 2000);
|
}, 2000);
|
||||||
})
|
})
|
||||||
.catch(_ => {});
|
.catch(_ => {});
|
||||||
|
},
|
||||||
|
cancelForm() {
|
||||||
|
this.loading = false;
|
||||||
|
this.dialog = false;
|
||||||
|
clearTimeout(this.timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,6 +280,7 @@ Si la variable `visible` se gestiona en el almacén de Vuex, el `.sync` no puede
|
||||||
| title | El título del Drawer, también se puede establecer por slot con nombre, las descripciones detalladas se pueden encontrar en el formulario de slot. | string | — | — |
|
| title | El título del Drawer, también se puede establecer por slot con nombre, las descripciones detalladas se pueden encontrar en el formulario de slot. | string | — | — |
|
||||||
| visible | Si se muestra el Drawer, también soporta la notación `.sync` | boolean | — | false |
|
| visible | Si se muestra el Drawer, también soporta la notación `.sync` | boolean | — | false |
|
||||||
| wrapperClosable | Indica si el usuario puede cerrar el Drawer haciendo clic en la capa de sombreado. | boolean | - | true |
|
| wrapperClosable | Indica si el usuario puede cerrar el Drawer haciendo clic en la capa de sombreado. | boolean | - | true |
|
||||||
|
| withHeader | Flag that controls the header section's existance, default to true, when withHeader set to false, both `title attribute` and `title slot` won't work | boolean | - | true |
|
||||||
|
|
||||||
### Drawer Slot's
|
### Drawer Slot's
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,36 @@ Callout a temporary drawer, from multiple direction
|
||||||
```
|
```
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
### No Title
|
||||||
|
|
||||||
|
When you no longer need a title, you can remove title from drawer.
|
||||||
|
|
||||||
|
:::demo Set the `withHeader` attribute to **false**, you can remove the title from drawer, thus your drawer can have more space on screen. If you want to be accessible, make sure to set the `title` attribute.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<el-button @click="drawer = true" type="primary" style="margin-left: 16px;">
|
||||||
|
open
|
||||||
|
</el-button>
|
||||||
|
|
||||||
|
<el-drawer
|
||||||
|
title="I am the title"
|
||||||
|
:visible.sync="drawer"
|
||||||
|
:with-header="false">
|
||||||
|
<span>Hi there!</span>
|
||||||
|
</el-drawer>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
drawer: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
### Customization Content
|
### Customization Content
|
||||||
|
|
||||||
Like `Dialog`, `Drawer` can do many diverse interaction as you wanted.
|
Like `Dialog`, `Drawer` can do many diverse interaction as you wanted.
|
||||||
|
@ -92,7 +122,7 @@ Like `Dialog`, `Drawer` can do many diverse interaction as you wanted.
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="demo-drawer__footer">
|
<div class="demo-drawer__footer">
|
||||||
<el-button @click="dialog = false">Cancel</el-button>
|
<el-button @click="cancelForm">Cancel</el-button>
|
||||||
<el-button type="primary" @click="$refs.drawer.closeDrawer()" :loading="loading">{{ loading ? 'Submitting ...' : 'Submit' }}</el-button>
|
<el-button type="primary" @click="$refs.drawer.closeDrawer()" :loading="loading">{{ loading ? 'Submitting ...' : 'Submit' }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -132,20 +162,32 @@ export default {
|
||||||
resource: '',
|
resource: '',
|
||||||
desc: ''
|
desc: ''
|
||||||
},
|
},
|
||||||
formLabelWidth: '80px'
|
formLabelWidth: '80px',
|
||||||
|
timer: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleClose(done) {
|
handleClose(done) {
|
||||||
|
if (this.loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.$confirm('Do you want to submit?')
|
this.$confirm('Do you want to submit?')
|
||||||
.then(_ => {
|
.then(_ => {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
setTimeout(() => {
|
this.timer = setTimeout(() => {
|
||||||
this.loading = false;
|
|
||||||
done();
|
done();
|
||||||
|
// animation takes time
|
||||||
|
setTimeout(() => {
|
||||||
|
this.loading = false;
|
||||||
|
}, 400);
|
||||||
}, 2000);
|
}, 2000);
|
||||||
})
|
})
|
||||||
.catch(_ => {});
|
.catch(_ => {});
|
||||||
|
},
|
||||||
|
cancelForm() {
|
||||||
|
this.loading = false;
|
||||||
|
this.dialog = false;
|
||||||
|
clearTimeout(this.timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,6 +280,7 @@ If the variable bound to `visible` is managed in Vuex store, the `.sync` can not
|
||||||
| title | Drawer's title, can also be set by named slot, detailed descriptions can be found in the slot form | string | — | — |
|
| title | Drawer's title, can also be set by named slot, detailed descriptions can be found in the slot form | string | — | — |
|
||||||
| visible | Should Drawer be displayed, also support the `.sync` notation | boolean | — | false |
|
| visible | Should Drawer be displayed, also support the `.sync` notation | boolean | — | false |
|
||||||
| wrapperClosable | Indicates whether user can close Drawer by clicking the shadowing layer. | boolean | - | true |
|
| wrapperClosable | Indicates whether user can close Drawer by clicking the shadowing layer. | boolean | - | true |
|
||||||
|
| withHeader | Flag that controls the header section's existance, default to true, when withHeader set to false, both `title attribute` and `title slot` won't work | boolean | - | true |
|
||||||
|
|
||||||
### Drawer Slot
|
### Drawer Slot
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,37 @@
|
||||||
```
|
```
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
### 不添加 Title
|
||||||
|
|
||||||
|
当你不需要标题到时候, 你还可以去掉标题
|
||||||
|
|
||||||
|
:::demo 当遇到不需要 title 的场景时, 可以通过 `withHeader` 这个属性来关闭掉 title 的显示, 这样可以留出更大的空间给到用户, 为了用户的可访问性, 请务必设定 `title` 的值
|
||||||
|
|
||||||
|
```html
|
||||||
|
<el-button @click="drawer = true" type="primary" style="margin-left: 16px;">
|
||||||
|
点我打开
|
||||||
|
</el-button>
|
||||||
|
|
||||||
|
<el-drawer
|
||||||
|
title="我是标题"
|
||||||
|
:visible.sync="drawer"
|
||||||
|
:with-header="false">
|
||||||
|
<span>我来啦!</span>
|
||||||
|
</el-drawer>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
drawer: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
### 自定义内容
|
### 自定义内容
|
||||||
|
|
||||||
和 `Dialog` 组件一样, `Drawer` 同样可以在其内部嵌套各种丰富的操作
|
和 `Dialog` 组件一样, `Drawer` 同样可以在其内部嵌套各种丰富的操作
|
||||||
|
@ -92,7 +123,7 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="demo-drawer__footer">
|
<div class="demo-drawer__footer">
|
||||||
<el-button @click="dialog = false">取 消</el-button>
|
<el-button @click="cancelForm">取 消</el-button>
|
||||||
<el-button type="primary" @click="$refs.drawer.closeDrawer()" :loading="loading">{{ loading ? '提交中 ...' : '确 定' }}</el-button>
|
<el-button type="primary" @click="$refs.drawer.closeDrawer()" :loading="loading">{{ loading ? '提交中 ...' : '确 定' }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -132,20 +163,32 @@ export default {
|
||||||
resource: '',
|
resource: '',
|
||||||
desc: ''
|
desc: ''
|
||||||
},
|
},
|
||||||
formLabelWidth: '80px'
|
formLabelWidth: '80px',
|
||||||
|
timer: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleClose(done) {
|
handleClose(done) {
|
||||||
|
if (this.loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.$confirm('确定要提交表单吗?')
|
this.$confirm('确定要提交表单吗?')
|
||||||
.then(_ => {
|
.then(_ => {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
setTimeout(() => {
|
this.timer = setTimeout(() => {
|
||||||
this.loading = false;
|
|
||||||
done();
|
done();
|
||||||
|
// 动画关闭需要一定的时间
|
||||||
|
setTimeout(() => {
|
||||||
|
this.loading = false;
|
||||||
|
}, 400);
|
||||||
}, 2000);
|
}, 2000);
|
||||||
})
|
})
|
||||||
.catch(_ => {});
|
.catch(_ => {});
|
||||||
|
},
|
||||||
|
cancelForm() {
|
||||||
|
this.loading = false;
|
||||||
|
this.dialog = false;
|
||||||
|
clearTimeout(this.timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,6 +282,7 @@ Drawer 提供一个 `destroyOnClose` API, 用来在关闭 Drawer 时销毁子组
|
||||||
| title | Drawer 的标题,也可通过具名 slot (见下表)传入 | string | — | — |
|
| title | Drawer 的标题,也可通过具名 slot (见下表)传入 | string | — | — |
|
||||||
| visible | 是否显示 Drawer,支持 .sync 修饰符 | boolean | — | false |
|
| visible | 是否显示 Drawer,支持 .sync 修饰符 | boolean | — | false |
|
||||||
| wrapperClosable | 点击遮罩层是否可以关闭 Drawer | boolean | - | true |
|
| wrapperClosable | 点击遮罩层是否可以关闭 Drawer | boolean | - | true |
|
||||||
|
| withHeader | 控制是否显示 header 栏, 默认为 true, 当此项为 false 时, title attribute 和 title slot 均不生效 | boolean | - | true |
|
||||||
|
|
||||||
### Drawer Slot
|
### Drawer Slot
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
@after-enter="afterEnter"
|
@after-enter="afterEnter"
|
||||||
@after-leave="afterLeave">
|
@after-leave="afterLeave">
|
||||||
<div
|
<div
|
||||||
class="el-dialog__wrapper"
|
class="el-drawer__wrapper"
|
||||||
role="presentation"
|
tabindex="-1"
|
||||||
v-show="visible">
|
v-show="visible">
|
||||||
<div
|
<div
|
||||||
class="el-drawer__container"
|
class="el-drawer__container"
|
||||||
|
@ -16,14 +16,17 @@
|
||||||
<div
|
<div
|
||||||
aria-modal="true"
|
aria-modal="true"
|
||||||
aria-labelledby="el-drawer__title"
|
aria-labelledby="el-drawer__title"
|
||||||
|
:aria-label="title"
|
||||||
class="el-drawer"
|
class="el-drawer"
|
||||||
:class="[direction, customClass]"
|
:class="[direction, customClass]"
|
||||||
:style="isHorizontal ? `width: ${size}` : `height: ${size}`"
|
:style="isHorizontal ? `width: ${size}` : `height: ${size}`"
|
||||||
ref="drawer"
|
ref="drawer"
|
||||||
role="presentation">
|
role="dialog"
|
||||||
<header class="el-drawer__header" id="el-drawer__title">
|
tabindex="-1"
|
||||||
|
>
|
||||||
|
<header class="el-drawer__header" id="el-drawer__title" v-if="withHeader">
|
||||||
<slot name="title">
|
<slot name="title">
|
||||||
<span role="heading">{{ title }}</span>
|
<span role="heading" tabindex="0" :title="title">{{ title }}</span>
|
||||||
</slot>
|
</slot>
|
||||||
<button
|
<button
|
||||||
:aria-label="`close ${title || 'drawer'}`"
|
:aria-label="`close ${title || 'drawer'}`"
|
||||||
|
@ -45,16 +48,16 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Popup from 'element-ui/src/utils/popup';
|
import Popup from 'element-ui/src/utils/popup';
|
||||||
import Migrating from 'element-ui/src/mixins/migrating';
|
|
||||||
import emitter from 'element-ui/src/mixins/emitter';
|
import emitter from 'element-ui/src/mixins/emitter';
|
||||||
|
import Utils from 'element-ui/src/utils/aria-utils';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ElDrawer',
|
name: 'ElDrawer',
|
||||||
mixins: [Popup, emitter, Migrating],
|
mixins: [Popup, emitter],
|
||||||
props: {
|
props: {
|
||||||
appendToBody: {
|
appendToBody: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: false
|
||||||
},
|
},
|
||||||
beforeClose: {
|
beforeClose: {
|
||||||
type: Function
|
type: Function
|
||||||
|
@ -63,6 +66,10 @@ export default {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
|
closeOnPressEscape: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
destroyOnClose: {
|
destroyOnClose: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
@ -78,6 +85,10 @@ export default {
|
||||||
return ['ltr', 'rtl', 'ttb', 'btt'].indexOf(val) !== -1;
|
return ['ltr', 'rtl', 'ttb', 'btt'].indexOf(val) !== -1;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
modalAppendToBody: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
showClose: {
|
showClose: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
|
@ -96,6 +107,10 @@ export default {
|
||||||
wrapperClosable: {
|
wrapperClosable: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
|
},
|
||||||
|
withHeader: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -105,7 +120,8 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
closed: false
|
closed: false,
|
||||||
|
prevActiveElement: null
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -116,8 +132,17 @@ export default {
|
||||||
if (this.appendToBody) {
|
if (this.appendToBody) {
|
||||||
document.body.appendChild(this.$el);
|
document.body.appendChild(this.$el);
|
||||||
}
|
}
|
||||||
|
this.prevActiveElement = document.activeElement;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
Utils.focusFirstDescendant(this.$refs.drawer);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
if (!this.closed) this.$emit('close');
|
if (!this.closed) this.$emit('close');
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.prevActiveElement) {
|
||||||
|
this.prevActiveElement.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -149,6 +174,12 @@ export default {
|
||||||
} else {
|
} else {
|
||||||
this.hide();
|
this.hide();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
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.
|
||||||
|
this.closeDrawer();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
|
@ -92,13 +92,13 @@
|
||||||
|
|
||||||
@mixin animation-in($direction) {
|
@mixin animation-in($direction) {
|
||||||
.el-drawer__open &.#{$direction} {
|
.el-drawer__open &.#{$direction} {
|
||||||
animation: #{$direction}-drawer-in 225ms cubic-bezier(0, 0, .2, 1) 0ms;
|
animation: #{$direction}-drawer-in .3s 1ms;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin animation-out($direction) {
|
@mixin animation-out($direction) {
|
||||||
&.#{$direction} {
|
&.#{$direction} {
|
||||||
animation: #{$direction}-drawer-out 225ms cubic-bezier(0, 0, .2, 1) 0ms;
|
animation: #{$direction}-drawer-out .3s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,6 +125,16 @@ $directions: rtl, ltr, ttb, btt;
|
||||||
@include animation-in($direction);
|
@include animation-in($direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__wrapper {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
&__header {
|
&__header {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: rgb(114, 118, 123);
|
color: rgb(114, 118, 123);
|
||||||
|
@ -199,9 +209,9 @@ $directions: rtl, ltr, ttb, btt;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-drawer-fade-enter-active {
|
.el-drawer-fade-enter-active {
|
||||||
animation: el-drawer-fade-in 225ms cubic-bezier(0, 0, 0.2, 1) 0ms;
|
animation: el-drawer-fade-in .3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-drawer-fade-leave-active {
|
.el-drawer-fade-leave-active {
|
||||||
animation: el-drawer-fade-in 225ms cubic-bezier(0, 0, 0.2, 1) 0ms reverse;
|
animation: el-drawer-fade-in .3s reverse;
|
||||||
}
|
}
|
||||||
|
|
|
@ -218,6 +218,24 @@ describe('Drawer', () => {
|
||||||
expect(vm.$el.querySelector(`.${classes}`)).to.exist;
|
expect(vm.$el.querySelector(`.${classes}`)).to.exist;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not render header when withHeader attribute is false', () => {
|
||||||
|
vm = createVue({
|
||||||
|
template: `
|
||||||
|
<el-drawer :title='title' :visible='visible' ref='drawer' :with-header='false'>
|
||||||
|
<span>${content}</span>
|
||||||
|
</el-drawer>
|
||||||
|
`,
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
title,
|
||||||
|
visible: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(vm.$el.querySelector('.el-drawer__header')).to.not.exist;
|
||||||
|
});
|
||||||
|
|
||||||
describe('directions', () => {
|
describe('directions', () => {
|
||||||
const renderer = direction => {
|
const renderer = direction => {
|
||||||
return createVue({
|
return createVue({
|
||||||
|
|
Loading…
Reference in New Issue