diff --git a/example/src/components/HelloWord.vue b/example/src/components/HelloWord.vue
index 8c304839465354c7430288ee44f085a4efe603e3..9006c616efceafb4d573b061fcb8169abb111d77 100644
--- a/example/src/components/HelloWord.vue
+++ b/example/src/components/HelloWord.vue
@@ -1,24 +1,39 @@
内容
+
+
+ 内部抽屉内容
+
+
+
-
diff --git a/src/css/layer.css b/src/css/layer.css
index ce7f6c1b4a1c6a8c5f3e7e6a00a9be2d219473de..ee0ff21734493acb9e67732c11c4c573a2d4718e 100644
--- a/src/css/layer.css
+++ b/src/css/layer.css
@@ -99,6 +99,284 @@ html #layuicss-layer {
-webkit-animation-duration: .3s;
animation-duration: .3s
}
+/* 抽屉开始 */
+/* right to left */
+@keyframes layer-rl {
+ from {
+ -webkit-transform: translate3d(100%, 0, 0);
+ -ms-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ opacity: 0;
+
+ }
+ to {
+ -webkit-transform: translate3d(0, 0, 0);
+ -ms-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ opacity: 1;
+ }
+}
+
+@-webkit-keyframes layer-rl {
+ from {
+ -webkit-transform: translate3d(100%, 0, 0);
+ -ms-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ opacity: 0;
+
+ }
+ to {
+ -webkit-transform: translate3d(0, 0, 0);
+ -ms-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ opacity: 1;
+ }
+}
+
+.layer-anim-rl {
+ -webkit-animation-name: layer-rl;
+ animation-name: layer-rl;
+ /* animation-timing-function:cubic-bezier(0.7, 0.3, 0.1, 1); */
+}
+
+/* right to left close */
+@keyframes layer-rl-close {
+ from {
+ -webkit-transform: translate3d(0, 0, 0);
+ -ms-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+
+ }
+ to {
+ -webkit-transform: translate3d(100%, 0, 0);
+ -ms-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ }
+}
+
+@-webkit-keyframes layer-rl-close {
+ from {
+ -webkit-transform: translate3d(0, 0, 0);
+ -ms-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+
+ }
+ to {
+ -webkit-transform: translate3d(100%, 0, 0);
+ -ms-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ }
+}
+
+.layer-anim-rl-close {
+ -webkit-animation-name: layer-rl-close;
+ animation-name: layer-rl-close;
+ /* animation-timing-function:cubic-bezier(0.7, 0.3, 0.1, 1); */
+}
+/* left to right */
+@-webkit-keyframes layer-lr {
+ from {
+ -webkit-transform: translate3d(0, 0, 0);
+ -ms-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ opacity: 0
+ }
+ to {
+ -webkit-transform: translate3d(-100%, 0, 0);
+ -ms-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ opacity: 1
+ }
+}
+
+@keyframes layer-lr {
+ from {
+ -webkit-transform: translate3d(-100%, 0, 0);
+ -ms-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ opacity: 0
+ }
+ to {
+ -webkit-transform: translate3d(0, 0, 0);
+ -ms-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ opacity: 1
+ }
+}
+.layer-anim-lr {
+ -webkit-animation-name: layer-lr;
+ animation-name: layer-lr
+}
+
+/* left to right close */
+@-webkit-keyframes layer-lr-close {
+ from {
+ -webkit-transform: translate3d(0, 0, 0);
+ -ms-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ }
+ to {
+ -webkit-transform: translate3d(-100%, 0, 0);
+ -ms-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ }
+}
+
+@keyframes layer-lr-close {
+ from {
+ -webkit-transform: translate3d(0, 0, 0);
+ -ms-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ }
+ to {
+ -webkit-transform: translate3d(-100%, 0, 0);
+ -ms-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ }
+}
+.layer-anim-lr-close {
+ -webkit-animation-name: layer-lr-close;
+ animation-name: layer-lr-close
+}
+
+/* top to bottom */
+@-webkit-keyframes layer-tb {
+ from {
+ -webkit-transform: translate3d(0, -100%, 0);
+ -ms-transform: translate3d(0, -100%, 0);
+ transform: translate3d(0, -100%, 0);
+ opacity: 0;
+ animation-timing-function:cubic-bezier(0.7, 0.3, 0.1, 1);
+ }
+ to {
+ -webkit-transform: translate3d(0, 0, 0);
+ -ms-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ opacity: 1;
+ animation-timing-function:cubic-bezier(0.7, 0.3, 0.1, 1);
+ }
+}
+
+@keyframes layer-tb {
+ from {
+ -webkit-transform: translate3d(0, -100%, 0);
+ -ms-transform: translate3d(0, -100%, 0);
+ transform: translate3d(0, -100%, 0);
+ opacity: 0;
+ animation-timing-function:cubic-bezier(0.7, 0.3, 0.1, 1);
+ }
+ to {
+ -webkit-transform: translate3d(0, 0, 0);
+ -ms-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ opacity: 1;
+ animation-timing-function:cubic-bezier(0.7, 0.3, 0.1, 1);
+ }
+}
+.layer-anim-tb {
+ -webkit-animation-name: layer-tb;
+ animation-name: layer-tb
+}
+
+/* top to bottom close */
+@-webkit-keyframes layer-tb-close {
+ from {
+ -webkit-transform: translate3d(0, 0, 0);
+ -ms-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ }
+ to {
+ -webkit-transform: translate3d(0, -100%, 0);
+ -ms-transform: translate3d(0, -100%, 0);
+ transform: translate3d(0, -100%, 0);
+ }
+}
+
+@keyframes layer-tb-close {
+ from {
+ -webkit-transform: translate3d(0, 0, 0);
+ -ms-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ }
+ to {
+ -webkit-transform: translate3d(0, -100%, 0);
+ -ms-transform: translate3d(0, -100%, 0);
+ transform: translate3d(0, -100%, 0);
+ }
+}
+.layer-anim-tb-close {
+ -webkit-animation-name: layer-tb-close;
+ animation-name: layer-tb-close
+}
+
+/* bottom to top */
+@-webkit-keyframes layer-bt {
+ from {
+ -webkit-transform: translate3d(0, 100%, 0);
+ -ms-transform: translate3d(0, 100%, 0);
+ transform: translate3d(0, 100%, 0);
+ opacity: 0
+ }
+ to {
+ -webkit-transform: translate3d(0, 0, 0);
+ -ms-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ opacity: 1
+ }
+}
+
+@keyframes layer-bt {
+ from {
+ -webkit-transform: translate3d(0, 100%, 0);
+ -ms-transform: translate3d(0, 100%, 0);
+ transform: translate3d(0, 100%, 0);
+ opacity: 0
+ }
+ to {
+ -webkit-transform: translate3d(0, 0, 0);
+ -ms-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ opacity: 1
+ }
+}
+.layer-anim-bt {
+ -webkit-animation-name: layer-bt;
+ animation-name: layer-bt
+}
+
+/* bottom to top close */
+@-webkit-keyframes layer-bt-close {
+ from {
+ -webkit-transform: translate3d(0, 0, 0);
+ -ms-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ }
+ to {
+ -webkit-transform: translate3d(0, 100%, 0);
+ -ms-transform: translate3d(0, 100%, 0);
+ transform: translate3d(0, 100%, 0);
+ }
+}
+
+@keyframes layer-bt-close {
+ from {
+ -webkit-transform: translate3d(0, 0, 0);
+ -ms-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+
+ }
+ to {
+ -webkit-transform: translate3d(0, 100%, 0);
+ -ms-transform: translate3d(0, 100%, 0);
+ transform: translate3d(0, 100%, 0);
+
+ }
+}
+.layer-anim-bt-close {
+ -webkit-animation-name: layer-bt-close;
+ animation-name: layer-bt-close
+}
+/* 抽屉结束 */
@-webkit-keyframes layer-bounceIn {
0% {
diff --git a/src/layer/index.ts b/src/layer/index.ts
index 592cd11cd5c4345902fee868fe7eceb840e5e71d..e7e0deff56597a420de6a9cb00e2877a9277ef2b 100644
--- a/src/layer/index.ts
+++ b/src/layer/index.ts
@@ -69,6 +69,13 @@ const layer = {
let defaultOption = {};
return layer.create(option, defaultOption, callback);
},
+ // 抽屉
+ drawer: (option: any, callback: Function) => {
+ let defaultOption = {
+ type:"drawer",
+ };
+ return layer.create(option, defaultOption, callback);
+ },
// 消息框
msg: (message: string, option: any, callback: Function) => {
let defaultOption = {
diff --git a/src/module/modal/index.vue b/src/module/modal/index.vue
index 820b0ff76a1c2a33d6ac4b46e83326783f914d3e..ed70cc0e3c1edf1aceca6dbe1a012cb2a6bd2219 100644
--- a/src/module/modal/index.vue
+++ b/src/module/modal/index.vue
@@ -20,6 +20,8 @@ import {
minArea,
minOffset,
updateMinArrays,
+ getDrawerAnimationClass,
+ calculateDrawerArea,
} from "../../tools";
import useMove from "../../tools/useMove";
@@ -43,7 +45,7 @@ export interface LayModalProps {
btn?: Record[] | false;
move?: boolean | string;
resize?: boolean | string;
- type?: 0 | 1 | 2 | 3 | "dialog" | "component" | "iframe" | "loading";
+ type?: 0 | 1 | 2 | 3 | "dialog" | "component" | "iframe" | "loading" | "drawer";
content?: string | Function | object | VNodeTypes
isHtmlFragment?: boolean;
shade?: boolean | string;
@@ -99,8 +101,8 @@ const id: Ref = ref(nextId());
const max: Ref = ref(false);
const min: Ref = ref(false);
const type: number = calculateType(props.type);
-const area: Ref = ref(calculateArea(props.area));
-const offset: Ref = ref(calculateOffset(props.offset, area));
+const area: Ref = props.type != "drawer" ? ref(calculateArea(props.area)) : ref(calculateDrawerArea(props.offset, props.area));
+const offset: Ref = ref(calculateOffset(props.offset, area, props.type));
const contentHeight = ref(calculateContent(area.value[1], props.btn, type));
const index: Ref = ref(props.zIndex);
const visible: Ref = ref(false);
@@ -122,7 +124,7 @@ const _l: Ref = ref(offset.value[1]);
const firstOpenDelayCalculation = function () {
setTimeout(() => {
area.value = getArea(layero.value);
- offset.value = calculateOffset(props.offset, area.value);
+ offset.value = calculateOffset(props.offset, area.value, props.type);
w.value = area.value[0];
h.value = area.value[1];
t.value = offset.value[0];
@@ -241,7 +243,7 @@ const setTopHandle = () => {
// 拖拽支持
const supportMove = function () {
- if (props.move) {
+ if (props.move && props.type != "drawer") {
if (layero.value != null) {
// @ts-ignore
useMove(layero.value, (width, height, left, top) => {
@@ -269,11 +271,17 @@ const styles = computed(() => {
// 入场动画
const enterActiveClass = computed(() => {
+ if(props.type === "drawer"){
+ return getDrawerAnimationClass(props.offset)
+ }
return `layer-anim layer-anim-0${props.anim}`;
});
// 出场动画
const leaveActiveClass = computed(() => {
+ if(props.type === "drawer"){
+ return getDrawerAnimationClass(props.offset,true);
+ }
return props.isOutAnim ? `layer-anim-close` : "";
});
diff --git a/src/tools/index.ts b/src/tools/index.ts
index 39544b2d2c3ea0346b7e22acd815a41b6edf5e0e..971c4813760e71f741f4c6fbdcaed7bf489536c6 100644
--- a/src/tools/index.ts
+++ b/src/tools/index.ts
@@ -50,10 +50,13 @@ export function calculateArea(area: any) {
// @param offset
// @param domSize
// @return 正确位置
-export function calculateOffset(offset: any, area: any) {
+export function calculateOffset(offset: any, area: any, type: any) {
var arr = ['t', 'r', 'b', 'l', 'lt', 'lb', 'rt', 'rb']
var t = offset[0];
var l = offset[1];
+ if(offset instanceof Array && type === "drawer"){
+ offset = 'r';
+ }
// @ts-ignore
if (arr.indexOf(offset) > -1) {
t = '50%';
@@ -80,7 +83,7 @@ export function calculateOffset(offset: any, area: any) {
export function calculateType(modalType: number | string) {
if(modalType === 'dialog' || modalType === 0 || modalType === '0'){
return 0;
- }else if(modalType === 'component' || modalType === 1 || modalType === '1'){
+ }else if(modalType === 'component' || modalType === 'drawer' || modalType === 1 || modalType === '1'){
return 1;
}else if(modalType === 'iframe' || modalType === 2 || modalType === '2'){
return 2;
@@ -171,4 +174,36 @@ export function updateMinArrays(id: string, state: Boolean) {
i = -1;
}
return i;
-}
\ No newline at end of file
+}
+
+// 抽屉动画类
+export function getDrawerAnimationClass(offset: any,isClose: boolean = false){
+ const prefix = "layer-anim layer-anim";
+ let suffix = "rl";
+ if(offset === "l"){
+ suffix = "lr";
+ }else if(offset === "r"){
+ suffix = "rl"
+ }else if(offset === "t"){
+ suffix = "tb"
+ }else if(offset === "b"){
+ suffix = "bt"
+ }
+ return isClose ? `${prefix}-${suffix}-close` : `${prefix}-${suffix}`;
+}
+
+// 抽屉宽/高
+export function calculateDrawerArea(offset: any, drawerArea: string[] | string = "350px"){
+ if(drawerArea instanceof Array){
+ return drawerArea;
+ }
+ if(drawerArea === "auto"){
+ drawerArea = "350px";
+ }
+ if(offset === "l" || offset === "r"){
+ return [drawerArea, "100%"];
+ }else if(offset === "t" || offset === "b"){
+ return ["100%", drawerArea];
+ }
+ return [drawerArea,"100%"];
+}